@lunora/codegen 1.0.0-alpha.2 → 1.0.0-alpha.21
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/__assets__/package-og.svg +1 -1
- package/dist/index.d.mts +444 -16
- package/dist/index.d.ts +444 -16
- package/dist/index.mjs +28 -22
- package/dist/packem_shared/{CONTAINERS_FILENAME-0K-pjNb8.mjs → CONTAINERS_FILENAME-DlP6YM_Q.mjs} +1 -1
- package/dist/packem_shared/{CodegenDiagnosticError-54jWDxA9.mjs → CodegenDiagnosticError-DeblMkzO.mjs} +3 -2
- package/dist/packem_shared/FLAGS_FILENAME-B1vE0LIo.mjs +139 -0
- package/dist/packem_shared/{emitApi-hRVC-kE7.mjs → GENERATED_HEADER-CI272wRm.mjs} +873 -54
- package/dist/packem_shared/LUNORA_SOLUTION_RULES-BTejmZp-.mjs +131 -0
- package/dist/packem_shared/MUTATORS_FILENAME-BhqdPtKp.mjs +81 -0
- package/dist/packem_shared/{buildOpenRpcDocument-BZGY1-jT.mjs → OPENRPC_VERSION-t5pV2NIN.mjs} +1 -1
- package/dist/packem_shared/QUEUES_FILENAME-B5_eWCRe.mjs +119 -0
- package/dist/packem_shared/{createCodegenProject-DGJm0_Pk.mjs → SCHEMA_SNAPSHOT_FILENAME-BMez-jgr.mjs} +187 -43
- package/dist/packem_shared/{buildSchemaSnapshot-DzLDbWk3.mjs → SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs} +12 -0
- package/dist/packem_shared/SHAPES_FILENAME-ChV7MqgE.mjs +94 -0
- package/dist/packem_shared/{discoverWorkflows-DRDQdhfq.mjs → WORKFLOWS_FILENAME-CCisG0Vy.mjs} +42 -2
- package/dist/packem_shared/{buildOpenApiDocument-yHVN66Xd.mjs → buildOpenApiDocument-Dx5QftUn.mjs} +1 -1
- package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-CoirYbg6.mjs} +1 -1
- package/dist/packem_shared/{discoverCrons-BL6iGuJ3.mjs → discoverCrons-Cev7RRAf.mjs} +20 -17
- package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-BWMczzBx.mjs} +7 -2
- package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-CfP6cMzt.mjs} +2 -2
- package/dist/packem_shared/{discoverInserts-CRQdXvHO.mjs → discoverInserts-C7zxXkUf.mjs} +24 -2
- package/dist/packem_shared/{discoverMaskProcedures-B64zA740.mjs → discoverMaskProcedures-Cm81kwrb.mjs} +1 -1
- package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-Bi5nJ0mJ.mjs} +10 -4
- package/dist/packem_shared/{discoverNondeterministicCalls-4KiPQxQU.mjs → discoverNondeterministicCalls-C4M8AXmQ.mjs} +1 -1
- package/dist/packem_shared/{discoverQueries-BkIi0dBD.mjs → discoverQueries-B0wGT-xe.mjs} +1 -1
- package/dist/packem_shared/discoverR2sqlCalls-BVNMd428.mjs +80 -0
- package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-BS9GOGC5.mjs} +1 -1
- package/dist/packem_shared/{discoverSchema-BBulgGbH.mjs → discoverSchema-KYq55qu3.mjs} +338 -16
- package/dist/packem_shared/{discoverStorageRulesMetadata-DAqJUxUv.mjs → discoverStorageRulesMetadata-Da8BKXcI.mjs} +1 -1
- package/dist/packem_shared/{emitApp-CzZ6GbrD.mjs → emitApp-cOSypPuO.mjs} +74 -8
- package/dist/packem_shared/{lintSchema-DicbOHvH.mjs → formatAdvisories-DdjK7sgh.mjs} +15 -2
- package/dist/packem_shared/{parse-validator-tuQtHrsr.mjs → parse-validator-Cabb60UV.mjs} +2 -1
- package/package.json +8 -7
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const LUNORA_SOLUTION_RULES = [
|
|
2
|
+
{
|
|
3
|
+
body: [
|
|
4
|
+
"Lunora codegen couldn't find a schema to generate from.",
|
|
5
|
+
"",
|
|
6
|
+
"Create `lunora/schema.ts` exporting a `defineSchema(...)` call:",
|
|
7
|
+
"",
|
|
8
|
+
"```ts",
|
|
9
|
+
'import { defineSchema, defineTable, v } from "@lunora/server";',
|
|
10
|
+
"",
|
|
11
|
+
"export default defineSchema({",
|
|
12
|
+
" messages: defineTable({ body: v.string() }),",
|
|
13
|
+
"});",
|
|
14
|
+
"```",
|
|
15
|
+
"",
|
|
16
|
+
"Or run `lunora init` to scaffold Lunora (a sample `lunora/schema.ts` included) into your app."
|
|
17
|
+
].join("\n"),
|
|
18
|
+
header: "No Lunora schema found",
|
|
19
|
+
id: "lunora-schema-missing",
|
|
20
|
+
test: (message) => message.includes("defineSchema() not found") || message.includes("schema.ts not found at")
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
body: [
|
|
24
|
+
"`defineSchema(...)` must be called with an **inline object literal** mapping table names to `defineTable(...)`:",
|
|
25
|
+
"",
|
|
26
|
+
"```ts",
|
|
27
|
+
"export default defineSchema({",
|
|
28
|
+
" todos: defineTable({ title: v.string(), done: v.boolean() }),",
|
|
29
|
+
"});",
|
|
30
|
+
"```",
|
|
31
|
+
"",
|
|
32
|
+
"Codegen reads the schema statically, so it can't follow a variable or a spread — pass the object literal directly."
|
|
33
|
+
].join("\n"),
|
|
34
|
+
header: "`defineSchema()` needs an inline object literal",
|
|
35
|
+
id: "lunora-schema-not-object-literal",
|
|
36
|
+
test: (message) => message.includes("defineSchema() expects an object literal")
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
body: [
|
|
40
|
+
"This table name collides with a built-in `ctx.db` member, so the generated client can't expose it.",
|
|
41
|
+
"",
|
|
42
|
+
"Rename the table to anything that isn't a reserved name (the error lists them) — e.g. `userAccounts` instead of `insert`."
|
|
43
|
+
].join("\n"),
|
|
44
|
+
header: "Table name is reserved",
|
|
45
|
+
id: "lunora-table-reserved",
|
|
46
|
+
test: (message) => message.includes("is reserved") && message.includes("ctx.db")
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
body: [
|
|
50
|
+
"Two tables resolve to the same name — usually a base table and a schema **extension** both defining it.",
|
|
51
|
+
"",
|
|
52
|
+
"Rename one of them, or drop the duplicate from the extension. Each table name must be unique across `defineSchema(...)` and every `.extend(...)`."
|
|
53
|
+
].join("\n"),
|
|
54
|
+
header: "Duplicate table name",
|
|
55
|
+
id: "lunora-table-duplicate",
|
|
56
|
+
// Anchor on `.extend(` — the only Lunora throw for this is
|
|
57
|
+
// `defineSchema(...).extend(...): table "x" already exists …`. Matching a
|
|
58
|
+
// bare "already exists"/"extension" pair would false-positive on
|
|
59
|
+
// unrelated forwarded errors (e.g. a "file already exists" + "extension").
|
|
60
|
+
test: (message) => message.includes("already exists") && message.includes(".extend(")
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
body: [
|
|
64
|
+
'`.jurisdiction(...)` accepts only a **string literal** of `"eu"`, `"us"`, or `"fedramp"`:',
|
|
65
|
+
"",
|
|
66
|
+
"```ts",
|
|
67
|
+
'defineSchema({ /* … */ }).jurisdiction("eu");',
|
|
68
|
+
"```"
|
|
69
|
+
].join("\n"),
|
|
70
|
+
header: "Invalid `.jurisdiction(...)` value",
|
|
71
|
+
id: "lunora-jurisdiction",
|
|
72
|
+
test: (message) => message.includes("unknown jurisdiction") || message.includes("jurisdiction") && message.includes('"eu", "us", or "fedramp"')
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
body: [
|
|
76
|
+
"The `unique` flag on an index must be a **literal** `true` or `false`, not a computed value — codegen needs to read it statically:",
|
|
77
|
+
"",
|
|
78
|
+
"```ts",
|
|
79
|
+
'defineTable({ email: v.string() }).index("by_email", ["email"], { unique: true });',
|
|
80
|
+
"```"
|
|
81
|
+
].join("\n"),
|
|
82
|
+
header: "`unique` must be a literal",
|
|
83
|
+
id: "lunora-unique-literal",
|
|
84
|
+
test: (message) => message.includes("must be a literal") && message.includes("unique")
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
body: [
|
|
88
|
+
"A declared container/workflow class isn't re-exported by your worker entry, so `wrangler deploy` would reject it.",
|
|
89
|
+
"",
|
|
90
|
+
"Add the generated re-export shown in the error to your worker entry (e.g. `src/index.ts`):",
|
|
91
|
+
"",
|
|
92
|
+
"```ts",
|
|
93
|
+
'export * from "./lunora/_generated/containers";',
|
|
94
|
+
"```"
|
|
95
|
+
].join("\n"),
|
|
96
|
+
header: "Binding not exported by your worker entry",
|
|
97
|
+
id: "lunora-worker-entry-export-gap",
|
|
98
|
+
test: (message) => message.includes("not exported by your worker entry")
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
body: [
|
|
102
|
+
"A row with the same value already exists in a `unique` index.",
|
|
103
|
+
"",
|
|
104
|
+
"- If you meant to upsert, use `ctx.db.<table>().upsert(...)` (or `.patch(...)` an existing row) instead of `.insert(...)`.",
|
|
105
|
+
`- Otherwise pick a value that isn't already taken, and consider surfacing a friendly "already exists" message to the user.`
|
|
106
|
+
].join("\n"),
|
|
107
|
+
header: "Unique constraint violation",
|
|
108
|
+
id: "lunora-runtime-unique",
|
|
109
|
+
test: (message) => message.includes("unique constraint violation on")
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
body: [
|
|
113
|
+
"Another write changed this row while your mutation was running (optimistic concurrency conflict).",
|
|
114
|
+
"",
|
|
115
|
+
"Re-read the row and retry the mutation with the fresh value. Lunora serializes a DO's mutations, so a persistent conflict usually means the handler conflicts **with itself** (e.g. a trigger or cascade touching the same row) — split that work rather than adding a retry loop."
|
|
116
|
+
].join("\n"),
|
|
117
|
+
header: "Optimistic concurrency conflict",
|
|
118
|
+
id: "lunora-runtime-occ",
|
|
119
|
+
test: (message) => message.includes("optimistic concurrency conflict")
|
|
120
|
+
}
|
|
121
|
+
];
|
|
122
|
+
const findLunoraSolution = (message) => {
|
|
123
|
+
for (const rule of LUNORA_SOLUTION_RULES) {
|
|
124
|
+
if (rule.test(message)) {
|
|
125
|
+
return { body: rule.body, header: rule.header, id: rule.id };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return void 0;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export { LUNORA_SOLUTION_RULES, findLunoraSolution };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
4
|
+
import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
|
|
5
|
+
|
|
6
|
+
const MUTATORS_FILENAME = "mutators.ts";
|
|
7
|
+
const MUTATOR_MODULE_SPECIFIERS = /* @__PURE__ */ new Set(["@lunora/server", "lunorash/server"]);
|
|
8
|
+
const isDefineMutator = (identifier) => {
|
|
9
|
+
const symbol = identifier.getSymbol();
|
|
10
|
+
if (!symbol) {
|
|
11
|
+
return identifier.getText() === "defineMutator";
|
|
12
|
+
}
|
|
13
|
+
for (const declaration of symbol.getDeclarations()) {
|
|
14
|
+
if (!Node.isImportSpecifier(declaration)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (!MUTATOR_MODULE_SPECIFIERS.has(declaration.getImportDeclaration().getModuleSpecifierValue())) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return declaration.getNameNode().getText() === "defineMutator";
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
const isMutatorNamespaceImport = (identifier) => {
|
|
25
|
+
const symbol = identifier.getSymbol();
|
|
26
|
+
if (!symbol) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
for (const declaration of symbol.getDeclarations()) {
|
|
30
|
+
if (!Node.isNamespaceImport(declaration)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const importDeclaration = declaration.getFirstAncestorByKind(SyntaxKind.ImportDeclaration);
|
|
34
|
+
return importDeclaration !== void 0 && MUTATOR_MODULE_SPECIFIERS.has(importDeclaration.getModuleSpecifierValue());
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
};
|
|
38
|
+
const isDefineMutatorCallee = (callee) => {
|
|
39
|
+
if (Node.isIdentifier(callee)) {
|
|
40
|
+
return isDefineMutator(callee);
|
|
41
|
+
}
|
|
42
|
+
if (Node.isPropertyAccessExpression(callee)) {
|
|
43
|
+
const object = callee.getExpression();
|
|
44
|
+
return callee.getName() === "defineMutator" && Node.isIdentifier(object) && isMutatorNamespaceImport(object);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
};
|
|
48
|
+
const mutatorsFromSource = (source) => {
|
|
49
|
+
const mutators = [];
|
|
50
|
+
for (const declaration of source.getVariableDeclarations()) {
|
|
51
|
+
if (!declaration.isExported()) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const initializer = declaration.getInitializer();
|
|
55
|
+
if (initializer?.getKind() !== SyntaxKind.CallExpression) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const callee = initializer.getExpression();
|
|
59
|
+
if (!isDefineMutatorCallee(callee)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const nameNode = declaration.getNameNode();
|
|
63
|
+
if (!Node.isIdentifier(nameNode)) {
|
|
64
|
+
throw diagnosticAt(nameNode, "defineMutator exports must be plain named exports (no destructuring)");
|
|
65
|
+
}
|
|
66
|
+
mutators.push({ exportName: nameNode.getText(), filePath: "mutators" });
|
|
67
|
+
}
|
|
68
|
+
return mutators;
|
|
69
|
+
};
|
|
70
|
+
const discoverMutators = (project, lunoraDirectory) => {
|
|
71
|
+
const mutatorsPath = join(lunoraDirectory, MUTATORS_FILENAME);
|
|
72
|
+
if (!existsSync(mutatorsPath)) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const source = project.getSourceFile(mutatorsPath) ?? project.addSourceFileAtPath(mutatorsPath);
|
|
76
|
+
const mutators = mutatorsFromSource(source);
|
|
77
|
+
mutators.sort((a, b) => a.exportName.localeCompare(b.exportName));
|
|
78
|
+
return mutators;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export { MUTATORS_FILENAME, discoverMutators, isDefineMutatorCallee };
|
package/dist/packem_shared/{buildOpenRpcDocument-BZGY1-jT.mjs → OPENRPC_VERSION-t5pV2NIN.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GENERATED_HEADER } from './
|
|
1
|
+
import { GENERATED_HEADER } from './GENERATED_HEADER-CI272wRm.mjs';
|
|
2
2
|
import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
|
|
3
3
|
import { argsObjectSchema, LUNORA_ERROR_CODES } from './LUNORA_ERROR_CODES-CySpQPD3.mjs';
|
|
4
4
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { queueDefaultName, queueBindingName } from '@lunora/queue';
|
|
4
|
+
import { SyntaxKind, Node } from 'ts-morph';
|
|
5
|
+
import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
|
|
6
|
+
|
|
7
|
+
const QUEUES_FILENAME = "queues.ts";
|
|
8
|
+
const isDefineQueue = (identifier) => {
|
|
9
|
+
const symbol = identifier.getSymbol();
|
|
10
|
+
if (!symbol) {
|
|
11
|
+
return identifier.getText() === "defineQueue";
|
|
12
|
+
}
|
|
13
|
+
for (const declaration of symbol.getDeclarations()) {
|
|
14
|
+
if (!Node.isImportSpecifier(declaration)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (declaration.getImportDeclaration().getModuleSpecifierValue() !== "@lunora/queue") {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return declaration.getNameNode().getText() === "defineQueue";
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
const stringProperty = (expression, exportName, property) => {
|
|
25
|
+
if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
|
|
26
|
+
return expression.getLiteralValue();
|
|
27
|
+
}
|
|
28
|
+
throw diagnosticAt(
|
|
29
|
+
expression,
|
|
30
|
+
`queue "${exportName}": \`${property}\` must be a static string literal — it is deploy configuration codegen writes into wrangler.jsonc`
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
const numberProperty = (expression, exportName, property) => {
|
|
34
|
+
if (Node.isNumericLiteral(expression)) {
|
|
35
|
+
return expression.getLiteralValue();
|
|
36
|
+
}
|
|
37
|
+
throw diagnosticAt(
|
|
38
|
+
expression,
|
|
39
|
+
`queue "${exportName}": \`${property}\` must be a static numeric literal — it is deploy configuration codegen writes into wrangler.jsonc`
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
const queueNameOverride = (argument, exportName) => {
|
|
43
|
+
const nameProperty = argument.getProperty("name");
|
|
44
|
+
if (!nameProperty || !Node.isPropertyAssignment(nameProperty)) {
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
const name = stringProperty(nameProperty.getInitializerOrThrow(), exportName, "name");
|
|
48
|
+
if (name.length === 0) {
|
|
49
|
+
throw diagnosticAt(nameProperty, `queue "${exportName}": \`name\` must be a non-empty string when provided`);
|
|
50
|
+
}
|
|
51
|
+
return name;
|
|
52
|
+
};
|
|
53
|
+
const queueFromCall = (call, exportName) => {
|
|
54
|
+
const argument = call.getArguments()[0];
|
|
55
|
+
if (!argument || !Node.isObjectLiteralExpression(argument)) {
|
|
56
|
+
throw diagnosticAt(call, `queue "${exportName}": defineQueue must be passed an inline object literal`);
|
|
57
|
+
}
|
|
58
|
+
const ir = {
|
|
59
|
+
bindingName: queueBindingName(exportName),
|
|
60
|
+
exportName,
|
|
61
|
+
mode: "push",
|
|
62
|
+
name: queueNameOverride(argument, exportName) ?? queueDefaultName(exportName),
|
|
63
|
+
tuning: {}
|
|
64
|
+
};
|
|
65
|
+
const modeProperty = argument.getProperty("mode");
|
|
66
|
+
if (modeProperty && Node.isPropertyAssignment(modeProperty)) {
|
|
67
|
+
const mode = stringProperty(modeProperty.getInitializerOrThrow(), exportName, "mode");
|
|
68
|
+
if (mode !== "push" && mode !== "pull") {
|
|
69
|
+
throw diagnosticAt(modeProperty, `queue "${exportName}": \`mode\` must be "push" or "pull" (got ${JSON.stringify(mode)})`);
|
|
70
|
+
}
|
|
71
|
+
ir.mode = mode;
|
|
72
|
+
}
|
|
73
|
+
const dlqProperty = argument.getProperty("deadLetterQueue");
|
|
74
|
+
if (dlqProperty && Node.isPropertyAssignment(dlqProperty)) {
|
|
75
|
+
ir.tuning.deadLetterQueue = stringProperty(dlqProperty.getInitializerOrThrow(), exportName, "deadLetterQueue");
|
|
76
|
+
}
|
|
77
|
+
for (const property of ["maxBatchSize", "maxBatchTimeout", "maxRetries", "retryDelay"]) {
|
|
78
|
+
const node = argument.getProperty(property);
|
|
79
|
+
if (node && Node.isPropertyAssignment(node)) {
|
|
80
|
+
ir.tuning[property] = numberProperty(node.getInitializerOrThrow(), exportName, property);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return ir;
|
|
84
|
+
};
|
|
85
|
+
const queuesFromSource = (source) => {
|
|
86
|
+
const queues = [];
|
|
87
|
+
for (const declaration of source.getVariableDeclarations()) {
|
|
88
|
+
if (!declaration.isExported()) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const initializer = declaration.getInitializer();
|
|
92
|
+
if (initializer?.getKind() !== SyntaxKind.CallExpression) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const call = initializer;
|
|
96
|
+
const callee = call.getExpression();
|
|
97
|
+
if (!Node.isIdentifier(callee) || !isDefineQueue(callee)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const nameNode = declaration.getNameNode();
|
|
101
|
+
if (!Node.isIdentifier(nameNode)) {
|
|
102
|
+
throw diagnosticAt(nameNode, "defineQueue exports must be plain named exports (no destructuring)");
|
|
103
|
+
}
|
|
104
|
+
queues.push(queueFromCall(call, nameNode.getText()));
|
|
105
|
+
}
|
|
106
|
+
return queues;
|
|
107
|
+
};
|
|
108
|
+
const discoverQueues = (project, lunoraDirectory) => {
|
|
109
|
+
const queuesPath = join(lunoraDirectory, QUEUES_FILENAME);
|
|
110
|
+
if (!existsSync(queuesPath)) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
const source = project.getSourceFile(queuesPath) ?? project.addSourceFileAtPath(queuesPath);
|
|
114
|
+
const queues = queuesFromSource(source);
|
|
115
|
+
queues.sort((a, b) => a.exportName.localeCompare(b.exportName));
|
|
116
|
+
return queues;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export { QUEUES_FILENAME, discoverQueues };
|