@supacloud/app 0.5.0 → 0.6.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/README.md CHANGED
@@ -8,6 +8,44 @@ SupaCloud compiler (`@supacloud/compiler`) reads that metadata from source,
8
8
  validates the dependency graph and generates plain static factories — there is
9
9
  no runtime reflection and no `reflect-metadata` dependency.
10
10
 
11
+ Runtime DI delegates to Angular's public `@angular/core` APIs through a small
12
+ compatibility adapter. SupaCloud decorators retain module/compiler metadata,
13
+ while production application factories remain compiler-generated and
14
+ reflection-free.
15
+
16
+ ## Runtime Boundary
17
+
18
+ Angular is the runtime DI engine: `InjectionToken`, hierarchical injectors,
19
+ `inject()`, `DestroyRef`, provider caching and lifecycle execution are delegated
20
+ to Angular public APIs. SupaCloud does not reimplement those mechanisms.
21
+
22
+ SupaCloud still owns the application model that Angular does not define:
23
+ `Module`, `Scope`, provider descriptors, controllers, commands, jobs, route
24
+ metadata, static aspects, `ApplicationGraph` and compiler diagnostics. Use
25
+ SupaCloud decorators for these semantics; they are compiler input, not Angular
26
+ decorator aliases.
27
+
28
+ ## Static AOP
29
+
30
+ Use one `around(context, next)` function for cross-cutting behavior at the
31
+ module, route, command, or job boundary:
32
+
33
+ ```ts
34
+ const auditAspect = async (context, next) => {
35
+ const result = await next();
36
+ await audit.write(context, result);
37
+ return result;
38
+ };
39
+
40
+ @Module({ name: "case", aspects: [auditAspect] })
41
+ export class CaseModule {}
42
+ ```
43
+
44
+ Aspect references must be explicit function identifiers. The compiler rejects
45
+ variables, spread expressions, strings, dynamic pointcuts, Proxy, and runtime
46
+ aspect registration. Angular remains the DI runtime; aspects are SupaCloud
47
+ compiler metadata and generated execution order.
48
+
11
49
  ```ts
12
50
  import {
13
51
  Command,
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Static application aspect contract.
3
+ *
4
+ * Aspects are explicit functions referenced by Module/Route/Command metadata.
5
+ * The compiler resolves those references and emits a direct invocation chain.
6
+ */
7
+ export type AspectKind = "route" | "command" | "job";
8
+ export interface AspectContext {
9
+ kind: AspectKind;
10
+ name: string;
11
+ input: unknown;
12
+ request?: Request;
13
+ requestContext?: unknown;
14
+ scope?: Record<string, unknown>;
15
+ services?: Record<string, unknown>;
16
+ metadata?: unknown;
17
+ }
18
+ export type AspectNext<TResult = unknown> = () => TResult | Promise<TResult>;
19
+ export type Aspect<TResult = unknown> = (context: AspectContext, next: AspectNext<TResult>) => TResult | Promise<TResult>;
20
+ export type RouteAspect = Aspect;
21
+ export type CommandAspect = Aspect;
22
+ export type JobAspect = Aspect;
@@ -1,6 +1,7 @@
1
- import type { Provider, Token, Type } from "./provider";
1
+ import type { Provider, ProviderDep, Token, Type } from "./provider";
2
2
  import type { EnvironmentProviders } from "./provider";
3
3
  import type { Scope } from "./scope";
4
+ import type { Aspect } from "./aspect";
4
5
  /**
5
6
  * Decorator metadata keys. Metadata is attached as static properties on the
6
7
  * decorated class so the SupaCloud compiler can read it from the AST *and*
@@ -9,6 +10,7 @@ import type { Scope } from "./scope";
9
10
  export declare const INJECTABLE_METADATA = "supacloud:injectable";
10
11
  export declare const MODULE_METADATA = "supacloud:module";
11
12
  export declare const COMMAND_METADATA = "supacloud:command";
13
+ export declare const JOB_METADATA = "supacloud:job";
12
14
  export declare const QUERY_METADATA = "supacloud:query";
13
15
  export declare const CONTROLLER_METADATA = "supacloud:controller";
14
16
  export declare const ROUTES_METADATA = "supacloud:routes";
@@ -40,12 +42,12 @@ export interface InjectableOptions {
40
42
  /** Automatically provide this service in root scope without manual module declaration (Angular-style). */
41
43
  providedIn?: "root";
42
44
  /** Explicit constructor dependency tokens, in parameter order. */
43
- deps?: Token[];
45
+ deps?: ProviderDep[];
44
46
  }
45
47
  export interface InjectableMeta {
46
48
  scope: Scope;
47
49
  providedIn?: "root";
48
- deps: Token[];
50
+ deps: ProviderDep[];
49
51
  }
50
52
  export interface ModuleOptions {
51
53
  name: string;
@@ -55,11 +57,15 @@ export interface ModuleOptions {
55
57
  providers?: Array<Provider | EnvironmentProviders>;
56
58
  controllers?: Array<Type<unknown>>;
57
59
  commands?: Array<Type<unknown>>;
60
+ jobs?: Array<Type<unknown>>;
58
61
  queries?: Array<Type<unknown>>;
62
+ /** Explicit static aspects applied to every route and command in this module. */
63
+ aspects?: Aspect[];
59
64
  exports?: Token[];
60
65
  }
61
- export interface ModuleMeta extends Required<Omit<ModuleOptions, "exports" | "tags">> {
66
+ export interface ModuleMeta extends Required<Omit<ModuleOptions, "exports" | "tags" | "aspects">> {
62
67
  tags?: string[];
68
+ aspects: Aspect[];
63
69
  exports: Token[];
64
70
  }
65
71
  export interface CommandOptions {
@@ -74,7 +80,15 @@ export interface CommandOptions {
74
80
  idempotency?: "required" | "none";
75
81
  /** Automatically discover and register without manual module declaration. */
76
82
  standalone?: boolean;
83
+ /** Explicit static aspects applied around this command invocation. */
84
+ aspects?: Aspect[];
77
85
  }
86
+ export interface JobOptions {
87
+ name: string;
88
+ /** Explicit static aspects applied around this job invocation. */
89
+ aspects?: Aspect[];
90
+ }
91
+ export type JobMeta = JobOptions;
78
92
  export type CommandMeta = Omit<CommandOptions, "transaction" | "idempotency"> & {
79
93
  transaction: "required" | "none";
80
94
  idempotency: "required" | "none";
@@ -124,6 +138,8 @@ export interface RouteOptions {
124
138
  title?: string;
125
139
  /** Static route metadata dictionary (modeled after Angular Route.data). */
126
140
  data?: Record<string, unknown>;
141
+ /** Explicit static aspects applied around this route invocation. */
142
+ aspects?: Aspect[];
127
143
  }
128
144
  export interface RouteDefinition extends RouteOptions {
129
145
  method: HttpMethod;
@@ -174,6 +190,8 @@ export declare function Module(options: ModuleOptions): ClassDecorator;
174
190
  export declare function getModuleMeta(target: object): ModuleMeta | undefined;
175
191
  export declare function Command(options: CommandOptions): ClassDecorator;
176
192
  export declare function getCommandMeta(target: object): CommandMeta | undefined;
193
+ export declare function Job(options: JobOptions): ClassDecorator;
194
+ export declare function getJobMeta(target: object): JobMeta | undefined;
177
195
  export declare function Param(nameOrOptions?: string | ParamOptions, options?: ParamOptions): ParameterDecorator;
178
196
  export declare function Body(): ParameterDecorator;
179
197
  export declare function Headers(name?: string): ParameterDecorator;
package/dist/forms.d.ts CHANGED
@@ -15,11 +15,12 @@ export interface AbstractControlOptions {
15
15
  */
16
16
  export declare abstract class AbstractControl<TValue = any> {
17
17
  private _value;
18
- private _status;
19
- private _errors;
18
+ protected _status: FormControlStatus;
19
+ protected _errors: ValidationErrors | null;
20
20
  private _pristine;
21
21
  private _touched;
22
22
  private _parent;
23
+ private _validationRun;
23
24
  protected _validator: ValidatorFn | null;
24
25
  protected _asyncValidator: AsyncValidatorFn | null;
25
26
  constructor(validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
@@ -45,6 +46,7 @@ export declare abstract class AbstractControl<TValue = any> {
45
46
  disable(): void;
46
47
  enable(): void;
47
48
  setErrors(errors: ValidationErrors | null): void;
49
+ protected cancelPendingValidation(): void;
48
50
  hasError(errorCode: string, path?: string | (string | number)[]): boolean;
49
51
  getError(errorCode: string, path?: string | (string | number)[]): unknown;
50
52
  abstract setValue(value: any): void;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  export { SCOPES, DEFAULT_SCOPE, SCOPE_LIFETIME_RANK, isScopeViolation } from "./scope";
2
2
  export type { Scope } from "./scope";
3
+ export type { Aspect, AspectContext, AspectKind, AspectNext, CommandAspect, JobAspect, RouteAspect, } from "./aspect";
3
4
  export { InjectionToken } from "./token";
4
5
  export type { InjectionTokenOptions } from "./token";
5
6
  export { flattenProviders, isEnvironmentProviders, isClassProvider, isExistingProvider, isFactoryProvider, isValueProvider, makeEnvironmentProviders, provideAppInitializer, provideEnvironmentInitializer, provideToken, } from "./provider";
6
- export type { ClassProvider, EnvironmentProviders, ExistingProvider, FactoryProvider, Provider, Token, Type, ValueProvider, } from "./provider";
7
- export { Body, CanDeactivate, Command, Controller, Data, Delete, Get, Head, Headers, Host, Inject, Injectable, Module, Optional, Options, Param, Patch, Post, Put, Query, Resolve, Self, SkipSelf, Title, UseGuards, executeResolvers, getCommandMeta, getControllerMeta, getGuards, getHostParams, getInjectParams, getOptionalParams, getRouteParams, getSelfParams, getSkipSelfParams, getInjectableMeta, getModuleMeta, getQueryMeta, getRoutes, COMMAND_METADATA, CONTROLLER_METADATA, GUARDS_METADATA, CAN_DEACTIVATE_METADATA, HOST_PARAMS_METADATA, INJECTABLE_METADATA, INJECT_PARAMS_METADATA, RESOLVE_METADATA, OPTIONAL_PARAMS_METADATA, ROUTE_PARAMS_METADATA, SELF_PARAMS_METADATA, SKIP_SELF_PARAMS_METADATA, MODULE_METADATA, QUERY_METADATA, ROUTES_METADATA, } from "./decorators";
8
- export type { CanActivateFn, CanDeactivateFn, CanMatchFn, CommandMeta, CommandOptions, ControllerMeta, ControllerOptions, HttpMethod, InjectableMeta, InjectableOptions, ModuleMeta, ModuleOptions, ParamOptions, QueryMeta, QueryOptions, ResolveFn, RouteDefinition, RouteOptions, RouteParamBinding, } from "./decorators";
7
+ export type { ClassProvider, EnvironmentProviders, ExistingProvider, FactoryProvider, Provider, ProviderDep, ProviderDependency, Token, Type, ValueProvider, } from "./provider";
8
+ export { Body, CanDeactivate, Command, Controller, Data, Delete, Get, Head, Headers, Host, Inject, Injectable, Job, Module, Optional, Options, Param, Patch, Post, Put, Query, Resolve, Self, SkipSelf, Title, UseGuards, executeResolvers, getCommandMeta, getJobMeta, getControllerMeta, getGuards, getHostParams, getInjectParams, getOptionalParams, getRouteParams, getSelfParams, getSkipSelfParams, getInjectableMeta, getModuleMeta, getQueryMeta, getRoutes, COMMAND_METADATA, JOB_METADATA, CONTROLLER_METADATA, GUARDS_METADATA, CAN_DEACTIVATE_METADATA, HOST_PARAMS_METADATA, INJECTABLE_METADATA, INJECT_PARAMS_METADATA, RESOLVE_METADATA, OPTIONAL_PARAMS_METADATA, ROUTE_PARAMS_METADATA, SELF_PARAMS_METADATA, SKIP_SELF_PARAMS_METADATA, MODULE_METADATA, QUERY_METADATA, ROUTES_METADATA, } from "./decorators";
9
+ export type { CanActivateFn, CanDeactivateFn, CanMatchFn, CommandMeta, CommandOptions, JobMeta, JobOptions, ControllerMeta, ControllerOptions, HttpMethod, InjectableMeta, InjectableOptions, ModuleMeta, ModuleOptions, ParamOptions, QueryMeta, QueryOptions, ResolveFn, RouteDefinition, RouteOptions, RouteParamBinding, } from "./decorators";
9
10
  export { defineModule } from "./module";
10
11
  export { APP_INITIALIZER, DB_CLIENT, DESTROY_REF, ENVIRONMENT_INITIALIZER, JOB_CONTEXT, REQUEST_CONTEXT, createDestroyRef, } from "./context";
11
12
  export type { DestroyRef, OnDestroy } from "./context";