@analogjs/platform 3.0.0-alpha.90 → 3.0.0-alpha.91

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/platform",
3
- "version": "3.0.0-alpha.90",
3
+ "version": "3.0.0-alpha.91",
4
4
  "description": "The fullstack meta-framework for Angular",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
@@ -31,7 +31,7 @@
31
31
  "url": "https://github.com/sponsors/brandonroberts"
32
32
  },
33
33
  "dependencies": {
34
- "@analogjs/vite-plugin-angular": "3.0.0-alpha.90",
34
+ "@analogjs/vite-plugin-angular": "3.0.0-alpha.91",
35
35
  "es-toolkit": "^1.45.1",
36
36
  "front-matter": "^4.0.2",
37
37
  "h3": "^2.0.1-rc.31",
package/src/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { platformPlugin } from "./lib/platform-plugin.js";
2
- export type { Options, PrerenderSitemapConfig, TypedRouterOptions, PrerenderContentFile, SitemapConfig, SitemapEntry, SitemapExcludeRule, SitemapPriority, SitemapRouteDefinition, SitemapRouteInput, SitemapRouteSource, SitemapTransform } from "./lib/options.js";
2
+ export type { Options, PrerenderSitemapConfig, PrerenderContentFile, SitemapConfig, SitemapEntry, SitemapExcludeRule, SitemapPriority, SitemapRouteDefinition, SitemapRouteInput, SitemapRouteSource, SitemapTransform } from "./lib/options.js";
3
3
  export { discoverLibraryRoutes } from "./lib/discover-library-routes.js";
4
4
  export type { DiscoveredLibraryRoutes } from "./lib/discover-library-routes.js";
5
- export { routeGenerationPlugin } from "./lib/route-generation-plugin.js";
6
5
  export default platformPlugin;
package/src/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { discoverLibraryRoutes } from "./lib/discover-library-routes.js";
2
- import { routeGenerationPlugin } from "./lib/route-generation-plugin.js";
3
2
  import { platformPlugin } from "./lib/platform-plugin.js";
4
3
  //#region packages/platform/src/index.ts
5
4
  var src_default = platformPlugin;
6
5
  //#endregion
7
- export { src_default as default, discoverLibraryRoutes, routeGenerationPlugin };
6
+ export { src_default as default, discoverLibraryRoutes };
8
7
 
9
8
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { platformPlugin } from './lib/platform-plugin.js';\n\nexport type {\n Options,\n PrerenderSitemapConfig,\n TypedRouterOptions,\n PrerenderContentFile,\n SitemapConfig,\n SitemapEntry,\n SitemapExcludeRule,\n SitemapPriority,\n SitemapRouteDefinition,\n SitemapRouteInput,\n SitemapRouteSource,\n SitemapTransform,\n} from './lib/options.js';\nexport { discoverLibraryRoutes } from './lib/discover-library-routes.js';\nexport type { DiscoveredLibraryRoutes } from './lib/discover-library-routes.js';\nexport { routeGenerationPlugin } from './lib/route-generation-plugin.js';\nexport default platformPlugin;\n"],"mappings":";;;;AAmBA,IAAA,cAAe"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { platformPlugin } from './lib/platform-plugin.js';\n\nexport type {\n Options,\n PrerenderSitemapConfig,\n PrerenderContentFile,\n SitemapConfig,\n SitemapEntry,\n SitemapExcludeRule,\n SitemapPriority,\n SitemapRouteDefinition,\n SitemapRouteInput,\n SitemapRouteSource,\n SitemapTransform,\n} from './lib/options.js';\nexport { discoverLibraryRoutes } from './lib/discover-library-routes.js';\nexport type { DiscoveredLibraryRoutes } from './lib/discover-library-routes.js';\nexport default platformPlugin;\n"],"mappings":";;;AAiBA,IAAA,cAAe"}
@@ -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.90";
4
- export declare const V18_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.90";
5
- export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.90";
6
- export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.90";
3
+ export declare const V18_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.91";
4
+ export declare const V18_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.91";
5
+ export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.91";
6
+ export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.91";
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,7 @@ 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.90";
18
+ export declare const V18_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.91";
19
19
  export declare const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = "^19.0.0";
20
20
  export declare const V18_X_NX_VITE = "^21.0.0";
