├── .npmignore ├── CHANGELOG.md ├── README.md ├── adapters ├── azure-swa │ └── vite.d.ts ├── bun-server │ └── vite.d.ts ├── cloud-run │ └── vite.d.ts ├── cloudflare-pages │ └── vite.d.ts ├── deno-server │ └── vite.d.ts ├── netlify-edge │ └── vite.d.ts ├── node-server │ └── vite.d.ts ├── shared │ └── vite.d.ts ├── static │ └── vite.d.ts └── vercel-edge │ └── vite.d.ts ├── global.d.ts ├── index.d.ts ├── lib ├── adapters │ ├── azure-swa │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── bun-server │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── cloud-run │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── cloudflare-pages │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── deno-server │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── netlify-edge │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── node-server │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── shared │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ ├── static │ │ └── vite │ │ │ ├── index.cjs │ │ │ ├── index.d.ts │ │ │ └── index.mjs │ └── vercel-edge │ │ └── vite │ │ ├── index.cjs │ │ ├── index.d.ts │ │ └── index.mjs ├── index.d.ts ├── index.qwik.cjs ├── index.qwik.mjs ├── middleware │ ├── aws-lambda │ │ ├── index.d.ts │ │ └── index.mjs │ ├── azure-swa │ │ ├── index.d.ts │ │ └── index.mjs │ ├── bun │ │ ├── index.d.ts │ │ └── index.mjs │ ├── cloudflare-pages │ │ ├── index.d.ts │ │ └── index.mjs │ ├── deno │ │ ├── index.d.ts │ │ └── index.mjs │ ├── firebase │ │ ├── index.d.ts │ │ └── index.mjs │ ├── netlify-edge │ │ ├── index.d.ts │ │ └── index.mjs │ ├── node │ │ ├── index.cjs │ │ ├── index.d.ts │ │ └── index.mjs │ ├── request-handler │ │ ├── index.cjs │ │ ├── index.d.ts │ │ └── index.mjs │ └── vercel-edge │ │ ├── index.d.ts │ │ └── index.mjs ├── modules.d.ts ├── service-worker.cjs ├── service-worker.d.ts ├── service-worker.mjs ├── static │ ├── deno.mjs │ ├── index.cjs │ ├── index.d.ts │ ├── index.mjs │ ├── node.cjs │ └── node.mjs └── vite │ ├── index.cjs │ ├── index.d.ts │ └── index.mjs ├── middleware ├── aws-lambda.d.ts ├── azure-swa.d.ts ├── bun.d.ts ├── cloudflare-pages.d.ts ├── deno.d.ts ├── firebase.d.ts ├── netlify-edge.d.ts ├── node.d.ts ├── request-handler.d.ts └── vercel-edge.d.ts ├── modules.d.ts ├── package.json ├── service-worker.d.ts ├── static.d.ts ├── tsconfig.json └── vite.d.ts /.npmignore: -------------------------------------------------------------------------------- 1 | adapters 2 | buildtime 3 | middleware 4 | runtime 5 | service-worker 6 | static 7 | utils 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @builder.io/qwik-city 2 | 3 | ## 1.14.1 4 | 5 | ## 1.14.0 6 | 7 | ### Minor Changes 8 | 9 | - 🐞🩹 qwik-city no longer forces `q-data.json` downloads, instead relying on the cache headers. This means that you have to make sure your `q-data.json` is served with `Cache-Control` headers that suit you. That file contains all the information about the route and is read for each qwik-city navigation. By default the data is cached for one hour. (by [@wmertens](https://github.com/wmertens) in [#7537](https://github.com/QwikDev/qwik/pull/7537)) 10 | 11 | - 🛠 the service workers have been deprecated and replaced with entries that unregister them. If you have it enabled in production, you can remove it after a while once you are sure all your users have the new version. (by [@wmertens](https://github.com/wmertens) in [#7453](https://github.com/QwikDev/qwik/pull/7453)) 12 | 13 | ### Patch Changes 14 | 15 | - 🐞🩹 linting errors which were previously being ignored across the monorepo. (by [@better-salmon](https://github.com/better-salmon) in [#7418](https://github.com/QwikDev/qwik/pull/7418)) 16 | 17 | - 🐞🩹 Link SPA subsequent navigation now properly prefetch the next routes. (by [@maiieul](https://github.com/maiieul) in [#7590](https://github.com/QwikDev/qwik/pull/7590)) 18 | 19 | - 🐞🩹 SPA Link now handle subsequent onQVisible$ passed as props. (by [@maiieul](https://github.com/maiieul) in [#7612](https://github.com/QwikDev/qwik/pull/7612)) 20 | 21 | ## 1.13.0 22 | 23 | ### Minor Changes 24 | 25 | - 🐞🩹 server$ errors can be caught by @plugin middleware (by [@DustinJSilk](https://github.com/DustinJSilk) in [#7185](https://github.com/QwikDev/qwik/pull/7185)) 26 | 27 | - refactor: Error types are standardised across server$ functions and routeLoaders (by [@DustinJSilk](https://github.com/DustinJSilk) in [#7185](https://github.com/QwikDev/qwik/pull/7185)) 28 | 29 | - ✨ 499 is now a valid status code (by [@DustinJSilk](https://github.com/DustinJSilk) in [#7185](https://github.com/QwikDev/qwik/pull/7185)) 30 | 31 | - 🐞🩹 server$ functions now correctly throw 4xx errors on the client (by [@DustinJSilk](https://github.com/DustinJSilk) in [#7185](https://github.com/QwikDev/qwik/pull/7185)) 32 | 33 | ### Patch Changes 34 | 35 | - 🐞🩹 Error boundary `ErrorBoundary` and fix `useErrorBoundary` (by [@damianpumar](https://github.com/damianpumar) in [#7342](https://github.com/QwikDev/qwik/pull/7342)) 36 | 37 | - 🐞🩹 Write Response object in the send request event even on redirects (by [@nelsonprsousa](https://github.com/nelsonprsousa) in [#7422](https://github.com/QwikDev/qwik/pull/7422)) 38 | 39 | ## 1.12.1 40 | 41 | ### Patch Changes 42 | 43 | - 🐞🩹 MDX content now accepts a prop of type `components` that lets you use your own custom components (by [@double-thinker](https://github.com/double-thinker) in [#7277](https://github.com/QwikDev/qwik/pull/7277)) 44 | 45 | To add custom components to your MDX content, you can now do this: 46 | 47 | ```tsx 48 | // routes/example/index.tsx 49 | import Content from './markdown.mdx'; 50 | import MyComponent from '../../components/my-component/my-component'; 51 | import { component$ } from '@builder.io/qwik'; 52 | 53 | export default component$(() => ); 54 | ``` 55 | 56 | You can also use props in JS expressions. See https://mdxjs.com/docs/using-mdx/#props 57 | 58 | - 🐞🩹 mdx not rendering (by [@shairez](https://github.com/shairez) in [#7168](https://github.com/QwikDev/qwik/pull/7168)) 59 | 60 | - 📃 added a "Qwik for Mobile" guide to build iOS and Android Qwik apps (by [@srapport](https://github.com/srapport) in [#7205](https://github.com/QwikDev/qwik/pull/7205)) 61 | 62 | - 🐞🩹 some qrls weren't fetched correctly on page load (by [@shairez](https://github.com/shairez) in [#7286](https://github.com/QwikDev/qwik/pull/7286)) 63 | 64 | ## 1.12.0 65 | 66 | ### Patch Changes 67 | 68 | - 🐞🩹 the previous URL now is undefined on first render. (by [@damianpumar](https://github.com/damianpumar) in [#7082](https://github.com/QwikDev/qwik/pull/7082)) 69 | 70 | - 🐞🩹 server$ functions now correctly throw errors for > 500 error codes (by [@DustinJSilk](https://github.com/DustinJSilk) in [#7078](https://github.com/QwikDev/qwik/pull/7078)) 71 | 72 | ## 1.11.0 73 | 74 | ## 1.10.0 75 | 76 | ### Patch Changes 77 | 78 | - 🐞🩹 MDX content no longer ignores Layout components. See [the MDX docs](https://mdxjs.com/docs/using-mdx/#layout) for more information. (by [@danielvaijk](https://github.com/danielvaijk) in [#6845](https://github.com/QwikDev/qwik/pull/6845)) 79 | 80 | - 🐞🩹 SSG errors now show the path that failed (by [@wmertens](https://github.com/wmertens) in [#6998](https://github.com/QwikDev/qwik/pull/6998)) 81 | 82 | - 🐞🩹 Fixed action redirect regression where searchParams were appended (by [@brandonpittman](https://github.com/brandonpittman) in [#6927](https://github.com/QwikDev/qwik/pull/6927)) 83 | 84 | - 🐞🩹 Redirect, error, and fail request events no longer forcefully delete user-defined Cache-Control HTTP header value. (by [@nelsonprsousa](https://github.com/nelsonprsousa) in [#6991](https://github.com/QwikDev/qwik/pull/6991)) 85 | 86 | - 🐞🩹 `vite` is now a peer dependency of `qwik`, `qwik-city`, `qwik-react` and `qwik-labs`, so that there can be no duplicate imports. This should not have consequences, since all apps also directly depend on `vite`. (by [@wmertens](https://github.com/wmertens) in [#6945](https://github.com/QwikDev/qwik/pull/6945)) 87 | 88 | - 🐞🩹 Fixed MDX layout default export being ignored by transformer. (by [@danielvaijk](https://github.com/danielvaijk) in [#6845](https://github.com/QwikDev/qwik/pull/6845)) 89 | 90 | - 🐞🩹 Prevent unexpected caching for q-data.json (by [@genki](https://github.com/genki) in [#6808](https://github.com/QwikDev/qwik/pull/6808)) 91 | 92 | - 🐞🩹 Multiple rewrite routes pointing to the same route is no longer an error. (by [@JerryWu1234](https://github.com/JerryWu1234) in [#6970](https://github.com/QwikDev/qwik/pull/6970)) 93 | 94 | ## 1.9.1 95 | 96 | ### Patch Changes 97 | 98 | - ✨ Experimental feature - `noSPA`. (by [@wmertens](https://github.com/wmertens) in [#6937](https://github.com/QwikDev/qwik/pull/6937)) 99 | This disables history patching, slightly reducing code size and startup time. Use this when your application is MPA only, meaning you don't use the Link component. To enable this, add it to the `experimental` array of the `qwikVite` plugin (not the `qwikCity` plugin). 100 | 101 | ## 1.9.0 102 | 103 | ### Minor Changes 104 | 105 | - ✨ **(EXPERIMENTAL)** valibot$ validator and a fix for zod$ types. (by [@fabian-hiller](https://github.com/fabian-hiller) in [#6752](https://github.com/QwikDev/qwik/pull/6752)) 106 | 107 | To use it, you need to pass `experimental: ['valibot']` as an option to the `qwikVite` plugin as such: 108 | 109 | ```ts 110 | // vite.config.ts 111 | 112 | export default defineConfig(({ command, mode }): UserConfig => { 113 | return { 114 | plugins: [ 115 | // ... other plugins like qwikCity() etc 116 | qwikVite({ 117 | experimental: ['valibot'] 118 | // ... other options 119 | }), 120 | 121 | ], 122 | // ... rest of the config 123 | }; 124 | } 125 | 126 | ``` 127 | 128 | - ✨ **(EXPERIMENTAL)** `usePreventNavigate` lets you prevent navigation while your app's state is unsaved. It works asynchronously for SPA navigation and falls back to the browser's default dialogs for other navigations. To use it, add `experimental: ['preventNavigate']` to your `qwikVite` options. (by [@wmertens](https://github.com/wmertens) in [#6825](https://github.com/QwikDev/qwik/pull/6825)) 129 | 130 | ### Patch Changes 131 | 132 | - 🐞🩹 added .ico to be detected by isStaticFile (by [@intellix](https://github.com/intellix) in [#6860](https://github.com/QwikDev/qwik/pull/6860)) 133 | 134 | - 🐞🩹 fixed delays caused from inefficient Service Worker prefetching (buffering) (by [@shairez](https://github.com/shairez) in [#6863](https://github.com/QwikDev/qwik/pull/6863)) 135 | 136 | ## 1.8.0 137 | 138 | ## 1.7.3 139 | 140 | ## 1.7.2 141 | 142 | ### Patch Changes 143 | 144 | - - built files are now under dist/ or lib/. All tools that respect package export maps should just work. (by [@wmertens](https://github.com/wmertens) in [#6715](https://github.com/QwikDev/qwik/pull/6715)) 145 | If you have trouble with Typescript, ensure that you use `moduleResolution: "Bundler"` in your `tsconfig.json`. 146 | - `@builder.io/qwik` no longer depends on `undici` 147 | 148 | - During dev mode, qwik-city will no longer serve files from `dist/`, which are very likely to be stale/incorrect. Furthermore, query parameters are taken into account when serving files (like production servers would do). (by [@wmertens](https://github.com/wmertens) in [#6694](https://github.com/QwikDev/qwik/pull/6694)) 149 | 150 | - qwik-city is now more careful about redirects after requesting routeLoader data (by [@wmertens](https://github.com/wmertens) in [#6740](https://github.com/QwikDev/qwik/pull/6740)) 151 | 152 | - strip internal search parameters in canonical URLs (by [@wmertens](https://github.com/wmertens) in [#6694](https://github.com/QwikDev/qwik/pull/6694)) 153 | 154 | - Support entry.ts routes in dev mode now that dist/ is no longer served, and special-case `repl-sw.js` in the docs. (by [@wmertens](https://github.com/wmertens) in [#6706](https://github.com/QwikDev/qwik/pull/6706)) 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Continuous Build Artifacts 2 | 3 | This repo contains build artifacts that are generated as part of the continues build pipeline. 4 | 5 | Currently supported artifacts: 6 | 7 | - [`@builder.io/qwik`](https://github.com/QwikDev/qwik-build) 8 | - [`@builder.io/qwik-city`](https://github.com/QwikDev/qwik-city-build) 9 | - [`@builder.io/qwik-labs`](https://github.com/QwikDev/qwik-labs-build) 10 | 11 | The build artifact is created if: 12 | 13 | - Code is merged to `main` branch 14 | - Code is merged to `build/*` branch 15 | 16 | ## How to use 17 | 18 | The build artifacts are useful if you want to: 19 | 20 | - Install an un-released change. 21 | - Bisect which specific commit caused a regression. 22 | 23 | ## Install specific build artifact 24 | 25 | To install a specific build artifact change you `package.json` like so (not all lines may be needed): 26 | 27 | ```json 28 | { 29 | "dependencies": { 30 | "@builder.io/qwik": "github:QwikDev/qwik-build#SHA", 31 | "@builder.io/qwik-city": "github:QwikDev/qwik-city-build#SHA", 32 | "@builder.io/qwik-labs": "github:QwikDev/qwik-labs-build#SHA" 33 | } 34 | } 35 | ``` 36 | 37 | Where `#SHA` is one of the following: 38 | 39 | - `#SHA` - Install a specific build SHA. You can get the SHA from: 40 | - [`@builder.io/qwik`](https://github.com/QwikDev/qwik-build/commits/) commits 41 | - [`@builder.io/qwik-city`](https://github.com/QwikDev/qwik-city-build/commits/) commits 42 | - [`@builder.io/qwik-labs`](https://github.com/QwikDev/qwik-labs-build/commits/) commits 43 | - `#build/name` (or `#main`) - Install a specific `build/*` (or `#main`) branch: 44 | - [`@builder.io/qwik`](https://github.com/QwikDev/qwik-build/branches/) branches 45 | - [`@builder.io/qwik-city`](https://github.com/QwikDev/qwik-city-build/branches/) branches 46 | - [`@builder.io/qwik-labs`](https://github.com/QwikDev/qwik-labs-build/branches/) branches 47 | > NOTE: Package managers will treat any SHA in the lock file which is on the branch as valid, and so they will not auto upgrade to the latest. For this reason this is not recommended. 48 | 49 | ## Bisect for regression 50 | 51 | You can bisect different commits to `main` to determine which specific change has cause the regression. 52 | 53 | 1. Install latest to get an upper mound 54 | 2. Install oldest known good to get a lower bound 55 | 3. Keep bisecting until you find a specific SHA where the code breaks. 56 | 57 | When creating the issue please include which SHA has caused the regression. 58 | -------------------------------------------------------------------------------- /adapters/azure-swa/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/azure-swa/vite'; 3 | -------------------------------------------------------------------------------- /adapters/bun-server/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/bun-server/vite'; 3 | -------------------------------------------------------------------------------- /adapters/cloud-run/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/cloud-run/vite'; 3 | -------------------------------------------------------------------------------- /adapters/cloudflare-pages/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/cloudflare-pages/vite'; 3 | -------------------------------------------------------------------------------- /adapters/deno-server/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/deno-server/vite'; 3 | -------------------------------------------------------------------------------- /adapters/netlify-edge/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/netlify-edge/vite'; 3 | -------------------------------------------------------------------------------- /adapters/node-server/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/node-server/vite'; 3 | -------------------------------------------------------------------------------- /adapters/shared/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/shared/vite'; 3 | -------------------------------------------------------------------------------- /adapters/static/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/static/vite'; 3 | -------------------------------------------------------------------------------- /adapters/vercel-edge/vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../../lib/adapters/vercel-edge/vite'; 3 | -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-var */ 2 | // Globals used by qwik-city, for internal use only 3 | 4 | type RequestEventInternal = 5 | import('./middleware/request-handler/request-event').RequestEventInternal; 6 | type AsyncStore = import('node:async_hooks').AsyncLocalStorage; 7 | 8 | /** @deprecated Remove this in v2 */ 9 | declare var QWIK_MANIFEST: import('@builder.io/qwik/optimizer').QwikManifest | undefined | null; 10 | 11 | declare var qcAsyncRequestStore: AsyncStore | undefined; 12 | declare var _qwikActionsMap: Map | undefined; 13 | declare var __qwikCityNew: boolean | undefined; 14 | 15 | type ExperimentalFeatures = import('@builder.io/qwik/optimizer').ExperimentalFeatures; 16 | 17 | declare var __EXPERIMENTAL__: { 18 | [K in ExperimentalFeatures]: boolean; 19 | }; 20 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from './lib'; 3 | -------------------------------------------------------------------------------- /lib/adapters/azure-swa/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/adapters/azure-swa/vite/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | azureSwaAdapter: () => azureSwaAdapter 34 | }); 35 | module.exports = __toCommonJS(index_exports); 36 | var import_vite = require("../../shared/vite/index.cjs"); 37 | var import_node_path = require("node:path"); 38 | var import_node_fs = __toESM(require("node:fs"), 1); 39 | function azureSwaAdapter(opts = {}) { 40 | const env = process == null ? void 0 : process.env; 41 | return (0, import_vite.viteAdapter)({ 42 | name: "azure-swa", 43 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.region.2.azurestaticapps.net", 44 | ssg: opts.ssg, 45 | cleanStaticGenerated: true, 46 | async generate({ outputEntries, serverOutDir, clientPublicOutDir }) { 47 | const serverPackageJsonPath = (0, import_node_path.join)(serverOutDir, "package.json"); 48 | const serverPackageJsonCode = `{"type":"module"}`; 49 | await import_node_fs.default.promises.mkdir(serverOutDir, { recursive: true }); 50 | await import_node_fs.default.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode); 51 | const azureSwaModulePath = outputEntries.find( 52 | (entryName) => entryName.indexOf("entry.azure-swa") === 0 53 | ); 54 | const funcJsonPath = (0, import_node_path.join)(serverOutDir, "function.json"); 55 | const funcJson = JSON.stringify( 56 | { 57 | bindings: [ 58 | { 59 | authLevel: "anonymous", 60 | type: "httpTrigger", 61 | direction: "in", 62 | name: "req", 63 | methods: [ 64 | "get", 65 | "head", 66 | "post", 67 | "put", 68 | "delete", 69 | "connect", 70 | "options", 71 | "trace", 72 | "patch" 73 | ] 74 | }, 75 | { 76 | type: "http", 77 | direction: "out", 78 | name: "$return" 79 | } 80 | ], 81 | scriptFile: azureSwaModulePath 82 | }, 83 | null, 84 | 2 85 | ); 86 | await import_node_fs.default.promises.writeFile(funcJsonPath, funcJson); 87 | if (!import_node_fs.default.existsSync((0, import_node_path.join)(clientPublicOutDir, "index.html"))) { 88 | await import_node_fs.default.promises.writeFile((0, import_node_path.join)(clientPublicOutDir, "index.html"), ""); 89 | } 90 | } 91 | }); 92 | } 93 | // Annotate the CommonJS export names for ESM import in node: 94 | 0 && (module.exports = { 95 | azureSwaAdapter 96 | }); 97 | -------------------------------------------------------------------------------- /lib/adapters/azure-swa/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @public */ 5 | export declare function azureSwaAdapter(opts?: AzureSwaAdapterOptions): any; 6 | 7 | /** @public */ 8 | export declare interface AzureSwaAdapterOptions extends ServerAdapterOptions { 9 | } 10 | 11 | export { StaticGenerateRenderOptions } 12 | 13 | export { } 14 | -------------------------------------------------------------------------------- /lib/adapters/azure-swa/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/azure-swa/vite/index.ts 2 | import { viteAdapter } from "../../shared/vite/index.mjs"; 3 | import { join } from "node:path"; 4 | import fs from "node:fs"; 5 | function azureSwaAdapter(opts = {}) { 6 | const env = process == null ? void 0 : process.env; 7 | return viteAdapter({ 8 | name: "azure-swa", 9 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.region.2.azurestaticapps.net", 10 | ssg: opts.ssg, 11 | cleanStaticGenerated: true, 12 | async generate({ outputEntries, serverOutDir, clientPublicOutDir }) { 13 | const serverPackageJsonPath = join(serverOutDir, "package.json"); 14 | const serverPackageJsonCode = `{"type":"module"}`; 15 | await fs.promises.mkdir(serverOutDir, { recursive: true }); 16 | await fs.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode); 17 | const azureSwaModulePath = outputEntries.find( 18 | (entryName) => entryName.indexOf("entry.azure-swa") === 0 19 | ); 20 | const funcJsonPath = join(serverOutDir, "function.json"); 21 | const funcJson = JSON.stringify( 22 | { 23 | bindings: [ 24 | { 25 | authLevel: "anonymous", 26 | type: "httpTrigger", 27 | direction: "in", 28 | name: "req", 29 | methods: [ 30 | "get", 31 | "head", 32 | "post", 33 | "put", 34 | "delete", 35 | "connect", 36 | "options", 37 | "trace", 38 | "patch" 39 | ] 40 | }, 41 | { 42 | type: "http", 43 | direction: "out", 44 | name: "$return" 45 | } 46 | ], 47 | scriptFile: azureSwaModulePath 48 | }, 49 | null, 50 | 2 51 | ); 52 | await fs.promises.writeFile(funcJsonPath, funcJson); 53 | if (!fs.existsSync(join(clientPublicOutDir, "index.html"))) { 54 | await fs.promises.writeFile(join(clientPublicOutDir, "index.html"), ""); 55 | } 56 | } 57 | }); 58 | } 59 | export { 60 | azureSwaAdapter 61 | }; 62 | -------------------------------------------------------------------------------- /lib/adapters/bun-server/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // packages/qwik-city/src/adapters/bun-server/vite/index.ts 21 | var index_exports = {}; 22 | __export(index_exports, { 23 | bunServerAdapter: () => bunServerAdapter 24 | }); 25 | module.exports = __toCommonJS(index_exports); 26 | var import_vite = require("../../shared/vite/index.cjs"); 27 | function bunServerAdapter(opts = {}) { 28 | const env = process == null ? void 0 : process.env; 29 | return (0, import_vite.viteAdapter)({ 30 | name: opts.name || "bun-server", 31 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.qwik.dev", 32 | ssg: opts.ssg, 33 | cleanStaticGenerated: true, 34 | config() { 35 | return { 36 | ssr: { 37 | target: "node" 38 | }, 39 | build: { 40 | ssr: true 41 | }, 42 | publicDir: false 43 | }; 44 | } 45 | }); 46 | } 47 | // Annotate the CommonJS export names for ESM import in node: 48 | 0 && (module.exports = { 49 | bunServerAdapter 50 | }); 51 | -------------------------------------------------------------------------------- /lib/adapters/bun-server/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @alpha */ 5 | export declare function bunServerAdapter(opts?: bunServerAdapterOptions): any; 6 | 7 | /** @alpha */ 8 | export declare interface bunServerAdapterOptions extends ServerAdapterOptions { 9 | name?: string; 10 | } 11 | 12 | export { StaticGenerateRenderOptions } 13 | 14 | export { } 15 | -------------------------------------------------------------------------------- /lib/adapters/bun-server/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/bun-server/vite/index.ts 2 | import { viteAdapter } from "../../shared/vite/index.mjs"; 3 | function bunServerAdapter(opts = {}) { 4 | const env = process == null ? void 0 : process.env; 5 | return viteAdapter({ 6 | name: opts.name || "bun-server", 7 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.qwik.dev", 8 | ssg: opts.ssg, 9 | cleanStaticGenerated: true, 10 | config() { 11 | return { 12 | ssr: { 13 | target: "node" 14 | }, 15 | build: { 16 | ssr: true 17 | }, 18 | publicDir: false 19 | }; 20 | } 21 | }); 22 | } 23 | export { 24 | bunServerAdapter 25 | }; 26 | -------------------------------------------------------------------------------- /lib/adapters/cloud-run/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // packages/qwik-city/src/adapters/cloud-run/vite/index.ts 21 | var index_exports = {}; 22 | __export(index_exports, { 23 | cloudRunAdapter: () => cloudRunAdapter 24 | }); 25 | module.exports = __toCommonJS(index_exports); 26 | var import_vite = require("../../shared/vite/index.cjs"); 27 | function cloudRunAdapter(opts = {}) { 28 | const env = process == null ? void 0 : process.env; 29 | return (0, import_vite.viteAdapter)({ 30 | name: "cloud-run", 31 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://your-app-name.run.app", 32 | ssg: opts.ssg, 33 | cleanStaticGenerated: true, 34 | config() { 35 | return { 36 | build: { 37 | ssr: true 38 | }, 39 | publicDir: false 40 | }; 41 | } 42 | }); 43 | } 44 | // Annotate the CommonJS export names for ESM import in node: 45 | 0 && (module.exports = { 46 | cloudRunAdapter 47 | }); 48 | -------------------------------------------------------------------------------- /lib/adapters/cloud-run/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @public */ 5 | export declare function cloudRunAdapter(opts?: CloudRunAdapterOptions): any; 6 | 7 | /** @public */ 8 | export declare interface CloudRunAdapterOptions extends ServerAdapterOptions { 9 | } 10 | 11 | export { StaticGenerateRenderOptions } 12 | 13 | export { } 14 | -------------------------------------------------------------------------------- /lib/adapters/cloud-run/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/cloud-run/vite/index.ts 2 | import { viteAdapter } from "../../shared/vite/index.mjs"; 3 | function cloudRunAdapter(opts = {}) { 4 | const env = process == null ? void 0 : process.env; 5 | return viteAdapter({ 6 | name: "cloud-run", 7 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://your-app-name.run.app", 8 | ssg: opts.ssg, 9 | cleanStaticGenerated: true, 10 | config() { 11 | return { 12 | build: { 13 | ssr: true 14 | }, 15 | publicDir: false 16 | }; 17 | } 18 | }); 19 | } 20 | export { 21 | cloudRunAdapter 22 | }; 23 | -------------------------------------------------------------------------------- /lib/adapters/cloudflare-pages/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/adapters/cloudflare-pages/vite/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | cloudflarePagesAdapter: () => cloudflarePagesAdapter 34 | }); 35 | module.exports = __toCommonJS(index_exports); 36 | var import_vite = require("../../shared/vite/index.cjs"); 37 | var import_node_fs = __toESM(require("node:fs"), 1); 38 | var import_node_path = require("node:path"); 39 | 40 | // packages/qwik-city/src/utils/fs.ts 41 | function normalizePathSlash(path) { 42 | const isExtendedLengthPath = /^\\\\\?\\/.test(path); 43 | const hasNonAscii = /[^\u0000-\u0080]+/.test(path); 44 | if (isExtendedLengthPath || hasNonAscii) { 45 | return path; 46 | } 47 | path = path.replace(/\\/g, "/"); 48 | if (path.endsWith("/")) { 49 | path = path.slice(0, path.length - 1); 50 | } 51 | return path; 52 | } 53 | 54 | // packages/qwik-city/src/adapters/cloudflare-pages/vite/index.ts 55 | function cloudflarePagesAdapter(opts = {}) { 56 | const env = process == null ? void 0 : process.env; 57 | return (0, import_vite.viteAdapter)({ 58 | name: "cloudflare-pages", 59 | origin: (env == null ? void 0 : env.CF_PAGES_URL) ?? (env == null ? void 0 : env.ORIGIN) ?? "https://your.cloudflare.pages.dev", 60 | ssg: opts.ssg, 61 | staticPaths: opts.staticPaths, 62 | cleanStaticGenerated: true, 63 | config() { 64 | return { 65 | resolve: { 66 | conditions: ["webworker", "worker"] 67 | }, 68 | ssr: { 69 | target: "webworker", 70 | noExternal: true, 71 | external: ["node:async_hooks"] 72 | }, 73 | build: { 74 | ssr: true, 75 | rollupOptions: { 76 | output: { 77 | format: "es", 78 | hoistTransitiveImports: false 79 | } 80 | } 81 | }, 82 | publicDir: false 83 | }; 84 | }, 85 | async generate({ clientOutDir, serverOutDir, basePathname, assetsDir }) { 86 | const routesJsonPath = (0, import_node_path.join)(clientOutDir, "_routes.json"); 87 | const hasRoutesJson = import_node_fs.default.existsSync(routesJsonPath); 88 | if (!hasRoutesJson && opts.functionRoutes !== false) { 89 | let pathName = assetsDir ? (0, import_node_path.join)(basePathname, assetsDir) : basePathname; 90 | if (!pathName.endsWith("/")) { 91 | pathName += "/"; 92 | } 93 | const routesJson = { 94 | version: 1, 95 | include: [basePathname + "*"], 96 | exclude: [pathName + "build/*", pathName + "assets/*"] 97 | }; 98 | await import_node_fs.default.promises.writeFile(routesJsonPath, JSON.stringify(routesJson, void 0, 2)); 99 | } 100 | const workerJsPath = (0, import_node_path.join)(clientOutDir, "_worker.js"); 101 | const hasWorkerJs = import_node_fs.default.existsSync(workerJsPath); 102 | if (!hasWorkerJs) { 103 | const importPath = (0, import_node_path.relative)(clientOutDir, (0, import_node_path.join)(serverOutDir, "entry.cloudflare-pages")); 104 | await import_node_fs.default.promises.writeFile( 105 | workerJsPath, 106 | `import { fetch } from "${normalizePathSlash(importPath)}"; export default { fetch };` 107 | ); 108 | } 109 | } 110 | }); 111 | } 112 | // Annotate the CommonJS export names for ESM import in node: 113 | 0 && (module.exports = { 114 | cloudflarePagesAdapter 115 | }); 116 | -------------------------------------------------------------------------------- /lib/adapters/cloudflare-pages/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @public */ 5 | export declare function cloudflarePagesAdapter(opts?: CloudflarePagesAdapterOptions): any; 6 | 7 | /** @public */ 8 | export declare interface CloudflarePagesAdapterOptions extends ServerAdapterOptions { 9 | /** 10 | * Determines if the build should generate the function invocation routes `_routes.json` file. 11 | * 12 | * https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes 13 | * 14 | * Defaults to `true`. 15 | */ 16 | functionRoutes?: boolean; 17 | /** 18 | * Manually add pathnames that should be treated as static paths and not SSR. For example, when 19 | * these pathnames are requested, their response should come from a static file, rather than a 20 | * server-side rendered response. 21 | */ 22 | staticPaths?: string[]; 23 | } 24 | 25 | export { StaticGenerateRenderOptions } 26 | 27 | export { } 28 | -------------------------------------------------------------------------------- /lib/adapters/cloudflare-pages/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/cloudflare-pages/vite/index.ts 2 | import { viteAdapter } from "../../shared/vite/index.mjs"; 3 | import fs from "node:fs"; 4 | import { join, relative } from "node:path"; 5 | 6 | // packages/qwik-city/src/utils/fs.ts 7 | function normalizePathSlash(path) { 8 | const isExtendedLengthPath = /^\\\\\?\\/.test(path); 9 | const hasNonAscii = /[^\u0000-\u0080]+/.test(path); 10 | if (isExtendedLengthPath || hasNonAscii) { 11 | return path; 12 | } 13 | path = path.replace(/\\/g, "/"); 14 | if (path.endsWith("/")) { 15 | path = path.slice(0, path.length - 1); 16 | } 17 | return path; 18 | } 19 | 20 | // packages/qwik-city/src/adapters/cloudflare-pages/vite/index.ts 21 | function cloudflarePagesAdapter(opts = {}) { 22 | const env = process == null ? void 0 : process.env; 23 | return viteAdapter({ 24 | name: "cloudflare-pages", 25 | origin: (env == null ? void 0 : env.CF_PAGES_URL) ?? (env == null ? void 0 : env.ORIGIN) ?? "https://your.cloudflare.pages.dev", 26 | ssg: opts.ssg, 27 | staticPaths: opts.staticPaths, 28 | cleanStaticGenerated: true, 29 | config() { 30 | return { 31 | resolve: { 32 | conditions: ["webworker", "worker"] 33 | }, 34 | ssr: { 35 | target: "webworker", 36 | noExternal: true, 37 | external: ["node:async_hooks"] 38 | }, 39 | build: { 40 | ssr: true, 41 | rollupOptions: { 42 | output: { 43 | format: "es", 44 | hoistTransitiveImports: false 45 | } 46 | } 47 | }, 48 | publicDir: false 49 | }; 50 | }, 51 | async generate({ clientOutDir, serverOutDir, basePathname, assetsDir }) { 52 | const routesJsonPath = join(clientOutDir, "_routes.json"); 53 | const hasRoutesJson = fs.existsSync(routesJsonPath); 54 | if (!hasRoutesJson && opts.functionRoutes !== false) { 55 | let pathName = assetsDir ? join(basePathname, assetsDir) : basePathname; 56 | if (!pathName.endsWith("/")) { 57 | pathName += "/"; 58 | } 59 | const routesJson = { 60 | version: 1, 61 | include: [basePathname + "*"], 62 | exclude: [pathName + "build/*", pathName + "assets/*"] 63 | }; 64 | await fs.promises.writeFile(routesJsonPath, JSON.stringify(routesJson, void 0, 2)); 65 | } 66 | const workerJsPath = join(clientOutDir, "_worker.js"); 67 | const hasWorkerJs = fs.existsSync(workerJsPath); 68 | if (!hasWorkerJs) { 69 | const importPath = relative(clientOutDir, join(serverOutDir, "entry.cloudflare-pages")); 70 | await fs.promises.writeFile( 71 | workerJsPath, 72 | `import { fetch } from "${normalizePathSlash(importPath)}"; export default { fetch };` 73 | ); 74 | } 75 | } 76 | }); 77 | } 78 | export { 79 | cloudflarePagesAdapter 80 | }; 81 | -------------------------------------------------------------------------------- /lib/adapters/deno-server/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // packages/qwik-city/src/adapters/deno-server/vite/index.ts 21 | var index_exports = {}; 22 | __export(index_exports, { 23 | denoServerAdapter: () => denoServerAdapter 24 | }); 25 | module.exports = __toCommonJS(index_exports); 26 | var import_vite = require("../../shared/vite/index.cjs"); 27 | function denoServerAdapter(opts = {}) { 28 | const env = process == null ? void 0 : process.env; 29 | return (0, import_vite.viteAdapter)({ 30 | name: opts.name || "deno-server", 31 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.qwik.dev", 32 | ssg: opts.ssg, 33 | cleanStaticGenerated: true, 34 | config() { 35 | return { 36 | resolve: { 37 | conditions: ["webworker", "worker"] 38 | }, 39 | ssr: { 40 | target: "webworker", 41 | noExternal: true, 42 | external: ["node:async_hooks"] 43 | }, 44 | build: { 45 | ssr: true, 46 | target: "esnext", 47 | rollupOptions: { 48 | output: { 49 | format: "es", 50 | hoistTransitiveImports: false 51 | } 52 | } 53 | }, 54 | publicDir: false 55 | }; 56 | } 57 | }); 58 | } 59 | // Annotate the CommonJS export names for ESM import in node: 60 | 0 && (module.exports = { 61 | denoServerAdapter 62 | }); 63 | -------------------------------------------------------------------------------- /lib/adapters/deno-server/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @alpha */ 5 | export declare function denoServerAdapter(opts?: DenoServerAdapterOptions): any; 6 | 7 | /** @alpha */ 8 | export declare interface DenoServerAdapterOptions extends ServerAdapterOptions { 9 | name?: string; 10 | } 11 | 12 | export { StaticGenerateRenderOptions } 13 | 14 | export { } 15 | -------------------------------------------------------------------------------- /lib/adapters/deno-server/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/deno-server/vite/index.ts 2 | import { viteAdapter } from "../../shared/vite/index.mjs"; 3 | function denoServerAdapter(opts = {}) { 4 | const env = process == null ? void 0 : process.env; 5 | return viteAdapter({ 6 | name: opts.name || "deno-server", 7 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.qwik.dev", 8 | ssg: opts.ssg, 9 | cleanStaticGenerated: true, 10 | config() { 11 | return { 12 | resolve: { 13 | conditions: ["webworker", "worker"] 14 | }, 15 | ssr: { 16 | target: "webworker", 17 | noExternal: true, 18 | external: ["node:async_hooks"] 19 | }, 20 | build: { 21 | ssr: true, 22 | target: "esnext", 23 | rollupOptions: { 24 | output: { 25 | format: "es", 26 | hoistTransitiveImports: false 27 | } 28 | } 29 | }, 30 | publicDir: false 31 | }; 32 | } 33 | }); 34 | } 35 | export { 36 | denoServerAdapter 37 | }; 38 | -------------------------------------------------------------------------------- /lib/adapters/netlify-edge/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/adapters/netlify-edge/vite/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | netlifyEdgeAdapter: () => netlifyEdgeAdapter 34 | }); 35 | module.exports = __toCommonJS(index_exports); 36 | var import_vite = require("../../shared/vite/index.cjs"); 37 | var import_node_fs = __toESM(require("node:fs"), 1); 38 | var import_node_path = require("node:path"); 39 | 40 | // packages/qwik-city/src/runtime/src/qwik-city-plan.ts 41 | var basePathname = "/"; 42 | 43 | // packages/qwik-city/src/adapters/netlify-edge/vite/index.ts 44 | function netlifyEdgeAdapter(opts = {}) { 45 | const env = process == null ? void 0 : process.env; 46 | return (0, import_vite.viteAdapter)({ 47 | name: "netlify-edge", 48 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.netlify.app", 49 | ssg: opts.ssg, 50 | staticPaths: opts.staticPaths, 51 | cleanStaticGenerated: true, 52 | config(config) { 53 | var _a; 54 | const outDir = ((_a = config.build) == null ? void 0 : _a.outDir) || ".netlify/edge-functions/entry.netlify-edge"; 55 | return { 56 | resolve: { 57 | conditions: ["webworker", "worker"] 58 | }, 59 | ssr: { 60 | target: "webworker", 61 | noExternal: true, 62 | external: ["node:async_hooks"] 63 | }, 64 | build: { 65 | ssr: true, 66 | outDir, 67 | rollupOptions: { 68 | output: { 69 | format: "es", 70 | hoistTransitiveImports: false 71 | } 72 | } 73 | }, 74 | publicDir: false 75 | }; 76 | }, 77 | async generate({ serverOutDir }) { 78 | if (opts.functionRoutes !== false) { 79 | const excludedPath = []; 80 | if (typeof opts.excludedPath === "string") { 81 | excludedPath.push(opts.excludedPath); 82 | } else if (Array.isArray(opts.excludedPath)) { 83 | excludedPath.push(...opts.excludedPath); 84 | } else { 85 | excludedPath.push( 86 | "/build/*", 87 | "/favicon.ico", 88 | "/robots.txt", 89 | "/mainifest.json", 90 | "/~partytown/*", 91 | "/service-worker.js", 92 | "/sitemap.xml" 93 | ); 94 | } 95 | const netlifyEdgeManifest = { 96 | functions: [ 97 | { 98 | path: basePathname + "*", 99 | function: "entry.netlify-edge", 100 | cache: "manual", 101 | excludedPath 102 | } 103 | ], 104 | version: 1 105 | }; 106 | const jsPath = (0, import_node_path.join)(serverOutDir, "entry.netlify-edge.js"); 107 | const mjsPath = (0, import_node_path.join)(serverOutDir, "entry.netlify-edge.mjs"); 108 | if ((0, import_node_fs.existsSync)(mjsPath)) { 109 | await import_node_fs.default.promises.writeFile( 110 | jsPath, 111 | [ 112 | `import entry_netlifyEdge from './entry.netlify-edge.mjs';`, 113 | `export default entry_netlifyEdge;` 114 | ].join("\n") 115 | ); 116 | } 117 | const netlifyEdgeFnsDir = (0, import_vite.getParentDir)(serverOutDir, "edge-functions"); 118 | await import_node_fs.default.promises.writeFile( 119 | (0, import_node_path.join)(netlifyEdgeFnsDir, "manifest.json"), 120 | JSON.stringify(netlifyEdgeManifest, null, 2) 121 | ); 122 | } 123 | } 124 | }); 125 | } 126 | // Annotate the CommonJS export names for ESM import in node: 127 | 0 && (module.exports = { 128 | netlifyEdgeAdapter 129 | }); 130 | -------------------------------------------------------------------------------- /lib/adapters/netlify-edge/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @public */ 5 | export declare function netlifyEdgeAdapter(opts?: NetlifyEdgeAdapterOptions): any; 6 | 7 | /** @public */ 8 | export declare interface NetlifyEdgeAdapterOptions extends ServerAdapterOptions { 9 | /** 10 | * Determines if the build should generate the edge functions declarations `manifest.json` file. 11 | * 12 | * https://docs.netlify.com/edge-functions/declarations/ 13 | * 14 | * Defaults to `true`. 15 | */ 16 | functionRoutes?: boolean; 17 | /** 18 | * Manually add pathnames that should be treated as static paths and not SSR. For example, when 19 | * these pathnames are requested, their response should come from a static file, rather than a 20 | * server-side rendered response. 21 | */ 22 | staticPaths?: string[]; 23 | /** 24 | * Manually add path pattern that should be excluded from the edge function routes that are 25 | * created by the 'manifest.json' file. 26 | * 27 | * If not specified, the following paths are excluded by default: 28 | * 29 | * - /build/* 30 | * - /favicon.ico 31 | * - /robots.txt 32 | * - /mainifest.json 33 | * - /~partytown/* 34 | * - /service-worker.js 35 | * - /sitemap.xml 36 | * 37 | * https://docs.netlify.com/edge-functions/declarations/#declare-edge-functions-in-netlify-toml 38 | */ 39 | excludedPath?: string | string[]; 40 | } 41 | 42 | export { StaticGenerateRenderOptions } 43 | 44 | export { } 45 | -------------------------------------------------------------------------------- /lib/adapters/netlify-edge/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/netlify-edge/vite/index.ts 2 | import { getParentDir, viteAdapter } from "../../shared/vite/index.mjs"; 3 | import fs, { existsSync } from "node:fs"; 4 | import { join } from "node:path"; 5 | 6 | // packages/qwik-city/src/runtime/src/qwik-city-plan.ts 7 | var basePathname = "/"; 8 | 9 | // packages/qwik-city/src/adapters/netlify-edge/vite/index.ts 10 | function netlifyEdgeAdapter(opts = {}) { 11 | const env = process == null ? void 0 : process.env; 12 | return viteAdapter({ 13 | name: "netlify-edge", 14 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.netlify.app", 15 | ssg: opts.ssg, 16 | staticPaths: opts.staticPaths, 17 | cleanStaticGenerated: true, 18 | config(config) { 19 | var _a; 20 | const outDir = ((_a = config.build) == null ? void 0 : _a.outDir) || ".netlify/edge-functions/entry.netlify-edge"; 21 | return { 22 | resolve: { 23 | conditions: ["webworker", "worker"] 24 | }, 25 | ssr: { 26 | target: "webworker", 27 | noExternal: true, 28 | external: ["node:async_hooks"] 29 | }, 30 | build: { 31 | ssr: true, 32 | outDir, 33 | rollupOptions: { 34 | output: { 35 | format: "es", 36 | hoistTransitiveImports: false 37 | } 38 | } 39 | }, 40 | publicDir: false 41 | }; 42 | }, 43 | async generate({ serverOutDir }) { 44 | if (opts.functionRoutes !== false) { 45 | const excludedPath = []; 46 | if (typeof opts.excludedPath === "string") { 47 | excludedPath.push(opts.excludedPath); 48 | } else if (Array.isArray(opts.excludedPath)) { 49 | excludedPath.push(...opts.excludedPath); 50 | } else { 51 | excludedPath.push( 52 | "/build/*", 53 | "/favicon.ico", 54 | "/robots.txt", 55 | "/mainifest.json", 56 | "/~partytown/*", 57 | "/service-worker.js", 58 | "/sitemap.xml" 59 | ); 60 | } 61 | const netlifyEdgeManifest = { 62 | functions: [ 63 | { 64 | path: basePathname + "*", 65 | function: "entry.netlify-edge", 66 | cache: "manual", 67 | excludedPath 68 | } 69 | ], 70 | version: 1 71 | }; 72 | const jsPath = join(serverOutDir, "entry.netlify-edge.js"); 73 | const mjsPath = join(serverOutDir, "entry.netlify-edge.mjs"); 74 | if (existsSync(mjsPath)) { 75 | await fs.promises.writeFile( 76 | jsPath, 77 | [ 78 | `import entry_netlifyEdge from './entry.netlify-edge.mjs';`, 79 | `export default entry_netlifyEdge;` 80 | ].join("\n") 81 | ); 82 | } 83 | const netlifyEdgeFnsDir = getParentDir(serverOutDir, "edge-functions"); 84 | await fs.promises.writeFile( 85 | join(netlifyEdgeFnsDir, "manifest.json"), 86 | JSON.stringify(netlifyEdgeManifest, null, 2) 87 | ); 88 | } 89 | } 90 | }); 91 | } 92 | export { 93 | netlifyEdgeAdapter 94 | }; 95 | -------------------------------------------------------------------------------- /lib/adapters/node-server/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // packages/qwik-city/src/adapters/node-server/vite/index.ts 21 | var index_exports = {}; 22 | __export(index_exports, { 23 | nodeServerAdapter: () => nodeServerAdapter 24 | }); 25 | module.exports = __toCommonJS(index_exports); 26 | var import_vite = require("../../shared/vite/index.cjs"); 27 | function nodeServerAdapter(opts = {}) { 28 | const env = process == null ? void 0 : process.env; 29 | return (0, import_vite.viteAdapter)({ 30 | name: opts.name || "node-server", 31 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.qwik.dev", 32 | ssg: opts.ssg, 33 | cleanStaticGenerated: true, 34 | config() { 35 | return { 36 | ssr: { 37 | target: "node" 38 | }, 39 | build: { 40 | ssr: true 41 | }, 42 | publicDir: false 43 | }; 44 | } 45 | }); 46 | } 47 | // Annotate the CommonJS export names for ESM import in node: 48 | 0 && (module.exports = { 49 | nodeServerAdapter 50 | }); 51 | -------------------------------------------------------------------------------- /lib/adapters/node-server/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | /** @alpha */ 5 | export declare function nodeServerAdapter(opts?: NodeServerAdapterOptions): any; 6 | 7 | /** @alpha */ 8 | export declare interface NodeServerAdapterOptions extends ServerAdapterOptions { 9 | name?: string; 10 | } 11 | 12 | export { StaticGenerateRenderOptions } 13 | 14 | export { } 15 | -------------------------------------------------------------------------------- /lib/adapters/node-server/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/node-server/vite/index.ts 2 | import { viteAdapter } from "../../shared/vite/index.mjs"; 3 | function nodeServerAdapter(opts = {}) { 4 | const env = process == null ? void 0 : process.env; 5 | return viteAdapter({ 6 | name: opts.name || "node-server", 7 | origin: (env == null ? void 0 : env.ORIGIN) ?? (env == null ? void 0 : env.URL) ?? "https://yoursitename.qwik.dev", 8 | ssg: opts.ssg, 9 | cleanStaticGenerated: true, 10 | config() { 11 | return { 12 | ssr: { 13 | target: "node" 14 | }, 15 | build: { 16 | ssr: true 17 | }, 18 | publicDir: false 19 | }; 20 | } 21 | }); 22 | } 23 | export { 24 | nodeServerAdapter 25 | }; 26 | -------------------------------------------------------------------------------- /lib/adapters/shared/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/adapters/shared/vite/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | NOT_FOUND_PATHS_ID: () => NOT_FOUND_PATHS_ID, 34 | RESOLVED_NOT_FOUND_PATHS_ID: () => RESOLVED_NOT_FOUND_PATHS_ID, 35 | RESOLVED_STATIC_PATHS_ID: () => RESOLVED_STATIC_PATHS_ID, 36 | STATIC_PATHS_ID: () => STATIC_PATHS_ID, 37 | getParentDir: () => getParentDir, 38 | viteAdapter: () => viteAdapter 39 | }); 40 | module.exports = __toCommonJS(index_exports); 41 | var import_node_fs2 = __toESM(require("node:fs"), 1); 42 | var import_node_path2 = require("node:path"); 43 | 44 | // packages/qwik-city/src/adapters/shared/vite/post-build.ts 45 | var import_node_fs = __toESM(require("node:fs"), 1); 46 | var import_node_path = require("node:path"); 47 | var import_request_handler = require("../../../middleware/request-handler/index.cjs"); 48 | async function postBuild(clientOutDir, pathName, userStaticPaths, format, cleanStatic) { 49 | if (pathName && !pathName.endsWith("/")) { 50 | pathName += "/"; 51 | } 52 | const ignorePathnames = /* @__PURE__ */ new Set([pathName + "build/", pathName + "assets/"]); 53 | const staticPaths = new Set(userStaticPaths.map(normalizeTrailingSlash)); 54 | const notFounds = []; 55 | const loadItem = async (fsDir, fsName, pathname) => { 56 | pathname = normalizeTrailingSlash(pathname); 57 | if (ignorePathnames.has(pathname)) { 58 | return; 59 | } 60 | const fsPath = (0, import_node_path.join)(fsDir, fsName); 61 | if (fsName === "index.html" || fsName === "q-data.json") { 62 | if (!staticPaths.has(pathname) && cleanStatic) { 63 | await import_node_fs.default.promises.unlink(fsPath); 64 | } 65 | return; 66 | } 67 | if (fsName === "404.html") { 68 | const notFoundHtml = await import_node_fs.default.promises.readFile(fsPath, "utf-8"); 69 | notFounds.push([pathname, notFoundHtml]); 70 | return; 71 | } 72 | const stat = await import_node_fs.default.promises.stat(fsPath); 73 | if (stat.isDirectory()) { 74 | await loadDir(fsPath, pathname + fsName + "/"); 75 | } else if (stat.isFile()) { 76 | staticPaths.add(pathname + fsName); 77 | } 78 | }; 79 | const loadDir = async (fsDir, pathname) => { 80 | const itemNames = await import_node_fs.default.promises.readdir(fsDir); 81 | await Promise.all(itemNames.map((i) => loadItem(fsDir, i, pathname))); 82 | }; 83 | if (import_node_fs.default.existsSync(clientOutDir)) { 84 | await loadDir(clientOutDir, pathName); 85 | } 86 | const notFoundPathsCode = createNotFoundPathsModule(pathName, notFounds, format); 87 | const staticPathsCode = createStaticPathsModule(pathName, staticPaths, format); 88 | return { 89 | notFoundPathsCode, 90 | staticPathsCode 91 | }; 92 | } 93 | function normalizeTrailingSlash(pathname) { 94 | if (!pathname.endsWith("/")) { 95 | return pathname + "/"; 96 | } 97 | return pathname; 98 | } 99 | function createNotFoundPathsModule(basePathname, notFounds, format) { 100 | notFounds.sort((a, b) => { 101 | if (a[0].length > b[0].length) { 102 | return -1; 103 | } 104 | if (a[0].length < b[0].length) { 105 | return 1; 106 | } 107 | if (a[0] < b[0]) { 108 | return -1; 109 | } 110 | if (a[0] > b[0]) { 111 | return 1; 112 | } 113 | return 0; 114 | }); 115 | if (!notFounds.some((r) => r[0] === basePathname)) { 116 | const html = (0, import_request_handler.getErrorHtml)(404, "Resource Not Found"); 117 | notFounds.push([basePathname, html]); 118 | } 119 | const c = []; 120 | c.push(`const notFounds = ${JSON.stringify(notFounds, null, 2)};`); 121 | c.push(`function getNotFound(p) {`); 122 | c.push(` for (const r of notFounds) {`); 123 | c.push(` if (p.startsWith(r[0])) {`); 124 | c.push(` return r[1];`); 125 | c.push(` }`); 126 | c.push(` }`); 127 | c.push(` return "Resource Not Found";`); 128 | c.push(`}`); 129 | if (format === "cjs") { 130 | c.push("exports.getNotFound = getNotFound;"); 131 | } else { 132 | c.push("export { getNotFound };"); 133 | } 134 | return c.join("\n"); 135 | } 136 | function createStaticPathsModule(basePathname, staticPaths, format) { 137 | const assetsPath = basePathname + "assets/"; 138 | const baseBuildPath = basePathname + "build/"; 139 | const c = []; 140 | c.push( 141 | `const staticPaths = new Set(${JSON.stringify( 142 | Array.from(new Set(staticPaths)).sort() 143 | )});` 144 | ); 145 | c.push(`function isStaticPath(method, url) {`); 146 | c.push(` if (method.toUpperCase() !== 'GET') {`); 147 | c.push(` return false;`); 148 | c.push(` }`); 149 | c.push(` const p = url.pathname;`); 150 | c.push(` if (p.startsWith(${JSON.stringify(baseBuildPath)})) {`); 151 | c.push(` return true;`); 152 | c.push(` }`); 153 | c.push(` if (p.startsWith(${JSON.stringify(assetsPath)})) {`); 154 | c.push(` return true;`); 155 | c.push(` }`); 156 | c.push(` if (staticPaths.has(p)) {`); 157 | c.push(` return true;`); 158 | c.push(` }`); 159 | c.push(` if (p.endsWith('/q-data.json')) {`); 160 | c.push(` const pWithoutQdata = p.replace(/\\/q-data.json$/, '');`); 161 | c.push(` if (staticPaths.has(pWithoutQdata + '/')) {`); 162 | c.push(` return true;`); 163 | c.push(` }`); 164 | c.push(` if (staticPaths.has(pWithoutQdata)) {`); 165 | c.push(` return true;`); 166 | c.push(` }`); 167 | c.push(` }`); 168 | c.push(` return false;`); 169 | c.push(`}`); 170 | if (format === "cjs") { 171 | c.push("exports.isStaticPath = isStaticPath;"); 172 | } else { 173 | c.push("export { isStaticPath };"); 174 | } 175 | return c.join("\n"); 176 | } 177 | 178 | // packages/qwik-city/src/adapters/shared/vite/index.ts 179 | function viteAdapter(opts) { 180 | let qwikCityPlugin = null; 181 | let qwikVitePlugin = null; 182 | let serverOutDir = null; 183 | let renderModulePath = null; 184 | let qwikCityPlanModulePath = null; 185 | let isSsrBuild = false; 186 | let format = "esm"; 187 | const outputEntries = []; 188 | const plugin = { 189 | name: `vite-plugin-qwik-city-${opts.name}`, 190 | enforce: "post", 191 | apply: "build", 192 | config(config) { 193 | if (typeof opts.config === "function") { 194 | config = opts.config(config); 195 | } 196 | config.define = { 197 | "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "production"), 198 | ...config.define 199 | }; 200 | return config; 201 | }, 202 | configResolved(config) { 203 | var _a, _b, _c, _d; 204 | isSsrBuild = !!config.build.ssr; 205 | if (isSsrBuild) { 206 | qwikCityPlugin = config.plugins.find( 207 | (p) => p.name === "vite-plugin-qwik-city" 208 | ); 209 | if (!qwikCityPlugin) { 210 | throw new Error("Missing vite-plugin-qwik-city"); 211 | } 212 | qwikVitePlugin = config.plugins.find( 213 | (p) => p.name === "vite-plugin-qwik" 214 | ); 215 | if (!qwikVitePlugin) { 216 | throw new Error("Missing vite-plugin-qwik"); 217 | } 218 | serverOutDir = config.build.outDir; 219 | if (((_a = config.build) == null ? void 0 : _a.ssr) !== true) { 220 | throw new Error( 221 | `"build.ssr" must be set to "true" in order to use the "${opts.name}" adapter.` 222 | ); 223 | } 224 | if (!((_c = (_b = config.build) == null ? void 0 : _b.rollupOptions) == null ? void 0 : _c.input)) { 225 | throw new Error( 226 | `"build.rollupOptions.input" must be set in order to use the "${opts.name}" adapter.` 227 | ); 228 | } 229 | if (((_d = config.ssr) == null ? void 0 : _d.format) === "cjs") { 230 | format = "cjs"; 231 | } 232 | } 233 | }, 234 | generateBundle(_, bundles) { 235 | if (isSsrBuild) { 236 | outputEntries.length = 0; 237 | for (const fileName in bundles) { 238 | const chunk = bundles[fileName]; 239 | if (chunk.type === "chunk" && chunk.isEntry) { 240 | outputEntries.push(fileName); 241 | if (chunk.name === "entry.ssr") { 242 | renderModulePath = (0, import_node_path2.join)(serverOutDir, fileName); 243 | } else if (chunk.name === "@qwik-city-plan") { 244 | qwikCityPlanModulePath = (0, import_node_path2.join)(serverOutDir, fileName); 245 | } 246 | } 247 | } 248 | if (!renderModulePath) { 249 | throw new Error( 250 | 'Unable to find "entry.ssr" entry point. Did you forget to add it to "build.rollupOptions.input"?' 251 | ); 252 | } 253 | if (!qwikCityPlanModulePath) { 254 | throw new Error( 255 | 'Unable to find "@qwik-city-plan" entry point. Did you forget to add it to "build.rollupOptions.input"?' 256 | ); 257 | } 258 | } 259 | }, 260 | closeBundle: { 261 | sequential: true, 262 | async handler() { 263 | var _a; 264 | if (isSsrBuild && opts.ssg !== null && serverOutDir && (qwikCityPlugin == null ? void 0 : qwikCityPlugin.api) && (qwikVitePlugin == null ? void 0 : qwikVitePlugin.api)) { 265 | const staticPaths = opts.staticPaths || []; 266 | const routes = qwikCityPlugin.api.getRoutes(); 267 | const basePathname = qwikCityPlugin.api.getBasePathname(); 268 | const clientOutDir = qwikVitePlugin.api.getClientOutDir(); 269 | const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir(); 270 | const assetsDir = qwikVitePlugin.api.getAssetsDir(); 271 | const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0; 272 | if (renderModulePath && qwikCityPlanModulePath && clientOutDir && clientPublicOutDir) { 273 | let ssgOrigin = ((_a = opts.ssg) == null ? void 0 : _a.origin) ?? opts.origin; 274 | if (!ssgOrigin) { 275 | ssgOrigin = `https://yoursite.qwik.dev`; 276 | } 277 | if (ssgOrigin.length > 0 && !/:\/\//.test(ssgOrigin)) { 278 | ssgOrigin = `https://${ssgOrigin}`; 279 | } 280 | if (ssgOrigin.startsWith("//")) { 281 | ssgOrigin = `https:${ssgOrigin}`; 282 | } 283 | try { 284 | ssgOrigin = new URL(ssgOrigin).origin; 285 | } catch (e) { 286 | this.warn( 287 | `Invalid "origin" option: "${ssgOrigin}". Using default origin: "https://yoursite.qwik.dev"` 288 | ); 289 | ssgOrigin = `https://yoursite.qwik.dev`; 290 | } 291 | const staticGenerate = await import("../../../static/index.cjs"); 292 | const generateOpts = { 293 | maxWorkers: opts.maxWorkers, 294 | basePathname, 295 | outDir: clientPublicOutDir, 296 | rootDir, 297 | ...opts.ssg, 298 | origin: ssgOrigin, 299 | renderModulePath, 300 | qwikCityPlanModulePath 301 | }; 302 | const staticGenerateResult = await staticGenerate.generate(generateOpts); 303 | if (staticGenerateResult.errors > 0) { 304 | const err = new Error( 305 | `Error while running SSG from "${opts.name}" adapter. At least one path failed to render.` 306 | ); 307 | err.stack = void 0; 308 | this.error(err); 309 | } 310 | staticPaths.push(...staticGenerateResult.staticPaths); 311 | const { staticPathsCode, notFoundPathsCode } = await postBuild( 312 | clientPublicOutDir, 313 | assetsDir ? (0, import_node_path2.join)(basePathname, assetsDir) : basePathname, 314 | staticPaths, 315 | format, 316 | !!opts.cleanStaticGenerated 317 | ); 318 | await Promise.all([ 319 | import_node_fs2.default.promises.writeFile((0, import_node_path2.join)(serverOutDir, RESOLVED_STATIC_PATHS_ID), staticPathsCode), 320 | import_node_fs2.default.promises.writeFile( 321 | (0, import_node_path2.join)(serverOutDir, RESOLVED_NOT_FOUND_PATHS_ID), 322 | notFoundPathsCode 323 | ) 324 | ]); 325 | if (typeof opts.generate === "function") { 326 | await opts.generate({ 327 | outputEntries, 328 | serverOutDir, 329 | clientOutDir, 330 | clientPublicOutDir, 331 | basePathname, 332 | routes, 333 | assetsDir, 334 | warn: (message) => this.warn(message), 335 | error: (message) => this.error(message) 336 | }); 337 | } 338 | this.warn( 339 | ` 340 | ============================================== 341 | Note: Make sure that you are serving the built files with proper cache headers. 342 | See https://qwik.dev/docs/deployments/#cache-headers for more information. 343 | ==============================================` 344 | ); 345 | } 346 | } 347 | } 348 | } 349 | }; 350 | return plugin; 351 | } 352 | function getParentDir(startDir, dirName) { 353 | const root = (0, import_node_path2.resolve)("/"); 354 | let dir = startDir; 355 | for (let i = 0; i < 20; i++) { 356 | dir = (0, import_node_path2.dirname)(dir); 357 | if ((0, import_node_path2.basename)(dir) === dirName) { 358 | return dir; 359 | } 360 | if (dir === root) { 361 | break; 362 | } 363 | } 364 | throw new Error(`Unable to find "${dirName}" directory from "${startDir}"`); 365 | } 366 | var STATIC_PATHS_ID = "@qwik-city-static-paths"; 367 | var RESOLVED_STATIC_PATHS_ID = `${STATIC_PATHS_ID}.js`; 368 | var NOT_FOUND_PATHS_ID = "@qwik-city-not-found-paths"; 369 | var RESOLVED_NOT_FOUND_PATHS_ID = `${NOT_FOUND_PATHS_ID}.js`; 370 | // Annotate the CommonJS export names for ESM import in node: 371 | 0 && (module.exports = { 372 | NOT_FOUND_PATHS_ID, 373 | RESOLVED_NOT_FOUND_PATHS_ID, 374 | RESOLVED_STATIC_PATHS_ID, 375 | STATIC_PATHS_ID, 376 | getParentDir, 377 | viteAdapter 378 | }); 379 | -------------------------------------------------------------------------------- /lib/adapters/shared/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin as Plugin_2 } from 'vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | import type { UserConfig } from 'vite'; 4 | 5 | /** @public */ 6 | export declare interface AdapterSSGOptions extends Omit { 7 | /** Defines routes that should be static generated. Accepts wildcard behavior. */ 8 | include: string[]; 9 | /** 10 | * Defines routes that should not be static generated. Accepts wildcard behavior. `exclude` always 11 | * take priority over `include`. 12 | */ 13 | exclude?: string[]; 14 | /** 15 | * The URL `origin`, which is a combination of the scheme (protocol) and hostname (domain). For 16 | * example, `https://qwik.dev` has the protocol `https://` and domain `qwik.dev`. However, the 17 | * `origin` does not include a `pathname`. 18 | * 19 | * The `origin` is used to provide a full URL during Static Site Generation (SSG), and to simulate 20 | * a complete URL rather than just the `pathname`. For example, in order to render a correct 21 | * canonical tag URL or URLs within the `sitemap.xml`, the `origin` must be provided too. 22 | * 23 | * If the site also starts with a pathname other than `/`, please use the `basePathname` option in 24 | * the Qwik City config options. 25 | */ 26 | origin?: string; 27 | } 28 | 29 | declare interface BuildLayout { 30 | filePath: string; 31 | dirPath: string; 32 | id: string; 33 | layoutType: 'top' | 'nested'; 34 | layoutName: string; 35 | } 36 | 37 | declare interface BuildRoute extends ParsedPathname { 38 | /** Unique id built from its relative file system path */ 39 | id: string; 40 | /** Local file system path */ 41 | filePath: string; 42 | ext: string; 43 | /** URL Pathname */ 44 | pathname: string; 45 | layouts: BuildLayout[]; 46 | } 47 | 48 | /** @public */ 49 | export declare function getParentDir(startDir: string, dirName: string): string; 50 | 51 | /** @public */ 52 | export declare const NOT_FOUND_PATHS_ID = "@qwik-city-not-found-paths"; 53 | 54 | declare interface ParsedPathname { 55 | routeName: string; 56 | pattern: RegExp; 57 | paramNames: string[]; 58 | segments: PathnameSegment[]; 59 | } 60 | 61 | declare type PathnameSegment = PathnameSegmentPart[]; 62 | 63 | declare interface PathnameSegmentPart { 64 | content: string; 65 | dynamic: boolean; 66 | rest: boolean; 67 | } 68 | 69 | /** @public */ 70 | export declare const RESOLVED_NOT_FOUND_PATHS_ID = "@qwik-city-not-found-paths.js"; 71 | 72 | /** @public */ 73 | export declare const RESOLVED_STATIC_PATHS_ID = "@qwik-city-static-paths.js"; 74 | 75 | /** @public */ 76 | export declare interface ServerAdapterOptions { 77 | /** 78 | * Options the adapter should use when running Static Site Generation (SSG). Defaults the `filter` 79 | * to "auto" which will attempt to automatically decides if a page can be statically generated and 80 | * does not have dynamic data, or if it the page should instead be rendered on the server (SSR). 81 | * Setting to `null` will prevent any pages from being statically generated. 82 | */ 83 | ssg?: AdapterSSGOptions | null; 84 | } 85 | 86 | /** @public */ 87 | export declare const STATIC_PATHS_ID = "@qwik-city-static-paths"; 88 | 89 | /** @public */ 90 | export declare function viteAdapter(opts: ViteAdapterPluginOptions): Plugin_2; 91 | 92 | /** @public */ 93 | declare interface ViteAdapterPluginOptions { 94 | name: string; 95 | origin: string; 96 | staticPaths?: string[]; 97 | ssg?: AdapterSSGOptions | null; 98 | cleanStaticGenerated?: boolean; 99 | maxWorkers?: number; 100 | config?: (config: UserConfig) => UserConfig; 101 | generate?: (generateOpts: { 102 | outputEntries: string[]; 103 | clientOutDir: string; 104 | clientPublicOutDir: string; 105 | serverOutDir: string; 106 | basePathname: string; 107 | routes: BuildRoute[]; 108 | assetsDir?: string; 109 | warn: (message: string) => void; 110 | error: (message: string) => void; 111 | }) => Promise; 112 | } 113 | 114 | export { } 115 | -------------------------------------------------------------------------------- /lib/adapters/shared/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/shared/vite/index.ts 2 | import fs2 from "node:fs"; 3 | import { basename, dirname, join as join2, resolve } from "node:path"; 4 | 5 | // packages/qwik-city/src/adapters/shared/vite/post-build.ts 6 | import fs from "node:fs"; 7 | import { join } from "node:path"; 8 | import { getErrorHtml } from "../../../middleware/request-handler/index.mjs"; 9 | async function postBuild(clientOutDir, pathName, userStaticPaths, format, cleanStatic) { 10 | if (pathName && !pathName.endsWith("/")) { 11 | pathName += "/"; 12 | } 13 | const ignorePathnames = /* @__PURE__ */ new Set([pathName + "build/", pathName + "assets/"]); 14 | const staticPaths = new Set(userStaticPaths.map(normalizeTrailingSlash)); 15 | const notFounds = []; 16 | const loadItem = async (fsDir, fsName, pathname) => { 17 | pathname = normalizeTrailingSlash(pathname); 18 | if (ignorePathnames.has(pathname)) { 19 | return; 20 | } 21 | const fsPath = join(fsDir, fsName); 22 | if (fsName === "index.html" || fsName === "q-data.json") { 23 | if (!staticPaths.has(pathname) && cleanStatic) { 24 | await fs.promises.unlink(fsPath); 25 | } 26 | return; 27 | } 28 | if (fsName === "404.html") { 29 | const notFoundHtml = await fs.promises.readFile(fsPath, "utf-8"); 30 | notFounds.push([pathname, notFoundHtml]); 31 | return; 32 | } 33 | const stat = await fs.promises.stat(fsPath); 34 | if (stat.isDirectory()) { 35 | await loadDir(fsPath, pathname + fsName + "/"); 36 | } else if (stat.isFile()) { 37 | staticPaths.add(pathname + fsName); 38 | } 39 | }; 40 | const loadDir = async (fsDir, pathname) => { 41 | const itemNames = await fs.promises.readdir(fsDir); 42 | await Promise.all(itemNames.map((i) => loadItem(fsDir, i, pathname))); 43 | }; 44 | if (fs.existsSync(clientOutDir)) { 45 | await loadDir(clientOutDir, pathName); 46 | } 47 | const notFoundPathsCode = createNotFoundPathsModule(pathName, notFounds, format); 48 | const staticPathsCode = createStaticPathsModule(pathName, staticPaths, format); 49 | return { 50 | notFoundPathsCode, 51 | staticPathsCode 52 | }; 53 | } 54 | function normalizeTrailingSlash(pathname) { 55 | if (!pathname.endsWith("/")) { 56 | return pathname + "/"; 57 | } 58 | return pathname; 59 | } 60 | function createNotFoundPathsModule(basePathname, notFounds, format) { 61 | notFounds.sort((a, b) => { 62 | if (a[0].length > b[0].length) { 63 | return -1; 64 | } 65 | if (a[0].length < b[0].length) { 66 | return 1; 67 | } 68 | if (a[0] < b[0]) { 69 | return -1; 70 | } 71 | if (a[0] > b[0]) { 72 | return 1; 73 | } 74 | return 0; 75 | }); 76 | if (!notFounds.some((r) => r[0] === basePathname)) { 77 | const html = getErrorHtml(404, "Resource Not Found"); 78 | notFounds.push([basePathname, html]); 79 | } 80 | const c = []; 81 | c.push(`const notFounds = ${JSON.stringify(notFounds, null, 2)};`); 82 | c.push(`function getNotFound(p) {`); 83 | c.push(` for (const r of notFounds) {`); 84 | c.push(` if (p.startsWith(r[0])) {`); 85 | c.push(` return r[1];`); 86 | c.push(` }`); 87 | c.push(` }`); 88 | c.push(` return "Resource Not Found";`); 89 | c.push(`}`); 90 | if (format === "cjs") { 91 | c.push("exports.getNotFound = getNotFound;"); 92 | } else { 93 | c.push("export { getNotFound };"); 94 | } 95 | return c.join("\n"); 96 | } 97 | function createStaticPathsModule(basePathname, staticPaths, format) { 98 | const assetsPath = basePathname + "assets/"; 99 | const baseBuildPath = basePathname + "build/"; 100 | const c = []; 101 | c.push( 102 | `const staticPaths = new Set(${JSON.stringify( 103 | Array.from(new Set(staticPaths)).sort() 104 | )});` 105 | ); 106 | c.push(`function isStaticPath(method, url) {`); 107 | c.push(` if (method.toUpperCase() !== 'GET') {`); 108 | c.push(` return false;`); 109 | c.push(` }`); 110 | c.push(` const p = url.pathname;`); 111 | c.push(` if (p.startsWith(${JSON.stringify(baseBuildPath)})) {`); 112 | c.push(` return true;`); 113 | c.push(` }`); 114 | c.push(` if (p.startsWith(${JSON.stringify(assetsPath)})) {`); 115 | c.push(` return true;`); 116 | c.push(` }`); 117 | c.push(` if (staticPaths.has(p)) {`); 118 | c.push(` return true;`); 119 | c.push(` }`); 120 | c.push(` if (p.endsWith('/q-data.json')) {`); 121 | c.push(` const pWithoutQdata = p.replace(/\\/q-data.json$/, '');`); 122 | c.push(` if (staticPaths.has(pWithoutQdata + '/')) {`); 123 | c.push(` return true;`); 124 | c.push(` }`); 125 | c.push(` if (staticPaths.has(pWithoutQdata)) {`); 126 | c.push(` return true;`); 127 | c.push(` }`); 128 | c.push(` }`); 129 | c.push(` return false;`); 130 | c.push(`}`); 131 | if (format === "cjs") { 132 | c.push("exports.isStaticPath = isStaticPath;"); 133 | } else { 134 | c.push("export { isStaticPath };"); 135 | } 136 | return c.join("\n"); 137 | } 138 | 139 | // packages/qwik-city/src/adapters/shared/vite/index.ts 140 | function viteAdapter(opts) { 141 | let qwikCityPlugin = null; 142 | let qwikVitePlugin = null; 143 | let serverOutDir = null; 144 | let renderModulePath = null; 145 | let qwikCityPlanModulePath = null; 146 | let isSsrBuild = false; 147 | let format = "esm"; 148 | const outputEntries = []; 149 | const plugin = { 150 | name: `vite-plugin-qwik-city-${opts.name}`, 151 | enforce: "post", 152 | apply: "build", 153 | config(config) { 154 | if (typeof opts.config === "function") { 155 | config = opts.config(config); 156 | } 157 | config.define = { 158 | "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "production"), 159 | ...config.define 160 | }; 161 | return config; 162 | }, 163 | configResolved(config) { 164 | var _a, _b, _c, _d; 165 | isSsrBuild = !!config.build.ssr; 166 | if (isSsrBuild) { 167 | qwikCityPlugin = config.plugins.find( 168 | (p) => p.name === "vite-plugin-qwik-city" 169 | ); 170 | if (!qwikCityPlugin) { 171 | throw new Error("Missing vite-plugin-qwik-city"); 172 | } 173 | qwikVitePlugin = config.plugins.find( 174 | (p) => p.name === "vite-plugin-qwik" 175 | ); 176 | if (!qwikVitePlugin) { 177 | throw new Error("Missing vite-plugin-qwik"); 178 | } 179 | serverOutDir = config.build.outDir; 180 | if (((_a = config.build) == null ? void 0 : _a.ssr) !== true) { 181 | throw new Error( 182 | `"build.ssr" must be set to "true" in order to use the "${opts.name}" adapter.` 183 | ); 184 | } 185 | if (!((_c = (_b = config.build) == null ? void 0 : _b.rollupOptions) == null ? void 0 : _c.input)) { 186 | throw new Error( 187 | `"build.rollupOptions.input" must be set in order to use the "${opts.name}" adapter.` 188 | ); 189 | } 190 | if (((_d = config.ssr) == null ? void 0 : _d.format) === "cjs") { 191 | format = "cjs"; 192 | } 193 | } 194 | }, 195 | generateBundle(_, bundles) { 196 | if (isSsrBuild) { 197 | outputEntries.length = 0; 198 | for (const fileName in bundles) { 199 | const chunk = bundles[fileName]; 200 | if (chunk.type === "chunk" && chunk.isEntry) { 201 | outputEntries.push(fileName); 202 | if (chunk.name === "entry.ssr") { 203 | renderModulePath = join2(serverOutDir, fileName); 204 | } else if (chunk.name === "@qwik-city-plan") { 205 | qwikCityPlanModulePath = join2(serverOutDir, fileName); 206 | } 207 | } 208 | } 209 | if (!renderModulePath) { 210 | throw new Error( 211 | 'Unable to find "entry.ssr" entry point. Did you forget to add it to "build.rollupOptions.input"?' 212 | ); 213 | } 214 | if (!qwikCityPlanModulePath) { 215 | throw new Error( 216 | 'Unable to find "@qwik-city-plan" entry point. Did you forget to add it to "build.rollupOptions.input"?' 217 | ); 218 | } 219 | } 220 | }, 221 | closeBundle: { 222 | sequential: true, 223 | async handler() { 224 | var _a; 225 | if (isSsrBuild && opts.ssg !== null && serverOutDir && (qwikCityPlugin == null ? void 0 : qwikCityPlugin.api) && (qwikVitePlugin == null ? void 0 : qwikVitePlugin.api)) { 226 | const staticPaths = opts.staticPaths || []; 227 | const routes = qwikCityPlugin.api.getRoutes(); 228 | const basePathname = qwikCityPlugin.api.getBasePathname(); 229 | const clientOutDir = qwikVitePlugin.api.getClientOutDir(); 230 | const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir(); 231 | const assetsDir = qwikVitePlugin.api.getAssetsDir(); 232 | const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0; 233 | if (renderModulePath && qwikCityPlanModulePath && clientOutDir && clientPublicOutDir) { 234 | let ssgOrigin = ((_a = opts.ssg) == null ? void 0 : _a.origin) ?? opts.origin; 235 | if (!ssgOrigin) { 236 | ssgOrigin = `https://yoursite.qwik.dev`; 237 | } 238 | if (ssgOrigin.length > 0 && !/:\/\//.test(ssgOrigin)) { 239 | ssgOrigin = `https://${ssgOrigin}`; 240 | } 241 | if (ssgOrigin.startsWith("//")) { 242 | ssgOrigin = `https:${ssgOrigin}`; 243 | } 244 | try { 245 | ssgOrigin = new URL(ssgOrigin).origin; 246 | } catch (e) { 247 | this.warn( 248 | `Invalid "origin" option: "${ssgOrigin}". Using default origin: "https://yoursite.qwik.dev"` 249 | ); 250 | ssgOrigin = `https://yoursite.qwik.dev`; 251 | } 252 | const staticGenerate = await import("../../../static/index.mjs"); 253 | const generateOpts = { 254 | maxWorkers: opts.maxWorkers, 255 | basePathname, 256 | outDir: clientPublicOutDir, 257 | rootDir, 258 | ...opts.ssg, 259 | origin: ssgOrigin, 260 | renderModulePath, 261 | qwikCityPlanModulePath 262 | }; 263 | const staticGenerateResult = await staticGenerate.generate(generateOpts); 264 | if (staticGenerateResult.errors > 0) { 265 | const err = new Error( 266 | `Error while running SSG from "${opts.name}" adapter. At least one path failed to render.` 267 | ); 268 | err.stack = void 0; 269 | this.error(err); 270 | } 271 | staticPaths.push(...staticGenerateResult.staticPaths); 272 | const { staticPathsCode, notFoundPathsCode } = await postBuild( 273 | clientPublicOutDir, 274 | assetsDir ? join2(basePathname, assetsDir) : basePathname, 275 | staticPaths, 276 | format, 277 | !!opts.cleanStaticGenerated 278 | ); 279 | await Promise.all([ 280 | fs2.promises.writeFile(join2(serverOutDir, RESOLVED_STATIC_PATHS_ID), staticPathsCode), 281 | fs2.promises.writeFile( 282 | join2(serverOutDir, RESOLVED_NOT_FOUND_PATHS_ID), 283 | notFoundPathsCode 284 | ) 285 | ]); 286 | if (typeof opts.generate === "function") { 287 | await opts.generate({ 288 | outputEntries, 289 | serverOutDir, 290 | clientOutDir, 291 | clientPublicOutDir, 292 | basePathname, 293 | routes, 294 | assetsDir, 295 | warn: (message) => this.warn(message), 296 | error: (message) => this.error(message) 297 | }); 298 | } 299 | this.warn( 300 | ` 301 | ============================================== 302 | Note: Make sure that you are serving the built files with proper cache headers. 303 | See https://qwik.dev/docs/deployments/#cache-headers for more information. 304 | ==============================================` 305 | ); 306 | } 307 | } 308 | } 309 | } 310 | }; 311 | return plugin; 312 | } 313 | function getParentDir(startDir, dirName) { 314 | const root = resolve("/"); 315 | let dir = startDir; 316 | for (let i = 0; i < 20; i++) { 317 | dir = dirname(dir); 318 | if (basename(dir) === dirName) { 319 | return dir; 320 | } 321 | if (dir === root) { 322 | break; 323 | } 324 | } 325 | throw new Error(`Unable to find "${dirName}" directory from "${startDir}"`); 326 | } 327 | var STATIC_PATHS_ID = "@qwik-city-static-paths"; 328 | var RESOLVED_STATIC_PATHS_ID = `${STATIC_PATHS_ID}.js`; 329 | var NOT_FOUND_PATHS_ID = "@qwik-city-not-found-paths"; 330 | var RESOLVED_NOT_FOUND_PATHS_ID = `${NOT_FOUND_PATHS_ID}.js`; 331 | export { 332 | NOT_FOUND_PATHS_ID, 333 | RESOLVED_NOT_FOUND_PATHS_ID, 334 | RESOLVED_STATIC_PATHS_ID, 335 | STATIC_PATHS_ID, 336 | getParentDir, 337 | viteAdapter 338 | }; 339 | -------------------------------------------------------------------------------- /lib/adapters/static/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/adapters/static/vite/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | staticAdapter: () => staticAdapter 34 | }); 35 | module.exports = __toCommonJS(index_exports); 36 | 37 | // packages/qwik-city/src/adapters/shared/vite/index.ts 38 | var import_node_fs2 = __toESM(require("node:fs"), 1); 39 | var import_node_path2 = require("node:path"); 40 | 41 | // packages/qwik-city/src/adapters/shared/vite/post-build.ts 42 | var import_node_fs = __toESM(require("node:fs"), 1); 43 | var import_node_path = require("node:path"); 44 | var import_request_handler = require("@builder.io/qwik-city/middleware/request-handler"); 45 | async function postBuild(clientOutDir, pathName, userStaticPaths, format, cleanStatic) { 46 | if (pathName && !pathName.endsWith("/")) { 47 | pathName += "/"; 48 | } 49 | const ignorePathnames = /* @__PURE__ */ new Set([pathName + "build/", pathName + "assets/"]); 50 | const staticPaths = new Set(userStaticPaths.map(normalizeTrailingSlash)); 51 | const notFounds = []; 52 | const loadItem = async (fsDir, fsName, pathname) => { 53 | pathname = normalizeTrailingSlash(pathname); 54 | if (ignorePathnames.has(pathname)) { 55 | return; 56 | } 57 | const fsPath = (0, import_node_path.join)(fsDir, fsName); 58 | if (fsName === "index.html" || fsName === "q-data.json") { 59 | if (!staticPaths.has(pathname) && cleanStatic) { 60 | await import_node_fs.default.promises.unlink(fsPath); 61 | } 62 | return; 63 | } 64 | if (fsName === "404.html") { 65 | const notFoundHtml = await import_node_fs.default.promises.readFile(fsPath, "utf-8"); 66 | notFounds.push([pathname, notFoundHtml]); 67 | return; 68 | } 69 | const stat = await import_node_fs.default.promises.stat(fsPath); 70 | if (stat.isDirectory()) { 71 | await loadDir(fsPath, pathname + fsName + "/"); 72 | } else if (stat.isFile()) { 73 | staticPaths.add(pathname + fsName); 74 | } 75 | }; 76 | const loadDir = async (fsDir, pathname) => { 77 | const itemNames = await import_node_fs.default.promises.readdir(fsDir); 78 | await Promise.all(itemNames.map((i) => loadItem(fsDir, i, pathname))); 79 | }; 80 | if (import_node_fs.default.existsSync(clientOutDir)) { 81 | await loadDir(clientOutDir, pathName); 82 | } 83 | const notFoundPathsCode = createNotFoundPathsModule(pathName, notFounds, format); 84 | const staticPathsCode = createStaticPathsModule(pathName, staticPaths, format); 85 | return { 86 | notFoundPathsCode, 87 | staticPathsCode 88 | }; 89 | } 90 | function normalizeTrailingSlash(pathname) { 91 | if (!pathname.endsWith("/")) { 92 | return pathname + "/"; 93 | } 94 | return pathname; 95 | } 96 | function createNotFoundPathsModule(basePathname, notFounds, format) { 97 | notFounds.sort((a, b) => { 98 | if (a[0].length > b[0].length) { 99 | return -1; 100 | } 101 | if (a[0].length < b[0].length) { 102 | return 1; 103 | } 104 | if (a[0] < b[0]) { 105 | return -1; 106 | } 107 | if (a[0] > b[0]) { 108 | return 1; 109 | } 110 | return 0; 111 | }); 112 | if (!notFounds.some((r) => r[0] === basePathname)) { 113 | const html = (0, import_request_handler.getErrorHtml)(404, "Resource Not Found"); 114 | notFounds.push([basePathname, html]); 115 | } 116 | const c = []; 117 | c.push(`const notFounds = ${JSON.stringify(notFounds, null, 2)};`); 118 | c.push(`function getNotFound(p) {`); 119 | c.push(` for (const r of notFounds) {`); 120 | c.push(` if (p.startsWith(r[0])) {`); 121 | c.push(` return r[1];`); 122 | c.push(` }`); 123 | c.push(` }`); 124 | c.push(` return "Resource Not Found";`); 125 | c.push(`}`); 126 | if (format === "cjs") { 127 | c.push("exports.getNotFound = getNotFound;"); 128 | } else { 129 | c.push("export { getNotFound };"); 130 | } 131 | return c.join("\n"); 132 | } 133 | function createStaticPathsModule(basePathname, staticPaths, format) { 134 | const assetsPath = basePathname + "assets/"; 135 | const baseBuildPath = basePathname + "build/"; 136 | const c = []; 137 | c.push( 138 | `const staticPaths = new Set(${JSON.stringify( 139 | Array.from(new Set(staticPaths)).sort() 140 | )});` 141 | ); 142 | c.push(`function isStaticPath(method, url) {`); 143 | c.push(` if (method.toUpperCase() !== 'GET') {`); 144 | c.push(` return false;`); 145 | c.push(` }`); 146 | c.push(` const p = url.pathname;`); 147 | c.push(` if (p.startsWith(${JSON.stringify(baseBuildPath)})) {`); 148 | c.push(` return true;`); 149 | c.push(` }`); 150 | c.push(` if (p.startsWith(${JSON.stringify(assetsPath)})) {`); 151 | c.push(` return true;`); 152 | c.push(` }`); 153 | c.push(` if (staticPaths.has(p)) {`); 154 | c.push(` return true;`); 155 | c.push(` }`); 156 | c.push(` if (p.endsWith('/q-data.json')) {`); 157 | c.push(` const pWithoutQdata = p.replace(/\\/q-data.json$/, '');`); 158 | c.push(` if (staticPaths.has(pWithoutQdata + '/')) {`); 159 | c.push(` return true;`); 160 | c.push(` }`); 161 | c.push(` if (staticPaths.has(pWithoutQdata)) {`); 162 | c.push(` return true;`); 163 | c.push(` }`); 164 | c.push(` }`); 165 | c.push(` return false;`); 166 | c.push(`}`); 167 | if (format === "cjs") { 168 | c.push("exports.isStaticPath = isStaticPath;"); 169 | } else { 170 | c.push("export { isStaticPath };"); 171 | } 172 | return c.join("\n"); 173 | } 174 | 175 | // packages/qwik-city/src/adapters/shared/vite/index.ts 176 | function viteAdapter(opts) { 177 | let qwikCityPlugin = null; 178 | let qwikVitePlugin = null; 179 | let serverOutDir = null; 180 | let renderModulePath = null; 181 | let qwikCityPlanModulePath = null; 182 | let isSsrBuild = false; 183 | let format = "esm"; 184 | const outputEntries = []; 185 | const plugin = { 186 | name: `vite-plugin-qwik-city-${opts.name}`, 187 | enforce: "post", 188 | apply: "build", 189 | config(config) { 190 | if (typeof opts.config === "function") { 191 | config = opts.config(config); 192 | } 193 | config.define = { 194 | "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "production"), 195 | ...config.define 196 | }; 197 | return config; 198 | }, 199 | configResolved(config) { 200 | var _a, _b, _c, _d; 201 | isSsrBuild = !!config.build.ssr; 202 | if (isSsrBuild) { 203 | qwikCityPlugin = config.plugins.find( 204 | (p) => p.name === "vite-plugin-qwik-city" 205 | ); 206 | if (!qwikCityPlugin) { 207 | throw new Error("Missing vite-plugin-qwik-city"); 208 | } 209 | qwikVitePlugin = config.plugins.find( 210 | (p) => p.name === "vite-plugin-qwik" 211 | ); 212 | if (!qwikVitePlugin) { 213 | throw new Error("Missing vite-plugin-qwik"); 214 | } 215 | serverOutDir = config.build.outDir; 216 | if (((_a = config.build) == null ? void 0 : _a.ssr) !== true) { 217 | throw new Error( 218 | `"build.ssr" must be set to "true" in order to use the "${opts.name}" adapter.` 219 | ); 220 | } 221 | if (!((_c = (_b = config.build) == null ? void 0 : _b.rollupOptions) == null ? void 0 : _c.input)) { 222 | throw new Error( 223 | `"build.rollupOptions.input" must be set in order to use the "${opts.name}" adapter.` 224 | ); 225 | } 226 | if (((_d = config.ssr) == null ? void 0 : _d.format) === "cjs") { 227 | format = "cjs"; 228 | } 229 | } 230 | }, 231 | generateBundle(_, bundles) { 232 | if (isSsrBuild) { 233 | outputEntries.length = 0; 234 | for (const fileName in bundles) { 235 | const chunk = bundles[fileName]; 236 | if (chunk.type === "chunk" && chunk.isEntry) { 237 | outputEntries.push(fileName); 238 | if (chunk.name === "entry.ssr") { 239 | renderModulePath = (0, import_node_path2.join)(serverOutDir, fileName); 240 | } else if (chunk.name === "@qwik-city-plan") { 241 | qwikCityPlanModulePath = (0, import_node_path2.join)(serverOutDir, fileName); 242 | } 243 | } 244 | } 245 | if (!renderModulePath) { 246 | throw new Error( 247 | 'Unable to find "entry.ssr" entry point. Did you forget to add it to "build.rollupOptions.input"?' 248 | ); 249 | } 250 | if (!qwikCityPlanModulePath) { 251 | throw new Error( 252 | 'Unable to find "@qwik-city-plan" entry point. Did you forget to add it to "build.rollupOptions.input"?' 253 | ); 254 | } 255 | } 256 | }, 257 | closeBundle: { 258 | sequential: true, 259 | async handler() { 260 | var _a; 261 | if (isSsrBuild && opts.ssg !== null && serverOutDir && (qwikCityPlugin == null ? void 0 : qwikCityPlugin.api) && (qwikVitePlugin == null ? void 0 : qwikVitePlugin.api)) { 262 | const staticPaths = opts.staticPaths || []; 263 | const routes = qwikCityPlugin.api.getRoutes(); 264 | const basePathname = qwikCityPlugin.api.getBasePathname(); 265 | const clientOutDir = qwikVitePlugin.api.getClientOutDir(); 266 | const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir(); 267 | const assetsDir = qwikVitePlugin.api.getAssetsDir(); 268 | const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0; 269 | if (renderModulePath && qwikCityPlanModulePath && clientOutDir && clientPublicOutDir) { 270 | let ssgOrigin = ((_a = opts.ssg) == null ? void 0 : _a.origin) ?? opts.origin; 271 | if (!ssgOrigin) { 272 | ssgOrigin = `https://yoursite.qwik.dev`; 273 | } 274 | if (ssgOrigin.length > 0 && !/:\/\//.test(ssgOrigin)) { 275 | ssgOrigin = `https://${ssgOrigin}`; 276 | } 277 | if (ssgOrigin.startsWith("//")) { 278 | ssgOrigin = `https:${ssgOrigin}`; 279 | } 280 | try { 281 | ssgOrigin = new URL(ssgOrigin).origin; 282 | } catch (e) { 283 | this.warn( 284 | `Invalid "origin" option: "${ssgOrigin}". Using default origin: "https://yoursite.qwik.dev"` 285 | ); 286 | ssgOrigin = `https://yoursite.qwik.dev`; 287 | } 288 | const staticGenerate = await import("../../../static/index.cjs"); 289 | const generateOpts = { 290 | maxWorkers: opts.maxWorkers, 291 | basePathname, 292 | outDir: clientPublicOutDir, 293 | rootDir, 294 | ...opts.ssg, 295 | origin: ssgOrigin, 296 | renderModulePath, 297 | qwikCityPlanModulePath 298 | }; 299 | const staticGenerateResult = await staticGenerate.generate(generateOpts); 300 | if (staticGenerateResult.errors > 0) { 301 | const err = new Error( 302 | `Error while running SSG from "${opts.name}" adapter. At least one path failed to render.` 303 | ); 304 | err.stack = void 0; 305 | this.error(err); 306 | } 307 | staticPaths.push(...staticGenerateResult.staticPaths); 308 | const { staticPathsCode, notFoundPathsCode } = await postBuild( 309 | clientPublicOutDir, 310 | assetsDir ? (0, import_node_path2.join)(basePathname, assetsDir) : basePathname, 311 | staticPaths, 312 | format, 313 | !!opts.cleanStaticGenerated 314 | ); 315 | await Promise.all([ 316 | import_node_fs2.default.promises.writeFile((0, import_node_path2.join)(serverOutDir, RESOLVED_STATIC_PATHS_ID), staticPathsCode), 317 | import_node_fs2.default.promises.writeFile( 318 | (0, import_node_path2.join)(serverOutDir, RESOLVED_NOT_FOUND_PATHS_ID), 319 | notFoundPathsCode 320 | ) 321 | ]); 322 | if (typeof opts.generate === "function") { 323 | await opts.generate({ 324 | outputEntries, 325 | serverOutDir, 326 | clientOutDir, 327 | clientPublicOutDir, 328 | basePathname, 329 | routes, 330 | assetsDir, 331 | warn: (message) => this.warn(message), 332 | error: (message) => this.error(message) 333 | }); 334 | } 335 | this.warn( 336 | ` 337 | ============================================== 338 | Note: Make sure that you are serving the built files with proper cache headers. 339 | See https://qwik.dev/docs/deployments/#cache-headers for more information. 340 | ==============================================` 341 | ); 342 | } 343 | } 344 | } 345 | } 346 | }; 347 | return plugin; 348 | } 349 | var STATIC_PATHS_ID = "@qwik-city-static-paths"; 350 | var RESOLVED_STATIC_PATHS_ID = `${STATIC_PATHS_ID}.js`; 351 | var NOT_FOUND_PATHS_ID = "@qwik-city-not-found-paths"; 352 | var RESOLVED_NOT_FOUND_PATHS_ID = `${NOT_FOUND_PATHS_ID}.js`; 353 | 354 | // packages/qwik-city/src/adapters/static/vite/index.ts 355 | function staticAdapter(opts) { 356 | return viteAdapter({ 357 | name: "static-generate", 358 | origin: opts.origin, 359 | ssg: { 360 | include: ["/*"], 361 | ...opts 362 | } 363 | }); 364 | } 365 | // Annotate the CommonJS export names for ESM import in node: 366 | 0 && (module.exports = { 367 | staticAdapter 368 | }); 369 | -------------------------------------------------------------------------------- /lib/adapters/static/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { StaticGenerateRenderOptions } from '../../../static'; 2 | 3 | /** @public */ 4 | export declare function staticAdapter(opts: StaticGenerateAdapterOptions): any; 5 | 6 | /** @public */ 7 | export declare interface StaticGenerateAdapterOptions extends Omit { 8 | } 9 | 10 | export { } 11 | -------------------------------------------------------------------------------- /lib/adapters/static/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/shared/vite/index.ts 2 | import fs2 from "node:fs"; 3 | import { basename, dirname, join as join2, resolve } from "node:path"; 4 | 5 | // packages/qwik-city/src/adapters/shared/vite/post-build.ts 6 | import fs from "node:fs"; 7 | import { join } from "node:path"; 8 | import { getErrorHtml } from "@builder.io/qwik-city/middleware/request-handler"; 9 | async function postBuild(clientOutDir, pathName, userStaticPaths, format, cleanStatic) { 10 | if (pathName && !pathName.endsWith("/")) { 11 | pathName += "/"; 12 | } 13 | const ignorePathnames = /* @__PURE__ */ new Set([pathName + "build/", pathName + "assets/"]); 14 | const staticPaths = new Set(userStaticPaths.map(normalizeTrailingSlash)); 15 | const notFounds = []; 16 | const loadItem = async (fsDir, fsName, pathname) => { 17 | pathname = normalizeTrailingSlash(pathname); 18 | if (ignorePathnames.has(pathname)) { 19 | return; 20 | } 21 | const fsPath = join(fsDir, fsName); 22 | if (fsName === "index.html" || fsName === "q-data.json") { 23 | if (!staticPaths.has(pathname) && cleanStatic) { 24 | await fs.promises.unlink(fsPath); 25 | } 26 | return; 27 | } 28 | if (fsName === "404.html") { 29 | const notFoundHtml = await fs.promises.readFile(fsPath, "utf-8"); 30 | notFounds.push([pathname, notFoundHtml]); 31 | return; 32 | } 33 | const stat = await fs.promises.stat(fsPath); 34 | if (stat.isDirectory()) { 35 | await loadDir(fsPath, pathname + fsName + "/"); 36 | } else if (stat.isFile()) { 37 | staticPaths.add(pathname + fsName); 38 | } 39 | }; 40 | const loadDir = async (fsDir, pathname) => { 41 | const itemNames = await fs.promises.readdir(fsDir); 42 | await Promise.all(itemNames.map((i) => loadItem(fsDir, i, pathname))); 43 | }; 44 | if (fs.existsSync(clientOutDir)) { 45 | await loadDir(clientOutDir, pathName); 46 | } 47 | const notFoundPathsCode = createNotFoundPathsModule(pathName, notFounds, format); 48 | const staticPathsCode = createStaticPathsModule(pathName, staticPaths, format); 49 | return { 50 | notFoundPathsCode, 51 | staticPathsCode 52 | }; 53 | } 54 | function normalizeTrailingSlash(pathname) { 55 | if (!pathname.endsWith("/")) { 56 | return pathname + "/"; 57 | } 58 | return pathname; 59 | } 60 | function createNotFoundPathsModule(basePathname, notFounds, format) { 61 | notFounds.sort((a, b) => { 62 | if (a[0].length > b[0].length) { 63 | return -1; 64 | } 65 | if (a[0].length < b[0].length) { 66 | return 1; 67 | } 68 | if (a[0] < b[0]) { 69 | return -1; 70 | } 71 | if (a[0] > b[0]) { 72 | return 1; 73 | } 74 | return 0; 75 | }); 76 | if (!notFounds.some((r) => r[0] === basePathname)) { 77 | const html = getErrorHtml(404, "Resource Not Found"); 78 | notFounds.push([basePathname, html]); 79 | } 80 | const c = []; 81 | c.push(`const notFounds = ${JSON.stringify(notFounds, null, 2)};`); 82 | c.push(`function getNotFound(p) {`); 83 | c.push(` for (const r of notFounds) {`); 84 | c.push(` if (p.startsWith(r[0])) {`); 85 | c.push(` return r[1];`); 86 | c.push(` }`); 87 | c.push(` }`); 88 | c.push(` return "Resource Not Found";`); 89 | c.push(`}`); 90 | if (format === "cjs") { 91 | c.push("exports.getNotFound = getNotFound;"); 92 | } else { 93 | c.push("export { getNotFound };"); 94 | } 95 | return c.join("\n"); 96 | } 97 | function createStaticPathsModule(basePathname, staticPaths, format) { 98 | const assetsPath = basePathname + "assets/"; 99 | const baseBuildPath = basePathname + "build/"; 100 | const c = []; 101 | c.push( 102 | `const staticPaths = new Set(${JSON.stringify( 103 | Array.from(new Set(staticPaths)).sort() 104 | )});` 105 | ); 106 | c.push(`function isStaticPath(method, url) {`); 107 | c.push(` if (method.toUpperCase() !== 'GET') {`); 108 | c.push(` return false;`); 109 | c.push(` }`); 110 | c.push(` const p = url.pathname;`); 111 | c.push(` if (p.startsWith(${JSON.stringify(baseBuildPath)})) {`); 112 | c.push(` return true;`); 113 | c.push(` }`); 114 | c.push(` if (p.startsWith(${JSON.stringify(assetsPath)})) {`); 115 | c.push(` return true;`); 116 | c.push(` }`); 117 | c.push(` if (staticPaths.has(p)) {`); 118 | c.push(` return true;`); 119 | c.push(` }`); 120 | c.push(` if (p.endsWith('/q-data.json')) {`); 121 | c.push(` const pWithoutQdata = p.replace(/\\/q-data.json$/, '');`); 122 | c.push(` if (staticPaths.has(pWithoutQdata + '/')) {`); 123 | c.push(` return true;`); 124 | c.push(` }`); 125 | c.push(` if (staticPaths.has(pWithoutQdata)) {`); 126 | c.push(` return true;`); 127 | c.push(` }`); 128 | c.push(` }`); 129 | c.push(` return false;`); 130 | c.push(`}`); 131 | if (format === "cjs") { 132 | c.push("exports.isStaticPath = isStaticPath;"); 133 | } else { 134 | c.push("export { isStaticPath };"); 135 | } 136 | return c.join("\n"); 137 | } 138 | 139 | // packages/qwik-city/src/adapters/shared/vite/index.ts 140 | function viteAdapter(opts) { 141 | let qwikCityPlugin = null; 142 | let qwikVitePlugin = null; 143 | let serverOutDir = null; 144 | let renderModulePath = null; 145 | let qwikCityPlanModulePath = null; 146 | let isSsrBuild = false; 147 | let format = "esm"; 148 | const outputEntries = []; 149 | const plugin = { 150 | name: `vite-plugin-qwik-city-${opts.name}`, 151 | enforce: "post", 152 | apply: "build", 153 | config(config) { 154 | if (typeof opts.config === "function") { 155 | config = opts.config(config); 156 | } 157 | config.define = { 158 | "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "production"), 159 | ...config.define 160 | }; 161 | return config; 162 | }, 163 | configResolved(config) { 164 | var _a, _b, _c, _d; 165 | isSsrBuild = !!config.build.ssr; 166 | if (isSsrBuild) { 167 | qwikCityPlugin = config.plugins.find( 168 | (p) => p.name === "vite-plugin-qwik-city" 169 | ); 170 | if (!qwikCityPlugin) { 171 | throw new Error("Missing vite-plugin-qwik-city"); 172 | } 173 | qwikVitePlugin = config.plugins.find( 174 | (p) => p.name === "vite-plugin-qwik" 175 | ); 176 | if (!qwikVitePlugin) { 177 | throw new Error("Missing vite-plugin-qwik"); 178 | } 179 | serverOutDir = config.build.outDir; 180 | if (((_a = config.build) == null ? void 0 : _a.ssr) !== true) { 181 | throw new Error( 182 | `"build.ssr" must be set to "true" in order to use the "${opts.name}" adapter.` 183 | ); 184 | } 185 | if (!((_c = (_b = config.build) == null ? void 0 : _b.rollupOptions) == null ? void 0 : _c.input)) { 186 | throw new Error( 187 | `"build.rollupOptions.input" must be set in order to use the "${opts.name}" adapter.` 188 | ); 189 | } 190 | if (((_d = config.ssr) == null ? void 0 : _d.format) === "cjs") { 191 | format = "cjs"; 192 | } 193 | } 194 | }, 195 | generateBundle(_, bundles) { 196 | if (isSsrBuild) { 197 | outputEntries.length = 0; 198 | for (const fileName in bundles) { 199 | const chunk = bundles[fileName]; 200 | if (chunk.type === "chunk" && chunk.isEntry) { 201 | outputEntries.push(fileName); 202 | if (chunk.name === "entry.ssr") { 203 | renderModulePath = join2(serverOutDir, fileName); 204 | } else if (chunk.name === "@qwik-city-plan") { 205 | qwikCityPlanModulePath = join2(serverOutDir, fileName); 206 | } 207 | } 208 | } 209 | if (!renderModulePath) { 210 | throw new Error( 211 | 'Unable to find "entry.ssr" entry point. Did you forget to add it to "build.rollupOptions.input"?' 212 | ); 213 | } 214 | if (!qwikCityPlanModulePath) { 215 | throw new Error( 216 | 'Unable to find "@qwik-city-plan" entry point. Did you forget to add it to "build.rollupOptions.input"?' 217 | ); 218 | } 219 | } 220 | }, 221 | closeBundle: { 222 | sequential: true, 223 | async handler() { 224 | var _a; 225 | if (isSsrBuild && opts.ssg !== null && serverOutDir && (qwikCityPlugin == null ? void 0 : qwikCityPlugin.api) && (qwikVitePlugin == null ? void 0 : qwikVitePlugin.api)) { 226 | const staticPaths = opts.staticPaths || []; 227 | const routes = qwikCityPlugin.api.getRoutes(); 228 | const basePathname = qwikCityPlugin.api.getBasePathname(); 229 | const clientOutDir = qwikVitePlugin.api.getClientOutDir(); 230 | const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir(); 231 | const assetsDir = qwikVitePlugin.api.getAssetsDir(); 232 | const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0; 233 | if (renderModulePath && qwikCityPlanModulePath && clientOutDir && clientPublicOutDir) { 234 | let ssgOrigin = ((_a = opts.ssg) == null ? void 0 : _a.origin) ?? opts.origin; 235 | if (!ssgOrigin) { 236 | ssgOrigin = `https://yoursite.qwik.dev`; 237 | } 238 | if (ssgOrigin.length > 0 && !/:\/\//.test(ssgOrigin)) { 239 | ssgOrigin = `https://${ssgOrigin}`; 240 | } 241 | if (ssgOrigin.startsWith("//")) { 242 | ssgOrigin = `https:${ssgOrigin}`; 243 | } 244 | try { 245 | ssgOrigin = new URL(ssgOrigin).origin; 246 | } catch (e) { 247 | this.warn( 248 | `Invalid "origin" option: "${ssgOrigin}". Using default origin: "https://yoursite.qwik.dev"` 249 | ); 250 | ssgOrigin = `https://yoursite.qwik.dev`; 251 | } 252 | const staticGenerate = await import("../../../static/index.mjs"); 253 | const generateOpts = { 254 | maxWorkers: opts.maxWorkers, 255 | basePathname, 256 | outDir: clientPublicOutDir, 257 | rootDir, 258 | ...opts.ssg, 259 | origin: ssgOrigin, 260 | renderModulePath, 261 | qwikCityPlanModulePath 262 | }; 263 | const staticGenerateResult = await staticGenerate.generate(generateOpts); 264 | if (staticGenerateResult.errors > 0) { 265 | const err = new Error( 266 | `Error while running SSG from "${opts.name}" adapter. At least one path failed to render.` 267 | ); 268 | err.stack = void 0; 269 | this.error(err); 270 | } 271 | staticPaths.push(...staticGenerateResult.staticPaths); 272 | const { staticPathsCode, notFoundPathsCode } = await postBuild( 273 | clientPublicOutDir, 274 | assetsDir ? join2(basePathname, assetsDir) : basePathname, 275 | staticPaths, 276 | format, 277 | !!opts.cleanStaticGenerated 278 | ); 279 | await Promise.all([ 280 | fs2.promises.writeFile(join2(serverOutDir, RESOLVED_STATIC_PATHS_ID), staticPathsCode), 281 | fs2.promises.writeFile( 282 | join2(serverOutDir, RESOLVED_NOT_FOUND_PATHS_ID), 283 | notFoundPathsCode 284 | ) 285 | ]); 286 | if (typeof opts.generate === "function") { 287 | await opts.generate({ 288 | outputEntries, 289 | serverOutDir, 290 | clientOutDir, 291 | clientPublicOutDir, 292 | basePathname, 293 | routes, 294 | assetsDir, 295 | warn: (message) => this.warn(message), 296 | error: (message) => this.error(message) 297 | }); 298 | } 299 | this.warn( 300 | ` 301 | ============================================== 302 | Note: Make sure that you are serving the built files with proper cache headers. 303 | See https://qwik.dev/docs/deployments/#cache-headers for more information. 304 | ==============================================` 305 | ); 306 | } 307 | } 308 | } 309 | } 310 | }; 311 | return plugin; 312 | } 313 | var STATIC_PATHS_ID = "@qwik-city-static-paths"; 314 | var RESOLVED_STATIC_PATHS_ID = `${STATIC_PATHS_ID}.js`; 315 | var NOT_FOUND_PATHS_ID = "@qwik-city-not-found-paths"; 316 | var RESOLVED_NOT_FOUND_PATHS_ID = `${NOT_FOUND_PATHS_ID}.js`; 317 | 318 | // packages/qwik-city/src/adapters/static/vite/index.ts 319 | function staticAdapter(opts) { 320 | return viteAdapter({ 321 | name: "static-generate", 322 | origin: opts.origin, 323 | ssg: { 324 | include: ["/*"], 325 | ...opts 326 | } 327 | }); 328 | } 329 | export { 330 | staticAdapter 331 | }; 332 | -------------------------------------------------------------------------------- /lib/adapters/vercel-edge/vite/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/adapters/vercel-edge/vite/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | vercelEdgeAdapter: () => vercelEdgeAdapter 34 | }); 35 | module.exports = __toCommonJS(index_exports); 36 | var import_vite = require("../../shared/vite/index.cjs"); 37 | var import_node_fs = __toESM(require("node:fs"), 1); 38 | var import_node_path = require("node:path"); 39 | function vercelEdgeAdapter(opts = {}) { 40 | var _a; 41 | return (0, import_vite.viteAdapter)({ 42 | name: "vercel-edge", 43 | origin: ((_a = process == null ? void 0 : process.env) == null ? void 0 : _a.VERCEL_URL) || "https://yoursitename.vercel.app", 44 | ssg: opts.ssg, 45 | staticPaths: opts.staticPaths, 46 | cleanStaticGenerated: true, 47 | config(config) { 48 | var _a2; 49 | const outDir = ((_a2 = config.build) == null ? void 0 : _a2.outDir) || (0, import_node_path.join)(".vercel", "output", "functions", "_qwik-city.func"); 50 | return { 51 | resolve: { 52 | conditions: opts.target === "node" ? ["node", "import", "module", "browser", "default"] : ["edge-light", "webworker", "worker", "browser", "module", "main"] 53 | }, 54 | ssr: { 55 | target: opts.target === "node" ? "node" : "webworker", 56 | noExternal: true 57 | }, 58 | build: { 59 | ssr: true, 60 | outDir, 61 | rollupOptions: { 62 | output: { 63 | format: "es", 64 | hoistTransitiveImports: false 65 | } 66 | } 67 | }, 68 | publicDir: false 69 | }; 70 | }, 71 | async generate({ clientPublicOutDir, serverOutDir, basePathname, outputEntries }) { 72 | const vercelOutputDir = (0, import_vite.getParentDir)(serverOutDir, "output"); 73 | if (opts.outputConfig !== false) { 74 | const vercelOutputConfig = { 75 | routes: [ 76 | { handle: "filesystem" }, 77 | { 78 | src: basePathname + ".*", 79 | dest: "/_qwik-city" 80 | } 81 | ], 82 | version: 3 83 | }; 84 | await import_node_fs.default.promises.writeFile( 85 | (0, import_node_path.join)(vercelOutputDir, "config.json"), 86 | JSON.stringify(vercelOutputConfig, null, 2) 87 | ); 88 | } 89 | let entrypoint = opts.vcConfigEntryPoint; 90 | if (!entrypoint) { 91 | if (outputEntries.some((n) => n === "entry.vercel-edge.mjs")) { 92 | entrypoint = "entry.vercel-edge.mjs"; 93 | } else { 94 | entrypoint = "entry.vercel-edge.js"; 95 | } 96 | } 97 | const vcConfigPath = (0, import_node_path.join)(serverOutDir, ".vc-config.json"); 98 | const vcConfig = { 99 | runtime: "edge", 100 | entrypoint, 101 | envVarsInUse: opts.vcConfigEnvVarsInUse 102 | }; 103 | await import_node_fs.default.promises.writeFile(vcConfigPath, JSON.stringify(vcConfig, null, 2)); 104 | let vercelStaticDir = (0, import_node_path.join)(vercelOutputDir, "static"); 105 | const basePathnameParts = basePathname.split("/").filter((p) => p.length > 0); 106 | if (basePathnameParts.length > 0) { 107 | vercelStaticDir = (0, import_node_path.join)(vercelStaticDir, ...basePathnameParts); 108 | } 109 | await import_node_fs.default.promises.rm(vercelStaticDir, { recursive: true, force: true }); 110 | await import_node_fs.default.promises.mkdir((0, import_node_path.dirname)(vercelStaticDir), { recursive: true }); 111 | await import_node_fs.default.promises.rename(clientPublicOutDir, vercelStaticDir); 112 | } 113 | }); 114 | } 115 | // Annotate the CommonJS export names for ESM import in node: 116 | 0 && (module.exports = { 117 | vercelEdgeAdapter 118 | }); 119 | -------------------------------------------------------------------------------- /lib/adapters/vercel-edge/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ServerAdapterOptions } from '../../shared/vite'; 2 | import type { StaticGenerateRenderOptions } from '@builder.io/qwik-city/static'; 3 | 4 | export { StaticGenerateRenderOptions } 5 | 6 | /** @public */ 7 | export declare function vercelEdgeAdapter(opts?: VercelEdgeAdapterOptions): any; 8 | 9 | /** @public */ 10 | export declare interface VercelEdgeAdapterOptions extends ServerAdapterOptions { 11 | /** 12 | * Determines if the build should auto-generate the `.vercel/output/config.json` config. 13 | * 14 | * Defaults to `true`. 15 | */ 16 | outputConfig?: boolean; 17 | /** 18 | * The `entrypoint` property in the `.vc-config.json` file. Indicates the initial file where code 19 | * will be executed for the Edge Function. 20 | * 21 | * Defaults to `entry.vercel-edge.js`. 22 | */ 23 | vcConfigEntryPoint?: string; 24 | /** 25 | * The `envVarsInUse` property in the `.vc-config.json` file. List of environment variable names 26 | * that will be available for the Edge Function to utilize. 27 | * 28 | * Defaults to `undefined`. 29 | */ 30 | vcConfigEnvVarsInUse?: string[]; 31 | /** 32 | * Manually add pathnames that should be treated as static paths and not SSR. For example, when 33 | * these pathnames are requested, their response should come from a static file, rather than a 34 | * server-side rendered response. 35 | */ 36 | staticPaths?: string[]; 37 | /** 38 | * Define the `target` property in the `ssr` object in the `vite.config.ts` file. 39 | * 40 | * Defaults to `webworker`. 41 | */ 42 | target?: 'webworker' | 'node'; 43 | } 44 | 45 | export { } 46 | -------------------------------------------------------------------------------- /lib/adapters/vercel-edge/vite/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/adapters/vercel-edge/vite/index.ts 2 | import { getParentDir, viteAdapter } from "../../shared/vite/index.mjs"; 3 | import fs from "node:fs"; 4 | import { dirname, join } from "node:path"; 5 | function vercelEdgeAdapter(opts = {}) { 6 | var _a; 7 | return viteAdapter({ 8 | name: "vercel-edge", 9 | origin: ((_a = process == null ? void 0 : process.env) == null ? void 0 : _a.VERCEL_URL) || "https://yoursitename.vercel.app", 10 | ssg: opts.ssg, 11 | staticPaths: opts.staticPaths, 12 | cleanStaticGenerated: true, 13 | config(config) { 14 | var _a2; 15 | const outDir = ((_a2 = config.build) == null ? void 0 : _a2.outDir) || join(".vercel", "output", "functions", "_qwik-city.func"); 16 | return { 17 | resolve: { 18 | conditions: opts.target === "node" ? ["node", "import", "module", "browser", "default"] : ["edge-light", "webworker", "worker", "browser", "module", "main"] 19 | }, 20 | ssr: { 21 | target: opts.target === "node" ? "node" : "webworker", 22 | noExternal: true 23 | }, 24 | build: { 25 | ssr: true, 26 | outDir, 27 | rollupOptions: { 28 | output: { 29 | format: "es", 30 | hoistTransitiveImports: false 31 | } 32 | } 33 | }, 34 | publicDir: false 35 | }; 36 | }, 37 | async generate({ clientPublicOutDir, serverOutDir, basePathname, outputEntries }) { 38 | const vercelOutputDir = getParentDir(serverOutDir, "output"); 39 | if (opts.outputConfig !== false) { 40 | const vercelOutputConfig = { 41 | routes: [ 42 | { handle: "filesystem" }, 43 | { 44 | src: basePathname + ".*", 45 | dest: "/_qwik-city" 46 | } 47 | ], 48 | version: 3 49 | }; 50 | await fs.promises.writeFile( 51 | join(vercelOutputDir, "config.json"), 52 | JSON.stringify(vercelOutputConfig, null, 2) 53 | ); 54 | } 55 | let entrypoint = opts.vcConfigEntryPoint; 56 | if (!entrypoint) { 57 | if (outputEntries.some((n) => n === "entry.vercel-edge.mjs")) { 58 | entrypoint = "entry.vercel-edge.mjs"; 59 | } else { 60 | entrypoint = "entry.vercel-edge.js"; 61 | } 62 | } 63 | const vcConfigPath = join(serverOutDir, ".vc-config.json"); 64 | const vcConfig = { 65 | runtime: "edge", 66 | entrypoint, 67 | envVarsInUse: opts.vcConfigEnvVarsInUse 68 | }; 69 | await fs.promises.writeFile(vcConfigPath, JSON.stringify(vcConfig, null, 2)); 70 | let vercelStaticDir = join(vercelOutputDir, "static"); 71 | const basePathnameParts = basePathname.split("/").filter((p) => p.length > 0); 72 | if (basePathnameParts.length > 0) { 73 | vercelStaticDir = join(vercelStaticDir, ...basePathnameParts); 74 | } 75 | await fs.promises.rm(vercelStaticDir, { recursive: true, force: true }); 76 | await fs.promises.mkdir(dirname(vercelStaticDir), { recursive: true }); 77 | await fs.promises.rename(clientPublicOutDir, vercelStaticDir); 78 | } 79 | }); 80 | } 81 | export { 82 | vercelEdgeAdapter 83 | }; 84 | -------------------------------------------------------------------------------- /lib/middleware/aws-lambda/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/aws-lambda/index.ts 2 | import { createQwikCity as createQwikCityNode } from "@builder.io/qwik-city/middleware/node"; 3 | function createQwikCity(opts) { 4 | try { 5 | const { router, staticFile, notFound } = createQwikCityNode({ 6 | render: opts.render, 7 | qwikCityPlan: opts.qwikCityPlan, 8 | manifest: opts.manifest, 9 | static: { 10 | cacheControl: "public, max-age=31557600" 11 | }, 12 | getOrigin(req) { 13 | if (process.env.IS_OFFLINE) { 14 | return `http://${req.headers.host}`; 15 | } 16 | return null; 17 | } 18 | }); 19 | const fixPath = (pathT) => { 20 | if (opts.qwikCityPlan.trailingSlash) { 21 | const url = new URL(pathT, "http://aws-qwik.local"); 22 | if (url.pathname.includes(".", url.pathname.lastIndexOf("/"))) { 23 | return pathT; 24 | } 25 | if (!url.pathname.endsWith("/")) { 26 | return url.pathname + "/" + url.search; 27 | } 28 | } 29 | return pathT; 30 | }; 31 | const handle = (req, res) => { 32 | req.url = fixPath(req.url); 33 | staticFile(req, res, () => { 34 | router(req, res, () => { 35 | notFound(req, res, () => { 36 | }); 37 | }); 38 | }); 39 | }; 40 | return { fixPath, router, staticFile, notFound, handle }; 41 | } catch (err) { 42 | throw new Error(err.message); 43 | } 44 | } 45 | export { 46 | createQwikCity 47 | }; 48 | -------------------------------------------------------------------------------- /lib/middleware/azure-swa/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { AzureFunction } from '@azure/functions'; 2 | import type { Context } from '@azure/functions'; 3 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 4 | 5 | /** @public */ 6 | export declare function createQwikCity(opts: QwikCityAzureOptions): AzureFunction; 7 | 8 | /** @public */ 9 | export declare interface PlatformAzure extends Partial { 10 | } 11 | 12 | /** @public */ 13 | export declare interface QwikCityAzureOptions extends ServerRenderOptions { 14 | } 15 | 16 | export { } 17 | -------------------------------------------------------------------------------- /lib/middleware/azure-swa/index.mjs: -------------------------------------------------------------------------------- 1 | var __create = Object.create; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __getProtoOf = Object.getPrototypeOf; 6 | var __hasOwnProp = Object.prototype.hasOwnProperty; 7 | var __commonJS = (cb, mod) => function __require() { 8 | return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 19 | // If the importer is in node compatibility mode or this is not an ESM 20 | // file that has been converted to a CommonJS file using a Babel- 21 | // compatible transform (i.e. "__esModule" has not been set), then set 22 | // "default" to the CommonJS "module.exports" for node compatibility. 23 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 24 | mod 25 | )); 26 | 27 | // node_modules/.pnpm/set-cookie-parser@2.6.0/node_modules/set-cookie-parser/lib/set-cookie.js 28 | var require_set_cookie = __commonJS({ 29 | "node_modules/.pnpm/set-cookie-parser@2.6.0/node_modules/set-cookie-parser/lib/set-cookie.js"(exports, module) { 30 | "use strict"; 31 | var defaultParseOptions = { 32 | decodeValues: true, 33 | map: false, 34 | silent: false 35 | }; 36 | function isNonEmptyString(str) { 37 | return typeof str === "string" && !!str.trim(); 38 | } 39 | function parseString2(setCookieValue, options) { 40 | var parts = setCookieValue.split(";").filter(isNonEmptyString); 41 | var nameValuePairStr = parts.shift(); 42 | var parsed = parseNameValuePair(nameValuePairStr); 43 | var name = parsed.name; 44 | var value = parsed.value; 45 | options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; 46 | try { 47 | value = options.decodeValues ? decodeURIComponent(value) : value; 48 | } catch (e) { 49 | console.error( 50 | "set-cookie-parser encountered an error while decoding a cookie with value '" + value + "'. Set options.decodeValues to false to disable this feature.", 51 | e 52 | ); 53 | } 54 | var cookie = { 55 | name, 56 | value 57 | }; 58 | parts.forEach(function(part) { 59 | var sides = part.split("="); 60 | var key = sides.shift().trimLeft().toLowerCase(); 61 | var value2 = sides.join("="); 62 | if (key === "expires") { 63 | cookie.expires = new Date(value2); 64 | } else if (key === "max-age") { 65 | cookie.maxAge = parseInt(value2, 10); 66 | } else if (key === "secure") { 67 | cookie.secure = true; 68 | } else if (key === "httponly") { 69 | cookie.httpOnly = true; 70 | } else if (key === "samesite") { 71 | cookie.sameSite = value2; 72 | } else { 73 | cookie[key] = value2; 74 | } 75 | }); 76 | return cookie; 77 | } 78 | function parseNameValuePair(nameValuePairStr) { 79 | var name = ""; 80 | var value = ""; 81 | var nameValueArr = nameValuePairStr.split("="); 82 | if (nameValueArr.length > 1) { 83 | name = nameValueArr.shift(); 84 | value = nameValueArr.join("="); 85 | } else { 86 | value = nameValuePairStr; 87 | } 88 | return { name, value }; 89 | } 90 | function parse(input, options) { 91 | options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; 92 | if (!input) { 93 | if (!options.map) { 94 | return []; 95 | } else { 96 | return {}; 97 | } 98 | } 99 | if (input.headers) { 100 | if (typeof input.headers.getSetCookie === "function") { 101 | input = input.headers.getSetCookie(); 102 | } else if (input.headers["set-cookie"]) { 103 | input = input.headers["set-cookie"]; 104 | } else { 105 | var sch = input.headers[Object.keys(input.headers).find(function(key) { 106 | return key.toLowerCase() === "set-cookie"; 107 | })]; 108 | if (!sch && input.headers.cookie && !options.silent) { 109 | console.warn( 110 | "Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning." 111 | ); 112 | } 113 | input = sch; 114 | } 115 | } 116 | if (!Array.isArray(input)) { 117 | input = [input]; 118 | } 119 | options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; 120 | if (!options.map) { 121 | return input.filter(isNonEmptyString).map(function(str) { 122 | return parseString2(str, options); 123 | }); 124 | } else { 125 | var cookies = {}; 126 | return input.filter(isNonEmptyString).reduce(function(cookies2, str) { 127 | var cookie = parseString2(str, options); 128 | cookies2[cookie.name] = cookie; 129 | return cookies2; 130 | }, cookies); 131 | } 132 | } 133 | function splitCookiesString(cookiesString) { 134 | if (Array.isArray(cookiesString)) { 135 | return cookiesString; 136 | } 137 | if (typeof cookiesString !== "string") { 138 | return []; 139 | } 140 | var cookiesStrings = []; 141 | var pos = 0; 142 | var start; 143 | var ch; 144 | var lastComma; 145 | var nextStart; 146 | var cookiesSeparatorFound; 147 | function skipWhitespace() { 148 | while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) { 149 | pos += 1; 150 | } 151 | return pos < cookiesString.length; 152 | } 153 | function notSpecialChar() { 154 | ch = cookiesString.charAt(pos); 155 | return ch !== "=" && ch !== ";" && ch !== ","; 156 | } 157 | while (pos < cookiesString.length) { 158 | start = pos; 159 | cookiesSeparatorFound = false; 160 | while (skipWhitespace()) { 161 | ch = cookiesString.charAt(pos); 162 | if (ch === ",") { 163 | lastComma = pos; 164 | pos += 1; 165 | skipWhitespace(); 166 | nextStart = pos; 167 | while (pos < cookiesString.length && notSpecialChar()) { 168 | pos += 1; 169 | } 170 | if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") { 171 | cookiesSeparatorFound = true; 172 | pos = nextStart; 173 | cookiesStrings.push(cookiesString.substring(start, lastComma)); 174 | start = pos; 175 | } else { 176 | pos = lastComma + 1; 177 | } 178 | } else { 179 | pos += 1; 180 | } 181 | } 182 | if (!cookiesSeparatorFound || pos >= cookiesString.length) { 183 | cookiesStrings.push(cookiesString.substring(start, cookiesString.length)); 184 | } 185 | } 186 | return cookiesStrings; 187 | } 188 | module.exports = parse; 189 | module.exports.parse = parse; 190 | module.exports.parseString = parseString2; 191 | module.exports.splitCookiesString = splitCookiesString; 192 | } 193 | }); 194 | 195 | // packages/qwik-city/src/middleware/azure-swa/index.ts 196 | var import_set_cookie_parser = __toESM(require_set_cookie(), 1); 197 | import { setServerPlatform } from "@builder.io/qwik/server"; 198 | import { requestHandler } from "../request-handler/index.mjs"; 199 | import { getNotFound } from "@qwik-city-not-found-paths"; 200 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 201 | import { isStaticPath } from "@qwik-city-static-paths"; 202 | function createQwikCity(opts) { 203 | const qwikSerializer = { 204 | _deserializeData, 205 | _serializeData, 206 | _verifySerializable 207 | }; 208 | if (opts.manifest) { 209 | setServerPlatform(opts.manifest); 210 | } 211 | async function onAzureSwaRequest(context, req) { 212 | try { 213 | const url = new URL(req.headers["x-ms-original-url"]); 214 | const options = { 215 | method: req.method || "GET", 216 | headers: req.headers, 217 | body: req.bufferBody || req.rawBody || req.body 218 | }; 219 | const serverRequestEv = { 220 | mode: "server", 221 | locale: void 0, 222 | url, 223 | platform: context, 224 | env: { 225 | get(key) { 226 | return process.env[key]; 227 | } 228 | }, 229 | request: new Request(url, options), 230 | getWritableStream: (status, headers, cookies, resolve) => { 231 | const response = { 232 | status, 233 | body: new Uint8Array(), 234 | headers: {}, 235 | cookies: cookies.headers().map((header) => (0, import_set_cookie_parser.parseString)(header)) 236 | }; 237 | headers.forEach((value, key) => response.headers[key] = value); 238 | return new WritableStream({ 239 | write(chunk) { 240 | if (response.body instanceof Uint8Array) { 241 | const newBuffer = new Uint8Array(response.body.length + chunk.length); 242 | newBuffer.set(response.body); 243 | newBuffer.set(chunk, response.body.length); 244 | response.body = newBuffer; 245 | } 246 | }, 247 | close() { 248 | resolve(response); 249 | } 250 | }); 251 | }, 252 | getClientConn: () => { 253 | return { 254 | ip: req.headers["x-forwarded-client-Ip"], 255 | country: void 0 256 | }; 257 | } 258 | }; 259 | const handledResponse = await requestHandler(serverRequestEv, opts, qwikSerializer); 260 | if (handledResponse) { 261 | handledResponse.completion.then((err) => { 262 | if (err) { 263 | console.error(err); 264 | } 265 | }); 266 | const response = await handledResponse.response; 267 | if (response) { 268 | return response; 269 | } 270 | } 271 | const notFoundHtml = isStaticPath(req.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 272 | return { 273 | status: 404, 274 | headers: { "Content-Type": "text/html; charset=utf-8", "X-Not-Found": url.pathname }, 275 | body: notFoundHtml 276 | }; 277 | } catch (e) { 278 | console.error(e); 279 | return { 280 | status: 500, 281 | headers: { "Content-Type": "text/plain; charset=utf-8" } 282 | }; 283 | } 284 | } 285 | return onAzureSwaRequest; 286 | } 287 | export { 288 | createQwikCity 289 | }; 290 | -------------------------------------------------------------------------------- /lib/middleware/bun/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ClientConn } from '@builder.io/qwik-city/middleware/request-handler'; 2 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 3 | 4 | /** @public */ 5 | export declare function createQwikCity(opts: QwikCityBunOptions): { 6 | router: (request: Request) => Promise; 7 | notFound: (request: Request) => Promise; 8 | staticFile: (request: Request) => Promise; 9 | }; 10 | 11 | /** @public */ 12 | export declare interface QwikCityBunOptions extends ServerRenderOptions { 13 | /** Options for serving static files */ 14 | static?: { 15 | /** The root folder for statics files. Defaults to /dist */ 16 | root?: string; 17 | /** Set the Cache-Control header for all static files */ 18 | cacheControl?: string; 19 | }; 20 | getClientConn?: (request: Request) => ClientConn; 21 | } 22 | 23 | export { } 24 | -------------------------------------------------------------------------------- /lib/middleware/bun/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/bun/index.ts 2 | import { 3 | mergeHeadersCookies, 4 | requestHandler, 5 | _TextEncoderStream_polyfill 6 | } from "../request-handler/index.mjs"; 7 | import { getNotFound } from "@qwik-city-not-found-paths"; 8 | import { isStaticPath } from "@qwik-city-static-paths"; 9 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 10 | import { setServerPlatform } from "@builder.io/qwik/server"; 11 | 12 | // packages/qwik-city/src/middleware/request-handler/mime-types.ts 13 | var MIME_TYPES = { 14 | "3gp": "video/3gpp", 15 | "3gpp": "video/3gpp", 16 | asf: "video/x-ms-asf", 17 | asx: "video/x-ms-asf", 18 | avi: "video/x-msvideo", 19 | avif: "image/avif", 20 | bmp: "image/x-ms-bmp", 21 | css: "text/css", 22 | flv: "video/x-flv", 23 | gif: "image/gif", 24 | htm: "text/html", 25 | html: "text/html", 26 | ico: "image/x-icon", 27 | jng: "image/x-jng", 28 | jpeg: "image/jpeg", 29 | jpg: "image/jpeg", 30 | js: "application/javascript", 31 | json: "application/json", 32 | kar: "audio/midi", 33 | m4a: "audio/x-m4a", 34 | m4v: "video/x-m4v", 35 | mid: "audio/midi", 36 | midi: "audio/midi", 37 | mng: "video/x-mng", 38 | mov: "video/quicktime", 39 | mp3: "audio/mpeg", 40 | mp4: "video/mp4", 41 | mpeg: "video/mpeg", 42 | mpg: "video/mpeg", 43 | ogg: "audio/ogg", 44 | pdf: "application/pdf", 45 | png: "image/png", 46 | rar: "application/x-rar-compressed", 47 | shtml: "text/html", 48 | svg: "image/svg+xml", 49 | svgz: "image/svg+xml", 50 | tif: "image/tiff", 51 | tiff: "image/tiff", 52 | ts: "video/mp2t", 53 | txt: "text/plain", 54 | wbmp: "image/vnd.wap.wbmp", 55 | webm: "video/webm", 56 | webp: "image/webp", 57 | wmv: "video/x-ms-wmv", 58 | woff: "font/woff", 59 | woff2: "font/woff2", 60 | xml: "text/xml", 61 | zip: "application/zip" 62 | }; 63 | 64 | // packages/qwik-city/src/middleware/bun/index.ts 65 | import { join, extname } from "node:path"; 66 | function createQwikCity(opts) { 67 | var _a; 68 | globalThis.TextEncoderStream ||= _TextEncoderStream_polyfill; 69 | const qwikSerializer = { 70 | _deserializeData, 71 | _serializeData, 72 | _verifySerializable 73 | }; 74 | if (opts.manifest) { 75 | setServerPlatform(opts.manifest); 76 | } 77 | const staticFolder = ((_a = opts.static) == null ? void 0 : _a.root) ?? join(Bun.fileURLToPath(import.meta.url), "..", "..", "dist"); 78 | async function router(request) { 79 | try { 80 | const url = new URL(request.url); 81 | const serverRequestEv = { 82 | mode: "server", 83 | locale: void 0, 84 | url, 85 | env: { 86 | get(key) { 87 | return Bun.env[key]; 88 | } 89 | }, 90 | request, 91 | getWritableStream: (status, headers, cookies, resolve) => { 92 | const { readable, writable } = new TransformStream(); 93 | const response = new Response(readable, { 94 | status, 95 | headers: mergeHeadersCookies(headers, cookies) 96 | }); 97 | resolve(response); 98 | return writable; 99 | }, 100 | platform: { 101 | ssr: true 102 | }, 103 | getClientConn: () => { 104 | return opts.getClientConn ? opts.getClientConn(request) : {}; 105 | } 106 | }; 107 | const handledResponse = await requestHandler(serverRequestEv, opts, qwikSerializer); 108 | if (handledResponse) { 109 | handledResponse.completion.then((v) => { 110 | if (v) { 111 | console.error(v); 112 | } 113 | }); 114 | const response = await handledResponse.response; 115 | if (response) { 116 | const status = response.status; 117 | const location = response.headers.get("Location"); 118 | const isRedirect = status >= 301 && status <= 308 && location; 119 | if (isRedirect) { 120 | return new Response(null, response); 121 | } 122 | return response; 123 | } 124 | } 125 | return null; 126 | } catch (e) { 127 | console.error(e); 128 | return new Response(String(e || "Error"), { 129 | status: 500, 130 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "bun-server" } 131 | }); 132 | } 133 | } 134 | const notFound = async (request) => { 135 | try { 136 | const url = new URL(request.url); 137 | const notFoundHtml = isStaticPath(request.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 138 | return new Response(notFoundHtml, { 139 | status: 404, 140 | headers: { "Content-Type": "text/html; charset=utf-8", "X-Not-Found": url.pathname } 141 | }); 142 | } catch (e) { 143 | console.error(e); 144 | return new Response(String(e || "Error"), { 145 | status: 500, 146 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "bun-server" } 147 | }); 148 | } 149 | }; 150 | const openStaticFile = async (url) => { 151 | const pathname = url.pathname; 152 | const fileName = pathname.slice(url.pathname.lastIndexOf("/")); 153 | let filePath; 154 | if (fileName.includes(".")) { 155 | filePath = join(staticFolder, pathname); 156 | } else if (opts.qwikCityPlan.trailingSlash) { 157 | filePath = join(staticFolder, pathname + "index.html"); 158 | } else { 159 | filePath = join(staticFolder, pathname, "index.html"); 160 | } 161 | return { 162 | filePath, 163 | content: Bun.file(filePath) 164 | }; 165 | }; 166 | const staticFile = async (request) => { 167 | var _a2; 168 | try { 169 | const url = new URL(request.url); 170 | if (isStaticPath(request.method || "GET", url)) { 171 | const { filePath, content } = await openStaticFile(url); 172 | if (!await content.exists()) { 173 | return new Response("Not Found", { 174 | status: 404, 175 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Not-Found": url.pathname } 176 | }); 177 | } 178 | const ext = extname(filePath).replace(/^\./, ""); 179 | return new Response(await content.stream(), { 180 | status: 200, 181 | headers: { 182 | "content-type": MIME_TYPES[ext] || "text/plain; charset=utf-8", 183 | "Cache-Control": ((_a2 = opts.static) == null ? void 0 : _a2.cacheControl) || "max-age=3600" 184 | } 185 | }); 186 | } 187 | return null; 188 | } catch (e) { 189 | console.error(e); 190 | return new Response(String(e || "Error"), { 191 | status: 500, 192 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "bun-server" } 193 | }); 194 | } 195 | }; 196 | return { 197 | router, 198 | notFound, 199 | staticFile 200 | }; 201 | } 202 | export { 203 | createQwikCity 204 | }; 205 | -------------------------------------------------------------------------------- /lib/middleware/cloudflare-pages/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 2 | 3 | /** @public */ 4 | export declare function createQwikCity(opts: QwikCityCloudflarePagesOptions): (request: PlatformCloudflarePages['request'], env: PlatformCloudflarePages['env'] & { 5 | ASSETS: { 6 | fetch: (req: Request) => Response; 7 | }; 8 | }, ctx: PlatformCloudflarePages['ctx']) => Promise; 9 | 10 | /** @public */ 11 | export declare interface PlatformCloudflarePages { 12 | request: Request; 13 | env?: Record; 14 | ctx: { 15 | waitUntil: (promise: Promise) => void; 16 | }; 17 | } 18 | 19 | /** @public */ 20 | export declare interface QwikCityCloudflarePagesOptions extends ServerRenderOptions { 21 | } 22 | 23 | export { } 24 | -------------------------------------------------------------------------------- /lib/middleware/cloudflare-pages/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/cloudflare-pages/index.ts 2 | import { 3 | mergeHeadersCookies, 4 | requestHandler, 5 | _TextEncoderStream_polyfill 6 | } from "../request-handler/index.mjs"; 7 | import { getNotFound } from "@qwik-city-not-found-paths"; 8 | import { isStaticPath } from "@qwik-city-static-paths"; 9 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 10 | import { setServerPlatform } from "@builder.io/qwik/server"; 11 | function createQwikCity(opts) { 12 | try { 13 | new globalThis.TextEncoderStream(); 14 | } catch (e) { 15 | globalThis.TextEncoderStream = _TextEncoderStream_polyfill; 16 | } 17 | const qwikSerializer = { 18 | _deserializeData, 19 | _serializeData, 20 | _verifySerializable 21 | }; 22 | if (opts.manifest) { 23 | setServerPlatform(opts.manifest); 24 | } 25 | async function onCloudflarePagesFetch(request, env, ctx) { 26 | try { 27 | const url = new URL(request.url); 28 | if (isStaticPath(request.method, url)) { 29 | return env.ASSETS.fetch(request); 30 | } 31 | const useCache = url.hostname !== "127.0.0.1" && url.hostname !== "localhost" && url.port === "" && request.method === "GET"; 32 | const cacheKey = new Request(url.href, request); 33 | const cache = useCache ? await caches.open("custom:qwikcity") : null; 34 | if (cache) { 35 | const cachedResponse = await cache.match(cacheKey); 36 | if (cachedResponse) { 37 | return cachedResponse; 38 | } 39 | } 40 | const serverRequestEv = { 41 | mode: "server", 42 | locale: void 0, 43 | url, 44 | request, 45 | env: { 46 | get(key) { 47 | return env[key]; 48 | } 49 | }, 50 | getWritableStream: (status, headers, cookies, resolve) => { 51 | const { readable, writable } = new TransformStream(); 52 | const response = new Response(readable, { 53 | status, 54 | headers: mergeHeadersCookies(headers, cookies) 55 | }); 56 | resolve(response); 57 | return writable; 58 | }, 59 | getClientConn: () => { 60 | return { 61 | ip: request.headers.get("CF-connecting-ip") || "", 62 | country: request.headers.get("CF-IPCountry") || "" 63 | }; 64 | }, 65 | platform: { 66 | request, 67 | env, 68 | ctx 69 | } 70 | }; 71 | const handledResponse = await requestHandler(serverRequestEv, opts, qwikSerializer); 72 | if (handledResponse) { 73 | handledResponse.completion.then((v) => { 74 | if (v) { 75 | console.error(v); 76 | } 77 | }); 78 | const response = await handledResponse.response; 79 | if (response) { 80 | if (response.ok && cache && response.headers.has("Cache-Control")) { 81 | ctx.waitUntil(cache.put(cacheKey, response.clone())); 82 | } 83 | return response; 84 | } 85 | } 86 | const notFoundHtml = isStaticPath(request.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 87 | return new Response(notFoundHtml, { 88 | status: 404, 89 | headers: { "Content-Type": "text/html; charset=utf-8", "X-Not-Found": url.pathname } 90 | }); 91 | } catch (e) { 92 | console.error(e); 93 | return new Response(String(e || "Error"), { 94 | status: 500, 95 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "cloudflare-pages" } 96 | }); 97 | } 98 | } 99 | return onCloudflarePagesFetch; 100 | } 101 | export { 102 | createQwikCity 103 | }; 104 | -------------------------------------------------------------------------------- /lib/middleware/deno/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ClientConn } from '@builder.io/qwik-city/middleware/request-handler'; 2 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 3 | 4 | /** @public */ 5 | export declare function createQwikCity(opts: QwikCityDenoOptions): { 6 | router: (request: Request, info: ServeHandlerInfo) => Promise; 7 | notFound: (request: Request) => Promise; 8 | staticFile: (request: Request) => Promise; 9 | }; 10 | 11 | /** @public */ 12 | export declare interface NetAddr { 13 | transport: 'tcp' | 'udp'; 14 | hostname: string; 15 | port: number; 16 | } 17 | 18 | /** @public */ 19 | export declare interface QwikCityDenoOptions extends ServerRenderOptions { 20 | /** Options for serving static files */ 21 | static?: { 22 | /** The root folder for statics files. Defaults to /dist */ 23 | root?: string; 24 | /** Set the Cache-Control header for all static files */ 25 | cacheControl?: string; 26 | }; 27 | getClientConn?: (request: Request, info: ServeHandlerInfo) => ClientConn; 28 | } 29 | 30 | /** @public */ 31 | export declare interface ServeHandlerInfo { 32 | remoteAddr: NetAddr; 33 | } 34 | 35 | export { } 36 | -------------------------------------------------------------------------------- /lib/middleware/deno/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/deno/index.ts 2 | import { 3 | mergeHeadersCookies, 4 | requestHandler 5 | } from "../request-handler/index.mjs"; 6 | import { getNotFound } from "@qwik-city-not-found-paths"; 7 | import { isStaticPath } from "@qwik-city-static-paths"; 8 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 9 | import { setServerPlatform } from "@builder.io/qwik/server"; 10 | 11 | // packages/qwik-city/src/middleware/request-handler/mime-types.ts 12 | var MIME_TYPES = { 13 | "3gp": "video/3gpp", 14 | "3gpp": "video/3gpp", 15 | asf: "video/x-ms-asf", 16 | asx: "video/x-ms-asf", 17 | avi: "video/x-msvideo", 18 | avif: "image/avif", 19 | bmp: "image/x-ms-bmp", 20 | css: "text/css", 21 | flv: "video/x-flv", 22 | gif: "image/gif", 23 | htm: "text/html", 24 | html: "text/html", 25 | ico: "image/x-icon", 26 | jng: "image/x-jng", 27 | jpeg: "image/jpeg", 28 | jpg: "image/jpeg", 29 | js: "application/javascript", 30 | json: "application/json", 31 | kar: "audio/midi", 32 | m4a: "audio/x-m4a", 33 | m4v: "video/x-m4v", 34 | mid: "audio/midi", 35 | midi: "audio/midi", 36 | mng: "video/x-mng", 37 | mov: "video/quicktime", 38 | mp3: "audio/mpeg", 39 | mp4: "video/mp4", 40 | mpeg: "video/mpeg", 41 | mpg: "video/mpeg", 42 | ogg: "audio/ogg", 43 | pdf: "application/pdf", 44 | png: "image/png", 45 | rar: "application/x-rar-compressed", 46 | shtml: "text/html", 47 | svg: "image/svg+xml", 48 | svgz: "image/svg+xml", 49 | tif: "image/tiff", 50 | tiff: "image/tiff", 51 | ts: "video/mp2t", 52 | txt: "text/plain", 53 | wbmp: "image/vnd.wap.wbmp", 54 | webm: "video/webm", 55 | webp: "image/webp", 56 | wmv: "video/x-ms-wmv", 57 | woff: "font/woff", 58 | woff2: "font/woff2", 59 | xml: "text/xml", 60 | zip: "application/zip" 61 | }; 62 | 63 | // packages/qwik-city/src/middleware/deno/index.ts 64 | import { extname, fromFileUrl, join } from "https://deno.land/std/path/mod.ts"; 65 | function createQwikCity(opts) { 66 | var _a; 67 | const qwikSerializer = { 68 | _deserializeData, 69 | _serializeData, 70 | _verifySerializable 71 | }; 72 | if (opts.manifest) { 73 | setServerPlatform(opts.manifest); 74 | } 75 | const staticFolder = ((_a = opts.static) == null ? void 0 : _a.root) ?? join(fromFileUrl(import.meta.url), "..", "..", "dist"); 76 | async function router(request, info) { 77 | try { 78 | const url = new URL(request.url); 79 | const serverRequestEv = { 80 | mode: "server", 81 | locale: void 0, 82 | url, 83 | // @ts-ignore 84 | env: Deno.env, 85 | request, 86 | getWritableStream: (status, headers, cookies, resolve) => { 87 | const { readable, writable } = new TransformStream(); 88 | const response = new Response(readable, { 89 | status, 90 | headers: mergeHeadersCookies(headers, cookies) 91 | }); 92 | resolve(response); 93 | return writable; 94 | }, 95 | platform: { 96 | ssr: true 97 | }, 98 | getClientConn: () => { 99 | return opts.getClientConn ? opts.getClientConn(request, info) : { 100 | ip: info.remoteAddr.hostname 101 | }; 102 | } 103 | }; 104 | const handledResponse = await requestHandler(serverRequestEv, opts, qwikSerializer); 105 | if (handledResponse) { 106 | handledResponse.completion.then((v) => { 107 | if (v) { 108 | console.error(v); 109 | } 110 | }); 111 | const response = await handledResponse.response; 112 | if (response) { 113 | return response; 114 | } 115 | } 116 | return null; 117 | } catch (e) { 118 | console.error(e); 119 | return new Response(String(e || "Error"), { 120 | status: 500, 121 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "deno-server" } 122 | }); 123 | } 124 | } 125 | const notFound = async (request) => { 126 | try { 127 | const url = new URL(request.url); 128 | const notFoundHtml = isStaticPath(request.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 129 | return new Response(notFoundHtml, { 130 | status: 404, 131 | headers: { "Content-Type": "text/html; charset=utf-8", "X-Not-Found": url.pathname } 132 | }); 133 | } catch (e) { 134 | console.error(e); 135 | return new Response(String(e || "Error"), { 136 | status: 500, 137 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "deno-server" } 138 | }); 139 | } 140 | }; 141 | const openStaticFile = async (url) => { 142 | const pathname = url.pathname; 143 | const fileName = pathname.slice(url.pathname.lastIndexOf("/")); 144 | let filePath; 145 | if (fileName.includes(".")) { 146 | filePath = join(staticFolder, pathname); 147 | } else if (opts.qwikCityPlan.trailingSlash) { 148 | filePath = join(staticFolder, pathname + "index.html"); 149 | } else { 150 | filePath = join(staticFolder, pathname, "index.html"); 151 | } 152 | return { 153 | filePath, 154 | // @ts-ignore 155 | content: await Deno.open(filePath, { read: true }) 156 | }; 157 | }; 158 | const staticFile = async (request) => { 159 | var _a2; 160 | try { 161 | const url = new URL(request.url); 162 | if (isStaticPath(request.method || "GET", url)) { 163 | const { filePath, content } = await openStaticFile(url); 164 | const ext = extname(filePath).replace(/^\./, ""); 165 | return new Response(content.readable, { 166 | status: 200, 167 | headers: { 168 | "content-type": MIME_TYPES[ext] || "text/plain; charset=utf-8", 169 | "Cache-Control": ((_a2 = opts.static) == null ? void 0 : _a2.cacheControl) || "max-age=3600" 170 | } 171 | }); 172 | } 173 | return null; 174 | } catch (e) { 175 | console.error(e); 176 | return new Response(String(e || "Error"), { 177 | status: 500, 178 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "deno-server" } 179 | }); 180 | } 181 | }; 182 | return { 183 | router, 184 | notFound, 185 | staticFile 186 | }; 187 | } 188 | export { 189 | createQwikCity 190 | }; 191 | -------------------------------------------------------------------------------- /lib/middleware/firebase/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 2 | 3 | /** @public */ 4 | export declare function createQwikCity(opts: QwikCityFirebaseOptions): (req: any, res: any) => Promise; 5 | 6 | /** @public */ 7 | export declare interface PlatformFirebase extends Object { 8 | } 9 | 10 | /** @public */ 11 | export declare interface QwikCityFirebaseOptions extends ServerRenderOptions { 12 | } 13 | 14 | export { } 15 | -------------------------------------------------------------------------------- /lib/middleware/firebase/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/firebase/index.ts 2 | import { createQwikCity as createQwikCityNode } from "@builder.io/qwik-city/middleware/node"; 3 | function createQwikCity(opts) { 4 | const { staticFile, notFound, router } = createQwikCityNode({ 5 | render: opts.render, 6 | manifest: opts.manifest, 7 | qwikCityPlan: opts.qwikCityPlan, 8 | static: { 9 | cacheControl: "public, max-age=31557600" 10 | }, 11 | getOrigin(req) { 12 | if (process.env.IS_OFFLINE) { 13 | return `http://${req.headers.host}`; 14 | } 15 | return null; 16 | } 17 | }); 18 | const qwikApp = (req, res) => { 19 | return staticFile(req, res, () => { 20 | router(req, res, () => notFound(req, res, () => { 21 | })); 22 | }); 23 | }; 24 | return qwikApp; 25 | } 26 | export { 27 | createQwikCity 28 | }; 29 | -------------------------------------------------------------------------------- /lib/middleware/netlify-edge/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { Context } from '@netlify/edge-functions'; 2 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 3 | 4 | /** @public */ 5 | export declare function createQwikCity(opts: QwikCityNetlifyOptions): (request: Request, context: Context) => Promise; 6 | 7 | /** @public */ 8 | export declare interface PlatformNetlify extends Partial> { 9 | } 10 | 11 | /** @public */ 12 | export declare interface QwikCityNetlifyOptions extends ServerRenderOptions { 13 | } 14 | 15 | export { } 16 | -------------------------------------------------------------------------------- /lib/middleware/netlify-edge/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/netlify-edge/index.ts 2 | import { 3 | mergeHeadersCookies, 4 | requestHandler 5 | } from "../request-handler/index.mjs"; 6 | import { getNotFound } from "@qwik-city-not-found-paths"; 7 | import { isStaticPath } from "@qwik-city-static-paths"; 8 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 9 | import { setServerPlatform } from "@builder.io/qwik/server"; 10 | function createQwikCity(opts) { 11 | const qwikSerializer = { 12 | _deserializeData, 13 | _serializeData, 14 | _verifySerializable 15 | }; 16 | if (opts.manifest) { 17 | setServerPlatform(opts.manifest); 18 | } 19 | async function onNetlifyEdgeRequest(request, context) { 20 | try { 21 | const url = new URL(request.url); 22 | if (isStaticPath(request.method, url) || url.pathname.startsWith("/.netlify")) { 23 | return context.next(); 24 | } 25 | const serverRequestEv = { 26 | mode: "server", 27 | locale: void 0, 28 | url, 29 | env: Deno.env, 30 | request, 31 | getWritableStream: (status, headers, cookies, resolve) => { 32 | const { readable, writable } = new TransformStream(); 33 | const response = new Response(readable, { 34 | status, 35 | headers: mergeHeadersCookies(headers, cookies) 36 | }); 37 | resolve(response); 38 | return writable; 39 | }, 40 | getClientConn: () => { 41 | var _a; 42 | return { 43 | ip: context.ip, 44 | country: (_a = context.geo.country) == null ? void 0 : _a.code 45 | }; 46 | }, 47 | platform: context 48 | }; 49 | const handledResponse = await requestHandler(serverRequestEv, opts, qwikSerializer); 50 | if (handledResponse) { 51 | handledResponse.completion.then((v) => { 52 | if (v) { 53 | console.error(v); 54 | } 55 | }); 56 | const response = await handledResponse.response; 57 | if (response) { 58 | return response; 59 | } 60 | } 61 | const notFoundHtml = isStaticPath(request.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 62 | return new Response(notFoundHtml, { 63 | status: 404, 64 | headers: { "Content-Type": "text/html; charset=utf-8", "X-Not-Found": url.pathname } 65 | }); 66 | } catch (e) { 67 | console.error(e); 68 | return new Response(String(e || "Error"), { 69 | status: 500, 70 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "netlify-edge" } 71 | }); 72 | } 73 | } 74 | return onNetlifyEdgeRequest; 75 | } 76 | export { 77 | createQwikCity 78 | }; 79 | -------------------------------------------------------------------------------- /lib/middleware/node/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __create = Object.create; 3 | var __defProp = Object.defineProperty; 4 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 | var __getOwnPropNames = Object.getOwnPropertyNames; 6 | var __getProtoOf = Object.getPrototypeOf; 7 | var __hasOwnProp = Object.prototype.hasOwnProperty; 8 | var __export = (target, all) => { 9 | for (var name in all) 10 | __defProp(target, name, { get: all[name], enumerable: true }); 11 | }; 12 | var __copyProps = (to, from, except, desc) => { 13 | if (from && typeof from === "object" || typeof from === "function") { 14 | for (let key of __getOwnPropNames(from)) 15 | if (!__hasOwnProp.call(to, key) && key !== except) 16 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 17 | } 18 | return to; 19 | }; 20 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 21 | // If the importer is in node compatibility mode or this is not an ESM 22 | // file that has been converted to a CommonJS file using a Babel- 23 | // compatible transform (i.e. "__esModule" has not been set), then set 24 | // "default" to the CommonJS "module.exports" for node compatibility. 25 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 26 | mod 27 | )); 28 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 29 | 30 | // packages/qwik-city/src/middleware/node/index.ts 31 | var index_exports = {}; 32 | __export(index_exports, { 33 | createQwikCity: () => createQwikCity 34 | }); 35 | module.exports = __toCommonJS(index_exports); 36 | var import_request_handler = require("../request-handler/index.cjs"); 37 | var import_server = require("@builder.io/qwik/server"); 38 | var import_qwik_city_not_found_paths = require("@qwik-city-not-found-paths"); 39 | var import_qwik_city_static_paths = require("@qwik-city-static-paths"); 40 | var import_node_fs = require("node:fs"); 41 | var import_node_path = require("node:path"); 42 | var import_node_url = require("node:url"); 43 | 44 | // packages/qwik-city/src/middleware/node/http.ts 45 | var import_node_http2 = require("node:http2"); 46 | function computeOrigin(req, opts) { 47 | var _a; 48 | return ((_a = opts == null ? void 0 : opts.getOrigin) == null ? void 0 : _a.call(opts, req)) ?? (opts == null ? void 0 : opts.origin) ?? process.env.ORIGIN ?? fallbackOrigin(req); 49 | } 50 | function fallbackOrigin(req) { 51 | const { PROTOCOL_HEADER, HOST_HEADER } = process.env; 52 | const headers = req.headers; 53 | const protocol = PROTOCOL_HEADER && headers[PROTOCOL_HEADER] || (req.socket.encrypted || req.connection.encrypted ? "https" : "http"); 54 | const hostHeader = HOST_HEADER ?? (req instanceof import_node_http2.Http2ServerRequest ? ":authority" : "host"); 55 | const host = headers[hostHeader]; 56 | return `${protocol}://${host}`; 57 | } 58 | function getUrl(req, origin) { 59 | return normalizeUrl(req.originalUrl || req.url || "/", origin); 60 | } 61 | function isIgnoredError(message = "") { 62 | const ignoredErrors = ["The stream has been destroyed", "write after end"]; 63 | return ignoredErrors.some((ignored) => message.includes(ignored)); 64 | } 65 | var invalidHeadersPattern = /^:(method|scheme|authority|path)$/i; 66 | function normalizeUrl(url, base) { 67 | const DOUBLE_SLASH_REG = /\/\/|\\\\/g; 68 | return new URL(url.replace(DOUBLE_SLASH_REG, "/"), base); 69 | } 70 | async function fromNodeHttp(url, req, res, mode, getClientConn) { 71 | const requestHeaders = new Headers(); 72 | const nodeRequestHeaders = req.headers; 73 | try { 74 | for (const [key, value] of Object.entries(nodeRequestHeaders)) { 75 | if (invalidHeadersPattern.test(key)) { 76 | continue; 77 | } 78 | if (typeof value === "string") { 79 | requestHeaders.set(key, value); 80 | } else if (Array.isArray(value)) { 81 | for (const v of value) { 82 | requestHeaders.append(key, v); 83 | } 84 | } 85 | } 86 | } catch (err) { 87 | console.error(err); 88 | } 89 | const getRequestBody = async function* () { 90 | for await (const chunk of req) { 91 | yield chunk; 92 | } 93 | }; 94 | const body = req.method === "HEAD" || req.method === "GET" ? void 0 : getRequestBody(); 95 | const controller = new AbortController(); 96 | const options = { 97 | method: req.method, 98 | headers: requestHeaders, 99 | body, 100 | signal: controller.signal, 101 | duplex: "half" 102 | }; 103 | res.on("close", () => { 104 | controller.abort(); 105 | }); 106 | const serverRequestEv = { 107 | mode, 108 | url, 109 | request: new Request(url.href, options), 110 | env: { 111 | get(key) { 112 | return process.env[key]; 113 | } 114 | }, 115 | getWritableStream: (status, headers, cookies) => { 116 | res.statusCode = status; 117 | try { 118 | for (const [key, value] of headers) { 119 | if (invalidHeadersPattern.test(key)) { 120 | continue; 121 | } 122 | res.setHeader(key, value); 123 | } 124 | const cookieHeaders = cookies.headers(); 125 | if (cookieHeaders.length > 0) { 126 | res.setHeader("Set-Cookie", cookieHeaders); 127 | } 128 | } catch (err) { 129 | console.error(err); 130 | } 131 | return new WritableStream({ 132 | write(chunk) { 133 | if (res.closed || res.destroyed) { 134 | return; 135 | } 136 | res.write(chunk, (error) => { 137 | if (error && !isIgnoredError(error.message)) { 138 | console.error(error); 139 | } 140 | }); 141 | }, 142 | close() { 143 | res.end(); 144 | } 145 | }); 146 | }, 147 | getClientConn: () => { 148 | return getClientConn ? getClientConn(req) : { 149 | ip: req.socket.remoteAddress 150 | }; 151 | }, 152 | platform: { 153 | ssr: true, 154 | incomingMessage: req, 155 | node: process.versions.node 156 | // Weirdly needed to make typecheck of insights happy 157 | }, 158 | locale: void 0 159 | }; 160 | return serverRequestEv; 161 | } 162 | 163 | // packages/qwik-city/src/middleware/request-handler/mime-types.ts 164 | var MIME_TYPES = { 165 | "3gp": "video/3gpp", 166 | "3gpp": "video/3gpp", 167 | asf: "video/x-ms-asf", 168 | asx: "video/x-ms-asf", 169 | avi: "video/x-msvideo", 170 | avif: "image/avif", 171 | bmp: "image/x-ms-bmp", 172 | css: "text/css", 173 | flv: "video/x-flv", 174 | gif: "image/gif", 175 | htm: "text/html", 176 | html: "text/html", 177 | ico: "image/x-icon", 178 | jng: "image/x-jng", 179 | jpeg: "image/jpeg", 180 | jpg: "image/jpeg", 181 | js: "application/javascript", 182 | json: "application/json", 183 | kar: "audio/midi", 184 | m4a: "audio/x-m4a", 185 | m4v: "video/x-m4v", 186 | mid: "audio/midi", 187 | midi: "audio/midi", 188 | mng: "video/x-mng", 189 | mov: "video/quicktime", 190 | mp3: "audio/mpeg", 191 | mp4: "video/mp4", 192 | mpeg: "video/mpeg", 193 | mpg: "video/mpeg", 194 | ogg: "audio/ogg", 195 | pdf: "application/pdf", 196 | png: "image/png", 197 | rar: "application/x-rar-compressed", 198 | shtml: "text/html", 199 | svg: "image/svg+xml", 200 | svgz: "image/svg+xml", 201 | tif: "image/tiff", 202 | tiff: "image/tiff", 203 | ts: "video/mp2t", 204 | txt: "text/plain", 205 | wbmp: "image/vnd.wap.wbmp", 206 | webm: "video/webm", 207 | webp: "image/webp", 208 | wmv: "video/x-ms-wmv", 209 | woff: "font/woff", 210 | woff2: "font/woff2", 211 | xml: "text/xml", 212 | zip: "application/zip" 213 | }; 214 | 215 | // packages/qwik-city/src/middleware/node/node-fetch.ts 216 | var import_web = require("node:stream/web"); 217 | var import_undici = require("undici"); 218 | var import_crypto = __toESM(require("crypto"), 1); 219 | function patchGlobalThis() { 220 | if (typeof global !== "undefined" && typeof globalThis.fetch !== "function" && typeof process !== "undefined" && process.versions.node) { 221 | globalThis.fetch = import_undici.fetch; 222 | globalThis.Headers = import_undici.Headers; 223 | globalThis.Request = import_undici.Request; 224 | globalThis.Response = import_undici.Response; 225 | globalThis.FormData = import_undici.FormData; 226 | } 227 | if (typeof globalThis.TextEncoderStream === "undefined") { 228 | globalThis.TextEncoderStream = import_web.TextEncoderStream; 229 | globalThis.TextDecoderStream = import_web.TextDecoderStream; 230 | } 231 | if (typeof globalThis.WritableStream === "undefined") { 232 | globalThis.WritableStream = import_web.WritableStream; 233 | globalThis.ReadableStream = import_web.ReadableStream; 234 | } 235 | if (typeof globalThis.crypto === "undefined") { 236 | globalThis.crypto = import_crypto.default.webcrypto; 237 | } 238 | } 239 | 240 | // packages/qwik-city/src/middleware/node/index.ts 241 | var import_qwik = require("@builder.io/qwik"); 242 | var import_meta = {}; 243 | function createQwikCity(opts) { 244 | var _a; 245 | patchGlobalThis(); 246 | const qwikSerializer = { 247 | _deserializeData: import_qwik._deserializeData, 248 | _serializeData: import_qwik._serializeData, 249 | _verifySerializable: import_qwik._verifySerializable 250 | }; 251 | if (opts.manifest) { 252 | (0, import_server.setServerPlatform)(opts.manifest); 253 | } 254 | const staticFolder = ((_a = opts.static) == null ? void 0 : _a.root) ?? (0, import_node_path.join)((0, import_node_url.fileURLToPath)(import_meta.url), "..", "..", "dist"); 255 | const router = async (req, res, next) => { 256 | try { 257 | const origin = computeOrigin(req, opts); 258 | const serverRequestEv = await fromNodeHttp( 259 | getUrl(req, origin), 260 | req, 261 | res, 262 | "server", 263 | opts.getClientConn 264 | ); 265 | const handled = await (0, import_request_handler.requestHandler)(serverRequestEv, opts, qwikSerializer); 266 | if (handled) { 267 | const err = await handled.completion; 268 | if (err) { 269 | throw err; 270 | } 271 | if (handled.requestEv.headersSent) { 272 | return; 273 | } 274 | } 275 | next(); 276 | } catch (e) { 277 | console.error(e); 278 | next(e); 279 | } 280 | }; 281 | const notFound = async (req, res, next) => { 282 | try { 283 | if (!res.headersSent) { 284 | const origin = computeOrigin(req, opts); 285 | const url = getUrl(req, origin); 286 | const notFoundHtml = (0, import_qwik_city_static_paths.isStaticPath)(req.method || "GET", url) ? "Not Found" : (0, import_qwik_city_not_found_paths.getNotFound)(url.pathname); 287 | res.writeHead(404, { 288 | "Content-Type": "text/html; charset=utf-8", 289 | "X-Not-Found": url.pathname 290 | }); 291 | res.end(notFoundHtml); 292 | } 293 | } catch (e) { 294 | console.error(e); 295 | next(e); 296 | } 297 | }; 298 | const staticFile = async (req, res, next) => { 299 | var _a2; 300 | try { 301 | const origin = computeOrigin(req, opts); 302 | const url = getUrl(req, origin); 303 | if ((0, import_qwik_city_static_paths.isStaticPath)(req.method || "GET", url)) { 304 | const pathname = url.pathname; 305 | let filePath; 306 | if ((0, import_node_path.basename)(pathname).includes(".")) { 307 | filePath = (0, import_node_path.join)(staticFolder, pathname); 308 | } else if (opts.qwikCityPlan.trailingSlash) { 309 | filePath = (0, import_node_path.join)(staticFolder, pathname + "index.html"); 310 | } else { 311 | filePath = (0, import_node_path.join)(staticFolder, pathname, "index.html"); 312 | } 313 | const ext = (0, import_node_path.extname)(filePath).replace(/^\./, ""); 314 | const stream = (0, import_node_fs.createReadStream)(filePath); 315 | stream.on("error", next); 316 | const contentType = MIME_TYPES[ext]; 317 | if (contentType) { 318 | res.setHeader("Content-Type", contentType); 319 | } 320 | if ((_a2 = opts.static) == null ? void 0 : _a2.cacheControl) { 321 | res.setHeader("Cache-Control", opts.static.cacheControl); 322 | } 323 | stream.pipe(res); 324 | return; 325 | } 326 | return next(); 327 | } catch (e) { 328 | console.error(e); 329 | next(e); 330 | } 331 | }; 332 | return { 333 | router, 334 | notFound, 335 | staticFile 336 | }; 337 | } 338 | // Annotate the CommonJS export names for ESM import in node: 339 | 0 && (module.exports = { 340 | createQwikCity 341 | }); 342 | -------------------------------------------------------------------------------- /lib/middleware/node/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { ClientConn } from '@builder.io/qwik-city/middleware/request-handler'; 4 | import type { Http2ServerRequest } from 'node:http2'; 5 | import type { IncomingMessage } from 'node:http'; 6 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 7 | import type { ServerResponse } from 'node:http'; 8 | 9 | /** @public */ 10 | export declare function createQwikCity(opts: QwikCityNodeRequestOptions): { 11 | router: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: NodeRequestNextFunction) => Promise; 12 | notFound: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e: any) => void) => Promise; 13 | staticFile: (req: IncomingMessage | Http2ServerRequest, res: ServerResponse, next: (e?: any) => void) => Promise; 14 | }; 15 | 16 | /** @public */ 17 | export declare interface NodeRequestNextFunction { 18 | (err?: any): void; 19 | } 20 | 21 | /** @public */ 22 | export declare interface PlatformNode { 23 | ssr?: true; 24 | incomingMessage?: IncomingMessage | Http2ServerRequest; 25 | node?: string; 26 | } 27 | 28 | /** @public */ 29 | export declare interface QwikCityNodeRequestOptions extends ServerRenderOptions { 30 | /** Options for serving static files */ 31 | static?: { 32 | /** The root folder for statics files. Defaults to /dist */ 33 | root?: string; 34 | /** Set the Cache-Control header for all static files */ 35 | cacheControl?: string; 36 | }; 37 | /** 38 | * Provide a function that computes the origin of the server, used to resolve relative URLs and 39 | * validate the request origin against CSRF attacks. 40 | * 41 | * When not specified, it defaults to the `ORIGIN` environment variable (if set). 42 | * 43 | * If `ORIGIN` is not set, it's derived from the incoming request, which is not recommended for 44 | * production use. You can specify the `PROTOCOL_HEADER`, `HOST_HEADER` to `X-Forwarded-Proto` and 45 | * `X-Forwarded-Host` respectively to override the default behavior. 46 | */ 47 | getOrigin?: (req: IncomingMessage | Http2ServerRequest) => string | null; 48 | /** Provide a function that returns a `ClientConn` for the given request. */ 49 | getClientConn?: (req: IncomingMessage | Http2ServerRequest) => ClientConn; 50 | /** @deprecated Use `getOrigin` instead. */ 51 | origin?: string; 52 | } 53 | 54 | export { } 55 | -------------------------------------------------------------------------------- /lib/middleware/node/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/node/index.ts 2 | import { requestHandler } from "../request-handler/index.mjs"; 3 | import { setServerPlatform } from "@builder.io/qwik/server"; 4 | import { getNotFound } from "@qwik-city-not-found-paths"; 5 | import { isStaticPath } from "@qwik-city-static-paths"; 6 | import { createReadStream } from "node:fs"; 7 | import { extname, join, basename } from "node:path"; 8 | import { fileURLToPath } from "node:url"; 9 | 10 | // packages/qwik-city/src/middleware/node/http.ts 11 | import { Http2ServerRequest } from "node:http2"; 12 | function computeOrigin(req, opts) { 13 | var _a; 14 | return ((_a = opts == null ? void 0 : opts.getOrigin) == null ? void 0 : _a.call(opts, req)) ?? (opts == null ? void 0 : opts.origin) ?? process.env.ORIGIN ?? fallbackOrigin(req); 15 | } 16 | function fallbackOrigin(req) { 17 | const { PROTOCOL_HEADER, HOST_HEADER } = process.env; 18 | const headers = req.headers; 19 | const protocol = PROTOCOL_HEADER && headers[PROTOCOL_HEADER] || (req.socket.encrypted || req.connection.encrypted ? "https" : "http"); 20 | const hostHeader = HOST_HEADER ?? (req instanceof Http2ServerRequest ? ":authority" : "host"); 21 | const host = headers[hostHeader]; 22 | return `${protocol}://${host}`; 23 | } 24 | function getUrl(req, origin) { 25 | return normalizeUrl(req.originalUrl || req.url || "/", origin); 26 | } 27 | function isIgnoredError(message = "") { 28 | const ignoredErrors = ["The stream has been destroyed", "write after end"]; 29 | return ignoredErrors.some((ignored) => message.includes(ignored)); 30 | } 31 | var invalidHeadersPattern = /^:(method|scheme|authority|path)$/i; 32 | function normalizeUrl(url, base) { 33 | const DOUBLE_SLASH_REG = /\/\/|\\\\/g; 34 | return new URL(url.replace(DOUBLE_SLASH_REG, "/"), base); 35 | } 36 | async function fromNodeHttp(url, req, res, mode, getClientConn) { 37 | const requestHeaders = new Headers(); 38 | const nodeRequestHeaders = req.headers; 39 | try { 40 | for (const [key, value] of Object.entries(nodeRequestHeaders)) { 41 | if (invalidHeadersPattern.test(key)) { 42 | continue; 43 | } 44 | if (typeof value === "string") { 45 | requestHeaders.set(key, value); 46 | } else if (Array.isArray(value)) { 47 | for (const v of value) { 48 | requestHeaders.append(key, v); 49 | } 50 | } 51 | } 52 | } catch (err) { 53 | console.error(err); 54 | } 55 | const getRequestBody = async function* () { 56 | for await (const chunk of req) { 57 | yield chunk; 58 | } 59 | }; 60 | const body = req.method === "HEAD" || req.method === "GET" ? void 0 : getRequestBody(); 61 | const controller = new AbortController(); 62 | const options = { 63 | method: req.method, 64 | headers: requestHeaders, 65 | body, 66 | signal: controller.signal, 67 | duplex: "half" 68 | }; 69 | res.on("close", () => { 70 | controller.abort(); 71 | }); 72 | const serverRequestEv = { 73 | mode, 74 | url, 75 | request: new Request(url.href, options), 76 | env: { 77 | get(key) { 78 | return process.env[key]; 79 | } 80 | }, 81 | getWritableStream: (status, headers, cookies) => { 82 | res.statusCode = status; 83 | try { 84 | for (const [key, value] of headers) { 85 | if (invalidHeadersPattern.test(key)) { 86 | continue; 87 | } 88 | res.setHeader(key, value); 89 | } 90 | const cookieHeaders = cookies.headers(); 91 | if (cookieHeaders.length > 0) { 92 | res.setHeader("Set-Cookie", cookieHeaders); 93 | } 94 | } catch (err) { 95 | console.error(err); 96 | } 97 | return new WritableStream({ 98 | write(chunk) { 99 | if (res.closed || res.destroyed) { 100 | return; 101 | } 102 | res.write(chunk, (error) => { 103 | if (error && !isIgnoredError(error.message)) { 104 | console.error(error); 105 | } 106 | }); 107 | }, 108 | close() { 109 | res.end(); 110 | } 111 | }); 112 | }, 113 | getClientConn: () => { 114 | return getClientConn ? getClientConn(req) : { 115 | ip: req.socket.remoteAddress 116 | }; 117 | }, 118 | platform: { 119 | ssr: true, 120 | incomingMessage: req, 121 | node: process.versions.node 122 | // Weirdly needed to make typecheck of insights happy 123 | }, 124 | locale: void 0 125 | }; 126 | return serverRequestEv; 127 | } 128 | 129 | // packages/qwik-city/src/middleware/request-handler/mime-types.ts 130 | var MIME_TYPES = { 131 | "3gp": "video/3gpp", 132 | "3gpp": "video/3gpp", 133 | asf: "video/x-ms-asf", 134 | asx: "video/x-ms-asf", 135 | avi: "video/x-msvideo", 136 | avif: "image/avif", 137 | bmp: "image/x-ms-bmp", 138 | css: "text/css", 139 | flv: "video/x-flv", 140 | gif: "image/gif", 141 | htm: "text/html", 142 | html: "text/html", 143 | ico: "image/x-icon", 144 | jng: "image/x-jng", 145 | jpeg: "image/jpeg", 146 | jpg: "image/jpeg", 147 | js: "application/javascript", 148 | json: "application/json", 149 | kar: "audio/midi", 150 | m4a: "audio/x-m4a", 151 | m4v: "video/x-m4v", 152 | mid: "audio/midi", 153 | midi: "audio/midi", 154 | mng: "video/x-mng", 155 | mov: "video/quicktime", 156 | mp3: "audio/mpeg", 157 | mp4: "video/mp4", 158 | mpeg: "video/mpeg", 159 | mpg: "video/mpeg", 160 | ogg: "audio/ogg", 161 | pdf: "application/pdf", 162 | png: "image/png", 163 | rar: "application/x-rar-compressed", 164 | shtml: "text/html", 165 | svg: "image/svg+xml", 166 | svgz: "image/svg+xml", 167 | tif: "image/tiff", 168 | tiff: "image/tiff", 169 | ts: "video/mp2t", 170 | txt: "text/plain", 171 | wbmp: "image/vnd.wap.wbmp", 172 | webm: "video/webm", 173 | webp: "image/webp", 174 | wmv: "video/x-ms-wmv", 175 | woff: "font/woff", 176 | woff2: "font/woff2", 177 | xml: "text/xml", 178 | zip: "application/zip" 179 | }; 180 | 181 | // packages/qwik-city/src/middleware/node/node-fetch.ts 182 | import { 183 | TextEncoderStream, 184 | TextDecoderStream, 185 | WritableStream as WritableStream2, 186 | ReadableStream 187 | } from "node:stream/web"; 188 | import { fetch, Headers as Headers2, Request as Request2, Response, FormData } from "undici"; 189 | import crypto from "crypto"; 190 | function patchGlobalThis() { 191 | if (typeof global !== "undefined" && typeof globalThis.fetch !== "function" && typeof process !== "undefined" && process.versions.node) { 192 | globalThis.fetch = fetch; 193 | globalThis.Headers = Headers2; 194 | globalThis.Request = Request2; 195 | globalThis.Response = Response; 196 | globalThis.FormData = FormData; 197 | } 198 | if (typeof globalThis.TextEncoderStream === "undefined") { 199 | globalThis.TextEncoderStream = TextEncoderStream; 200 | globalThis.TextDecoderStream = TextDecoderStream; 201 | } 202 | if (typeof globalThis.WritableStream === "undefined") { 203 | globalThis.WritableStream = WritableStream2; 204 | globalThis.ReadableStream = ReadableStream; 205 | } 206 | if (typeof globalThis.crypto === "undefined") { 207 | globalThis.crypto = crypto.webcrypto; 208 | } 209 | } 210 | 211 | // packages/qwik-city/src/middleware/node/index.ts 212 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 213 | function createQwikCity(opts) { 214 | var _a; 215 | patchGlobalThis(); 216 | const qwikSerializer = { 217 | _deserializeData, 218 | _serializeData, 219 | _verifySerializable 220 | }; 221 | if (opts.manifest) { 222 | setServerPlatform(opts.manifest); 223 | } 224 | const staticFolder = ((_a = opts.static) == null ? void 0 : _a.root) ?? join(fileURLToPath(import.meta.url), "..", "..", "dist"); 225 | const router = async (req, res, next) => { 226 | try { 227 | const origin = computeOrigin(req, opts); 228 | const serverRequestEv = await fromNodeHttp( 229 | getUrl(req, origin), 230 | req, 231 | res, 232 | "server", 233 | opts.getClientConn 234 | ); 235 | const handled = await requestHandler(serverRequestEv, opts, qwikSerializer); 236 | if (handled) { 237 | const err = await handled.completion; 238 | if (err) { 239 | throw err; 240 | } 241 | if (handled.requestEv.headersSent) { 242 | return; 243 | } 244 | } 245 | next(); 246 | } catch (e) { 247 | console.error(e); 248 | next(e); 249 | } 250 | }; 251 | const notFound = async (req, res, next) => { 252 | try { 253 | if (!res.headersSent) { 254 | const origin = computeOrigin(req, opts); 255 | const url = getUrl(req, origin); 256 | const notFoundHtml = isStaticPath(req.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 257 | res.writeHead(404, { 258 | "Content-Type": "text/html; charset=utf-8", 259 | "X-Not-Found": url.pathname 260 | }); 261 | res.end(notFoundHtml); 262 | } 263 | } catch (e) { 264 | console.error(e); 265 | next(e); 266 | } 267 | }; 268 | const staticFile = async (req, res, next) => { 269 | var _a2; 270 | try { 271 | const origin = computeOrigin(req, opts); 272 | const url = getUrl(req, origin); 273 | if (isStaticPath(req.method || "GET", url)) { 274 | const pathname = url.pathname; 275 | let filePath; 276 | if (basename(pathname).includes(".")) { 277 | filePath = join(staticFolder, pathname); 278 | } else if (opts.qwikCityPlan.trailingSlash) { 279 | filePath = join(staticFolder, pathname + "index.html"); 280 | } else { 281 | filePath = join(staticFolder, pathname, "index.html"); 282 | } 283 | const ext = extname(filePath).replace(/^\./, ""); 284 | const stream = createReadStream(filePath); 285 | stream.on("error", next); 286 | const contentType = MIME_TYPES[ext]; 287 | if (contentType) { 288 | res.setHeader("Content-Type", contentType); 289 | } 290 | if ((_a2 = opts.static) == null ? void 0 : _a2.cacheControl) { 291 | res.setHeader("Cache-Control", opts.static.cacheControl); 292 | } 293 | stream.pipe(res); 294 | return; 295 | } 296 | return next(); 297 | } catch (e) { 298 | console.error(e); 299 | next(e); 300 | } 301 | }; 302 | return { 303 | router, 304 | notFound, 305 | staticFile 306 | }; 307 | } 308 | export { 309 | createQwikCity 310 | }; 311 | -------------------------------------------------------------------------------- /lib/middleware/vercel-edge/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { ServerRenderOptions } from '@builder.io/qwik-city/middleware/request-handler'; 2 | 3 | /** @public */ 4 | export declare function createQwikCity(opts: QwikCityVercelEdgeOptions): (request: Request) => Promise; 5 | 6 | /** @public */ 7 | export declare interface PlatformVercel { 8 | } 9 | 10 | /** @public */ 11 | export declare interface QwikCityVercelEdgeOptions extends ServerRenderOptions { 12 | } 13 | 14 | export { } 15 | -------------------------------------------------------------------------------- /lib/middleware/vercel-edge/index.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/middleware/vercel-edge/index.ts 2 | import { 3 | mergeHeadersCookies, 4 | requestHandler 5 | } from "../request-handler/index.mjs"; 6 | import { getNotFound } from "@qwik-city-not-found-paths"; 7 | import { isStaticPath } from "@qwik-city-static-paths"; 8 | import { _deserializeData, _serializeData, _verifySerializable } from "@builder.io/qwik"; 9 | import { setServerPlatform } from "@builder.io/qwik/server"; 10 | var COUNTRY_HEADER_NAME = "x-vercel-ip-country"; 11 | var IP_HEADER_NAME = "x-real-ip"; 12 | var VERCEL_COOKIE = "__vdpl"; 13 | var VERCEL_SKEW_PROTECTION_ENABLED = "VERCEL_SKEW_PROTECTION_ENABLED"; 14 | var VERCEL_DEPLOYMENT_ID = "VERCEL_DEPLOYMENT_ID"; 15 | var BASE_URL = "BASE_URL"; 16 | function createQwikCity(opts) { 17 | const qwikSerializer = { 18 | _deserializeData, 19 | _serializeData, 20 | _verifySerializable 21 | }; 22 | if (opts.manifest) { 23 | setServerPlatform(opts.manifest); 24 | } 25 | async function onVercelEdgeRequest(request) { 26 | try { 27 | const url = new URL(request.url); 28 | if (isStaticPath(request.method, url)) { 29 | return new Response(null, { 30 | headers: { 31 | "x-middleware-next": "1" 32 | } 33 | }); 34 | } 35 | const p = (() => globalThis.process)(); 36 | const serverRequestEv = { 37 | mode: "server", 38 | locale: void 0, 39 | url, 40 | request, 41 | env: { 42 | get(key) { 43 | return p.env[key]; 44 | } 45 | }, 46 | getWritableStream: (status, headers, cookies, resolve) => { 47 | const { readable, writable } = new TransformStream(); 48 | if (serverRequestEv.env.get(VERCEL_SKEW_PROTECTION_ENABLED)) { 49 | const deploymentId = serverRequestEv.env.get(VERCEL_DEPLOYMENT_ID) || ""; 50 | const baseUrl = serverRequestEv.env.get(BASE_URL) || "/"; 51 | if (request.headers.has("Sec-Fetch-Dest")) { 52 | cookies.set(VERCEL_COOKIE, deploymentId, { 53 | path: baseUrl, 54 | secure: true, 55 | sameSite: true, 56 | httpOnly: true 57 | }); 58 | } 59 | } 60 | const response = new Response(readable, { 61 | status, 62 | headers: mergeHeadersCookies(headers, cookies) 63 | }); 64 | resolve(response); 65 | return writable; 66 | }, 67 | platform: {}, 68 | getClientConn: () => { 69 | return { 70 | ip: request.headers.get(IP_HEADER_NAME) ?? void 0, 71 | country: request.headers.get(COUNTRY_HEADER_NAME) ?? void 0 72 | }; 73 | } 74 | }; 75 | const handledResponse = await requestHandler(serverRequestEv, opts, qwikSerializer); 76 | if (handledResponse) { 77 | handledResponse.completion.then((v) => { 78 | if (v) { 79 | console.error(v); 80 | } 81 | }); 82 | const response = await handledResponse.response; 83 | if (response) { 84 | return response; 85 | } 86 | } 87 | const notFoundHtml = isStaticPath(request.method || "GET", url) ? "Not Found" : getNotFound(url.pathname); 88 | return new Response(notFoundHtml, { 89 | status: 404, 90 | headers: { "Content-Type": "text/html; charset=utf-8", "X-Not-Found": url.pathname } 91 | }); 92 | } catch (e) { 93 | console.error(e); 94 | return new Response(String(e || "Error"), { 95 | status: 500, 96 | headers: { "Content-Type": "text/plain; charset=utf-8", "X-Error": "vercel-edge" } 97 | }); 98 | } 99 | } 100 | return onVercelEdgeRequest; 101 | } 102 | export { 103 | createQwikCity 104 | }; 105 | -------------------------------------------------------------------------------- /lib/modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@qwik-city-plan' { 2 | export const routes: any[]; 3 | export const menus: any[]; 4 | export const trailingSlash: boolean; 5 | export const basePathname: string; 6 | export const cacheModules: boolean; 7 | const defaultExport: { 8 | routes: any[]; 9 | menus: any[]; 10 | trailingSlash: boolean; 11 | basePathname: string; 12 | cacheModules: boolean; 13 | }; 14 | export default defaultExport; 15 | } 16 | declare module '@qwik-city-not-found-paths' { 17 | function getNotFound(_pathname: string): string; 18 | export { getNotFound }; 19 | } 20 | declare module '@qwik-city-static-paths' { 21 | function isStaticPath(method: string, url: URL): boolean; 22 | export { isStaticPath }; 23 | } 24 | -------------------------------------------------------------------------------- /lib/service-worker.cjs: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @deprecated This is no longer needed, Qwik now automatically embeds preloading logic into the 5 | * application. 6 | * 7 | * If your service-worker.ts file contains no custom code, you should deploy to production until 8 | * you're sure that all users picked up the new version, then you can remove it and also remove 9 | * the `` component from your `Root.tsx`. 10 | * 11 | * If you do have custom service worker logic, you should keep the `service-worker.ts` file and 12 | * `` component, but remove the `setupServiceWorker()` call. 13 | * @public 14 | */ 15 | const setupServiceWorker = () => { }; 16 | 17 | exports.setupServiceWorker = setupServiceWorker; 18 | -------------------------------------------------------------------------------- /lib/service-worker.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @deprecated This is no longer needed, Qwik now automatically embeds preloading logic into the 3 | * application. 4 | * 5 | * If your service-worker.ts file contains no custom code, you should deploy to production until 6 | * you're sure that all users picked up the new version, then you can remove it and also remove 7 | * the `` component from your `Root.tsx`. 8 | * 9 | * If you do have custom service worker logic, you should keep the `service-worker.ts` file and 10 | * `` component, but remove the `setupServiceWorker()` call. 11 | * @public 12 | */ 13 | export declare const setupServiceWorker: () => void; 14 | 15 | export { } 16 | -------------------------------------------------------------------------------- /lib/service-worker.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @deprecated This is no longer needed, Qwik now automatically embeds preloading logic into the 3 | * application. 4 | * 5 | * If your service-worker.ts file contains no custom code, you should deploy to production until 6 | * you're sure that all users picked up the new version, then you can remove it and also remove 7 | * the `` component from your `Root.tsx`. 8 | * 9 | * If you do have custom service worker logic, you should keep the `service-worker.ts` file and 10 | * `` component, but remove the `setupServiceWorker()` call. 11 | * @public 12 | */ 13 | const setupServiceWorker = () => { }; 14 | 15 | export { setupServiceWorker }; 16 | -------------------------------------------------------------------------------- /lib/static/deno.mjs: -------------------------------------------------------------------------------- 1 | // packages/qwik-city/src/static/deno/index.ts 2 | async function generate(_opts) { 3 | console.error(`Deno not implemented`); 4 | Deno.exit(1); 5 | } 6 | export { 7 | generate 8 | }; 9 | -------------------------------------------------------------------------------- /lib/static/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // packages/qwik-city/src/static/index.ts 21 | var index_exports = {}; 22 | __export(index_exports, { 23 | generate: () => generate 24 | }); 25 | module.exports = __toCommonJS(index_exports); 26 | async function generate(opts) { 27 | const ssgPlatform = await getEntryModule(); 28 | const result = await ssgPlatform.generate(opts); 29 | return result; 30 | } 31 | function getEntryModulePath() { 32 | if (isDeno()) { 33 | return "./deno.mjs"; 34 | } 35 | if (isNode() || isBun()) { 36 | if (isCjs()) { 37 | return "./node.cjs"; 38 | } 39 | return "./node.mjs"; 40 | } 41 | throw new Error(`Unsupported platform`); 42 | } 43 | function getEntryModule() { 44 | const entryModule = getEntryModulePath(); 45 | if (isCjs()) { 46 | return require(entryModule); 47 | } 48 | return import(entryModule); 49 | } 50 | function isDeno() { 51 | return typeof Deno !== "undefined"; 52 | } 53 | function isBun() { 54 | return typeof Bun !== "undefined"; 55 | } 56 | function isNode() { 57 | var _a; 58 | return !isBun() && !isDeno() && typeof process !== "undefined" && !!((_a = process.versions) == null ? void 0 : _a.node); 59 | } 60 | function isCjs() { 61 | const req = "require"; 62 | return isNode() && typeof globalThis[req] === "function"; 63 | } 64 | // Annotate the CommonJS export names for ESM import in node: 65 | 0 && (module.exports = { 66 | generate 67 | }); 68 | -------------------------------------------------------------------------------- /lib/static/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { RenderOptions } from '@builder.io/qwik/server'; 4 | 5 | /** 6 | * Use this function when SSG should be generated from another module, such as a Vite plugin. This 7 | * function's should be passed the paths of the entry module and Qwik City Plan. 8 | * 9 | * @public 10 | */ 11 | export declare function generate(opts: StaticGenerateOptions): Promise; 12 | 13 | /** @public */ 14 | export declare interface StaticGenerateOptions extends StaticGenerateRenderOptions { 15 | /** 16 | * Path to the SSR module exporting the default render function. In most cases it'll be 17 | * `./src/entry.ssr.tsx`. 18 | */ 19 | renderModulePath: string; 20 | /** Path to the Qwik City Plan module exporting the default `@qwik-city-plan`. */ 21 | qwikCityPlanModulePath: string; 22 | /** Defaults to `/` */ 23 | basePathname?: string; 24 | rootDir?: string; 25 | } 26 | 27 | /** @public */ 28 | export declare interface StaticGenerateRenderOptions extends RenderOptions { 29 | /** File system directory where the static files should be written. */ 30 | outDir: string; 31 | /** 32 | * The URL `origin`, which is a combination of the scheme (protocol) and hostname (domain). For 33 | * example, `https://qwik.dev` has the protocol `https://` and domain `qwik.dev`. However, the 34 | * `origin` does not include a `pathname`. 35 | * 36 | * The `origin` is used to provide a full URL during Static Site Generation (SSG), and to simulate 37 | * a complete URL rather than just the `pathname`. For example, in order to render a correct 38 | * canonical tag URL or URLs within the `sitemap.xml`, the `origin` must be provided too. 39 | * 40 | * If the site also starts with a pathname other than `/`, please use the `basePathname` option in 41 | * the Qwik City config options. 42 | */ 43 | origin: string; 44 | /** 45 | * Maximum number of workers to use while generating the static pages. Defaults to the number of 46 | * CPUs available. 47 | */ 48 | maxWorkers?: number; 49 | /** Maximum number of tasks to be running at one time per worker. Defaults to `20`. */ 50 | maxTasksPerWorker?: number; 51 | /** 52 | * File system path to write the `sitemap.xml` to. Defaults to `sitemap.xml` and written to the 53 | * root of the `outDir`. Setting to `null` will prevent the sitemap from being created. 54 | */ 55 | sitemapOutFile?: string | null; 56 | /** Log level. */ 57 | log?: 'debug'; 58 | /** 59 | * Set to `false` if the generated static HTML files should not be written to disk. Setting to 60 | * `false` is useful if the SSG should only write the `q-data.json` files to disk. Defaults to 61 | * `true`. 62 | */ 63 | emitHtml?: boolean; 64 | /** 65 | * Set to `false` if the generated `q-data.json` data files should not be written to disk. 66 | * Defaults to `true`. 67 | */ 68 | emitData?: boolean; 69 | /** 70 | * Set to `false` if the static build should not write custom or default `404.html` pages. 71 | * Defaults to `true`. 72 | */ 73 | emit404Pages?: boolean; 74 | /** 75 | * Defines file system routes relative to the source `routes` directory that should be static 76 | * generated. Accepts wildcard behavior. This should not include the "base" pathname. If not 77 | * provided, all routes will be static generated. `exclude` always takes priority over `include`. 78 | */ 79 | include?: string[]; 80 | /** 81 | * Defines file system routes relative to the source `routes` directory that should not be static 82 | * generated. Accepts wildcard behavior. This should not include the "base" pathname. `exclude` 83 | * always takes priority over `include`. 84 | */ 85 | exclude?: string[]; 86 | } 87 | 88 | /** @public */ 89 | export declare interface StaticGenerateResult { 90 | duration: number; 91 | rendered: number; 92 | errors: number; 93 | staticPaths: string[]; 94 | } 95 | 96 | export { } 97 | -------------------------------------------------------------------------------- /lib/static/index.mjs: -------------------------------------------------------------------------------- 1 | var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { 2 | get: (a, b) => (typeof require !== "undefined" ? require : a)[b] 3 | }) : x)(function(x) { 4 | if (typeof require !== "undefined") return require.apply(this, arguments); 5 | throw Error('Dynamic require of "' + x + '" is not supported'); 6 | }); 7 | 8 | // packages/qwik-city/src/static/index.ts 9 | async function generate(opts) { 10 | const ssgPlatform = await getEntryModule(); 11 | const result = await ssgPlatform.generate(opts); 12 | return result; 13 | } 14 | function getEntryModulePath() { 15 | if (isDeno()) { 16 | return "./deno.mjs"; 17 | } 18 | if (isNode() || isBun()) { 19 | if (isCjs()) { 20 | return "./node.cjs"; 21 | } 22 | return "./node.mjs"; 23 | } 24 | throw new Error(`Unsupported platform`); 25 | } 26 | function getEntryModule() { 27 | const entryModule = getEntryModulePath(); 28 | if (isCjs()) { 29 | return __require(entryModule); 30 | } 31 | return import(entryModule); 32 | } 33 | function isDeno() { 34 | return typeof Deno !== "undefined"; 35 | } 36 | function isBun() { 37 | return typeof Bun !== "undefined"; 38 | } 39 | function isNode() { 40 | return !isBun() && !isDeno() && typeof process !== "undefined" && !!process.versions?.node; 41 | } 42 | function isCjs() { 43 | const req = "require"; 44 | return isNode() && typeof globalThis[req] === "function"; 45 | } 46 | export { 47 | generate 48 | }; 49 | -------------------------------------------------------------------------------- /lib/vite/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { BuiltinsWithOptionalParams } from 'svgo/plugins/plugins-types'; 2 | import type { CompileOptions } from '@mdx-js/mdx'; 3 | import type { Config } from 'svgo'; 4 | import { ConfigEnv } from 'vite'; 5 | import type { Plugin as Plugin_2 } from 'vite'; 6 | import type { PluginOption } from 'vite'; 7 | import { UserConfigExport } from 'vite'; 8 | 9 | declare interface BuildEntry extends ParsedPathname { 10 | id: string; 11 | chunkFileName: string; 12 | filePath: string; 13 | } 14 | 15 | declare interface BuildLayout { 16 | filePath: string; 17 | dirPath: string; 18 | id: string; 19 | layoutType: 'top' | 'nested'; 20 | layoutName: string; 21 | } 22 | 23 | declare interface BuildRoute extends ParsedPathname { 24 | /** Unique id built from its relative file system path */ 25 | id: string; 26 | /** Local file system path */ 27 | filePath: string; 28 | ext: string; 29 | /** URL Pathname */ 30 | pathname: string; 31 | layouts: BuildLayout[]; 32 | } 33 | 34 | /** @public */ 35 | export declare function extendConfig(baseConfigExport: UserConfigExport, serverConfigExport: UserConfigExport): (env: ConfigEnv) => Promise>; 36 | 37 | /** @public */ 38 | declare interface ImageOptimizationOptions { 39 | jsxDirectives?: { 40 | quality?: `${number}`; 41 | format?: 'webp' | 'avif' | 'png'; 42 | w?: string; 43 | h?: string; 44 | [key: string]: string | undefined; 45 | }; 46 | svgo?: Pick & { 47 | defaultPresetOverrides?: BuiltinsWithOptionalParams['preset-default']['overrides']; 48 | prefixIds?: BuiltinsWithOptionalParams['prefixIds'] | false; 49 | }; 50 | enabled?: boolean | 'only-production'; 51 | } 52 | 53 | /** @public */ 54 | export declare type MdxOptions = CompileOptions; 55 | 56 | declare interface MdxPlugins { 57 | remarkGfm: boolean; 58 | rehypeSyntaxHighlight: boolean; 59 | rehypeAutolinkHeadings: boolean; 60 | } 61 | 62 | declare type P = Plugin_2 & { 63 | api: T; 64 | }; 65 | 66 | declare interface ParsedPathname { 67 | routeName: string; 68 | pattern: RegExp; 69 | paramNames: string[]; 70 | segments: PathnameSegment[]; 71 | } 72 | 73 | declare type PathnameSegment = PathnameSegmentPart[]; 74 | 75 | declare interface PathnameSegmentPart { 76 | content: string; 77 | dynamic: boolean; 78 | rest: boolean; 79 | } 80 | 81 | /** @public */ 82 | declare interface PluginOptions { 83 | /** Directory of the `routes`. Defaults to `src/routes`. */ 84 | routesDir?: string; 85 | /** Directory of the `server plugins`. Defaults to `src/server-plugins`. */ 86 | serverPluginsDir?: string; 87 | /** 88 | * The base pathname is used to create absolute URL paths up to the `hostname`, and must always 89 | * start and end with a `/`. Defaults to `/`. 90 | */ 91 | basePathname?: string; 92 | /** 93 | * Ensure a trailing slash ends page urls. Defaults to `true`. (Note: Previous versions defaulted 94 | * to `false`). 95 | */ 96 | trailingSlash?: boolean; 97 | /** Enable or disable MDX plugins included by default in qwik-city. */ 98 | mdxPlugins?: MdxPlugins; 99 | /** MDX Options https://mdxjs.com/ */ 100 | mdx?: any; 101 | /** The platform object which can be used to mock the Cloudflare bindings. */ 102 | platform?: Record; 103 | /** Configuration to rewrite url paths */ 104 | rewriteRoutes?: RewriteRouteOption[]; 105 | } 106 | 107 | /** @public */ 108 | export declare function qwikCity(userOpts?: QwikCityVitePluginOptions): PluginOption[]; 109 | 110 | /** @public */ 111 | export declare interface QwikCityPlugin extends P { 112 | name: 'vite-plugin-qwik-city'; 113 | } 114 | 115 | /** @public */ 116 | declare interface QwikCityPluginApi { 117 | getBasePathname: () => string; 118 | getRoutes: () => BuildRoute[]; 119 | getServiceWorkers: () => BuildEntry[]; 120 | } 121 | 122 | /** @public */ 123 | export declare interface QwikCityVitePluginOptions extends Omit { 124 | mdxPlugins?: MdxPlugins; 125 | mdx?: MdxOptions; 126 | platform?: Record; 127 | imageOptimization?: ImageOptimizationOptions; 128 | } 129 | 130 | /** @public */ 131 | declare interface RewriteRouteOption { 132 | prefix?: string; 133 | paths: Record; 134 | } 135 | 136 | export { } 137 | -------------------------------------------------------------------------------- /middleware/aws-lambda.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/aws-lambda'; 3 | -------------------------------------------------------------------------------- /middleware/azure-swa.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/azure-swa'; 3 | -------------------------------------------------------------------------------- /middleware/bun.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/bun'; 3 | -------------------------------------------------------------------------------- /middleware/cloudflare-pages.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/cloudflare-pages'; 3 | -------------------------------------------------------------------------------- /middleware/deno.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/deno'; 3 | -------------------------------------------------------------------------------- /middleware/firebase.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/firebase'; 3 | -------------------------------------------------------------------------------- /middleware/netlify-edge.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/netlify-edge'; 3 | -------------------------------------------------------------------------------- /middleware/node.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/node'; 3 | -------------------------------------------------------------------------------- /middleware/request-handler.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/request-handler'; 3 | -------------------------------------------------------------------------------- /middleware/vercel-edge.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from '../lib/middleware/vercel-edge'; 3 | -------------------------------------------------------------------------------- /modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@qwik-city-plan' { 2 | export const routes: any[]; 3 | export const menus: any[]; 4 | export const trailingSlash: boolean; 5 | export const basePathname: string; 6 | export const cacheModules: boolean; 7 | const defaultExport: { 8 | routes: any[]; 9 | menus: any[]; 10 | trailingSlash: boolean; 11 | basePathname: string; 12 | cacheModules: boolean; 13 | }; 14 | export default defaultExport; 15 | } 16 | declare module '@qwik-city-not-found-paths' { 17 | function getNotFound(_pathname: string): string; 18 | export { getNotFound }; 19 | } 20 | declare module '@qwik-city-static-paths' { 21 | function isStaticPath(method: string, url: URL): boolean; 22 | export { isStaticPath }; 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@builder.io/qwik-city", 3 | "description": "The meta-framework for Qwik.", 4 | "version": "1.14.1", 5 | "bugs": "https://github.com/QwikDev/qwik/issues", 6 | "dependencies": { 7 | "@mdx-js/mdx": "^3", 8 | "@types/mdx": "^2", 9 | "source-map": "^0.7.4", 10 | "svgo": "^3.3", 11 | "undici": "*", 12 | "valibot": ">=0.36.0 <2", 13 | "vfile": "6.0.2", 14 | "vite": "^5", 15 | "vite-imagetools": "^7", 16 | "zod": "3.22.4" 17 | }, 18 | "devDependencies": { 19 | "@azure/functions": "3.5.1", 20 | "@builder.io/qwik": "1.14.1", 21 | "@microsoft/api-extractor": "7.52.4", 22 | "@netlify/edge-functions": "2.10.0", 23 | "@types/mdast": "4.0.4", 24 | "@types/node": "20.14.11", 25 | "@types/refractor": "3.4.1", 26 | "@types/set-cookie-parser": "2.4.10", 27 | "estree-util-value-to-estree": "3.1.2", 28 | "github-slugger": "2.0.0", 29 | "hast-util-heading-rank": "2.1.1", 30 | "hast-util-to-string": "2.0.0", 31 | "kleur": "4.1.5", 32 | "marked": "12.0.2", 33 | "mdast-util-mdx": "3.0.0", 34 | "refractor": "4.8.1", 35 | "rehype-autolink-headings": "7.1.0", 36 | "remark-frontmatter": "5.0.0", 37 | "remark-gfm": "4.0.0", 38 | "set-cookie-parser": "2.6.0", 39 | "tsm": "2.3.0", 40 | "typescript": "5.4.5", 41 | "unified": "11.0.5", 42 | "unist-util-visit": "5.0.0", 43 | "uvu": "0.5.6", 44 | "yaml": "2.4.5" 45 | }, 46 | "engines": { 47 | "node": ">=16.8.0 <18.0.0 || >=18.11" 48 | }, 49 | "exports": { 50 | ".": { 51 | "types": "./lib/index.d.ts", 52 | "import": "./lib/index.qwik.mjs", 53 | "require": "./lib/index.qwik.cjs" 54 | }, 55 | "./adapters/azure-swa/vite": { 56 | "types": "./lib/adapters/azure-swa/vite/index.d.ts", 57 | "import": "./lib/adapters/azure-swa/vite/index.mjs", 58 | "require": "./lib/adapters/azure-swa/vite/index.cjs" 59 | }, 60 | "./adapters/cloudflare-pages/vite": { 61 | "types": "./lib/adapters/cloudflare-pages/vite/index.d.ts", 62 | "import": "./lib/adapters/cloudflare-pages/vite/index.mjs", 63 | "require": "./lib/adapters/cloudflare-pages/vite/index.cjs" 64 | }, 65 | "./adapters/cloud-run/vite": { 66 | "types": "./lib/adapters/cloud-run/vite/index.d.ts", 67 | "import": "./lib/adapters/cloud-run/vite/index.mjs", 68 | "require": "./lib/adapters/cloud-run/vite/index.cjs" 69 | }, 70 | "./adapters/bun-server/vite": { 71 | "types": "./lib/adapters/bun-server/vite/index.d.ts", 72 | "import": "./lib/adapters/bun-server/vite/index.mjs", 73 | "require": "./lib/adapters/bun-server/vite/index.cjs" 74 | }, 75 | "./adapters/deno-server/vite": { 76 | "types": "./lib/adapters/deno-server/vite/index.d.ts", 77 | "import": "./lib/adapters/deno-server/vite/index.mjs", 78 | "require": "./lib/adapters/deno-server/vite/index.cjs" 79 | }, 80 | "./adapters/node-server/vite": { 81 | "types": "./lib/adapters/node-server/vite/index.d.ts", 82 | "import": "./lib/adapters/node-server/vite/index.mjs", 83 | "require": "./lib/adapters/node-server/vite/index.cjs" 84 | }, 85 | "./adapters/netlify-edge/vite": { 86 | "types": "./lib/adapters/netlify-edge/vite/index.d.ts", 87 | "import": "./lib/adapters/netlify-edge/vite/index.mjs", 88 | "require": "./lib/adapters/netlify-edge/vite/index.cjs" 89 | }, 90 | "./adapters/shared/vite": { 91 | "types": "./lib/adapters/shared/vite/index.d.ts", 92 | "import": "./lib/adapters/shared/vite/index.mjs", 93 | "require": "./lib/adapters/shared/vite/index.cjs" 94 | }, 95 | "./adapters/static/vite": { 96 | "types": "./lib/adapters/static/vite/index.d.ts", 97 | "import": "./lib/adapters/static/vite/index.mjs", 98 | "require": "./lib/adapters/static/vite/index.cjs" 99 | }, 100 | "./adapters/vercel-edge/vite": { 101 | "types": "./lib/adapters/vercel-edge/vite/index.d.ts", 102 | "import": "./lib/adapters/vercel-edge/vite/index.mjs", 103 | "require": "./lib/adapters/vercel-edge/vite/index.cjs" 104 | }, 105 | "./middleware/azure-swa": { 106 | "types": "./lib/middleware/azure-swa/index.d.ts", 107 | "import": "./lib/middleware/azure-swa/index.mjs" 108 | }, 109 | "./middleware/aws-lambda": { 110 | "types": "./lib/middleware/aws-lambda/index.d.ts", 111 | "import": "./lib/middleware/aws-lambda/index.mjs" 112 | }, 113 | "./middleware/cloudflare-pages": { 114 | "types": "./lib/middleware/cloudflare-pages/index.d.ts", 115 | "import": "./lib/middleware/cloudflare-pages/index.mjs" 116 | }, 117 | "./middleware/firebase": { 118 | "types": "./lib/middleware/firebase/index.d.ts", 119 | "import": "./lib/middleware/firebase/index.mjs" 120 | }, 121 | "./middleware/deno": { 122 | "types": "./lib/middleware/deno/index.d.ts", 123 | "import": "./lib/middleware/deno/index.mjs" 124 | }, 125 | "./middleware/bun": { 126 | "types": "./lib/middleware/bun/index.d.ts", 127 | "import": "./lib/middleware/bun/index.mjs" 128 | }, 129 | "./middleware/netlify-edge": { 130 | "types": "./lib/middleware/netlify-edge/index.d.ts", 131 | "import": "./lib/middleware/netlify-edge/index.mjs" 132 | }, 133 | "./middleware/node": { 134 | "types": "./lib/middleware/node/index.d.ts", 135 | "import": "./lib/middleware/node/index.mjs", 136 | "require": "./lib/middleware/node/index.cjs" 137 | }, 138 | "./middleware/request-handler": { 139 | "types": "./lib/middleware/request-handler/index.d.ts", 140 | "import": "./lib/middleware/request-handler/index.mjs", 141 | "require": "./lib/middleware/request-handler/index.cjs" 142 | }, 143 | "./middleware/vercel-edge": { 144 | "types": "./lib/middleware/vercel-edge/index.d.ts", 145 | "import": "./lib/middleware/vercel-edge/index.mjs" 146 | }, 147 | "./static": { 148 | "types": "./lib/static/index.d.ts", 149 | "import": "./lib/static/index.mjs", 150 | "require": "./lib/static/index.cjs" 151 | }, 152 | "./vite": { 153 | "types": "./lib/vite/index.d.ts", 154 | "import": "./lib/vite/index.mjs", 155 | "require": "./lib/vite/index.cjs" 156 | }, 157 | "./service-worker": { 158 | "types": "./service-worker.d.ts", 159 | "import": "./lib/service-worker.mjs", 160 | "require": "./lib/service-worker.cjs" 161 | } 162 | }, 163 | "files": [ 164 | "adapters", 165 | "index.d.ts", 166 | "lib", 167 | "middleware", 168 | "modules.d.ts", 169 | "README.md", 170 | "service-worker.d.ts", 171 | "static.d.ts", 172 | "vite.d.ts" 173 | ], 174 | "homepage": "https://qwik.dev/", 175 | "license": "MIT", 176 | "main": "./lib/index.qwik.mjs", 177 | "peerDependencies": { 178 | "vite": "^5" 179 | }, 180 | "publishConfig": { 181 | "access": "public" 182 | }, 183 | "qwik": "./lib/index.qwik.mjs", 184 | "repository": { 185 | "type": "git", 186 | "url": "https://github.com/QwikDev/qwik.git", 187 | "directory": "packages/qwik-city" 188 | }, 189 | "scripts": { 190 | "build": "cd src/runtime && vite build --mode lib" 191 | }, 192 | "type": "module", 193 | "types": "./lib/index.d.ts" 194 | } 195 | -------------------------------------------------------------------------------- /service-worker.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from './lib/service-worker'; 3 | -------------------------------------------------------------------------------- /static.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from './lib/static'; 3 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "paths": { 5 | "@builder.io/qwik-city": ["packages/qwik-city/src/runtime/src/index.ts"], 6 | "@builder.io/qwik-city/service-worker": [ 7 | "packages/qwik-city/src/runtime/src/service-worker/index.ts" 8 | ], 9 | "@builder.io/qwik-city/adapters/azure-swa/vite": [ 10 | "packages/qwik-city/src/adapters/azure-swa/vite/index.ts" 11 | ], 12 | "@builder.io/qwik-city/adapters/cloudflare-pages/vite": [ 13 | "packages/qwik-city/src/adapters/cloudflare-pages/vite/index.ts" 14 | ], 15 | "@builder.io/qwik-city/adapters/node-server/vite": [ 16 | "packages/qwik-city/src/adapters/node-server/vite/index.ts" 17 | ], 18 | "@builder.io/qwik-city/adapters/netlify-edge/vite": [ 19 | "packages/qwik-city/src/adapters/netlify-edge/vite/index.ts" 20 | ], 21 | "@builder.io/qwik-city/adapters/shared/vite": [ 22 | "packages/qwik-city/src/adapters/shared/vite/index.ts" 23 | ], 24 | "@builder.io/qwik-city/adapters/static/vite": [ 25 | "packages/qwik-city/src/adapters/static/vite/index.ts" 26 | ], 27 | "@builder.io/qwik-city/middleware/azure-swa": ["packages/qwik-city/src/middleware/azure-swa"], 28 | "@builder.io/qwik-city/middleware/aws-lambda": [ 29 | "packages/qwik-city/src/middleware/aws-lambda" 30 | ], 31 | "@builder.io/qwik-city/middleware/cloudflare-pages": [ 32 | "packages/qwik-city/src/middleware/cloudflare-pages" 33 | ], 34 | "@builder.io/qwik-city/middleware/request-handler": [ 35 | "packages/qwik-city/src/middleware/request-handler" 36 | ], 37 | "@builder.io/qwik-city/middleware/node": ["packages/qwik-city/src/middleware/node"], 38 | "@builder.io/qwik-city/middleware/netlify-edge": [ 39 | "packages/qwik-city/src/middleware/netlify-edge" 40 | ], 41 | "@builder.io/qwik-city/static": ["packages/qwik-city/src/static"], 42 | "@builder.io/qwik-city/vite": ["packages/qwik-city/src/buildtime/vite"], 43 | 44 | "@qwik-city-plan": ["packages/qwik-city/src/runtime/src/qwik-city-plan.ts"], 45 | "@qwik-city-sw-register-build": [ 46 | "packages/qwik-city/src/buildtime/runtime-generation/sw-register-build.ts" 47 | ], 48 | "@qwik-city-sw-register": ["packages/qwik-city/src/runtime/src/sw-register-runtime.ts"], 49 | "@qwik-city-not-found-paths": [ 50 | "packages/qwik-city/src/middleware/request-handler/generated/not-found-paths.ts" 51 | ], 52 | "@qwik-city-static-paths": [ 53 | "packages/qwik-city/src/middleware/request-handler/generated/static-paths.ts" 54 | ] 55 | } 56 | }, 57 | "include": ["."] 58 | } 59 | -------------------------------------------------------------------------------- /vite.d.ts: -------------------------------------------------------------------------------- 1 | // re-export for typescript in old resolution mode 2 | export * from './lib/vite'; 3 | --------------------------------------------------------------------------------