@supacloud/app 0.4.0 → 0.5.0

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/dist/index.js CHANGED
@@ -1,3 +1,14 @@
1
+ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
4
+ r = Reflect.decorate(decorators, target, key, desc);
5
+ else
6
+ for (var i = decorators.length - 1;i >= 0; i--)
7
+ if (d = decorators[i])
8
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+
1
12
  // src/scope.ts
2
13
  var SCOPES = ["application", "request", "job"];
3
14
  var DEFAULT_SCOPE = "application";
@@ -13,16 +24,71 @@ function isScopeViolation(from, to) {
13
24
  class InjectionToken {
14
25
  name;
15
26
  factory;
27
+ providedIn;
16
28
  scope;
17
29
  constructor(name, options = {}) {
18
30
  this.name = name;
19
31
  this.factory = options.factory;
32
+ this.providedIn = options.providedIn;
20
33
  this.scope = options.scope;
21
34
  }
22
35
  toString() {
23
36
  return `InjectionToken ${this.name}`;
24
37
  }
25
38
  }
39
+ // src/context.ts
40
+ var REQUEST_CONTEXT = new InjectionToken("supacloud.request-context", {
41
+ scope: "request"
42
+ });
43
+ var JOB_CONTEXT = new InjectionToken("supacloud.job-context", {
44
+ scope: "job"
45
+ });
46
+ var DB_CLIENT = new InjectionToken("supacloud.db-client", {
47
+ scope: "application"
48
+ });
49
+ var APP_INITIALIZER = new InjectionToken("supacloud.app-initializer", { scope: "application" });
50
+ var ENVIRONMENT_INITIALIZER = new InjectionToken("supacloud.environment-initializer", { scope: "application" });
51
+ var DESTROY_REF = new InjectionToken("supacloud.destroy-ref", {
52
+ scope: "application",
53
+ factory: () => createDestroyRef()
54
+ });
55
+ function createDestroyRef() {
56
+ let isDestroyed = false;
57
+ const abortController = new AbortController;
58
+ const callbacks = [];
59
+ return {
60
+ get destroyed() {
61
+ return isDestroyed;
62
+ },
63
+ get signal() {
64
+ return abortController.signal;
65
+ },
66
+ onDestroy(callback) {
67
+ if (isDestroyed) {
68
+ throw new Error("Cannot register onDestroy callback on an already destroyed DestroyRef");
69
+ }
70
+ callbacks.push(callback);
71
+ return () => {
72
+ const idx = callbacks.indexOf(callback);
73
+ if (idx !== -1)
74
+ callbacks.splice(idx, 1);
75
+ };
76
+ },
77
+ async destroy() {
78
+ if (isDestroyed)
79
+ return;
80
+ isDestroyed = true;
81
+ abortController.abort();
82
+ const reversed = [...callbacks].reverse();
83
+ callbacks.length = 0;
84
+ for (const cb of reversed) {
85
+ await cb();
86
+ }
87
+ },
88
+ _teardowns: callbacks
89
+ };
90
+ }
91
+
26
92
  // src/provider.ts
27
93
  function isClassProvider(provider) {
28
94
  return typeof provider === "object" && provider !== null && "useClass" in provider;
@@ -36,6 +102,49 @@ function isFactoryProvider(provider) {
36
102
  function isExistingProvider(provider) {
37
103
  return typeof provider === "object" && provider !== null && "useExisting" in provider;
38
104
  }
105
+ function makeEnvironmentProviders(providers) {
106
+ return { ɵproviders: providers };
107
+ }
108
+ function isEnvironmentProviders(value) {
109
+ return typeof value === "object" && value !== null && "ɵproviders" in value && Array.isArray(value.ɵproviders);
110
+ }
111
+ function flattenProviders(providers) {
112
+ const result = [];
113
+ for (const p of providers) {
114
+ if (isEnvironmentProviders(p)) {
115
+ result.push(...p.ɵproviders);
116
+ } else {
117
+ result.push(p);
118
+ }
119
+ }
120
+ return result;
121
+ }
122
+ function provideAppInitializer(initializerFn) {
123
+ return makeEnvironmentProviders([
124
+ {
125
+ provide: APP_INITIALIZER,
126
+ useValue: initializerFn,
127
+ multi: true
128
+ }
129
+ ]);
130
+ }
131
+ function provideEnvironmentInitializer(initializerFn) {
132
+ return makeEnvironmentProviders([
133
+ {
134
+ provide: ENVIRONMENT_INITIALIZER,
135
+ useValue: initializerFn,
136
+ multi: true
137
+ }
138
+ ]);
139
+ }
140
+ function provideToken(token, value) {
141
+ return makeEnvironmentProviders([
142
+ {
143
+ provide: token,
144
+ useValue: value
145
+ }
146
+ ]);
147
+ }
39
148
  // src/decorators.ts
40
149
  var INJECTABLE_METADATA = "supacloud:injectable";
41
150
  var MODULE_METADATA = "supacloud:module";
@@ -44,6 +153,16 @@ var QUERY_METADATA = "supacloud:query";
44
153
  var CONTROLLER_METADATA = "supacloud:controller";
45
154
  var ROUTES_METADATA = "supacloud:routes";
46
155
  var INJECT_PARAMS_METADATA = "supacloud:inject-params";
156
+ var OPTIONAL_PARAMS_METADATA = "supacloud:optional-params";
157
+ var SELF_PARAMS_METADATA = "supacloud:self-params";
158
+ var SKIP_SELF_PARAMS_METADATA = "supacloud:skip-self-params";
159
+ var HOST_PARAMS_METADATA = "supacloud:host-params";
160
+ var GUARDS_METADATA = "supacloud:guards";
161
+ var CAN_DEACTIVATE_METADATA = "supacloud:guards:can-deactivate";
162
+ var RESOLVE_METADATA = "supacloud:resolvers";
163
+ var TITLE_METADATA = "supacloud:route:title";
164
+ var DATA_METADATA = "supacloud:route:data";
165
+ var ROUTE_PARAMS_METADATA = "supacloud:route-params";
47
166
  function defineMetadata(target, key, value) {
48
167
  Object.defineProperty(target, key, {
49
168
  value,
@@ -58,6 +177,7 @@ function Injectable(options = {}) {
58
177
  return (target) => {
59
178
  const meta = {
60
179
  scope: options.scope ?? DEFAULT_SCOPE,
180
+ providedIn: options.providedIn,
61
181
  deps: options.deps ?? []
62
182
  };
63
183
  defineMetadata(target, INJECTABLE_METADATA, meta);
@@ -82,13 +202,94 @@ function Inject(token) {
82
202
  function getInjectParams(target) {
83
203
  return readOwnOrInherited(target, INJECT_PARAMS_METADATA) ?? {};
84
204
  }
205
+ function Optional() {
206
+ return (target, propertyKey, parameterIndex) => {
207
+ if (propertyKey !== undefined) {
208
+ throw new Error("@Optional() is only supported on constructor parameters");
209
+ }
210
+ const cls = target;
211
+ const list = [...readOwnOrInherited(cls, OPTIONAL_PARAMS_METADATA) ?? []];
212
+ if (!list.includes(parameterIndex))
213
+ list.push(parameterIndex);
214
+ defineMetadata(cls, OPTIONAL_PARAMS_METADATA, list);
215
+ };
216
+ }
217
+ function getOptionalParams(target) {
218
+ return readOwnOrInherited(target, OPTIONAL_PARAMS_METADATA) ?? [];
219
+ }
220
+ function Self() {
221
+ return (target, propertyKey, parameterIndex) => {
222
+ if (propertyKey !== undefined) {
223
+ throw new Error("@Self() is only supported on constructor parameters");
224
+ }
225
+ const cls = target;
226
+ const list = [...readOwnOrInherited(cls, SELF_PARAMS_METADATA) ?? []];
227
+ if (!list.includes(parameterIndex))
228
+ list.push(parameterIndex);
229
+ defineMetadata(cls, SELF_PARAMS_METADATA, list);
230
+ };
231
+ }
232
+ function getSelfParams(target) {
233
+ return readOwnOrInherited(target, SELF_PARAMS_METADATA) ?? [];
234
+ }
235
+ function SkipSelf() {
236
+ return (target, propertyKey, parameterIndex) => {
237
+ if (propertyKey !== undefined) {
238
+ throw new Error("@SkipSelf() is only supported on constructor parameters");
239
+ }
240
+ const cls = target;
241
+ const list = [...readOwnOrInherited(cls, SKIP_SELF_PARAMS_METADATA) ?? []];
242
+ if (!list.includes(parameterIndex))
243
+ list.push(parameterIndex);
244
+ defineMetadata(cls, SKIP_SELF_PARAMS_METADATA, list);
245
+ };
246
+ }
247
+ function getSkipSelfParams(target) {
248
+ return readOwnOrInherited(target, SKIP_SELF_PARAMS_METADATA) ?? [];
249
+ }
250
+ function Host() {
251
+ return (target, propertyKey, parameterIndex) => {
252
+ if (propertyKey !== undefined) {
253
+ throw new Error("@Host() is only supported on constructor parameters");
254
+ }
255
+ const cls = target;
256
+ const list = [...readOwnOrInherited(cls, HOST_PARAMS_METADATA) ?? []];
257
+ if (!list.includes(parameterIndex))
258
+ list.push(parameterIndex);
259
+ defineMetadata(cls, HOST_PARAMS_METADATA, list);
260
+ };
261
+ }
262
+ function getHostParams(target) {
263
+ return readOwnOrInherited(target, HOST_PARAMS_METADATA) ?? [];
264
+ }
265
+ function UseGuards(...guards) {
266
+ return (target, propertyKey) => {
267
+ if (propertyKey !== undefined) {
268
+ const cls = target.constructor;
269
+ const key = `${GUARDS_METADATA}:${String(propertyKey)}`;
270
+ const existing = readOwnOrInherited(cls, key) ?? [];
271
+ defineMetadata(cls, key, [...existing, ...guards]);
272
+ } else {
273
+ const existing = readOwnOrInherited(target, GUARDS_METADATA) ?? [];
274
+ defineMetadata(target, GUARDS_METADATA, [...existing, ...guards]);
275
+ }
276
+ };
277
+ }
278
+ function getGuards(target, propertyKey) {
279
+ if (propertyKey !== undefined) {
280
+ const methodGuards = readOwnOrInherited(target, `${GUARDS_METADATA}:${String(propertyKey)}`) ?? [];
281
+ const classGuards = readOwnOrInherited(target, GUARDS_METADATA) ?? [];
282
+ return [...classGuards, ...methodGuards];
283
+ }
284
+ return readOwnOrInherited(target, GUARDS_METADATA) ?? [];
285
+ }
85
286
  function Module(options) {
86
287
  return (target) => {
87
288
  const meta = {
88
289
  name: options.name,
89
290
  tags: options.tags ?? [],
90
291
  imports: options.imports ?? [],
91
- providers: options.providers ?? [],
292
+ providers: options.providers ? flattenProviders(options.providers) : [],
92
293
  controllers: options.controllers ?? [],
93
294
  commands: options.commands ?? [],
94
295
  queries: options.queries ?? [],
@@ -112,17 +313,69 @@ function Command(options) {
112
313
  function getCommandMeta(target) {
113
314
  return readOwnOrInherited(target, COMMAND_METADATA);
114
315
  }
115
- function Query(options) {
116
- return (target) => {
117
- defineMetadata(target, QUERY_METADATA, { ...options });
316
+ function Param(nameOrOptions, options) {
317
+ return (target, propertyKey, parameterIndex) => {
318
+ if (propertyKey === undefined) {
319
+ throw new Error("@Param() is only supported on controller method parameters");
320
+ }
321
+ const cls = target.constructor;
322
+ const key = `${ROUTE_PARAMS_METADATA}:${String(propertyKey)}`;
323
+ const existing = readOwnOrInherited(cls, key) ?? [];
324
+ const name = typeof nameOrOptions === "string" ? nameOrOptions : nameOrOptions?.name;
325
+ const transform = typeof nameOrOptions === "object" ? nameOrOptions.transform : options?.transform;
326
+ const defaultValue = typeof nameOrOptions === "object" ? nameOrOptions.default : options?.default;
327
+ defineMetadata(cls, key, [...existing, { index: parameterIndex, type: "param", name, transform, default: defaultValue }]);
118
328
  };
119
329
  }
330
+ function Body() {
331
+ return (target, propertyKey, parameterIndex) => {
332
+ if (propertyKey === undefined) {
333
+ throw new Error("@Body() is only supported on controller method parameters");
334
+ }
335
+ const cls = target.constructor;
336
+ const key = `${ROUTE_PARAMS_METADATA}:${String(propertyKey)}`;
337
+ const existing = readOwnOrInherited(cls, key) ?? [];
338
+ defineMetadata(cls, key, [...existing, { index: parameterIndex, type: "body" }]);
339
+ };
340
+ }
341
+ function Headers(name) {
342
+ return (target, propertyKey, parameterIndex) => {
343
+ if (propertyKey === undefined) {
344
+ throw new Error("@Headers() is only supported on controller method parameters");
345
+ }
346
+ const cls = target.constructor;
347
+ const key = `${ROUTE_PARAMS_METADATA}:${String(propertyKey)}`;
348
+ const existing = readOwnOrInherited(cls, key) ?? [];
349
+ defineMetadata(cls, key, [...existing, { index: parameterIndex, type: "headers", name }]);
350
+ };
351
+ }
352
+ function Query(optionsOrName, options) {
353
+ return (target, propertyKey, parameterIndex) => {
354
+ if (typeof parameterIndex === "number" && propertyKey !== undefined) {
355
+ const cls = target.constructor;
356
+ const key = `${ROUTE_PARAMS_METADATA}:${String(propertyKey)}`;
357
+ const existing = readOwnOrInherited(cls, key) ?? [];
358
+ const name = typeof optionsOrName === "string" ? optionsOrName : optionsOrName?.name;
359
+ const transform = typeof optionsOrName === "object" ? optionsOrName.transform : options?.transform;
360
+ const defaultValue = typeof optionsOrName === "object" ? optionsOrName.default : options?.default;
361
+ defineMetadata(cls, key, [...existing, { index: parameterIndex, type: "query", name, transform, default: defaultValue }]);
362
+ } else {
363
+ const opts = typeof optionsOrName === "object" && optionsOrName !== null ? optionsOrName : { name: String(optionsOrName ?? "") };
364
+ defineMetadata(target, QUERY_METADATA, { ...opts });
365
+ }
366
+ };
367
+ }
368
+ function getRouteParams(target, propertyKey) {
369
+ const params = readOwnOrInherited(target, `${ROUTE_PARAMS_METADATA}:${String(propertyKey)}`) ?? [];
370
+ return [...params].sort((a, b) => a.index - b.index);
371
+ }
120
372
  function getQueryMeta(target) {
121
373
  return readOwnOrInherited(target, QUERY_METADATA);
122
374
  }
123
- function Controller(path) {
375
+ function Controller(pathOrOptions = "/") {
124
376
  return (target) => {
125
- defineMetadata(target, CONTROLLER_METADATA, { path });
377
+ const meta = typeof pathOrOptions === "string" ? { path: pathOrOptions } : { path: pathOrOptions.path ?? "/", standalone: pathOrOptions.standalone };
378
+ defineMetadata(target, CONTROLLER_METADATA, meta);
126
379
  };
127
380
  }
128
381
  function getControllerMeta(target) {
@@ -131,6 +384,23 @@ function getControllerMeta(target) {
131
384
  function createRouteDecorator(method) {
132
385
  return (path, options = {}) => (target, propertyKey) => {
133
386
  const cls = target.constructor;
387
+ const titleKey = `${TITLE_METADATA}:${String(propertyKey)}`;
388
+ const dataKey = `${DATA_METADATA}:${String(propertyKey)}`;
389
+ const deactKey = `${CAN_DEACTIVATE_METADATA}:${String(propertyKey)}`;
390
+ const resolveKey = `${RESOLVE_METADATA}:${String(propertyKey)}`;
391
+ const title = options.title ?? readOwnOrInherited(cls, titleKey);
392
+ const data = {
393
+ ...readOwnOrInherited(cls, dataKey) ?? {},
394
+ ...options.data ?? {}
395
+ };
396
+ const canDeactivate = [
397
+ ...readOwnOrInherited(cls, deactKey) ?? [],
398
+ ...options.canDeactivate ?? []
399
+ ];
400
+ const resolvers = {
401
+ ...readOwnOrInherited(cls, resolveKey) ?? {},
402
+ ...options.resolvers ?? {}
403
+ };
134
404
  const routes = [
135
405
  ...readOwnOrInherited(cls, ROUTES_METADATA) ?? []
136
406
  ];
@@ -138,7 +408,11 @@ function createRouteDecorator(method) {
138
408
  method,
139
409
  path,
140
410
  handler: String(propertyKey),
141
- ...options
411
+ ...options,
412
+ resolvers: Object.keys(resolvers).length > 0 ? resolvers : undefined,
413
+ canDeactivate: canDeactivate.length > 0 ? canDeactivate : undefined,
414
+ title: title || undefined,
415
+ data: Object.keys(data).length > 0 ? data : undefined
142
416
  });
143
417
  defineMetadata(cls, ROUTES_METADATA, routes);
144
418
  };
@@ -150,6 +424,68 @@ var Patch = createRouteDecorator("PATCH");
150
424
  var Delete = createRouteDecorator("DELETE");
151
425
  var Head = createRouteDecorator("HEAD");
152
426
  var Options = createRouteDecorator("OPTIONS");
427
+ function Title(title) {
428
+ return (target, propertyKey) => {
429
+ const cls = target.constructor;
430
+ const key = `${TITLE_METADATA}:${String(propertyKey)}`;
431
+ defineMetadata(cls, key, title);
432
+ const routes = readOwnOrInherited(cls, ROUTES_METADATA) ?? [];
433
+ const route = routes.find((r) => r.handler === String(propertyKey));
434
+ if (route) {
435
+ route.title = title;
436
+ }
437
+ };
438
+ }
439
+ function Data(data) {
440
+ return (target, propertyKey) => {
441
+ const cls = target.constructor;
442
+ const key = `${DATA_METADATA}:${String(propertyKey)}`;
443
+ const existing = readOwnOrInherited(cls, key) ?? {};
444
+ defineMetadata(cls, key, { ...existing, ...data });
445
+ const routes = readOwnOrInherited(cls, ROUTES_METADATA) ?? [];
446
+ const route = routes.find((r) => r.handler === String(propertyKey));
447
+ if (route) {
448
+ route.data = { ...route.data, ...data };
449
+ }
450
+ };
451
+ }
452
+ function CanDeactivate(...guards) {
453
+ return (target, propertyKey) => {
454
+ const cls = target.constructor;
455
+ const key = `${CAN_DEACTIVATE_METADATA}:${String(propertyKey)}`;
456
+ const existing = readOwnOrInherited(cls, key) ?? [];
457
+ defineMetadata(cls, key, [...existing, ...guards]);
458
+ const routes = readOwnOrInherited(cls, ROUTES_METADATA) ?? [];
459
+ const route = routes.find((r) => r.handler === String(propertyKey));
460
+ if (route) {
461
+ route.canDeactivate = [...route.canDeactivate ?? [], ...guards];
462
+ }
463
+ };
464
+ }
465
+ function Resolve(resolvers) {
466
+ return (target, propertyKey) => {
467
+ const cls = target.constructor;
468
+ const key = `${RESOLVE_METADATA}:${String(propertyKey)}`;
469
+ const existing = readOwnOrInherited(cls, key) ?? {};
470
+ defineMetadata(cls, key, { ...existing, ...resolvers });
471
+ const routes = readOwnOrInherited(cls, ROUTES_METADATA) ?? [];
472
+ const route = routes.find((r) => r.handler === String(propertyKey));
473
+ if (route) {
474
+ route.resolvers = { ...route.resolvers ?? {}, ...resolvers };
475
+ }
476
+ };
477
+ }
478
+ async function executeResolvers(resolvers, ctx) {
479
+ const entries = Object.entries(resolvers);
480
+ const resolved = await Promise.all(entries.map(async ([key, resolver]) => {
481
+ if (typeof resolver === "function") {
482
+ const val = await resolver(ctx);
483
+ return [key, val];
484
+ }
485
+ return [key, resolver];
486
+ }));
487
+ return Object.fromEntries(resolved);
488
+ }
153
489
  function getRoutes(target) {
154
490
  return readOwnOrInherited(target, ROUTES_METADATA) ?? [];
155
491
  }
@@ -164,55 +500,2349 @@ function defineModule(options) {
164
500
  Module(options)(DefinedModule);
165
501
  return DefinedModule;
166
502
  }
167
- // src/context.ts
168
- var REQUEST_CONTEXT = new InjectionToken("supacloud.request-context", {
169
- scope: "request"
503
+ // src/forward_ref.ts
504
+ function forwardRef(fn) {
505
+ fn.__forward_ref__ = forwardRef;
506
+ return fn;
507
+ }
508
+ function resolveForwardRef(type) {
509
+ if (isForwardRef(type)) {
510
+ return type();
511
+ }
512
+ return type;
513
+ }
514
+ function isForwardRef(fn) {
515
+ return typeof fn === "function" && fn.__forward_ref__ === forwardRef;
516
+ }
517
+
518
+ // src/inject.ts
519
+ var currentInjector = null;
520
+ function getActiveInjector() {
521
+ return currentInjector;
522
+ }
523
+ var INJECTOR = new InjectionToken("supacloud.injector", {
524
+ scope: "application",
525
+ factory: () => {
526
+ const active = getActiveInjector();
527
+ if (!active) {
528
+ throw new Error("Cannot resolve INJECTOR outside of an active injection context.");
529
+ }
530
+ return active;
531
+ }
170
532
  });
171
- var JOB_CONTEXT = new InjectionToken("supacloud.job-context", {
172
- scope: "job"
533
+ function runInInjectionContext(injector, fn) {
534
+ const prev = currentInjector;
535
+ currentInjector = injector;
536
+ try {
537
+ return fn();
538
+ } finally {
539
+ currentInjector = prev;
540
+ }
541
+ }
542
+ function inject(token, options) {
543
+ if (!currentInjector) {
544
+ throw new Error(`inject() can only be used within an active injection context (constructor, factory, guard, or runInInjectionContext). Token: ${tokenToString(token)}`);
545
+ }
546
+ const resolved = resolveForwardRef(token);
547
+ let value;
548
+ if (options?.skipSelf) {
549
+ if (!currentInjector.parent) {
550
+ if (options.optional)
551
+ return;
552
+ throw new Error(`NullInjectorError: No parent provider found for skipSelf token ${tokenToString(resolved)}`);
553
+ }
554
+ value = currentInjector.parent.get(resolved, options);
555
+ } else {
556
+ value = currentInjector.get(resolved, options);
557
+ }
558
+ if (value === undefined) {
559
+ if (options?.optional) {
560
+ return;
561
+ }
562
+ if (resolved instanceof InjectionToken && resolved.factory && !options?.self && !options?.skipSelf) {
563
+ return resolved.factory();
564
+ }
565
+ throw new Error(`NullInjectorError: No provider for ${tokenToString(resolved)}`);
566
+ }
567
+ return value;
568
+ }
569
+ function injectAll(token) {
570
+ const value = inject(token, { optional: true });
571
+ if (value === undefined)
572
+ return [];
573
+ return Array.isArray(value) ? value : [value];
574
+ }
575
+ function createChildInjector(parent, localProviders = new Map) {
576
+ const providerMap = localProviders instanceof Map ? localProviders : new Map(Object.entries(localProviders));
577
+ return {
578
+ parent,
579
+ get(token, options) {
580
+ const resolved = resolveForwardRef(token);
581
+ if (providerMap.has(resolved)) {
582
+ return providerMap.get(resolved);
583
+ }
584
+ if (resolved instanceof InjectionToken && providerMap.has(resolved.name)) {
585
+ return providerMap.get(resolved.name);
586
+ }
587
+ if (options?.self) {
588
+ return;
589
+ }
590
+ return parent.get(resolved);
591
+ }
592
+ };
593
+ }
594
+ function assertInInjectionContext(fnName) {
595
+ if (!currentInjector) {
596
+ throw new Error(`${fnName} must be called from an active injection context.`);
597
+ }
598
+ }
599
+ function injectDestroySignal() {
600
+ const ref = inject(DESTROY_REF);
601
+ if (ref.signal)
602
+ return ref.signal;
603
+ throw new Error("Active DestroyRef does not provide an AbortSignal");
604
+ }
605
+ function tokenToString(token) {
606
+ if (typeof token === "string")
607
+ return token;
608
+ if (token instanceof InjectionToken)
609
+ return token.toString();
610
+ if (typeof token === "function")
611
+ return token.name || "AnonymousClass";
612
+ return String(token);
613
+ }
614
+ function createEnvironmentInjector(providers, parent) {
615
+ let isDestroyed = false;
616
+ const flatProviders = flattenProviders(providers);
617
+ const effectiveProviders = new Map;
618
+ const multiProviders = new Map;
619
+ const instances = new Map;
620
+ const localDestroyRef = createDestroyRef();
621
+ instances.set(DESTROY_REF, localDestroyRef);
622
+ for (const p of flatProviders) {
623
+ const token = typeof p === "function" ? resolveForwardRef(p) : resolveForwardRef(p.provide);
624
+ if (typeof p !== "function" && p.multi) {
625
+ const list = multiProviders.get(token) ?? [];
626
+ list.push(p);
627
+ multiProviders.set(token, list);
628
+ } else {
629
+ effectiveProviders.set(token, p);
630
+ }
631
+ }
632
+ const injector = {
633
+ parent,
634
+ get destroyed() {
635
+ return isDestroyed;
636
+ },
637
+ runInContext(fn) {
638
+ if (isDestroyed) {
639
+ throw new Error("EnvironmentInjector has already been destroyed.");
640
+ }
641
+ return runInInjectionContext(injector, fn);
642
+ },
643
+ destroy() {
644
+ if (isDestroyed)
645
+ return;
646
+ isDestroyed = true;
647
+ localDestroyRef.destroy();
648
+ for (const inst of instances.values()) {
649
+ if (inst && typeof inst === "object" && inst !== localDestroyRef) {
650
+ if ("onDestroy" in inst && typeof inst.onDestroy === "function") {
651
+ try {
652
+ inst.onDestroy();
653
+ } catch (err) {
654
+ console.error("Error in onDestroy hook:", err);
655
+ }
656
+ }
657
+ if ("ngOnDestroy" in inst && typeof inst.ngOnDestroy === "function") {
658
+ try {
659
+ inst.ngOnDestroy();
660
+ } catch (err) {
661
+ console.error("Error in ngOnDestroy hook:", err);
662
+ }
663
+ }
664
+ }
665
+ }
666
+ instances.clear();
667
+ },
668
+ get(token, notFoundOrOptions, maybeOptions) {
669
+ if (isDestroyed) {
670
+ throw new Error("EnvironmentInjector has already been destroyed.");
671
+ }
672
+ let notFoundValue = undefined;
673
+ let flags = undefined;
674
+ if (notFoundOrOptions !== undefined && (typeof notFoundOrOptions !== "object" || notFoundOrOptions === null || !("optional" in notFoundOrOptions) && !("skipSelf" in notFoundOrOptions) && !("self" in notFoundOrOptions) && !("host" in notFoundOrOptions))) {
675
+ notFoundValue = notFoundOrOptions;
676
+ flags = maybeOptions;
677
+ } else if (notFoundOrOptions && typeof notFoundOrOptions === "object") {
678
+ flags = notFoundOrOptions;
679
+ }
680
+ const resolved = resolveForwardRef(token);
681
+ if (flags?.skipSelf) {
682
+ if (!parent) {
683
+ if (flags.optional)
684
+ return;
685
+ if (notFoundValue !== undefined)
686
+ return notFoundValue;
687
+ throw new Error(`NullInjectorError: No parent provider found for skipSelf token ${tokenToString(resolved)}`);
688
+ }
689
+ const val = parent.get(resolved, flags);
690
+ if (val === undefined && notFoundValue !== undefined)
691
+ return notFoundValue;
692
+ return val;
693
+ }
694
+ if (instances.has(resolved)) {
695
+ return instances.get(resolved);
696
+ }
697
+ if (resolved instanceof InjectionToken && instances.has(resolved.name)) {
698
+ return instances.get(resolved.name);
699
+ }
700
+ if (multiProviders.has(resolved)) {
701
+ const provs = multiProviders.get(resolved);
702
+ const results = provs.map((prov) => {
703
+ if (isValueProvider(prov))
704
+ return prov.useValue;
705
+ if (isFactoryProvider(prov))
706
+ return runInInjectionContext(injector, () => prov.useFactory());
707
+ if (isClassProvider(prov))
708
+ return runInInjectionContext(injector, () => new prov.useClass);
709
+ if (isExistingProvider(prov))
710
+ return injector.get(prov.useExisting);
711
+ return;
712
+ });
713
+ instances.set(resolved, results);
714
+ if (resolved instanceof InjectionToken) {
715
+ instances.set(resolved.name, results);
716
+ }
717
+ return results;
718
+ }
719
+ const provider = effectiveProviders.get(resolved);
720
+ if (!provider) {
721
+ if (flags?.self) {
722
+ if (flags.optional)
723
+ return;
724
+ if (notFoundValue !== undefined)
725
+ return notFoundValue;
726
+ throw new Error(`NullInjectorError: No local provider for ${tokenToString(resolved)}`);
727
+ }
728
+ if (parent) {
729
+ const fromParent = parent.get(resolved, flags);
730
+ if (fromParent !== undefined)
731
+ return fromParent;
732
+ }
733
+ if (flags?.optional)
734
+ return;
735
+ if (notFoundValue !== undefined)
736
+ return notFoundValue;
737
+ if (resolved instanceof InjectionToken && resolved.factory && !flags?.self && !flags?.skipSelf) {
738
+ const inst = resolved.factory();
739
+ instances.set(resolved, inst);
740
+ return inst;
741
+ }
742
+ if (typeof resolved === "function") {
743
+ try {
744
+ const inst = new resolved;
745
+ instances.set(resolved, inst);
746
+ return inst;
747
+ } catch {}
748
+ }
749
+ throw new Error(`NullInjectorError: No provider for ${tokenToString(resolved)}`);
750
+ }
751
+ let created;
752
+ if (typeof provider === "function") {
753
+ created = runInInjectionContext(injector, () => new provider);
754
+ } else if (isValueProvider(provider)) {
755
+ created = provider.useValue;
756
+ } else if (isFactoryProvider(provider)) {
757
+ created = runInInjectionContext(injector, () => provider.useFactory());
758
+ } else if (isClassProvider(provider)) {
759
+ created = runInInjectionContext(injector, () => new provider.useClass);
760
+ } else if (isExistingProvider(provider)) {
761
+ created = injector.get(provider.useExisting);
762
+ }
763
+ instances.set(resolved, created);
764
+ return created;
765
+ }
766
+ };
767
+ instances.set(INJECTOR, injector);
768
+ const envInitializers = injector.get(ENVIRONMENT_INITIALIZER, { optional: true });
769
+ const seenInits = new Set;
770
+ if (Array.isArray(envInitializers)) {
771
+ for (const init of envInitializers) {
772
+ if (typeof init === "function") {
773
+ seenInits.add(init);
774
+ runInInjectionContext(injector, () => {
775
+ init();
776
+ });
777
+ }
778
+ }
779
+ }
780
+ const appInitializers = injector.get(APP_INITIALIZER, { optional: true });
781
+ if (Array.isArray(appInitializers)) {
782
+ for (const init of appInitializers) {
783
+ if (typeof init === "function" && !seenInits.has(init)) {
784
+ seenInits.add(init);
785
+ runInInjectionContext(injector, () => {
786
+ init();
787
+ });
788
+ }
789
+ }
790
+ }
791
+ return injector;
792
+ }
793
+ // src/route_match.ts
794
+ function matchRoute(pattern, url, strategy = "full") {
795
+ const patternSegments = pattern.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
796
+ const cleanUrl = url.split("?")[0].replace(/^\/+|\/+$/g, "");
797
+ const urlSegments = cleanUrl.split("/").filter(Boolean);
798
+ if (strategy === "full" && patternSegments.length !== urlSegments.length) {
799
+ return { matched: false, params: {} };
800
+ }
801
+ if (strategy === "prefix" && urlSegments.length < patternSegments.length) {
802
+ return { matched: false, params: {} };
803
+ }
804
+ const params = {};
805
+ for (let i = 0;i < patternSegments.length; i += 1) {
806
+ const p = patternSegments[i];
807
+ const u = urlSegments[i];
808
+ if (p.startsWith(":")) {
809
+ const paramName = p.slice(1);
810
+ params[paramName] = decodeURIComponent(u);
811
+ } else if (p !== u) {
812
+ return { matched: false, params: {} };
813
+ }
814
+ }
815
+ const remainingSegments = urlSegments.slice(patternSegments.length);
816
+ const remainingUrl = remainingSegments.length > 0 ? `/${remainingSegments.join("/")}` : undefined;
817
+ return {
818
+ matched: true,
819
+ params,
820
+ remainingUrl
821
+ };
822
+ }
823
+ // src/interceptor.ts
824
+ function withInterceptors(...interceptors) {
825
+ return interceptors.flat();
826
+ }
827
+ function createBearerAuthInterceptor(tokenOrGetter) {
828
+ return async (req, next) => {
829
+ const token = typeof tokenOrGetter === "function" ? await tokenOrGetter() : tokenOrGetter;
830
+ if (token) {
831
+ req.headers = {
832
+ ...req.headers,
833
+ authorization: `Bearer ${token}`
834
+ };
835
+ }
836
+ return next(req);
837
+ };
838
+ }
839
+ function createHeaderInterceptor(headers) {
840
+ return async (req, next) => {
841
+ const custom = typeof headers === "function" ? await headers() : headers;
842
+ req.headers = {
843
+ ...req.headers,
844
+ ...custom
845
+ };
846
+ return next(req);
847
+ };
848
+ }
849
+ function createTimeoutInterceptor(timeoutMs) {
850
+ return async (req, next) => {
851
+ let timer;
852
+ const timeoutPromise = new Promise((_, reject) => {
853
+ timer = setTimeout(() => {
854
+ reject(new Error(`HTTP request timed out after ${timeoutMs}ms: ${req.method} ${req.url}`));
855
+ }, timeoutMs);
856
+ });
857
+ try {
858
+ return await Promise.race([next(req), timeoutPromise]);
859
+ } finally {
860
+ if (timer)
861
+ clearTimeout(timer);
862
+ }
863
+ };
864
+ }
865
+ function createRetryInterceptor(maxRetries, delayMs = 50) {
866
+ return async (req, next) => {
867
+ let lastError;
868
+ for (let attempt = 0;attempt <= maxRetries; attempt++) {
869
+ try {
870
+ const res = await next(req);
871
+ if (res.ok || attempt === maxRetries)
872
+ return res;
873
+ } catch (err) {
874
+ lastError = err;
875
+ if (attempt === maxRetries)
876
+ throw err;
877
+ }
878
+ if (delayMs > 0) {
879
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
880
+ }
881
+ }
882
+ throw lastError;
883
+ };
884
+ }
885
+ // src/signal.ts
886
+ var activeConsumer = null;
887
+ var isTrackingEnabled = true;
888
+ function signal(initialValue) {
889
+ let value = initialValue;
890
+ const subscribers = new Set;
891
+ const read = () => {
892
+ if (isTrackingEnabled && activeConsumer) {
893
+ subscribers.add(activeConsumer);
894
+ }
895
+ return value;
896
+ };
897
+ read.set = (newValue) => {
898
+ if (!Object.is(value, newValue)) {
899
+ value = newValue;
900
+ for (const notify of [...subscribers]) {
901
+ notify();
902
+ }
903
+ }
904
+ };
905
+ read.update = (updateFn) => {
906
+ read.set(updateFn(value));
907
+ };
908
+ read.asReadonly = () => () => read();
909
+ return read;
910
+ }
911
+ function computed(computation) {
912
+ let cachedValue;
913
+ let isDirty = true;
914
+ const subscribers = new Set;
915
+ const recompute = () => {
916
+ if (!isDirty) {
917
+ isDirty = true;
918
+ for (const notify of [...subscribers]) {
919
+ notify();
920
+ }
921
+ }
922
+ };
923
+ return () => {
924
+ if (isTrackingEnabled && activeConsumer) {
925
+ subscribers.add(activeConsumer);
926
+ }
927
+ if (isDirty) {
928
+ const prevConsumer = activeConsumer;
929
+ activeConsumer = recompute;
930
+ try {
931
+ cachedValue = computation();
932
+ isDirty = false;
933
+ } finally {
934
+ activeConsumer = prevConsumer;
935
+ }
936
+ }
937
+ return cachedValue;
938
+ };
939
+ }
940
+ function effect(effectFn) {
941
+ let cleanup;
942
+ let isDestroyed = false;
943
+ const run = () => {
944
+ if (isDestroyed)
945
+ return;
946
+ if (typeof cleanup === "function") {
947
+ cleanup();
948
+ }
949
+ const prevConsumer = activeConsumer;
950
+ activeConsumer = run;
951
+ try {
952
+ cleanup = effectFn();
953
+ } finally {
954
+ activeConsumer = prevConsumer;
955
+ }
956
+ };
957
+ run();
958
+ return () => {
959
+ isDestroyed = true;
960
+ if (typeof cleanup === "function") {
961
+ cleanup();
962
+ }
963
+ };
964
+ }
965
+ function untracked(fn) {
966
+ const prevTracking = isTrackingEnabled;
967
+ isTrackingEnabled = false;
968
+ try {
969
+ return fn();
970
+ } finally {
971
+ isTrackingEnabled = prevTracking;
972
+ }
973
+ }
974
+ function linkedSignal(computationOrOptions, shorthandOptions) {
975
+ let sourceFn;
976
+ let computationFn;
977
+ let equalFn;
978
+ if (typeof computationOrOptions === "function") {
979
+ sourceFn = computationOrOptions;
980
+ computationFn = (s) => s;
981
+ equalFn = shorthandOptions?.equal ?? Object.is;
982
+ } else {
983
+ sourceFn = computationOrOptions.source;
984
+ computationFn = computationOrOptions.computation;
985
+ equalFn = computationOrOptions.equal ?? Object.is;
986
+ }
987
+ let currentValue;
988
+ let hasValue = false;
989
+ let previousRecord = undefined;
990
+ let isDirty = true;
991
+ const subscribers = new Set;
992
+ const onSourceChanged = () => {
993
+ if (!isDirty) {
994
+ isDirty = true;
995
+ for (const notify of [...subscribers]) {
996
+ notify();
997
+ }
998
+ }
999
+ };
1000
+ const recompute = () => {
1001
+ const prevConsumer = activeConsumer;
1002
+ activeConsumer = onSourceChanged;
1003
+ let nextSource;
1004
+ try {
1005
+ nextSource = sourceFn();
1006
+ } finally {
1007
+ activeConsumer = prevConsumer;
1008
+ }
1009
+ if (hasValue && previousRecord && Object.is(nextSource, previousRecord.source)) {
1010
+ isDirty = false;
1011
+ return currentValue;
1012
+ }
1013
+ const nextValue = computationFn(nextSource, previousRecord);
1014
+ currentValue = nextValue;
1015
+ hasValue = true;
1016
+ previousRecord = { source: nextSource, value: currentValue };
1017
+ isDirty = false;
1018
+ return currentValue;
1019
+ };
1020
+ const read = () => {
1021
+ if (isTrackingEnabled && activeConsumer) {
1022
+ subscribers.add(activeConsumer);
1023
+ }
1024
+ if (isDirty || !hasValue) {
1025
+ return recompute();
1026
+ }
1027
+ return currentValue;
1028
+ };
1029
+ read.set = (newValue) => {
1030
+ if (!hasValue || isDirty) {
1031
+ recompute();
1032
+ }
1033
+ if (!equalFn(currentValue, newValue)) {
1034
+ currentValue = newValue;
1035
+ if (previousRecord) {
1036
+ previousRecord.value = newValue;
1037
+ }
1038
+ for (const notify of [...subscribers]) {
1039
+ notify();
1040
+ }
1041
+ }
1042
+ };
1043
+ read.update = (updateFn) => {
1044
+ read.set(updateFn(read()));
1045
+ };
1046
+ read.asReadonly = () => () => read();
1047
+ return read;
1048
+ }
1049
+ // src/resource.ts
1050
+ function resource(options) {
1051
+ const valueSignal = signal(options.initialValue);
1052
+ const statusSignal = signal("idle");
1053
+ const errorSignal = signal(undefined);
1054
+ const isLoadingSignal = signal(false);
1055
+ let activeAbortController = null;
1056
+ const reloadCounter = signal(0);
1057
+ let isDestroyed = false;
1058
+ const load = async (req) => {
1059
+ if (isDestroyed)
1060
+ return;
1061
+ if (activeAbortController) {
1062
+ activeAbortController.abort();
1063
+ }
1064
+ const ac = new AbortController;
1065
+ activeAbortController = ac;
1066
+ const prevStatus = statusSignal();
1067
+ statusSignal.set("loading");
1068
+ isLoadingSignal.set(true);
1069
+ errorSignal.set(undefined);
1070
+ try {
1071
+ const result = await options.loader({
1072
+ request: req,
1073
+ abortSignal: ac.signal,
1074
+ previous: { status: prevStatus }
1075
+ });
1076
+ if (!ac.signal.aborted && !isDestroyed) {
1077
+ valueSignal.set(result);
1078
+ statusSignal.set("resolved");
1079
+ isLoadingSignal.set(false);
1080
+ }
1081
+ } catch (err) {
1082
+ if (!ac.signal.aborted && !isDestroyed) {
1083
+ errorSignal.set(err);
1084
+ statusSignal.set("error");
1085
+ isLoadingSignal.set(false);
1086
+ }
1087
+ } finally {
1088
+ if (activeAbortController === ac) {
1089
+ activeAbortController = null;
1090
+ }
1091
+ }
1092
+ };
1093
+ const disposeEffect = effect(() => {
1094
+ reloadCounter();
1095
+ const req = options.request ? options.request() : undefined;
1096
+ untracked(() => {
1097
+ load(req);
1098
+ });
1099
+ });
1100
+ return {
1101
+ value: valueSignal.asReadonly(),
1102
+ status: statusSignal.asReadonly(),
1103
+ error: errorSignal.asReadonly(),
1104
+ isLoading: isLoadingSignal.asReadonly(),
1105
+ reload() {
1106
+ reloadCounter.update((c) => c + 1);
1107
+ },
1108
+ set(newVal) {
1109
+ if (activeAbortController) {
1110
+ activeAbortController.abort();
1111
+ activeAbortController = null;
1112
+ }
1113
+ valueSignal.set(newVal);
1114
+ statusSignal.set("resolved");
1115
+ errorSignal.set(undefined);
1116
+ isLoadingSignal.set(false);
1117
+ },
1118
+ update(updateFn) {
1119
+ this.set(updateFn(valueSignal()));
1120
+ },
1121
+ destroy() {
1122
+ isDestroyed = true;
1123
+ if (activeAbortController) {
1124
+ activeAbortController.abort();
1125
+ activeAbortController = null;
1126
+ }
1127
+ disposeEffect();
1128
+ }
1129
+ };
1130
+ }
1131
+ // src/title_strategy.ts
1132
+ class TitleStrategy {
1133
+ buildTitle(title, appPrefix) {
1134
+ if (!title)
1135
+ return;
1136
+ return appPrefix ? `${appPrefix} | ${title}` : title;
1137
+ }
1138
+ }
1139
+
1140
+ class DefaultTitleStrategy extends TitleStrategy {
1141
+ updateTitle(title, ctx) {
1142
+ if (!title)
1143
+ return;
1144
+ if (ctx) {
1145
+ if (!ctx.data)
1146
+ ctx.data = {};
1147
+ ctx.data.title = title;
1148
+ }
1149
+ if (typeof globalThis !== "undefined" && globalThis.document) {
1150
+ globalThis.document.title = title;
1151
+ }
1152
+ }
1153
+ }
1154
+ var TITLE_STRATEGY = new InjectionToken("supacloud.title-strategy", {
1155
+ scope: "application",
1156
+ factory: () => new DefaultTitleStrategy
173
1157
  });
174
- var DB_CLIENT = new InjectionToken("supacloud.db-client", {
175
- scope: "application"
1158
+
1159
+ // src/route_pipeline.ts
1160
+ class RedirectCommand {
1161
+ redirectTo;
1162
+ navigationExtras;
1163
+ constructor(redirectTo, navigationExtras) {
1164
+ this.redirectTo = redirectTo;
1165
+ this.navigationExtras = navigationExtras;
1166
+ }
1167
+ }
1168
+ function isRedirectCommand(val) {
1169
+ return val instanceof RedirectCommand || typeof val === "object" && val !== null && "redirectTo" in val && val.constructor?.name === "RedirectCommand";
1170
+ }
1171
+ async function executeRoutePipeline(route, ctx, componentInstance, options) {
1172
+ const emit = (type, data) => {
1173
+ if (options?.onEvent) {
1174
+ options.onEvent({
1175
+ type,
1176
+ url: ctx.url,
1177
+ timestamp: Date.now(),
1178
+ data
1179
+ });
1180
+ }
1181
+ };
1182
+ emit("NavigationStart");
1183
+ emit("RoutesRecognized", { method: route.method, path: route.path });
1184
+ if (route.canMatch && route.canMatch.length > 0) {
1185
+ emit("GuardsCheckStart", { stage: "canMatch" });
1186
+ for (const guard of route.canMatch) {
1187
+ if (typeof guard === "function") {
1188
+ const can = await guard(ctx);
1189
+ if (isRedirectCommand(can)) {
1190
+ emit("GuardsCheckEnd", { stage: "canMatch", allowed: false });
1191
+ emit("NavigationCancel", { reason: "Redirected by CanMatch guard" });
1192
+ return {
1193
+ matched: true,
1194
+ status: can.navigationExtras?.status ?? 302,
1195
+ redirect: String(can.redirectTo),
1196
+ headers: { Location: String(can.redirectTo), ...can.navigationExtras?.headers ?? {} }
1197
+ };
1198
+ }
1199
+ if (!can) {
1200
+ emit("GuardsCheckEnd", { stage: "canMatch", allowed: false });
1201
+ emit("NavigationCancel", { reason: "CanMatch guard rejected" });
1202
+ return { matched: false, status: 404, error: "Route match rejected by CanMatch guard" };
1203
+ }
1204
+ }
1205
+ }
1206
+ emit("GuardsCheckEnd", { stage: "canMatch", allowed: true });
1207
+ }
1208
+ if (route.guards && route.guards.length > 0) {
1209
+ emit("GuardsCheckStart", { stage: "canActivate" });
1210
+ for (const guard of route.guards) {
1211
+ if (typeof guard === "function") {
1212
+ const allowed = await guard(ctx);
1213
+ if (isRedirectCommand(allowed)) {
1214
+ emit("GuardsCheckEnd", { stage: "canActivate", allowed: false });
1215
+ emit("NavigationCancel", { reason: "Redirected by CanActivate guard" });
1216
+ return {
1217
+ matched: true,
1218
+ status: allowed.navigationExtras?.status ?? 302,
1219
+ redirect: String(allowed.redirectTo),
1220
+ headers: { Location: String(allowed.redirectTo), ...allowed.navigationExtras?.headers ?? {} }
1221
+ };
1222
+ }
1223
+ if (!allowed) {
1224
+ emit("GuardsCheckEnd", { stage: "canActivate", allowed: false });
1225
+ emit("NavigationCancel", { reason: "CanActivate guard rejected" });
1226
+ return { matched: true, status: 403, error: "Route activation rejected by CanActivate guard" };
1227
+ }
1228
+ }
1229
+ }
1230
+ emit("GuardsCheckEnd", { stage: "canActivate", allowed: true });
1231
+ }
1232
+ let resolvedData;
1233
+ if (route.resolvers && Object.keys(route.resolvers).length > 0) {
1234
+ emit("ResolveStart", { keys: Object.keys(route.resolvers) });
1235
+ resolvedData = await executeResolvers(route.resolvers, ctx);
1236
+ ctx.resolved = { ...ctx.resolved ?? {}, ...resolvedData };
1237
+ ctx.data = { ...ctx.data ?? {}, ...route.data ?? {}, ...resolvedData };
1238
+ emit("ResolveEnd", { keys: Object.keys(route.resolvers) });
1239
+ } else if (route.data) {
1240
+ ctx.data = { ...ctx.data ?? {}, ...route.data };
1241
+ }
1242
+ let responseBody;
1243
+ try {
1244
+ emit("ExecutionStart");
1245
+ if (route.invoker && typeof route.invoker === "function") {
1246
+ responseBody = await route.invoker(componentInstance, ctx);
1247
+ } else if (componentInstance && typeof route.handler === "string" && typeof componentInstance[route.handler] === "function") {
1248
+ responseBody = await componentInstance[route.handler](ctx);
1249
+ } else if (typeof route.handler === "function") {
1250
+ responseBody = await route.handler(ctx);
1251
+ } else {
1252
+ throw new Error(`Handler '${String(route.handler)}' is not executable on component instance.`);
1253
+ }
1254
+ if (isRedirectCommand(responseBody)) {
1255
+ emit("ExecutionEnd");
1256
+ return {
1257
+ matched: true,
1258
+ status: responseBody.navigationExtras?.status ?? 302,
1259
+ redirect: String(responseBody.redirectTo),
1260
+ headers: { Location: String(responseBody.redirectTo), ...responseBody.navigationExtras?.headers ?? {} },
1261
+ resolvedData
1262
+ };
1263
+ }
1264
+ emit("ExecutionEnd");
1265
+ } catch (err) {
1266
+ const errorMsg = err instanceof Error ? err.message : String(err);
1267
+ emit("NavigationError", { error: errorMsg });
1268
+ return {
1269
+ matched: true,
1270
+ status: 500,
1271
+ error: errorMsg,
1272
+ resolvedData
1273
+ };
1274
+ }
1275
+ if (route.canDeactivate && route.canDeactivate.length > 0 && componentInstance) {
1276
+ emit("GuardsCheckStart", { stage: "canDeactivate" });
1277
+ for (const guard of route.canDeactivate) {
1278
+ if (typeof guard === "function") {
1279
+ const canLeave = await guard(componentInstance, ctx);
1280
+ if (!canLeave) {
1281
+ emit("GuardsCheckEnd", { stage: "canDeactivate", allowed: false });
1282
+ emit("NavigationCancel", { reason: "CanDeactivate guard rejected" });
1283
+ return {
1284
+ matched: true,
1285
+ status: 409,
1286
+ body: responseBody,
1287
+ error: "Route deactivation rejected by CanDeactivate guard",
1288
+ resolvedData
1289
+ };
1290
+ }
1291
+ }
1292
+ }
1293
+ emit("GuardsCheckEnd", { stage: "canDeactivate", allowed: true });
1294
+ }
1295
+ if (route.title) {
1296
+ const titleStrategy = options?.titleStrategy ?? new DefaultTitleStrategy;
1297
+ titleStrategy.updateTitle(route.title, ctx);
1298
+ }
1299
+ emit("NavigationEnd");
1300
+ return {
1301
+ matched: true,
1302
+ status: 200,
1303
+ body: responseBody,
1304
+ resolvedData
1305
+ };
1306
+ }
1307
+ // src/testing.ts
1308
+ class TestBed {
1309
+ static declaredProviders = [];
1310
+ static overriddenProviders = new Map;
1311
+ static activeInjector = null;
1312
+ static instances = new Map;
1313
+ static configureTestingModule(moduleDef) {
1314
+ TestBed.resetTestingModule();
1315
+ const allProviders = [...moduleDef.providers ?? []];
1316
+ if (moduleDef.imports) {
1317
+ for (const imp of moduleDef.imports) {
1318
+ if (imp && typeof imp === "object" && "providers" in imp && Array.isArray(imp.providers)) {
1319
+ allProviders.push(...imp.providers);
1320
+ }
1321
+ }
1322
+ }
1323
+ TestBed.declaredProviders = flattenProviders(allProviders);
1324
+ return TestBed;
1325
+ }
1326
+ static overrideProvider(token, provider) {
1327
+ TestBed.overriddenProviders.set(resolveForwardRef(token), provider);
1328
+ TestBed.activeInjector = null;
1329
+ return TestBed;
1330
+ }
1331
+ static inject(token, notFoundValue, flags) {
1332
+ const injector = TestBed.getOrCreateInjector();
1333
+ return runInInjectionContext(injector, () => {
1334
+ const resolved = resolveForwardRef(token);
1335
+ const val = injector.get(resolved, flags);
1336
+ if (val === undefined) {
1337
+ if (notFoundValue !== undefined)
1338
+ return notFoundValue;
1339
+ if (flags?.optional)
1340
+ return;
1341
+ throw new Error(`TestBed: No provider found for token ${String(resolved)}`);
1342
+ }
1343
+ return val;
1344
+ });
1345
+ }
1346
+ static injectAll(token) {
1347
+ const injector = TestBed.getOrCreateInjector();
1348
+ return runInInjectionContext(injector, () => {
1349
+ return injectAll(token);
1350
+ });
1351
+ }
1352
+ static run(fn) {
1353
+ const injector = TestBed.getOrCreateInjector();
1354
+ return runInInjectionContext(injector, fn);
1355
+ }
1356
+ static resetTestingModule() {
1357
+ TestBed.declaredProviders = [];
1358
+ TestBed.overriddenProviders.clear();
1359
+ TestBed.activeInjector = null;
1360
+ TestBed.instances.clear();
1361
+ return TestBed;
1362
+ }
1363
+ static getOrCreateInjector() {
1364
+ if (TestBed.activeInjector)
1365
+ return TestBed.activeInjector;
1366
+ const effectiveProviders = new Map;
1367
+ const multiProviders = new Map;
1368
+ for (const p of TestBed.declaredProviders) {
1369
+ const token = typeof p === "function" ? resolveForwardRef(p) : resolveForwardRef(p.provide);
1370
+ if (typeof p !== "function" && p.multi) {
1371
+ const list = multiProviders.get(token) ?? [];
1372
+ list.push(p);
1373
+ multiProviders.set(token, list);
1374
+ } else {
1375
+ effectiveProviders.set(token, p);
1376
+ }
1377
+ }
1378
+ for (const [token, p] of TestBed.overriddenProviders) {
1379
+ if (typeof p !== "function" && p.multi) {
1380
+ const list = multiProviders.get(token) ?? [];
1381
+ list.push(p);
1382
+ multiProviders.set(token, list);
1383
+ } else {
1384
+ effectiveProviders.set(token, p);
1385
+ multiProviders.delete(token);
1386
+ }
1387
+ }
1388
+ const instances = TestBed.instances;
1389
+ const rootInjector = {
1390
+ get(token, flags) {
1391
+ const resolved = resolveForwardRef(token);
1392
+ if (instances.has(resolved)) {
1393
+ return instances.get(resolved);
1394
+ }
1395
+ if (resolved instanceof InjectionToken && instances.has(resolved.name)) {
1396
+ return instances.get(resolved.name);
1397
+ }
1398
+ if (multiProviders.has(resolved)) {
1399
+ const providers = multiProviders.get(resolved);
1400
+ const results = providers.map((prov) => {
1401
+ if (isValueProvider(prov))
1402
+ return prov.useValue;
1403
+ if (isFactoryProvider(prov))
1404
+ return runInInjectionContext(rootInjector, () => prov.useFactory());
1405
+ if (isClassProvider(prov))
1406
+ return runInInjectionContext(rootInjector, () => new prov.useClass);
1407
+ if (isExistingProvider(prov))
1408
+ return rootInjector.get(prov.useExisting);
1409
+ return;
1410
+ });
1411
+ instances.set(resolved, results);
1412
+ if (resolved instanceof InjectionToken) {
1413
+ instances.set(resolved.name, results);
1414
+ }
1415
+ return results;
1416
+ }
1417
+ const provider = effectiveProviders.get(resolved);
1418
+ if (!provider) {
1419
+ if (flags?.optional)
1420
+ return;
1421
+ if (resolved instanceof InjectionToken && resolved.factory) {
1422
+ const inst = resolved.factory();
1423
+ instances.set(resolved, inst);
1424
+ return inst;
1425
+ }
1426
+ if (typeof resolved === "function") {
1427
+ try {
1428
+ const inst = new resolved;
1429
+ instances.set(resolved, inst);
1430
+ return inst;
1431
+ } catch {
1432
+ return;
1433
+ }
1434
+ }
1435
+ return;
1436
+ }
1437
+ let created;
1438
+ if (typeof provider === "function") {
1439
+ created = runInInjectionContext(rootInjector, () => new provider);
1440
+ } else if (isValueProvider(provider)) {
1441
+ created = provider.useValue;
1442
+ } else if (isFactoryProvider(provider)) {
1443
+ created = runInInjectionContext(rootInjector, () => provider.useFactory());
1444
+ } else if (isClassProvider(provider)) {
1445
+ created = runInInjectionContext(rootInjector, () => new provider.useClass);
1446
+ } else if (isExistingProvider(provider)) {
1447
+ created = rootInjector.get(provider.useExisting);
1448
+ }
1449
+ instances.set(resolved, created);
1450
+ return created;
1451
+ }
1452
+ };
1453
+ TestBed.activeInjector = rootInjector;
1454
+ instances.set(INJECTOR, rootInjector);
1455
+ return rootInjector;
1456
+ }
1457
+ }
1458
+ // src/route_provider.ts
1459
+ var ROUTE_CONFIG = new InjectionToken("supacloud:route-config");
1460
+ var APP_BASE_HREF = new InjectionToken("supacloud.app-base-href", {
1461
+ scope: "application",
1462
+ factory: () => "/"
176
1463
  });
1464
+ var ROUTER_CONFIGURATION = new InjectionToken("supacloud.router-configuration", {
1465
+ scope: "application",
1466
+ factory: () => ({ onSameUrlNavigation: "ignore", paramsInheritanceStrategy: "emptyOnly" })
1467
+ });
1468
+ function withComponentInputBinding() {
1469
+ return {
1470
+ kind: "componentInputBinding",
1471
+ providers: [
1472
+ {
1473
+ provide: new InjectionToken("supacloud.with-component-input-binding"),
1474
+ useValue: true
1475
+ }
1476
+ ]
1477
+ };
1478
+ }
1479
+ function withRouterConfig(options) {
1480
+ return {
1481
+ kind: "routerConfig",
1482
+ providers: [
1483
+ {
1484
+ provide: ROUTER_CONFIGURATION,
1485
+ useValue: options
1486
+ }
1487
+ ]
1488
+ };
1489
+ }
1490
+ function withTitleStrategy(strategy) {
1491
+ return {
1492
+ kind: "titleStrategy",
1493
+ providers: [
1494
+ typeof strategy === "function" ? { provide: TITLE_STRATEGY, useClass: strategy } : { provide: TITLE_STRATEGY, useValue: strategy }
1495
+ ]
1496
+ };
1497
+ }
1498
+ function provideRouter(routes, ...features) {
1499
+ const featureProviders = [];
1500
+ for (const feature of features) {
1501
+ if (feature && Array.isArray(feature.providers)) {
1502
+ featureProviders.push(...feature.providers);
1503
+ }
1504
+ }
1505
+ return makeEnvironmentProviders([
1506
+ {
1507
+ provide: ROUTE_CONFIG,
1508
+ useValue: routes
1509
+ },
1510
+ ...featureProviders
1511
+ ]);
1512
+ }
1513
+ // src/location.ts
1514
+ function normalizePath(path) {
1515
+ if (!path)
1516
+ return "/";
1517
+ const clean = path.replace(/\/+/g, "/");
1518
+ return clean.startsWith("/") ? clean : `/${clean}`;
1519
+ }
1520
+ function stripTrailingSlash(path) {
1521
+ if (!path || path === "/")
1522
+ return "/";
1523
+ return path.replace(/\/+$/, "");
1524
+ }
1525
+ function joinWithSlash(start, end) {
1526
+ if (!start)
1527
+ return end.startsWith("/") ? end : `/${end}`;
1528
+ if (!end)
1529
+ return start;
1530
+ const s = stripTrailingSlash(start);
1531
+ const e = end.startsWith("/") ? end.slice(1) : end;
1532
+ return `${s}/${e}`;
1533
+ }
1534
+ // src/transfer_state.ts
1535
+ function makeStateKey(key) {
1536
+ return key;
1537
+ }
1538
+
1539
+ class TransferState {
1540
+ store = new Map;
1541
+ get(key, defaultValue) {
1542
+ if (this.store.has(key)) {
1543
+ return this.store.get(key);
1544
+ }
1545
+ return defaultValue;
1546
+ }
1547
+ set(key, value) {
1548
+ this.store.set(key, value);
1549
+ }
1550
+ hasKey(key) {
1551
+ return this.store.has(key);
1552
+ }
1553
+ remove(key) {
1554
+ this.store.delete(key);
1555
+ }
1556
+ isEmpty() {
1557
+ return this.store.size === 0;
1558
+ }
1559
+ toJson() {
1560
+ const obj = {};
1561
+ for (const [k, v] of this.store.entries()) {
1562
+ obj[k] = v;
1563
+ }
1564
+ return JSON.stringify(obj);
1565
+ }
1566
+ static fromJson(json) {
1567
+ const state = new TransferState;
1568
+ try {
1569
+ const parsed = JSON.parse(json);
1570
+ if (parsed && typeof parsed === "object" && parsed !== null) {
1571
+ for (const [k, v] of Object.entries(parsed)) {
1572
+ state.set(k, v);
1573
+ }
1574
+ }
1575
+ } catch {}
1576
+ return state;
1577
+ }
1578
+ static fromObject(record) {
1579
+ const state = new TransferState;
1580
+ for (const [k, v] of Object.entries(record)) {
1581
+ state.set(k, v);
1582
+ }
1583
+ return state;
1584
+ }
1585
+ }
1586
+ var TRANSFER_STATE = new InjectionToken("supacloud.transfer-state", {
1587
+ scope: "application",
1588
+ factory: () => new TransferState
1589
+ });
1590
+ // src/platform.ts
1591
+ var PLATFORM_SERVER_ID = "server";
1592
+ var PLATFORM_BROWSER_ID = "browser";
1593
+ var PLATFORM_EDGE_ID = "edge";
1594
+ function detectPlatform() {
1595
+ if (typeof window !== "undefined" && typeof window.document !== "undefined") {
1596
+ return PLATFORM_BROWSER_ID;
1597
+ }
1598
+ if (typeof globalThis.EdgeRuntime === "string") {
1599
+ return PLATFORM_EDGE_ID;
1600
+ }
1601
+ return PLATFORM_SERVER_ID;
1602
+ }
1603
+ var DOCUMENT = new InjectionToken("supacloud.document", {
1604
+ scope: "application",
1605
+ factory: () => {
1606
+ if (typeof globalThis !== "undefined" && globalThis.document) {
1607
+ return globalThis.document;
1608
+ }
1609
+ return;
1610
+ }
1611
+ });
1612
+ var PLATFORM_ID = new InjectionToken("supacloud.platform-id", {
1613
+ scope: "application",
1614
+ factory: () => detectPlatform()
1615
+ });
1616
+ function isPlatformBrowser(platformId) {
1617
+ return platformId === PLATFORM_BROWSER_ID;
1618
+ }
1619
+ function isPlatformServer(platformId) {
1620
+ return platformId === PLATFORM_SERVER_ID || platformId === PLATFORM_EDGE_ID;
1621
+ }
1622
+ function isPlatformEdge(platformId) {
1623
+ return platformId === PLATFORM_EDGE_ID;
1624
+ }
1625
+ // src/http_params.ts
1626
+ class HttpParams {
1627
+ map;
1628
+ constructor(options) {
1629
+ this.map = new Map;
1630
+ if (!options)
1631
+ return;
1632
+ if (options.fromString) {
1633
+ const raw = options.fromString.startsWith("?") ? options.fromString.slice(1) : options.fromString;
1634
+ if (raw.length > 0) {
1635
+ const pairs = raw.split("&");
1636
+ for (const pair of pairs) {
1637
+ if (!pair)
1638
+ continue;
1639
+ const eqIndex = pair.indexOf("=");
1640
+ const rawKey = eqIndex >= 0 ? pair.slice(0, eqIndex) : pair;
1641
+ const rawVal = eqIndex >= 0 ? pair.slice(eqIndex + 1) : "";
1642
+ const key = decodeURIComponent(rawKey.replace(/\+/g, " "));
1643
+ const val = decodeURIComponent(rawVal.replace(/\+/g, " "));
1644
+ const existing = this.map.get(key) ?? [];
1645
+ existing.push(val);
1646
+ this.map.set(key, existing);
1647
+ }
1648
+ }
1649
+ }
1650
+ if (options.fromObject) {
1651
+ for (const [key, val] of Object.entries(options.fromObject)) {
1652
+ if (val === undefined || val === null)
1653
+ continue;
1654
+ if (Array.isArray(val)) {
1655
+ this.map.set(key, val.map((v) => String(v)));
1656
+ } else {
1657
+ this.map.set(key, [String(val)]);
1658
+ }
1659
+ }
1660
+ }
1661
+ }
1662
+ clone(newMap) {
1663
+ const clone = new HttpParams;
1664
+ for (const [k, v] of newMap.entries()) {
1665
+ clone.map.set(k, [...v]);
1666
+ }
1667
+ return clone;
1668
+ }
1669
+ has(param) {
1670
+ return this.map.has(param);
1671
+ }
1672
+ get(param) {
1673
+ const values = this.map.get(param);
1674
+ return values && values.length > 0 ? values[0] : null;
1675
+ }
1676
+ getAll(param) {
1677
+ const values = this.map.get(param);
1678
+ return values ? [...values] : null;
1679
+ }
1680
+ keys() {
1681
+ return Array.from(this.map.keys());
1682
+ }
1683
+ set(param, value) {
1684
+ const newMap = new Map(this.map);
1685
+ newMap.set(param, [String(value)]);
1686
+ return this.clone(newMap);
1687
+ }
1688
+ append(param, value) {
1689
+ const newMap = new Map(this.map);
1690
+ const existing = newMap.get(param) ? [...newMap.get(param)] : [];
1691
+ existing.push(String(value));
1692
+ newMap.set(param, existing);
1693
+ return this.clone(newMap);
1694
+ }
1695
+ delete(param, value) {
1696
+ if (!this.map.has(param))
1697
+ return this;
1698
+ const newMap = new Map(this.map);
1699
+ if (value === undefined) {
1700
+ newMap.delete(param);
1701
+ } else {
1702
+ const target = String(value);
1703
+ const existing = newMap.get(param).filter((v) => v !== target);
1704
+ if (existing.length === 0) {
1705
+ newMap.delete(param);
1706
+ } else {
1707
+ newMap.set(param, existing);
1708
+ }
1709
+ }
1710
+ return this.clone(newMap);
1711
+ }
1712
+ toString() {
1713
+ const parts = [];
1714
+ for (const [key, values] of this.map.entries()) {
1715
+ const encodedKey = encodeURIComponent(key);
1716
+ for (const val of values) {
1717
+ parts.push(`${encodedKey}=${encodeURIComponent(val)}`);
1718
+ }
1719
+ }
1720
+ return parts.join("&");
1721
+ }
1722
+ }
1723
+ // src/http_headers.ts
1724
+ class HttpHeaders {
1725
+ headersMap;
1726
+ originalNames;
1727
+ constructor(headers) {
1728
+ this.headersMap = new Map;
1729
+ this.originalNames = new Map;
1730
+ if (!headers)
1731
+ return;
1732
+ if (headers instanceof HttpHeaders) {
1733
+ for (const [k, v] of headers.headersMap.entries()) {
1734
+ this.headersMap.set(k, [...v]);
1735
+ this.originalNames.set(k, headers.originalNames.get(k) ?? k);
1736
+ }
1737
+ return;
1738
+ }
1739
+ for (const [key, value] of Object.entries(headers)) {
1740
+ if (value === undefined || value === null)
1741
+ continue;
1742
+ const lower = key.toLowerCase();
1743
+ this.originalNames.set(lower, key);
1744
+ if (Array.isArray(value)) {
1745
+ this.headersMap.set(lower, [...value]);
1746
+ } else {
1747
+ this.headersMap.set(lower, [String(value)]);
1748
+ }
1749
+ }
1750
+ }
1751
+ clone(newMap, newNames) {
1752
+ const clone = new HttpHeaders;
1753
+ for (const [k, v] of newMap.entries()) {
1754
+ clone.headersMap.set(k, [...v]);
1755
+ }
1756
+ for (const [k, v] of newNames.entries()) {
1757
+ clone.originalNames.set(k, v);
1758
+ }
1759
+ return clone;
1760
+ }
1761
+ has(name) {
1762
+ return this.headersMap.has(name.toLowerCase());
1763
+ }
1764
+ get(name) {
1765
+ const values = this.headersMap.get(name.toLowerCase());
1766
+ return values && values.length > 0 ? values[0] : null;
1767
+ }
1768
+ getAll(name) {
1769
+ const values = this.headersMap.get(name.toLowerCase());
1770
+ return values ? [...values] : null;
1771
+ }
1772
+ keys() {
1773
+ return Array.from(this.originalNames.values());
1774
+ }
1775
+ set(name, value) {
1776
+ const lower = name.toLowerCase();
1777
+ const newMap = new Map(this.headersMap);
1778
+ const newNames = new Map(this.originalNames);
1779
+ const valArray = Array.isArray(value) ? [...value] : [String(value)];
1780
+ newMap.set(lower, valArray);
1781
+ newNames.set(lower, name);
1782
+ return this.clone(newMap, newNames);
1783
+ }
1784
+ append(name, value) {
1785
+ const lower = name.toLowerCase();
1786
+ const newMap = new Map(this.headersMap);
1787
+ const newNames = new Map(this.originalNames);
1788
+ const existing = newMap.get(lower) ? [...newMap.get(lower)] : [];
1789
+ if (Array.isArray(value)) {
1790
+ existing.push(...value);
1791
+ } else {
1792
+ existing.push(String(value));
1793
+ }
1794
+ newMap.set(lower, existing);
1795
+ if (!newNames.has(lower)) {
1796
+ newNames.set(lower, name);
1797
+ }
1798
+ return this.clone(newMap, newNames);
1799
+ }
1800
+ delete(name) {
1801
+ const lower = name.toLowerCase();
1802
+ if (!this.headersMap.has(lower))
1803
+ return this;
1804
+ const newMap = new Map(this.headersMap);
1805
+ const newNames = new Map(this.originalNames);
1806
+ newMap.delete(lower);
1807
+ newNames.delete(lower);
1808
+ return this.clone(newMap, newNames);
1809
+ }
1810
+ toObject() {
1811
+ const result = {};
1812
+ for (const [lower, values] of this.headersMap.entries()) {
1813
+ const originalName = this.originalNames.get(lower) ?? lower;
1814
+ result[originalName] = values.join(", ");
1815
+ }
1816
+ return result;
1817
+ }
1818
+ }
1819
+ // src/http_context.ts
1820
+ class HttpContextToken {
1821
+ defaultValue;
1822
+ constructor(defaultValue) {
1823
+ this.defaultValue = defaultValue;
1824
+ }
1825
+ }
1826
+
1827
+ class HttpContext {
1828
+ map = new Map;
1829
+ set(token, value) {
1830
+ this.map.set(token, value);
1831
+ return this;
1832
+ }
1833
+ get(token) {
1834
+ if (this.map.has(token)) {
1835
+ return this.map.get(token);
1836
+ }
1837
+ return token.defaultValue();
1838
+ }
1839
+ delete(token) {
1840
+ this.map.delete(token);
1841
+ return this;
1842
+ }
1843
+ has(token) {
1844
+ return this.map.has(token);
1845
+ }
1846
+ keys() {
1847
+ return this.map.keys();
1848
+ }
1849
+ }
1850
+ // src/http_client.ts
1851
+ var HTTP_CLIENT_CONFIG = new InjectionToken("HTTP_CLIENT_CONFIG", { scope: "application", factory: () => ({}) });
1852
+ var HTTP_INTERCEPTORS = new InjectionToken("HTTP_INTERCEPTORS", { scope: "application", factory: () => [] });
1853
+
1854
+ class HttpErrorResponse extends Error {
1855
+ status;
1856
+ statusText;
1857
+ url;
1858
+ error;
1859
+ constructor(init) {
1860
+ super(`Http failure response for ${init.url ?? "unknown"}: ${init.status ?? 0} ${init.statusText ?? "Unknown Error"}`);
1861
+ this.name = "HttpErrorResponse";
1862
+ this.status = init.status ?? 0;
1863
+ this.statusText = init.statusText ?? "Unknown Error";
1864
+ this.url = init.url ?? null;
1865
+ this.error = init.error ?? null;
1866
+ }
1867
+ }
1868
+ function withFetch(customFetch) {
1869
+ return {
1870
+ kind: "Fetch",
1871
+ providers: [
1872
+ {
1873
+ provide: HTTP_CLIENT_CONFIG,
1874
+ useFactory: () => ({ fetch: customFetch ?? (typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : undefined) })
1875
+ }
1876
+ ]
1877
+ };
1878
+ }
1879
+ function withRequestsMadeViaParent() {
1880
+ return {
1881
+ kind: "ParentRequests",
1882
+ providers: []
1883
+ };
1884
+ }
1885
+ function provideHttpClient(...features) {
1886
+ const providers = [
1887
+ HttpClient
1888
+ ];
1889
+ for (const feature of features) {
1890
+ providers.push(...feature.providers);
1891
+ }
1892
+ return makeEnvironmentProviders(providers);
1893
+ }
1894
+
1895
+ class HttpClient {
1896
+ config;
1897
+ interceptors;
1898
+ constructor(config, interceptors) {
1899
+ if (config) {
1900
+ this.config = config;
1901
+ } else {
1902
+ try {
1903
+ this.config = inject(HTTP_CLIENT_CONFIG, { optional: true }) ?? {};
1904
+ } catch {
1905
+ this.config = {};
1906
+ }
1907
+ }
1908
+ if (interceptors) {
1909
+ this.interceptors = [...interceptors];
1910
+ } else {
1911
+ try {
1912
+ const resolved = injectAll(HTTP_INTERCEPTORS);
1913
+ this.interceptors = resolved.flat();
1914
+ } catch {
1915
+ this.interceptors = [];
1916
+ }
1917
+ }
1918
+ }
1919
+ get(url, options) {
1920
+ return this.request("GET", url, options);
1921
+ }
1922
+ post(url, body, options) {
1923
+ return this.request("POST", url, { ...options, body });
1924
+ }
1925
+ put(url, body, options) {
1926
+ return this.request("PUT", url, { ...options, body });
1927
+ }
1928
+ delete(url, options) {
1929
+ return this.request("DELETE", url, options);
1930
+ }
1931
+ patch(url, body, options) {
1932
+ return this.request("PATCH", url, { ...options, body });
1933
+ }
1934
+ async request(method, url, options) {
1935
+ let targetUrl = url;
1936
+ if (this.config.baseUrl && !/^https?:\/\//i.test(targetUrl)) {
1937
+ const base = this.config.baseUrl.endsWith("/") ? this.config.baseUrl.slice(0, -1) : this.config.baseUrl;
1938
+ const rel = targetUrl.startsWith("/") ? targetUrl : `/${targetUrl}`;
1939
+ targetUrl = `${base}${rel}`;
1940
+ }
1941
+ if (options?.params) {
1942
+ const params = options.params instanceof HttpParams ? options.params : new HttpParams({ fromObject: options.params });
1943
+ const qs = params.toString();
1944
+ if (qs.length > 0) {
1945
+ targetUrl += targetUrl.includes("?") ? `&${qs}` : `?${qs}`;
1946
+ }
1947
+ }
1948
+ let headers = {};
1949
+ if (options?.headers) {
1950
+ if (options.headers instanceof HttpHeaders) {
1951
+ headers = options.headers.toObject();
1952
+ } else {
1953
+ for (const [k, v] of Object.entries(options.headers)) {
1954
+ if (v !== undefined && v !== null) {
1955
+ headers[k] = Array.isArray(v) ? v.join(", ") : String(v);
1956
+ }
1957
+ }
1958
+ }
1959
+ }
1960
+ let body = options?.body;
1961
+ if (body !== undefined && body !== null && typeof body === "object" && !(body instanceof FormData) && !(body instanceof Blob) && !(body instanceof URLSearchParams) && !(body instanceof ArrayBuffer)) {
1962
+ body = JSON.stringify(body);
1963
+ const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
1964
+ if (!hasContentType) {
1965
+ headers["content-type"] = "application/json";
1966
+ }
1967
+ }
1968
+ const payload = {
1969
+ method: method.toUpperCase(),
1970
+ url: targetUrl,
1971
+ headers,
1972
+ body,
1973
+ context: options?.context
1974
+ };
1975
+ const fetchFn = this.config.fetch ?? (typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : undefined);
1976
+ if (!fetchFn) {
1977
+ throw new Error("No fetch implementation available. Provide withFetch() in provideHttpClient or run in an environment with global fetch.");
1978
+ }
1979
+ const finalHandler = async (req) => {
1980
+ return fetchFn(req.url, {
1981
+ method: req.method,
1982
+ headers: req.headers,
1983
+ body: req.body ?? undefined,
1984
+ signal: options?.signal
1985
+ });
1986
+ };
1987
+ const pipeline = this.interceptors.reduceRight((next, interceptor) => (req) => interceptor(req, next), finalHandler);
1988
+ const response = await pipeline(payload);
1989
+ if (options?.observe === "response") {
1990
+ return response;
1991
+ }
1992
+ if (!response.ok) {
1993
+ let errorBody;
1994
+ try {
1995
+ errorBody = await response.json();
1996
+ } catch {
1997
+ try {
1998
+ errorBody = await response.text();
1999
+ } catch {
2000
+ errorBody = null;
2001
+ }
2002
+ }
2003
+ throw new HttpErrorResponse({
2004
+ url: response.url || targetUrl,
2005
+ status: response.status,
2006
+ statusText: response.statusText,
2007
+ error: errorBody
2008
+ });
2009
+ }
2010
+ if (options?.responseType === "text") {
2011
+ return await response.text();
2012
+ }
2013
+ if (options?.responseType === "blob") {
2014
+ return await response.blob();
2015
+ }
2016
+ const contentType = response.headers?.get("content-type") ?? "";
2017
+ if (contentType.includes("application/json")) {
2018
+ return await response.json();
2019
+ }
2020
+ const text = await response.text();
2021
+ try {
2022
+ return JSON.parse(text);
2023
+ } catch {
2024
+ return text;
2025
+ }
2026
+ }
2027
+ }
2028
+ HttpClient = __legacyDecorateClassTS([
2029
+ Injectable({ providedIn: "root" })
2030
+ ], HttpClient);
2031
+ // src/url_tree.ts
2032
+ class UrlSegmentGroup {
2033
+ segments;
2034
+ children;
2035
+ parent = null;
2036
+ constructor(segments, children = {}) {
2037
+ this.segments = segments;
2038
+ this.children = children;
2039
+ for (const child of Object.values(children)) {
2040
+ child.parent = this;
2041
+ }
2042
+ }
2043
+ hasChildren() {
2044
+ return Object.keys(this.children).length > 0;
2045
+ }
2046
+ }
2047
+
2048
+ class UrlTree {
2049
+ root;
2050
+ queryParams;
2051
+ fragment;
2052
+ constructor(root, queryParams = {}, fragment = null) {
2053
+ this.root = root;
2054
+ this.queryParams = queryParams;
2055
+ this.fragment = fragment;
2056
+ }
2057
+ get queryParamMap() {
2058
+ return new Map(Object.entries(this.queryParams));
2059
+ }
2060
+ toString() {
2061
+ return new DefaultUrlSerializer().serialize(this);
2062
+ }
2063
+ }
2064
+
2065
+ class UrlSerializer {
2066
+ }
2067
+
2068
+ class DefaultUrlSerializer {
2069
+ parse(url) {
2070
+ let remaining = url.trim();
2071
+ let fragment = null;
2072
+ const fragIndex = remaining.indexOf("#");
2073
+ if (fragIndex >= 0) {
2074
+ fragment = decodeURIComponent(remaining.slice(fragIndex + 1));
2075
+ remaining = remaining.slice(0, fragIndex);
2076
+ }
2077
+ const queryParams = {};
2078
+ const queryIndex = remaining.indexOf("?");
2079
+ if (queryIndex >= 0) {
2080
+ const rawQuery = remaining.slice(queryIndex + 1);
2081
+ remaining = remaining.slice(0, queryIndex);
2082
+ if (rawQuery.length > 0) {
2083
+ for (const pair of rawQuery.split("&")) {
2084
+ if (!pair)
2085
+ continue;
2086
+ const eq = pair.indexOf("=");
2087
+ const rawKey = eq >= 0 ? pair.slice(0, eq) : pair;
2088
+ const rawVal = eq >= 0 ? pair.slice(eq + 1) : "";
2089
+ queryParams[decodeURIComponent(rawKey.replace(/\+/g, " "))] = decodeURIComponent(rawVal.replace(/\+/g, " "));
2090
+ }
2091
+ }
2092
+ }
2093
+ const rawSegments = remaining.split("/").filter((s) => s.length > 0);
2094
+ const segments = [];
2095
+ for (const rawSeg of rawSegments) {
2096
+ const matrixParts = rawSeg.split(";");
2097
+ const path = decodeURIComponent(matrixParts[0]);
2098
+ const parameters = {};
2099
+ for (let i = 1;i < matrixParts.length; i++) {
2100
+ const part = matrixParts[i];
2101
+ if (!part)
2102
+ continue;
2103
+ const eq = part.indexOf("=");
2104
+ const pKey = eq >= 0 ? part.slice(0, eq) : part;
2105
+ const pVal = eq >= 0 ? part.slice(eq + 1) : "";
2106
+ parameters[decodeURIComponent(pKey)] = decodeURIComponent(pVal);
2107
+ }
2108
+ segments.push({ path, parameters });
2109
+ }
2110
+ const root = new UrlSegmentGroup(segments);
2111
+ return new UrlTree(root, queryParams, fragment);
2112
+ }
2113
+ serialize(tree) {
2114
+ const segmentStrings = [];
2115
+ for (const seg of tree.root.segments) {
2116
+ let segStr = encodeURIComponent(seg.path);
2117
+ const paramKeys = Object.keys(seg.parameters).sort();
2118
+ for (const pk of paramKeys) {
2119
+ segStr += `;${encodeURIComponent(pk)}=${encodeURIComponent(seg.parameters[pk])}`;
2120
+ }
2121
+ segmentStrings.push(segStr);
2122
+ }
2123
+ let path = "/" + segmentStrings.join("/");
2124
+ if (segmentStrings.length === 0) {
2125
+ path = "/";
2126
+ }
2127
+ const qKeys = Object.keys(tree.queryParams).sort();
2128
+ if (qKeys.length > 0) {
2129
+ const qParts = qKeys.map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(tree.queryParams[k])}`);
2130
+ path += `?${qParts.join("&")}`;
2131
+ }
2132
+ if (tree.fragment !== null && tree.fragment !== undefined) {
2133
+ path += `#${encodeURIComponent(tree.fragment)}`;
2134
+ }
2135
+ return path;
2136
+ }
2137
+ }
2138
+ // src/forms.ts
2139
+ class AbstractControl {
2140
+ _value;
2141
+ _status = "VALID";
2142
+ _errors = null;
2143
+ _pristine = true;
2144
+ _touched = false;
2145
+ _parent = null;
2146
+ _validator = null;
2147
+ _asyncValidator = null;
2148
+ constructor(validatorOrOpts, asyncValidator) {
2149
+ if (validatorOrOpts && typeof validatorOrOpts === "object" && !Array.isArray(validatorOrOpts) && (("validators" in validatorOrOpts) || ("asyncValidators" in validatorOrOpts))) {
2150
+ const opts = validatorOrOpts;
2151
+ this._validator = Validators.compose(opts.validators ? Array.isArray(opts.validators) ? opts.validators : [opts.validators] : null);
2152
+ this._asyncValidator = Validators.composeAsync(opts.asyncValidators ? Array.isArray(opts.asyncValidators) ? opts.asyncValidators : [opts.asyncValidators] : null);
2153
+ } else {
2154
+ const v = validatorOrOpts;
2155
+ this._validator = Validators.compose(v ? Array.isArray(v) ? v : [v] : null);
2156
+ this._asyncValidator = Validators.composeAsync(asyncValidator ? Array.isArray(asyncValidator) ? asyncValidator : [asyncValidator] : null);
2157
+ }
2158
+ }
2159
+ get value() {
2160
+ return this._value;
2161
+ }
2162
+ setRawValue(val) {
2163
+ this._value = val;
2164
+ }
2165
+ get status() {
2166
+ return this._status;
2167
+ }
2168
+ get valid() {
2169
+ return this._status === "VALID";
2170
+ }
2171
+ get invalid() {
2172
+ return this._status === "INVALID";
2173
+ }
2174
+ get pending() {
2175
+ return this._status === "PENDING";
2176
+ }
2177
+ get disabled() {
2178
+ return this._status === "DISABLED";
2179
+ }
2180
+ get enabled() {
2181
+ return this._status !== "DISABLED";
2182
+ }
2183
+ get errors() {
2184
+ return this._errors;
2185
+ }
2186
+ get pristine() {
2187
+ return this._pristine;
2188
+ }
2189
+ get dirty() {
2190
+ return !this._pristine;
2191
+ }
2192
+ get touched() {
2193
+ return this._touched;
2194
+ }
2195
+ get untouched() {
2196
+ return !this._touched;
2197
+ }
2198
+ get parent() {
2199
+ return this._parent;
2200
+ }
2201
+ setParent(parent) {
2202
+ this._parent = parent;
2203
+ }
2204
+ markAsTouched() {
2205
+ this._touched = true;
2206
+ }
2207
+ markAsUntouched() {
2208
+ this._touched = false;
2209
+ }
2210
+ markAsDirty() {
2211
+ this._pristine = false;
2212
+ if (this._parent)
2213
+ this._parent.markAsDirty();
2214
+ }
2215
+ markAsPristine() {
2216
+ this._pristine = true;
2217
+ }
2218
+ disable() {
2219
+ this._status = "DISABLED";
2220
+ this._errors = null;
2221
+ if (this._parent)
2222
+ this._parent.updateValueAndValidity();
2223
+ }
2224
+ enable() {
2225
+ this._status = "VALID";
2226
+ this.updateValueAndValidity();
2227
+ }
2228
+ setErrors(errors) {
2229
+ this._errors = errors;
2230
+ this._status = errors ? "INVALID" : "VALID";
2231
+ }
2232
+ hasError(errorCode, path) {
2233
+ return this.getError(errorCode, path) !== null;
2234
+ }
2235
+ getError(errorCode, path) {
2236
+ const control = path ? this.get(path) : this;
2237
+ if (!control || !control._errors)
2238
+ return null;
2239
+ return control._errors[errorCode] ?? null;
2240
+ }
2241
+ get(_path) {
2242
+ return null;
2243
+ }
2244
+ updateValueAndValidity() {
2245
+ if (this.disabled) {
2246
+ this._status = "DISABLED";
2247
+ this._errors = null;
2248
+ return;
2249
+ }
2250
+ if (this._validator) {
2251
+ this._errors = this._validator(this);
2252
+ } else {
2253
+ this._errors = null;
2254
+ }
2255
+ this._status = this._errors ? "INVALID" : "VALID";
2256
+ if (this._status === "VALID" && this._asyncValidator) {
2257
+ this._status = "PENDING";
2258
+ this._asyncValidator(this).then((errors) => {
2259
+ if (this._status === "PENDING") {
2260
+ this.setErrors(errors);
2261
+ }
2262
+ });
2263
+ }
2264
+ if (this._parent) {
2265
+ this._parent.updateValueAndValidity();
2266
+ }
2267
+ }
2268
+ }
2269
+
2270
+ class FormControl extends AbstractControl {
2271
+ constructor(formState, validatorOrOpts, asyncValidator) {
2272
+ super(validatorOrOpts, asyncValidator);
2273
+ if (formState && typeof formState === "object" && "value" in formState && "disabled" in formState) {
2274
+ this.setRawValue(formState.value);
2275
+ if (formState.disabled) {
2276
+ this.disable();
2277
+ } else {
2278
+ this.updateValueAndValidity();
2279
+ }
2280
+ } else {
2281
+ this.setRawValue(formState);
2282
+ this.updateValueAndValidity();
2283
+ }
2284
+ }
2285
+ setValue(value) {
2286
+ this.setRawValue(value);
2287
+ this.markAsDirty();
2288
+ this.updateValueAndValidity();
2289
+ }
2290
+ patchValue(value) {
2291
+ this.setValue(value);
2292
+ }
2293
+ reset(formState) {
2294
+ this.setRawValue(formState !== undefined ? formState : null);
2295
+ this.markAsPristine();
2296
+ this.markAsUntouched();
2297
+ this.updateValueAndValidity();
2298
+ }
2299
+ }
2300
+
2301
+ class FormGroup extends AbstractControl {
2302
+ controls;
2303
+ constructor(controls, validatorOrOpts, asyncValidator) {
2304
+ super(validatorOrOpts, asyncValidator);
2305
+ this.controls = controls;
2306
+ for (const ctrl of Object.values(controls)) {
2307
+ ctrl.setParent(this);
2308
+ }
2309
+ this.updateValueAndValidity();
2310
+ }
2311
+ get value() {
2312
+ const res = {};
2313
+ for (const [key, ctrl] of Object.entries(this.controls)) {
2314
+ res[key] = ctrl.value;
2315
+ }
2316
+ return res;
2317
+ }
2318
+ get(path) {
2319
+ const parts = Array.isArray(path) ? path : path.split(".");
2320
+ let current = this;
2321
+ for (const part of parts) {
2322
+ if (!current)
2323
+ return null;
2324
+ if (current instanceof FormGroup) {
2325
+ current = current.controls[String(part)] ?? null;
2326
+ } else if (current instanceof FormArray) {
2327
+ current = current.at(Number(part)) ?? null;
2328
+ } else {
2329
+ return null;
2330
+ }
2331
+ }
2332
+ return current;
2333
+ }
2334
+ addControl(name, control) {
2335
+ this.controls[name] = control;
2336
+ control.setParent(this);
2337
+ this.updateValueAndValidity();
2338
+ }
2339
+ removeControl(name) {
2340
+ const ctrl = this.controls[name];
2341
+ if (ctrl) {
2342
+ ctrl.setParent(null);
2343
+ delete this.controls[name];
2344
+ this.updateValueAndValidity();
2345
+ }
2346
+ }
2347
+ setControl(name, control) {
2348
+ this.removeControl(name);
2349
+ this.addControl(name, control);
2350
+ }
2351
+ contains(name) {
2352
+ return Boolean(this.controls[name]);
2353
+ }
2354
+ setValue(value) {
2355
+ for (const [key, val] of Object.entries(value)) {
2356
+ if (this.controls[key]) {
2357
+ this.controls[key].setValue(val);
2358
+ }
2359
+ }
2360
+ this.markAsDirty();
2361
+ }
2362
+ patchValue(value) {
2363
+ for (const [key, val] of Object.entries(value)) {
2364
+ if (this.controls[key] && val !== undefined) {
2365
+ this.controls[key].patchValue(val);
2366
+ }
2367
+ }
2368
+ this.markAsDirty();
2369
+ }
2370
+ reset() {
2371
+ for (const ctrl of Object.values(this.controls)) {
2372
+ ctrl.reset();
2373
+ }
2374
+ this.markAsPristine();
2375
+ this.markAsUntouched();
2376
+ }
2377
+ updateValueAndValidity() {
2378
+ if (this.disabled) {
2379
+ this.setErrors(null);
2380
+ return;
2381
+ }
2382
+ let hasInvalid = false;
2383
+ let hasPending = false;
2384
+ for (const ctrl of Object.values(this.controls)) {
2385
+ if (ctrl.invalid)
2386
+ hasInvalid = true;
2387
+ if (ctrl.pending)
2388
+ hasPending = true;
2389
+ }
2390
+ if (hasInvalid) {
2391
+ this.setErrors({ invalidChildren: true });
2392
+ } else if (hasPending) {
2393
+ this._status = "PENDING";
2394
+ } else {
2395
+ super.updateValueAndValidity();
2396
+ }
2397
+ }
2398
+ }
2399
+
2400
+ class FormArray extends AbstractControl {
2401
+ controls;
2402
+ constructor(controls = [], validatorOrOpts, asyncValidator) {
2403
+ super(validatorOrOpts, asyncValidator);
2404
+ this.controls = controls;
2405
+ for (const ctrl of controls) {
2406
+ ctrl.setParent(this);
2407
+ }
2408
+ this.updateValueAndValidity();
2409
+ }
2410
+ get length() {
2411
+ return this.controls.length;
2412
+ }
2413
+ at(index) {
2414
+ return this.controls[index] ?? null;
2415
+ }
2416
+ push(control) {
2417
+ this.controls.push(control);
2418
+ control.setParent(this);
2419
+ this.updateValueAndValidity();
2420
+ }
2421
+ insert(index, control) {
2422
+ this.controls.splice(index, 0, control);
2423
+ control.setParent(this);
2424
+ this.updateValueAndValidity();
2425
+ }
2426
+ removeAt(index) {
2427
+ if (index >= 0 && index < this.controls.length) {
2428
+ this.controls[index].setParent(null);
2429
+ this.controls.splice(index, 1);
2430
+ this.updateValueAndValidity();
2431
+ }
2432
+ }
2433
+ clear() {
2434
+ for (const ctrl of this.controls) {
2435
+ ctrl.setParent(null);
2436
+ }
2437
+ this.controls.length = 0;
2438
+ this.updateValueAndValidity();
2439
+ }
2440
+ get value() {
2441
+ return this.controls.map((c) => c.value);
2442
+ }
2443
+ setValue(value) {
2444
+ value.forEach((val, i) => {
2445
+ if (this.controls[i])
2446
+ this.controls[i].setValue(val);
2447
+ });
2448
+ this.markAsDirty();
2449
+ }
2450
+ patchValue(value) {
2451
+ value.forEach((val, i) => {
2452
+ if (this.controls[i] && val !== undefined)
2453
+ this.controls[i].patchValue(val);
2454
+ });
2455
+ this.markAsDirty();
2456
+ }
2457
+ reset() {
2458
+ for (const ctrl of this.controls)
2459
+ ctrl.reset();
2460
+ this.markAsPristine();
2461
+ this.markAsUntouched();
2462
+ }
2463
+ updateValueAndValidity() {
2464
+ if (this.disabled) {
2465
+ this.setErrors(null);
2466
+ return;
2467
+ }
2468
+ let hasInvalid = false;
2469
+ let hasPending = false;
2470
+ for (const ctrl of this.controls) {
2471
+ if (ctrl.invalid)
2472
+ hasInvalid = true;
2473
+ if (ctrl.pending)
2474
+ hasPending = true;
2475
+ }
2476
+ if (hasInvalid) {
2477
+ this.setErrors({ invalidChildren: true });
2478
+ } else if (hasPending) {
2479
+ this._status = "PENDING";
2480
+ } else {
2481
+ super.updateValueAndValidity();
2482
+ }
2483
+ }
2484
+ }
2485
+
2486
+ class Validators {
2487
+ static nullValidator(_control) {
2488
+ return null;
2489
+ }
2490
+ static required(control) {
2491
+ const val = control.value;
2492
+ if (val === null || val === undefined || val === "" || Array.isArray(val) && val.length === 0) {
2493
+ return { required: true };
2494
+ }
2495
+ return null;
2496
+ }
2497
+ static requiredTrue(control) {
2498
+ return control.value === true ? null : { required: true };
2499
+ }
2500
+ static min(min) {
2501
+ return (control) => {
2502
+ const val = control.value;
2503
+ if (val === null || val === undefined || val === "")
2504
+ return null;
2505
+ const num = Number(val);
2506
+ return !Number.isNaN(num) && num < min ? { min: { min, actual: val } } : null;
2507
+ };
2508
+ }
2509
+ static max(max) {
2510
+ return (control) => {
2511
+ const val = control.value;
2512
+ if (val === null || val === undefined || val === "")
2513
+ return null;
2514
+ const num = Number(val);
2515
+ return !Number.isNaN(num) && num > max ? { max: { max, actual: val } } : null;
2516
+ };
2517
+ }
2518
+ static minLength(minLength) {
2519
+ return (control) => {
2520
+ const val = control.value;
2521
+ if (val === null || val === undefined)
2522
+ return null;
2523
+ const length = typeof val === "string" || Array.isArray(val) ? val.length : 0;
2524
+ return length < minLength ? { minlength: { requiredLength: minLength, actualLength: length } } : null;
2525
+ };
2526
+ }
2527
+ static maxLength(maxLength) {
2528
+ return (control) => {
2529
+ const val = control.value;
2530
+ if (val === null || val === undefined)
2531
+ return null;
2532
+ const length = typeof val === "string" || Array.isArray(val) ? val.length : 0;
2533
+ return length > maxLength ? { maxlength: { requiredLength: maxLength, actualLength: length } } : null;
2534
+ };
2535
+ }
2536
+ static email(control) {
2537
+ const val = control.value;
2538
+ if (!val)
2539
+ return null;
2540
+ const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
2541
+ return typeof val === "string" && emailRegex.test(val) ? null : { email: true };
2542
+ }
2543
+ static pattern(pattern) {
2544
+ const regex = typeof pattern === "string" ? new RegExp(`^${pattern}$`) : pattern;
2545
+ return (control) => {
2546
+ const val = control.value;
2547
+ if (!val)
2548
+ return null;
2549
+ return regex.test(String(val)) ? null : { pattern: { requiredPattern: String(pattern), actualValue: val } };
2550
+ };
2551
+ }
2552
+ static compose(validators) {
2553
+ if (!validators)
2554
+ return null;
2555
+ const present = validators.filter((v) => typeof v === "function");
2556
+ if (present.length === 0)
2557
+ return null;
2558
+ return (control) => {
2559
+ const errors = {};
2560
+ let hasErrors = false;
2561
+ for (const fn of present) {
2562
+ const err = fn(control);
2563
+ if (err) {
2564
+ Object.assign(errors, err);
2565
+ hasErrors = true;
2566
+ }
2567
+ }
2568
+ return hasErrors ? errors : null;
2569
+ };
2570
+ }
2571
+ static composeAsync(validators) {
2572
+ if (!validators)
2573
+ return null;
2574
+ const present = validators.filter((v) => typeof v === "function");
2575
+ if (present.length === 0)
2576
+ return null;
2577
+ return async (control) => {
2578
+ const results = await Promise.all(present.map((fn) => fn(control)));
2579
+ const errors = {};
2580
+ let hasErrors = false;
2581
+ for (const err of results) {
2582
+ if (err) {
2583
+ Object.assign(errors, err);
2584
+ hasErrors = true;
2585
+ }
2586
+ }
2587
+ return hasErrors ? errors : null;
2588
+ };
2589
+ }
2590
+ }
2591
+ // src/input_transform.ts
2592
+ function booleanAttribute(value) {
2593
+ if (typeof value === "boolean") {
2594
+ return value;
2595
+ }
2596
+ if (value === null || value === undefined) {
2597
+ return false;
2598
+ }
2599
+ if (typeof value === "string") {
2600
+ return value !== "false";
2601
+ }
2602
+ return Boolean(value);
2603
+ }
2604
+ function numberAttribute(value, fallbackValue = NaN) {
2605
+ const isNumber = typeof value === "number";
2606
+ const isString = typeof value === "string";
2607
+ if (!isNumber && !isString) {
2608
+ return fallbackValue;
2609
+ }
2610
+ const parsed = isNumber ? value : parseFloat(value);
2611
+ return isNaN(parsed) ? fallbackValue : parsed;
2612
+ }
2613
+ // src/pipe.ts
2614
+ var PIPE_METADATA_KEY = Symbol.for("supacloud.pipe");
2615
+ function Pipe(options) {
2616
+ return (target) => {
2617
+ const meta = {
2618
+ pure: true,
2619
+ standalone: true,
2620
+ ...options
2621
+ };
2622
+ if (typeof Reflect !== "undefined" && typeof Reflect.defineMetadata === "function") {
2623
+ Reflect.defineMetadata(PIPE_METADATA_KEY, meta, target);
2624
+ }
2625
+ target[PIPE_METADATA_KEY] = meta;
2626
+ };
2627
+ }
2628
+ function getPipeMetadata(target) {
2629
+ if (!target)
2630
+ return;
2631
+ if (typeof Reflect !== "undefined" && typeof Reflect.getMetadata === "function") {
2632
+ const meta = Reflect.getMetadata(PIPE_METADATA_KEY, target);
2633
+ if (meta)
2634
+ return meta;
2635
+ }
2636
+ return target[PIPE_METADATA_KEY];
2637
+ }
2638
+
2639
+ class UpperCasePipe {
2640
+ transform(value) {
2641
+ return value != null ? String(value).toUpperCase() : "";
2642
+ }
2643
+ }
2644
+ UpperCasePipe = __legacyDecorateClassTS([
2645
+ Pipe({ name: "uppercase", pure: true })
2646
+ ], UpperCasePipe);
2647
+
2648
+ class LowerCasePipe {
2649
+ transform(value) {
2650
+ return value != null ? String(value).toLowerCase() : "";
2651
+ }
2652
+ }
2653
+ LowerCasePipe = __legacyDecorateClassTS([
2654
+ Pipe({ name: "lowercase", pure: true })
2655
+ ], LowerCasePipe);
2656
+
2657
+ class TrimPipe {
2658
+ transform(value) {
2659
+ return value != null ? String(value).trim() : "";
2660
+ }
2661
+ }
2662
+ TrimPipe = __legacyDecorateClassTS([
2663
+ Pipe({ name: "trim", pure: true })
2664
+ ], TrimPipe);
2665
+
2666
+ class JsonPipe {
2667
+ transform(value, space = 2) {
2668
+ return JSON.stringify(value, null, space);
2669
+ }
2670
+ }
2671
+ JsonPipe = __legacyDecorateClassTS([
2672
+ Pipe({ name: "json", pure: true })
2673
+ ], JsonPipe);
2674
+
2675
+ class DatePipe {
2676
+ transform(value, format = "iso") {
2677
+ if (!value)
2678
+ return "";
2679
+ const d = new Date(value);
2680
+ if (isNaN(d.getTime()))
2681
+ return "";
2682
+ return format === "iso" ? d.toISOString() : d.toLocaleString();
2683
+ }
2684
+ }
2685
+ DatePipe = __legacyDecorateClassTS([
2686
+ Pipe({ name: "date", pure: true })
2687
+ ], DatePipe);
177
2688
  export {
2689
+ APP_BASE_HREF,
2690
+ APP_INITIALIZER,
2691
+ AbstractControl,
2692
+ Body,
2693
+ CAN_DEACTIVATE_METADATA,
178
2694
  COMMAND_METADATA,
179
2695
  CONTROLLER_METADATA,
2696
+ CanDeactivate,
180
2697
  Command,
181
2698
  Controller,
182
2699
  DB_CLIENT,
183
2700
  DEFAULT_SCOPE,
2701
+ DESTROY_REF,
2702
+ DOCUMENT,
2703
+ Data,
2704
+ DatePipe,
2705
+ DefaultTitleStrategy,
2706
+ DefaultUrlSerializer,
184
2707
  Delete,
2708
+ ENVIRONMENT_INITIALIZER,
2709
+ FormArray,
2710
+ FormControl,
2711
+ FormGroup,
2712
+ GUARDS_METADATA,
185
2713
  Get,
2714
+ HOST_PARAMS_METADATA,
2715
+ HTTP_CLIENT_CONFIG,
2716
+ HTTP_INTERCEPTORS,
186
2717
  Head,
2718
+ Headers,
2719
+ Host,
2720
+ HttpClient,
2721
+ HttpContext,
2722
+ HttpContextToken,
2723
+ HttpErrorResponse,
2724
+ HttpHeaders,
2725
+ HttpParams,
187
2726
  INJECTABLE_METADATA,
2727
+ INJECTOR,
188
2728
  INJECT_PARAMS_METADATA,
189
2729
  Inject,
190
2730
  Injectable,
191
2731
  InjectionToken,
192
2732
  JOB_CONTEXT,
2733
+ JsonPipe,
2734
+ LowerCasePipe,
193
2735
  MODULE_METADATA,
194
2736
  Module,
2737
+ OPTIONAL_PARAMS_METADATA,
2738
+ Optional,
195
2739
  Options,
2740
+ PLATFORM_BROWSER_ID,
2741
+ PLATFORM_EDGE_ID,
2742
+ PLATFORM_ID,
2743
+ PLATFORM_SERVER_ID,
2744
+ Param,
196
2745
  Patch,
2746
+ Pipe,
197
2747
  Post,
198
2748
  Put,
199
2749
  QUERY_METADATA,
200
2750
  Query,
201
2751
  REQUEST_CONTEXT,
2752
+ RESOLVE_METADATA,
2753
+ ROUTER_CONFIGURATION,
202
2754
  ROUTES_METADATA,
2755
+ ROUTE_CONFIG,
2756
+ ROUTE_PARAMS_METADATA,
2757
+ RedirectCommand,
2758
+ Resolve,
203
2759
  SCOPES,
204
2760
  SCOPE_LIFETIME_RANK,
2761
+ SELF_PARAMS_METADATA,
2762
+ SKIP_SELF_PARAMS_METADATA,
2763
+ Self,
2764
+ SkipSelf,
2765
+ TITLE_STRATEGY,
2766
+ TRANSFER_STATE,
2767
+ TestBed,
2768
+ Title,
2769
+ TitleStrategy,
2770
+ TransferState,
2771
+ TrimPipe,
2772
+ UpperCasePipe,
2773
+ UrlSegmentGroup,
2774
+ UrlSerializer,
2775
+ UrlTree,
2776
+ UseGuards,
2777
+ Validators,
2778
+ assertInInjectionContext,
2779
+ booleanAttribute,
2780
+ computed,
2781
+ createBearerAuthInterceptor,
2782
+ createChildInjector,
2783
+ createDestroyRef,
2784
+ createEnvironmentInjector,
2785
+ createHeaderInterceptor,
2786
+ createRetryInterceptor,
2787
+ createTimeoutInterceptor,
205
2788
  defineModule,
2789
+ detectPlatform,
2790
+ effect,
2791
+ executeResolvers,
2792
+ executeRoutePipeline,
2793
+ flattenProviders,
2794
+ forwardRef,
2795
+ getActiveInjector,
206
2796
  getCommandMeta,
207
2797
  getControllerMeta,
2798
+ getGuards,
2799
+ getHostParams,
208
2800
  getInjectParams,
209
2801
  getInjectableMeta,
210
2802
  getModuleMeta,
2803
+ getOptionalParams,
2804
+ getPipeMetadata,
211
2805
  getQueryMeta,
2806
+ getRouteParams,
212
2807
  getRoutes,
2808
+ getSelfParams,
2809
+ getSkipSelfParams,
2810
+ inject,
2811
+ injectAll,
2812
+ injectDestroySignal,
213
2813
  isClassProvider,
2814
+ isEnvironmentProviders,
214
2815
  isExistingProvider,
215
2816
  isFactoryProvider,
2817
+ isForwardRef,
2818
+ isPlatformBrowser,
2819
+ isPlatformEdge,
2820
+ isPlatformServer,
2821
+ isRedirectCommand,
216
2822
  isScopeViolation,
217
- isValueProvider
2823
+ isValueProvider,
2824
+ joinWithSlash,
2825
+ linkedSignal,
2826
+ makeEnvironmentProviders,
2827
+ makeStateKey,
2828
+ matchRoute,
2829
+ normalizePath,
2830
+ numberAttribute,
2831
+ provideAppInitializer,
2832
+ provideEnvironmentInitializer,
2833
+ provideHttpClient,
2834
+ provideRouter,
2835
+ provideToken,
2836
+ resolveForwardRef,
2837
+ resource,
2838
+ runInInjectionContext,
2839
+ signal,
2840
+ stripTrailingSlash,
2841
+ untracked,
2842
+ withComponentInputBinding,
2843
+ withFetch,
2844
+ withInterceptors,
2845
+ withRequestsMadeViaParent,
2846
+ withRouterConfig,
2847
+ withTitleStrategy
218
2848
  };