@lunora/config 1.0.0-alpha.27 → 1.0.0-alpha.271
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/LICENSE.md +135 -0
- package/README.md +3 -3
- package/dist/cloudflare/index.d.mts +969 -0
- package/dist/cloudflare/index.d.ts +969 -0
- package/dist/cloudflare/index.mjs +1 -0
- package/dist/index.d.mts +864 -921
- package/dist/index.d.ts +864 -921
- package/dist/index.mjs +1 -23
- package/dist/packem_shared/ACCENT-CotPTfv7.mjs +7 -0
- package/dist/packem_shared/AGENT_MODE_ENV-D8MvSwPE.mjs +1 -0
- package/dist/packem_shared/AGENT_RULES_DIR-C54Ta_vz.mjs +1 -0
- package/dist/packem_shared/ALLOW_FORWARDED_ENV-BUndghJx.mjs +1 -0
- package/dist/packem_shared/BINDING_MANIFEST_VERSION-B8dwEKLn.mjs +1 -0
- package/dist/packem_shared/CLOUDFLARE_DRIVER-Ci9oJMYb.mjs +1 -0
- package/dist/packem_shared/CODEGEN_ENV-ZsCxV1kP.mjs +1 -0
- package/dist/packem_shared/COMPOSED_WORKER_ENTRY-Bj793dir.mjs +1 -0
- package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-B-e9mqgX.mjs +1 -0
- package/dist/packem_shared/DEV_BINDINGS_FILE-pyOiNLP4.mjs +4 -0
- package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs +6 -0
- package/dist/packem_shared/LINKED_PROJECT_DIR-Ba5qPEwo.mjs +2 -0
- package/dist/packem_shared/LUNORA_EVENT_SOURCE-DYdcDU9G.mjs +1 -0
- package/dist/packem_shared/LUNORA_IGNORED_PATHS-BHABA9u-.mjs +19 -0
- package/dist/packem_shared/LunoraReporter-f277GLNT.mjs +6 -0
- package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-De7gLGIy.mjs +1 -0
- package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-0QiGKazX.mjs +1 -0
- package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-D-edJjVY.mjs +1 -0
- package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-SdRHaUwh.mjs +1 -0
- package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Dbt0faMd.mjs +1 -0
- package/dist/packem_shared/SEED_ENDPOINT-2B56PN_H.mjs +1 -0
- package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs +1 -0
- package/dist/packem_shared/WRANGLER_FILES-UNW-xY5u.mjs +1 -0
- package/dist/packem_shared/addArgsFor-CWb4cPij.mjs +1 -0
- package/dist/packem_shared/applyAdditiveEdit-CH0VhMJ2.mjs +6 -0
- package/dist/packem_shared/applyStudioAssetCache-DHQEJuuv.mjs +1 -0
- package/dist/packem_shared/assetContentType-CUb5bpbI.mjs +1 -0
- package/dist/packem_shared/buildPackageSecretsBlock-yv9mjKEW.mjs +19 -0
- package/dist/packem_shared/classifyPolicyEdit-D8NwrHxR.mjs +24 -0
- package/dist/packem_shared/collectExportGaps-BJw9LdRV.mjs +2 -0
- package/dist/packem_shared/collectWranglerSecretVariables-D-usPfT8.mjs +1 -0
- package/dist/packem_shared/createConfirm-D5mKTMHj.mjs +7 -0
- package/dist/packem_shared/describePreservedCrons-Ci5r2aph.mjs +1 -0
- package/dist/packem_shared/detectFramework-CUiVEHDQ.mjs +1 -0
- package/dist/packem_shared/discover-info-Vj9d4qYt.mjs +1 -0
- package/dist/packem_shared/discoverAgentInfo-CTdCSfYM.mjs +1 -0
- package/dist/packem_shared/discoverContainerInfo-EhZtEBQs.mjs +1 -0
- package/dist/packem_shared/discoverSchemaInfo-DJvevsCm.mjs +1 -0
- package/dist/packem_shared/discoverWorkflowInfo-BsPvlo6O.mjs +1 -0
- package/dist/packem_shared/interpretRemote-CQ06qpjM.mjs +1 -0
- package/dist/packem_shared/jsonc-edit-BZgQIdAH.mjs +1 -0
- package/dist/packem_shared/lunora-manifest-V77OcyFC.mjs +6 -0
- package/dist/packem_shared/package-secrets-registry-DvtTiK4b.mjs +1 -0
- package/dist/packem_shared/parseDevVariable-teAAahVD.mjs +1 -0
- package/dist/packem_shared/parseSchema-D1Wbr1qv.mjs +1 -0
- package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.mts +86 -0
- package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.ts +86 -0
- package/dist/packem_shared/reconcileWranglerCompatibilityDate-7OO_xaKR.mjs +1 -0
- package/dist/packem_shared/renderStudioHtml-ByowDtMl.mjs +15 -0
- package/dist/packem_shared/runPostCodegenHook-CVrOTiGB.mjs +1 -0
- package/dist/packem_shared/schema-info.d-DvKkJ7HJ.d.mts +331 -0
- package/dist/packem_shared/schema-info.d-DvKkJ7HJ.d.ts +331 -0
- package/dist/packem_shared/serveJsonHandler-Dv0EdCb9.mjs +1 -0
- package/dist/packem_shared/streamContainerLogs-0nko1qpv.mjs +2 -0
- package/dist/packem_shared/wranglerToAlchemy-SDoS_XY0.mjs +6 -0
- package/dist/packem_shared/write-atomic-9d9xs5ON.mjs +1 -0
- package/dist/studio-host/index.d.mts +250 -95
- package/dist/studio-host/index.d.ts +250 -95
- package/dist/studio-host/index.mjs +1 -7
- package/package.json +15 -7
- package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
- package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
- package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
- package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
- package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
- package/dist/packem_shared/LUNORA_EVENT_SOURCE-D2fDeGB6.mjs +0 -86
- package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
- package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-B8t_SdoZ.mjs +0 -70
- package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs +0 -103
- package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs +0 -105
- package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-2YYyWJUq.mjs +0 -561
- package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs +0 -99
- package/dist/packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs +0 -61
- package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
- package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
- package/dist/packem_shared/buildPackageSecretsBlock-DWDKHViT.mjs +0 -243
- package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
- package/dist/packem_shared/createConfirm-fvpdgJ9s.mjs +0 -100
- package/dist/packem_shared/detectFramework-Br-BcPBq.mjs +0 -41
- package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
- package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
- package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
- package/dist/packem_shared/inferLunoraBindings-ByMwG-gH.mjs +0 -352
- package/dist/packem_shared/loadStudioAssets-Csk5RS4E.mjs +0 -28
- package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
- package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
- package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.mts +0 -74
- package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.ts +0 -74
- package/dist/packem_shared/reconcileWranglerBindings-Cruwwx1M.mjs +0 -334
- package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
- package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
- package/dist/packem_shared/streamContainerLogs-BZ4cOZwH.mjs +0 -157
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { AgentIR, ContainerIR, QueueIR, WorkflowIR } from '@lunora/codegen';
|
|
2
|
+
/**
|
|
3
|
+
* `DeployDriver` — the provider-neutral seam between a Lunora command and the
|
|
4
|
+
* host CLI that carries it out (plan 114, §5.3).
|
|
5
|
+
*
|
|
6
|
+
* The seam is the **toolchain surface**: which command a host runs to deploy,
|
|
7
|
+
* serve, tail, or set a secret. A driver only *describes* that command
|
|
8
|
+
* ({@link ToolchainCommand}); it never spawns. The CLI keeps ownership of
|
|
9
|
+
* running it — package-manager resolution (`pnpm exec` / `npx --` / `bun x`)
|
|
10
|
+
* and the injected spawner its tests substitute — so the driver stays free of
|
|
11
|
+
* process concerns and remains trivially testable as a pure function.
|
|
12
|
+
*
|
|
13
|
+
* Each request type below is deliberately neutral: `preview`, `environment`,
|
|
14
|
+
* `temporary` are concepts, not wrangler flags. A second host maps the same
|
|
15
|
+
* request onto its own CLI without the caller changing.
|
|
16
|
+
*
|
|
17
|
+
* Two drivers are registered: Cloudflare (`cloudflare/cloudflare-driver.ts`),
|
|
18
|
+
* which is the only one with a toolchain, and Node (`node/node-driver.ts`),
|
|
19
|
+
* which has none — it is a codegen target, and `lunora deploy` / `lunora dev`
|
|
20
|
+
* refuse it at selection.
|
|
21
|
+
*
|
|
22
|
+
* **What this seam deliberately does NOT carry: configuration inference.** It
|
|
23
|
+
* used to, through an `infer`/`provision` pair over a provider-neutral
|
|
24
|
+
* `ResourceGraph`. Nothing ever called either one — every consumer reads
|
|
25
|
+
* `.toolchain` or just validates the target — and the arm rotted in place: the
|
|
26
|
+
* Node driver was *only* `infer` + `provision`, so its report of what that
|
|
27
|
+
* target cannot serve (containers, undispatched crons) could not reach an
|
|
28
|
+
* operator however wrong the app was. The reason it never got wired is worth
|
|
29
|
+
* keeping: writing real host configuration needs the host's own encodings —
|
|
30
|
+
* binding names, DO class wiring, migration tags — which a neutral graph
|
|
31
|
+
* necessarily discards, so `provision` re-derived them anyway and the graph was
|
|
32
|
+
* decorative. A second target that needs to share inference should grow the
|
|
33
|
+
* seam back with a caller attached, and with an encoding escape hatch.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* A host CLI invocation, described but not run.
|
|
37
|
+
*
|
|
38
|
+
* `tool` is the binary name only (`"wrangler"`); the caller resolves how to
|
|
39
|
+
* execute it through the project's package manager. Keeping that split means a
|
|
40
|
+
* driver never has to know whether the project uses pnpm, npm, yarn, or bun.
|
|
41
|
+
*/
|
|
42
|
+
interface ToolchainCommand {
|
|
43
|
+
/** Arguments for {@link ToolchainCommand.tool}. */
|
|
44
|
+
args: ReadonlyArray<string>;
|
|
45
|
+
/** The host CLI binary, e.g. `"wrangler"`. */
|
|
46
|
+
tool: string;
|
|
47
|
+
}
|
|
48
|
+
/** Neutral options for a deploy. */
|
|
49
|
+
interface DeployRequest {
|
|
50
|
+
/** Validate and bundle without publishing — nothing ships. */
|
|
51
|
+
dryRun?: boolean;
|
|
52
|
+
/** Deploy this entry file instead of the host config's default (framework composition). */
|
|
53
|
+
entry?: string;
|
|
54
|
+
/** Named deployment environment, when the host supports them. */
|
|
55
|
+
environment?: string;
|
|
56
|
+
/** Write the built bundle (and any build metadata) to this directory. */
|
|
57
|
+
outDir?: string;
|
|
58
|
+
/** Upload a preview/versioned artifact instead of taking production traffic. */
|
|
59
|
+
preview?: boolean;
|
|
60
|
+
/** Deploy to a short-lived, unauthenticated account where the host offers one. */
|
|
61
|
+
temporary?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Neutral options for a local dev server. */
|
|
64
|
+
interface DevRequest {
|
|
65
|
+
/** Host config file to run against, when the flow uses a generated one. */
|
|
66
|
+
configPath?: string;
|
|
67
|
+
/** Named environment. */
|
|
68
|
+
environment?: string;
|
|
69
|
+
/** Extra host-specific flags the caller has already resolved. */
|
|
70
|
+
extraArgs?: ReadonlyArray<string>;
|
|
71
|
+
}
|
|
72
|
+
/** Neutral options for tailing live logs. */
|
|
73
|
+
interface TailRequest {
|
|
74
|
+
/** Named environment. */
|
|
75
|
+
environment?: string;
|
|
76
|
+
/** Output format the host tail supports (`"json"`, `"pretty"`, …). */
|
|
77
|
+
format?: string;
|
|
78
|
+
/** Free-text filter. */
|
|
79
|
+
search?: string;
|
|
80
|
+
/** Status filter (`"error"`, `"ok"`, …). */
|
|
81
|
+
status?: string;
|
|
82
|
+
/** Tail a short-lived account's deployment. */
|
|
83
|
+
temporary?: boolean;
|
|
84
|
+
/** Tail a specific deployed worker/service by name, when the host addresses them individually. */
|
|
85
|
+
worker?: string;
|
|
86
|
+
}
|
|
87
|
+
/** Neutral options for reading or writing deployment secrets. */
|
|
88
|
+
interface SecretRequest {
|
|
89
|
+
/** Named environment. */
|
|
90
|
+
environment?: string;
|
|
91
|
+
/** The secret's name — required for `put`, unused for `list`. */
|
|
92
|
+
key?: string;
|
|
93
|
+
/** Operate against a short-lived account. */
|
|
94
|
+
temporary?: boolean;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The host's command-line surface. Optional as a whole: a host with no vendor
|
|
98
|
+
* CLI (the Node target; a hypothetical API-driven one) declares none, and
|
|
99
|
+
* `isRunnableTarget` refuses it for the commands that would have to shell out.
|
|
100
|
+
*/
|
|
101
|
+
interface DriverToolchain {
|
|
102
|
+
/** The command that deploys the app. */
|
|
103
|
+
deploy: (request: DeployRequest) => ToolchainCommand;
|
|
104
|
+
/** The command that runs a local dev server. */
|
|
105
|
+
dev: (request: DevRequest) => ToolchainCommand;
|
|
106
|
+
/** The command that lists remote secret names. */
|
|
107
|
+
secretList: (request: SecretRequest) => ToolchainCommand;
|
|
108
|
+
/** The command that writes one secret. Its value is passed on stdin, never argv. */
|
|
109
|
+
secretPut: (request: SecretRequest) => ToolchainCommand;
|
|
110
|
+
/** The command that tails live logs. */
|
|
111
|
+
tail: (request: TailRequest) => ToolchainCommand;
|
|
112
|
+
}
|
|
113
|
+
/** A deploy target's implementation: an identity the registry resolves, and the host CLI surface (if any) behind it. */
|
|
114
|
+
interface DeployDriver {
|
|
115
|
+
/** The target id this driver serves (`"cloudflare"`, …) — matches codegen's `target`. */
|
|
116
|
+
readonly id: string;
|
|
117
|
+
/** Human-readable target name, for logs. */
|
|
118
|
+
readonly name: string;
|
|
119
|
+
/**
|
|
120
|
+
* The host's command-line surface, or `undefined` for a host that has none.
|
|
121
|
+
* Pure: these build argv, they never spawn.
|
|
122
|
+
*/
|
|
123
|
+
readonly toolchain?: DriverToolchain;
|
|
124
|
+
}
|
|
125
|
+
interface DurableObjectSpec {
|
|
126
|
+
binding: string;
|
|
127
|
+
className: string;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* A `defineContainer` declaration plus whether its generated DO class is
|
|
131
|
+
* exported by the worker entry. Only exported containers are safe to
|
|
132
|
+
* provision — wrangler rejects a `containers[].class_name` (and its Durable
|
|
133
|
+
* Object binding) that the worker doesn't export.
|
|
134
|
+
*/
|
|
135
|
+
interface InferredContainer extends ContainerIR {
|
|
136
|
+
exported: boolean;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* A `defineWorkflow` declaration plus whether its generated
|
|
140
|
+
* `WorkflowEntrypoint` class is exported by the worker entry. Only exported
|
|
141
|
+
* workflows are safe to provision — wrangler rejects a `workflows[].class_name`
|
|
142
|
+
* the worker doesn't export. Workflows are NOT Durable Objects, so this never
|
|
143
|
+
* implies a `durable_objects` binding or migration.
|
|
144
|
+
*/
|
|
145
|
+
interface InferredWorkflow extends WorkflowIR {
|
|
146
|
+
exported: boolean;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* A `defineAgent` declaration plus whether its generated agent
|
|
150
|
+
* `WorkflowEntrypoint` class (e.g. `SupportAgentWorkflow`) is exported by the
|
|
151
|
+
* worker entry. An agent compiles onto a Cloudflare Workflow, so — exactly like
|
|
152
|
+
* {@link InferredWorkflow} — only exported agents are safe to provision
|
|
153
|
+
* (wrangler rejects a `workflows[].class_name` the worker doesn't export), and
|
|
154
|
+
* an agent is NOT a Durable Object (no `durable_objects` binding or migration).
|
|
155
|
+
*/
|
|
156
|
+
interface InferredAgent extends AgentIR {
|
|
157
|
+
exported: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* A queue declared in `lunora/queues.ts`. Unlike workflows, a queue needs no
|
|
161
|
+
* worker-entry class export (its `queue()` handler rides `createWorker`), so
|
|
162
|
+
* there is no `exported` flag — every declared queue is reconcilable into the
|
|
163
|
+
* wrangler `queues.producers[]` / `queues.consumers[]`.
|
|
164
|
+
*/
|
|
165
|
+
type InferredQueue = QueueIR;
|
|
166
|
+
interface InferredBindings {
|
|
167
|
+
/** Agents declared in `lunora/agents.ts` (exported or not — see {@link InferredAgent.exported}); reconciled into `workflows[]`. */
|
|
168
|
+
agents: InferredAgent[];
|
|
169
|
+
/** Containers declared in `lunora/containers.ts` (exported or not — see {@link InferredContainer.exported}). */
|
|
170
|
+
containers: InferredContainer[];
|
|
171
|
+
/** Durable Objects the worker entry exports → safe to bind. */
|
|
172
|
+
durableObjects: DurableObjectSpec[];
|
|
173
|
+
/**
|
|
174
|
+
* The wrangler `flagship[].binding` name implied by `lunora/flags.ts` when it
|
|
175
|
+
* uses the Flagship provider in binding mode — `undefined` for HTTP-mode
|
|
176
|
+
* Flagship, a custom OpenFeature provider, or no flags. The binding needs an
|
|
177
|
+
* un-mintable `app_id`, so it is reconciled as a hint, not auto-written.
|
|
178
|
+
*/
|
|
179
|
+
flagshipBinding?: string;
|
|
180
|
+
/** Schema declares a `.global()` table → needs the `DB` D1 binding. */
|
|
181
|
+
needsD1: boolean;
|
|
182
|
+
/** Queues declared in `lunora/queues.ts` → reconciled into `queues.producers[]` / `queues.consumers[]`. */
|
|
183
|
+
queues: InferredQueue[];
|
|
184
|
+
/** Human-readable provenance for each inferred binding / hint, for logging. */
|
|
185
|
+
signals: string[];
|
|
186
|
+
/** `@lunora/ai` is imported or `env.AI` is used → needs the `ai` Workers AI binding. */
|
|
187
|
+
usesAi: boolean;
|
|
188
|
+
/** `@lunora/bindings/analytics` is imported → self-describing `analytics_engine_datasets` binding (auto-writeable). */
|
|
189
|
+
usesAnalytics: boolean;
|
|
190
|
+
/** `@lunora/auth` is imported (sessions may be D1- or `SessionDO`-backed). */
|
|
191
|
+
usesAuth: boolean;
|
|
192
|
+
/** `@lunora/browser` is imported → self-describing `browser` binding (auto-writeable). */
|
|
193
|
+
usesBrowser: boolean;
|
|
194
|
+
/** `lunora/flags.ts` declares a feature-flag provider (any OpenFeature provider — Flagship or custom). */
|
|
195
|
+
usesFlags: boolean;
|
|
196
|
+
/** `@lunora/hyperdrive` is imported (binding needs an un-mintable remote `id`; hint-only). */
|
|
197
|
+
usesHyperdrive: boolean;
|
|
198
|
+
/** `@lunora/bindings/images` is imported → self-describing `images` binding (auto-writeable). */
|
|
199
|
+
usesImages: boolean;
|
|
200
|
+
/** `@lunora/bindings/kv` is imported (namespace binding name + id are user-defined; hint-only). */
|
|
201
|
+
usesKv: boolean;
|
|
202
|
+
/** `@lunora/mail` is imported (Resend API key must be set in `.dev.vars`; no binding). */
|
|
203
|
+
usesMail: boolean;
|
|
204
|
+
/** `@lunora/notify` is imported (Web Push needs VAPID/FCM secrets in `.dev.vars`; no binding). */
|
|
205
|
+
usesNotify: boolean;
|
|
206
|
+
/** `@lunora/payment` is imported (provider secrets must be set in `.dev.vars`; no binding). */
|
|
207
|
+
usesPayment: boolean;
|
|
208
|
+
/** `ctx.pipelines` is used (binding needs an un-mintable remote pipeline name; hint-only). */
|
|
209
|
+
usesPipelines: boolean;
|
|
210
|
+
/** `ctx.r2sql` is used (needs the `R2_SQL_*` secrets in `.dev.vars`; no binding). */
|
|
211
|
+
usesR2sql: boolean;
|
|
212
|
+
/** `@lunora/scheduler` is imported. */
|
|
213
|
+
usesScheduler: boolean;
|
|
214
|
+
/** `@lunora/storage` is imported (R2 bucket binding name is user-defined). */
|
|
215
|
+
usesStorage: boolean;
|
|
216
|
+
/** `@lunora/x402/charge` is imported — the charge rail settles USDC to a recipient address (a public `[vars]` entry, user-named; hint-only). */
|
|
217
|
+
usesX402Charge: boolean;
|
|
218
|
+
/** `@lunora/x402/pay` is imported — the agent-wallet pay rail signs from a Secrets Store binding paired with a spend policy (ActionCtx-only; hint-only). */
|
|
219
|
+
usesX402Pay: boolean;
|
|
220
|
+
/** Workflows declared in `lunora/workflows.ts` (exported or not — see {@link InferredWorkflow.exported}). */
|
|
221
|
+
workflows: InferredWorkflow[];
|
|
222
|
+
}
|
|
223
|
+
interface InferOptions {
|
|
224
|
+
projectRoot: string;
|
|
225
|
+
/** Directories (relative to root) to scan. Defaults to `lunora` + `src`. */
|
|
226
|
+
scanDirs?: ReadonlyArray<string>;
|
|
227
|
+
/** Lunora source directory holding `schema.ts`. Defaults to `lunora`. */
|
|
228
|
+
schemaDir?: string;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The `_generated/` modules that hold a generated Durable Object / Workflow
|
|
232
|
+
* class — one per class kind a project can declare. wrangler validates every
|
|
233
|
+
* `class_name` against the worker's exports, so this is the set a worker entry
|
|
234
|
+
* re-exports (and the set the composed class-A entry star-re-exports for the
|
|
235
|
+
* kinds the project has).
|
|
236
|
+
*
|
|
237
|
+
* Owned here because four places need it and they must not drift:
|
|
238
|
+
* `@lunora/vite` emits one star re-export per entry, the wrangler validator
|
|
239
|
+
* DECIDES the composed entry's exports from it, `reconcile-bindings` types its
|
|
240
|
+
* export-gap `module` field on it, and this module's own `detectClassExports`
|
|
241
|
+
* probes the same names.
|
|
242
|
+
*
|
|
243
|
+
* `scheduler` carries no `define*` declarations of its own — codegen writes it
|
|
244
|
+
* off `hasScheduler` purely so the composed class-A entry has a `SchedulerDO`
|
|
245
|
+
* to forward. Its presence is therefore the ONLY signal the plugin and the
|
|
246
|
+
* validator need, and it is the same signal that decides whether the builder
|
|
247
|
+
* has a `.scheduler()` method at all. `@lunora/vite` depends on `@lunora/config`, so config
|
|
248
|
+
* owning it is the direction the dependency graph allows.
|
|
249
|
+
*/
|
|
250
|
+
declare const GENERATED_CLASS_MODULES: readonly ["agents", "containers", "scheduler", "workflows"];
|
|
251
|
+
/** One {@link GENERATED_CLASS_MODULES} entry. */
|
|
252
|
+
type GeneratedClassModule = (typeof GENERATED_CLASS_MODULES)[number];
|
|
253
|
+
/**
|
|
254
|
+
* The class-B composed entry. `lunora deploy` passes this file to wrangler as
|
|
255
|
+
* the positional script whenever it exists, overriding `wrangler.main` — so it
|
|
256
|
+
* is what actually gets bundled and what wrangler checks its DO/Workflow
|
|
257
|
+
* bindings against. `main` in a class-B project names the framework adapter's
|
|
258
|
+
* build output (`.svelte-kit/cloudflare/_worker.js`, `dist/_worker.js`), which
|
|
259
|
+
* exists after `vite build` and exports only the SSR fetch handler. Lexing that
|
|
260
|
+
* instead read every declared class as unexported: nothing provisioned, plus a
|
|
261
|
+
* "add `export * from …`" warning the user cannot silence.
|
|
262
|
+
*
|
|
263
|
+
* Exported, not documented-as-duplicated: the CLI's `resolveComposedWorkerEntry`
|
|
264
|
+
* imports this constant, so the deploy's positional entry and the file this
|
|
265
|
+
* module lexes for exported classes cannot drift apart.
|
|
266
|
+
*/
|
|
267
|
+
declare const COMPOSED_WORKER_ENTRY = "src/worker.ts";
|
|
268
|
+
/**
|
|
269
|
+
* Scan a Lunora project and report which Cloudflare bindings its code implies.
|
|
270
|
+
* Read-only: performs no writes. Binding provisioning is driven by the worker
|
|
271
|
+
* entry's Durable Object exports plus the schema's D1 need; capability imports
|
|
272
|
+
* surface as hints.
|
|
273
|
+
*/
|
|
274
|
+
declare const inferLunoraBindings: (options: InferOptions) => Promise<InferredBindings>;
|
|
275
|
+
/**
|
|
276
|
+
* Derive the list of `@lunora/*` package names that are actively used by a
|
|
277
|
+
* project, based on its already-resolved {@link InferredBindings}.
|
|
278
|
+
*
|
|
279
|
+
* This is the canonical bridge between binding inference and the package-aware
|
|
280
|
+
* `.dev.vars.example` scaffolding in `scaffold-dev-variables.ts`. The result is
|
|
281
|
+
* a stable, predictable slice of {@link CAPABILITY_SOURCES} source values,
|
|
282
|
+
* filtered to the flags that are `true` in `bindings` — in CAPABILITY_SOURCES
|
|
283
|
+
* declaration order.
|
|
284
|
+
*/
|
|
285
|
+
declare const packageNamesFromBindings: (bindings: InferredBindings) => string[];
|
|
286
|
+
/** One filterable Vectorize metadata property a schema declares. */
|
|
287
|
+
interface VectorMetadataDeclaration {
|
|
288
|
+
/** The vector index the property belongs to. */
|
|
289
|
+
index: string;
|
|
290
|
+
/**
|
|
291
|
+
* The validator kind behind the column, or `undefined` when the column
|
|
292
|
+
* isn't in the owning table's shape. Callers map it to the Vectorize
|
|
293
|
+
* metadata type; a kind that can't be filtered on is reported, not indexed.
|
|
294
|
+
*/
|
|
295
|
+
kind: string | undefined;
|
|
296
|
+
/** Column mirrored into vector metadata. */
|
|
297
|
+
property: string;
|
|
298
|
+
}
|
|
299
|
+
interface SchemaInfo {
|
|
300
|
+
/**
|
|
301
|
+
* Whether the schema declares a **D1-backed** `.global()` table — the only
|
|
302
|
+
* flavour that needs the `DB` binding and the app's `.global({ d1 })` chain.
|
|
303
|
+
* A `.global({ backend: "hyperdrive" })` table needs neither, and counting it
|
|
304
|
+
* here demanded a D1 database of a project that has none.
|
|
305
|
+
*/
|
|
306
|
+
hasD1GlobalTable: boolean;
|
|
307
|
+
/** Whether the schema declares a `.global({ backend: "hyperdrive" })` table — needs the app's `.hyperdriveGlobal(...)` chain instead. Required, not optional: the only producer always knows the answer, and `?` made every consumer read a two-valued fact as three-valued. */
|
|
308
|
+
hasHyperdriveGlobalTable: boolean;
|
|
309
|
+
/** Names of vector indexes declared via `.vectorize()` / `defineVectorIndex()`. */
|
|
310
|
+
vectorIndexNames?: ReadonlyArray<string>;
|
|
311
|
+
/**
|
|
312
|
+
* Metadata properties declared filterable on a vector index. Cloudflare
|
|
313
|
+
* needs an explicit metadata index per property before a `filter` can match
|
|
314
|
+
* anything, so deploy provisions these and doctor reports them.
|
|
315
|
+
*/
|
|
316
|
+
vectorMetadata?: ReadonlyArray<VectorMetadataDeclaration>;
|
|
317
|
+
}
|
|
318
|
+
interface DiscoverSchemaInfoResult {
|
|
319
|
+
/** Parse error message, when the schema exists but could not be analyzed. */
|
|
320
|
+
error?: string;
|
|
321
|
+
/** Schema facts, or `undefined` when no `schema.ts` exists or parsing failed. */
|
|
322
|
+
info: SchemaInfo | undefined;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Discover {@link SchemaInfo} for a project. Returns `{ info: undefined }` when
|
|
326
|
+
* the project declares no `schema.ts` (not an error), or `{ info: undefined,
|
|
327
|
+
* error }` when a present schema could not be parsed — callers decide whether a
|
|
328
|
+
* parse failure is a warning (validator) or simply ignorable (inference).
|
|
329
|
+
*/
|
|
330
|
+
declare const discoverSchemaInfo: (projectRoot: string, schemaDirectory: string) => DiscoverSchemaInfoResult;
|
|
331
|
+
export { COMPOSED_WORKER_ENTRY as C, DeployDriver as D, GeneratedClassModule as G, InferredBindings as I, SchemaInfo as S, TailRequest as T, DeployRequest as a, DevRequest as b, DiscoverSchemaInfoResult as c, DriverToolchain as d, GENERATED_CLASS_MODULES as e, InferOptions as f, InferredAgent as g, InferredContainer as h, InferredWorkflow as i, SecretRequest as j, ToolchainCommand as k, discoverSchemaInfo as l, inferLunoraBindings as m, packageNamesFromBindings as p };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{headerValue as a}from"./ALLOW_FORWARDED_ENV-BUndghJx.mjs";const l=1e6,g=async t=>await new Promise((o,e)=>{const n=[];let i=0;t.on("data",c=>{if(i+=c.length,i>l){e(new Error("request body too large"));return}n.push(c)}),t.on("end",()=>{o(Buffer.concat(n).toString("utf8"))}),t.on("error",e)}),s=(t,o,e)=>{t.statusCode=o,t.setHeader("Content-Type","application/json; charset=utf-8"),t.end(JSON.stringify(e))},u=new Set(["none","same-origin","same-site"]),y=t=>{const o=a(t.headers["sec-fetch-site"]);if(o!==void 0)return u.has(o)?void 0:"cross-origin request rejected";const e=a(t.headers.origin);if(e===void 0||e==="null")return;let n;try{n=new URL(e).host.toLowerCase()}catch{return"invalid origin header"}return n===a(t.headers.host)?void 0:"cross-origin request rejected"},p=t=>{const o=(t.method??"GET").toUpperCase(),e=o!=="GET"&&o!=="HEAD",n=y(t);if(n!==void 0)return n;if(e&&!a(t.headers["content-type"])?.startsWith("application/json"))return"content-type must be application/json"},v=(t,o,e,n,i={})=>{(async()=>{try{const r=p(t);if(r!==void 0){s(o,403,{error:r,ok:!1});return}const d=t.method==="GET"?"":await g(t);let h;try{h=d===""?void 0:JSON.parse(d)}catch{s(o,400,{error:"invalid-json",ok:!1});return}const f=e({...i,body:h,method:t.method??"POST",projectRoot:n});s(o,f.status,f.body)}catch(r){s(o,500,{error:r instanceof Error?r.message:String(r),ok:!1})}})().catch(()=>{})};export{v as serveJsonHandler};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Writable as D}from"node:stream";import{StringDecoder as N}from"node:string_decoder";const y="cloudflare-dev/",_=1500,b=async()=>{const{default:t}=await import("dockerode");return new t},C=t=>{if(!t.startsWith(y))return;const[a]=t.slice(y.length).split(":");return a!==void 0&&a.length>0?a:void 0},I=t=>{const a=new N("utf8");let c="";const o=r=>{t(r.endsWith("\r")?r.slice(0,-1):r)};return new D({final(r){c+=a.end(),c.length>0&&(o(c),c=""),r()},write(r,m,i){c+=a.write(r);const d=c.split(`
|
|
2
|
+
`);c=d.pop()??"";for(const v of d)o(v);i()}})},T=t=>{const a=new Map(t.containers.map(e=>[e.className.toLowerCase(),e.exportName]));if(a.size===0)return{close:()=>{}};const c=t.pollIntervalMs??_,o=new Map;let r=!1,m=!1,i,d;const v=async()=>(d??=t.docker?Promise.resolve(t.docker):b(),d),p=async(e,s,f)=>{try{const n=await e.getContainer(s).logs({follow:!0,stderr:!0,stdout:!0,tail:"all",timestamps:!1});if(r){n.destroy();return}const l=I(w=>{t.onLine({level:"info",name:f,text:w})}),u=I(w=>{t.onLine({level:"error",name:f,text:w})});e.modem.demuxStream(n,l,u),n.on("end",()=>{l.end(),u.end(),o.delete(s)}),n.on("error",()=>{o.delete(s)}),o.set(s,n)}catch{}},L=async()=>{try{const s=await(await v()).listContainers({filters:{status:["running"]}});return m=!1,s}catch(e){m||(m=!0,t.onUnavailable?.(e instanceof Error?e.message:String(e)));return}},k=async(e,s)=>{const f=new Set;for(const n of s){const l=C(n.Image),u=l===void 0?void 0:a.get(l);u!==void 0&&(f.add(n.Id),o.has(n.Id)||await p(e,n.Id,u))}for(const[n,l]of o)f.has(n)||(l.destroy(),o.delete(n))},E=async()=>{if(r)return;const e=await L();e!==void 0&&await k(await v(),e)};let g=!1;const h=()=>{g||r||(g=!0,E().finally(()=>{g=!1}).catch(()=>{}))};return i=setInterval(h,c),i.unref(),h(),{close:()=>{r=!0,i&&(clearInterval(i),i=void 0);for(const[e,s]of o)s.destroy(),o.delete(e)}}};export{T as streamContainerLogs};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const o=e=>JSON.stringify(e),$=/^[A-Z_a-z][\w$]*$/u,d=e=>$.test(e),u=e=>d(e)?e:`binding_${e.replaceAll(/\W/gu,"_")}`,m=(e,s=u(e))=>{const n=d(e);return n&&s===e?`${e},`:`${n?e:o(e)}: ${s},`},g=e=>{const s=new Set;for(const n of e.migrations??[])for(const r of n.new_sqlite_classes??[])s.add(r);return s},v=(e,s,n,r,c)=>{for(const a of e.durable_objects?.bindings??[])if(!(a.name===void 0||a.class_name===void 0)){if(a.script_name!==void 0){c.push(`durable_objects.${a.name} (external script_name "${a.script_name}")`);continue}n.add("DurableObjectNamespace"),r.push(m(a.name,`DurableObjectNamespace(${o(a.name)}, { className: ${o(a.class_name)}, sqlite: ${String(s.has(a.class_name))} })`))}},h=(e,s)=>{for(const[n,r]of Object.entries(e.vars??{}))s.push(m(n,o(r)))},f=["ai","analytics_engine_datasets","assets","browser","containers","flagship","hyperdrive","images","pipelines","secrets_store_secrets","send_email","services","tail_consumers","vectorize","workflows"],w=(e,s)=>{for(const n of f){const r=e[n];r!==void 0&&(!Array.isArray(r)||r.length>0)&&s.push(n)}(e.queues?.consumers?.length??0)>0&&s.push("queues.consumers")},k=e=>{const s=e.name??"worker",n=[],r=new Set(["Worker"]),c=[],a=[],p=g(e),b=[{construct:"D1Database",entries:(e.d1_databases??[]).map(t=>({binding:t.binding,name:t.database_name})),nameKey:"name"},{construct:"R2Bucket",entries:(e.r2_buckets??[]).map(t=>({binding:t.binding,name:t.bucket_name})),nameKey:"name"},{construct:"KVNamespace",entries:(e.kv_namespaces??[]).map(t=>({binding:t.binding,name:t.binding})),nameKey:"title"},{construct:"Queue",entries:(e.queues?.producers??[]).map(t=>({binding:t.binding,name:t.queue})),nameKey:"name"}];for(const{construct:t,entries:l,nameKey:y}of b)for(const i of l)i.binding!==void 0&&(r.add(t),c.push(`const ${u(i.binding)} = await ${t}(${o(i.binding)}, { adopt: true, ${y}: ${o(i.name??i.binding)} });`),a.push(m(i.binding)));v(e,p,r,a,n),h(e,a),w(e,n);const _=["adopt: true,",a.length===0?void 0:`bindings: {
|
|
2
|
+
${a.join(`
|
|
3
|
+
`)}
|
|
4
|
+
},`,e.compatibility_date===void 0?void 0:`compatibilityDate: ${o(e.compatibility_date)},`,e.compatibility_flags===void 0||e.compatibility_flags.length===0?void 0:`compatibilityFlags: ${o([...e.compatibility_flags])},`,e.triggers?.crons===void 0||e.triggers.crons.length===0?void 0:`crons: ${o([...e.triggers.crons])},`,e.main===void 0?void 0:`entrypoint: ${o(e.main)},`,`name: ${o(s)},`].filter(t=>t!==void 0);return{source:["// GENERATED by @lunora/config from wrangler.jsonc — do not edit.","// Re-generated on every `lunora deploy`; edit wrangler.jsonc instead.","",'import alchemy from "alchemy";',`import { ${[...r].toSorted((t,l)=>t.localeCompare(l)).join(", ")} } from "alchemy/cloudflare";`,"",`const app = await alchemy(${o(s)});`,"",...c.length===0?[]:[...c,""],`export const worker = await Worker(${o(s)}, {`,` ${_.join(`
|
|
5
|
+
`)}`,"});","","await app.finalize();",""].join(`
|
|
6
|
+
`),unsupported:n}};export{g as sqliteClasses,k as wranglerToAlchemy};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{runCodegen as c,CodegenDiagnosticError as a}from"@lunora/codegen";import{collectWranglerSecretVariables as i}from"./collectWranglerSecretVariables-D-usPfT8.mjs";import{isCodegenDisabled as s,CODEGEN_ENV as t}from"./CODEGEN_ENV-ZsCxV1kP.mjs";import{writeFileSync as m,renameSync as p,rmSync as d}from"node:fs";const g=r=>({apiSpec:r.apiSpec,lunoraDirectory:r.schemaDirectory??"lunora",projectRoot:r.projectRoot,wranglerVariables:i(r.projectRoot)}),y=r=>{if(s(process.env[t]))return[`codegen is off (${t}=0 / \`lunora dev --no-codegen\`) — the source was written but \`_generated/\` was NOT regenerated`];try{c(g(r))}catch(e){if(e instanceof a)return[e.message];throw e}return[]},S=(r,e)=>{const o=`${r}.lunora-tmp`;try{m(o,e,"utf8"),p(o,r)}catch(n){throw d(o,{force:!0}),n}};export{y as r,S as w};
|