@analogjs/router 3.0.0-alpha.7 → 3.0.0-alpha.70

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.
Files changed (99) hide show
  1. package/content/package.json +4 -0
  2. package/fesm2022/analogjs-router-content.mjs +63 -0
  3. package/fesm2022/analogjs-router-content.mjs.map +1 -0
  4. package/fesm2022/analogjs-router-i18n.mjs +156 -0
  5. package/fesm2022/analogjs-router-i18n.mjs.map +1 -0
  6. package/fesm2022/analogjs-router-server-actions.mjs +2 -27
  7. package/fesm2022/analogjs-router-server.mjs +734 -105
  8. package/fesm2022/analogjs-router-server.mjs.map +1 -0
  9. package/fesm2022/analogjs-router-tanstack-query-server.mjs +71 -0
  10. package/fesm2022/analogjs-router-tanstack-query-server.mjs.map +1 -0
  11. package/fesm2022/analogjs-router-tanstack-query.mjs +39 -0
  12. package/fesm2022/analogjs-router-tanstack-query.mjs.map +1 -0
  13. package/fesm2022/analogjs-router-tokens.mjs +7 -2
  14. package/fesm2022/analogjs-router-tokens.mjs.map +1 -0
  15. package/fesm2022/analogjs-router.mjs +670 -170
  16. package/fesm2022/analogjs-router.mjs.map +1 -0
  17. package/fesm2022/debug.page.mjs +53 -31
  18. package/fesm2022/debug.page.mjs.map +1 -0
  19. package/fesm2022/provide-analog-query.mjs +72 -0
  20. package/fesm2022/provide-analog-query.mjs.map +1 -0
  21. package/fesm2022/route-files.mjs +361 -0
  22. package/fesm2022/route-files.mjs.map +1 -0
  23. package/fesm2022/routes.mjs +5 -278
  24. package/fesm2022/routes.mjs.map +1 -0
  25. package/fesm2022/src.mjs +335 -0
  26. package/fesm2022/src.mjs.map +1 -0
  27. package/i18n/package.json +4 -0
  28. package/package.json +52 -5
  29. package/tanstack-query/package.json +4 -0
  30. package/tanstack-query/server/package.json +4 -0
  31. package/types/content/src/index.d.ts +4 -0
  32. package/types/content/src/lib/debug/routes.d.ts +10 -0
  33. package/types/{src → content/src}/lib/markdown-helpers.d.ts +1 -1
  34. package/types/content/src/lib/routes.d.ts +8 -0
  35. package/types/content/src/lib/with-content-routes.d.ts +2 -0
  36. package/types/i18n/src/index.d.ts +1 -0
  37. package/types/i18n/src/provide-i18n.d.ts +92 -0
  38. package/types/server/actions/src/define-action.d.ts +54 -0
  39. package/types/server/actions/src/define-api-route.d.ts +57 -0
  40. package/types/server/actions/src/define-page-load.d.ts +55 -0
  41. package/types/server/actions/src/define-server-route.d.ts +68 -0
  42. package/types/server/actions/src/index.d.ts +9 -1
  43. package/types/server/actions/src/parse-request-data.d.ts +9 -0
  44. package/types/server/actions/src/validate.d.ts +8 -0
  45. package/types/server/src/defer-reconcile-runtime.d.ts +23 -0
  46. package/types/server/src/index.d.ts +9 -2
  47. package/types/server/src/provide-server-context.d.ts +15 -1
  48. package/types/server/src/render-stream.d.ts +40 -0
  49. package/types/server/src/render.d.ts +3 -3
  50. package/types/server/src/server-fn/app-injector.d.ts +30 -0
  51. package/types/server/src/server-fn/dispatch.d.ts +56 -0
  52. package/types/server/src/server-fn/event-handler.d.ts +22 -0
  53. package/types/server/src/server-fn/interceptors.d.ts +30 -0
  54. package/types/server/src/server-fn/node-context.d.ts +14 -0
  55. package/types/server/src/server-fn/registry.d.ts +7 -0
  56. package/types/server/src/server-fn/same-origin.d.ts +46 -0
  57. package/types/server/src/server-fn/server-fn.d.ts +21 -0
  58. package/types/server/src/server-fn/ssr-dispatcher.d.ts +17 -0
  59. package/types/server/src/utils/reset-component-def-tviews.d.ts +14 -0
  60. package/types/server/src/utils/stream-html.d.ts +13 -0
  61. package/types/server/src/utils/stream-request.d.ts +24 -0
  62. package/types/src/index.d.ts +20 -6
  63. package/types/src/lib/cache-key.d.ts +1 -1
  64. package/types/src/lib/cookie-interceptor.d.ts +1 -1
  65. package/types/src/lib/debug/debug.page.d.ts +4 -2
  66. package/types/src/lib/define-route.d.ts +6 -1
  67. package/types/src/lib/endpoints.d.ts +1 -1
  68. package/types/src/lib/experimental.d.ts +140 -0
  69. package/types/src/lib/form-action.directive.d.ts +12 -5
  70. package/types/src/lib/inject-load.d.ts +5 -2
  71. package/types/src/lib/inject-navigate.d.ts +23 -0
  72. package/types/src/lib/inject-route-context.d.ts +32 -0
  73. package/types/src/lib/inject-typed-params.d.ts +63 -0
  74. package/types/src/lib/json-ld.d.ts +32 -0
  75. package/types/src/lib/meta-tags.d.ts +3 -1
  76. package/types/src/lib/models.d.ts +3 -0
  77. package/types/src/lib/provide-file-router-base.d.ts +4 -0
  78. package/types/src/lib/provide-file-router.d.ts +2 -8
  79. package/types/src/lib/route-builder.d.ts +5 -0
  80. package/types/src/lib/route-files.d.ts +18 -0
  81. package/types/src/lib/route-path.d.ts +124 -0
  82. package/types/src/lib/route-types.d.ts +2 -1
  83. package/types/src/lib/routes.d.ts +2 -10
  84. package/types/src/lib/server-fn/dispatcher.d.ts +23 -0
  85. package/types/src/lib/server-fn/inject-server-fn.d.ts +44 -0
  86. package/types/src/lib/server-fn/server-fn-ref.d.ts +24 -0
  87. package/types/src/lib/server-fn/types.d.ts +55 -0
  88. package/types/src/lib/validation-errors.d.ts +7 -0
  89. package/types/tanstack-query/server/src/define-page-load-queries.d.ts +66 -0
  90. package/types/tanstack-query/server/src/index.d.ts +3 -0
  91. package/types/tanstack-query/src/constants.d.ts +9 -0
  92. package/types/tanstack-query/src/index.d.ts +2 -0
  93. package/types/tanstack-query/src/provide-analog-query.d.ts +4 -0
  94. package/types/tanstack-query/src/provide-server-analog-query.d.ts +2 -0
  95. package/types/tanstack-query/src/server-query.d.ts +16 -0
  96. package/types/tokens/src/index.d.ts +2 -0
  97. package/types/server/src/server-component-render.d.ts +0 -4
  98. package/types/server/src/tokens.d.ts +0 -7
  99. package/types/src/lib/server.component.d.ts +0 -33