21
21
  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.90';\nexport const V18_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.90';\nexport const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.90';\nexport const V18_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.90';\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.90';\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"}
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.91';\nexport const V18_X_ANALOG_JS_ROUTER = '^3.0.0-alpha.91';\nexport const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.91';\nexport const V18_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.91';\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.91';\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"}
@@ -1,13 +1,13 @@
1
- export declare const V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.90";
2
- export declare const V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.90";
1
+ export declare const V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.91";
2
+ export declare const V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.91";
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.90";
9
- export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.90";
10
- export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.90";
8
+ export declare const V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.91";
9
+ export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.91";
10
+ export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.91";
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.90";
3
- var V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.90";
2
+ var V19_X_ANALOG_JS_ROUTER = "^3.0.0-alpha.91";
3
+ var V19_X_ANALOG_JS_CONTENT = "^3.0.0-alpha.91";
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.90";
10
- var V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.90";
11
- var V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.90";
9
+ var V19_X_ANALOG_JS_PLATFORM = "^3.0.0-alpha.91";
10
+ var V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^3.0.0-alpha.91";
11
+ var V19_X_ANALOG_JS_VITEST_ANGULAR = "^3.0.0-alpha.91";
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.90';\nexport const V19_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.90';\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.90';\nexport const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.90';\nexport const V19_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.90';\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"}
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.91';\nexport const V19_X_ANALOG_JS_CONTENT = '^3.0.0-alpha.91';\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.91';\nexport const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^3.0.0-alpha.91';\nexport const V19_X_ANALOG_JS_VITEST_ANGULAR = '^3.0.0-alpha.91';\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"}
@@ -113,58 +113,10 @@ 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?: {
125
- /**
126
- * Enable typed route table generation for type-safe navigation.
127
- *
128
- * When enabled, `@analogjs/platform` generates a single route module
129
- * that augments `AnalogRouteTable` with typed params and query for each
130
- * file-based route. JSON-LD manifest generation is configured on the same
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.
144
- */
145
- typedRouter?: boolean | TypedRouterOptions;
118
+ /** Generate route declarations and enable typed navigation helpers. */
119
+ typedRouting?: boolean | import("./typed-routes-plugin.js").TypedRoutingOptions;
146
120
  };
147
121
  }
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
122
  export type { PrerenderContentDir, PrerenderContentFile, PrerenderSitemapConfig, SitemapConfig, SitemapEntry, SitemapExcludeRule, SitemapPriority, SitemapRouteDefinition, SitemapRouteInput, SitemapRouteSource, SitemapTransform };
@@ -7,7 +7,7 @@ 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
9
  import { serverModePlugin } from "../server-mode-plugin.js";
10
- import { routeGenerationPlugin } from "./route-generation-plugin.js";
10
+ import { typedRoutes } from "./typed-routes-plugin.js";
11
11
  import { i18nComponentRegistryPlugin } from "./i18n-component-registry-plugin.js";
12
12
  import { analogNitroPlugin } from "./nitro/analog-nitro-plugin.js";
13
13
  import "node:module";
@@ -20,8 +20,14 @@ function platformPlugin(opts = {}) {
20
20
  ssr: true,
21
21
  ...opts
22
22
  };
