@celerity-sdk/cli 0.2.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.cjs ADDED
@@ -0,0 +1,351 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ buildScannedModule: () => buildScannedModule,
35
+ deriveClassHandlerFunction: () => deriveClassHandlerFunction,
36
+ deriveClassHandlerName: () => deriveClassHandlerName,
37
+ deriveClassResourceName: () => deriveClassResourceName,
38
+ deriveCodeLocation: () => deriveCodeLocation,
39
+ deriveFunctionHandlerFunction: () => deriveFunctionHandlerFunction,
40
+ deriveFunctionResourceName: () => deriveFunctionResourceName,
41
+ joinHandlerPath: () => import_common.joinHandlerPath,
42
+ serializeManifest: () => serializeManifest,
43
+ validateScannedDependencies: () => validateScannedDependencies
44
+ });
45
+ module.exports = __toCommonJS(index_exports);
46
+
47
+ // src/extract/metadata-app.ts
48
+ var import_reflect_metadata = require("reflect-metadata");
49
+ var import_debug = __toESM(require("debug"), 1);
50
+ var import_core = require("@celerity-sdk/core");
51
+ var debug = (0, import_debug.default)("celerity:cli");
52
+ function scanProvider(provider, seenTokens) {
53
+ if (typeof provider === "function") {
54
+ if (seenTokens.has(provider)) return null;
55
+ seenTokens.add(provider);
56
+ return {
57
+ token: provider,
58
+ providerType: "class",
59
+ dependencies: (0, import_core.getClassDependencyTokens)(provider)
60
+ };
61
+ }
62
+ const typed = provider;
63
+ if (seenTokens.has(typed.provide)) return null;
64
+ seenTokens.add(typed.provide);
65
+ return {
66
+ token: typed.provide,
67
+ providerType: "useFactory" in typed ? "factory" : "useClass" in typed ? "class" : "value",
68
+ dependencies: (0, import_core.getProviderDependencyTokens)(typed)
69
+ };
70
+ }
71
+ __name(scanProvider, "scanProvider");
72
+ function buildScannedModule(rootModule) {
73
+ const graph = (0, import_core.buildModuleGraph)(rootModule);
74
+ const controllerClasses = [];
75
+ const functionHandlers = [];
76
+ const providers = [];
77
+ const seenTokens = /* @__PURE__ */ new Set();
78
+ for (const [moduleClass, node] of graph) {
79
+ debug("scan: module %s \u2014 %d providers, %d controllers", moduleClass.name, node.providers.length, node.controllers.length);
80
+ for (const provider of node.providers) {
81
+ const scanned = scanProvider(provider, seenTokens);
82
+ if (scanned) providers.push(scanned);
83
+ }
84
+ for (const controller of node.controllers) {
85
+ controllerClasses.push(controller);
86
+ if (!seenTokens.has(controller)) {
87
+ seenTokens.add(controller);
88
+ providers.push({
89
+ token: controller,
90
+ providerType: "class",
91
+ dependencies: (0, import_core.getClassDependencyTokens)(controller)
92
+ });
93
+ }
94
+ }
95
+ functionHandlers.push(...node.functionHandlers);
96
+ }
97
+ return {
98
+ controllerClasses,
99
+ functionHandlers,
100
+ providers
101
+ };
102
+ }
103
+ __name(buildScannedModule, "buildScannedModule");
104
+ function validateScannedDependencies(scanned) {
105
+ const registeredTokens = new Set(scanned.providers.map((p) => p.token));
106
+ const diagnostics = [];
107
+ const visited = /* @__PURE__ */ new Set();
108
+ function walk(token, deps) {
109
+ if (visited.has(token)) return;
110
+ visited.add(token);
111
+ for (const dep of deps) {
112
+ if (registeredTokens.has(dep)) {
113
+ const provider = scanned.providers.find((p) => p.token === dep);
114
+ if (provider) {
115
+ walk(dep, provider.dependencies);
116
+ }
117
+ } else if (typeof dep === "function") {
118
+ walk(dep, (0, import_core.getClassDependencyTokens)(dep));
119
+ } else {
120
+ diagnostics.push({
121
+ consumer: serializeToken(token),
122
+ dependency: serializeToken(dep)
123
+ });
124
+ }
125
+ }
126
+ }
127
+ __name(walk, "walk");
128
+ for (const provider of scanned.providers) {
129
+ walk(provider.token, provider.dependencies);
130
+ }
131
+ return diagnostics;
132
+ }
133
+ __name(validateScannedDependencies, "validateScannedDependencies");
134
+ function serializeToken(token) {
135
+ if (typeof token === "function") return token.name;
136
+ if (typeof token === "symbol") return token.description ?? "Symbol()";
137
+ return String(token);
138
+ }
139
+ __name(serializeToken, "serializeToken");
140
+
141
+ // src/extract/serializer.ts
142
+ var import_reflect_metadata2 = require("reflect-metadata");
143
+ var import_core2 = require("@celerity-sdk/core");
144
+
145
+ // src/extract/path-utils.ts
146
+ var import_common = require("@celerity-sdk/common");
147
+
148
+ // src/extract/identity.ts
149
+ var import_node_path = require("path");
150
+ function deriveClassResourceName(className, methodName) {
151
+ const camelClass = className.charAt(0).toLowerCase() + className.slice(1);
152
+ return `${camelClass}_${methodName}`;
153
+ }
154
+ __name(deriveClassResourceName, "deriveClassResourceName");
155
+ function deriveClassHandlerName(className, methodName) {
156
+ return `${className}-${methodName}`;
157
+ }
158
+ __name(deriveClassHandlerName, "deriveClassHandlerName");
159
+ function deriveClassHandlerFunction(sourceFile, className, methodName) {
160
+ const base = (0, import_node_path.basename)(sourceFile).replace(/\.[^.]+$/, "");
161
+ return `${base}.${className}.${methodName}`;
162
+ }
163
+ __name(deriveClassHandlerFunction, "deriveClassHandlerFunction");
164
+ function deriveFunctionResourceName(exportName) {
165
+ return exportName;
166
+ }
167
+ __name(deriveFunctionResourceName, "deriveFunctionResourceName");
168
+ function deriveFunctionHandlerFunction(sourceFile, exportName) {
169
+ const base = (0, import_node_path.basename)(sourceFile).replace(/\.[^.]+$/, "");
170
+ return `${base}.${exportName}`;
171
+ }
172
+ __name(deriveFunctionHandlerFunction, "deriveFunctionHandlerFunction");
173
+ function deriveCodeLocation(sourceFile, projectRoot) {
174
+ const rel = (0, import_node_path.relative)(projectRoot, sourceFile);
175
+ const dir = (0, import_node_path.dirname)(rel);
176
+ return dir === "." ? "./" : `./${dir}`;
177
+ }
178
+ __name(deriveCodeLocation, "deriveCodeLocation");
179
+
180
+ // src/extract/serializer.ts
181
+ function serializeManifest(scanned, sourceFile, options) {
182
+ const handlers = [];
183
+ const functionHandlers = [];
184
+ for (const controllerClass of scanned.controllerClasses) {
185
+ const entries = serializeClassHandler(controllerClass, sourceFile, options);
186
+ handlers.push(...entries);
187
+ }
188
+ for (const fnHandler of scanned.functionHandlers) {
189
+ const entry = serializeFunctionHandler(fnHandler, sourceFile, options);
190
+ if (entry) {
191
+ functionHandlers.push(entry);
192
+ }
193
+ }
194
+ return {
195
+ version: "1.0.0",
196
+ handlers,
197
+ functionHandlers,
198
+ dependencyGraph: serializeDependencyGraph(scanned)
199
+ };
200
+ }
201
+ __name(serializeManifest, "serializeManifest");
202
+ function extractClassMeta(controllerClass) {
203
+ const controllerMeta = Reflect.getOwnMetadata(import_core2.CONTROLLER_METADATA, controllerClass);
204
+ if (!controllerMeta) return null;
205
+ return {
206
+ prefix: controllerMeta.prefix ?? "",
207
+ protectedBy: Reflect.getOwnMetadata(import_core2.GUARD_PROTECTEDBY_METADATA, controllerClass) ?? [],
208
+ customGuardName: Reflect.getOwnMetadata(import_core2.GUARD_CUSTOM_METADATA, controllerClass),
209
+ customMetadata: Reflect.getOwnMetadata(import_core2.CUSTOM_METADATA, controllerClass) ?? {}
210
+ };
211
+ }
212
+ __name(extractClassMeta, "extractClassMeta");
213
+ function buildMethodAnnotations(classMeta, prototype, methodName, httpMethod, fullPath) {
214
+ const annotations = {};
215
+ annotations["celerity.handler.http"] = true;
216
+ annotations["celerity.handler.http.method"] = httpMethod;
217
+ annotations["celerity.handler.http.path"] = fullPath;
218
+ const methodProtectedBy = Reflect.getOwnMetadata(import_core2.GUARD_PROTECTEDBY_METADATA, prototype, methodName) ?? [];
219
+ const allProtectedBy = [
220
+ ...classMeta.protectedBy,
221
+ ...methodProtectedBy
222
+ ];
223
+ if (allProtectedBy.length > 0) {
224
+ annotations["celerity.handler.guard.protectedBy"] = allProtectedBy;
225
+ }
226
+ if (classMeta.customGuardName) {
227
+ annotations["celerity.handler.guard.custom"] = classMeta.customGuardName;
228
+ }
229
+ const isPublic = Reflect.getOwnMetadata(import_core2.PUBLIC_METADATA, prototype, methodName) === true;
230
+ if (isPublic) {
231
+ annotations["celerity.handler.public"] = true;
232
+ }
233
+ const methodCustomMetadata = Reflect.getOwnMetadata(import_core2.CUSTOM_METADATA, prototype, methodName) ?? {};
234
+ const customMetadata = {
235
+ ...classMeta.customMetadata,
236
+ ...methodCustomMetadata
237
+ };
238
+ for (const [key, value] of Object.entries(customMetadata)) {
239
+ if (value === void 0) continue;
240
+ annotations[`celerity.handler.metadata.${key}`] = serializeAnnotationValue(value);
241
+ }
242
+ return annotations;
243
+ }
244
+ __name(buildMethodAnnotations, "buildMethodAnnotations");
245
+ function serializeClassHandler(controllerClass, sourceFile, options) {
246
+ const classMeta = extractClassMeta(controllerClass);
247
+ if (!classMeta) return [];
248
+ const className = controllerClass.name;
249
+ const prototype = controllerClass.prototype;
250
+ const methods = Object.getOwnPropertyNames(prototype).filter((n) => n !== "constructor");
251
+ const entries = [];
252
+ for (const methodName of methods) {
253
+ const httpMethod = Reflect.getOwnMetadata(import_core2.HTTP_METHOD_METADATA, prototype, methodName);
254
+ if (!httpMethod) continue;
255
+ const routePath = Reflect.getOwnMetadata(import_core2.ROUTE_PATH_METADATA, prototype, methodName) ?? "/";
256
+ const fullPath = (0, import_common.joinHandlerPath)(classMeta.prefix, routePath);
257
+ const annotations = buildMethodAnnotations(classMeta, prototype, methodName, httpMethod, fullPath);
258
+ entries.push({
259
+ resourceName: deriveClassResourceName(className, methodName),
260
+ className,
261
+ methodName,
262
+ sourceFile,
263
+ handlerType: "http",
264
+ annotations,
265
+ spec: {
266
+ handlerName: deriveClassHandlerName(className, methodName),
267
+ codeLocation: deriveCodeLocation(sourceFile, options.projectRoot),
268
+ handler: deriveClassHandlerFunction(sourceFile, className, methodName)
269
+ }
270
+ });
271
+ }
272
+ return entries;
273
+ }
274
+ __name(serializeClassHandler, "serializeClassHandler");
275
+ function serializeFunctionHandler(definition, sourceFile, options) {
276
+ const exportName = definition.metadata.handlerName ?? "handler";
277
+ const customMetadata = definition.metadata.customMetadata ?? {};
278
+ const annotations = {};
279
+ const path = definition.metadata.path;
280
+ const method = definition.metadata.method;
281
+ if (path !== void 0 && method !== void 0) {
282
+ annotations["celerity.handler.http"] = true;
283
+ annotations["celerity.handler.http.method"] = method;
284
+ annotations["celerity.handler.http.path"] = path;
285
+ }
286
+ for (const [key, value] of Object.entries(customMetadata)) {
287
+ if (value === void 0) continue;
288
+ annotations[`celerity.handler.metadata.${key}`] = serializeAnnotationValue(value);
289
+ }
290
+ return {
291
+ resourceName: deriveFunctionResourceName(exportName),
292
+ exportName,
293
+ sourceFile,
294
+ ...Object.keys(annotations).length > 0 ? {
295
+ annotations
296
+ } : {},
297
+ spec: {
298
+ handlerName: exportName,
299
+ codeLocation: deriveCodeLocation(sourceFile, options.projectRoot),
300
+ handler: deriveFunctionHandlerFunction(sourceFile, exportName)
301
+ }
302
+ };
303
+ }
304
+ __name(serializeFunctionHandler, "serializeFunctionHandler");
305
+ function serializeAnnotationValue(value) {
306
+ if (typeof value === "boolean") return value;
307
+ if (typeof value === "string") return value;
308
+ if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
309
+ return value;
310
+ }
311
+ return JSON.stringify(value);
312
+ }
313
+ __name(serializeAnnotationValue, "serializeAnnotationValue");
314
+ function serializeToken2(token) {
315
+ if (typeof token === "function") return token.name;
316
+ if (typeof token === "symbol") return token.description ?? "Symbol()";
317
+ return token;
318
+ }
319
+ __name(serializeToken2, "serializeToken");
320
+ function tokenType(token) {
321
+ if (typeof token === "function") return "class";
322
+ if (typeof token === "symbol") return "symbol";
323
+ return "string";
324
+ }
325
+ __name(tokenType, "tokenType");
326
+ function serializeDependencyGraph(scanned) {
327
+ const nodes = scanned.providers.map((provider) => ({
328
+ token: serializeToken2(provider.token),
329
+ tokenType: tokenType(provider.token),
330
+ providerType: provider.providerType,
331
+ dependencies: provider.dependencies.map(serializeToken2)
332
+ }));
333
+ return {
334
+ nodes
335
+ };
336
+ }
337
+ __name(serializeDependencyGraph, "serializeDependencyGraph");
338
+ // Annotate the CommonJS export names for ESM import in node:
339
+ 0 && (module.exports = {
340
+ buildScannedModule,
341
+ deriveClassHandlerFunction,
342
+ deriveClassHandlerName,
343
+ deriveClassResourceName,
344
+ deriveCodeLocation,
345
+ deriveFunctionHandlerFunction,
346
+ deriveFunctionResourceName,
347
+ joinHandlerPath,
348
+ serializeManifest,
349
+ validateScannedDependencies
350
+ });
351
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/extract/metadata-app.ts","../src/extract/serializer.ts","../src/extract/path-utils.ts","../src/extract/identity.ts"],"sourcesContent":["export {\n buildScannedModule,\n validateScannedDependencies,\n type ScannedModule,\n type DependencyDiagnostic,\n} from \"./extract/metadata-app\";\nexport { serializeManifest, type SerializeOptions } from \"./extract/serializer\";\nexport { joinHandlerPath } from \"./extract/path-utils\";\nexport {\n deriveClassResourceName,\n deriveClassHandlerName,\n deriveClassHandlerFunction,\n deriveFunctionResourceName,\n deriveFunctionHandlerFunction,\n deriveCodeLocation,\n} from \"./extract/identity\";\nexport type { HandlerManifest, ClassHandlerEntry, FunctionHandlerEntry } from \"./extract/types\";\n","import \"reflect-metadata\";\nimport createDebug from \"debug\";\nimport type {\n Type,\n InjectionToken,\n Provider,\n FunctionHandlerDefinition,\n} from \"@celerity-sdk/types\";\nimport {\n buildModuleGraph,\n getClassDependencyTokens,\n getProviderDependencyTokens,\n} from \"@celerity-sdk/core\";\nimport type { ModuleGraph } from \"@celerity-sdk/core\";\n\nconst debug = createDebug(\"celerity:cli\");\n\nexport type ScannedProvider = {\n token: InjectionToken;\n providerType: \"class\" | \"factory\" | \"value\";\n dependencies: InjectionToken[];\n};\n\nexport type ScannedModule = {\n controllerClasses: Type[];\n functionHandlers: FunctionHandlerDefinition[];\n providers: ScannedProvider[];\n};\n\nfunction scanProvider(\n provider: Type | (Provider & { provide: InjectionToken }),\n seenTokens: Set<InjectionToken>,\n): ScannedProvider | null {\n if (typeof provider === \"function\") {\n if (seenTokens.has(provider)) return null;\n seenTokens.add(provider);\n return {\n token: provider,\n providerType: \"class\",\n dependencies: getClassDependencyTokens(provider),\n };\n }\n\n const typed = provider as Provider & { provide: InjectionToken };\n if (seenTokens.has(typed.provide)) return null;\n seenTokens.add(typed.provide);\n\n return {\n token: typed.provide,\n providerType: \"useFactory\" in typed ? \"factory\" : \"useClass\" in typed ? \"class\" : \"value\",\n dependencies: getProviderDependencyTokens(typed),\n };\n}\n\n/**\n * Builds a scanned module from the root module class using the shared\n * `buildModuleGraph` from core. Collects all handler classes, function\n * handler definitions, and provider dependency information without\n * instantiating anything.\n *\n * Inherits circular import detection from the shared graph builder.\n */\nexport function buildScannedModule(rootModule: Type): ScannedModule {\n const graph: ModuleGraph = buildModuleGraph(rootModule);\n const controllerClasses: Type[] = [];\n const functionHandlers: FunctionHandlerDefinition[] = [];\n const providers: ScannedProvider[] = [];\n const seenTokens = new Set<InjectionToken>();\n\n for (const [moduleClass, node] of graph) {\n debug(\n \"scan: module %s — %d providers, %d controllers\",\n moduleClass.name,\n node.providers.length,\n node.controllers.length,\n );\n for (const provider of node.providers) {\n const scanned = scanProvider(provider, seenTokens);\n if (scanned) providers.push(scanned);\n }\n\n for (const controller of node.controllers) {\n controllerClasses.push(controller);\n if (!seenTokens.has(controller)) {\n seenTokens.add(controller);\n providers.push({\n token: controller,\n providerType: \"class\",\n dependencies: getClassDependencyTokens(controller),\n });\n }\n }\n\n functionHandlers.push(...node.functionHandlers);\n }\n\n return { controllerClasses, functionHandlers, providers };\n}\n\nexport type DependencyDiagnostic = {\n consumer: string;\n dependency: string;\n};\n\n/**\n * Validates that all scanned providers have resolvable dependencies.\n * Returns an array of diagnostics for each unresolvable dependency.\n * A token is resolvable if it's registered or is a class (implicitly constructable).\n */\nexport function validateScannedDependencies(scanned: ScannedModule): DependencyDiagnostic[] {\n const registeredTokens = new Set<InjectionToken>(scanned.providers.map((p) => p.token));\n const diagnostics: DependencyDiagnostic[] = [];\n const visited = new Set<InjectionToken>();\n\n function walk(token: InjectionToken, deps: InjectionToken[]): void {\n if (visited.has(token)) return;\n visited.add(token);\n\n for (const dep of deps) {\n if (registeredTokens.has(dep)) {\n const provider = scanned.providers.find((p) => p.token === dep);\n if (provider) {\n walk(dep, provider.dependencies);\n }\n } else if (typeof dep === \"function\") {\n walk(dep, getClassDependencyTokens(dep as Type));\n } else {\n diagnostics.push({\n consumer: serializeToken(token),\n dependency: serializeToken(dep),\n });\n }\n }\n }\n\n for (const provider of scanned.providers) {\n walk(provider.token, provider.dependencies);\n }\n\n return diagnostics;\n}\n\nfunction serializeToken(token: InjectionToken): string {\n if (typeof token === \"function\") return token.name;\n if (typeof token === \"symbol\") return token.description ?? \"Symbol()\";\n return String(token);\n}\n","import \"reflect-metadata\";\nimport type { Type, HttpMethod, InjectionToken } from \"@celerity-sdk/types\";\nimport {\n CONTROLLER_METADATA,\n HTTP_METHOD_METADATA,\n ROUTE_PATH_METADATA,\n GUARD_PROTECTEDBY_METADATA,\n GUARD_CUSTOM_METADATA,\n PUBLIC_METADATA,\n CUSTOM_METADATA,\n} from \"@celerity-sdk/core\";\nimport type { ControllerMetadata } from \"@celerity-sdk/core\";\nimport type { ScannedModule } from \"./metadata-app\";\nimport type {\n HandlerManifest,\n ClassHandlerEntry,\n FunctionHandlerEntry,\n DependencyGraph,\n DependencyNode,\n} from \"./types\";\nimport { joinHandlerPath } from \"./path-utils\";\nimport {\n deriveClassResourceName,\n deriveClassHandlerName,\n deriveClassHandlerFunction,\n deriveCodeLocation,\n deriveFunctionResourceName,\n deriveFunctionHandlerFunction,\n} from \"./identity\";\n\nexport type SerializeOptions = {\n projectRoot: string;\n};\n\nexport function serializeManifest(\n scanned: ScannedModule,\n sourceFile: string,\n options: SerializeOptions,\n): HandlerManifest {\n const handlers: ClassHandlerEntry[] = [];\n const functionHandlers: FunctionHandlerEntry[] = [];\n\n for (const controllerClass of scanned.controllerClasses) {\n const entries = serializeClassHandler(controllerClass, sourceFile, options);\n handlers.push(...entries);\n }\n\n for (const fnHandler of scanned.functionHandlers) {\n const entry = serializeFunctionHandler(fnHandler, sourceFile, options);\n if (entry) {\n functionHandlers.push(entry);\n }\n }\n\n return {\n version: \"1.0.0\",\n handlers,\n functionHandlers,\n dependencyGraph: serializeDependencyGraph(scanned),\n };\n}\n\ntype ClassMeta = {\n prefix: string;\n protectedBy: string[];\n customGuardName: string | undefined;\n customMetadata: Record<string, unknown>;\n};\n\nfunction extractClassMeta(controllerClass: Type): ClassMeta | null {\n const controllerMeta: ControllerMetadata | undefined = Reflect.getOwnMetadata(\n CONTROLLER_METADATA,\n controllerClass,\n );\n if (!controllerMeta) return null;\n\n return {\n prefix: controllerMeta.prefix ?? \"\",\n protectedBy: Reflect.getOwnMetadata(GUARD_PROTECTEDBY_METADATA, controllerClass) ?? [],\n customGuardName: Reflect.getOwnMetadata(GUARD_CUSTOM_METADATA, controllerClass),\n customMetadata: Reflect.getOwnMetadata(CUSTOM_METADATA, controllerClass) ?? {},\n };\n}\n\nfunction buildMethodAnnotations(\n classMeta: ClassMeta,\n prototype: object,\n methodName: string,\n httpMethod: HttpMethod,\n fullPath: string,\n): Record<string, string | string[] | boolean> {\n const annotations: Record<string, string | string[] | boolean> = {};\n\n annotations[\"celerity.handler.http\"] = true;\n annotations[\"celerity.handler.http.method\"] = httpMethod;\n annotations[\"celerity.handler.http.path\"] = fullPath;\n\n const methodProtectedBy: string[] =\n Reflect.getOwnMetadata(GUARD_PROTECTEDBY_METADATA, prototype, methodName) ?? [];\n const allProtectedBy = [...classMeta.protectedBy, ...methodProtectedBy];\n if (allProtectedBy.length > 0) {\n annotations[\"celerity.handler.guard.protectedBy\"] = allProtectedBy;\n }\n if (classMeta.customGuardName) {\n annotations[\"celerity.handler.guard.custom\"] = classMeta.customGuardName;\n }\n\n const isPublic: boolean = Reflect.getOwnMetadata(PUBLIC_METADATA, prototype, methodName) === true;\n if (isPublic) {\n annotations[\"celerity.handler.public\"] = true;\n }\n\n const methodCustomMetadata: Record<string, unknown> =\n Reflect.getOwnMetadata(CUSTOM_METADATA, prototype, methodName) ?? {};\n const customMetadata = { ...classMeta.customMetadata, ...methodCustomMetadata };\n for (const [key, value] of Object.entries(customMetadata)) {\n if (value === undefined) continue;\n annotations[`celerity.handler.metadata.${key}`] = serializeAnnotationValue(value);\n }\n\n return annotations;\n}\n\nfunction serializeClassHandler(\n controllerClass: Type,\n sourceFile: string,\n options: SerializeOptions,\n): ClassHandlerEntry[] {\n const classMeta = extractClassMeta(controllerClass);\n if (!classMeta) return [];\n\n const className = controllerClass.name;\n const prototype = controllerClass.prototype as object;\n const methods = Object.getOwnPropertyNames(prototype).filter((n) => n !== \"constructor\");\n const entries: ClassHandlerEntry[] = [];\n\n for (const methodName of methods) {\n const httpMethod: HttpMethod | undefined = Reflect.getOwnMetadata(\n HTTP_METHOD_METADATA,\n prototype,\n methodName,\n );\n if (!httpMethod) continue;\n\n const routePath: string =\n Reflect.getOwnMetadata(ROUTE_PATH_METADATA, prototype, methodName) ?? \"/\";\n const fullPath = joinHandlerPath(classMeta.prefix, routePath);\n const annotations = buildMethodAnnotations(\n classMeta,\n prototype,\n methodName,\n httpMethod,\n fullPath,\n );\n\n entries.push({\n resourceName: deriveClassResourceName(className, methodName),\n className,\n methodName,\n sourceFile,\n handlerType: \"http\",\n annotations,\n spec: {\n handlerName: deriveClassHandlerName(className, methodName),\n codeLocation: deriveCodeLocation(sourceFile, options.projectRoot),\n handler: deriveClassHandlerFunction(sourceFile, className, methodName),\n },\n });\n }\n\n return entries;\n}\n\nfunction serializeFunctionHandler(\n definition: { metadata: Record<string, unknown>; handler: (...args: unknown[]) => unknown },\n sourceFile: string,\n options: SerializeOptions,\n): FunctionHandlerEntry | null {\n // Function handlers don't have a reliable export name from the definition alone.\n // The CLI entry point will need to derive this from the module's named exports.\n // For now, use \"handler\" as a placeholder — the CLI enriches this.\n const exportName = (definition.metadata.handlerName as string) ?? \"handler\";\n const customMetadata = (definition.metadata.customMetadata as Record<string, unknown>) ?? {};\n\n const annotations: Record<string, string | string[] | boolean> = {};\n\n const path = definition.metadata.path as string | undefined;\n const method = definition.metadata.method as string | undefined;\n if (path !== undefined && method !== undefined) {\n annotations[\"celerity.handler.http\"] = true;\n annotations[\"celerity.handler.http.method\"] = method;\n annotations[\"celerity.handler.http.path\"] = path;\n }\n\n for (const [key, value] of Object.entries(customMetadata)) {\n if (value === undefined) continue;\n annotations[`celerity.handler.metadata.${key}`] = serializeAnnotationValue(value);\n }\n\n return {\n resourceName: deriveFunctionResourceName(exportName),\n exportName,\n sourceFile,\n ...(Object.keys(annotations).length > 0 ? { annotations } : {}),\n spec: {\n handlerName: exportName,\n codeLocation: deriveCodeLocation(sourceFile, options.projectRoot),\n handler: deriveFunctionHandlerFunction(sourceFile, exportName),\n },\n };\n}\n\nfunction serializeAnnotationValue(value: unknown): string | string[] | boolean {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"string\") return value;\n if (Array.isArray(value) && value.every((v) => typeof v === \"string\")) {\n return value as string[];\n }\n return JSON.stringify(value);\n}\n\nexport function serializeToken(token: InjectionToken): string {\n if (typeof token === \"function\") return token.name;\n if (typeof token === \"symbol\") return token.description ?? \"Symbol()\";\n return token;\n}\n\nexport function tokenType(token: InjectionToken): \"class\" | \"string\" | \"symbol\" {\n if (typeof token === \"function\") return \"class\";\n if (typeof token === \"symbol\") return \"symbol\";\n return \"string\";\n}\n\nfunction serializeDependencyGraph(scanned: ScannedModule): DependencyGraph {\n const nodes: DependencyNode[] = scanned.providers.map((provider) => ({\n token: serializeToken(provider.token),\n tokenType: tokenType(provider.token),\n providerType: provider.providerType,\n dependencies: provider.dependencies.map(serializeToken),\n }));\n\n return { nodes };\n}\n","export { joinHandlerPath } from \"@celerity-sdk/common\";\n","import { basename, dirname, relative } from \"node:path\";\n\n/**\n * Derives a resource name for a class-based handler method.\n * Format: camelCase(className) + \"_\" + methodName\n *\n * @example deriveClassResourceName(\"OrdersHandler\", \"getOrder\") => \"ordersHandler_getOrder\"\n */\nexport function deriveClassResourceName(className: string, methodName: string): string {\n const camelClass = className.charAt(0).toLowerCase() + className.slice(1);\n return `${camelClass}_${methodName}`;\n}\n\n/**\n * Derives a handler name for a class-based handler method.\n * Format: className + \"-\" + methodName\n *\n * @example deriveClassHandlerName(\"OrdersHandler\", \"getOrder\") => \"OrdersHandler-getOrder\"\n */\nexport function deriveClassHandlerName(className: string, methodName: string): string {\n return `${className}-${methodName}`;\n}\n\n/**\n * Derives the handler function reference for a class-based handler.\n * Format: moduleBaseName + \".\" + className + \".\" + methodName\n *\n * @example deriveClassHandlerFunction(\"src/handlers/orders.ts\", \"OrdersHandler\", \"getOrder\")\n * => \"orders.OrdersHandler.getOrder\"\n */\nexport function deriveClassHandlerFunction(\n sourceFile: string,\n className: string,\n methodName: string,\n): string {\n const base = basename(sourceFile).replace(/\\.[^.]+$/, \"\");\n return `${base}.${className}.${methodName}`;\n}\n\n/**\n * Derives a resource name for a function-based handler.\n * Uses the export name directly.\n *\n * @example deriveFunctionResourceName(\"getOrder\") => \"getOrder\"\n */\nexport function deriveFunctionResourceName(exportName: string): string {\n return exportName;\n}\n\n/**\n * Derives the handler function reference for a function-based handler.\n * Format: moduleBaseName + \".\" + exportName\n *\n * @example deriveFunctionHandlerFunction(\"src/handlers/orders.ts\", \"getOrder\")\n * => \"orders.getOrder\"\n */\nexport function deriveFunctionHandlerFunction(sourceFile: string, exportName: string): string {\n const base = basename(sourceFile).replace(/\\.[^.]+$/, \"\");\n return `${base}.${exportName}`;\n}\n\n/**\n * Derives the code location from a source file path relative to the project root.\n * Returns the directory prefixed with \"./\"\n *\n * @example deriveCodeLocation(\"src/handlers/orders.ts\", \"/project\") => \"./src/handlers\"\n */\nexport function deriveCodeLocation(sourceFile: string, projectRoot: string): string {\n const rel = relative(projectRoot, sourceFile);\n const dir = dirname(rel);\n return dir === \".\" ? \"./\" : `./${dir}`;\n}\n"],"mappings":"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","names":["debug","createDebug","scanProvider","provider","seenTokens","has","add","token","providerType","dependencies","getClassDependencyTokens","typed","provide","getProviderDependencyTokens","buildScannedModule","rootModule","graph","buildModuleGraph","controllerClasses","functionHandlers","providers","Set","moduleClass","node","name","length","controllers","scanned","push","controller","validateScannedDependencies","registeredTokens","map","p","diagnostics","visited","walk","deps","dep","find","consumer","serializeToken","dependency","description","String","import_reflect_metadata","import_core","deriveClassResourceName","className","methodName","camelClass","charAt","toLowerCase","slice","deriveClassHandlerName","deriveClassHandlerFunction","sourceFile","base","basename","replace","deriveFunctionResourceName","exportName","deriveFunctionHandlerFunction","deriveCodeLocation","projectRoot","rel","relative","dir","dirname","serializeManifest","scanned","sourceFile","options","handlers","functionHandlers","controllerClass","controllerClasses","entries","serializeClassHandler","push","fnHandler","entry","serializeFunctionHandler","version","dependencyGraph","serializeDependencyGraph","extractClassMeta","controllerMeta","Reflect","getOwnMetadata","CONTROLLER_METADATA","prefix","protectedBy","GUARD_PROTECTEDBY_METADATA","customGuardName","GUARD_CUSTOM_METADATA","customMetadata","CUSTOM_METADATA","buildMethodAnnotations","classMeta","prototype","methodName","httpMethod","fullPath","annotations","methodProtectedBy","allProtectedBy","length","isPublic","PUBLIC_METADATA","methodCustomMetadata","key","value","Object","undefined","serializeAnnotationValue","className","name","methods","getOwnPropertyNames","filter","n","HTTP_METHOD_METADATA","routePath","ROUTE_PATH_METADATA","joinHandlerPath","resourceName","deriveClassResourceName","handlerType","spec","handlerName","deriveClassHandlerName","codeLocation","deriveCodeLocation","projectRoot","handler","deriveClassHandlerFunction","definition","exportName","metadata","path","method","deriveFunctionResourceName","keys","deriveFunctionHandlerFunction","Array","isArray","every","v","JSON","stringify","serializeToken","token","description","tokenType","nodes","providers","map","provider","providerType","dependencies"]}
@@ -0,0 +1,125 @@
1
+ import { Type, FunctionHandlerDefinition, InjectionToken } from '@celerity-sdk/types';
2
+ export { joinHandlerPath } from '@celerity-sdk/common';
3
+
4
+ type ScannedProvider = {
5
+ token: InjectionToken;
6
+ providerType: "class" | "factory" | "value";
7
+ dependencies: InjectionToken[];
8
+ };
9
+ type ScannedModule = {
10
+ controllerClasses: Type[];
11
+ functionHandlers: FunctionHandlerDefinition[];
12
+ providers: ScannedProvider[];
13
+ };
14
+ /**
15
+ * Builds a scanned module from the root module class using the shared
16
+ * `buildModuleGraph` from core. Collects all handler classes, function
17
+ * handler definitions, and provider dependency information without
18
+ * instantiating anything.
19
+ *
20
+ * Inherits circular import detection from the shared graph builder.
21
+ */
22
+ declare function buildScannedModule(rootModule: Type): ScannedModule;
23
+ type DependencyDiagnostic = {
24
+ consumer: string;
25
+ dependency: string;
26
+ };
27
+ /**
28
+ * Validates that all scanned providers have resolvable dependencies.
29
+ * Returns an array of diagnostics for each unresolvable dependency.
30
+ * A token is resolvable if it's registered or is a class (implicitly constructable).
31
+ */
32
+ declare function validateScannedDependencies(scanned: ScannedModule): DependencyDiagnostic[];
33
+
34
+ type DependencyNode = {
35
+ token: string;
36
+ tokenType: "class" | "string" | "symbol";
37
+ providerType: "class" | "factory" | "value";
38
+ dependencies: string[];
39
+ };
40
+ type DependencyGraph = {
41
+ nodes: DependencyNode[];
42
+ };
43
+ type HandlerManifest = {
44
+ version: "1.0.0";
45
+ handlers: ClassHandlerEntry[];
46
+ functionHandlers: FunctionHandlerEntry[];
47
+ dependencyGraph: DependencyGraph;
48
+ };
49
+ type ClassHandlerEntry = {
50
+ resourceName: string;
51
+ className: string;
52
+ methodName: string;
53
+ sourceFile: string;
54
+ handlerType: "http" | "websocket" | "consumer" | "schedule";
55
+ annotations: Record<string, string | string[] | boolean>;
56
+ spec: {
57
+ handlerName: string;
58
+ codeLocation: string;
59
+ handler: string;
60
+ timeout?: number;
61
+ };
62
+ };
63
+ type FunctionHandlerEntry = {
64
+ resourceName: string;
65
+ exportName: string;
66
+ sourceFile: string;
67
+ annotations?: Record<string, string | string[] | boolean>;
68
+ spec: {
69
+ handlerName: string;
70
+ codeLocation: string;
71
+ handler: string;
72
+ };
73
+ };
74
+
75
+ type SerializeOptions = {
76
+ projectRoot: string;
77
+ };
78
+ declare function serializeManifest(scanned: ScannedModule, sourceFile: string, options: SerializeOptions): HandlerManifest;
79
+
80
+ /**
81
+ * Derives a resource name for a class-based handler method.
82
+ * Format: camelCase(className) + "_" + methodName
83
+ *
84
+ * @example deriveClassResourceName("OrdersHandler", "getOrder") => "ordersHandler_getOrder"
85
+ */
86
+ declare function deriveClassResourceName(className: string, methodName: string): string;
87
+ /**
88
+ * Derives a handler name for a class-based handler method.
89
+ * Format: className + "-" + methodName
90
+ *
91
+ * @example deriveClassHandlerName("OrdersHandler", "getOrder") => "OrdersHandler-getOrder"
92
+ */
93
+ declare function deriveClassHandlerName(className: string, methodName: string): string;
94
+ /**
95
+ * Derives the handler function reference for a class-based handler.
96
+ * Format: moduleBaseName + "." + className + "." + methodName
97
+ *
98
+ * @example deriveClassHandlerFunction("src/handlers/orders.ts", "OrdersHandler", "getOrder")
99
+ * => "orders.OrdersHandler.getOrder"
100
+ */
101
+ declare function deriveClassHandlerFunction(sourceFile: string, className: string, methodName: string): string;
102
+ /**
103
+ * Derives a resource name for a function-based handler.
104
+ * Uses the export name directly.
105
+ *
106
+ * @example deriveFunctionResourceName("getOrder") => "getOrder"
107
+ */
108
+ declare function deriveFunctionResourceName(exportName: string): string;
109
+ /**
110
+ * Derives the handler function reference for a function-based handler.
111
+ * Format: moduleBaseName + "." + exportName
112
+ *
113
+ * @example deriveFunctionHandlerFunction("src/handlers/orders.ts", "getOrder")
114
+ * => "orders.getOrder"
115
+ */
116
+ declare function deriveFunctionHandlerFunction(sourceFile: string, exportName: string): string;
117
+ /**
118
+ * Derives the code location from a source file path relative to the project root.
119
+ * Returns the directory prefixed with "./"
120
+ *
121
+ * @example deriveCodeLocation("src/handlers/orders.ts", "/project") => "./src/handlers"
122
+ */
123
+ declare function deriveCodeLocation(sourceFile: string, projectRoot: string): string;
124
+
125
+ export { type ClassHandlerEntry, type DependencyDiagnostic, type FunctionHandlerEntry, type HandlerManifest, type ScannedModule, type SerializeOptions, buildScannedModule, deriveClassHandlerFunction, deriveClassHandlerName, deriveClassResourceName, deriveCodeLocation, deriveFunctionHandlerFunction, deriveFunctionResourceName, serializeManifest, validateScannedDependencies };
@@ -0,0 +1,125 @@
1
+ import { Type, FunctionHandlerDefinition, InjectionToken } from '@celerity-sdk/types';
2
+ export { joinHandlerPath } from '@celerity-sdk/common';
3
+
4
+ type ScannedProvider = {
5
+ token: InjectionToken;
6
+ providerType: "class" | "factory" | "value";
7
+ dependencies: InjectionToken[];
8
+ };
9
+ type ScannedModule = {
10
+ controllerClasses: Type[];
11
+ functionHandlers: FunctionHandlerDefinition[];
12
+ providers: ScannedProvider[];
13
+ };
14
+ /**
15
+ * Builds a scanned module from the root module class using the shared
16
+ * `buildModuleGraph` from core. Collects all handler classes, function
17
+ * handler definitions, and provider dependency information without
18
+ * instantiating anything.
19
+ *
20
+ * Inherits circular import detection from the shared graph builder.
21
+ */
22
+ declare function buildScannedModule(rootModule: Type): ScannedModule;
23
+ type DependencyDiagnostic = {
24
+ consumer: string;
25
+ dependency: string;
26
+ };
27
+ /**
28
+ * Validates that all scanned providers have resolvable dependencies.
29
+ * Returns an array of diagnostics for each unresolvable dependency.
30
+ * A token is resolvable if it's registered or is a class (implicitly constructable).
31
+ */
32
+ declare function validateScannedDependencies(scanned: ScannedModule): DependencyDiagnostic[];
33
+
34
+ type DependencyNode = {
35
+ token: string;
36
+ tokenType: "class" | "string" | "symbol";
37
+ providerType: "class" | "factory" | "value";
38
+ dependencies: string[];
39
+ };
40
+ type DependencyGraph = {
41
+ nodes: DependencyNode[];
42
+ };
43
+ type HandlerManifest = {
44
+ version: "1.0.0";
45
+ handlers: ClassHandlerEntry[];
46
+ functionHandlers: FunctionHandlerEntry[];
47
+ dependencyGraph: DependencyGraph;
48
+ };
49
+ type ClassHandlerEntry = {
50
+ resourceName: string;
51
+ className: string;
52
+ methodName: string;
53
+ sourceFile: string;
54
+ handlerType: "http" | "websocket" | "consumer" | "schedule";
55
+ annotations: Record<string, string | string[] | boolean>;
56
+ spec: {
57
+ handlerName: string;
58
+ codeLocation: string;
59
+ handler: string;
60
+ timeout?: number;
61
+ };
62
+ };
63
+ type FunctionHandlerEntry = {
64
+ resourceName: string;
65
+ exportName: string;
66
+ sourceFile: string;
67
+ annotations?: Record<string, string | string[] | boolean>;
68
+ spec: {
69
+ handlerName: string;
70
+ codeLocation: string;
71
+ handler: string;
72
+ };
73
+ };
74
+
75
+ type SerializeOptions = {
76
+ projectRoot: string;
77
+ };
78
+ declare function serializeManifest(scanned: ScannedModule, sourceFile: string, options: SerializeOptions): HandlerManifest;
79
+
80
+ /**
81
+ * Derives a resource name for a class-based handler method.
82
+ * Format: camelCase(className) + "_" + methodName
83
+ *
84
+ * @example deriveClassResourceName("OrdersHandler", "getOrder") => "ordersHandler_getOrder"
85
+ */
86
+ declare function deriveClassResourceName(className: string, methodName: string): string;
87
+ /**
88
+ * Derives a handler name for a class-based handler method.
89
+ * Format: className + "-" + methodName
90
+ *
91
+ * @example deriveClassHandlerName("OrdersHandler", "getOrder") => "OrdersHandler-getOrder"
92
+ */
93
+ declare function deriveClassHandlerName(className: string, methodName: string): string;
94
+ /**
95
+ * Derives the handler function reference for a class-based handler.
96
+ * Format: moduleBaseName + "." + className + "." + methodName
97
+ *
98
+ * @example deriveClassHandlerFunction("src/handlers/orders.ts", "OrdersHandler", "getOrder")
99
+ * => "orders.OrdersHandler.getOrder"
100
+ */
101
+ declare function deriveClassHandlerFunction(sourceFile: string, className: string, methodName: string): string;
102
+ /**
103
+ * Derives a resource name for a function-based handler.
104
+ * Uses the export name directly.
105
+ *
106
+ * @example deriveFunctionResourceName("getOrder") => "getOrder"
107
+ */
108
+ declare function deriveFunctionResourceName(exportName: string): string;
109
+ /**
110
+ * Derives the handler function reference for a function-based handler.
111
+ * Format: moduleBaseName + "." + exportName
112
+ *
113
+ * @example deriveFunctionHandlerFunction("src/handlers/orders.ts", "getOrder")
114
+ * => "orders.getOrder"
115
+ */
116
+ declare function deriveFunctionHandlerFunction(sourceFile: string, exportName: string): string;
117
+ /**
118
+ * Derives the code location from a source file path relative to the project root.
119
+ * Returns the directory prefixed with "./"
120
+ *
121
+ * @example deriveCodeLocation("src/handlers/orders.ts", "/project") => "./src/handlers"
122
+ */
123
+ declare function deriveCodeLocation(sourceFile: string, projectRoot: string): string;
124
+
125
+ export { type ClassHandlerEntry, type DependencyDiagnostic, type FunctionHandlerEntry, type HandlerManifest, type ScannedModule, type SerializeOptions, buildScannedModule, deriveClassHandlerFunction, deriveClassHandlerName, deriveClassResourceName, deriveCodeLocation, deriveFunctionHandlerFunction, deriveFunctionResourceName, serializeManifest, validateScannedDependencies };