@lunora/config 1.0.0-alpha.80 → 1.0.0-alpha.82

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.
Files changed (81) hide show
  1. package/dist/index.mjs +1 -30
  2. package/dist/packem_shared/ACCENT-CLeV5v0K.mjs +7 -0
  3. package/dist/packem_shared/AGENT_MODE_ENV-B54hVQ_w.mjs +1 -0
  4. package/dist/packem_shared/AGENT_RULES_DIR-hP9TiDNx.mjs +1 -0
  5. package/dist/packem_shared/DEV_DAEMON_ENV-D9Z83rlU.mjs +4 -0
  6. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-DX6xGbpr.mjs +1 -0
  7. package/dist/packem_shared/LINKED_PROJECT_DIR-CMzUvj-1.mjs +2 -0
  8. package/dist/packem_shared/LUNORA_CONFIG_FILE-3bpx6TZN.mjs +1 -0
  9. package/dist/packem_shared/LUNORA_EVENT_SOURCE-ZclWASXS.mjs +1 -0
  10. package/dist/packem_shared/LunoraReporter-BnXUqh8t.mjs +6 -0
  11. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-BgmvEPA-.mjs +1 -0
  12. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CUYWD0Mh.mjs +1 -0
  13. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-ws6iE0y-.mjs +1 -0
  14. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-DPcRuAhj.mjs +1 -0
  15. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-CZ8rSh2k.mjs +1 -0
  16. package/dist/packem_shared/SEED_ENDPOINT-BaYShU8q.mjs +1 -0
  17. package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-B1h_wNDN.mjs +1 -0
  18. package/dist/packem_shared/WRANGLER_FILES-Bi_18Pj6.mjs +1 -0
  19. package/dist/packem_shared/applyAdditiveEdit-BdcnSa-j.mjs +6 -0
  20. package/dist/packem_shared/assetContentType-DNZyUOuF.mjs +1 -0
  21. package/dist/packem_shared/buildPackageSecretsBlock-BpvaZzQ8.mjs +18 -0
  22. package/dist/packem_shared/classifyPolicyEdit-BzC_MfYK.mjs +24 -0
  23. package/dist/packem_shared/collectWranglerSecretVariables-OacEwPmL.mjs +1 -0
  24. package/dist/packem_shared/createConfirm-7IL0kZyE.mjs +7 -0
  25. package/dist/packem_shared/detectFramework-VTQfCNXy.mjs +1 -0
  26. package/dist/packem_shared/discoverAgentInfo-BJm0QtoI.mjs +1 -0
  27. package/dist/packem_shared/discoverContainerInfo-CYG9j2LY.mjs +1 -0
  28. package/dist/packem_shared/discoverSchemaInfo-B2W3VrcT.mjs +1 -0
  29. package/dist/packem_shared/discoverWorkflowInfo-Bbc0u2gE.mjs +1 -0
  30. package/dist/packem_shared/inferLunoraBindings-DWSabh1j.mjs +1 -0
  31. package/dist/packem_shared/jsonc-edit-BZVpxVA0.mjs +1 -0
  32. package/dist/packem_shared/parseDevVariable-NAVJ8tgA.mjs +1 -0
  33. package/dist/packem_shared/parseSchema-BPmtMgmb.mjs +1 -0
  34. package/dist/packem_shared/reconcileWranglerBindings-Dd3tLauZ.mjs +1 -0
  35. package/dist/packem_shared/reconcileWranglerCompatibilityDate-BXNiEQ7p.mjs +1 -0
  36. package/dist/packem_shared/reconcileWranglerCrons-BmQa_kGL.mjs +1 -0
  37. package/dist/packem_shared/renderStudioHtml-B2AkxcW1.mjs +15 -0
  38. package/dist/packem_shared/serveJsonHandler-C5GWlWJF.mjs +1 -0
  39. package/dist/packem_shared/streamContainerLogs-BPYBNrWS.mjs +2 -0
  40. package/dist/packem_shared/write-atomic-Cdr2oQb-.mjs +1 -0
  41. package/dist/studio-host/index.mjs +1 -7
  42. package/package.json +3 -3
  43. package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
  44. package/dist/packem_shared/AGENT_MODE_ENV-B5R7jpY7.mjs +0 -17
  45. package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
  46. package/dist/packem_shared/DEV_DAEMON_ENV-FIEtW7Fz.mjs +0 -163
  47. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
  48. package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
  49. package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
  50. package/dist/packem_shared/LUNORA_EVENT_SOURCE-M1KM9_pR.mjs +0 -112
  51. package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
  52. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-NCTSphDk.mjs +0 -138
  53. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CvTZpaZF.mjs +0 -100
  54. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-C-F_Flgy.mjs +0 -100
  55. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-DP0SFVy9.mjs +0 -607
  56. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Bt2SNkpV.mjs +0 -95
  57. package/dist/packem_shared/SEED_ENDPOINT-7izz_Jao.mjs +0 -61
  58. package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-CaXbS7CX.mjs +0 -11
  59. package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
  60. package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
  61. package/dist/packem_shared/assetContentType-ByZjeV3D.mjs +0 -72
  62. package/dist/packem_shared/buildPackageSecretsBlock-BxOcyaAY.mjs +0 -281
  63. package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
  64. package/dist/packem_shared/collectWranglerSecretVariables-BRWIvT-e.mjs +0 -56
  65. package/dist/packem_shared/createConfirm-BMikeJC9.mjs +0 -117
  66. package/dist/packem_shared/detectFramework-U08038Yp.mjs +0 -41
  67. package/dist/packem_shared/discoverAgentInfo-eXA3hF4v.mjs +0 -19
  68. package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
  69. package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
  70. package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
  71. package/dist/packem_shared/inferLunoraBindings-BcvvtpSG.mjs +0 -397
  72. package/dist/packem_shared/jsonc-edit-SbcD7MAe.mjs +0 -9
  73. package/dist/packem_shared/parseDevVariable-B0FEvfHC.mjs +0 -21
  74. package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
  75. package/dist/packem_shared/reconcileWranglerBindings-2Cww5VLa.mjs +0 -362
  76. package/dist/packem_shared/reconcileWranglerCompatibilityDate-C8c497ag.mjs +0 -31
  77. package/dist/packem_shared/reconcileWranglerCrons-DvsceVFz.mjs +0 -29
  78. package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
  79. package/dist/packem_shared/serveJsonHandler-Cl2Wqkv8.mjs +0 -86
  80. package/dist/packem_shared/streamContainerLogs-BZ4cOZwH.mjs +0 -157
  81. package/dist/packem_shared/write-atomic-B2REqapi.mjs +0 -14
