@alzulejos/laranja-scanner 0.2.4
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/ast-utils.d.ts +34 -0
- package/dist/ast-utils.js +112 -0
- package/dist/ast-utils.js.map +1 -0
- package/dist/detect.d.ts +3 -0
- package/dist/detect.js +14 -0
- package/dist/detect.js.map +1 -0
- package/dist/dev-scan.d.ts +1 -0
- package/dist/dev-scan.js +19 -0
- package/dist/dev-scan.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/nest-routes.d.ts +9 -0
- package/dist/nest-routes.js +67 -0
- package/dist/nest-routes.js.map +1 -0
- package/dist/resource-types.d.ts +24 -0
- package/dist/resource-types.js +105 -0
- package/dist/resource-types.js.map +1 -0
- package/dist/scan.d.ts +12 -0
- package/dist/scan.js +799 -0
- package/dist/scan.js.map +1 -0
- package/package.json +24 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Node } from "ts-morph";
|
|
2
|
+
import type { ObjectLiteralExpression } from "ts-morph";
|
|
3
|
+
import { type Schedule } from "@alzulejos/laranja-core";
|
|
4
|
+
/** Resolve a literal AST node to a plain JS value, or undefined if not a literal. */
|
|
5
|
+
export declare function literalValue(node: Node | undefined): string | number | boolean | undefined;
|
|
6
|
+
/** Flatten an object literal's simple property assignments into a record. */
|
|
7
|
+
export declare function objectToRecord(obj: ObjectLiteralExpression): Record<string, string | number | boolean | undefined>;
|
|
8
|
+
/**
|
|
9
|
+
* Constant-fold a call to laranja's own `rate(...)`/`every(...)` helpers using
|
|
10
|
+
* literal arguments. Returns the neutral structured Schedule, or undefined if
|
|
11
|
+
* the call isn't a recognized helper or its args aren't literals.
|
|
12
|
+
*/
|
|
13
|
+
export declare function foldScheduleCall(node: Node | undefined): Schedule | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a node used as a schedule into the neutral structured Schedule. Accepts,
|
|
16
|
+
* in order: a `rate(...)`/`every(...)` helper call; a `CronExpression.MEMBER`
|
|
17
|
+
* reference; a raw AWS `rate(...)`/`cron(...)` string; or a bare node-cron string
|
|
18
|
+
* (the `@nestjs/schedule` form, translated to the AWS dialect — which THROWS a
|
|
19
|
+
* located error for anything EventBridge can't honor). Returns undefined only for
|
|
20
|
+
* non-static input (e.g. a variable), so callers can raise a "not static" error.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveScheduleNode(node: Node | undefined, where: string): Schedule | undefined;
|
|
23
|
+
/** Return the initializer node of a named property on an object literal. */
|
|
24
|
+
export declare function getPropertyInitializer(obj: ObjectLiteralExpression, name: string): Node | undefined;
|
|
25
|
+
/** Read a decorator's first argument as either a string or a flattened object. */
|
|
26
|
+
export declare function readDecoratorArg(node: Node | undefined): {
|
|
27
|
+
kind: "string";
|
|
28
|
+
value: string;
|
|
29
|
+
} | {
|
|
30
|
+
kind: "object";
|
|
31
|
+
value: Record<string, string | number | boolean | undefined>;
|
|
32
|
+
} | {
|
|
33
|
+
kind: "unknown";
|
|
34
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Node, SyntaxKind } from "ts-morph";
|
|
2
|
+
import { rate, every, parseScheduleString, nestCronToSchedule, CRON_EXPRESSION_VALUES, } from "@alzulejos/laranja-core";
|
|
3
|
+
/** Resolve a literal AST node to a plain JS value, or undefined if not a literal. */
|
|
4
|
+
export function literalValue(node) {
|
|
5
|
+
if (!node)
|
|
6
|
+
return undefined;
|
|
7
|
+
if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
8
|
+
return node.getLiteralText();
|
|
9
|
+
}
|
|
10
|
+
if (Node.isNumericLiteral(node))
|
|
11
|
+
return Number(node.getLiteralText());
|
|
12
|
+
if (node.getKind() === SyntaxKind.TrueKeyword)
|
|
13
|
+
return true;
|
|
14
|
+
if (node.getKind() === SyntaxKind.FalseKeyword)
|
|
15
|
+
return false;
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
/** Flatten an object literal's simple property assignments into a record. */
|
|
19
|
+
export function objectToRecord(obj) {
|
|
20
|
+
const out = {};
|
|
21
|
+
for (const prop of obj.getProperties()) {
|
|
22
|
+
if (Node.isPropertyAssignment(prop)) {
|
|
23
|
+
out[prop.getName()] = literalValue(prop.getInitializer());
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
const RATE_UNITS = new Set(["minute", "minutes", "hour", "hours", "day", "days"]);
|
|
29
|
+
/**
|
|
30
|
+
* Constant-fold a call to laranja's own `rate(...)`/`every(...)` helpers using
|
|
31
|
+
* literal arguments. Returns the neutral structured Schedule, or undefined if
|
|
32
|
+
* the call isn't a recognized helper or its args aren't literals.
|
|
33
|
+
*/
|
|
34
|
+
export function foldScheduleCall(node) {
|
|
35
|
+
if (!node || !Node.isCallExpression(node))
|
|
36
|
+
return undefined;
|
|
37
|
+
const callee = node.getExpression();
|
|
38
|
+
if (!Node.isIdentifier(callee))
|
|
39
|
+
return undefined;
|
|
40
|
+
const name = callee.getText();
|
|
41
|
+
const args = node.getArguments().map((a) => literalValue(a));
|
|
42
|
+
if (name === "rate" && typeof args[0] === "number" && typeof args[1] === "string" && RATE_UNITS.has(args[1])) {
|
|
43
|
+
try {
|
|
44
|
+
return rate(args[0], args[1]);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (name === "every" && (args[0] === "minute" || args[0] === "hour" || args[0] === "day")) {
|
|
51
|
+
return every(args[0]);
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a `CronExpression.MEMBER` reference to its node-cron string, matching on
|
|
57
|
+
* the object identifier name (`CronExpression`) and a known member. Alias-agnostic:
|
|
58
|
+
* whether the enum is imported from laranja or `@nestjs/schedule`, the member names
|
|
59
|
+
* and values are identical, so we fold through our own mirror.
|
|
60
|
+
*/
|
|
61
|
+
function resolveCronExpressionMember(node) {
|
|
62
|
+
if (!Node.isPropertyAccessExpression(node))
|
|
63
|
+
return undefined;
|
|
64
|
+
const obj = node.getExpression();
|
|
65
|
+
if (!Node.isIdentifier(obj) || obj.getText() !== "CronExpression")
|
|
66
|
+
return undefined;
|
|
67
|
+
return CRON_EXPRESSION_VALUES[node.getName()];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a node used as a schedule into the neutral structured Schedule. Accepts,
|
|
71
|
+
* in order: a `rate(...)`/`every(...)` helper call; a `CronExpression.MEMBER`
|
|
72
|
+
* reference; a raw AWS `rate(...)`/`cron(...)` string; or a bare node-cron string
|
|
73
|
+
* (the `@nestjs/schedule` form, translated to the AWS dialect — which THROWS a
|
|
74
|
+
* located error for anything EventBridge can't honor). Returns undefined only for
|
|
75
|
+
* non-static input (e.g. a variable), so callers can raise a "not static" error.
|
|
76
|
+
*/
|
|
77
|
+
export function resolveScheduleNode(node, where) {
|
|
78
|
+
if (!node)
|
|
79
|
+
return undefined;
|
|
80
|
+
const folded = foldScheduleCall(node);
|
|
81
|
+
if (folded)
|
|
82
|
+
return folded;
|
|
83
|
+
const enumExpr = resolveCronExpressionMember(node);
|
|
84
|
+
if (enumExpr !== undefined)
|
|
85
|
+
return nestCronToSchedule(enumExpr, where);
|
|
86
|
+
const lit = literalValue(node);
|
|
87
|
+
if (typeof lit === "string") {
|
|
88
|
+
// A wrapped AWS string (`rate(...)`/`cron(...)`) is the native form; anything
|
|
89
|
+
// else that's a string is treated as a node-cron expression and translated.
|
|
90
|
+
return parseScheduleString(lit) ?? nestCronToSchedule(lit, where);
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
/** Return the initializer node of a named property on an object literal. */
|
|
95
|
+
export function getPropertyInitializer(obj, name) {
|
|
96
|
+
const prop = obj.getProperty(name);
|
|
97
|
+
if (prop && Node.isPropertyAssignment(prop))
|
|
98
|
+
return prop.getInitializer();
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
/** Read a decorator's first argument as either a string or a flattened object. */
|
|
102
|
+
export function readDecoratorArg(node) {
|
|
103
|
+
if (!node)
|
|
104
|
+
return { kind: "unknown" };
|
|
105
|
+
const lit = literalValue(node);
|
|
106
|
+
if (typeof lit === "string")
|
|
107
|
+
return { kind: "string", value: lit };
|
|
108
|
+
if (Node.isObjectLiteralExpression(node))
|
|
109
|
+
return { kind: "object", value: objectToRecord(node) };
|
|
110
|
+
return { kind: "unknown" };
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=ast-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../src/ast-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/detect.d.ts
ADDED
package/dist/detect.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
/** Detect the framework from the project's package.json dependencies. */
|
|
4
|
+
export function detectFramework(projectDir) {
|
|
5
|
+
const pkgPath = path.join(projectDir, "package.json");
|
|
6
|
+
if (!existsSync(pkgPath))
|
|
7
|
+
return "express";
|
|
8
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
9
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
10
|
+
if (deps["@nestjs/core"])
|
|
11
|
+
return "nest";
|
|
12
|
+
return "express";
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGnD,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAGnD,CAAC;IACF,MAAM,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;IAC7D,IAAI,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,MAAM,CAAC;IACxC,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/dev-scan.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev helper: scan a project and print its Infra IR.
|
|
3
|
+
* npm run scan:express
|
|
4
|
+
* tsx packages/scanner/src/dev-scan.ts <project-dir>
|
|
5
|
+
*/
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { loadConfig } from "@alzulejos/laranja-core";
|
|
8
|
+
import { scan } from "./scan.js";
|
|
9
|
+
async function main() {
|
|
10
|
+
const dir = path.resolve(process.argv[2] ?? ".");
|
|
11
|
+
const config = await loadConfig(dir);
|
|
12
|
+
const ir = scan({ projectDir: dir, config });
|
|
13
|
+
console.log(JSON.stringify(ir, null, 2));
|
|
14
|
+
}
|
|
15
|
+
main().catch((err) => {
|
|
16
|
+
console.error(err instanceof Error ? err.message : err);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=dev-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-scan.js","sourceRoot":"","sources":["../src/dev-scan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SourceFile } from "ts-morph";
|
|
2
|
+
import type { HttpRoute } from "@alzulejos/laranja-core";
|
|
3
|
+
/**
|
|
4
|
+
* Discover HTTP routes from Nest controllers for visibility/validation — the same
|
|
5
|
+
* role `collectExpressRoutes` plays for Express. Reads `@Controller("prefix")` +
|
|
6
|
+
* method decorators (`@Get`/`@Post`/…) and composes the full route path. Matching
|
|
7
|
+
* is by decorator NAME, which is safe because this only runs for Nest projects.
|
|
8
|
+
*/
|
|
9
|
+
export declare function collectNestRoutes(rel: string, sf: SourceFile, routes: HttpRoute[]): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Node } from "ts-morph";
|
|
2
|
+
import { getPropertyInitializer } from "./ast-utils.js";
|
|
3
|
+
/** Nest HTTP-method decorators -> the HTTP verb they map to. */
|
|
4
|
+
const NEST_HTTP_METHODS = new Map([
|
|
5
|
+
["Get", "GET"],
|
|
6
|
+
["Post", "POST"],
|
|
7
|
+
["Put", "PUT"],
|
|
8
|
+
["Patch", "PATCH"],
|
|
9
|
+
["Delete", "DELETE"],
|
|
10
|
+
["Options", "OPTIONS"],
|
|
11
|
+
["Head", "HEAD"],
|
|
12
|
+
["All", "ALL"],
|
|
13
|
+
]);
|
|
14
|
+
/** Read a path string from a decorator arg: string, `["a","b"]` (first), or object `{ path }`. */
|
|
15
|
+
function pathArg(arg) {
|
|
16
|
+
if (!arg)
|
|
17
|
+
return "";
|
|
18
|
+
if (Node.isStringLiteral(arg) || Node.isNoSubstitutionTemplateLiteral(arg)) {
|
|
19
|
+
return arg.getLiteralText();
|
|
20
|
+
}
|
|
21
|
+
if (Node.isArrayLiteralExpression(arg)) {
|
|
22
|
+
const first = arg.getElements()[0];
|
|
23
|
+
if (first && (Node.isStringLiteral(first) || Node.isNoSubstitutionTemplateLiteral(first))) {
|
|
24
|
+
return first.getLiteralText();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (Node.isObjectLiteralExpression(arg)) {
|
|
28
|
+
return pathArg(getPropertyInitializer(arg, "path"));
|
|
29
|
+
}
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
/** The prefix declared by `@Controller(...)` — string, array, or `{ path }` form. */
|
|
33
|
+
function controllerPrefix(dec) {
|
|
34
|
+
return pathArg(dec.getArguments()[0]);
|
|
35
|
+
}
|
|
36
|
+
/** Join a controller prefix and a method sub-path into one normalized `/path`. */
|
|
37
|
+
function joinPath(prefix, sub) {
|
|
38
|
+
const segments = `${prefix}/${sub}`.split("/").filter(Boolean);
|
|
39
|
+
return "/" + segments.join("/");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Discover HTTP routes from Nest controllers for visibility/validation — the same
|
|
43
|
+
* role `collectExpressRoutes` plays for Express. Reads `@Controller("prefix")` +
|
|
44
|
+
* method decorators (`@Get`/`@Post`/…) and composes the full route path. Matching
|
|
45
|
+
* is by decorator NAME, which is safe because this only runs for Nest projects.
|
|
46
|
+
*/
|
|
47
|
+
export function collectNestRoutes(rel, sf, routes) {
|
|
48
|
+
for (const cls of sf.getClasses()) {
|
|
49
|
+
const controller = cls.getDecorator("Controller");
|
|
50
|
+
if (!controller)
|
|
51
|
+
continue;
|
|
52
|
+
const prefix = controllerPrefix(controller);
|
|
53
|
+
for (const method of cls.getMethods()) {
|
|
54
|
+
for (const dec of method.getDecorators()) {
|
|
55
|
+
const httpMethod = NEST_HTTP_METHODS.get(dec.getName());
|
|
56
|
+
if (!httpMethod)
|
|
57
|
+
continue;
|
|
58
|
+
routes.push({
|
|
59
|
+
method: httpMethod,
|
|
60
|
+
path: joinPath(prefix, pathArg(dec.getArguments()[0])),
|
|
61
|
+
source: `${rel}:${dec.getStartLineNumber()}`,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=nest-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nest-routes.js","sourceRoot":"","sources":["../src/nest-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { InfraIR } from "@alzulejos/laranja-core";
|
|
2
|
+
/**
|
|
3
|
+
* The resource-key ids in a project: "http" (when there's an HTTP app), each
|
|
4
|
+
* cron's id, and each queue's name. This is the one namespace that `resources`
|
|
5
|
+
* overrides and DLQ references address — sorted + de-duplicated.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resourceIds(ir: InfraIR): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Generate the contents of the project's `laranja.types.ts` — the resource‑id
|
|
10
|
+
* unions plus a `TypedLaranjaConfig` alias that maps each key to the right override
|
|
11
|
+
* shape. Post‑consolidation a Nest module is one Lambda, so compute lives on a
|
|
12
|
+
* `WorkerId` (module) key while a grouped cron/queue key only takes its trigger
|
|
13
|
+
* knobs; a standalone handler (Express / function‑style) is its own Lambda and
|
|
14
|
+
* keeps compute + trigger. Opting in (typing the config with `TypedLaranjaConfig`)
|
|
15
|
+
* turns a mistyped id, a compute knob on a grouped handler, or a queue DLQ missing
|
|
16
|
+
* `maxReceiveCount` into a compile‑time error with autocomplete.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateResourceTypes(ir: InfraIR): string;
|
|
19
|
+
/**
|
|
20
|
+
* The stub written by `init`, before any scan has discovered resources. `string`
|
|
21
|
+
* keeps `resources` permissive (any key, compute + trigger) until the first
|
|
22
|
+
* deploy/synth narrows it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateResourceTypesStub(): string;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The resource-key ids in a project: "http" (when there's an HTTP app), each
|
|
3
|
+
* cron's id, and each queue's name. This is the one namespace that `resources`
|
|
4
|
+
* overrides and DLQ references address — sorted + de-duplicated.
|
|
5
|
+
*/
|
|
6
|
+
export function resourceIds(ir) {
|
|
7
|
+
return dedupeSort([
|
|
8
|
+
...(ir.http ? ["http"] : []),
|
|
9
|
+
...ir.crons.map((c) => c.id),
|
|
10
|
+
...ir.queues.map((q) => q.name),
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
/** `"a" | "b"` from ids, or `never` when there are none. */
|
|
14
|
+
function unionOf(ids) {
|
|
15
|
+
return ids.length > 0 ? ids.map((id) => JSON.stringify(id)).join(" | ") : "never";
|
|
16
|
+
}
|
|
17
|
+
function dedupeSort(ids) {
|
|
18
|
+
return [...new Set(ids)].sort();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate the contents of the project's `laranja.types.ts` — the resource‑id
|
|
22
|
+
* unions plus a `TypedLaranjaConfig` alias that maps each key to the right override
|
|
23
|
+
* shape. Post‑consolidation a Nest module is one Lambda, so compute lives on a
|
|
24
|
+
* `WorkerId` (module) key while a grouped cron/queue key only takes its trigger
|
|
25
|
+
* knobs; a standalone handler (Express / function‑style) is its own Lambda and
|
|
26
|
+
* keeps compute + trigger. Opting in (typing the config with `TypedLaranjaConfig`)
|
|
27
|
+
* turns a mistyped id, a compute knob on a grouped handler, or a queue DLQ missing
|
|
28
|
+
* `maxReceiveCount` into a compile‑time error with autocomplete.
|
|
29
|
+
*/
|
|
30
|
+
export function generateResourceTypes(ir) {
|
|
31
|
+
const grouped = (xs, on) => xs.filter((x) => Boolean(x.workersId) === on);
|
|
32
|
+
return render({
|
|
33
|
+
http: unionOf(ir.http ? ["http"] : []),
|
|
34
|
+
worker: unionOf(dedupeSort((ir.workers ?? []).map((w) => w.id))),
|
|
35
|
+
groupedCron: unionOf(dedupeSort(grouped(ir.crons, true).map((c) => c.id))),
|
|
36
|
+
standaloneCron: unionOf(dedupeSort(grouped(ir.crons, false).map((c) => c.id))),
|
|
37
|
+
groupedQueue: unionOf(dedupeSort(grouped(ir.queues, true).map((q) => q.name))),
|
|
38
|
+
standaloneQueue: unionOf(dedupeSort(grouped(ir.queues, false).map((q) => q.name))),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The stub written by `init`, before any scan has discovered resources. `string`
|
|
43
|
+
* keeps `resources` permissive (any key, compute + trigger) until the first
|
|
44
|
+
* deploy/synth narrows it.
|
|
45
|
+
*/
|
|
46
|
+
export function generateResourceTypesStub() {
|
|
47
|
+
return render({
|
|
48
|
+
http: "string",
|
|
49
|
+
worker: "never",
|
|
50
|
+
groupedCron: "never",
|
|
51
|
+
standaloneCron: "string",
|
|
52
|
+
groupedQueue: "never",
|
|
53
|
+
standaloneQueue: "string",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function render(ids) {
|
|
57
|
+
return `// AUTO-GENERATED by laranja — do not edit. Regenerated on deploy/synth/diff.
|
|
58
|
+
import type {
|
|
59
|
+
LaranjaConfig,
|
|
60
|
+
HttpResourceConfig,
|
|
61
|
+
WorkerResourceConfig,
|
|
62
|
+
CronResourceConfig,
|
|
63
|
+
CronTriggerConfig,
|
|
64
|
+
QueueResourceConfig,
|
|
65
|
+
QueueTriggerConfig,
|
|
66
|
+
} from "@alzulejos/laranja-core";
|
|
67
|
+
|
|
68
|
+
/** The HTTP app id, if this project serves one. */
|
|
69
|
+
export type HttpResourceId = ${ids.http};
|
|
70
|
+
/** Worker module ids — each is ONE Lambda; set compute (memory/timeout/…) here. */
|
|
71
|
+
export type WorkerId = ${ids.worker};
|
|
72
|
+
/** Cron ids that share a worker module's Lambda (trigger knobs only). */
|
|
73
|
+
type GroupedCronId = ${ids.groupedCron};
|
|
74
|
+
/** Cron ids that are their own Lambda (Express / function-style): compute + trigger. */
|
|
75
|
+
type StandaloneCronId = ${ids.standaloneCron};
|
|
76
|
+
/** Queue names that share a worker module's Lambda (trigger knobs only). */
|
|
77
|
+
type GroupedQueueId = ${ids.groupedQueue};
|
|
78
|
+
/** Queue names that are their own Lambda (Express / function-style): compute + trigger. */
|
|
79
|
+
type StandaloneQueueId = ${ids.standaloneQueue};
|
|
80
|
+
|
|
81
|
+
/** Cron ids in this project. */
|
|
82
|
+
export type CronResourceId = GroupedCronId | StandaloneCronId;
|
|
83
|
+
/** Queue names in this project (also the valid DLQ targets). */
|
|
84
|
+
export type QueueResourceId = GroupedQueueId | StandaloneQueueId;
|
|
85
|
+
|
|
86
|
+
/** Every resource id: the http id, worker ids, cron ids, and queue names. */
|
|
87
|
+
export type ResourceId = HttpResourceId | WorkerId | CronResourceId | QueueResourceId;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* LaranjaConfig with \`resources\` keys checked against your real resources. Compute
|
|
91
|
+
* lives on a worker module key; a grouped cron/queue takes only its trigger knobs
|
|
92
|
+
* (compute there is a compile error pointing at the module); a standalone handler
|
|
93
|
+
* takes compute + trigger. A queue DLQ requires \`maxReceiveCount\`.
|
|
94
|
+
*/
|
|
95
|
+
export type TypedLaranjaConfig = Omit<LaranjaConfig, "resources"> & {
|
|
96
|
+
resources?: Partial<Record<HttpResourceId, HttpResourceConfig>> &
|
|
97
|
+
Partial<Record<WorkerId, WorkerResourceConfig>> &
|
|
98
|
+
Partial<Record<GroupedCronId, CronTriggerConfig<QueueResourceId>>> &
|
|
99
|
+
Partial<Record<StandaloneCronId, CronResourceConfig<QueueResourceId>>> &
|
|
100
|
+
Partial<Record<GroupedQueueId, QueueTriggerConfig<QueueResourceId>>> &
|
|
101
|
+
Partial<Record<StandaloneQueueId, QueueResourceConfig<QueueResourceId>>>;
|
|
102
|
+
};
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=resource-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-types.js","sourceRoot":"","sources":["../src/resource-types.ts"],"names":[],"mappings":"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"}
|
package/dist/scan.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type InfraIR, type LaranjaConfig } from "@alzulejos/laranja-core";
|
|
2
|
+
export interface ScanInput {
|
|
3
|
+
projectDir: string;
|
|
4
|
+
config: LaranjaConfig & {
|
|
5
|
+
env: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Statically scans the user's project and produces the Infra IR.
|
|
10
|
+
* No user code is executed — this is pure AST analysis.
|
|
11
|
+
*/
|
|
12
|
+
export declare function scan({ projectDir, config }: ScanInput): InfraIR;
|