23
- debugPlatform("experimental options resolved", { typedRouter: platformOptions.experimental?.typedRouter });
23
+ debugPlatform("experimental options resolved", { typedRouting: platformOptions.experimental?.typedRouting });
24
24
  return [
25
+ ...platformOptions.experimental?.typedRouting ? [typedRoutes({
26
+ ...typeof platformOptions.experimental.typedRouting === "object" ? platformOptions.experimental.typedRouting : {},
27
+ workspaceRoot: platformOptions.workspaceRoot,
28
+ additionalPagesDirs: platformOptions.additionalPagesDirs,
29
+ additionalContentDirs: platformOptions.additionalContentDirs
30
+ })] : [],
25
31
  {
26
32
  name: "analogjs-debug-activate",
27
33
  config(_, { command }) {
@@ -33,7 +39,6 @@ function platformPlugin(opts = {}) {
33
39
  ...!isTest ? depsPlugin(platformOptions) : [],
34
40
  ...routerPlugin(platformOptions),
35
41
  analogIntegrationPlugin(platformOptions),
36
- routeGenerationPlugin(platformOptions),
37
42
  ...contentPlugin(platformOptions?.content, platformOptions),
38
43
  ...platformOptions.i18n ? [i18nComponentRegistryPlugin()] : [],
39
44
  ...serverModePlugin(),
@@ -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 { routeGenerationPlugin } from './route-generation-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 debugPlatform('experimental options resolved', {\n typedRouter: platformOptions.experimental?.typedRouter,\n });\n\n return [\n {\n name: 'analogjs-debug-activate',\n config(_, { command }) {\n activateDeferredDebug(command);\n },\n },\n ...(!isTest ? [analogNitroPlugin(platformOptions)] : []),\n ...(platformOptions.ssr\n ? [...ssrBuildPlugin(), ...injectHTMLPlugin()]\n : []),\n ...(!isTest ? depsPlugin(platformOptions) : []),\n ...routerPlugin(platformOptions),\n analogIntegrationPlugin(platformOptions),\n routeGenerationPlugin(platformOptions),\n ...contentPlugin(platformOptions?.content, platformOptions),\n ...(platformOptions.i18n ? [i18nComponentRegistryPlugin()] : []),\n ...serverModePlugin(),\n clearClientPageEndpointsPlugin(),\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;AAyCA,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;AAED,eAAc,iCAAiC,EAC7C,aAAa,gBAAgB,cAAc,aAC5C,CAAC;AAEF,QAAO;EACL;GACE,MAAM;GACN,OAAO,GAAG,EAAE,WAAW;AACrB,0BAAsB,QAAQ;;GAEjC;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,CAAC,SAAS,WAAW,gBAAgB,GAAG,EAAE;EAC9C,GAAG,aAAa,gBAAgB;EAChC,wBAAwB,gBAAgB;EACxC,sBAAsB,gBAAgB;EACtC,GAAG,cAAc,iBAAiB,SAAS,gBAAgB;EAC3D,GAAI,gBAAgB,OAAO,CAAC,6BAA6B,CAAC,GAAG,EAAE;EAC/D,GAAG,kBAAkB;EACrB,gCAAgC;EACjC"}
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 { 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 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 ...(!isTest ? [analogNitroPlugin(platformOptions)] : []),\n ...(platformOptions.ssr\n ? [...ssrBuildPlugin(), ...injectHTMLPlugin()]\n : []),\n ...(!isTest ? depsPlugin(platformOptions) : []),\n ...routerPlugin(platformOptions),\n analogIntegrationPlugin(platformOptions),\n ...contentPlugin(platformOptions?.content, platformOptions),\n ...(platformOptions.i18n ? [i18nComponentRegistryPlugin()] : []),\n ...serverModePlugin(),\n clearClientPageEndpointsPlugin(),\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;AAyCA,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;AAED,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;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,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,kBAAkB;EACrB,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
- getDiscoveredFileKind(path: string): "route" | "content" | null;
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.startsWith(workspaceRoot) ? normalizePath(dir) : dir.startsWith("/") ? normalizePath(`${workspaceRoot}${dir}`) : normalizePath(resolve(workspaceRoot, 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.startsWith(root)) return normalized.slice(root.length);
17
- if (normalized.startsWith(workspaceRoot)) return normalized.slice(workspaceRoot.length);
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
- if (normalized.endsWith(".md") && (normalized.includes("/src/app/routes/") || normalized.includes("/src/app/pages/") || normalized.includes("/src/content/") || additionalContentRoots.some((dir) => isWithinDir(normalized, dir)))) return "content";
26
- if ((normalized.includes("/app/routes/") || normalized.includes("/src/app/routes/")) && normalized.endsWith(".ts")) return "route";
27
- if (normalized.endsWith(".page.ts") && (normalized.includes("/src/app/pages/") || additionalPagesRoots.some((dir) => isWithinDir(normalized, dir)))) return "route";
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).startsWith(root);
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): 'route' | 'content' | 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 dir.startsWith(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 (normalized.startsWith(root)) {\n return normalized.slice(root.length);\n }\n if (normalized.startsWith(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 getDiscoveredFileKind(path: string): 'route' | 'content' | null {\n const normalized = normalizePath(path);\n\n if (\n normalized.endsWith('.md') &&\n (normalized.includes('/src/app/routes/') ||\n normalized.includes('/src/app/pages/') ||\n normalized.includes('/src/content/') ||\n additionalContentRoots.some((dir) => isWithinDir(normalized, dir)))\n ) {\n return 'content';\n }\n\n if (\n (normalized.includes('/app/routes/') ||\n normalized.includes('/src/app/routes/')) &&\n normalized.endsWith('.ts')\n ) {\n return 'route';\n }\n\n // Keep the dev watcher aligned with the build-time route scan. In\n // particular, `src/server/routes/**` must stay out of typed route codegen\n // because Nitro API handlers are not client-navigable pages.\n if (\n normalized.endsWith('.page.ts') &&\n (normalized.includes('/src/app/pages/') ||\n additionalPagesRoots.some((dir) => isWithinDir(normalized, dir)))\n ) {\n return 'route';\n }\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 normalized.startsWith(root);\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): 'route' | 'content' | 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) {\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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"}
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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"}
@@ -1,14 +1,13 @@
1
+ /**
2
+ * Route-manifest engine for typed file routes.
3
+ *
4
+ * Pure functions (no Angular dependencies) for converting discovered
5
+ * filenames into typed route manifests and generated declarations.
6
+ */
1
7
  export interface RouteParamInfo {
2
8
  name: string;
3
9
  type: "dynamic" | "catchAll" | "optionalCatchAll";
4
10
  }
5
- export interface RouteSchemaInfo {
6
- hasParamsSchema: boolean;
7
- hasQuerySchema: boolean;
8
- }
9
- export interface GenerateRouteTreeDeclarationOptions {
10
- jsonLdFiles?: Iterable<string>;
11
- }
12
11
  export interface RouteEntry {
13
12
  /** Stable structural route id derived from the source filename */
14
13
  id: string;
@@ -20,8 +19,6 @@ export interface RouteEntry {
20
19
  params: RouteParamInfo[];
21
20
  /** Original filename that produced this route */
22
21
  filename: string;
23
- /** Schema export info (detected from file content) */
24
- schemas: RouteSchemaInfo;
25
22
  /** Type of source that produced this route */
26
23
  kind: "page" | "content";
27
24
  /** Parent route id, or null for top-level routes */
@@ -36,6 +33,8 @@ export interface RouteEntry {
36
33
  isCatchAll: boolean;
37
34
  /** Whether the route contains an optional catch-all parameter */
38
35
  isOptionalCatchAll: boolean;
36
+ /** Layout files that wrap this route, outermost first */
37
+ layouts: string[];
39
38
  }
40
39
  export interface RouteCollision {
41
40
  fullPath: string;
@@ -49,6 +48,8 @@ export interface RouteManifest {
49
48
  collisions: RouteCollision[];
50
49
  /** Canonical route per fullPath — precomputed once to avoid redundant work. */
51
50
  canonicalByFullPath: Map<string, RouteEntry>;
51
+ /** Full paths defined by more than one file, such as a layout and its index page. */
52
+ sharedFullPaths: Set<string>;
52
53
  }
53
54
  /**
54
55
  * Converts a discovered filename to a route path pattern.
@@ -94,29 +95,24 @@ export declare function filenameToRouteId(filename: string): string;
94
95
  */
95
96
  export declare function extractRouteParams(routePath: string): RouteParamInfo[];
96
97
  /**
97
- * Detects whether a route file exports schema constants.
98
- */
99
- export declare function detectSchemaExports(fileContent: string): RouteSchemaInfo;
100
- /**
101
98
  * Generates a route manifest from a list of discovered filenames.
102
99
  *
103
100
  * @param collisionPriority - Optional callback that returns a numeric priority
104
101
  * for each filename (lower wins). When provided, this replaces the default
105
102
  * hard-coded path-substring heuristic with config-derived precedence.
106
103
  */
107
- export declare function generateRouteManifest(filenames: string[], schemaDetector?: (filename: string) => RouteSchemaInfo, collisionPriority?: (filename: string) => number): RouteManifest;
108
- /**
109
- * Produces a human-readable summary of the generated route manifest.
110
- */
111
- export declare function formatManifestSummary(manifest: RouteManifest): string;
104
+ export declare function generateRouteManifest(filenames: string[], collisionPriority?: (filename: string) => number): RouteManifest;
105
+ /** Import specifiers for a page module's typed exports. */
106
+ export interface RouteModuleImports {
107
+ routeMeta?: string;
108
+ load?: string;
109
+ }
112
110
  /**
113
111
  * Generates the route-table section for the combined generated route module.
112
+ *
113
+ * `resolveModuleImports` adds `routeMeta` and `load` types for pages whose
114
+ * URL is defined by a single file, along with the `routeMeta` of the layouts
115
+ * that wrap them. URLs shared by several files, such as a layout and its
116
+ * index page, are ambiguous and only get params and query types.
114
117
  */
115
- export declare function generateRouteTableDeclaration(manifest: RouteManifest): string;
116
- /**
117
- * Generates the route-tree section for the combined generated route module.
118
- */
119
- export declare function generateRouteTreeDeclaration(manifest: RouteManifest, options?: GenerateRouteTreeDeclarationOptions): string;
120
- export type JsonLdObject = Record<string, unknown>;
121
- export declare function isJsonLdObject(value: unknown): value is JsonLdObject;
122
- export declare function normalizeJsonLd(value: unknown): JsonLdObject[];
118
+ export declare function generateRouteTableDeclaration(manifest: RouteManifest, resolveModuleImports?: (filename: string) => RouteModuleImports | undefined): string;