@@ -1,362 +0,0 @@
1
- import { writeFileSync } from 'node:fs';
2
- import { containerBuildTag } from '@lunora/container';
3
- import { a as applyModify } from './jsonc-edit-SbcD7MAe.mjs';
4
- import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
5
-
6
- const D1_PLACEHOLDER_ID = "<replace-with-d1-create-id>";
7
- const collectExportGaps = (inferred) => {
8
- const gaps = [];
9
- for (const container of inferred.containers) {
10
- if (!container.exported) {
11
- gaps.push({ className: container.className, exportName: container.exportName, kind: "container", module: "containers" });
12
- }
13
- }
14
- for (const workflow of inferred.workflows) {
15
- if (!workflow.exported) {
16
- gaps.push({ className: workflow.className, exportName: workflow.exportName, kind: "workflow", module: "workflows" });
17
- }
18
- }
19
- for (const agent of inferred.agents) {
20
- if (!agent.exported) {
21
- gaps.push({ className: agent.className, exportName: agent.exportName, kind: "agent", module: "agents" });
22
- }
23
- }
24
- return gaps;
25
- };
26
- const collectHintBindingWarnings = (inferred, parsed) => {
27
- const flagshipBindingMissing = inferred.flagshipBinding !== void 0 && !(parsed?.flagship ?? []).some((entry) => entry.binding === inferred.flagshipBinding);
28
- const rules = [
29
- [
30
- inferred.usesKv && (parsed?.kv_namespaces?.length ?? 0) === 0,
31
- "@lunora/bindings/kv is used but no kv_namespaces binding exists; add a kv_namespaces entry ({ binding, id }) and pass env.<BINDING> to createKv() — the namespace id can't be auto-provisioned."
32
- ],
33
- [
34
- inferred.usesHyperdrive && (parsed?.hyperdrive?.length ?? 0) === 0,
35
- "@lunora/hyperdrive is used but no hyperdrive binding exists; run 'wrangler hyperdrive create' and add a 'hyperdrive' binding ({ binding, id }) — the id can't be auto-provisioned."
36
- ],
37
- [
38
- inferred.usesPipelines && (parsed?.pipelines?.length ?? 0) === 0,
39
- "ctx.pipelines is used but no pipelines binding exists; run 'wrangler pipelines create <name>' and add a 'pipelines' binding ({ binding, pipeline }) — the pipeline resource can't be auto-provisioned."
40
- ],
41
- [
42
- flagshipBindingMissing,
43
- `lunora/flags.ts uses Flagship in binding mode but no flagship binding "${inferred.flagshipBinding ?? ""}" exists; add a flagship entry ({ binding: "${inferred.flagshipBinding ?? ""}", app_id }) — the app_id can't be auto-provisioned.`
44
- ]
45
- ];
46
- return rules.filter(([active]) => active).map(([, warning]) => warning);
47
- };
48
- const collectX402Warnings = (inferred) => {
49
- const rules = [
50
- [
51
- inferred.usesX402Charge,
52
- "@lunora/x402/charge is used; set the recipient wallet address as a [vars] entry (the var name is your choice) and pass it to the charge config — the x402 facilitator settles USDC to that address."
53
- ],
54
- [
55
- inferred.usesX402Pay,
56
- "@lunora/x402/pay is used (ActionCtx-only, spends real funds); add a secrets_store_secrets[] binding holding the agent wallet key (binding name == signer.secretName) and pair the pay rail with a spend policy — ctx.secrets reads a Secrets Store binding, not .dev.vars."
57
- ]
58
- ];
59
- return rules.filter(([active]) => active).map(([, warning]) => warning);
60
- };
61
- const unexportedDeclarationWarnings = (kind, module, declarations) => declarations.filter((declaration) => !declaration.exported).map(
62
- (declaration) => `${kind} "${declaration.exportName}" is declared but ${declaration.className} is not exported by the worker entry; add \`export * from "./lunora/_generated/${module}"\` so its binding can be provisioned.`
63
- );
64
- const collectWarnings = (inferred, parsed) => {
65
- const exported = new Set(inferred.durableObjects.map((object) => object.className));
66
- const warnings = [];
67
- const hasR2Bucket = (parsed?.r2_buckets?.length ?? 0) > 0;
68
- const hasSessionStore = (parsed?.d1_databases?.some((binding) => binding.binding === "DB") ?? false) || inferred.needsD1;
69
- if (inferred.usesStorage && !hasR2Bucket) {
70
- warnings.push(
71
- "@lunora/storage is used but R2 bucket bindings have user-defined names; add an r2_buckets entry and pass env.<BINDING> to createStorage()."
72
- );
73
- }
74
- if (inferred.usesAuth && !exported.has("SessionDO") && !hasSessionStore) {
75
- warnings.push(
76
- "@lunora/auth is used but the worker entry exports no SessionDO; sessions are D1-backed, or export SessionDO to enable DO-backed sessions."
77
- );
78
- }
79
- if (inferred.usesScheduler && !exported.has("SchedulerDO")) {
80
- warnings.push("@lunora/scheduler is used but the worker entry exports no SchedulerDO; export it so the SCHEDULER binding can be provisioned.");
81
- }
82
- warnings.push(
83
- ...unexportedDeclarationWarnings("container", "containers", inferred.containers),
84
- ...unexportedDeclarationWarnings("workflow", "workflows", inferred.workflows),
85
- ...unexportedDeclarationWarnings("agent", "agents", inferred.agents)
86
- );
87
- if (inferred.containers.length > 0 && parsed?.observability?.enabled === false) {
88
- warnings.push("containers are declared but observability is explicitly disabled in wrangler.jsonc — container logs will not be captured.");
89
- }
90
- if (inferred.usesPayment) {
91
- warnings.push(
92
- "@lunora/payment is used; set the provider secrets in .dev.vars — STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET (Stripe) or POLAR_ACCESS_TOKEN + POLAR_WEBHOOK_SECRET (Polar)."
93
- );
94
- }
95
- warnings.push(...collectX402Warnings(inferred), ...collectHintBindingWarnings(inferred, parsed));
96
- return warnings;
97
- };
98
- const nextMigrationTag = (migrations) => {
99
- const used = new Set(migrations.map((migration) => migration.tag));
100
- let index = 1;
101
- while (used.has(`v${String(index)}`)) {
102
- index += 1;
103
- }
104
- return `v${String(index)}`;
105
- };
106
- const reconcileDurableObjects = (text, parsed, required) => {
107
- const existingBindings = parsed.durable_objects?.bindings ?? [];
108
- const existingNames = new Set(existingBindings.map((binding) => binding.name));
109
- const missing = required.filter((object) => !existingNames.has(object.binding));
110
- let nextText = text;
111
- const added = [];
112
- if (missing.length > 0) {
113
- const nextBindings = [
114
- ...existingBindings,
115
- ...missing.map((object) => {
116
- return { class_name: object.className, name: object.binding };
117
- })
118
- ];
119
- nextText = applyModify(nextText, ["durable_objects", "bindings"], nextBindings);
120
- added.push(...missing.map((object) => `${object.binding}/${object.className}`));
121
- }
122
- const migrations = parsed.migrations ?? [];
123
- const registered = new Set(migrations.flatMap((migration) => [...migration.new_sqlite_classes ?? [], ...migration.new_classes ?? []]));
124
- const missingClasses = required.map((object) => object.className).filter((className) => !registered.has(className));
125
- if (missingClasses.length > 0) {
126
- const nextMigrations = [...migrations, { new_sqlite_classes: missingClasses, tag: nextMigrationTag(migrations) }];
127
- nextText = applyModify(nextText, ["migrations"], nextMigrations);
128
- }
129
- return { added, text: nextText };
130
- };
131
- const reconcileD1 = (text, parsed) => {
132
- const d1Bindings = parsed.d1_databases ?? [];
133
- if (d1Bindings.some((binding) => binding.binding === "DB")) {
134
- return { added: [], text };
135
- }
136
- const databaseName = typeof parsed.name === "string" && parsed.name.length > 0 ? parsed.name : "lunora";
137
- const nextD1 = [...d1Bindings, { binding: "DB", database_id: D1_PLACEHOLDER_ID, database_name: databaseName }];
138
- return { added: ["DB (D1)"], text: applyModify(text, ["d1_databases"], nextD1) };
139
- };
140
- const reconcileSelfDescribing = (text, parsed, key, binding, label) => {
141
- const current = parsed[key]?.binding;
142
- if (typeof current === "string" && current.length > 0) {
143
- return { added: [], text };
144
- }
145
- return { added: [label], text: applyModify(text, [key], { binding }) };
146
- };
147
- const reconcileAnalytics = (text, parsed) => {
148
- if ((parsed.analytics_engine_datasets?.length ?? 0) > 0) {
149
- return { added: [], text };
150
- }
151
- const nextDatasets = [{ binding: "ANALYTICS", dataset: "ANALYTICS" }];
152
- return { added: ["ANALYTICS (Analytics Engine)"], text: applyModify(text, ["analytics_engine_datasets"], nextDatasets) };
153
- };
154
- const wranglerInstanceType = (instanceType) => {
155
- if (typeof instanceType === "string") {
156
- return instanceType;
157
- }
158
- const custom = {};
159
- if (instanceType.diskMb !== void 0) {
160
- custom.disk_mb = instanceType.diskMb;
161
- }
162
- if (instanceType.memoryMib !== void 0) {
163
- custom.memory_mib = instanceType.memoryMib;
164
- }
165
- if (instanceType.vcpu !== void 0) {
166
- custom.vcpu = instanceType.vcpu;
167
- }
168
- return custom;
169
- };
170
- const imageRefFor = (container) => {
171
- if (container.image.kind === "dockerfile") {
172
- return container.image.dockerfilePath;
173
- }
174
- if (container.image.kind === "registry") {
175
- return container.image.reference;
176
- }
177
- return containerBuildTag(container.exportName);
178
- };
179
- const containerEntryFor = (container) => {
180
- const entry = {
181
- class_name: container.className,
182
- image: imageRefFor(container)
183
- };
184
- if (container.image.kind === "dockerfile") {
185
- entry.image_build_context = container.image.buildContext;
186
- }
187
- if (container.buildArgs !== void 0 && container.image.kind !== "registry") {
188
- entry.image_vars = container.buildArgs;
189
- }
190
- if (container.instanceType !== void 0) {
191
- entry.instance_type = wranglerInstanceType(container.instanceType);
192
- }
193
- if (container.maxInstances !== void 0) {
194
- entry.max_instances = container.maxInstances;
195
- }
196
- if (container.name !== void 0) {
197
- entry.name = container.name;
198
- }
199
- if (container.rollout?.stepPercentage !== void 0) {
200
- entry.rollout_step_percentage = container.rollout.stepPercentage;
201
- }
202
- if (container.rollout?.gracePeriodSeconds !== void 0) {
203
- entry.rollout_active_grace_period = container.rollout.gracePeriodSeconds;
204
- }
205
- return entry;
206
- };
207
- const reconcileContainers = (text, parsed, containers) => {
208
- const existing = parsed.containers ?? [];
209
- const existingClasses = new Set(existing.map((entry) => entry.class_name));
210
- const missing = containers.filter((container) => !existingClasses.has(container.className));
211
- if (missing.length === 0) {
212
- return { added: [], text };
213
- }
214
- const nextText = applyModify(text, ["containers"], [...existing, ...missing.map((container) => containerEntryFor(container))]);
215
- return { added: missing.map((container) => `containers/${container.className}`), text: nextText };
216
- };
217
- const reconcileObservability = (text, parsed) => {
218
- if (parsed.observability !== void 0) {
219
- return { added: [], text };
220
- }
221
- const nextText = applyModify(text, ["observability"], { enabled: true, head_sampling_rate: 1 });
222
- return { added: ["observability"], text: nextText };
223
- };
224
- const workflowEntryFor = (workflow) => {
225
- return { binding: workflow.bindingName, class_name: workflow.className, name: workflow.name };
226
- };
227
- const agentEntryFor = (agent) => {
228
- return { binding: agent.bindingName, class_name: agent.className, name: agent.name };
229
- };
230
- const reconcileWorkflows = (text, parsed, workflows, agents = []) => {
231
- const existing = parsed.workflows ?? [];
232
- const existingClasses = new Set(existing.map((entry) => entry.class_name));
233
- const missingWorkflows = workflows.filter((workflow) => !existingClasses.has(workflow.className));
234
- const missingAgents = agents.filter((agent) => !existingClasses.has(agent.className));
235
- if (missingWorkflows.length === 0 && missingAgents.length === 0) {
236
- return { added: [], text };
237
- }
238
- const nextText = applyModify(
239
- text,
240
- ["workflows"],
241
- [...existing, ...missingWorkflows.map((workflow) => workflowEntryFor(workflow)), ...missingAgents.map((agent) => agentEntryFor(agent))]
242
- );
243
- return {
244
- added: [...missingWorkflows.map((workflow) => `workflows/${workflow.className}`), ...missingAgents.map((agent) => `workflows/${agent.className}`)],
245
- text: nextText
246
- };
247
- };
248
- const reconcileQueues = (text, parsed, queues) => {
249
- const existing = parsed.queues ?? {};
250
- const existingProducers = existing.producers ?? [];
251
- const existingConsumers = existing.consumers ?? [];
252
- const haveProducer = new Set(existingProducers.map((entry) => entry.binding));
253
- const haveConsumer = new Set(existingConsumers.map((entry) => entry.queue));
254
- const missingProducers = queues.filter((queue) => !haveProducer.has(queue.bindingName));
255
- const missingConsumers = queues.filter((queue) => !haveConsumer.has(queue.name));
256
- if (missingProducers.length === 0 && missingConsumers.length === 0) {
257
- return { added: [], text };
258
- }
259
- const nextProducers = [
260
- ...existingProducers,
261
- ...missingProducers.map((queue) => {
262
- return { binding: queue.bindingName, queue: queue.name };
263
- })
264
- ];
265
- const nextConsumers = [
266
- ...existingConsumers,
267
- ...missingConsumers.map((queue) => {
268
- const consumer = { queue: queue.name };
269
- if (queue.mode === "pull") {
270
- consumer.type = "http_pull";
271
- }
272
- if (queue.tuning.maxBatchSize !== void 0) {
273
- consumer.max_batch_size = queue.tuning.maxBatchSize;
274
- }
275
- if (queue.tuning.maxBatchTimeout !== void 0) {
276
- consumer.max_batch_timeout = queue.tuning.maxBatchTimeout;
277
- }
278
- if (queue.tuning.maxRetries !== void 0) {
279
- consumer.max_retries = queue.tuning.maxRetries;
280
- }
281
- if (queue.tuning.deadLetterQueue !== void 0) {
282
- consumer.dead_letter_queue = queue.tuning.deadLetterQueue;
283
- }
284
- if (queue.tuning.retryDelay !== void 0) {
285
- consumer.retry_delay = queue.tuning.retryDelay;
286
- }
287
- return consumer;
288
- })
289
- ];
290
- const nextText = applyModify(text, ["queues"], { consumers: nextConsumers, producers: nextProducers });
291
- return {
292
- added: [
293
- ...missingProducers.map((queue) => `queues.producers/${queue.bindingName}`),
294
- ...missingConsumers.map((queue) => `queues.consumers/${queue.name}`)
295
- ],
296
- text: nextText
297
- };
298
- };
299
- const reconcileWranglerBindings = (projectRoot, inferred) => {
300
- const wranglerPath = findWranglerFile(projectRoot);
301
- const exportGaps = collectExportGaps(inferred);
302
- if (!wranglerPath) {
303
- return { added: [], changed: false, exportGaps, reason: "wrangler.jsonc not found", warnings: collectWarnings(inferred) };
304
- }
305
- const { parsed, text: original } = readWranglerJsonc(wranglerPath);
306
- if (parsed === void 0) {
307
- return { added: [], changed: false, exportGaps, reason: `failed to parse ${wranglerPath} as JSONC`, warnings: collectWarnings(inferred), wranglerPath };
308
- }
309
- const warnings = collectWarnings(inferred, parsed);
310
- const exportedContainers = inferred.containers.filter((container) => container.exported);
311
- const voiceAgents = inferred.agents.filter(
312
- (agent) => agent.exported && agent.voice === true && agent.voiceBindingName !== void 0 && agent.voiceClassName !== void 0
313
- );
314
- const requiredDurableObjects = [
315
- ...inferred.durableObjects,
316
- ...exportedContainers.map((container) => {
317
- return { binding: container.bindingName, className: container.className };
318
- }),
319
- ...voiceAgents.map((agent) => {
320
- return { binding: agent.voiceBindingName, className: agent.voiceClassName };
321
- })
322
- ];
323
- const exportedWorkflows = inferred.workflows.filter((workflow) => workflow.exported);
324
- const exportedAgents = inferred.agents.filter((agent) => agent.exported);
325
- const pipeline = [
326
- { enabled: true, run: (text2) => reconcileDurableObjects(text2, parsed, requiredDurableObjects) },
327
- { enabled: inferred.needsD1, run: (text2) => reconcileD1(text2, parsed) },
328
- { enabled: inferred.usesAi, run: (text2) => reconcileSelfDescribing(text2, parsed, "ai", "AI", "AI (Workers AI)") },
329
- { enabled: inferred.usesBrowser, run: (text2) => reconcileSelfDescribing(text2, parsed, "browser", "BROWSER", "BROWSER (Browser Rendering)") },
330
- { enabled: inferred.usesImages, run: (text2) => reconcileSelfDescribing(text2, parsed, "images", "IMAGES", "IMAGES (Cloudflare Images)") },
331
- { enabled: inferred.usesAnalytics, run: (text2) => reconcileAnalytics(text2, parsed) },
332
- { enabled: true, run: (text2) => reconcileObservability(text2, parsed) },
333
- { enabled: exportedContainers.length > 0, run: (text2) => reconcileContainers(text2, parsed, exportedContainers) },
334
- {
335
- enabled: exportedWorkflows.length > 0 || exportedAgents.length > 0,
336
- run: (text2) => reconcileWorkflows(text2, parsed, exportedWorkflows, exportedAgents)
337
- },
338
- { enabled: inferred.queues.length > 0, run: (text2) => reconcileQueues(text2, parsed, inferred.queues) }
339
- ];
340
- let text = original;
341
- const added = [];
342
- for (const step of pipeline) {
343
- if (!step.enabled) {
344
- continue;
345
- }
346
- const result = step.run(text);
347
- text = result.text;
348
- added.push(...result.added);
349
- }
350
- if (added.includes("DB (D1)")) {
351
- warnings.push(
352
- `wrote a DB binding with a placeholder database_id ("${D1_PLACEHOLDER_ID}") — run \`wrangler d1 create <name>\` and replace it before deploying.`
353
- );
354
- }
355
- if (text === original) {
356
- return { added: [], changed: false, exportGaps, reason: "bindings already in sync", warnings, wranglerPath };
357
- }
358
- writeFileSync(wranglerPath, text, "utf8");
359
- return { added, changed: true, exportGaps, warnings, wranglerPath };
360
- };
361
-
362
- export { reconcileWranglerBindings };
@@ -1,31 +0,0 @@
1
- import { writeFileSync } from 'node:fs';
2
- import { modify, applyEdits } from 'jsonc-parser';
3
- import { F as FORMATTING } from './jsonc-edit-SbcD7MAe.mjs';
4
- import { isCacheEnabled, WORKERS_CACHE_MIN_DATE } from './WORKERS_CACHE_MIN_DATE-CaXbS7CX.mjs';
5
- import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
6
-
7
- const reconcileWranglerCompatibilityDate = (projectRoot) => {
8
- const wranglerPath = findWranglerFile(projectRoot);
9
- if (!wranglerPath) {
10
- return { changed: false, date: void 0, reason: "wrangler.jsonc not found" };
11
- }
12
- const { parsed, text } = readWranglerJsonc(wranglerPath);
13
- if (parsed === void 0) {
14
- return { changed: false, date: void 0, reason: `failed to parse ${wranglerPath} as JSONC`, wranglerPath };
15
- }
16
- const currentDate = parsed.compatibility_date ?? "";
17
- if (!isCacheEnabled(parsed)) {
18
- return { changed: false, date: currentDate || void 0, reason: "cache not enabled", wranglerPath };
19
- }
20
- if (currentDate >= WORKERS_CACHE_MIN_DATE) {
21
- return { changed: false, date: currentDate, reason: `compatibility_date already >= ${WORKERS_CACHE_MIN_DATE}`, wranglerPath };
22
- }
23
- const edits = modify(text, ["compatibility_date"], WORKERS_CACHE_MIN_DATE, FORMATTING);
24
- if (edits.length === 0) {
25
- return { changed: false, date: currentDate || void 0, reason: "no structural edit produced", wranglerPath };
26
- }
27
- writeFileSync(wranglerPath, applyEdits(text, edits), "utf8");
28
- return { changed: true, date: WORKERS_CACHE_MIN_DATE, wranglerPath };
29
- };
30
-
31
- export { reconcileWranglerCompatibilityDate };
@@ -1,29 +0,0 @@
1
- import { writeFileSync } from 'node:fs';
2
- import { modify, applyEdits } from 'jsonc-parser';
3
- import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
4
-
5
- const sameTriggers = (a, b) => a.length === b.length && a.every((value, index) => value === b[index]);
6
- const reconcileWranglerCrons = (projectRoot, cronTriggers) => {
7
- const wranglerPath = findWranglerFile(projectRoot);
8
- if (!wranglerPath) {
9
- return { changed: false, reason: "wrangler.jsonc not found" };
10
- }
11
- const { parsed, text } = readWranglerJsonc(wranglerPath);
12
- if (parsed === void 0) {
13
- return { changed: false, reason: `failed to parse ${wranglerPath} as JSONC`, wranglerPath };
14
- }
15
- const existing = Array.isArray(parsed.triggers?.crons) ? parsed.triggers.crons.filter((value) => typeof value === "string") : [];
16
- if (sameTriggers(existing, cronTriggers)) {
17
- return { changed: false, reason: "triggers.crons already in sync", wranglerPath };
18
- }
19
- const edits = modify(text, ["triggers", "crons"], [...cronTriggers], {
20
- formattingOptions: { insertSpaces: true, tabSize: 4 }
21
- });
22
- if (edits.length === 0) {
23
- return { changed: false, reason: "no structural edit produced", wranglerPath };
24
- }
25
- writeFileSync(wranglerPath, applyEdits(text, edits), "utf8");
26
- return { changed: true, wranglerPath };
27
- };
28
-
29
- export { reconcileWranglerCrons };
@@ -1,37 +0,0 @@
1
- const forInlineScript = (value) => JSON.stringify(value).replaceAll("<", String.raw`\u003c`);
2
- const forAttribute = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;");
3
- const renderStudioHtml = (config) => {
4
- const settings = [`window.__LUNORA_BASE_PATH__=${forInlineScript(config.basePath)};`];
5
- if (config.adminToken !== void 0 && config.adminToken !== "") {
6
- settings.push(`window.__LUNORA_ADMIN_TOKEN__=${forInlineScript(config.adminToken)};`);
7
- }
8
- if (config.dataEditable === true) {
9
- settings.push("window.__LUNORA_DATA_EDITABLE__=true;");
10
- }
11
- if (config.runAsIdentity === true) {
12
- settings.push("window.__LUNORA_RUN_AS_IDENTITY__=true;");
13
- }
14
- if (config.schemaEditable === true) {
15
- settings.push("window.__LUNORA_SCHEMA_EDITABLE__=true;");
16
- }
17
- if (config.rulesInstalled === false) {
18
- settings.push("window.__LUNORA_RULES_INSTALLED__=false;");
19
- }
20
- return `<!doctype html>
21
- <html lang="en">
22
- <head>
23
- <meta charset="UTF-8" />
24
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
25
- <title>Lunora Studio</title>
26
- <script>${settings.join("")}<\/script>
27
- <link rel="stylesheet" href="${forAttribute(config.styleHref)}" />
28
- </head>
29
- <body>
30
- <div id="root"></div>
31
- <script type="module" src="${forAttribute(config.scriptSrc)}"><\/script>
32
- </body>
33
- </html>
34
- `;
35
- };
36
-
37
- export { renderStudioHtml as default };
@@ -1,86 +0,0 @@
1
- const MAX_BODY_BYTES = 1e6;
2
- const readBody = async (request) => await new Promise((resolve, reject) => {
3
- const chunks = [];
4
- let size = 0;
5
- request.on("data", (chunk) => {
6
- size += chunk.length;
7
- if (size > MAX_BODY_BYTES) {
8
- reject(new Error("request body too large"));
9
- return;
10
- }
11
- chunks.push(chunk);
12
- });
13
- request.on("end", () => {
14
- resolve(Buffer.concat(chunks).toString("utf8"));
15
- });
16
- request.on("error", reject);
17
- });
18
- const respondJson = (response, status, body) => {
19
- response.statusCode = status;
20
- response.setHeader("Content-Type", "application/json; charset=utf-8");
21
- response.end(JSON.stringify(body));
22
- };
23
- const headerValue = (raw) => {
24
- const value = Array.isArray(raw) ? raw[0] : raw;
25
- return typeof value === "string" ? value.trim().toLowerCase() : void 0;
26
- };
27
- const SAME_SITE_FETCH_VALUES = /* @__PURE__ */ new Set(["none", "same-origin", "same-site"]);
28
- const originRejectionReason = (request) => {
29
- const secFetchSite = headerValue(request.headers["sec-fetch-site"]);
30
- if (secFetchSite !== void 0) {
31
- return SAME_SITE_FETCH_VALUES.has(secFetchSite) ? void 0 : "cross-origin request rejected";
32
- }
33
- const origin = headerValue(request.headers.origin);
34
- if (origin === void 0 || origin === "null") {
35
- return void 0;
36
- }
37
- let originHost;
38
- try {
39
- originHost = new URL(origin).host.toLowerCase();
40
- } catch {
41
- return "invalid origin header";
42
- }
43
- return originHost === headerValue(request.headers.host) ? void 0 : "cross-origin request rejected";
44
- };
45
- const csrfRejectionReason = (request) => {
46
- const method = (request.method ?? "GET").toUpperCase();
47
- const isStateChanging = method !== "GET" && method !== "HEAD";
48
- const originReason = originRejectionReason(request);
49
- if (originReason !== void 0) {
50
- return originReason;
51
- }
52
- if (isStateChanging) {
53
- const contentType = headerValue(request.headers["content-type"]);
54
- if (!contentType?.startsWith("application/json")) {
55
- return "content-type must be application/json";
56
- }
57
- }
58
- return void 0;
59
- };
60
- const serveJsonHandler = (request, response, handle, projectRoot, schemaDirectory) => {
61
- const run = async () => {
62
- try {
63
- const rejection = csrfRejectionReason(request);
64
- if (rejection !== void 0) {
65
- respondJson(response, 403, { error: rejection, ok: false });
66
- return;
67
- }
68
- const raw = request.method === "GET" ? "" : await readBody(request);
69
- let parsed;
70
- try {
71
- parsed = raw === "" ? void 0 : JSON.parse(raw);
72
- } catch {
73
- respondJson(response, 400, { error: "invalid-json", ok: false });
74
- return;
75
- }
76
- const result = handle({ body: parsed, method: request.method ?? "POST", projectRoot, schemaDirectory });
77
- respondJson(response, result.status, result.body);
78
- } catch (error) {
79
- respondJson(response, 500, { error: error instanceof Error ? error.message : String(error), ok: false });
80
- }
81
- };
82
- run().catch(() => {
83
- });
84
- };
85
-
86
- export { serveJsonHandler };