@fragno-dev/core 0.2.0 → 0.2.2
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/.turbo/turbo-build.log +72 -62
- package/CHANGELOG.md +28 -0
- package/dist/api/api.d.ts +3 -2
- package/dist/api/api.d.ts.map +1 -1
- package/dist/api/api.js +2 -1
- package/dist/api/api.js.map +1 -1
- package/dist/api/bind-services.d.ts +0 -1
- package/dist/api/bind-services.d.ts.map +1 -1
- package/dist/api/bind-services.js.map +1 -1
- package/dist/api/error.d.ts.map +1 -1
- package/dist/api/error.js.map +1 -1
- package/dist/api/fragment-definition-builder.d.ts +26 -44
- package/dist/api/fragment-definition-builder.d.ts.map +1 -1
- package/dist/api/fragment-definition-builder.js +15 -22
- package/dist/api/fragment-definition-builder.js.map +1 -1
- package/dist/api/fragment-instantiator.d.ts +51 -37
- package/dist/api/fragment-instantiator.d.ts.map +1 -1
- package/dist/api/fragment-instantiator.js +74 -69
- package/dist/api/fragment-instantiator.js.map +1 -1
- package/dist/api/request-context-storage.d.ts +4 -0
- package/dist/api/request-context-storage.d.ts.map +1 -1
- package/dist/api/request-context-storage.js +6 -0
- package/dist/api/request-context-storage.js.map +1 -1
- package/dist/api/request-input-context.d.ts.map +1 -1
- package/dist/api/request-input-context.js.map +1 -1
- package/dist/api/request-middleware.d.ts +1 -1
- package/dist/api/request-middleware.d.ts.map +1 -1
- package/dist/api/request-middleware.js.map +1 -1
- package/dist/api/request-output-context.d.ts +1 -1
- package/dist/api/request-output-context.d.ts.map +1 -1
- package/dist/api/request-output-context.js.map +1 -1
- package/dist/api/route-caller.d.ts +30 -0
- package/dist/api/route-caller.d.ts.map +1 -0
- package/dist/api/route-caller.js +63 -0
- package/dist/api/route-caller.js.map +1 -0
- package/dist/api/route-handler-input-options.d.ts.map +1 -1
- package/dist/api/route.d.ts +1 -1
- package/dist/api/route.d.ts.map +1 -1
- package/dist/api/route.js.map +1 -1
- package/dist/api/shared-types.d.ts.map +1 -1
- package/dist/client/client-error.d.ts.map +1 -1
- package/dist/client/client-error.js.map +1 -1
- package/dist/client/client.d.ts +91 -52
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +25 -9
- package/dist/client/client.js.map +1 -1
- package/dist/client/client.svelte.d.ts +6 -5
- package/dist/client/client.svelte.d.ts.map +1 -1
- package/dist/client/client.svelte.js +10 -2
- package/dist/client/client.svelte.js.map +1 -1
- package/dist/client/internal/ndjson-streaming.js.map +1 -1
- package/dist/client/react.d.ts +5 -4
- package/dist/client/react.d.ts.map +1 -1
- package/dist/client/react.js +104 -12
- package/dist/client/react.js.map +1 -1
- package/dist/client/solid.d.ts +7 -5
- package/dist/client/solid.d.ts.map +1 -1
- package/dist/client/solid.js +23 -9
- package/dist/client/solid.js.map +1 -1
- package/dist/client/vanilla.d.ts +16 -4
- package/dist/client/vanilla.d.ts.map +1 -1
- package/dist/client/vanilla.js +21 -1
- package/dist/client/vanilla.js.map +1 -1
- package/dist/client/vue.d.ts +7 -5
- package/dist/client/vue.d.ts.map +1 -1
- package/dist/client/vue.js +18 -10
- package/dist/client/vue.js.map +1 -1
- package/dist/id.d.ts +2 -0
- package/dist/id.js +3 -0
- package/dist/internal/cuid.d.ts +16 -0
- package/dist/internal/cuid.d.ts.map +1 -0
- package/dist/internal/cuid.js +82 -0
- package/dist/internal/cuid.js.map +1 -0
- package/dist/mod-client.d.ts +5 -4
- package/dist/mod-client.d.ts.map +1 -1
- package/dist/mod-client.js +7 -5
- package/dist/mod-client.js.map +1 -1
- package/dist/mod.d.ts +6 -5
- package/dist/mod.js +2 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/test/test.d.ts +6 -6
- package/dist/test/test.d.ts.map +1 -1
- package/dist/test/test.js.map +1 -1
- package/dist/util/ssr.js.map +1 -1
- package/package.json +24 -40
- package/src/api/api.test.ts +3 -1
- package/src/api/api.ts +6 -0
- package/src/api/bind-services.ts +0 -5
- package/src/api/error.ts +1 -0
- package/src/api/fragment-definition-builder.extend.test.ts +2 -1
- package/src/api/fragment-definition-builder.test.ts +2 -1
- package/src/api/fragment-definition-builder.ts +49 -124
- package/src/api/fragment-instantiator.test.ts +92 -233
- package/src/api/fragment-instantiator.ts +228 -196
- package/src/api/fragment-services.test.ts +1 -0
- package/src/api/internal/path-runtime.test.ts +1 -0
- package/src/api/internal/path-type.test.ts +3 -1
- package/src/api/internal/route.test.ts +1 -0
- package/src/api/request-context-storage.ts +7 -0
- package/src/api/request-input-context.test.ts +4 -2
- package/src/api/request-input-context.ts +2 -1
- package/src/api/request-middleware.test.ts +9 -14
- package/src/api/request-middleware.ts +3 -2
- package/src/api/request-output-context.test.ts +3 -1
- package/src/api/request-output-context.ts +2 -1
- package/src/api/route-caller.test.ts +195 -0
- package/src/api/route-caller.ts +167 -0
- package/src/api/route-handler-input-options.ts +2 -1
- package/src/api/route.test.ts +4 -2
- package/src/api/route.ts +2 -1
- package/src/api/shared-types.ts +2 -1
- package/src/client/client-builder.test.ts +4 -2
- package/src/client/client-error.test.ts +2 -1
- package/src/client/client-error.ts +1 -1
- package/src/client/client-types.test.ts +19 -5
- package/src/client/client.ssr.test.ts +6 -4
- package/src/client/client.svelte.test.ts +18 -9
- package/src/client/client.svelte.ts +38 -13
- package/src/client/client.test.ts +49 -10
- package/src/client/client.ts +291 -141
- package/src/client/internal/ndjson-streaming.test.ts +6 -3
- package/src/client/internal/ndjson-streaming.ts +1 -0
- package/src/client/react.test.ts +176 -6
- package/src/client/react.ts +226 -31
- package/src/client/solid.test.ts +29 -5
- package/src/client/solid.ts +60 -22
- package/src/client/vanilla.test.ts +148 -6
- package/src/client/vanilla.ts +63 -9
- package/src/client/vue.test.ts +223 -84
- package/src/client/vue.ts +57 -30
- package/src/id.ts +1 -0
- package/src/internal/cuid.test.ts +164 -0
- package/src/internal/cuid.ts +133 -0
- package/src/mod-client.ts +4 -2
- package/src/mod.ts +3 -2
- package/src/runtime.ts +1 -1
- package/src/test/test.test.ts +4 -2
- package/src/test/test.ts +7 -9
- package/src/util/async.test.ts +1 -0
- package/src/util/content-type.test.ts +1 -0
- package/src/util/nanostores.test.ts +3 -1
- package/src/util/ssr.ts +1 -0
- package/tsconfig.json +1 -1
- package/tsdown.config.ts +1 -0
- package/vitest.config.ts +2 -1
|
@@ -1,10 +1,26 @@
|
|
|
1
|
+
import { addRoute, createRouter, findRoute } from "rou3";
|
|
2
|
+
|
|
1
3
|
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
|
|
5
|
+
import type { ExtractRouteByPath, ExtractRoutePath } from "../client/client";
|
|
6
|
+
import { instantiatedFragmentFakeSymbol } from "../internal/symbols";
|
|
7
|
+
import { recordTraceEvent } from "../internal/trace-context";
|
|
8
|
+
import type { InferOrUnknown } from "../util/types-util";
|
|
2
9
|
import { type FragnoRouteConfig, type HTTPMethod, type RequestThisContext } from "./api";
|
|
10
|
+
import { bindServicesToContext, type BoundServices } from "./bind-services";
|
|
3
11
|
import { FragnoApiError } from "./error";
|
|
12
|
+
import type { FragmentDefinition } from "./fragment-definition-builder";
|
|
13
|
+
import { type FragnoResponse, parseFragnoResponse } from "./fragno-response";
|
|
14
|
+
import type { ExtractPathParams } from "./internal/path";
|
|
4
15
|
import { getMountRoute } from "./internal/route";
|
|
5
|
-
import {
|
|
16
|
+
import { MutableRequestState } from "./mutable-request-state";
|
|
17
|
+
import { RequestContextStorage } from "./request-context-storage";
|
|
6
18
|
import { RequestInputContext, type RequestBodyType } from "./request-input-context";
|
|
7
|
-
import
|
|
19
|
+
import {
|
|
20
|
+
RequestMiddlewareInputContext,
|
|
21
|
+
RequestMiddlewareOutputContext,
|
|
22
|
+
type FragnoMiddlewareCallback,
|
|
23
|
+
} from "./request-middleware";
|
|
8
24
|
import { RequestOutputContext } from "./request-output-context";
|
|
9
25
|
import {
|
|
10
26
|
type AnyFragnoRouteConfig,
|
|
@@ -12,26 +28,42 @@ import {
|
|
|
12
28
|
type FlattenRouteFactories,
|
|
13
29
|
resolveRouteFactories,
|
|
14
30
|
} from "./route";
|
|
15
|
-
import {
|
|
16
|
-
RequestMiddlewareInputContext,
|
|
17
|
-
RequestMiddlewareOutputContext,
|
|
18
|
-
type FragnoMiddlewareCallback,
|
|
19
|
-
} from "./request-middleware";
|
|
20
|
-
import { MutableRequestState } from "./mutable-request-state";
|
|
21
31
|
import type { RouteHandlerInputOptions } from "./route-handler-input-options";
|
|
22
|
-
import type { ExtractRouteByPath, ExtractRoutePath } from "../client/client";
|
|
23
|
-
import { type FragnoResponse, parseFragnoResponse } from "./fragno-response";
|
|
24
|
-
import type { InferOrUnknown } from "../util/types-util";
|
|
25
|
-
import type { FragmentDefinition } from "./fragment-definition-builder";
|
|
26
32
|
import type { FragnoPublicConfig } from "./shared-types";
|
|
27
|
-
import { RequestContextStorage } from "./request-context-storage";
|
|
28
|
-
import { bindServicesToContext, type BoundServices } from "./bind-services";
|
|
29
|
-
import { instantiatedFragmentFakeSymbol } from "../internal/symbols";
|
|
30
|
-
import { recordTraceEvent } from "../internal/trace-context";
|
|
31
33
|
|
|
32
34
|
// Re-export types needed by consumers
|
|
33
35
|
export type { BoundServices };
|
|
34
36
|
|
|
37
|
+
type CallRoutePath<TRoutes extends readonly AnyFragnoRouteConfig[], TMethod extends HTTPMethod> = [
|
|
38
|
+
ExtractRoutePath<TRoutes, TMethod>,
|
|
39
|
+
] extends [never]
|
|
40
|
+
? string
|
|
41
|
+
: ExtractRoutePath<TRoutes, TMethod>;
|
|
42
|
+
|
|
43
|
+
type CallRouteMatch<
|
|
44
|
+
TRoutes extends readonly AnyFragnoRouteConfig[],
|
|
45
|
+
TMethod extends HTTPMethod,
|
|
46
|
+
TPath extends string,
|
|
47
|
+
> = [ExtractRouteByPath<TRoutes, TPath, TMethod>] extends [never]
|
|
48
|
+
? AnyFragnoRouteConfig
|
|
49
|
+
: ExtractRouteByPath<TRoutes, TPath, TMethod>;
|
|
50
|
+
|
|
51
|
+
const requestSourceSymbol = Symbol.for("fragno-request-source");
|
|
52
|
+
const requestRouteSymbol = Symbol.for("fragno-request-route");
|
|
53
|
+
const requestWaitUntilSymbol = Symbol.for("fragno-request-wait-until");
|
|
54
|
+
|
|
55
|
+
type RequestRouteInfo = {
|
|
56
|
+
method: HTTPMethod;
|
|
57
|
+
path: string;
|
|
58
|
+
mountRoute?: string;
|
|
59
|
+
fullPath?: string;
|
|
60
|
+
};
|
|
61
|
+
type RequestSource = "route" | "context";
|
|
62
|
+
|
|
63
|
+
export type FragnoRequestLifecycleContext = {
|
|
64
|
+
waitUntil?: (promise: Promise<unknown>) => void;
|
|
65
|
+
};
|
|
66
|
+
|
|
35
67
|
type InternalRoutePrefix = "/_internal";
|
|
36
68
|
|
|
37
69
|
type JoinInternalRoutePath<TPath extends string> = TPath extends "" | "/"
|
|
@@ -66,33 +98,27 @@ type PrefixInternalRoutes<TRoutes extends readonly AnyFragnoRouteConfig[]> =
|
|
|
66
98
|
? { [K in keyof TRoutesTuple]: PrefixInternalRoute<TRoutesTuple[K]> }
|
|
67
99
|
: readonly AnyFragnoRouteConfig[];
|
|
68
100
|
|
|
69
|
-
type
|
|
70
|
-
|
|
71
|
-
infer TRoutes,
|
|
72
|
-
infer _TDeps,
|
|
73
|
-
infer _TServices,
|
|
74
|
-
infer _TServiceThisContext,
|
|
75
|
-
infer _THandlerThisContext,
|
|
76
|
-
infer _TRequestStorage,
|
|
77
|
-
infer _TOptions,
|
|
78
|
-
infer _TLinkedFragments
|
|
79
|
-
>
|
|
80
|
-
? TRoutes
|
|
81
|
-
: never;
|
|
82
|
-
|
|
83
|
-
type InternalLinkedRoutes<TLinkedFragments> =
|
|
84
|
-
TLinkedFragments extends Record<string, AnyFragnoInstantiatedFragment>
|
|
85
|
-
? TLinkedFragments extends { _fragno_internal: infer TInternal }
|
|
86
|
-
? ExtractRoutesFromFragment<TInternal> extends readonly AnyFragnoRouteConfig[]
|
|
87
|
-
? PrefixInternalRoutes<ExtractRoutesFromFragment<TInternal>>
|
|
88
|
-
: readonly []
|
|
89
|
-
: readonly []
|
|
90
|
-
: readonly [];
|
|
101
|
+
type InternalRoutesFromDefinition<TInternalRoutes extends readonly AnyRouteOrFactory[]> =
|
|
102
|
+
PrefixInternalRoutes<FlattenRouteFactories<TInternalRoutes>>;
|
|
91
103
|
|
|
92
104
|
export type RoutesWithInternal<
|
|
93
105
|
TRoutes extends readonly AnyFragnoRouteConfig[],
|
|
94
|
-
|
|
95
|
-
> = readonly [...TRoutes, ...
|
|
106
|
+
TInternalRoutes extends readonly AnyRouteOrFactory[],
|
|
107
|
+
> = readonly [...TRoutes, ...InternalRoutesFromDefinition<TInternalRoutes>];
|
|
108
|
+
|
|
109
|
+
type ExtractServiceCallResult<T> = T extends undefined
|
|
110
|
+
? undefined
|
|
111
|
+
: T extends { _internal: { finalResult?: infer R } }
|
|
112
|
+
? R
|
|
113
|
+
: Awaited<T>;
|
|
114
|
+
|
|
115
|
+
type ExtractServiceCallResults<T extends readonly unknown[]> = {
|
|
116
|
+
[K in keyof T]: ExtractServiceCallResult<T[K]>;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
type ExtractServiceCallResultsOrSingle<T> = T extends readonly unknown[]
|
|
120
|
+
? ExtractServiceCallResults<T>
|
|
121
|
+
: ExtractServiceCallResult<T>;
|
|
96
122
|
|
|
97
123
|
/**
|
|
98
124
|
* Helper type to extract the instantiated fragment type from a fragment definition.
|
|
@@ -119,17 +145,16 @@ export type InstantiatedFragmentFromDefinition<
|
|
|
119
145
|
infer TServiceThisContext,
|
|
120
146
|
infer THandlerThisContext,
|
|
121
147
|
infer TRequestStorage,
|
|
122
|
-
infer
|
|
148
|
+
infer TInternalRoutes
|
|
123
149
|
>
|
|
124
150
|
? FragnoInstantiatedFragment<
|
|
125
|
-
RoutesWithInternal<readonly AnyFragnoRouteConfig[],
|
|
151
|
+
RoutesWithInternal<readonly AnyFragnoRouteConfig[], TInternalRoutes>,
|
|
126
152
|
TDeps,
|
|
127
153
|
BoundServices<TBaseServices & TServices>,
|
|
128
154
|
TServiceThisContext,
|
|
129
155
|
THandlerThisContext,
|
|
130
156
|
TRequestStorage,
|
|
131
|
-
TOptions
|
|
132
|
-
TLinkedFragments
|
|
157
|
+
TOptions
|
|
133
158
|
>
|
|
134
159
|
: never;
|
|
135
160
|
|
|
@@ -217,24 +242,11 @@ export type AnyFragnoInstantiatedFragment = FragnoInstantiatedFragment<
|
|
|
217
242
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
218
243
|
any,
|
|
219
244
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
220
|
-
any,
|
|
221
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
222
245
|
any
|
|
223
246
|
>;
|
|
224
247
|
|
|
225
|
-
const INTERNAL_LINKED_FRAGMENT_NAME = "_fragno_internal";
|
|
226
248
|
const INTERNAL_ROUTE_PREFIX = "/_internal";
|
|
227
249
|
|
|
228
|
-
type InternalLinkedRouteMeta = {
|
|
229
|
-
fragment: AnyFragnoInstantiatedFragment;
|
|
230
|
-
originalPath: string;
|
|
231
|
-
routes: readonly AnyFragnoRouteConfig[];
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
type InternalLinkedRouteConfig = AnyFragnoRouteConfig & {
|
|
235
|
-
__internal?: InternalLinkedRouteMeta;
|
|
236
|
-
};
|
|
237
|
-
|
|
238
250
|
function normalizeRoutePrefix(prefix: string): string {
|
|
239
251
|
if (!prefix.startsWith("/")) {
|
|
240
252
|
prefix = `/${prefix}`;
|
|
@@ -251,37 +263,6 @@ function joinRoutePath(prefix: string, path: string): string {
|
|
|
251
263
|
return `${normalizedPrefix}${normalizedPath}`;
|
|
252
264
|
}
|
|
253
265
|
|
|
254
|
-
function collectLinkedFragmentRoutes(
|
|
255
|
-
linkedFragments: Record<string, AnyFragnoInstantiatedFragment>,
|
|
256
|
-
): InternalLinkedRouteConfig[] {
|
|
257
|
-
const linkedRoutes: InternalLinkedRouteConfig[] = [];
|
|
258
|
-
|
|
259
|
-
for (const [name, fragment] of Object.entries(linkedFragments)) {
|
|
260
|
-
if (name !== INTERNAL_LINKED_FRAGMENT_NAME) {
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const internalRoutes = (fragment.routes ?? []) as readonly AnyFragnoRouteConfig[];
|
|
265
|
-
if (internalRoutes.length === 0) {
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
for (const route of internalRoutes) {
|
|
270
|
-
linkedRoutes.push({
|
|
271
|
-
...route,
|
|
272
|
-
path: joinRoutePath(INTERNAL_ROUTE_PREFIX, route.path),
|
|
273
|
-
__internal: {
|
|
274
|
-
fragment,
|
|
275
|
-
originalPath: route.path,
|
|
276
|
-
routes: internalRoutes,
|
|
277
|
-
},
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return linkedRoutes;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
266
|
export interface FragnoFragmentSharedConfig<
|
|
286
267
|
TRoutes extends readonly FragnoRouteConfig<
|
|
287
268
|
HTTPMethod,
|
|
@@ -308,9 +289,7 @@ export class FragnoInstantiatedFragment<
|
|
|
308
289
|
THandlerThisContext extends RequestThisContext,
|
|
309
290
|
TRequestStorage = {},
|
|
310
291
|
TOptions extends FragnoPublicConfig = FragnoPublicConfig,
|
|
311
|
-
|
|
312
|
-
> implements IFragnoInstantiatedFragment
|
|
313
|
-
{
|
|
292
|
+
> implements IFragnoInstantiatedFragment {
|
|
314
293
|
readonly [instantiatedFragmentFakeSymbol] = instantiatedFragmentFakeSymbol;
|
|
315
294
|
|
|
316
295
|
// Private fields
|
|
@@ -326,7 +305,6 @@ export class FragnoInstantiatedFragment<
|
|
|
326
305
|
#contextStorage: RequestContextStorage<TRequestStorage>;
|
|
327
306
|
#createRequestStorage?: () => TRequestStorage;
|
|
328
307
|
#options: TOptions;
|
|
329
|
-
#linkedFragments: TLinkedFragments;
|
|
330
308
|
#internalData: Record<string, unknown>;
|
|
331
309
|
|
|
332
310
|
constructor(params: {
|
|
@@ -340,7 +318,6 @@ export class FragnoInstantiatedFragment<
|
|
|
340
318
|
storage: RequestContextStorage<TRequestStorage>;
|
|
341
319
|
createRequestStorage?: () => TRequestStorage;
|
|
342
320
|
options: TOptions;
|
|
343
|
-
linkedFragments?: TLinkedFragments;
|
|
344
321
|
internalData?: Record<string, unknown>;
|
|
345
322
|
}) {
|
|
346
323
|
this.#name = params.name;
|
|
@@ -353,7 +330,6 @@ export class FragnoInstantiatedFragment<
|
|
|
353
330
|
this.#contextStorage = params.storage;
|
|
354
331
|
this.#createRequestStorage = params.createRequestStorage;
|
|
355
332
|
this.#options = params.options;
|
|
356
|
-
this.#linkedFragments = params.linkedFragments ?? ({} as TLinkedFragments);
|
|
357
333
|
this.#internalData = params.internalData ?? {};
|
|
358
334
|
|
|
359
335
|
// Build router
|
|
@@ -402,7 +378,6 @@ export class FragnoInstantiatedFragment<
|
|
|
402
378
|
return {
|
|
403
379
|
deps: this.#deps,
|
|
404
380
|
options: this.#options,
|
|
405
|
-
linkedFragments: this.#linkedFragments,
|
|
406
381
|
...this.#internalData,
|
|
407
382
|
};
|
|
408
383
|
}
|
|
@@ -424,9 +399,24 @@ export class FragnoInstantiatedFragment<
|
|
|
424
399
|
* This is a shared helper used by inContext(), handler(), and callRouteRaw().
|
|
425
400
|
* @private
|
|
426
401
|
*/
|
|
427
|
-
#withRequestStorage<T>(
|
|
428
|
-
|
|
429
|
-
|
|
402
|
+
#withRequestStorage<T>(
|
|
403
|
+
callback: () => T,
|
|
404
|
+
source?: RequestSource,
|
|
405
|
+
routeInfo?: RequestRouteInfo,
|
|
406
|
+
lifecycleContext?: FragnoRequestLifecycleContext,
|
|
407
|
+
): T;
|
|
408
|
+
#withRequestStorage<T>(
|
|
409
|
+
callback: () => Promise<T>,
|
|
410
|
+
source?: RequestSource,
|
|
411
|
+
routeInfo?: RequestRouteInfo,
|
|
412
|
+
lifecycleContext?: FragnoRequestLifecycleContext,
|
|
413
|
+
): Promise<T>;
|
|
414
|
+
#withRequestStorage<T>(
|
|
415
|
+
callback: () => T | Promise<T>,
|
|
416
|
+
source: RequestSource = "context",
|
|
417
|
+
routeInfo?: RequestRouteInfo,
|
|
418
|
+
lifecycleContext?: FragnoRequestLifecycleContext,
|
|
419
|
+
): T | Promise<T> {
|
|
430
420
|
if (!this.#serviceThisContext && !this.#handlerThisContext) {
|
|
431
421
|
// No request context configured - just run callback directly
|
|
432
422
|
return callback();
|
|
@@ -436,6 +426,16 @@ export class FragnoInstantiatedFragment<
|
|
|
436
426
|
const storageData = this.#createRequestStorage
|
|
437
427
|
? this.#createRequestStorage()
|
|
438
428
|
: ({} as TRequestStorage);
|
|
429
|
+
if (storageData && typeof storageData === "object") {
|
|
430
|
+
const metadataTarget = storageData as Record<symbol, unknown>;
|
|
431
|
+
metadataTarget[requestSourceSymbol] = source;
|
|
432
|
+
if (routeInfo) {
|
|
433
|
+
metadataTarget[requestRouteSymbol] = routeInfo;
|
|
434
|
+
}
|
|
435
|
+
if (lifecycleContext?.waitUntil) {
|
|
436
|
+
metadataTarget[requestWaitUntilSymbol] = lifecycleContext.waitUntil;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
439
|
return this.#contextStorage.run(storageData, callback);
|
|
440
440
|
}
|
|
441
441
|
|
|
@@ -463,9 +463,55 @@ export class FragnoInstantiatedFragment<
|
|
|
463
463
|
// Always use handler context for inContext - it has full capabilities
|
|
464
464
|
if (this.#handlerThisContext) {
|
|
465
465
|
const boundCallback = callback.bind(this.#handlerThisContext);
|
|
466
|
-
return this.#withRequestStorage(boundCallback);
|
|
466
|
+
return this.#withRequestStorage(boundCallback, "context");
|
|
467
|
+
}
|
|
468
|
+
return this.#withRequestStorage(callback, "context");
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Execute multiple service calls within a handler context.
|
|
473
|
+
* If called outside a request context, it will create one automatically.
|
|
474
|
+
* Pass a factory so service calls are created inside the active context.
|
|
475
|
+
* Primarily used by database fragments (handlerTx).
|
|
476
|
+
*/
|
|
477
|
+
async callServices<TServiceCalls>(
|
|
478
|
+
serviceCalls: () => TServiceCalls,
|
|
479
|
+
): Promise<ExtractServiceCallResultsOrSingle<TServiceCalls>> {
|
|
480
|
+
const handlerContext = this.#handlerThisContext as
|
|
481
|
+
| {
|
|
482
|
+
handlerTx?: () => {
|
|
483
|
+
withServiceCalls: (fn: () => readonly unknown[]) => { execute: () => Promise<unknown> };
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
| undefined;
|
|
487
|
+
|
|
488
|
+
if (!handlerContext?.handlerTx) {
|
|
489
|
+
throw new Error(
|
|
490
|
+
"callServices is only supported for fragments with handlerTx (database fragments).",
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
let callWasArray = false;
|
|
495
|
+
const execute = () => {
|
|
496
|
+
return handlerContext.handlerTx!()
|
|
497
|
+
.withServiceCalls(() => {
|
|
498
|
+
const calls = serviceCalls();
|
|
499
|
+
callWasArray = Array.isArray(calls);
|
|
500
|
+
return (callWasArray ? calls : [calls]) as readonly unknown[];
|
|
501
|
+
})
|
|
502
|
+
.execute();
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
const result = this.#contextStorage.hasStore()
|
|
506
|
+
? await execute()
|
|
507
|
+
: await this.#withRequestStorage(execute, "context");
|
|
508
|
+
|
|
509
|
+
if (callWasArray) {
|
|
510
|
+
return result as ExtractServiceCallResultsOrSingle<TServiceCalls>;
|
|
467
511
|
}
|
|
468
|
-
|
|
512
|
+
|
|
513
|
+
const [first] = result as unknown[];
|
|
514
|
+
return first as ExtractServiceCallResultsOrSingle<TServiceCalls>;
|
|
469
515
|
}
|
|
470
516
|
|
|
471
517
|
/**
|
|
@@ -534,7 +580,7 @@ export class FragnoInstantiatedFragment<
|
|
|
534
580
|
* Main request handler for this fragment.
|
|
535
581
|
* Handles routing, middleware, and error handling.
|
|
536
582
|
*/
|
|
537
|
-
async handler(req: Request): Promise<Response> {
|
|
583
|
+
async handler(req: Request, lifecycleContext?: FragnoRequestLifecycleContext): Promise<Response> {
|
|
538
584
|
const url = new URL(req.url);
|
|
539
585
|
const pathname = url.pathname;
|
|
540
586
|
|
|
@@ -565,7 +611,7 @@ export class FragnoInstantiatedFragment<
|
|
|
565
611
|
}
|
|
566
612
|
|
|
567
613
|
// Get the expected content type from route config (default: application/json)
|
|
568
|
-
const routeConfig = route.data as
|
|
614
|
+
const routeConfig = route.data as AnyFragnoRouteConfig;
|
|
569
615
|
const expectedContentType = routeConfig.contentType ?? "application/json";
|
|
570
616
|
|
|
571
617
|
// Parse request body based on route's expected content type
|
|
@@ -653,6 +699,17 @@ export class FragnoInstantiatedFragment<
|
|
|
653
699
|
headers: new Headers(req.headers),
|
|
654
700
|
});
|
|
655
701
|
|
|
702
|
+
const fullRoutePath =
|
|
703
|
+
this.#mountRoute && this.#mountRoute !== "/"
|
|
704
|
+
? `${this.#mountRoute}${routeConfig.path}`
|
|
705
|
+
: routeConfig.path;
|
|
706
|
+
const routeInfo: RequestRouteInfo = {
|
|
707
|
+
method: routeConfig.method,
|
|
708
|
+
path: routeConfig.path,
|
|
709
|
+
mountRoute: this.#mountRoute,
|
|
710
|
+
fullPath: fullRoutePath,
|
|
711
|
+
};
|
|
712
|
+
|
|
656
713
|
// Execute middleware and handler
|
|
657
714
|
const executeRequest = async (): Promise<Response> => {
|
|
658
715
|
// Parent middleware execution
|
|
@@ -661,46 +718,28 @@ export class FragnoInstantiatedFragment<
|
|
|
661
718
|
return middlewareResult;
|
|
662
719
|
}
|
|
663
720
|
|
|
664
|
-
// Internal fragment middleware execution (if linked)
|
|
665
|
-
const internalMeta = routeConfig.__internal;
|
|
666
|
-
if (internalMeta) {
|
|
667
|
-
const internalResult = await FragnoInstantiatedFragment.#runMiddlewareForFragment(
|
|
668
|
-
internalMeta.fragment as AnyFragnoInstantiatedFragment,
|
|
669
|
-
{
|
|
670
|
-
req,
|
|
671
|
-
method: routeConfig.method,
|
|
672
|
-
path: internalMeta.originalPath,
|
|
673
|
-
requestState,
|
|
674
|
-
routes: internalMeta.routes,
|
|
675
|
-
},
|
|
676
|
-
);
|
|
677
|
-
if (internalResult !== undefined) {
|
|
678
|
-
return internalResult;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
721
|
// Handler execution
|
|
683
722
|
return this.#executeHandler(req, route, requestState, rawBody);
|
|
684
723
|
};
|
|
685
724
|
|
|
686
725
|
// Wrap with request storage context if provided
|
|
687
|
-
return this.#withRequestStorage(executeRequest);
|
|
726
|
+
return this.#withRequestStorage(executeRequest, "route", routeInfo, lifecycleContext);
|
|
688
727
|
}
|
|
689
728
|
|
|
690
729
|
/**
|
|
691
730
|
* Call a route directly with typed inputs and outputs.
|
|
692
731
|
* Useful for testing and server-side route calls.
|
|
693
732
|
*/
|
|
694
|
-
async callRoute<TMethod extends HTTPMethod, TPath extends
|
|
733
|
+
async callRoute<TMethod extends HTTPMethod, TPath extends CallRoutePath<TRoutes, TMethod>>(
|
|
695
734
|
method: TMethod,
|
|
696
735
|
path: TPath,
|
|
697
736
|
inputOptions?: RouteHandlerInputOptions<
|
|
698
737
|
TPath,
|
|
699
|
-
|
|
738
|
+
CallRouteMatch<TRoutes, TMethod, TPath>["inputSchema"]
|
|
700
739
|
>,
|
|
701
740
|
): Promise<
|
|
702
741
|
FragnoResponse<
|
|
703
|
-
InferOrUnknown<NonNullable<
|
|
742
|
+
InferOrUnknown<NonNullable<CallRouteMatch<TRoutes, TMethod, TPath>["outputSchema"]>>
|
|
704
743
|
>
|
|
705
744
|
> {
|
|
706
745
|
const response = await this.callRouteRaw(method, path, inputOptions);
|
|
@@ -711,12 +750,12 @@ export class FragnoInstantiatedFragment<
|
|
|
711
750
|
* Call a route directly and get the raw Response object.
|
|
712
751
|
* Useful for testing and server-side route calls.
|
|
713
752
|
*/
|
|
714
|
-
async callRouteRaw<TMethod extends HTTPMethod, TPath extends
|
|
753
|
+
async callRouteRaw<TMethod extends HTTPMethod, TPath extends CallRoutePath<TRoutes, TMethod>>(
|
|
715
754
|
method: TMethod,
|
|
716
755
|
path: TPath,
|
|
717
756
|
inputOptions?: RouteHandlerInputOptions<
|
|
718
757
|
TPath,
|
|
719
|
-
|
|
758
|
+
CallRouteMatch<TRoutes, TMethod, TPath>["inputSchema"]
|
|
720
759
|
>,
|
|
721
760
|
): Promise<Response> {
|
|
722
761
|
// Find route in this.#routes
|
|
@@ -732,7 +771,8 @@ export class FragnoInstantiatedFragment<
|
|
|
732
771
|
);
|
|
733
772
|
}
|
|
734
773
|
|
|
735
|
-
const { pathParams = {},
|
|
774
|
+
const { pathParams = {}, query, headers } = inputOptions || {};
|
|
775
|
+
const body = inputOptions && "body" in inputOptions ? inputOptions.body : undefined;
|
|
736
776
|
|
|
737
777
|
// Convert query to URLSearchParams if needed
|
|
738
778
|
const searchParams =
|
|
@@ -770,6 +810,17 @@ export class FragnoInstantiatedFragment<
|
|
|
770
810
|
// Construct RequestOutputContext
|
|
771
811
|
const outputContext = new RequestOutputContext(route.outputSchema);
|
|
772
812
|
|
|
813
|
+
const fullRoutePath =
|
|
814
|
+
this.#mountRoute && this.#mountRoute !== "/"
|
|
815
|
+
? `${this.#mountRoute}${route.path}`
|
|
816
|
+
: route.path;
|
|
817
|
+
const routeInfo: RequestRouteInfo = {
|
|
818
|
+
method: route.method,
|
|
819
|
+
path: route.path,
|
|
820
|
+
mountRoute: this.#mountRoute,
|
|
821
|
+
fullPath: fullRoutePath,
|
|
822
|
+
};
|
|
823
|
+
|
|
773
824
|
// Execute handler
|
|
774
825
|
const executeHandler = async (): Promise<Response> => {
|
|
775
826
|
try {
|
|
@@ -791,7 +842,7 @@ export class FragnoInstantiatedFragment<
|
|
|
791
842
|
};
|
|
792
843
|
|
|
793
844
|
// Wrap with request storage context if provided
|
|
794
|
-
return this.#withRequestStorage(executeHandler);
|
|
845
|
+
return this.#withRequestStorage(executeHandler, "route", routeInfo);
|
|
795
846
|
}
|
|
796
847
|
|
|
797
848
|
/**
|
|
@@ -970,7 +1021,7 @@ export function instantiateFragment<
|
|
|
970
1021
|
const THandlerThisContext extends RequestThisContext,
|
|
971
1022
|
const TRequestStorage,
|
|
972
1023
|
const TRoutesOrFactories extends readonly AnyRouteOrFactory[],
|
|
973
|
-
const
|
|
1024
|
+
const TInternalRoutes extends readonly AnyRouteOrFactory[],
|
|
974
1025
|
>(
|
|
975
1026
|
definition: FragmentDefinition<
|
|
976
1027
|
TConfig,
|
|
@@ -983,7 +1034,7 @@ export function instantiateFragment<
|
|
|
983
1034
|
TServiceThisContext,
|
|
984
1035
|
THandlerThisContext,
|
|
985
1036
|
TRequestStorage,
|
|
986
|
-
|
|
1037
|
+
TInternalRoutes
|
|
987
1038
|
>,
|
|
988
1039
|
config: TConfig,
|
|
989
1040
|
routesOrFactories: TRoutesOrFactories,
|
|
@@ -991,14 +1042,13 @@ export function instantiateFragment<
|
|
|
991
1042
|
serviceImplementations?: TServiceDependencies,
|
|
992
1043
|
instantiationOptions?: InstantiationOptions,
|
|
993
1044
|
): FragnoInstantiatedFragment<
|
|
994
|
-
RoutesWithInternal<FlattenRouteFactories<TRoutesOrFactories>,
|
|
1045
|
+
RoutesWithInternal<FlattenRouteFactories<TRoutesOrFactories>, TInternalRoutes>,
|
|
995
1046
|
TDeps,
|
|
996
1047
|
BoundServices<TBaseServices & TServices>,
|
|
997
1048
|
TServiceThisContext,
|
|
998
1049
|
THandlerThisContext,
|
|
999
1050
|
TRequestStorage,
|
|
1000
|
-
TOptions
|
|
1001
|
-
TLinkedFragments
|
|
1051
|
+
TOptions
|
|
1002
1052
|
> {
|
|
1003
1053
|
const { dryRun = false } = instantiationOptions ?? {};
|
|
1004
1054
|
|
|
@@ -1033,36 +1083,18 @@ export function instantiateFragment<
|
|
|
1033
1083
|
}
|
|
1034
1084
|
}
|
|
1035
1085
|
|
|
1036
|
-
// 3.
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
if (definition.linkedFragments) {
|
|
1042
|
-
for (const [name, callback] of Object.entries(definition.linkedFragments)) {
|
|
1043
|
-
const linkedFragment = callback({
|
|
1044
|
-
config,
|
|
1045
|
-
options,
|
|
1046
|
-
serviceDependencies: serviceImplementations,
|
|
1047
|
-
});
|
|
1048
|
-
(linkedFragmentInstances as Record<string, AnyFragnoInstantiatedFragment>)[name] =
|
|
1049
|
-
linkedFragment;
|
|
1050
|
-
|
|
1051
|
-
// Merge all services from linked fragment into private services directly by their service name
|
|
1052
|
-
const services = linkedFragment.services as Record<string, unknown>;
|
|
1053
|
-
for (const [serviceName, service] of Object.entries(services)) {
|
|
1054
|
-
linkedFragmentServices[serviceName] = service;
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1086
|
+
// 3. Calculate mount route early so internal routes can reference it
|
|
1087
|
+
const mountRoute = getMountRoute({
|
|
1088
|
+
name: definition.name,
|
|
1089
|
+
mountRoute: options.mountRoute,
|
|
1090
|
+
});
|
|
1058
1091
|
|
|
1059
|
-
// Identity function for service definition (used to set 'this' context)
|
|
1092
|
+
// 4. Identity function for service definition (used to set 'this' context)
|
|
1060
1093
|
const defineService = <T>(services: T & ThisType<TServiceThisContext>): T => services;
|
|
1061
1094
|
|
|
1062
|
-
//
|
|
1095
|
+
// 5. Call privateServices factories
|
|
1063
1096
|
// Private services are instantiated in order, so earlier ones are available to later ones
|
|
1064
|
-
|
|
1065
|
-
const privateServices = { ...linkedFragmentServices } as TPrivateServices;
|
|
1097
|
+
const privateServices = {} as TPrivateServices;
|
|
1066
1098
|
if (definition.privateServices) {
|
|
1067
1099
|
for (const [serviceName, factory] of Object.entries(definition.privateServices)) {
|
|
1068
1100
|
const serviceFactory = factory as (context: {
|
|
@@ -1097,7 +1129,7 @@ export function instantiateFragment<
|
|
|
1097
1129
|
}
|
|
1098
1130
|
}
|
|
1099
1131
|
|
|
1100
|
-
//
|
|
1132
|
+
// 6. Call baseServices callback (with access to private services)
|
|
1101
1133
|
let baseServices: TBaseServices;
|
|
1102
1134
|
try {
|
|
1103
1135
|
baseServices =
|
|
@@ -1121,7 +1153,7 @@ export function instantiateFragment<
|
|
|
1121
1153
|
}
|
|
1122
1154
|
}
|
|
1123
1155
|
|
|
1124
|
-
//
|
|
1156
|
+
// 7. Call namedServices factories (with access to private services)
|
|
1125
1157
|
const namedServices = {} as TServices;
|
|
1126
1158
|
if (definition.namedServices) {
|
|
1127
1159
|
for (const [serviceName, factory] of Object.entries(definition.namedServices)) {
|
|
@@ -1157,13 +1189,13 @@ export function instantiateFragment<
|
|
|
1157
1189
|
}
|
|
1158
1190
|
}
|
|
1159
1191
|
|
|
1160
|
-
//
|
|
1192
|
+
// 8. Merge public services (NOT including private services)
|
|
1161
1193
|
const services = {
|
|
1162
1194
|
...baseServices,
|
|
1163
1195
|
...namedServices,
|
|
1164
1196
|
};
|
|
1165
1197
|
|
|
1166
|
-
//
|
|
1198
|
+
// 9. Create request context storage and both service & handler contexts
|
|
1167
1199
|
// Use external storage if provided, otherwise create new storage
|
|
1168
1200
|
const storage = definition.getExternalStorage
|
|
1169
1201
|
? definition.getExternalStorage({ config, options, deps })
|
|
@@ -1179,19 +1211,20 @@ export function instantiateFragment<
|
|
|
1179
1211
|
|
|
1180
1212
|
const serviceContext = contexts?.serviceContext;
|
|
1181
1213
|
const handlerContext = contexts?.handlerContext;
|
|
1214
|
+
|
|
1215
|
+
// 10. Bind services to serviceContext (restricted)
|
|
1216
|
+
// Services get the restricted context (for database fragments, this excludes execute methods)
|
|
1217
|
+
const boundServices = serviceContext ? bindServicesToContext(services, serviceContext) : services;
|
|
1182
1218
|
const internalData =
|
|
1183
1219
|
definition.internalDataFactory?.({
|
|
1184
1220
|
config,
|
|
1185
1221
|
options,
|
|
1186
1222
|
deps,
|
|
1187
|
-
|
|
1223
|
+
services: boundServices as BoundServices<TBaseServices & TServices>,
|
|
1224
|
+
serviceDeps: (serviceImplementations ?? {}) as TServiceDependencies,
|
|
1188
1225
|
}) ?? {};
|
|
1189
1226
|
|
|
1190
|
-
//
|
|
1191
|
-
// Services get the restricted context (for database fragments, this excludes execute methods)
|
|
1192
|
-
const boundServices = serviceContext ? bindServicesToContext(services, serviceContext) : services;
|
|
1193
|
-
|
|
1194
|
-
// 10. Resolve routes with bound services
|
|
1227
|
+
// 11. Resolve routes with bound services
|
|
1195
1228
|
const context = {
|
|
1196
1229
|
config,
|
|
1197
1230
|
deps,
|
|
@@ -1199,17 +1232,17 @@ export function instantiateFragment<
|
|
|
1199
1232
|
serviceDeps: serviceImplementations ?? ({} as TServiceDependencies),
|
|
1200
1233
|
};
|
|
1201
1234
|
const routes = resolveRouteFactories(context, routesOrFactories) as AnyFragnoRouteConfig[];
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
1235
|
+
const internalRoutes = definition.internalRoutes
|
|
1236
|
+
? (resolveRouteFactories(context, definition.internalRoutes) as readonly AnyFragnoRouteConfig[])
|
|
1237
|
+
: [];
|
|
1238
|
+
const prefixedInternalRoutes = internalRoutes.map((route) => ({
|
|
1239
|
+
...route,
|
|
1240
|
+
path: joinRoutePath(INTERNAL_ROUTE_PREFIX, route.path),
|
|
1241
|
+
}));
|
|
1205
1242
|
const finalRoutes =
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
const mountRoute = getMountRoute({
|
|
1210
|
-
name: definition.name,
|
|
1211
|
-
mountRoute: options.mountRoute,
|
|
1212
|
-
});
|
|
1243
|
+
prefixedInternalRoutes.length > 0
|
|
1244
|
+
? [...routes, ...prefixedInternalRoutes]
|
|
1245
|
+
: (routes as AnyFragnoRouteConfig[]);
|
|
1213
1246
|
|
|
1214
1247
|
// 12. Wrap createRequestStorage to capture context
|
|
1215
1248
|
const createRequestStorageWithContext = definition.createRequestStorage
|
|
@@ -1223,7 +1256,7 @@ export function instantiateFragment<
|
|
|
1223
1256
|
name: definition.name,
|
|
1224
1257
|
routes: finalRoutes as unknown as RoutesWithInternal<
|
|
1225
1258
|
FlattenRouteFactories<TRoutesOrFactories>,
|
|
1226
|
-
|
|
1259
|
+
TInternalRoutes
|
|
1227
1260
|
>,
|
|
1228
1261
|
deps,
|
|
1229
1262
|
services: boundServices as BoundServices<TBaseServices & TServices>,
|
|
@@ -1233,7 +1266,6 @@ export function instantiateFragment<
|
|
|
1233
1266
|
storage,
|
|
1234
1267
|
createRequestStorage: createRequestStorageWithContext,
|
|
1235
1268
|
options,
|
|
1236
|
-
linkedFragments: linkedFragmentInstances,
|
|
1237
1269
|
internalData: internalData as Record<string, unknown>,
|
|
1238
1270
|
});
|
|
1239
1271
|
}
|
|
@@ -1310,7 +1342,6 @@ interface IFragnoInstantiatedFragment {
|
|
|
1310
1342
|
get $internal(): {
|
|
1311
1343
|
deps: unknown;
|
|
1312
1344
|
options: unknown;
|
|
1313
|
-
linkedFragments: unknown;
|
|
1314
1345
|
} & Record<string, unknown>;
|
|
1315
1346
|
|
|
1316
1347
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1321,10 +1352,13 @@ interface IFragnoInstantiatedFragment {
|
|
|
1321
1352
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1322
1353
|
inContext<T>(callback: any): Promise<T>;
|
|
1323
1354
|
|
|
1355
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1356
|
+
callServices(serviceCalls: () => any): Promise<any>;
|
|
1357
|
+
|
|
1324
1358
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1325
1359
|
handlersFor(framework: FullstackFrameworks): any;
|
|
1326
1360
|
|
|
1327
|
-
handler(req: Request): Promise<Response>;
|
|
1361
|
+
handler(req: Request, lifecycleContext?: FragnoRequestLifecycleContext): Promise<Response>;
|
|
1328
1362
|
|
|
1329
1363
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1330
1364
|
callRoute(method: HTTPMethod, path: string, inputOptions?: any): Promise<any>;
|
|
@@ -1349,9 +1383,8 @@ export class FragmentInstantiationBuilder<
|
|
|
1349
1383
|
THandlerThisContext extends RequestThisContext,
|
|
1350
1384
|
TRequestStorage,
|
|
1351
1385
|
TRoutesOrFactories extends readonly AnyRouteOrFactory[],
|
|
1352
|
-
|
|
1353
|
-
> implements IFragmentInstantiationBuilder
|
|
1354
|
-
{
|
|
1386
|
+
TInternalRoutes extends readonly AnyRouteOrFactory[],
|
|
1387
|
+
> implements IFragmentInstantiationBuilder {
|
|
1355
1388
|
#definition: FragmentDefinition<
|
|
1356
1389
|
TConfig,
|
|
1357
1390
|
TOptions,
|
|
@@ -1363,7 +1396,7 @@ export class FragmentInstantiationBuilder<
|
|
|
1363
1396
|
TServiceThisContext,
|
|
1364
1397
|
THandlerThisContext,
|
|
1365
1398
|
TRequestStorage,
|
|
1366
|
-
|
|
1399
|
+
TInternalRoutes
|
|
1367
1400
|
>;
|
|
1368
1401
|
#config?: TConfig;
|
|
1369
1402
|
#routes?: TRoutesOrFactories;
|
|
@@ -1382,7 +1415,7 @@ export class FragmentInstantiationBuilder<
|
|
|
1382
1415
|
TServiceThisContext,
|
|
1383
1416
|
THandlerThisContext,
|
|
1384
1417
|
TRequestStorage,
|
|
1385
|
-
|
|
1418
|
+
TInternalRoutes
|
|
1386
1419
|
>,
|
|
1387
1420
|
routes?: TRoutesOrFactories,
|
|
1388
1421
|
) {
|
|
@@ -1404,7 +1437,7 @@ export class FragmentInstantiationBuilder<
|
|
|
1404
1437
|
TServiceThisContext,
|
|
1405
1438
|
THandlerThisContext,
|
|
1406
1439
|
TRequestStorage,
|
|
1407
|
-
|
|
1440
|
+
TInternalRoutes
|
|
1408
1441
|
> {
|
|
1409
1442
|
return this.#definition;
|
|
1410
1443
|
}
|
|
@@ -1455,7 +1488,7 @@ export class FragmentInstantiationBuilder<
|
|
|
1455
1488
|
THandlerThisContext,
|
|
1456
1489
|
TRequestStorage,
|
|
1457
1490
|
TNewRoutes,
|
|
1458
|
-
|
|
1491
|
+
TInternalRoutes
|
|
1459
1492
|
> {
|
|
1460
1493
|
const newBuilder = new FragmentInstantiationBuilder(this.#definition, routes);
|
|
1461
1494
|
// Preserve config, options, and services from the current instance
|
|
@@ -1485,14 +1518,13 @@ export class FragmentInstantiationBuilder<
|
|
|
1485
1518
|
* Build and return the instantiated fragment
|
|
1486
1519
|
*/
|
|
1487
1520
|
build(): FragnoInstantiatedFragment<
|
|
1488
|
-
RoutesWithInternal<FlattenRouteFactories<TRoutesOrFactories>,
|
|
1521
|
+
RoutesWithInternal<FlattenRouteFactories<TRoutesOrFactories>, TInternalRoutes>,
|
|
1489
1522
|
TDeps,
|
|
1490
1523
|
BoundServices<TBaseServices & TServices>,
|
|
1491
1524
|
TServiceThisContext,
|
|
1492
1525
|
THandlerThisContext,
|
|
1493
1526
|
TRequestStorage,
|
|
1494
|
-
TOptions
|
|
1495
|
-
TLinkedFragments
|
|
1527
|
+
TOptions
|
|
1496
1528
|
> {
|
|
1497
1529
|
// This variable is set by the frango-cli when extracting database schemas
|
|
1498
1530
|
const dryRun = process.env["FRAGNO_INIT_DRY_RUN"] === "true";
|
|
@@ -1531,7 +1563,7 @@ export function instantiate<
|
|
|
1531
1563
|
TServiceThisContext extends RequestThisContext,
|
|
1532
1564
|
THandlerThisContext extends RequestThisContext,
|
|
1533
1565
|
TRequestStorage,
|
|
1534
|
-
|
|
1566
|
+
TInternalRoutes extends readonly AnyRouteOrFactory[],
|
|
1535
1567
|
>(
|
|
1536
1568
|
definition: FragmentDefinition<
|
|
1537
1569
|
TConfig,
|
|
@@ -1544,7 +1576,7 @@ export function instantiate<
|
|
|
1544
1576
|
TServiceThisContext,
|
|
1545
1577
|
THandlerThisContext,
|
|
1546
1578
|
TRequestStorage,
|
|
1547
|
-
|
|
1579
|
+
TInternalRoutes
|
|
1548
1580
|
>,
|
|
1549
1581
|
): FragmentInstantiationBuilder<
|
|
1550
1582
|
TConfig,
|
|
@@ -1558,7 +1590,7 @@ export function instantiate<
|
|
|
1558
1590
|
THandlerThisContext,
|
|
1559
1591
|
TRequestStorage,
|
|
1560
1592
|
readonly [],
|
|
1561
|
-
|
|
1593
|
+
TInternalRoutes
|
|
1562
1594
|
> {
|
|
1563
1595
|
return new FragmentInstantiationBuilder(definition);
|
|
1564
1596
|
}
|