@@ -1,17 +1,24 @@
1
- import { InputSignal, OutputEmitterRef } from '@angular/core';
1
+ import { type InputSignal, type OutputEmitterRef, type WritableSignal } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
+ export type FormActionState = 'submitting' | 'error' | 'redirect' | 'success' | 'navigate';
3
4
  export declare class FormAction {
4
5
  action: InputSignal<string>;
5
6
  onSuccess: OutputEmitterRef<unknown>;
6
7
  onError: OutputEmitterRef<unknown>;
7
- state: OutputEmitterRef<'submitting' | 'error' | 'redirect' | 'success' | 'navigate'>;
8
+ state: OutputEmitterRef<FormActionState>;
8
9
  private router;
9
10
  private route;
10
- private path;
11
- submitted($event: any): void;
11
+ protected currentState: WritableSignal<FormActionState | 'idle'>;
12
+ /** Cached during construction (injection context) so inject() works. */
13
+ private _endpointUrl;
14
+ submitted($event: SubmitEvent): void;
12
15
  private _handleGet;
13
16
  private _handlePost;
14
- private _getPath;
17
+ private _getExplicitAction;
18
+ private _getGetPath;
19
+ private _getPostPath;
20
+ private _emitState;
21
+ private _navigateTo;
15
22
  private _isJSON;
16
23
  static ɵfac: i0.ɵɵFactoryDeclaration<FormAction, never>;
17
24
  static ɵdir: i0.ɵɵDirectiveDeclaration<FormAction, "form[action],form[method]", never, { "action": { "alias": "action"; "required": false; "isSignal": true; }; }, { "onSuccess": "onSuccess"; "onError": "onError"; "state": "state"; }, never, never, true, never>;
@@ -1,6 +1,9 @@
1
1
  import { Injector } from '@angular/core';
2
2
  import { Observable } from 'rxjs';
3
- import { PageServerLoad } from './route-types';
4
- export declare function injectLoad<T extends (pageServerLoad: PageServerLoad) => Promise<any>>(options?: {
3
+ import { LoadDataResult, PageServerLoad } from './route-types';
4
+ export declare function injectLoad<T extends (pageServerLoad: PageServerLoad) => Promise<unknown>>(options?: {
5
5
  injector?: Injector;
6
6
  }): Observable<Awaited<ReturnType<T>>>;
7
+ export declare function injectLoadData<T extends (pageServerLoad: PageServerLoad) => Promise<unknown>>(options?: {
8
+ injector?: Injector;
9
+ }): Observable<LoadDataResult<T>>;
@@ -0,0 +1,23 @@
1
+ import { type NavigationBehaviorOptions } from '@angular/router';
2
+ import type { AnalogRoutePath, RoutePathArgs } from './route-path';
3
+ type NavigateWithExtrasArgs<P extends AnalogRoutePath> = RoutePathArgs<P> extends [options?: infer Options] ? [extras: NavigationBehaviorOptions] | [options: Options | undefined, extras: NavigationBehaviorOptions] : [options: RoutePathArgs<P>[0], extras: NavigationBehaviorOptions];
4
+ type TypedNavigate = {
5
+ <P extends AnalogRoutePath>(path: P, ...args: RoutePathArgs<P>): Promise<boolean>;
6
+ <P extends AnalogRoutePath>(path: P, ...args: NavigateWithExtrasArgs<P>): Promise<boolean>;
7
+ };
8
+ /**
9
+ * Injects a typed navigate function.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const navigate = injectNavigate();
14
+ *
15
+ * navigate('/users/[id]', { params: { id: '42' } }); // ✅
16
+ * navigate('/users/[id]', { params: { id: 42 } }); // ❌ type error
17
+ *
18
+ * // With navigation extras
19
+ * navigate('/users/[id]', { params: { id: '42' } }, { replaceUrl: true });
20
+ * ```
21
+ */
22
+ export declare function injectNavigate(): TypedNavigate;
23
+ export {};
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Injects the root route context provided via `withRouteContext()`.
3
+ *
4
+ * Inspired by TanStack Router's context inheritance where
5
+ * `createRootRouteWithContext<T>()` makes a typed context available
6
+ * to every route's `beforeLoad` and `loader` callbacks.
7
+ *
8
+ * In Angular, this uses DI under the hood — `withRouteContext(ctx)`
9
+ * provides the value, and `injectRouteContext<T>()` retrieves it
10
+ * with the expected type.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // app.config.ts
15
+ * provideFileRouter(
16
+ * withRouteContext({
17
+ * auth: inject(AuthService),
18
+ * analytics: inject(AnalyticsService),
19
+ * }),
20
+ * )
21
+ *
22
+ * // any-page.page.ts
23
+ * const ctx = injectRouteContext<{
24
+ * auth: AuthService;
25
+ * analytics: AnalyticsService;
26
+ * }>();
27
+ * ctx.analytics.trackPageView();
28
+ * ```
29
+ *
30
+ * @experimental
31
+ */
32
+ export declare function injectRouteContext<T extends Record<string, unknown> = Record<string, unknown>>(): T;
@@ -0,0 +1,63 @@
1
+ import { Injector, Signal } from '@angular/core';
2
+ import type { AnalogRoutePath, RouteParamsOutput, RouteQueryOutput } from './route-path';
3
+ /**
4
+ * Injects typed route params as a signal, constrained by the route table.
5
+ *
6
+ * Inspired by TanStack Router's `useParams({ from: '/users/$userId' })`
7
+ * pattern where the `from` parameter narrows the return type to only
8
+ * the params defined for that route.
9
+ *
10
+ * The `from` parameter is used purely for TypeScript type inference —
11
+ * at runtime, params are read from the current `ActivatedRoute`. This
12
+ * means it works correctly when used inside a component rendered by
13
+ * the specified route.
14
+ *
15
+ * When `withTypedRouter({ strictRouteParams: true })` is configured,
16
+ * a dev-mode assertion checks that the expected params from `from`
17
+ * exist in the active route and warns on mismatch.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * // In a component rendered at /users/[id]
22
+ * const params = injectParams('/users/[id]');
23
+ * // params() → { id: string }
24
+ *
25
+ * // With schema validation output types
26
+ * const params = injectParams('/products/[slug]');
27
+ * // params() → validated output type from routeParamsSchema
28
+ * ```
29
+ *
30
+ * @experimental
31
+ */
32
+ export declare function injectParams<P extends AnalogRoutePath>(_from: P, options?: {
33
+ injector?: Injector;
34
+ }): Signal<RouteParamsOutput<P>>;
35
+ /**
36
+ * Injects typed route query params as a signal, constrained by the
37
+ * route table.
38
+ *
39
+ * Inspired by TanStack Router's `useSearch({ from: '/issues' })` pattern
40
+ * where search params are validated and typed per-route via
41
+ * `validateSearch` schemas.
42
+ *
43
+ * In Analog, the typing comes from `routeQuerySchema` exports that are
44
+ * detected at build time and recorded in the generated route table.
45
+ *
46
+ * The `from` parameter is used purely for TypeScript type inference.
47
+ * When `withTypedRouter({ strictRouteParams: true })` is configured,
48
+ * a dev-mode assertion checks that the expected params from `from`
49
+ * exist in the active route and warns on mismatch.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * // In a component rendered at /issues
54
+ * // (where routeQuerySchema validates { page: number, status: string })
55
+ * const query = injectQuery('/issues');
56
+ * // query() → { page: number; status: string }
57
+ * ```
58
+ *
59
+ * @experimental
60
+ */
61
+ export declare function injectQuery<P extends AnalogRoutePath>(_from: P, options?: {
62
+ injector?: Injector;
63
+ }): Signal<RouteQueryOutput<P>>;
@@ -0,0 +1,32 @@
1
+ import { Router } from '@angular/router';
2
+ import type { Graph, Thing, WithContext } from 'schema-dts';
3
+ export type JsonLdObject = Record<string, unknown>;
4
+ export declare function isJsonLdObject(value: unknown): value is JsonLdObject;
5
+ export declare function normalizeJsonLd(value: unknown): JsonLdObject[];
6
+ export type JsonLd = JsonLdObject | JsonLdObject[];
7
+ /**
8
+ * Typed JSON-LD document based on `schema-dts`.
9
+ *
10
+ * Accepts single Schema.org nodes (`WithContext<Thing>`),
11
+ * `@graph`-based documents (`Graph`), or arrays of nodes.
12
+ *
13
+ * This is the canonical JSON-LD type for route authoring surfaces
14
+ * (`routeMeta.jsonLd`, `routeJsonLd`, generated manifest).
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import type { WebPage, WithContext } from 'schema-dts';
19
+ *
20
+ * export const routeMeta = {
21
+ * jsonLd: {
22
+ * '@context': 'https://schema.org',
23
+ * '@type': 'WebPage',
24
+ * name: 'Products',
25
+ * } satisfies WithContext<WebPage>,
26
+ * };
27
+ * ```
28
+ */
29
+ export type AnalogJsonLdDocument = WithContext<Thing> | Graph | WithContext<Thing>[];
30
+ export declare const ROUTE_JSON_LD_KEY: unique symbol;
31
+ export declare function updateJsonLdOnRouteChange(router?: Router, document?: Document | null): void;
32
+ export declare function serializeJsonLd(entry: JsonLdObject): string | null;
@@ -1,3 +1,5 @@
1
+ import { Meta } from '@angular/platform-browser';
2
+ import { Router } from '@angular/router';
1
3
  export declare const ROUTE_META_TAGS_KEY: unique symbol;
2
4
  declare const CHARSET_KEY = "charset";
3
5
  declare const HTTP_EQUIV_KEY = "httpEquiv";
@@ -29,5 +31,5 @@ type MetaTagKey = typeof CHARSET_KEY | typeof HTTP_EQUIV_KEY | typeof NAME_KEY |
29
31
  type ExcludeRestMetaTagKeys<Key extends MetaTagKey> = {
30
32
  [K in Exclude<MetaTagKey, Key>]?: never;
31
33
  };
32
- export declare function updateMetaTagsOnRouteChange(): void;
34
+ export declare function updateMetaTagsOnRouteChange(router?: Router, metaService?: Meta): void;
33
35
  export {};
@@ -1,6 +1,7 @@
1
1
  import { Type } from '@angular/core';
2
2
  import { CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanMatchFn, DeprecatedGuard, ResolveFn, Route } from '@angular/router';
3
3
  import { defineRouteMeta } from './define-route';
4
+ import { AnalogJsonLdDocument } from './json-ld';
4
5
  import { MetaTag } from './meta-tags';
5
6
  type OmittedRouteProps = 'path' | 'matcher' | 'component' | 'loadComponent' | 'children' | 'loadChildren' | 'canLoad' | 'outlet';
6
7
  export type RouteConfig = Omit<Route, OmittedRouteProps>;
@@ -14,6 +15,7 @@ export interface DefaultRouteMeta extends Omit<Route, OmittedRouteProps | keyof
14
15
  };
15
16
  title?: string | ResolveFn<string>;
16
17
  meta?: MetaTag[] | ResolveFn<MetaTag[]>;
18
+ jsonLd?: AnalogJsonLdDocument | ResolveFn<AnalogJsonLdDocument | undefined>;
17
19
  }
18
20
  export interface RedirectRouteMeta {
19
21
  redirectTo: string;
@@ -25,5 +27,6 @@ export type RouteMeta = (DefaultRouteMeta & {
25
27
  export type RouteExport = {
26
28
  default: Type<unknown>;
27
29
  routeMeta?: RouteMeta | ReturnType<typeof defineRouteMeta>;
30
+ routeJsonLd?: AnalogJsonLdDocument | ResolveFn<AnalogJsonLdDocument | undefined>;
28
31
  };
29
32
  export {};
@@ -0,0 +1,4 @@
1
+ import { EnvironmentProviders } from '@angular/core';
2
+ import { RouterFeatures, Routes } from '@angular/router';
3
+ export declare function provideFileRouterWithRoutes(...features: RouterFeatures[]): EnvironmentProviders;
4
+ export declare function withExtraRoutes(routes: Routes): RouterFeatures;
@@ -1,5 +1,5 @@
1
1
  import { EnvironmentProviders } from '@angular/core';
2
- import { RouterFeatures, Routes } from '@angular/router';
2
+ import { RouterFeatures } from '@angular/router';
3
3
  /**
4
4
  * Sets up providers for the Angular router, and registers
5
5
  * file-based routes. Additional features can be provided
@@ -9,10 +9,4 @@ import { RouterFeatures, Routes } from '@angular/router';
9
9
  * @returns Providers and features to configure the router with routes
10
10
  */
11
11
  export declare function provideFileRouter(...features: RouterFeatures[]): EnvironmentProviders;
12
- /**
13
- * Provides extra custom routes in addition to the routes
14
- * discovered from the filesystem-based routing. These routes are
15
- * inserted before the filesystem-based routes, and take priority in
16
- * route matching.
17
- */
18
- export declare function withExtraRoutes(routes: Routes): RouterFeatures;
12
+ export { withExtraRoutes } from './provide-file-router-base';
@@ -0,0 +1,5 @@
1
+ import type { Route } from '@angular/router';
2
+ import type { RouteExport } from './models';
3
+ export type RouteModuleFactory = () => Promise<RouteExport>;
4
+ export type RouteModuleResolver<TFile> = (filename: string, fileLoader: () => Promise<TFile>) => RouteModuleFactory;
5
+ export declare function createRoutes<TFile>(files: Record<string, () => Promise<TFile>>, resolveModule: RouteModuleResolver<TFile>, debug?: boolean): Route[];
@@ -0,0 +1,18 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import type { RouteExport } from './models';
3
+ export type Files = Record<string, () => Promise<RouteExport>>;
4
+ /**
5
+ * This variable reference is replaced with a glob of all page routes.
6
+ */
7
+ export declare const ANALOG_ROUTE_FILES: {};
8
+ export interface ExtraRouteFileSource {
9
+ files: Record<string, () => Promise<unknown>>;
10
+ resolveModule: (filename: string, fileLoader: () => Promise<unknown>) => () => Promise<RouteExport>;
11
+ }
12
+ export declare const ANALOG_EXTRA_ROUTE_FILE_SOURCES: InjectionToken<ExtraRouteFileSource[]>;
13
+ /**
14
+ * Replaced at build time by the Vite router plugin with the number of
15
+ * discovered content route files. Used in dev mode to warn when content
16
+ * files exist but `withContentRoutes()` is not configured.
17
+ */
18
+ export declare const ANALOG_CONTENT_FILE_COUNT = 0;
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Typed route path utilities for Analog.
3
+ *
4
+ * This module provides:
5
+ * - The `AnalogRouteTable` base interface (augmented by generated code)
6
+ * - The `AnalogRoutePath` union type
7
+ * - The `routePath()` URL builder function
8
+ *
9
+ * No Angular dependencies — can be used in any context.
10
+ */
11
+ /**
12
+ * Base interface for the typed route table.
13
+ *
14
+ * This interface is augmented by generated code in `src/routeTree.gen.ts`.
15
+ * When no routes are generated, it is empty and `AnalogRoutePath` falls
16
+ * back to `string`.
17
+ */
18
+ export interface AnalogRouteTable {
19
+ }
20
+ /**
21
+ * Union of all valid route paths.
22
+ *
23
+ * When routes are generated, this is a string literal union.
24
+ * When no routes are generated, this falls back to `string`.
25
+ */
26
+ export type AnalogRoutePath = keyof AnalogRouteTable extends never ? string : Extract<keyof AnalogRouteTable, string>;
27
+ /**
28
+ * Options for building a route URL.
29
+ */
30
+ export interface RoutePathOptionsBase {
31
+ params?: Record<string, string | string[] | undefined>;
32
+ query?: Record<string, string | string[] | undefined>;
33
+ hash?: string;
34
+ }
35
+ /**
36
+ * Extracts the validated output type for route params.
37
+ *
38
+ * When a route exports `routeParamsSchema`, this resolves to the schema's
39
+ * output type (e.g., `{ id: number }` after coercion).
40
+ * When no schema exists, this is the same as the navigation param type.
41
+ */
42
+ export type RouteParamsOutput<P extends string> = P extends keyof AnalogRouteTable ? AnalogRouteTable[P] extends {
43
+ paramsOutput: infer O;
44
+ } ? O : AnalogRouteTable[P] extends {
45
+ params: infer Params;
46
+ } ? Params : Record<string, unknown> : Record<string, unknown>;
47
+ /**
48
+ * Extracts the validated output type for route query params.
49
+ */
50
+ export type RouteQueryOutput<P extends string> = P extends keyof AnalogRouteTable ? AnalogRouteTable[P] extends {
51
+ queryOutput: infer O;
52
+ } ? O : Record<string, string | string[] | undefined> : Record<string, string | string[] | undefined>;
53
+ type RequiredRouteParamKeys<Params> = Params extends Record<string, never> ? never : {
54
+ [K in keyof Params]-?: Record<string, never> extends Pick<Params, K> ? never : K;
55
+ }[keyof Params];
56
+ type HasRequiredRouteParams<Params> = [RequiredRouteParamKeys<Params>] extends [
57
+ never
58
+ ] ? false : true;
59
+ /**
60
+ * Typed options that infer params from the route table when available.
61
+ */
62
+ export type RoutePathOptions<P extends string = string> = P extends keyof AnalogRouteTable ? AnalogRouteTable[P] extends {
63
+ params: infer Params;
64
+ } ? Params extends Record<string, never> ? {
65
+ query?: RouteQueryOutput<P>;
66
+ hash?: string;
67
+ } : HasRequiredRouteParams<Params> extends true ? {
68
+ params: Params;
69
+ query?: RouteQueryOutput<P>;
70
+ hash?: string;
71
+ } : {
72
+ params?: Params;
73
+ query?: RouteQueryOutput<P>;
74
+ hash?: string;
75
+ } : RoutePathOptionsBase : RoutePathOptionsBase;
76
+ /**
77
+ * Conditional args: require options when the route has params.
78
+ */
79
+ export type RoutePathArgs<P extends string = string> = P extends keyof AnalogRouteTable ? AnalogRouteTable[P] extends {
80
+ params: infer Params;
81
+ } ? Params extends Record<string, never> ? [options?: RoutePathOptions<P>] : HasRequiredRouteParams<Params> extends true ? [options: RoutePathOptions<P>] : [options?: RoutePathOptions<P>] : [options?: RoutePathOptionsBase] : [options?: RoutePathOptionsBase];
82
+ /**
83
+ * Result of `routePath()` — contains properties that map directly
84
+ * to Angular's `[routerLink]`, `[queryParams]`, and `[fragment]` inputs.
85
+ */
86
+ export interface RouteLinkResult {
87
+ path: string;
88
+ queryParams: Record<string, string | string[]> | null;
89
+ fragment: string | undefined;
90
+ }
91
+ /**
92
+ * Builds a typed route link object from a route path pattern and options.
93
+ *
94
+ * The returned object separates path, query params, and fragment for
95
+ * direct use with Angular's routerLink directive inputs.
96
+ *
97
+ * @example
98
+ * routePath('/about')
99
+ * // → { path: '/about', queryParams: null, fragment: undefined }
100
+ *
101
+ * routePath('/users/[id]', { params: { id: '42' } })
102
+ * // → { path: '/users/42', queryParams: null, fragment: undefined }
103
+ *
104
+ * routePath('/users/[id]', { params: { id: '42' }, query: { tab: 'settings' }, hash: 'bio' })
105
+ * // → { path: '/users/42', queryParams: { tab: 'settings' }, fragment: 'bio' }
106
+ *
107
+ * @example Template usage
108
+ * ```html
109
+ * @let link = routePath('/users/[id]', { params: { id: userId } });
110
+ * <a [routerLink]="link.path" [queryParams]="link.queryParams" [fragment]="link.fragment">
111
+ * ```
112
+ */
113
+ export declare function routePath<P extends AnalogRoutePath>(path: P, ...args: RoutePathArgs<P>): RouteLinkResult;
114
+ /**
115
+ * Internal: builds a `RouteLinkResult` from path and options.
116
+ * Exported for direct use in tests (avoids generic constraints).
117
+ */
118
+ export declare function buildRouteLink(path: string, options?: RoutePathOptionsBase): RouteLinkResult;
119
+ /**
120
+ * Internal URL builder. Separated from `routePath` so it can be
121
+ * used without generic constraints (e.g., in `injectNavigate`).
122
+ */
123
+ export declare function buildUrl(path: string, options?: RoutePathOptionsBase): string;
124
+ export {};
@@ -8,4 +8,5 @@ export type PageServerLoad = {
8
8
  fetch: $Fetch;
9
9
  event: H3Event;
10
10
  };
11
- export type LoadResult<A extends (pageServerLoad: PageServerLoad) => Promise<any>> = Awaited<ReturnType<A>>;
11
+ export type LoadResult<A extends (pageServerLoad: PageServerLoad) => Promise<unknown>> = Awaited<ReturnType<A>>;
12
+ export type LoadDataResult<A extends (pageServerLoad: PageServerLoad) => Promise<unknown>> = Exclude<LoadResult<A>, Response>;
@@ -1,14 +1,5 @@
1
1
  import type { Route } from '@angular/router';
2
- import type { RouteExport } from './models';
3
- /**
4
- * This variable reference is replaced with a glob of all page routes.
5
- */
6
- export declare const ANALOG_ROUTE_FILES: {};
7
- /**
8
- * This variable reference is replaced with a glob of all content routes.
9
- */
10
- export declare const ANALOG_CONTENT_ROUTE_FILES: {};
11
- export type Files = Record<string, () => Promise<RouteExport | string>>;
2
+ import { type Files } from './route-files';
12
3
  /**
13
4
  * A function used to parse list of files and create configuration of routes.
14
5
  *
@@ -16,4 +7,5 @@ export type Files = Record<string, () => Promise<RouteExport | string>>;
16
7
  * @returns Array of routes
17
8
  */
18
9
  export declare function createRoutes(files: Files, debug?: boolean): Route[];
10
+ export { ANALOG_ROUTE_FILES } from './route-files';
19
11
  export declare const routes: Route[];
@@ -0,0 +1,23 @@
1
+ import { InjectionToken, type Injector } from '@angular/core';
2
+ import type { ServerFn } from './types';
3
+ /**
4
+ * In-process transport for a server function call.
5
+ *
6
+ * Provided on the server by `provideServerContext`, so during SSR a server
7
+ * function runs in the same process — and the same request injector — as the
8
+ * render instead of making an HTTP request back into the app. Absent in the
9
+ * browser, where `ServerFnClient` falls back to `HttpClient`.
10
+ *
11
+ * `injector` is the **app environment injector** — `ServerFnClient` is
12
+ * `providedIn: 'root'`, and SSR bootstraps a fresh application per request, so
13
+ * its injector is both per-request and the right scope for a handler to resolve
14
+ * from. It is passed rather than captured from the token because
15
+ * `provideServerContext` is applied as *platform* providers, which sit above
16
+ * the app's `providedIn: 'root'` services.
17
+ *
18
+ * Deliberately not a component's node injector: a handler resolves app-level
19
+ * services, and making that depend on which component happened to call it would
20
+ * be surprising and unportable.
21
+ */
22
+ export type ServerFnDispatcher = <In, Out>(fn: ServerFn<In, Out>, input: In, injector: Injector) => Promise<Out>;
23
+ export declare const SERVER_FN_DISPATCHER: InjectionToken<ServerFnDispatcher>;
@@ -0,0 +1,44 @@
1
+ import { type ResourceRef, type StateKey } from '@angular/core';
2
+ import type { ServerFn } from './types';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Client transport for server functions. In the browser it goes through Angular
6
+ * `HttpClient`, so client `HttpInterceptorFn`s apply. During SSR the dispatcher
7
+ * token is provided, and the call short-circuits the HTTP round-trip: the
8
+ * handler runs in-process in the current request injector. Lives in the client
9
+ * entry (client-safe).
10
+ */
11
+ export declare class ServerFnClient {
12
+ private readonly http;
13
+ private readonly transferState;
14
+ private readonly injector;
15
+ private readonly dispatcher;
16
+ /** True while rendering on the server (the in-process dispatcher is provided). */
17
+ get isServer(): boolean;
18
+ call<In, Out>(fn: ServerFn<In, Out>, input: In): Promise<Out>;
19
+ /** Key a read's value for TransferState hydration (fn id + input). */
20
+ stateKey<Out>(fn: ServerFn<unknown, Out>, input: unknown): StateKey<Out>;
21
+ readSeed<Out>(fn: ServerFn<unknown, Out>, input: unknown): Out | undefined;
22
+ writeSeed<Out>(fn: ServerFn<unknown, Out>, input: unknown, value: Out): void;
23
+ static ɵfac: i0.ɵɵFactoryDeclaration<ServerFnClient, never>;
24
+ static ɵprov: i0.ɵɵInjectableDeclaration<ServerFnClient>;
25
+ }
26
+ /** No-op provider hook; ServerFnClient is `providedIn: 'root'`. */
27
+ export declare function provideServerFnClient(): readonly [];
28
+ /**
29
+ * Reactive read of a server function as an Angular `resource()`.
30
+ *
31
+ * `args` is optional: omit it for an input-less read (the resource loads once);
32
+ * provide it for an input-bearing read (returning `undefined` from `args` leaves
33
+ * the resource idle until inputs are ready, the standard resource pattern). For
34
+ * imperative calls (mutations, event handlers) use `injectServerFnMutation`.
35
+ */
36
+ export declare function injectServerFn<Out>(fn: ServerFn<void, Out>): ResourceRef<Out | undefined>;
37
+ export declare function injectServerFn<In, Out>(fn: ServerFn<In, Out>, args: () => In | undefined): ResourceRef<Out | undefined>;
38
+ /**
39
+ * Imperative binding of a server function: returns a callable that dispatches
40
+ * the call through `HttpClient` (so client interceptors apply) and resolves the
41
+ * result. Use for mutations and event-driven calls; use `injectServerFn` for
42
+ * reactive reads.
43
+ */
44
+ export declare function injectServerFnMutation<In, Out>(fn: ServerFn<In, Out>): (input: In) => Promise<Out>;
@@ -0,0 +1,24 @@
1
+ import type { ServerFn, ServerFnMethod } from './types';
2
+ export interface ServerFnRefConfig {
3
+ id?: string;
4
+ method?: ServerFnMethod;
5
+ /**
6
+ * Only its presence matters here: when `method` is omitted, a config with an
7
+ * `input` schema defaults to `POST`, otherwise `GET`. The schema itself is
8
+ * never used to build the ref — validation happens server-side.
9
+ */
10
+ input?: unknown;
11
+ }
12
+ /**
13
+ * Builds a server-function reference: the client-safe `{ __serverFn, id, url,
14
+ * method }` metadata that `injectServerFn`/`ServerFnClient` dispatch through.
15
+ *
16
+ * Shared by both sides so they produce identical refs: the server `serverFn`
17
+ * wraps this with registration + the handler, and the client build's scrub
18
+ * transform emits a call to this factory in place of the server module so the
19
+ * browser bundle carries only the ref, never the handler or its server imports.
20
+ *
21
+ * The returned value is callable-typed but throws if invoked directly — it is
22
+ * always dispatched via `injectServerFn`/`ServerFnClient`, never called.
23
+ */
24
+ export declare function createServerFnRef<In, Out>(config: ServerFnRefConfig): ServerFn<In, Out>;
@@ -0,0 +1,55 @@
1
+ /** Minimal Standard Schema shape (valibot/zod/arktype conform). */
2
+ export interface StandardSchemaV1<In = unknown> {
3
+ readonly '~standard': {
4
+ readonly version: 1;
5
+ readonly vendor: string;
6
+ validate: (value: unknown) => {
7
+ value: In;
8
+ issues?: undefined;
9
+ } | {
10
+ issues: ReadonlyArray<{
11
+ message: string;
12
+ }>;
13
+ } | Promise<{
14
+ value: In;
15
+ issues?: undefined;
16
+ } | {
17
+ issues: ReadonlyArray<{
18
+ message: string;
19
+ }>;
20
+ }>;
21
+ };
22
+ }
23
+ export type ServerFnMethod = 'GET' | 'POST';
24
+ export interface ServerFnConfig<In> {
25
+ /**
26
+ * Opaque route id `/_analog/fn/<id>`. **Build-injected, not author-supplied:**
27
+ * the Analog transform derives `hash(fileId + exportName)` and stamps it into
28
+ * both the server registration and the client proxy, so authors never choose a
29
+ * route. Absent at runtime means the transform did not run — `serverFn` throws.
30
+ */
31
+ id?: string;
32
+ /** Defaults to 'POST' when `input` is present, otherwise 'GET'. */
33
+ method?: ServerFnMethod;
34
+ input?: StandardSchemaV1<In>;
35
+ }
36
+ /**
37
+ * Interceptor-accumulated context, delivered to the handler as its second
38
+ * argument. Apps extend this by declaration merging.
39
+ */
40
+ export interface ServerFnContext {
41
+ }
42
+ /** A server function reference: callable type on both sides; real impl only on the server. */
43
+ export type ServerFn<In, Out> = ((input: In) => Promise<Out>) & {
44
+ readonly __serverFn: true;
45
+ readonly id: string;
46
+ readonly url: string;
47
+ readonly method: ServerFnMethod;
48
+ };
49
+ export type ServerFnHandler<In, Out> = (input: In, context: ServerFnContext) => Promise<Out> | Out;
50
+ export interface ServerFnDef {
51
+ id: string;
52
+ method: ServerFnMethod;
53
+ config: ServerFnConfig<unknown>;
54
+ handler: ServerFnHandler<unknown, unknown>;
55
+ }
@@ -0,0 +1,7 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ export type ValidationFieldErrors = Record<string, string[]>;
3
+ export declare function issuePathToFieldName(path: ReadonlyArray<string | number | symbol | {
4
+ key: string | number | symbol;
5
+ }>): string;
6
+ export declare function issuesToFieldErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>): ValidationFieldErrors;
7
+ export declare function issuesToFormErrors(issues: ReadonlyArray<StandardSchemaV1.Issue>): string[];