@analogjs/router 3.0.0-alpha.2 → 3.0.0-alpha.21
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/content/package.json +4 -0
- package/fesm2022/analogjs-router-content.mjs +63 -0
- package/fesm2022/analogjs-router-content.mjs.map +1 -0
- package/fesm2022/analogjs-router-server-actions.mjs +327 -31
- package/fesm2022/analogjs-router-server-actions.mjs.map +1 -1
- package/fesm2022/analogjs-router-server.mjs +151 -199
- package/fesm2022/analogjs-router-server.mjs.map +1 -1
- package/fesm2022/analogjs-router-tanstack-query-server.mjs +22 -0
- package/fesm2022/analogjs-router-tanstack-query-server.mjs.map +1 -0
- package/fesm2022/analogjs-router-tanstack-query.mjs +39 -0
- package/fesm2022/analogjs-router-tanstack-query.mjs.map +1 -0
- package/fesm2022/analogjs-router-tokens.mjs +15 -18
- package/fesm2022/analogjs-router-tokens.mjs.map +1 -1
- package/fesm2022/analogjs-router.mjs +960 -815
- package/fesm2022/analogjs-router.mjs.map +1 -1
- package/fesm2022/debug.page.mjs +135 -0
- package/fesm2022/debug.page.mjs.map +1 -0
- package/fesm2022/provide-analog-query.mjs +23 -0
- package/fesm2022/provide-analog-query.mjs.map +1 -0
- package/fesm2022/route-files.mjs +345 -0
- package/fesm2022/route-files.mjs.map +1 -0
- package/fesm2022/routes.mjs +28 -0
- package/fesm2022/routes.mjs.map +1 -0
- package/package.json +67 -27
- package/server/actions/package.json +4 -0
- package/server/package.json +4 -0
- package/tanstack-query/package.json +4 -0
- package/tanstack-query/server/package.json +4 -0
- package/tokens/package.json +4 -0
- package/types/content/src/index.d.ts +4 -0
- package/types/content/src/lib/debug/routes.d.ts +10 -0
- package/types/content/src/lib/markdown-helpers.d.ts +2 -0
- package/types/content/src/lib/routes.d.ts +8 -0
- package/types/content/src/lib/with-content-routes.d.ts +2 -0
- package/types/server/actions/src/actions.d.ts +13 -0
- package/types/server/actions/src/define-action.d.ts +54 -0
- package/types/server/actions/src/define-api-route.d.ts +57 -0
- package/types/server/actions/src/define-page-load.d.ts +55 -0
- package/types/server/actions/src/define-server-route.d.ts +68 -0
- package/types/server/actions/src/index.d.ts +9 -0
- package/types/server/actions/src/parse-request-data.d.ts +9 -0
- package/types/server/actions/src/validate.d.ts +8 -0
- package/types/server/src/index.d.ts +4 -0
- package/types/server/src/provide-server-context.d.ts +11 -0
- package/types/server/src/render.d.ts +12 -0
- package/types/server/src/server-component-render.d.ts +4 -0
- package/types/server/src/tokens.d.ts +7 -0
- package/types/src/index.d.ts +27 -0
- package/types/src/lib/cache-key.d.ts +3 -0
- package/types/src/lib/constants.d.ts +2 -0
- package/types/src/lib/cookie-interceptor.d.ts +4 -0
- package/types/src/lib/debug/debug.page.d.ts +20 -0
- package/types/src/lib/debug/index.d.ts +10 -0
- package/types/src/lib/debug/routes.d.ts +10 -0
- package/types/src/lib/define-route.d.ts +51 -0
- package/types/src/lib/endpoints.d.ts +5 -0
- package/types/src/lib/experimental.d.ts +140 -0
- package/types/src/lib/form-action.directive.d.ts +25 -0
- package/types/src/lib/get-load-resolver.d.ts +8 -0
- package/types/src/lib/inject-load.d.ts +9 -0
- package/types/src/lib/inject-navigate.d.ts +23 -0
- package/types/src/lib/inject-route-context.d.ts +32 -0
- package/types/src/lib/inject-route-endpoint-url.d.ts +2 -0
- package/types/src/lib/inject-typed-params.d.ts +63 -0
- package/types/src/lib/json-ld.d.ts +31 -0
- package/types/src/lib/meta-tags.d.ts +33 -0
- package/types/src/lib/models.d.ts +32 -0
- package/types/src/lib/provide-file-router-base.d.ts +4 -0
- package/types/src/lib/provide-file-router.d.ts +12 -0
- package/types/src/lib/request-context.d.ts +13 -0
- package/types/src/lib/route-builder.d.ts +5 -0
- package/types/src/lib/route-config.d.ts +2 -0
- package/types/src/lib/route-files.d.ts +18 -0
- package/types/src/lib/route-path.d.ts +124 -0
- package/types/src/lib/route-types.d.ts +12 -0
- package/types/src/lib/routes.d.ts +11 -0
- package/types/src/lib/server.component.d.ts +33 -0
- package/types/src/lib/validation-errors.d.ts +7 -0
- package/types/tanstack-query/server/src/index.d.ts +1 -0
- package/types/tanstack-query/src/index.d.ts +2 -0
- package/types/tanstack-query/src/provide-analog-query.d.ts +4 -0
- package/types/tanstack-query/src/provide-server-analog-query.d.ts +2 -0
- package/types/tanstack-query/src/server-query.d.ts +16 -0
- package/types/tokens/src/index.d.ts +23 -0
- package/fesm2022/analogjs-router-debug.page-jzggTA45.mjs +0 -91
- package/fesm2022/analogjs-router-debug.page-jzggTA45.mjs.map +0 -1
- package/types/analogjs-router-server-actions.d.ts +0 -17
- package/types/analogjs-router-server.d.ts +0 -29
- package/types/analogjs-router-tokens.d.ts +0 -27
- package/types/analogjs-router.d.ts +0 -269
|
@@ -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,31 @@
|
|
|
1
|
+
import type { Graph, Thing, WithContext } from 'schema-dts';
|
|
2
|
+
export type JsonLdObject = Record<string, unknown>;
|
|
3
|
+
export declare function isJsonLdObject(value: unknown): value is JsonLdObject;
|
|
4
|
+
export declare function normalizeJsonLd(value: unknown): JsonLdObject[];
|
|
5
|
+
export type JsonLd = JsonLdObject | JsonLdObject[];
|
|
6
|
+
/**
|
|
7
|
+
* Typed JSON-LD document based on `schema-dts`.
|
|
8
|
+
*
|
|
9
|
+
* Accepts single Schema.org nodes (`WithContext<Thing>`),
|
|
10
|
+
* `@graph`-based documents (`Graph`), or arrays of nodes.
|
|
11
|
+
*
|
|
12
|
+
* This is the canonical JSON-LD type for route authoring surfaces
|
|
13
|
+
* (`routeMeta.jsonLd`, `routeJsonLd`, generated manifest).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import type { WebPage, WithContext } from 'schema-dts';
|
|
18
|
+
*
|
|
19
|
+
* export const routeMeta = {
|
|
20
|
+
* jsonLd: {
|
|
21
|
+
* '@context': 'https://schema.org',
|
|
22
|
+
* '@type': 'WebPage',
|
|
23
|
+
* name: 'Products',
|
|
24
|
+
* } satisfies WithContext<WebPage>,
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export type AnalogJsonLdDocument = WithContext<Thing> | Graph | Array<WithContext<Thing>>;
|
|
29
|
+
export declare const ROUTE_JSON_LD_KEY: unique symbol;
|
|
30
|
+
export declare function updateJsonLdOnRouteChange(): void;
|
|
31
|
+
export declare function serializeJsonLd(entry: JsonLdObject): string | null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const ROUTE_META_TAGS_KEY: unique symbol;
|
|
2
|
+
declare const CHARSET_KEY = "charset";
|
|
3
|
+
declare const HTTP_EQUIV_KEY = "httpEquiv";
|
|
4
|
+
declare const NAME_KEY = "name";
|
|
5
|
+
declare const PROPERTY_KEY = "property";
|
|
6
|
+
declare const CONTENT_KEY = "content";
|
|
7
|
+
declare const ITEMPROP_KEY = "itemprop";
|
|
8
|
+
export type MetaTag = (CharsetMetaTag & ExcludeRestMetaTagKeys<typeof CHARSET_KEY>) | (HttpEquivMetaTag & ExcludeRestMetaTagKeys<typeof HTTP_EQUIV_KEY>) | (NameMetaTag & ExcludeRestMetaTagKeys<typeof NAME_KEY>) | (PropertyMetaTag & ExcludeRestMetaTagKeys<typeof PROPERTY_KEY>) | (ItempropMetaTag & ExcludeRestMetaTagKeys<typeof ITEMPROP_KEY>);
|
|
9
|
+
type CharsetMetaTag = {
|
|
10
|
+
[CHARSET_KEY]: string;
|
|
11
|
+
};
|
|
12
|
+
type HttpEquivMetaTag = {
|
|
13
|
+
[HTTP_EQUIV_KEY]: string;
|
|
14
|
+
[CONTENT_KEY]: string;
|
|
15
|
+
};
|
|
16
|
+
type NameMetaTag = {
|
|
17
|
+
[NAME_KEY]: string;
|
|
18
|
+
[CONTENT_KEY]: string;
|
|
19
|
+
};
|
|
20
|
+
type PropertyMetaTag = {
|
|
21
|
+
[PROPERTY_KEY]: string;
|
|
22
|
+
[CONTENT_KEY]: string;
|
|
23
|
+
};
|
|
24
|
+
type ItempropMetaTag = {
|
|
25
|
+
[ITEMPROP_KEY]: string;
|
|
26
|
+
[CONTENT_KEY]: string;
|
|
27
|
+
};
|
|
28
|
+
type MetaTagKey = typeof CHARSET_KEY | typeof HTTP_EQUIV_KEY | typeof NAME_KEY | typeof PROPERTY_KEY | typeof ITEMPROP_KEY;
|
|
29
|
+
type ExcludeRestMetaTagKeys<Key extends MetaTagKey> = {
|
|
30
|
+
[K in Exclude<MetaTagKey, Key>]?: never;
|
|
31
|
+
};
|
|
32
|
+
export declare function updateMetaTagsOnRouteChange(): void;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Type } from '@angular/core';
|
|
2
|
+
import { CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanMatchFn, DeprecatedGuard, ResolveFn, Route } from '@angular/router';
|
|
3
|
+
import { defineRouteMeta } from './define-route';
|
|
4
|
+
import { AnalogJsonLdDocument } from './json-ld';
|
|
5
|
+
import { MetaTag } from './meta-tags';
|
|
6
|
+
type OmittedRouteProps = 'path' | 'matcher' | 'component' | 'loadComponent' | 'children' | 'loadChildren' | 'canLoad' | 'outlet';
|
|
7
|
+
export type RouteConfig = Omit<Route, OmittedRouteProps>;
|
|
8
|
+
export interface DefaultRouteMeta extends Omit<Route, OmittedRouteProps | keyof RedirectRouteMeta> {
|
|
9
|
+
canActivate?: CanActivateFn[] | DeprecatedGuard[];
|
|
10
|
+
canActivateChild?: CanActivateChildFn[];
|
|
11
|
+
canDeactivate?: CanDeactivateFn<unknown>[];
|
|
12
|
+
canMatch?: CanMatchFn[];
|
|
13
|
+
resolve?: {
|
|
14
|
+
[key: string | symbol]: ResolveFn<unknown>;
|
|
15
|
+
};
|
|
16
|
+
title?: string | ResolveFn<string>;
|
|
17
|
+
meta?: MetaTag[] | ResolveFn<MetaTag[]>;
|
|
18
|
+
jsonLd?: AnalogJsonLdDocument | ResolveFn<AnalogJsonLdDocument | undefined>;
|
|
19
|
+
}
|
|
20
|
+
export interface RedirectRouteMeta {
|
|
21
|
+
redirectTo: string;
|
|
22
|
+
pathMatch?: Route['pathMatch'];
|
|
23
|
+
}
|
|
24
|
+
export type RouteMeta = (DefaultRouteMeta & {
|
|
25
|
+
redirectTo?: never;
|
|
26
|
+
}) | RedirectRouteMeta;
|
|
27
|
+
export type RouteExport = {
|
|
28
|
+
default: Type<unknown>;
|
|
29
|
+
routeMeta?: RouteMeta | ReturnType<typeof defineRouteMeta>;
|
|
30
|
+
routeJsonLd?: AnalogJsonLdDocument | ResolveFn<AnalogJsonLdDocument | undefined>;
|
|
31
|
+
};
|
|
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;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { RouterFeatures } from '@angular/router';
|
|
3
|
+
/**
|
|
4
|
+
* Sets up providers for the Angular router, and registers
|
|
5
|
+
* file-based routes. Additional features can be provided
|
|
6
|
+
* to further configure the behavior of the router.
|
|
7
|
+
*
|
|
8
|
+
* @param features
|
|
9
|
+
* @returns Providers and features to configure the router with routes
|
|
10
|
+
*/
|
|
11
|
+
export declare function provideFileRouter(...features: RouterFeatures[]): EnvironmentProviders;
|
|
12
|
+
export { withExtraRoutes } from './provide-file-router-base';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
/**
|
|
4
|
+
* Interceptor that is server-aware when making HttpClient requests.
|
|
5
|
+
* Server-side requests use the full URL
|
|
6
|
+
* Prerendering uses the internal Nitro $fetch function, along with state transfer
|
|
7
|
+
* Client-side requests use the window.location.origin
|
|
8
|
+
*
|
|
9
|
+
* @param req HttpRequest<unknown>
|
|
10
|
+
* @param next HttpHandlerFn
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export declare function requestContextInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>;
|
|
@@ -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 {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { H3Event, H3EventContext } from 'nitro/h3';
|
|
2
|
+
import type { $Fetch } from 'nitro/types';
|
|
3
|
+
export type NodeContext = NonNullable<H3Event['node']>;
|
|
4
|
+
export type PageServerLoad = {
|
|
5
|
+
params: H3EventContext['params'];
|
|
6
|
+
req: NodeContext['req'];
|
|
7
|
+
res: NonNullable<NodeContext['res']>;
|
|
8
|
+
fetch: $Fetch;
|
|
9
|
+
event: H3Event;
|
|
10
|
+
};
|
|
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>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Route } from '@angular/router';
|
|
2
|
+
import { type Files } from './route-files';
|
|
3
|
+
/**
|
|
4
|
+
* A function used to parse list of files and create configuration of routes.
|
|
5
|
+
*
|
|
6
|
+
* @param files
|
|
7
|
+
* @returns Array of routes
|
|
8
|
+
*/
|
|
9
|
+
export declare function createRoutes(files: Files, debug?: boolean): Route[];
|
|
10
|
+
export { ANALOG_ROUTE_FILES } from './route-files';
|
|
11
|
+
export declare const routes: Route[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InputSignal, OutputEmitterRef, WritableSignal } from '@angular/core';
|
|
2
|
+
import { SafeHtml } from '@angular/platform-browser';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
type ServerProps = Record<string, any>;
|
|
5
|
+
type ServerOutputs = Record<string, any>;
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* Component that defines the bridge between the client and server-only
|
|
9
|
+
* components. The component passes the component ID and props to the server
|
|
10
|
+
* and retrieves the rendered HTML and outputs from the server-only component.
|
|
11
|
+
*
|
|
12
|
+
* Status: experimental
|
|
13
|
+
*/
|
|
14
|
+
export declare class ServerOnly {
|
|
15
|
+
component: InputSignal<string>;
|
|
16
|
+
props: InputSignal<ServerProps | undefined>;
|
|
17
|
+
outputs: OutputEmitterRef<ServerOutputs>;
|
|
18
|
+
private http;
|
|
19
|
+
private sanitizer;
|
|
20
|
+
protected content: WritableSignal<SafeHtml>;
|
|
21
|
+
private route;
|
|
22
|
+
private baseURL;
|
|
23
|
+
private transferState;
|
|
24
|
+
constructor();
|
|
25
|
+
updateContent(content: {
|
|
26
|
+
html: string;
|
|
27
|
+
outputs: ServerOutputs;
|
|
28
|
+
}): void;
|
|
29
|
+
getComponentUrl(componentId: string): string;
|
|
30
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ServerOnly, never>;
|
|
31
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ServerOnly, "server-only,ServerOnly,Server", never, { "component": { "alias": "component"; "required": true; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, { "outputs": "outputs"; }, never, never, true, never>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -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[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { provideServerAnalogQuery } from '../../src/provide-server-analog-query';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EnvironmentProviders, StateKey } from '@angular/core';
|
|
2
|
+
import type { DehydratedState } from '@tanstack/angular-query-experimental';
|
|
3
|
+
export declare const ANALOG_QUERY_STATE_KEY: StateKey<DehydratedState>;
|
|
4
|
+
export declare function provideAnalogQuery(): EnvironmentProviders;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HttpClient } from '@angular/common/http';
|
|
2
|
+
import type { CreateQueryOptions, CreateMutationOptions, CreateInfiniteQueryOptions, DefaultError, InfiniteData, QueryKey } from '@tanstack/angular-query-experimental';
|
|
3
|
+
import type { ServerRouteHandler, InferRouteQuery, InferRouteBody, InferRouteResult } from '@analogjs/router/server/actions';
|
|
4
|
+
export declare function serverQueryOptions<TRoute extends ServerRouteHandler<any, any, any>, TError = DefaultError, TData = InferRouteResult<TRoute>, TQueryKey extends QueryKey = QueryKey>(http: HttpClient, url: string, options: {
|
|
5
|
+
queryKey: TQueryKey;
|
|
6
|
+
query?: InferRouteQuery<TRoute>;
|
|
7
|
+
} & Omit<CreateQueryOptions<InferRouteResult<TRoute>, TError, TData, TQueryKey>, 'queryKey' | 'queryFn'>): CreateQueryOptions<InferRouteResult<TRoute>, TError, TData, TQueryKey>;
|
|
8
|
+
export declare function serverMutationOptions<TRoute extends ServerRouteHandler<any, any, any>, TError = DefaultError, TOnMutateResult = unknown>(http: HttpClient, url: string, options?: Omit<CreateMutationOptions<InferRouteResult<TRoute>, TError, InferRouteBody<TRoute>, TOnMutateResult>, 'mutationFn'>): CreateMutationOptions<InferRouteResult<TRoute>, TError, InferRouteBody<TRoute>, TOnMutateResult>;
|
|
9
|
+
export declare function serverInfiniteQueryOptions<TRoute extends ServerRouteHandler<any, any, any>, TError = DefaultError, TData = InfiniteData<InferRouteResult<TRoute>>, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(http: HttpClient, url: string, options: {
|
|
10
|
+
queryKey: TQueryKey;
|
|
11
|
+
query: (context: {
|
|
12
|
+
pageParam: TPageParam;
|
|
13
|
+
}) => InferRouteQuery<TRoute>;
|
|
14
|
+
initialPageParam: TPageParam;
|
|
15
|
+
getNextPageParam: (lastPage: InferRouteResult<TRoute>, allPages: InferRouteResult<TRoute>[]) => TPageParam | undefined | null;
|
|
16
|
+
} & Omit<CreateInfiniteQueryOptions<InferRouteResult<TRoute>, TError, TData, TQueryKey, TPageParam>, 'queryKey' | 'queryFn' | 'initialPageParam' | 'getNextPageParam'>): CreateInfiniteQueryOptions<InferRouteResult<TRoute>, TError, TData, TQueryKey, TPageParam>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import type { $Fetch } from 'nitro/types';
|
|
3
|
+
import type { IncomingMessage, ServerResponse as NodeServerResponse } from 'node:http';
|
|
4
|
+
export type ServerRequest = IncomingMessage & {
|
|
5
|
+
originalUrl: string;
|
|
6
|
+
};
|
|
7
|
+
export type ServerResponse = NodeServerResponse;
|
|
8
|
+
export type ServerInternalFetch = $Fetch;
|
|
9
|
+
export type ServerContext = {
|
|
10
|
+
req: ServerRequest;
|
|
11
|
+
res: ServerResponse;
|
|
12
|
+
fetch?: ServerInternalFetch;
|
|
13
|
+
};
|
|
14
|
+
export declare const REQUEST: InjectionToken<ServerRequest>;
|
|
15
|
+
export declare const RESPONSE: InjectionToken<ServerResponse>;
|
|
16
|
+
export declare const BASE_URL: InjectionToken<string>;
|
|
17
|
+
export declare const INTERNAL_FETCH: InjectionToken<ServerInternalFetch>;
|
|
18
|
+
export declare const API_PREFIX: InjectionToken<string>;
|
|
19
|
+
export declare function injectRequest(): ServerRequest | null;
|
|
20
|
+
export declare function injectResponse(): ServerResponse | null;
|
|
21
|
+
export declare function injectBaseURL(): string | null;
|
|
22
|
+
export declare function injectInternalServerFetch(): ServerInternalFetch | null;
|
|
23
|
+
export declare function injectAPIPrefix(): string;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
3
|
-
import { injectDebugRoutes } from './analogjs-router.mjs';
|
|
4
|
-
|
|
5
|
-
class DebugRoutesComponent {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.collectedRoutes = [];
|
|
8
|
-
this.debugRoutes = injectDebugRoutes();
|
|
9
|
-
}
|
|
10
|
-
ngOnInit() {
|
|
11
|
-
this.traverseRoutes(this.debugRoutes);
|
|
12
|
-
}
|
|
13
|
-
traverseRoutes(routes, parent) {
|
|
14
|
-
routes.forEach((route) => {
|
|
15
|
-
this.collectedRoutes.push({
|
|
16
|
-
path: route.isLayout
|
|
17
|
-
? `${parent ? `/${parent}` : ''}${route.path ? `/${route.path}` : ''}`
|
|
18
|
-
: `${parent ? `/${parent}` : ''}${route.path ? `/${route.path}` : '/'}`,
|
|
19
|
-
filename: route.filename,
|
|
20
|
-
file: route.filename?.replace(/(^.*)pages\//, '') || '',
|
|
21
|
-
isLayout: route.isLayout,
|
|
22
|
-
});
|
|
23
|
-
if (route.children) {
|
|
24
|
-
const parentSegments = [parent, route.path];
|
|
25
|
-
const fullParentPath = parentSegments.filter((s) => !!s).join('/');
|
|
26
|
-
this.traverseRoutes(route.children, fullParentPath);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DebugRoutesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
31
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DebugRoutesComponent, isStandalone: true, selector: "analogjs-debug-routes-page", ngImport: i0, template: `
|
|
32
|
-
<h2>Routes</h2>
|
|
33
|
-
|
|
34
|
-
<div class="table-container">
|
|
35
|
-
<div class="table-header">
|
|
36
|
-
<div class="header-cell">Route Path</div>
|
|
37
|
-
<div class="header-cell">File</div>
|
|
38
|
-
<div class="header-cell">Type</div>
|
|
39
|
-
</div>
|
|
40
|
-
<div class="table-body">
|
|
41
|
-
@for (
|
|
42
|
-
collectedRoute of collectedRoutes;
|
|
43
|
-
track collectedRoute.filename
|
|
44
|
-
) {
|
|
45
|
-
<div class="table-row">
|
|
46
|
-
<div class="table-cell">{{ collectedRoute.path }}</div>
|
|
47
|
-
<div class="table-cell" [title]="collectedRoute.filename">
|
|
48
|
-
{{ collectedRoute.file }}
|
|
49
|
-
</div>
|
|
50
|
-
<div class="table-cell">
|
|
51
|
-
{{ collectedRoute.isLayout ? 'Layout' : 'Page' }}
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
}
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
`, isInline: true, styles: [":host{width:100%}.table-container{width:100%;max-width:900px;margin:0 auto;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;overflow:hidden}.table-header{display:grid;grid-template-columns:repeat(3,1fr);background:gray;border-bottom:2px solid #e5e7eb}.header-cell{padding:16px 24px;font-weight:600;text-transform:uppercase;font-size:14px;letter-spacing:.05em;color:#fff}.table-body{display:flex;flex-direction:column}.table-row{display:grid;grid-template-columns:repeat(3,1fr);border-bottom:1px solid #e5e7eb;transition:background-color .2s ease}.table-row:last-child{border-bottom:none}.table-row:hover{background-color:#f9fafb}.table-cell{padding:16px 24px;font-size:16px;color:#4b5563}@media(max-width:640px){.table-container{border-radius:0;margin:0}.header-cell,.table-cell{padding:12px 16px}}\n"] }); }
|
|
58
|
-
}
|
|
59
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DebugRoutesComponent, decorators: [{
|
|
60
|
-
type: Component,
|
|
61
|
-
args: [{ selector: 'analogjs-debug-routes-page', standalone: true, template: `
|
|
62
|
-
<h2>Routes</h2>
|
|
63
|
-
|
|
64
|
-
<div class="table-container">
|
|
65
|
-
<div class="table-header">
|
|
66
|
-
<div class="header-cell">Route Path</div>
|
|
67
|
-
<div class="header-cell">File</div>
|
|
68
|
-
<div class="header-cell">Type</div>
|
|
69
|
-
</div>
|
|
70
|
-
<div class="table-body">
|
|
71
|
-
@for (
|
|
72
|
-
collectedRoute of collectedRoutes;
|
|
73
|
-
track collectedRoute.filename
|
|
74
|
-
) {
|
|
75
|
-
<div class="table-row">
|
|
76
|
-
<div class="table-cell">{{ collectedRoute.path }}</div>
|
|
77
|
-
<div class="table-cell" [title]="collectedRoute.filename">
|
|
78
|
-
{{ collectedRoute.file }}
|
|
79
|
-
</div>
|
|
80
|
-
<div class="table-cell">
|
|
81
|
-
{{ collectedRoute.isLayout ? 'Layout' : 'Page' }}
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
}
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
`, styles: [":host{width:100%}.table-container{width:100%;max-width:900px;margin:0 auto;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;overflow:hidden}.table-header{display:grid;grid-template-columns:repeat(3,1fr);background:gray;border-bottom:2px solid #e5e7eb}.header-cell{padding:16px 24px;font-weight:600;text-transform:uppercase;font-size:14px;letter-spacing:.05em;color:#fff}.table-body{display:flex;flex-direction:column}.table-row{display:grid;grid-template-columns:repeat(3,1fr);border-bottom:1px solid #e5e7eb;transition:background-color .2s ease}.table-row:last-child{border-bottom:none}.table-row:hover{background-color:#f9fafb}.table-cell{padding:16px 24px;font-size:16px;color:#4b5563}@media(max-width:640px){.table-container{border-radius:0;margin:0}.header-cell,.table-cell{padding:12px 16px}}\n"] }]
|
|
88
|
-
}] });
|
|
89
|
-
|
|
90
|
-
export { DebugRoutesComponent as default };
|
|
91
|
-
//# sourceMappingURL=analogjs-router-debug.page-jzggTA45.mjs.map
|