@supacloud/compiler 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/README.md +29 -1
- package/dist/analyze.d.ts +5 -5
- package/dist/cli.js +2343 -148
- package/dist/compile.d.ts +2 -2
- package/dist/generate.d.ts +15 -0
- package/dist/incremental.d.ts +30 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +2180 -92
- package/dist/inspect.d.ts +21 -0
- package/dist/types.d.ts +153 -20
- package/dist/util.d.ts +11 -7
- package/dist/validate.d.ts +6 -2
- package/dist/watch.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ApplicationGraph, Diagnostic } from "./types";
|
|
2
|
+
export interface DoctorResult {
|
|
3
|
+
checks: Array<{
|
|
4
|
+
name: string;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
detail: string;
|
|
7
|
+
}>;
|
|
8
|
+
diagnostics: ApplicationGraph["diagnostics"];
|
|
9
|
+
errors: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function formatGraph(graph: ApplicationGraph): string;
|
|
12
|
+
export declare function explainGraph(graph: ApplicationGraph, subject: string): string;
|
|
13
|
+
export declare function doctorProject(rootDir: string, outDir: string, graph: ApplicationGraph, upToDate: boolean, diagnostics?: Diagnostic[]): DoctorResult;
|
|
14
|
+
/**
|
|
15
|
+
* Exports the application module architecture as a Mermaid graph diagram.
|
|
16
|
+
*/
|
|
17
|
+
export declare function exportGraphMermaid(graph: ApplicationGraph): string;
|
|
18
|
+
/**
|
|
19
|
+
* Exports the application module architecture as a Graphviz DOT script.
|
|
20
|
+
*/
|
|
21
|
+
export declare function exportGraphDot(graph: ApplicationGraph): string;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ApplicationGraph
|
|
3
|
-
*
|
|
2
|
+
* ApplicationGraph: Static application graph built by the compiler from source AST.
|
|
3
|
+
* No runtime reflection or container; all metadata is explicitly represented here and in generated code.
|
|
4
4
|
*/
|
|
5
5
|
export type Scope = "application" | "request" | "job";
|
|
6
6
|
export type ProviderKind = "class" | "value" | "factory" | "existing";
|
|
@@ -11,9 +11,15 @@ export interface Diagnostic {
|
|
|
11
11
|
message: string;
|
|
12
12
|
file?: string;
|
|
13
13
|
line?: number;
|
|
14
|
+
/** Actionable Angular Ivy-style remediation hint. */
|
|
15
|
+
suggestion?: string;
|
|
16
|
+
/** Standardized compiler diagnostic code (e.g. SC1001) modeled after Angular ngtsc error codes. */
|
|
17
|
+
errorCode?: string;
|
|
18
|
+
/** Documentation URL for this diagnostic. */
|
|
19
|
+
docsUrl?: string;
|
|
14
20
|
}
|
|
15
21
|
export interface ProviderNode {
|
|
16
|
-
/**
|
|
22
|
+
/** Token name (InjectionToken variable name or class name). */
|
|
17
23
|
token: string;
|
|
18
24
|
tokenKind: TokenKind;
|
|
19
25
|
kind: ProviderKind;
|
|
@@ -22,14 +28,35 @@ export interface ProviderNode {
|
|
|
22
28
|
useFactoryName?: string;
|
|
23
29
|
useExisting?: string;
|
|
24
30
|
scope: Scope;
|
|
25
|
-
/**
|
|
31
|
+
/** Token names in constructor/factory parameter order. */
|
|
26
32
|
deps: string[];
|
|
33
|
+
/** Parameter tokens that are marked @Optional() (receive undefined if unresolved). */
|
|
34
|
+
optionalDeps?: string[];
|
|
35
|
+
/** Parameter tokens marked @Self() (must be resolved from current module's own providers). */
|
|
36
|
+
selfDeps?: string[];
|
|
37
|
+
/** Parameter tokens marked @SkipSelf() (must NOT be resolved from current module's own providers). */
|
|
38
|
+
skipSelfDeps?: string[];
|
|
39
|
+
/** Parameter tokens marked @Host(). */
|
|
40
|
+
hostDeps?: string[];
|
|
41
|
+
/** When true, multiple providers can contribute to this token as an array of instances (Angular multi-providers). */
|
|
42
|
+
multi?: boolean;
|
|
43
|
+
/** Automatically provided in the root injector context without manual module declaration (Angular-style). */
|
|
44
|
+
providedIn?: "root";
|
|
45
|
+
/** Class implements OnDestroy interface or onDestroy method. */
|
|
46
|
+
hasOnDestroy?: boolean;
|
|
27
47
|
exported: boolean;
|
|
28
48
|
file: string;
|
|
29
49
|
line: number;
|
|
30
|
-
/** useClass/useFactory/useValue
|
|
50
|
+
/** Relative module path of useClass/useFactory/useValue symbol (for import generation). */
|
|
31
51
|
importPath?: string;
|
|
32
52
|
}
|
|
53
|
+
export interface HandlerParamNode {
|
|
54
|
+
name: string;
|
|
55
|
+
kind: "param" | "query" | "body" | "headers" | "context" | "unknown";
|
|
56
|
+
bindingName?: string;
|
|
57
|
+
transform?: "number" | "boolean" | "string";
|
|
58
|
+
default?: unknown;
|
|
59
|
+
}
|
|
33
60
|
export interface RouteNode {
|
|
34
61
|
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
|
|
35
62
|
path: string;
|
|
@@ -40,16 +67,56 @@ export interface RouteNode {
|
|
|
40
67
|
response?: string;
|
|
41
68
|
/** @Command-decorated class explicitly bound by the route. */
|
|
42
69
|
command?: string;
|
|
70
|
+
/** Route guards executed before handler (Angular CanActivateFn style). */
|
|
71
|
+
guards?: string[];
|
|
72
|
+
/** Route matching guards executed before route activation (Angular CanMatchFn style). */
|
|
73
|
+
canMatch?: string[];
|
|
74
|
+
/** Route deactivation guards executed before leaving route (Angular CanDeactivateFn style). */
|
|
75
|
+
canDeactivate?: string[];
|
|
76
|
+
/** Route resolvers executed before handler (Angular ResolveFn style). */
|
|
77
|
+
resolvers?: Record<string, string>;
|
|
78
|
+
/** Route redirect target (Angular Router style). */
|
|
79
|
+
redirectTo?: string;
|
|
80
|
+
/** Route redirect matching rule (Angular Router style). */
|
|
81
|
+
pathMatch?: "full" | "prefix";
|
|
82
|
+
/** Path parameters parsed from route path (e.g. :id -> 'id'). */
|
|
83
|
+
pathParams?: string[];
|
|
84
|
+
/** Handler method parameter bindings declared via @Param('name'). */
|
|
85
|
+
paramBindings?: string[];
|
|
86
|
+
/** Handler method query bindings declared via @Query('name'). */
|
|
87
|
+
queryBindings?: string[];
|
|
88
|
+
/** Handler method has @Body() binding. */
|
|
89
|
+
hasBodyBinding?: boolean;
|
|
90
|
+
/** Parameter transforms declared via @Param({ transform: ... }) */
|
|
91
|
+
paramTransforms?: Record<string, "number" | "boolean" | "string">;
|
|
92
|
+
/** Parameter defaults declared via @Param({ default: ... }) */
|
|
93
|
+
paramDefaults?: Record<string, unknown>;
|
|
94
|
+
/** Query transforms declared via @Query({ transform: ... }) */
|
|
95
|
+
queryTransforms?: Record<string, "number" | "boolean" | "string">;
|
|
96
|
+
/** Query defaults declared via @Query({ default: ... }) */
|
|
97
|
+
queryDefaults?: Record<string, unknown>;
|
|
98
|
+
/** Route title (Angular Route.title style). */
|
|
99
|
+
title?: string;
|
|
100
|
+
/** Route static metadata dictionary (Angular Route.data style). */
|
|
101
|
+
data?: Record<string, unknown>;
|
|
102
|
+
/** Detailed method parameter metadata for compile-time typed invoker generation. */
|
|
103
|
+
handlerParams?: HandlerParamNode[];
|
|
43
104
|
}
|
|
44
105
|
export interface ControllerNode {
|
|
45
106
|
className: string;
|
|
46
107
|
path: string;
|
|
47
108
|
scope: Scope;
|
|
48
109
|
deps: string[];
|
|
110
|
+
/** Parameter tokens marked @Optional(). */
|
|
111
|
+
optionalDeps?: string[];
|
|
112
|
+
selfDeps?: string[];
|
|
113
|
+
skipSelfDeps?: string[];
|
|
114
|
+
/** Automatically registered without manual module declaration (Angular standalone controller style). */
|
|
115
|
+
standalone?: boolean;
|
|
49
116
|
routes: RouteNode[];
|
|
50
117
|
file: string;
|
|
51
118
|
importPath: string;
|
|
52
|
-
/**
|
|
119
|
+
/** Route schema symbol name -> relative module path (for import generation). */
|
|
53
120
|
schemaImports?: Record<string, string>;
|
|
54
121
|
}
|
|
55
122
|
export interface CommandNode {
|
|
@@ -59,52 +126,59 @@ export interface CommandNode {
|
|
|
59
126
|
transaction: "required" | "none";
|
|
60
127
|
audit?: string;
|
|
61
128
|
idempotency: "required" | "none";
|
|
129
|
+
/** Automatically registered without manual module declaration. */
|
|
130
|
+
standalone?: boolean;
|
|
62
131
|
}
|
|
63
132
|
export interface QueryNode {
|
|
64
133
|
className: string;
|
|
65
134
|
name: string;
|
|
66
135
|
}
|
|
67
136
|
export interface ModuleNode {
|
|
68
|
-
/** @Module({ name })
|
|
137
|
+
/** Name from @Module({ name }) or defineModule. */
|
|
69
138
|
name: string;
|
|
70
139
|
className: string;
|
|
71
|
-
/**
|
|
140
|
+
/** Module tags (e.g. ['scope:case', 'type:feature']) for architecture boundary governance. */
|
|
72
141
|
tags?: string[];
|
|
73
142
|
file: string;
|
|
74
143
|
line: number;
|
|
75
|
-
/**
|
|
144
|
+
/** Names of imported modules. */
|
|
76
145
|
imports: string[];
|
|
77
146
|
providers: ProviderNode[];
|
|
78
147
|
controllers: ControllerNode[];
|
|
79
148
|
commands: CommandNode[];
|
|
80
149
|
queries: QueryNode[];
|
|
81
|
-
/**
|
|
150
|
+
/** Exported token names. */
|
|
82
151
|
exports: string[];
|
|
83
152
|
}
|
|
84
153
|
export interface ApplicationGraph {
|
|
85
154
|
modules: ModuleNode[];
|
|
86
|
-
/**
|
|
155
|
+
/** Depended token names provided by platform injection rather than any module. */
|
|
87
156
|
externalTokens: string[];
|
|
88
157
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
158
|
+
* Diagnostics produced during analysis (e.g. missing-deps), merged by compileProject.
|
|
159
|
+
* Omitted from app.manifest.json.
|
|
91
160
|
*/
|
|
92
161
|
diagnostics?: Diagnostic[];
|
|
93
162
|
/**
|
|
94
|
-
* InjectionToken
|
|
95
|
-
* "supacloud.request-context"
|
|
96
|
-
*
|
|
163
|
+
* InjectionToken variable name -> string name (e.g. REQUEST_CONTEXT ->
|
|
164
|
+
* "supacloud.request-context"), used during code generation to identify built-in context tokens.
|
|
165
|
+
* Omitted from app.manifest.json.
|
|
97
166
|
*/
|
|
98
167
|
tokenNames?: Record<string, string>;
|
|
168
|
+
/** Incremental cache statistics (modules reused vs reanalyzed). */
|
|
169
|
+
cacheStats?: {
|
|
170
|
+
reusedModules: string[];
|
|
171
|
+
reanalyzedModules: string[];
|
|
172
|
+
};
|
|
99
173
|
}
|
|
100
174
|
export interface CompileOptions {
|
|
101
|
-
/**
|
|
175
|
+
/** Project root directory (containing tsconfig). */
|
|
102
176
|
rootDir: string;
|
|
103
|
-
/**
|
|
177
|
+
/** Glob patterns, defaults to ['**\/*.module.ts', '**\/*.ts']. */
|
|
104
178
|
include?: string[];
|
|
105
|
-
/**
|
|
179
|
+
/** Output directory (e.g. <rootDir>/generated). */
|
|
106
180
|
outDir: string;
|
|
107
|
-
/** warn
|
|
181
|
+
/** Upgrade warn-level diagnostics to error. */
|
|
108
182
|
strict?: boolean;
|
|
109
183
|
/** Built-in architecture boundary preset (for example, 'modular-monolith'). */
|
|
110
184
|
moduleBoundaryPreset?: ModuleBoundaryPresetName;
|
|
@@ -118,6 +192,16 @@ export interface CompileOptions {
|
|
|
118
192
|
disallowControllerDirectDb?: boolean;
|
|
119
193
|
/** Detect modules declared in the project that are unreachable from any root module. */
|
|
120
194
|
detectOrphanModules?: boolean;
|
|
195
|
+
/** Write generated artifacts even when error-level diagnostics exist (default: true). */
|
|
196
|
+
writeOnError?: boolean;
|
|
197
|
+
/** Generate typed API client in client.ts (default: false). */
|
|
198
|
+
generateClient?: boolean;
|
|
199
|
+
/** Generate typed permissions registry in permissions.ts (default: false). */
|
|
200
|
+
generatePermissions?: boolean;
|
|
201
|
+
/** Prune unused root providers from compiled output (Angular Ivy AOT tree-shaking). */
|
|
202
|
+
treeShakeUnusedProviders?: boolean;
|
|
203
|
+
/** Incremental dependency graph cache. */
|
|
204
|
+
cache?: DependencyGraphCache;
|
|
121
205
|
}
|
|
122
206
|
export interface ModuleBoundaryRule {
|
|
123
207
|
/** Source module tag pattern or tag (for example, 'type:ui', 'scope:case', or '*'). */
|
|
@@ -167,6 +251,14 @@ export interface CompileResult {
|
|
|
167
251
|
diagnostics: Diagnostic[];
|
|
168
252
|
graph: ApplicationGraph;
|
|
169
253
|
written: string[];
|
|
254
|
+
stats?: CompileStats;
|
|
255
|
+
}
|
|
256
|
+
export interface CompileStats {
|
|
257
|
+
cacheHit: boolean;
|
|
258
|
+
changedFiles: string[];
|
|
259
|
+
affectedModules: string[];
|
|
260
|
+
reanalyzedModules?: string[];
|
|
261
|
+
reusedModules?: string[];
|
|
170
262
|
}
|
|
171
263
|
export interface CheckProjectResult {
|
|
172
264
|
/** Whether generated artifacts exactly match the files on disk. */
|
|
@@ -176,3 +268,44 @@ export interface CheckProjectResult {
|
|
|
176
268
|
diagnostics: Diagnostic[];
|
|
177
269
|
graph: ApplicationGraph;
|
|
178
270
|
}
|
|
271
|
+
export interface WatchEvent {
|
|
272
|
+
type: "compile-start" | "compiled" | "compile-error";
|
|
273
|
+
initial: boolean;
|
|
274
|
+
durationMs: number;
|
|
275
|
+
diagnostics: Diagnostic[];
|
|
276
|
+
written: string[];
|
|
277
|
+
stats?: CompileStats;
|
|
278
|
+
}
|
|
279
|
+
export interface WatchOptions extends CompileOptions {
|
|
280
|
+
/** Debounce source changes before starting a compile (default: 100ms). */
|
|
281
|
+
debounceMs?: number;
|
|
282
|
+
onEvent?: (event: WatchEvent) => void;
|
|
283
|
+
}
|
|
284
|
+
export interface WatchHandle {
|
|
285
|
+
/** Resolves after the initial compile has completed. */
|
|
286
|
+
ready: Promise<WatchEvent>;
|
|
287
|
+
close(): Promise<void>;
|
|
288
|
+
}
|
|
289
|
+
export interface CachedModuleEntry {
|
|
290
|
+
module: ModuleNode;
|
|
291
|
+
/** Files owned by this module (normalized relative paths). */
|
|
292
|
+
ownedFiles: string[];
|
|
293
|
+
/** File hash mapping for owned files. */
|
|
294
|
+
fileHashes: Record<string, string>;
|
|
295
|
+
/** Diagnostics captured during this module's analysis. */
|
|
296
|
+
diagnostics?: Diagnostic[];
|
|
297
|
+
}
|
|
298
|
+
export interface DependencyGraphCache {
|
|
299
|
+
/** Cached modules by module name. */
|
|
300
|
+
modules: Map<string, CachedModuleEntry>;
|
|
301
|
+
/** Global file hashes by relative file path. */
|
|
302
|
+
fileHashes: Map<string, string>;
|
|
303
|
+
/** Retained AST project for true incremental graph re-analysis. */
|
|
304
|
+
project?: any;
|
|
305
|
+
/** Retained module dependency graph tracking imports and reverse dependents. */
|
|
306
|
+
dependencyGraph?: any;
|
|
307
|
+
lastStats?: {
|
|
308
|
+
reusedModules: string[];
|
|
309
|
+
reanalyzedModules: string[];
|
|
310
|
+
};
|
|
311
|
+
}
|
package/dist/util.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* CASE_REPOSITORY
|
|
4
|
-
* CaseService
|
|
2
|
+
* Token name -> key in services object.
|
|
3
|
+
* CASE_REPOSITORY -> caseRepository, LOGGER -> logger (convert CONSTANT_CASE to camelCase),
|
|
4
|
+
* CaseService -> caseService (lowercase first letter of PascalCase).
|
|
5
5
|
*/
|
|
6
6
|
export declare function camelName(token: string): string;
|
|
7
|
-
/**
|
|
7
|
+
/** Computes relative import path from fromDir to toFile (stripping extension, ensuring ./ or ../ prefix). */
|
|
8
8
|
export declare function relativeImportPath(fromDir: string, toFile: string): string;
|
|
9
|
-
/**
|
|
9
|
+
/** String names of built-in context tokens (aligned with REQUEST_CONTEXT/JOB_CONTEXT in @supacloud/app). */
|
|
10
10
|
export declare const REQUEST_CONTEXT_TOKEN_NAME = "supacloud.request-context";
|
|
11
11
|
export declare const JOB_CONTEXT_TOKEN_NAME = "supacloud.job-context";
|
|
12
|
-
/**
|
|
12
|
+
/** Determines whether token is built-in request context (variable name REQUEST_CONTEXT or matching token name). */
|
|
13
13
|
export declare function isRequestContextToken(token: string, tokenNames?: Record<string, string>): boolean;
|
|
14
|
-
/**
|
|
14
|
+
/** Determines whether token is built-in job context. */
|
|
15
15
|
export declare function isJobContextToken(token: string, tokenNames?: Record<string, string>): boolean;
|
|
16
|
+
/** Normalizes and combines controller path and route path. */
|
|
17
|
+
export declare function joinRoutePaths(prefix: string, path: string): string;
|
|
18
|
+
/** Finds the closest match from a list of candidate strings (case/delimiter-insensitive). */
|
|
19
|
+
export declare function findClosestMatch(target: string, candidates: string[]): string | undefined;
|
package/dist/validate.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { ApplicationGraph, Diagnostic, ValidateOptions } from "./types";
|
|
2
|
+
export declare const COMPILER_DIAGNOSTIC_CODES: Record<string, {
|
|
3
|
+
code: string;
|
|
4
|
+
docsUrl: string;
|
|
5
|
+
}>;
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
4
|
-
* strict
|
|
7
|
+
* Validates ApplicationGraph and produces diagnostics list.
|
|
8
|
+
* In strict mode, warn-level diagnostics are promoted to error.
|
|
5
9
|
*/
|
|
6
10
|
export declare function validateGraph(graph: ApplicationGraph, options?: boolean | ValidateOptions): Diagnostic[];
|
package/dist/watch.d.ts
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Static compiler for @supacloud/app metadata: builds the application graph from AST, validates it, and generates reflection-free factory code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|