@analogjs/platform 3.0.0-alpha.90 → 3.0.0-alpha.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.d.ts +2 -0
- package/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.js +203 -0
- package/migrations/migrate-to-separated-plugins/migrate-to-separated-plugins.js.map +1 -0
- package/package.json +11 -7
- package/src/index.d.ts +1 -2
- package/src/index.js +1 -2
- package/src/index.js.map +1 -1
- package/src/lib/clear-client-page-endpoint.js +1 -0
- package/src/lib/clear-client-page-endpoint.js.map +1 -1
- package/src/lib/deps-plugin.js +17 -6
- package/src/lib/deps-plugin.js.map +1 -1
- package/src/lib/nitro/analog-nitro-plugin.js +102 -45
- package/src/lib/nitro/analog-nitro-plugin.js.map +1 -1
- package/src/lib/nitro/get-server-fn-handlers.d.ts +29 -0
- package/src/lib/nitro/get-server-fn-handlers.js +66 -0
- package/src/lib/nitro/get-server-fn-handlers.js.map +1 -0
- package/src/lib/nitro/server-fn-endpoints.d.ts +41 -0
- package/src/lib/nitro/server-fn-endpoints.js +57 -0
- package/src/lib/nitro/server-fn-endpoints.js.map +1 -0
- package/src/lib/nx-plugin/src/generators/app/files/template-angular/src/server/routes/api/v1/hello.ts__template__ +2 -2
- package/src/lib/nx-plugin/src/generators/app/files/template-angular/vite.config.ts__template__ +4 -0
- package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.d.ts +7 -5
- package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/preset/__snapshots__/generator.spec.ts.snap +3 -1
- package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.d.ts +5 -5
- package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js +5 -5
- package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js.map +1 -1
- package/src/lib/options.d.ts +9 -49
- package/src/lib/platform-plugin.js +42 -6
- package/src/lib/platform-plugin.js.map +1 -1
- package/src/lib/route-file-discovery.d.ts +3 -1
- package/src/lib/route-file-discovery.js +19 -8
- package/src/lib/route-file-discovery.js.map +1 -1
- package/src/lib/route-manifest.d.ts +22 -26
- package/src/lib/route-manifest.js +58 -189
- package/src/lib/route-manifest.js.map +1 -1
- package/src/lib/ssr/defer-streaming-plugin.js +97 -0
- package/src/lib/ssr/defer-streaming-plugin.js.map +1 -0
- package/src/lib/typed-routes-plugin.d.ts +6 -43
- package/src/lib/typed-routes-plugin.js +80 -195
- package/src/lib/typed-routes-plugin.js.map +1 -1
- package/src/lib/utils/debug.js +4 -7
- package/src/lib/utils/debug.js.map +1 -1
- package/src/lib/utils/rolldown.js +1 -1
- package/src/server-mode-plugin.d.ts +1 -1
- package/src/server-mode-plugin.js +13 -1
- package/src/server-mode-plugin.js.map +1 -1
- package/src/lib/json-ld-manifest-plugin.d.ts +0 -41
- package/src/lib/json-ld-manifest-plugin.js +0 -84
- package/src/lib/json-ld-manifest-plugin.js.map +0 -1
- package/src/lib/route-generation-plugin.d.ts +0 -3
- package/src/lib/route-generation-plugin.js +0 -45
- package/src/lib/route-generation-plugin.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-server-fn-handlers.js","names":[],"sources":["../../../../src/lib/nitro/get-server-fn-handlers.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { parseSync } from 'oxc-parser';\nimport { resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\n\nimport { normalizePath } from 'vite';\n\nexport type GetServerFnHandlersArgs = {\n workspaceRoot: string;\n sourceRoot: string;\n rootDir: string;\n additionalServerFnDirs?: string[];\n};\n\nexport type ServerFnHandlerModule = {\n /** Absolute, normalized path to a discovered `*.server.ts` module. */\n file: string;\n};\n\n/**\n * `*.server.ts` files that are matched by the glob but are never server-function\n * hosts, so importing them for registration side-effects would be wrong.\n *\n * The SSR entries (`main.server.ts`, `main-cf.server.ts`, …) sit at the top of\n * the source root and bootstrap the whole Angular application; importing one\n * would pull the entire app into the dispatch bundle. They are matched by\n * directory rather than by name so a page named `main.server.ts` still counts.\n */\nconst EXCLUDED_SERVER_FILES: RegExp[] = [/\\/app\\.config\\.server\\.ts$/];\n\n/**\n * Discovers the `*.server.ts` modules that may define server functions.\n *\n * Unlike page endpoints (one Nitro handler per file), server functions all\n * share a single `/_analog/fn/:id` dispatch route. The discovered modules are\n * imported for their registration side-effects — each `serverFn(...)` call\n * registers itself into the server-side registry at import time — after which\n * dispatch looks up the requested function by id.\n *\n * Scope is `<projectRoot>/<sourceRoot>/**\\/*.server.ts` because the RFC allows a\n * server function to live in any `.server.ts` module, including existing page\n * server files. Only modules defining a server function that the client\n * transform can rewrite participate.\n * Angular SSR config (`app.config.server.ts`) is excluded — it is not a route or\n * function module and must not be pulled into the dispatch bundle.\n *\n * @returns discovered modules, de-duplicated and sorted for deterministic output\n */\nexport function getServerFnHandlers({\n workspaceRoot,\n sourceRoot,\n rootDir,\n additionalServerFnDirs,\n}: GetServerFnHandlersArgs): ServerFnHandlerModule[] {\n const root = normalizePath(resolve(workspaceRoot, rootDir));\n\n const files = globSync(\n [\n `${root}/${sourceRoot}/**/*.server.ts`,\n ...(additionalServerFnDirs || []).map(\n (dir) => `${workspaceRoot}${dir}/**/*.server.ts`,\n ),\n ],\n { dot: true, absolute: true },\n ).map((file) => normalizePath(file));\n\n const sourceRootDir = `${root}/${sourceRoot}/`;\n const seen = new Set<string>();\n return files\n .filter((file) => !EXCLUDED_SERVER_FILES.some((re) => re.test(file)))\n .filter(\n (file) =>\n !file.startsWith(sourceRootDir) ||\n file.slice(sourceRootDir.length).includes('/'),\n )\n .filter((file) => (seen.has(file) ? false : (seen.add(file), true)))\n .sort()\n .filter(definesServerFn)\n .map((file) => ({ file }));\n}\n\n/**\n * Match the client scrub's supported server-function declaration shape. The\n * scrub deliberately falls back to the conventional `serverFn` name when the\n * function is re-exported through a local barrel, so discovery must make the\n * same choice or the browser receives a proxy without a dispatch route.\n */\nfunction definesServerFn(file: string): boolean {\n const code = readFileSync(file, 'utf8');\n if (!code.includes('serverFn')) return false;\n\n const { program } = parseSync(file, code);\n const localNames = new Set<string>();\n for (const node of program.body) {\n if (\n node.type !== 'ImportDeclaration' ||\n node.source.value !== '@analogjs/router/server'\n ) {\n continue;\n }\n for (const specifier of node.specifiers) {\n if (\n specifier.type === 'ImportSpecifier' &&\n (specifier.imported.type === 'Identifier'\n ? specifier.imported.name\n : specifier.imported.value) === 'serverFn'\n ) {\n localNames.add(specifier.local.name);\n }\n }\n }\n if (localNames.size === 0) localNames.add('serverFn');\n\n return program.body.some(\n (node) =>\n node.type === 'ExportNamedDeclaration' &&\n node.declaration?.type === 'VariableDeclaration' &&\n node.declaration.declarations.some(\n (declarator) =>\n declarator.id?.type === 'Identifier' &&\n declarator.init?.type === 'CallExpression' &&\n declarator.init.callee?.type === 'Identifier' &&\n localNames.has(declarator.init.callee.name),\n ),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AA4BA,IAAM,wBAAkC,CAAC,6BAA6B;;;;;;;;;;;;;;;;;;;AAoBtE,SAAgB,oBAAoB,EAClC,eACA,YACA,SACA,0BACmD;CACnD,MAAM,OAAO,cAAc,QAAQ,eAAe,QAAQ,CAAC;CAE3D,MAAM,QAAQ,SACZ,CACE,GAAG,KAAK,GAAG,WAAW,kBACtB,IAAI,0BAA0B,EAAE,EAAE,KAC/B,QAAQ,GAAG,gBAAgB,IAAI,iBACjC,CACF,EACD;EAAE,KAAK;EAAM,UAAU;EAAM,CAC9B,CAAC,KAAK,SAAS,cAAc,KAAK,CAAC;CAEpC,MAAM,gBAAgB,GAAG,KAAK,GAAG,WAAW;CAC5C,MAAM,uBAAO,IAAI,KAAa;AAC9B,QAAO,MACJ,QAAQ,SAAS,CAAC,sBAAsB,MAAM,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC,CACpE,QACE,SACC,CAAC,KAAK,WAAW,cAAc,IAC/B,KAAK,MAAM,cAAc,OAAO,CAAC,SAAS,IAAI,CACjD,CACA,QAAQ,SAAU,KAAK,IAAI,KAAK,GAAG,SAAS,KAAK,IAAI,KAAK,EAAE,MAAO,CACnE,MAAM,CACN,OAAO,gBAAgB,CACvB,KAAK,UAAU,EAAE,MAAM,EAAE;;;;;;;;AAS9B,SAAS,gBAAgB,MAAuB;CAC9C,MAAM,OAAO,aAAa,MAAM,OAAO;AACvC,KAAI,CAAC,KAAK,SAAS,WAAW,CAAE,QAAO;CAEvC,MAAM,EAAE,YAAY,UAAU,MAAM,KAAK;CACzC,MAAM,6BAAa,IAAI,KAAa;AACpC,MAAK,MAAM,QAAQ,QAAQ,MAAM;AAC/B,MACE,KAAK,SAAS,uBACd,KAAK,OAAO,UAAU,0BAEtB;AAEF,OAAK,MAAM,aAAa,KAAK,WAC3B,KACE,UAAU,SAAS,sBAClB,UAAU,SAAS,SAAS,eACzB,UAAU,SAAS,OACnB,UAAU,SAAS,WAAW,WAElC,YAAW,IAAI,UAAU,MAAM,KAAK;;AAI1C,KAAI,WAAW,SAAS,EAAG,YAAW,IAAI,WAAW;AAErD,QAAO,QAAQ,KAAK,MACjB,SACC,KAAK,SAAS,4BACd,KAAK,aAAa,SAAS,yBAC3B,KAAK,YAAY,aAAa,MAC3B,eACC,WAAW,IAAI,SAAS,gBACxB,WAAW,MAAM,SAAS,oBAC1B,WAAW,KAAK,QAAQ,SAAS,gBACjC,WAAW,IAAI,WAAW,KAAK,OAAO,KAAK,CAC9C,CACJ"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { NitroEventHandler } from "nitro/types";
|
|
2
|
+
import type { ServerFnHandlerModule } from "./get-server-fn-handlers.js";
|
|
3
|
+
/**
|
|
4
|
+
* Nitro virtual-module id for the generated server-function dispatch handler.
|
|
5
|
+
* Referenced from `nitroConfig.handlers` and provided via `nitroConfig.virtual`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SERVER_FN_DISPATCH_VIRTUAL = "#ANALOG_SERVER_FN_DISPATCH";
|
|
8
|
+
/** The single transport route all server functions dispatch through. */
|
|
9
|
+
export declare const SERVER_FN_DISPATCH_ROUTE = "/_analog/fn/:id";
|
|
10
|
+
/** URL prefix of that route, for matching requests before the id is known. */
|
|
11
|
+
export declare const SERVER_FN_DISPATCH_PREFIX = "/_analog/fn/";
|
|
12
|
+
/**
|
|
13
|
+
* The Nitro handler registration for the server-function dispatch route.
|
|
14
|
+
* Unlike page endpoints (one handler per file), every server function shares
|
|
15
|
+
* this one `/_analog/fn/:id` route; the id selects the function at runtime.
|
|
16
|
+
*
|
|
17
|
+
* The route is fixed and NOT `/api`-prefixed: client proxies always call the
|
|
18
|
+
* absolute `/_analog/fn/:id` URL, so an `/api` prefix (as page endpoints use)
|
|
19
|
+
* would leave the handler unreachable in apps that have an API directory.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getServerFnDispatchHandler(): NitroEventHandler;
|
|
22
|
+
export type BuildServerFnDispatchModuleArgs = {
|
|
23
|
+
/** Discovered `*.server.ts` modules, imported for registration side-effects. */
|
|
24
|
+
modules: ServerFnHandlerModule[];
|
|
25
|
+
/**
|
|
26
|
+
* Absolute path to the app's server config module (`app.config.server.ts`),
|
|
27
|
+
* which exports the `ApplicationConfig` (as `config`) that `main.server.ts`
|
|
28
|
+
* renders with. Handlers bootstrap against it, so they see the same DI the
|
|
29
|
+
* app configured. When absent, handlers run with only `providedIn: 'root'`.
|
|
30
|
+
*/
|
|
31
|
+
appConfigModule?: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Generates the source of the Nitro dispatch handler.
|
|
35
|
+
*
|
|
36
|
+
* The handler imports every discovered `*.server.ts` module so each
|
|
37
|
+
* `serverFn(...)` registers itself, imports the app's server config, then on
|
|
38
|
+
* each request looks up the function by id and runs it via `dispatchServerFn` —
|
|
39
|
+
* the same call path the validation harnesses exercise.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildServerFnDispatchModule({ modules, appConfigModule }: BuildServerFnDispatchModuleArgs): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { normalizePath } from "vite";
|
|
2
|
+
//#region packages/platform/src/lib/nitro/server-fn-endpoints.ts
|
|
3
|
+
/**
|
|
4
|
+
* Nitro virtual-module id for the generated server-function dispatch handler.
|
|
5
|
+
* Referenced from `nitroConfig.handlers` and provided via `nitroConfig.virtual`.
|
|
6
|
+
*/
|
|
7
|
+
var SERVER_FN_DISPATCH_VIRTUAL = "#ANALOG_SERVER_FN_DISPATCH";
|
|
8
|
+
/** The single transport route all server functions dispatch through. */
|
|
9
|
+
var SERVER_FN_DISPATCH_ROUTE = "/_analog/fn/:id";
|
|
10
|
+
/**
|
|
11
|
+
* The Nitro handler registration for the server-function dispatch route.
|
|
12
|
+
* Unlike page endpoints (one handler per file), every server function shares
|
|
13
|
+
* this one `/_analog/fn/:id` route; the id selects the function at runtime.
|
|
14
|
+
*
|
|
15
|
+
* The route is fixed and NOT `/api`-prefixed: client proxies always call the
|
|
16
|
+
* absolute `/_analog/fn/:id` URL, so an `/api` prefix (as page endpoints use)
|
|
17
|
+
* would leave the handler unreachable in apps that have an API directory.
|
|
18
|
+
*/
|
|
19
|
+
function getServerFnDispatchHandler() {
|
|
20
|
+
return {
|
|
21
|
+
route: SERVER_FN_DISPATCH_ROUTE,
|
|
22
|
+
handler: SERVER_FN_DISPATCH_VIRTUAL,
|
|
23
|
+
lazy: true
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generates the source of the Nitro dispatch handler.
|
|
28
|
+
*
|
|
29
|
+
* The handler imports every discovered `*.server.ts` module so each
|
|
30
|
+
* `serverFn(...)` registers itself, imports the app's server config, then on
|
|
31
|
+
* each request looks up the function by id and runs it via `dispatchServerFn` —
|
|
32
|
+
* the same call path the validation harnesses exercise.
|
|
33
|
+
*/
|
|
34
|
+
function buildServerFnDispatchModule({ modules, appConfigModule }) {
|
|
35
|
+
return `import '@angular/compiler';
|
|
36
|
+
import 'zone.js/node';
|
|
37
|
+
import '@angular/platform-server/init';
|
|
38
|
+
import { createServerFnAppInjector, createServerFnEventHandler } from '@analogjs/router/server';
|
|
39
|
+
|
|
40
|
+
// Discovered server-function modules (registration side-effects).
|
|
41
|
+
${modules.map((m) => `import ${JSON.stringify(normalizePath(m.file))};`).join("\n")}
|
|
42
|
+
|
|
43
|
+
${appConfigModule ? `import { config as serverFnAppConfig } from ${JSON.stringify(normalizePath(appConfigModule))};` : `const serverFnAppConfig = { providers: [] };`}
|
|
44
|
+
|
|
45
|
+
// Bootstrapped once from the app's own server config, so a handler resolves the
|
|
46
|
+
// same DI as an SSR render (\`providedIn: 'root'\` and listed providers alike).
|
|
47
|
+
// No component is bootstrapped, so nothing renders and the router never
|
|
48
|
+
// navigates. Only REQUEST/RESPONSE are rebuilt per call.
|
|
49
|
+
export default createServerFnEventHandler(
|
|
50
|
+
createServerFnAppInjector(serverFnAppConfig),
|
|
51
|
+
);
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { SERVER_FN_DISPATCH_VIRTUAL, buildServerFnDispatchModule, getServerFnDispatchHandler };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=server-fn-endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-fn-endpoints.js","names":[],"sources":["../../../../src/lib/nitro/server-fn-endpoints.ts"],"sourcesContent":["import type { NitroEventHandler } from 'nitro/types';\nimport { normalizePath } from 'vite';\n\nimport type { ServerFnHandlerModule } from './get-server-fn-handlers.js';\n\n/**\n * Nitro virtual-module id for the generated server-function dispatch handler.\n * Referenced from `nitroConfig.handlers` and provided via `nitroConfig.virtual`.\n */\nexport const SERVER_FN_DISPATCH_VIRTUAL = '#ANALOG_SERVER_FN_DISPATCH';\n\n/** The single transport route all server functions dispatch through. */\nexport const SERVER_FN_DISPATCH_ROUTE = '/_analog/fn/:id';\n\n/** URL prefix of that route, for matching requests before the id is known. */\nexport const SERVER_FN_DISPATCH_PREFIX = '/_analog/fn/';\n\n/**\n * The Nitro handler registration for the server-function dispatch route.\n * Unlike page endpoints (one handler per file), every server function shares\n * this one `/_analog/fn/:id` route; the id selects the function at runtime.\n *\n * The route is fixed and NOT `/api`-prefixed: client proxies always call the\n * absolute `/_analog/fn/:id` URL, so an `/api` prefix (as page endpoints use)\n * would leave the handler unreachable in apps that have an API directory.\n */\nexport function getServerFnDispatchHandler(): NitroEventHandler {\n return {\n route: SERVER_FN_DISPATCH_ROUTE,\n handler: SERVER_FN_DISPATCH_VIRTUAL,\n lazy: true,\n };\n}\n\nexport type BuildServerFnDispatchModuleArgs = {\n /** Discovered `*.server.ts` modules, imported for registration side-effects. */\n modules: ServerFnHandlerModule[];\n /**\n * Absolute path to the app's server config module (`app.config.server.ts`),\n * which exports the `ApplicationConfig` (as `config`) that `main.server.ts`\n * renders with. Handlers bootstrap against it, so they see the same DI the\n * app configured. When absent, handlers run with only `providedIn: 'root'`.\n */\n appConfigModule?: string;\n};\n\n/**\n * Generates the source of the Nitro dispatch handler.\n *\n * The handler imports every discovered `*.server.ts` module so each\n * `serverFn(...)` registers itself, imports the app's server config, then on\n * each request looks up the function by id and runs it via `dispatchServerFn` —\n * the same call path the validation harnesses exercise.\n */\nexport function buildServerFnDispatchModule({\n modules,\n appConfigModule,\n}: BuildServerFnDispatchModuleArgs): string {\n const registrationImports = modules\n .map((m) => `import ${JSON.stringify(normalizePath(m.file))};`)\n .join('\\n');\n\n // Bootstrap against the app's own server config so a handler resolves exactly\n // the services, tokens, and interceptors the app configured — one config, no\n // second provider list. Fall back to an empty config when the app has none.\n const appConfig = appConfigModule\n ? `import { config as serverFnAppConfig } from ${JSON.stringify(\n normalizePath(appConfigModule),\n )};`\n : `const serverFnAppConfig = { providers: [] };`;\n\n // `@analogjs/router/server` is a partially-compiled Angular library, and this\n // module is bundled by Nitro rather than by the app's Angular pipeline, so the\n // linker never runs over it. Loading the compiler gives it the JIT fallback.\n // `zone.js` and the server platform init match the SSR entry, so bootstrapping\n // the app injector below runs in the same environment a render would.\n //\n // The transport itself — id decoding, the malformed-body contract, dispatch,\n // and response writing — lives in `createServerFnEventHandler`, so this module\n // is only wiring: bootstrap the app injector from the app's server config, and\n // hand it to that handler.\n return `import '@angular/compiler';\nimport 'zone.js/node';\nimport '@angular/platform-server/init';\nimport { createServerFnAppInjector, createServerFnEventHandler } from '@analogjs/router/server';\n\n// Discovered server-function modules (registration side-effects).\n${registrationImports}\n\n${appConfig}\n\n// Bootstrapped once from the app's own server config, so a handler resolves the\n// same DI as an SSR render (\\`providedIn: 'root'\\` and listed providers alike).\n// No component is bootstrapped, so nothing renders and the router never\n// navigates. Only REQUEST/RESPONSE are rebuilt per call.\nexport default createServerFnEventHandler(\n createServerFnAppInjector(serverFnAppConfig),\n);\n`;\n}\n"],"mappings":";;;;;;AASA,IAAa,6BAA6B;;AAG1C,IAAa,2BAA2B;;;;;;;;;;AAcxC,SAAgB,6BAAgD;AAC9D,QAAO;EACL,OAAO;EACP,SAAS;EACT,MAAM;EACP;;;;;;;;;;AAuBH,SAAgB,4BAA4B,EAC1C,SACA,mBAC0C;AAwB1C,QAAO;;;;;;EAvBqB,QACzB,KAAK,MAAM,UAAU,KAAK,UAAU,cAAc,EAAE,KAAK,CAAC,CAAC,GAAG,CAC9D,KAAK,KAAK,CA2BO;;EAtBF,kBACd,+CAA+C,KAAK,UAClD,cAAc,gBAAgB,CAC/B,CAAC,KACF,+CAoBM"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineEventHandler } from 'h3';
|
|
2
2
|
|
|
3
|
-
export default
|
|
3
|
+
export default defineEventHandler(() => ({ message: 'Hello World' }));
|
package/src/lib/nx-plugin/src/generators/app/files/template-angular/vite.config.ts__template__
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="vitest" />
|
|
2
2
|
|
|
3
3
|
import analog from '@analogjs/platform';
|
|
4
|
+
import angular from '@analogjs/vite-plugin-angular';
|
|
5
|
+
import nitro from '@analogjs/vite-plugin-nitro';
|
|
4
6
|
import { defineConfig } from 'vite';
|
|
5
7
|
<% if (addTailwind) { %>
|
|
6
8
|
import tailwindcss from '@tailwindcss/vite';
|
|
@@ -23,6 +25,8 @@ export default defineConfig(({ mode }) => {
|
|
|
23
25
|
},
|
|
24
26
|
plugins: [
|
|
25
27
|
analog(),
|
|
28
|
+
angular(),
|
|
29
|
+
nitro(),
|
|
26
30
|
<% if (addTailwind) { %>
|
|
27
31
|
tailwindcss(),
|
|
28
32
|
<% } %>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare const V18_X_NX_DEVKIT = "^20.0.0";
|
|
2
2
|
export declare const V18_X_NX_ANGULAR = "^20.0.0";
|
|
3
|
-
export declare const V18_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.
|
|
4
|
-
export declare const V18_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.
|
|
5
|
-
export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.
|
|
6
|
-
export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.
|
|
3
|
+
export declare const V18_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.92";
|
|
4
|
+
export declare const V18_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.92";
|
|
5
|
+
export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.92";
|
|
6
|
+
export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.92";
|
|
7
7
|
export declare const V18_X_FRONT_MATTER = "^4.0.2";
|
|
8
8
|
export declare const V18_X_MARKED = "^18.0.0";
|
|
9
9
|
export declare const V18_X_MARKED_GFM_HEADING_ID = "^4.1.1";
|
|
@@ -15,7 +15,9 @@ export declare const V18_X_TAILWINDCSS = "^4.2.2";
|
|
|
15
15
|
export declare const V18_X_TAILWINDCSS_POSTCSS = "^4.2.2";
|
|
16
16
|
export declare const V18_X_TAILWINDCSS_VITE = "^4.2.2";
|
|
17
17
|
export declare const V18_X_POSTCSS = "^8.5.6";
|
|
18
|
-
export declare const V18_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.
|
|
18
|
+
export declare const V18_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.92";
|
|
19
|
+
export declare const V18_X_ANALOG_JS_VITE_PLUGIN_NITRO = "^3.0.0-alpha.92";
|
|
20
|
+
export declare const V18_X_H3 = "^1.13.0";
|
|
19
21
|
export declare const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = "^19.0.0";
|
|
20
22
|
export declare const V18_X_NX_VITE = "^21.0.0";
|
|
21
23
|
export declare const V18_X_NX_LINTER = "^21.0.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../../nx-plugin/src/generators/app/versions/nx_18_X/versions.ts"],"sourcesContent":["// V18_X\n// dependencies\nexport const V18_X_NX_DEVKIT = '^20.0.0';\nexport const V18_X_NX_ANGULAR = '^20.0.0';\nexport const V18_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.
|
|
1
|
+
{"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../../nx-plugin/src/generators/app/versions/nx_18_X/versions.ts"],"sourcesContent":["// V18_X\n// dependencies\nexport const V18_X_NX_DEVKIT = '^20.0.0';\nexport const V18_X_NX_ANGULAR = '^20.0.0';\nexport const V18_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.92';\nexport const V18_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.92';\nexport const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.92';\nexport const V18_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.92';\nexport const V18_X_FRONT_MATTER = '^4.0.2';\nexport const V18_X_MARKED = '^18.0.0';\nexport const V18_X_MARKED_GFM_HEADING_ID = '^4.1.1';\nexport const V18_X_MARKED_HIGHLIGHT = '^2.2.1';\nexport const V18_X_MARKED_MANGLE = '^1.1.10';\nexport const V18_X_MERMAID = '^10.2.4';\nexport const V18_X_PRISMJS = '^1.29.0';\nexport const V18_X_TAILWINDCSS = '^4.2.2';\nexport const V18_X_TAILWINDCSS_POSTCSS = '^4.2.2';\nexport const V18_X_TAILWINDCSS_VITE = '^4.2.2';\nexport const V18_X_POSTCSS = '^8.5.6';\n\n// devDependencies\nexport const V18_X_ANALOG_JS_PLATFORM = '^3.0.0-alpha.92';\nexport const V18_X_ANALOG_JS_VITE_PLUGIN_NITRO = '^3.0.0-alpha.92';\nexport const V18_X_H3 = '^1.13.0';\nexport const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = '^19.0.0';\nexport const V18_X_NX_VITE = '^21.0.0';\nexport const V18_X_NX_LINTER = '^21.0.0';\nexport const V18_X_JSDOM = '^22.1.0';\nexport const V18_X_VITE = '^8.0.0';\nexport const V18_X_VITE_TSCONFIG_PATHS = '^4.2.0';\nexport const V18_X_VITEST = '^4.0.0';\nexport const V18_X_ZOD = '^3.21.4';\n"],"mappings":";AAeA,IAAa,oBAAoB;AACjC,IAAa,4BAA4B;AACzC,IAAa,yBAAyB;AACtC,IAAa,gBAAgB"}
|
|
@@ -101,6 +101,8 @@ exports[`preset generator > should match vite.config.ts 1`] = `
|
|
|
101
101
|
"/// <reference types="vitest" />
|
|
102
102
|
|
|
103
103
|
import analog from '@analogjs/platform';
|
|
104
|
+
import angular from '@analogjs/vite-plugin-angular';
|
|
105
|
+
import nitro from '@analogjs/vite-plugin-nitro';
|
|
104
106
|
import { defineConfig } from 'vite';
|
|
105
107
|
|
|
106
108
|
import tailwindcss from '@tailwindcss/vite';
|
|
@@ -120,7 +122,7 @@ export default defineConfig(({ mode }) => {
|
|
|
120
122
|
allow: ['.'],
|
|
121
123
|
},
|
|
122
124
|
},
|
|
123
|
-
plugins: [analog(), tailwindcss()],
|
|
125
|
+
plugins: [analog(), angular(), nitro(), tailwindcss()],
|
|
124
126
|
test: {
|
|
125
127
|
globals: true,
|
|
126
128
|
environment: 'jsdom',
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export declare const V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.
|
|
2
|
-
export declare const V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.
|
|
1
|
+
export declare const V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.92";
|
|
2
|
+
export declare const V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.92";
|
|
3
3
|
export declare const V19_X_MARKED = "^18.0.0";
|
|
4
4
|
export declare const V19_X_MARKED_GFM_HEADING_ID = "^4.1.1";
|
|
5
5
|
export declare const V19_X_MARKED_HIGHLIGHT = "^2.2.1";
|
|
6
6
|
export declare const V19_X_MARKED_MANGLE = "^1.1.10";
|
|
7
7
|
export declare const V19_X_PRISMJS = "^1.29.0";
|
|
8
|
-
export declare const V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.
|
|
9
|
-
export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.
|
|
10
|
-
export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.
|
|
8
|
+
export declare const V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.92";
|
|
9
|
+
export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.92";
|
|
10
|
+
export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.92";
|
|
11
11
|
export declare const V19_X_NX_ANGULAR = "^22.0.0";
|
|
12
12
|
export declare const V19_X_NX_VITE = "^22.0.0";
|
|
13
13
|
export declare const V19_X_JSDOM = "^22.0.0";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//#region packages/nx-plugin/src/utils/versions/ng_19_X/versions.ts
|
|
2
|
-
var V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.
|
|
3
|
-
var V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.
|
|
2
|
+
var V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.92";
|
|
3
|
+
var V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.92";
|
|
4
4
|
var V19_X_MARKED = "^18.0.0";
|
|
5
5
|
var V19_X_MARKED_GFM_HEADING_ID = "^4.1.1";
|
|
6
6
|
var V19_X_MARKED_HIGHLIGHT = "^2.2.1";
|
|
7
7
|
var V19_X_MARKED_MANGLE = "^1.1.10";
|
|
8
8
|
var V19_X_PRISMJS = "^1.29.0";
|
|
9
|
-
var V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.
|
|
10
|
-
var V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.
|
|
11
|
-
var V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.
|
|
9
|
+
var V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.92";
|
|
10
|
+
var V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.92";
|
|
11
|
+
var V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.92";
|
|
12
12
|
var V19_X_NX_VITE = "^22.0.0";
|
|
13
13
|
var V19_X_JSDOM = "^22.0.0";
|
|
14
14
|
var V19_X_VITE_TSCONFIG_PATHS = "^4.2.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/utils/versions/ng_19_X/versions.ts"],"sourcesContent":["// V19_X\nexport const V19_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.
|
|
1
|
+
{"version":3,"file":"versions.js","names":[],"sources":["../../../../../../../../../nx-plugin/src/utils/versions/ng_19_X/versions.ts"],"sourcesContent":["// V19_X\nexport const V19_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.92';\nexport const V19_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.92';\nexport const V19_X_MARKED = '^18.0.0';\nexport const V19_X_MARKED_GFM_HEADING_ID = '^4.1.1';\nexport const V19_X_MARKED_HIGHLIGHT = '^2.2.1';\nexport const V19_X_MARKED_MANGLE = '^1.1.10';\nexport const V19_X_PRISMJS = '^1.29.0';\n\n// devDependencies\nexport const V19_X_ANALOG_JS_PLATFORM = '^3.0.0-alpha.92';\nexport const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.92';\nexport const V19_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.92';\nexport const V19_X_NX_ANGULAR = '^22.0.0';\nexport const V19_X_NX_VITE = '^22.0.0';\nexport const V19_X_JSDOM = '^22.0.0';\nexport const V19_X_VITE_TSCONFIG_PATHS = '^4.2.0';\nexport const V19_X_VITEST = '^3.0.0';\nexport const V19_X_VITE = '^6.0.0';\nexport const NX_X_LATEST_VITE = '^8.0.0';\nexport const NX_X_LATEST_VITEST = '^4.0.0';\nexport const NX_X_LATEST_NX = '^23.0.0';\n"],"mappings":";AACA,IAAa,yBAAyB;AACtC,IAAa,0BAA0B;AACvC,IAAa,eAAe;AAC5B,IAAa,8BAA8B;AAC3C,IAAa,yBAAyB;AACtC,IAAa,sBAAsB;AACnC,IAAa,gBAAgB;AAG7B,IAAa,2BAA2B;AACxC,IAAa,sCAAsC;AACnD,IAAa,iCAAiC;AAE9C,IAAa,gBAAgB;AAC7B,IAAa,cAAc;AAC3B,IAAa,4BAA4B;AACzC,IAAa,eAAe;AAC5B,IAAa,aAAa;AAC1B,IAAa,mBAAmB;AAChC,IAAa,qBAAqB;AAClC,IAAa,iBAAiB"}
|
package/src/lib/options.d.ts
CHANGED
|
@@ -113,58 +113,18 @@ export interface Options {
|
|
|
113
113
|
* the LOCALE injection token.
|
|
114
114
|
*/
|
|
115
115
|
i18n?: I18nOptions;
|
|
116
|
-
/**
|
|
117
|
-
* Experimental features. These APIs are subject to change.
|
|
118
|
-
*
|
|
119
|
-
* `@analogjs/platform` is the default rollout and orchestration surface for
|
|
120
|
-
* Analog-owned experiments. These flags may delegate to dedicated feature
|
|
121
|
-
* plugins or forward options into lower-level integrations while preserving
|
|
122
|
-
* a single Analog-first authoring surface.
|
|
123
|
-
*/
|
|
116
|
+
/** Opt-in experimental features. */
|
|
124
117
|
experimental?: {
|
|
118
|
+
/** Generate route declarations and enable typed navigation helpers. */
|
|
119
|
+
typedRouting?: boolean | import("./typed-routes-plugin.js").TypedRoutingOptions;
|
|
125
120
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* object so both codegen features share one generated file.
|
|
132
|
-
*
|
|
133
|
-
* - `true` — generates `src/routeTree.gen.ts` with `routeJsonLdManifest`
|
|
134
|
-
* - `TypedRouterOptions` — customize output path or disable just the
|
|
135
|
-
* JSON-LD manifest piece
|
|
136
|
-
*
|
|
137
|
-
* Unlocks type-safe usage of:
|
|
138
|
-
* - `routePath()` — build route link objects for `[routerLink]`
|
|
139
|
-
* - `injectNavigate()` — typed navigation
|
|
140
|
-
* - `injectParams(from)` — typed params signal
|
|
141
|
-
* - `injectQuery(from)` — typed query signal
|
|
142
|
-
*
|
|
143
|
-
* Inspired by TanStack Router's `routeTree.gen.ts` codegen.
|
|
121
|
+
* Opt into progressive streaming SSR. When enabled, the SSR build patches
|
|
122
|
+
* `@angular/core` with a per-`@defer` block resolution hook so
|
|
123
|
+
* `@analogjs/router`'s `renderStream` can flush the document head first and
|
|
124
|
+
* each `@defer (hydrate …)` block as it resolves on the server. Has no
|
|
125
|
+
* effect unless the server entry uses `renderStream`.
|
|
144
126
|
*/
|
|
145
|
-
|
|
127
|
+
streaming?: boolean;
|
|
146
128
|
};
|
|
147
129
|
}
|
|
148
|
-
export interface TypedRouterOptions {
|
|
149
|
-
/**
|
|
150
|
-
* Output path for the single generated route module,
|
|
151
|
-
* relative to the app root.
|
|
152
|
-
*
|
|
153
|
-
* @default 'src/routeTree.gen.ts'
|
|
154
|
-
*/
|
|
155
|
-
outFile?: string;
|
|
156
|
-
/**
|
|
157
|
-
* Include generated `routeJsonLdManifest` data in the generated route file.
|
|
158
|
-
*
|
|
159
|
-
* @default true
|
|
160
|
-
*/
|
|
161
|
-
jsonLdManifest?: boolean;
|
|
162
|
-
/**
|
|
163
|
-
* Fail production builds after regenerating a stale checked-in route file.
|
|
164
|
-
* Development and watch mode continue to update the file automatically.
|
|
165
|
-
*
|
|
166
|
-
* @default true
|
|
167
|
-
*/
|
|
168
|
-
verifyOnBuild?: boolean;
|
|
169
|
-
}
|
|
170
130
|
export type { PrerenderContentDir, PrerenderContentFile, PrerenderSitemapConfig, SitemapConfig, SitemapEntry, SitemapExcludeRule, SitemapPriority, SitemapRouteDefinition, SitemapRouteInput, SitemapRouteSource, SitemapTransform };
|
|
@@ -6,13 +6,29 @@ import { contentPlugin } from "./content-plugin.js";
|
|
|
6
6
|
import { clearClientPageEndpointsPlugin } from "./clear-client-page-endpoint.js";
|
|
7
7
|
import { depsPlugin } from "./deps-plugin.js";
|
|
8
8
|
import { injectHTMLPlugin } from "./ssr/inject-html-plugin.js";
|
|
9
|
+
import { deferStreamingPlugin, streamingSupportedOnAngular } from "./ssr/defer-streaming-plugin.js";
|
|
9
10
|
import { serverModePlugin } from "../server-mode-plugin.js";
|
|
10
|
-
import {
|
|
11
|
+
import { typedRoutes } from "./typed-routes-plugin.js";
|
|
11
12
|
import { i18nComponentRegistryPlugin } from "./i18n-component-registry-plugin.js";
|
|
12
13
|
import { analogNitroPlugin } from "./nitro/analog-nitro-plugin.js";
|
|
13
|
-
import "node:module";
|
|
14
|
-
import "node:path";
|
|
14
|
+
import { createRequire } from "node:module";
|
|
15
|
+
import { join } from "node:path";
|
|
15
16
|
//#region packages/platform/src/lib/platform-plugin.ts
|
|
17
|
+
/**
|
|
18
|
+
* The installed `@angular/core` major version, resolved from the workspace root
|
|
19
|
+
* (where the app's Angular is installed). Returns `null` when it cannot be
|
|
20
|
+
* detected, in which case streaming is not blocked and the build-time
|
|
21
|
+
* anchor-drift detection is relied on instead.
|
|
22
|
+
*/
|
|
23
|
+
function getAngularCoreMajor(workspaceRoot) {
|
|
24
|
+
try {
|
|
25
|
+
const { version } = createRequire(join(workspaceRoot, "noop.js"))("@angular/core/package.json");
|
|
26
|
+
const major = Number.parseInt(version.split(".")[0], 10);
|
|
27
|
+
return Number.isNaN(major) ? null : major;
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
16
32
|
function platformPlugin(opts = {}) {
|
|
17
33
|
applyDebugOption(opts.debug, opts.workspaceRoot);
|
|
18
34
|
const isTest = process.env.NODE_ENV === "test" || !!process.env["VITEST"];
|
|
@@ -20,23 +36,43 @@ function platformPlugin(opts = {}) {
|
|
|
20
36
|
ssr: true,
|
|
21
37
|
...opts
|
|
22
38
|
};
|
|
23
|
-
|
|
39
|
+
if (platformOptions.ssr && platformOptions.experimental?.streaming) {
|
|
40
|
+
const major = getAngularCoreMajor(platformOptions.workspaceRoot ?? process.cwd());
|
|
41
|
+
if (!streamingSupportedOnAngular(major)) {
|
|
42
|
+
console.warn(`[@analogjs/platform] experimental.streaming requires Angular 21+ (detected v${major}); streaming is disabled and rendering falls back to buffered SSR.`);
|
|
43
|
+
platformOptions.experimental = {
|
|
44
|
+
...platformOptions.experimental,
|
|
45
|
+
streaming: false
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
debugPlatform("experimental options resolved", { typedRouting: platformOptions.experimental?.typedRouting });
|
|
24
50
|
return [
|
|
51
|
+
...platformOptions.experimental?.typedRouting ? [typedRoutes({
|
|
52
|
+
...typeof platformOptions.experimental.typedRouting === "object" ? platformOptions.experimental.typedRouting : {},
|
|
53
|
+
workspaceRoot: platformOptions.workspaceRoot,
|
|
54
|
+
additionalPagesDirs: platformOptions.additionalPagesDirs,
|
|
55
|
+
additionalContentDirs: platformOptions.additionalContentDirs
|
|
56
|
+
})] : [],
|
|
25
57
|
{
|
|
26
58
|
name: "analogjs-debug-activate",
|
|
27
59
|
config(_, { command }) {
|
|
28
60
|
activateDeferredDebug(command);
|
|
29
61
|
}
|
|
30
62
|
},
|
|
63
|
+
{
|
|
64
|
+
name: "@analogjs/platform-options",
|
|
65
|
+
api: { analogOptions: platformOptions }
|
|
66
|
+
},
|
|
31
67
|
...!isTest ? [analogNitroPlugin(platformOptions)] : [],
|
|
32
68
|
...platformOptions.ssr ? [...ssrBuildPlugin(), ...injectHTMLPlugin()] : [],
|
|
69
|
+
...platformOptions.ssr && platformOptions.experimental?.streaming ? [deferStreamingPlugin()] : [],
|
|
33
70
|
...!isTest ? depsPlugin(platformOptions) : [],
|
|
34
71
|
...routerPlugin(platformOptions),
|
|
35
72
|
analogIntegrationPlugin(platformOptions),
|
|
36
|
-
routeGenerationPlugin(platformOptions),
|
|
37
73
|
...contentPlugin(platformOptions?.content, platformOptions),
|
|
38
74
|
...platformOptions.i18n ? [i18nComponentRegistryPlugin()] : [],
|
|
39
|
-
...serverModePlugin(),
|
|
75
|
+
...serverModePlugin(platformOptions.entryServer),
|
|
40
76
|
clearClientPageEndpointsPlugin()
|
|
41
77
|
];
|
|
42
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-plugin.js","names":[],"sources":["../../../src/lib/platform-plugin.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport { Plugin } from 'vite';\n\nimport { Options } from './options.js';\nimport {\n activateDeferredDebug,\n applyDebugOption,\n debugPlatform,\n} from './utils/debug.js';\nimport { routerPlugin } from './router-plugin.js';\nimport { analogIntegrationPlugin } from './analog-integration-plugin.js';\nimport { ssrBuildPlugin } from './ssr/ssr-build-plugin.js';\nimport { contentPlugin } from './content-plugin.js';\nimport { clearClientPageEndpointsPlugin } from './clear-client-page-endpoint.js';\nimport { depsPlugin } from './deps-plugin.js';\nimport { injectHTMLPlugin } from './ssr/inject-html-plugin.js';\nimport { serverModePlugin } from '../server-mode-plugin.js';\nimport {
|
|
1
|
+
{"version":3,"file":"platform-plugin.js","names":[],"sources":["../../../src/lib/platform-plugin.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport { Plugin } from 'vite';\n\nimport { Options } from './options.js';\nimport {\n activateDeferredDebug,\n applyDebugOption,\n debugPlatform,\n} from './utils/debug.js';\nimport { routerPlugin } from './router-plugin.js';\nimport { analogIntegrationPlugin } from './analog-integration-plugin.js';\nimport { ssrBuildPlugin } from './ssr/ssr-build-plugin.js';\nimport { contentPlugin } from './content-plugin.js';\nimport { clearClientPageEndpointsPlugin } from './clear-client-page-endpoint.js';\nimport { depsPlugin } from './deps-plugin.js';\nimport { injectHTMLPlugin } from './ssr/inject-html-plugin.js';\nimport {\n deferStreamingPlugin,\n MIN_STREAMING_ANGULAR_MAJOR,\n streamingSupportedOnAngular,\n} from './ssr/defer-streaming-plugin.js';\nimport { serverModePlugin } from '../server-mode-plugin.js';\nimport { typedRoutes } from './typed-routes-plugin.js';\nimport { i18nComponentRegistryPlugin } from './i18n-component-registry-plugin.js';\nimport { analogNitroPlugin } from './nitro/analog-nitro-plugin.js';\n\n/**\n * The installed `@angular/core` major version, resolved from the workspace root\n * (where the app's Angular is installed). Returns `null` when it cannot be\n * detected, in which case streaming is not blocked and the build-time\n * anchor-drift detection is relied on instead.\n */\nfunction getAngularCoreMajor(workspaceRoot: string): number | null {\n try {\n const req = createRequire(join(workspaceRoot, 'noop.js'));\n const { version } = req('@angular/core/package.json') as {\n version: string;\n };\n const major = Number.parseInt(version.split('.')[0], 10);\n return Number.isNaN(major) ? null : major;\n } catch {\n return null;\n }\n}\n\nexport function platformPlugin(opts: Options = {}): Plugin[] {\n applyDebugOption(opts.debug, opts.workspaceRoot);\n\n const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const { ...platformOptions } = {\n ssr: true,\n ...opts,\n };\n\n // Streaming patches the compiled @angular/core, which needs a supported\n // Angular version. Turn it off otherwise so the renderer stays buffered.\n if (platformOptions.ssr && platformOptions.experimental?.streaming) {\n const major = getAngularCoreMajor(\n platformOptions.workspaceRoot ?? process.cwd(),\n );\n if (!streamingSupportedOnAngular(major)) {\n console.warn(\n `[@analogjs/platform] experimental.streaming requires Angular ` +\n `${MIN_STREAMING_ANGULAR_MAJOR}+ (detected v${major}); streaming is ` +\n `disabled and rendering falls back to buffered SSR.`,\n );\n platformOptions.experimental = {\n ...platformOptions.experimental,\n streaming: false,\n };\n }\n }\n\n debugPlatform('experimental options resolved', {\n typedRouting: platformOptions.experimental?.typedRouting,\n });\n\n return [\n ...(platformOptions.experimental?.typedRouting\n ? [\n typedRoutes({\n ...(typeof platformOptions.experimental.typedRouting === 'object'\n ? platformOptions.experimental.typedRouting\n : {}),\n workspaceRoot: platformOptions.workspaceRoot,\n additionalPagesDirs: platformOptions.additionalPagesDirs,\n additionalContentDirs: platformOptions.additionalContentDirs,\n }),\n ]\n : []),\n {\n name: 'analogjs-debug-activate',\n config(_, { command }) {\n activateDeferredDebug(command);\n },\n },\n // `nitro()` from `@analogjs/vite-plugin-nitro` reads these as its defaults.\n {\n name: '@analogjs/platform-options',\n api: { analogOptions: platformOptions },\n },\n ...(!isTest ? [analogNitroPlugin(platformOptions)] : []),\n ...(platformOptions.ssr\n ? [...ssrBuildPlugin(), ...injectHTMLPlugin()]\n : []),\n ...(platformOptions.ssr && platformOptions.experimental?.streaming\n ? [deferStreamingPlugin()]\n : []),\n ...(!isTest ? depsPlugin(platformOptions) : []),\n ...routerPlugin(platformOptions),\n analogIntegrationPlugin(platformOptions),\n ...contentPlugin(platformOptions?.content, platformOptions),\n ...(platformOptions.i18n ? [i18nComponentRegistryPlugin()] : []),\n ...serverModePlugin(platformOptions.entryServer),\n clearClientPageEndpointsPlugin(),\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAS,oBAAoB,eAAsC;AACjE,KAAI;EAEF,MAAM,EAAE,YADI,cAAc,KAAK,eAAe,UAAU,CAAC,CACjC,6BAA6B;EAGrD,MAAM,QAAQ,OAAO,SAAS,QAAQ,MAAM,IAAI,CAAC,IAAI,GAAG;AACxD,SAAO,OAAO,MAAM,MAAM,GAAG,OAAO;SAC9B;AACN,SAAO;;;AAIX,SAAgB,eAAe,OAAgB,EAAE,EAAY;AAC3D,kBAAiB,KAAK,OAAO,KAAK,cAAc;CAEhD,MAAM,SAAA,QAAA,IAAA,aAAqC,UAAU,CAAC,CAAC,QAAQ,IAAI;CACnE,MAAM,EAAE,GAAG,oBAAoB;EAC7B,KAAK;EACL,GAAG;EACJ;AAID,KAAI,gBAAgB,OAAO,gBAAgB,cAAc,WAAW;EAClE,MAAM,QAAQ,oBACZ,gBAAgB,iBAAiB,QAAQ,KAAK,CAC/C;AACD,MAAI,CAAC,4BAA4B,MAAM,EAAE;AACvC,WAAQ,KACN,+EACgD,MAAM,oEAEvD;AACD,mBAAgB,eAAe;IAC7B,GAAG,gBAAgB;IACnB,WAAW;IACZ;;;AAIL,eAAc,iCAAiC,EAC7C,cAAc,gBAAgB,cAAc,cAC7C,CAAC;AAEF,QAAO;EACL,GAAI,gBAAgB,cAAc,eAC9B,CACE,YAAY;GACV,GAAI,OAAO,gBAAgB,aAAa,iBAAiB,WACrD,gBAAgB,aAAa,eAC7B,EAAE;GACN,eAAe,gBAAgB;GAC/B,qBAAqB,gBAAgB;GACrC,uBAAuB,gBAAgB;GACxC,CAAC,CACH,GACD,EAAE;EACN;GACE,MAAM;GACN,OAAO,GAAG,EAAE,WAAW;AACrB,0BAAsB,QAAQ;;GAEjC;EAED;GACE,MAAM;GACN,KAAK,EAAE,eAAe,iBAAiB;GACxC;EACD,GAAI,CAAC,SAAS,CAAC,kBAAkB,gBAAgB,CAAC,GAAG,EAAE;EACvD,GAAI,gBAAgB,MAChB,CAAC,GAAG,gBAAgB,EAAE,GAAG,kBAAkB,CAAC,GAC5C,EAAE;EACN,GAAI,gBAAgB,OAAO,gBAAgB,cAAc,YACrD,CAAC,sBAAsB,CAAC,GACxB,EAAE;EACN,GAAI,CAAC,SAAS,WAAW,gBAAgB,GAAG,EAAE;EAC9C,GAAG,aAAa,gBAAgB;EAChC,wBAAwB,gBAAgB;EACxC,GAAG,cAAc,iBAAiB,SAAS,gBAAgB;EAC3D,GAAI,gBAAgB,OAAO,CAAC,6BAA6B,CAAC,GAAG,EAAE;EAC/D,GAAG,iBAAiB,gBAAgB,YAAY;EAChD,gCAAgC;EACjC"}
|
|
@@ -4,10 +4,12 @@ export interface RouteFileDiscoveryOptions {
|
|
|
4
4
|
additionalPagesDirs: string[];
|
|
5
5
|
additionalContentDirs: string[];
|
|
6
6
|
}
|
|
7
|
+
export type RouteFileKind = "route" | "content" | "server";
|
|
7
8
|
export interface RouteFileDiscovery {
|
|
8
9
|
getRouteFiles(): string[];
|
|
9
10
|
getContentFiles(): string[];
|
|
10
|
-
|
|
11
|
+
/** `server` marks page `.server.ts` files, which affect `load` types only. */
|
|
12
|
+
getDiscoveredFileKind(path: string): RouteFileKind | null;
|
|
11
13
|
updateDiscoveredFile(path: string, event: "add" | "change" | "unlink"): void;
|
|
12
14
|
/**
|
|
13
15
|
* Returns true if the normalized filename was discovered from an app-local
|
|
@@ -8,23 +8,34 @@ function createRouteFileDiscovery(options) {
|
|
|
8
8
|
let contentFilesCache = /* @__PURE__ */ new Set();
|
|
9
9
|
let appLocalFilesCache = /* @__PURE__ */ new Set();
|
|
10
10
|
let initialized = false;
|
|
11
|
-
const joinDir = (dir) => dir
|
|
11
|
+
const joinDir = (dir) => isWithinDir(dir, workspaceRoot) ? normalizePath(dir) : dir.startsWith("/") ? normalizePath(`${workspaceRoot}${dir}`) : normalizePath(resolve(workspaceRoot, dir));
|
|
12
12
|
const additionalPagesRoots = additionalPagesDirs.map(joinDir);
|
|
13
13
|
const additionalContentRoots = additionalContentDirs.map(joinDir);
|
|
14
14
|
function normalizePath_(absolutePath) {
|
|
15
15
|
const normalized = normalizePath(absolutePath);
|
|
16
|
-
if (normalized
|
|
17
|
-
if (normalized
|
|
16
|
+
if (isWithinDir(normalized, root)) return normalized.slice(root.length);
|
|
17
|
+
if (isWithinDir(normalized, workspaceRoot)) return normalized.slice(workspaceRoot.length);
|
|
18
18
|
return normalized;
|
|
19
19
|
}
|
|
20
20
|
function isWithinDir(path, dir) {
|
|
21
21
|
return path === dir || path.startsWith(`${dir}/`);
|
|
22
22
|
}
|
|
23
|
+
function getAppLocalFileKind(path) {
|
|
24
|
+
if (path.endsWith(".md") && [
|
|
25
|
+
"src/app/routes",
|
|
26
|
+
"src/app/pages",
|
|
27
|
+
"src/content"
|
|
28
|
+
].some((dir) => isWithinDir(path, `${root}/${dir}`))) return "content";
|
|
29
|
+
if (path.endsWith(".ts") && ["app/routes", "src/app/routes"].some((dir) => isWithinDir(path, `${root}/${dir}`)) || path.endsWith(".page.ts") && isWithinDir(path, `${root}/src/app/pages`)) return "route";
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
23
32
|
function getDiscoveredFileKind(path) {
|
|
24
33
|
const normalized = normalizePath(path);
|
|
25
|
-
|
|
26
|
-
if (
|
|
27
|
-
if (normalized.endsWith(".
|
|
34
|
+
const localKind = getAppLocalFileKind(normalized);
|
|
35
|
+
if (localKind) return localKind;
|
|
36
|
+
if (normalized.endsWith(".md") && additionalContentRoots.some((dir) => isWithinDir(normalized, dir))) return "content";
|
|
37
|
+
if (normalized.endsWith(".page.ts") && additionalPagesRoots.some((dir) => isWithinDir(normalized, dir))) return "route";
|
|
38
|
+
if (normalized.endsWith(".server.ts") && [`${root}/src/app/pages`, ...additionalPagesRoots].some((dir) => isWithinDir(normalized, dir))) return "server";
|
|
28
39
|
return null;
|
|
29
40
|
}
|
|
30
41
|
function scanRouteFiles() {
|
|
@@ -64,7 +75,7 @@ function createRouteFileDiscovery(options) {
|
|
|
64
75
|
return [...appLocal, ...additional];
|
|
65
76
|
}
|
|
66
77
|
function isAppLocalByPath(absolutePath) {
|
|
67
|
-
return normalizePath(absolutePath)
|
|
78
|
+
return getAppLocalFileKind(normalizePath(absolutePath)) !== null;
|
|
68
79
|
}
|
|
69
80
|
function ensureInitialized() {
|
|
70
81
|
if (initialized) return;
|
|
@@ -87,7 +98,7 @@ function createRouteFileDiscovery(options) {
|
|
|
87
98
|
updateDiscoveredFile(path, event) {
|
|
88
99
|
ensureInitialized();
|
|
89
100
|
const kind = getDiscoveredFileKind(path);
|
|
90
|
-
if (!kind) return;
|
|
101
|
+
if (!kind || kind === "server") return;
|
|
91
102
|
const normalizedPath = normalizePath_(path);
|
|
92
103
|
const targetCache = kind === "content" ? contentFilesCache : routeFilesCache;
|
|
93
104
|
if (event === "unlink") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-file-discovery.js","names":[],"sources":["../../../src/lib/route-file-discovery.ts"],"sourcesContent":["import { normalizePath } from 'vite';\nimport { resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\n\nexport interface RouteFileDiscoveryOptions {\n root: string;\n workspaceRoot: string;\n additionalPagesDirs: string[];\n additionalContentDirs: string[];\n}\n\nexport interface RouteFileDiscovery {\n getRouteFiles(): string[];\n getContentFiles(): string[];\n getDiscoveredFileKind(path: string):
|
|
1
|
+
{"version":3,"file":"route-file-discovery.js","names":[],"sources":["../../../src/lib/route-file-discovery.ts"],"sourcesContent":["import { normalizePath } from 'vite';\nimport { resolve } from 'node:path';\nimport { globSync } from 'tinyglobby';\n\nexport interface RouteFileDiscoveryOptions {\n root: string;\n workspaceRoot: string;\n additionalPagesDirs: string[];\n additionalContentDirs: string[];\n}\n\nexport type RouteFileKind = 'route' | 'content' | 'server';\n\nexport interface RouteFileDiscovery {\n getRouteFiles(): string[];\n getContentFiles(): string[];\n /** `server` marks page `.server.ts` files, which affect `load` types only. */\n getDiscoveredFileKind(path: string): RouteFileKind | null;\n updateDiscoveredFile(path: string, event: 'add' | 'change' | 'unlink'): void;\n /**\n * Returns true if the normalized filename was discovered from an app-local\n * glob (under the configured root) rather than from an additional directory.\n *\n * Used by collision priority to prefer app-local routes over shared/external\n * routes based on actual configured roots instead of hard-coded path\n * substrings.\n */\n isAppLocal(normalizedFilename: string): boolean;\n reset(): void;\n}\n\nexport function createRouteFileDiscovery(\n options: RouteFileDiscoveryOptions,\n): RouteFileDiscovery {\n const { root, workspaceRoot, additionalPagesDirs, additionalContentDirs } =\n options;\n\n let routeFilesCache = new Set<string>();\n let contentFilesCache = new Set<string>();\n let appLocalFilesCache = new Set<string>();\n let initialized = false;\n const joinDir = (dir: string) =>\n isWithinDir(dir, workspaceRoot)\n ? normalizePath(dir)\n : dir.startsWith('/')\n ? normalizePath(`${workspaceRoot}${dir}`)\n : normalizePath(resolve(workspaceRoot, dir));\n const additionalPagesRoots = additionalPagesDirs.map(joinDir);\n const additionalContentRoots = additionalContentDirs.map(joinDir);\n\n function normalizePath_(absolutePath: string): string {\n const normalized = normalizePath(absolutePath);\n if (isWithinDir(normalized, root)) {\n return normalized.slice(root.length);\n }\n if (isWithinDir(normalized, workspaceRoot)) {\n return normalized.slice(workspaceRoot.length);\n }\n return normalized;\n }\n\n function isWithinDir(path: string, dir: string): boolean {\n return path === dir || path.startsWith(`${dir}/`);\n }\n\n function getAppLocalFileKind(path: string): 'route' | 'content' | null {\n if (\n path.endsWith('.md') &&\n ['src/app/routes', 'src/app/pages', 'src/content'].some((dir) =>\n isWithinDir(path, `${root}/${dir}`),\n )\n )\n return 'content';\n if (\n (path.endsWith('.ts') &&\n ['app/routes', 'src/app/routes'].some((dir) =>\n isWithinDir(path, `${root}/${dir}`),\n )) ||\n (path.endsWith('.page.ts') && isWithinDir(path, `${root}/src/app/pages`))\n )\n return 'route';\n return null;\n }\n\n function getDiscoveredFileKind(path: string): RouteFileKind | null {\n const normalized = normalizePath(path);\n const localKind = getAppLocalFileKind(normalized);\n if (localKind) return localKind;\n if (\n normalized.endsWith('.md') &&\n additionalContentRoots.some((dir) => isWithinDir(normalized, dir))\n ) {\n return 'content';\n }\n if (\n normalized.endsWith('.page.ts') &&\n additionalPagesRoots.some((dir) => isWithinDir(normalized, dir))\n ) {\n return 'route';\n }\n if (\n normalized.endsWith('.server.ts') &&\n [`${root}/src/app/pages`, ...additionalPagesRoots].some((dir) =>\n isWithinDir(normalized, dir),\n )\n ) {\n return 'server';\n }\n return null;\n }\n\n function scanRouteFiles(): string[] {\n const appLocalGlobs = [\n `${root}/app/routes/**/*.ts`,\n `${root}/src/app/routes/**/*.ts`,\n `${root}/src/app/pages/**/*.page.ts`,\n ];\n const additionalGlobs = additionalPagesDirs.map(\n (dir) => `${joinDir(dir)}/**/*.page.ts`,\n );\n\n const appLocal = globSync(appLocalGlobs, {\n dot: true,\n absolute: true,\n }).map(normalizePath_);\n\n const additional = globSync(additionalGlobs, {\n dot: true,\n absolute: true,\n }).map(normalizePath_);\n\n for (const f of appLocal) {\n appLocalFilesCache.add(f);\n }\n\n return [...appLocal, ...additional];\n }\n\n function scanContentFiles(): string[] {\n const appLocalGlobs = [\n `${root}/src/app/routes/**/*.md`,\n `${root}/src/app/pages/**/*.md`,\n `${root}/src/content/**/*.md`,\n ];\n const additionalGlobs = additionalContentDirs.map(\n (dir) => `${joinDir(dir)}/**/*.md`,\n );\n\n const appLocal = globSync(appLocalGlobs, {\n dot: true,\n absolute: true,\n }).map(normalizePath_);\n\n const additional = globSync(additionalGlobs, {\n dot: true,\n absolute: true,\n }).map(normalizePath_);\n\n for (const f of appLocal) {\n appLocalFilesCache.add(f);\n }\n\n return [...appLocal, ...additional];\n }\n\n function isAppLocalByPath(absolutePath: string): boolean {\n const normalized = normalizePath(absolutePath);\n return getAppLocalFileKind(normalized) !== null;\n }\n\n function ensureInitialized(): void {\n if (initialized) {\n return;\n }\n\n routeFilesCache = new Set(scanRouteFiles());\n contentFilesCache = new Set(scanContentFiles());\n initialized = true;\n }\n\n return {\n getRouteFiles(): string[] {\n ensureInitialized();\n return [...routeFilesCache].sort();\n },\n\n getContentFiles(): string[] {\n ensureInitialized();\n return [...contentFilesCache].sort();\n },\n\n getDiscoveredFileKind(path: string): RouteFileKind | null {\n return getDiscoveredFileKind(path);\n },\n\n updateDiscoveredFile(\n path: string,\n event: 'add' | 'change' | 'unlink',\n ): void {\n ensureInitialized();\n const kind = getDiscoveredFileKind(path);\n if (!kind || kind === 'server') {\n return;\n }\n\n const normalizedPath = normalizePath_(path);\n const targetCache =\n kind === 'content' ? contentFilesCache : routeFilesCache;\n\n if (event === 'unlink') {\n targetCache.delete(normalizedPath);\n appLocalFilesCache.delete(normalizedPath);\n return;\n }\n\n targetCache.add(normalizedPath);\n if (isAppLocalByPath(path)) {\n appLocalFilesCache.add(normalizedPath);\n }\n },\n\n isAppLocal(normalizedFilename: string): boolean {\n ensureInitialized();\n return appLocalFilesCache.has(normalizedFilename);\n },\n\n reset(): void {\n initialized = false;\n appLocalFilesCache = new Set<string>();\n },\n };\n}\n"],"mappings":"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"}
|