@supacloud/compiler 0.51.2 → 0.52.1
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/DELIVERY.md +63 -12
- package/README.md +38 -1
- package/dist/cli.js +188 -41
- package/dist/delivery-bundle-protocol.d.ts +7 -0
- package/dist/delivery-bundle-worker.js +56 -7
- package/dist/delivery-function.d.ts +7 -0
- package/dist/delivery-render.d.ts +2 -2
- package/dist/diagnostics.d.ts +10 -10
- package/dist/index.js +188 -41
- package/dist/migration-app-version.d.ts +1 -1
- package/dist/migration-elysia-version.d.ts +1 -1
- package/dist/route-contracts.d.ts +3 -3
- package/dist/type-safety.d.ts +24 -24
- package/dist/types.d.ts +2 -0
- package/package.json +6 -6
package/DELIVERY.md
CHANGED
|
@@ -62,25 +62,48 @@ their kind. HTTP and Job ownership are independent, so one module can contribute
|
|
|
62
62
|
HTTP to `api` and Jobs to `jobs`. Two HTTP targets cannot both own the same module.
|
|
63
63
|
`api` and `jobs` are reserved for their matching workload kinds.
|
|
64
64
|
|
|
65
|
-
`kind: "function"` declares an Edge Function target
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
`kind: "function"` declares an Edge Function target. It always carries a
|
|
66
|
+
`function` descriptor (`slug`, `entrypoint`, `verifyJwt`). A Function target may
|
|
67
|
+
be standalone or own modules:
|
|
68
|
+
|
|
69
|
+
- **Standalone** (`modules` omitted): the entrypoint is the Function handler
|
|
70
|
+
itself. It may export a default function/object or named `fetch`/`handle`.
|
|
71
|
+
- **Module-backed** (for example `modules: ["reports"]`): the entrypoint is a
|
|
72
|
+
trusted host composition module exporting
|
|
73
|
+
`createDeliveryApplication(modules, lifecycle)`, the same contract used by an
|
|
74
|
+
HTTP host. The selected modules' HTTP routes move to the Function target; their
|
|
75
|
+
Jobs do not. This is the supported way to split a heavy module out of `api`
|
|
76
|
+
without writing a second application by hand.
|
|
69
77
|
|
|
70
78
|
```ts
|
|
71
79
|
{
|
|
72
80
|
version: 1,
|
|
73
81
|
targets: [
|
|
82
|
+
{ name: "reports", kind: "function", modules: ["reports"],
|
|
83
|
+
function: { slug: "app-reports", entrypoint: "functions/reports-host.ts", verifyJwt: true } },
|
|
74
84
|
{ name: "intake-hooks", kind: "function",
|
|
75
|
-
function: { slug: "
|
|
85
|
+
function: { slug: "app-intake-hooks", entrypoint: "functions/intake/index.ts", verifyJwt: false } },
|
|
76
86
|
],
|
|
77
87
|
}
|
|
78
88
|
```
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
For a module/feature declaration, the `functions` shorthand expands to the same
|
|
91
|
+
validated Function target. The target name defaults to the slug:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
{
|
|
95
|
+
version: 1,
|
|
96
|
+
functions: [
|
|
97
|
+
{ slug: "app-reports", modules: ["reports"],
|
|
98
|
+
entrypoint: "functions/reports-host.ts", verifyJwt: true },
|
|
99
|
+
],
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Expansion is deterministic and happens before route ownership. Duplicate target
|
|
104
|
+
names, duplicate Function slugs, and modules owned by two HTTP/Function targets
|
|
105
|
+
fail closed. The shorthand does not guess entrypoints or permissions. `api` and
|
|
106
|
+
`jobs` remain reserved for their matching workload kinds.
|
|
84
107
|
|
|
85
108
|
No unused explicit target is accepted. Unknown modules, duplicate ownership,
|
|
86
109
|
unresolved imports, cyclic dependencies, duplicate job names, and conflicting
|
|
@@ -152,7 +175,8 @@ delivery/
|
|
|
152
175
|
generated/application.ts
|
|
153
176
|
bundle/index.js
|
|
154
177
|
bundle/package.json
|
|
155
|
-
bundle/app.manifest.json
|
|
178
|
+
bundle/app.manifest.json # module-backed targets
|
|
179
|
+
bundle/function.json # Function targets only
|
|
156
180
|
bundle/target.json
|
|
157
181
|
bundle/assets/...
|
|
158
182
|
```
|
|
@@ -287,8 +311,10 @@ HOST=127.0.0.1 PORT=3000 bun --no-env-file bundle/index.js
|
|
|
287
311
|
```
|
|
288
312
|
|
|
289
313
|
HTTP objects have `entryKind: "bun-http-application"`; their entry is an executable
|
|
290
|
-
that starts the listener, not an import-only module factory.
|
|
291
|
-
|
|
314
|
+
that starts the listener, not an import-only module factory. Function targets
|
|
315
|
+
produce `entryKind: "bun-function-application"` entries exporting a default
|
|
316
|
+
`fetch` handler. Targets without a host keep
|
|
317
|
+
`entryKind: "compiled-module-factory"`. All object kinds still report
|
|
292
318
|
`deploymentReady: false`: a local build neither activates a service nor verifies
|
|
293
319
|
its environment, migrations, health, credentials, isolation or recovery.
|
|
294
320
|
HTTP object identities bind their executable discriminator; existing factory
|
|
@@ -310,6 +336,31 @@ and host cleanup; expiry exits nonzero without claiming cleanup succeeded.
|
|
|
310
336
|
Startup, listener and shutdown failures use generic messages; the host remains
|
|
311
337
|
responsible for sanitizing its own logging and responses.
|
|
312
338
|
|
|
339
|
+
## Runnable Functions
|
|
340
|
+
|
|
341
|
+
Module-backed Function targets use the same host contract as HTTP targets:
|
|
342
|
+
export `createDeliveryApplication(modules, lifecycle)` from the declared
|
|
343
|
+
entrypoint. The generated bundle exports a default `{ fetch(request) }` object.
|
|
344
|
+
The host is created lazily once per Function isolate and the host owns its
|
|
345
|
+
identity, database, governance, and error policy. The compiler does not provide
|
|
346
|
+
an anonymous or in-memory fallback.
|
|
347
|
+
|
|
348
|
+
Standalone Function targets do not require a compiler application graph. Their
|
|
349
|
+
declared entrypoint is imported and its default export (or the module namespace
|
|
350
|
+
when there is no default) becomes the Function handler. Use this for an existing
|
|
351
|
+
fetch handler that has no module-owned HTTP routes.
|
|
352
|
+
|
|
353
|
+
Function bundles include `bundle/function.json` with the attested slug,
|
|
354
|
+
entrypoint, and `verifyJwt` declaration. Module-backed Functions also include
|
|
355
|
+
the normal application manifest, execution context, and development metadata;
|
|
356
|
+
standalone Functions do not. Function objects carry
|
|
357
|
+
`entryKind: "bun-function-application"` in their immutable identity.
|
|
358
|
+
|
|
359
|
+
This stage builds local Function artifacts only. Application release upload still
|
|
360
|
+
rejects a delivery manifest containing Function targets, so they cannot be
|
|
361
|
+
silently started as application HTTP services. Creating the Edge Function
|
|
362
|
+
version, activation, and receipt remains a separate trusted release operation.
|
|
363
|
+
|
|
313
364
|
## Runnable Workers
|
|
314
365
|
|
|
315
366
|
Job targets can explicitly bind a worker host:
|
package/README.md
CHANGED
|
@@ -594,6 +594,42 @@ parameters、requestBody、responses、securitySchemes 以及 `x-supacloud` 路
|
|
|
594
594
|
因此不会维护第二份 API contract。默认包含 bearer JWT scheme;项目可在
|
|
595
595
|
`openApi` 配置中补充文档信息、servers 和其他显式 security schemes。
|
|
596
596
|
|
|
597
|
+
内存受限的业务进程可配置 `openApi: { snapshots: false }`,只生成
|
|
598
|
+
`createOpenApiDocument` 和 `serializeOpenApiDocument` 工厂,不导出
|
|
599
|
+
`OPENAPI_DOCUMENT` / `OPENAPI_JSON`,也不在模块加载时转换完整文档或序列化 JSON。
|
|
600
|
+
例如:
|
|
601
|
+
|
|
602
|
+
```ts
|
|
603
|
+
export default defineSupacloudConfig({
|
|
604
|
+
generateOpenApi: true,
|
|
605
|
+
openApi: { title: "Orders API", version: "1.0.0", snapshots: false },
|
|
606
|
+
});
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
重新生成后,可将工厂传给可选文档插件,按请求创建文档:
|
|
610
|
+
|
|
611
|
+
```ts
|
|
612
|
+
import { createOpenApiDocument } from "./generated/openapi";
|
|
613
|
+
|
|
614
|
+
const documentation = {
|
|
615
|
+
openApi: { document: createOpenApiDocument },
|
|
616
|
+
};
|
|
617
|
+
// createApplication({ ..., documentation })
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
该模式仍加载文档所引用的 schema 和路由定义,但不会缓存生成的文档对象或 JSON
|
|
621
|
+
字符串。`serializeOpenApiDocument()` 每次调用都会创建并序列化一份新文档;传入
|
|
622
|
+
显式 document 时直接序列化该对象。应用路由的响应校验不受影响。
|
|
623
|
+
|
|
624
|
+
需要彻底移出业务进程时,在构建/发布阶段使用下方 `openapi-export` 导出静态
|
|
625
|
+
`openapi.json`,由静态服务或独立文档入口提供,业务入口不再导入生成的 OpenAPI
|
|
626
|
+
模块。GraphQL SDL 同样可直接发布已有 `schema.graphql` 文件;生成的 GraphQL
|
|
627
|
+
查询和结果校验应继续保留。部署必须显式携带这些静态文件,单文件函数 bundle
|
|
628
|
+
不能假设请求时可访问源码目录。
|
|
629
|
+
|
|
630
|
+
`snapshots` 默认仍为 `true`,保持旧导出兼容。快照初始化带有 pure 注解,支持该
|
|
631
|
+
注解的打包器可移除未使用的快照;未打包导入默认模块仍会创建两份快照。
|
|
632
|
+
|
|
597
633
|
`OPENAPI_JSON` 是运行时快照;需要提交独立 `openapi.json` 时,在应用已经能加载
|
|
598
634
|
生成模块的运行时调用 `exportGeneratedOpenApiJson()` 或直接写出该字符串。编译器
|
|
599
635
|
不会为了生成 JSON 执行应用 schema。`readOpenApiJson()` 和
|
|
@@ -625,7 +661,8 @@ supacloud-compiler openapi-export ./generated/openapi.ts ./generated/openapi.jso
|
|
|
625
661
|
supacloud-compiler openapi-diff ./contracts/openapi.base.json ./generated/openapi.json --json
|
|
626
662
|
```
|
|
627
663
|
|
|
628
|
-
`openapi-export` 在运行时加载生成的 `openapi.ts` 并原子地写出独立 JSON
|
|
664
|
+
`openapi-export` 在运行时加载生成的 `openapi.ts` 并原子地写出独立 JSON;也支持
|
|
665
|
+
`snapshots: false` 的模块,此时调用 `createOpenApiDocument()`。它不会在
|
|
629
666
|
编译阶段执行应用 schema。可用 `--space 0` 到 `--space 10` 控制缩进,重复执行不会
|
|
630
667
|
改写内容不变的文件。当前只承诺 JSON 输出,YAML 转换由发布流水线按需处理。
|
|
631
668
|
|
package/dist/cli.js
CHANGED
|
@@ -3438,6 +3438,7 @@ ${procedureMethods.join(`
|
|
|
3438
3438
|
function renderOpenApi(graph, options) {
|
|
3439
3439
|
const rootDir = options?.rootDir ?? process.cwd();
|
|
3440
3440
|
const outDir = options?.outDir ?? process.cwd();
|
|
3441
|
+
const snapshots = options?.openApi?.snapshots !== false;
|
|
3441
3442
|
const imports = new ImportManager;
|
|
3442
3443
|
const schemaLocals = new Map;
|
|
3443
3444
|
const schemaComponents = new Map;
|
|
@@ -3933,14 +3934,18 @@ function renderOpenApi(graph, options) {
|
|
|
3933
3934
|
" };",
|
|
3934
3935
|
"}",
|
|
3935
3936
|
"",
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3937
|
+
...snapshots ? [
|
|
3938
|
+
"export const OPENAPI_DOCUMENT = /* @__PURE__ */ createOpenApiDocument();",
|
|
3939
|
+
""
|
|
3940
|
+
] : [],
|
|
3941
|
+
`export function serializeOpenApiDocument(document: OpenApiDocument = ${snapshots ? "OPENAPI_DOCUMENT" : "createOpenApiDocument()"}, space = 2): string {`,
|
|
3939
3942
|
' return JSON.stringify(document, null, space) + "\\n";',
|
|
3940
3943
|
"}",
|
|
3941
3944
|
"",
|
|
3942
|
-
|
|
3943
|
-
|
|
3945
|
+
...snapshots ? [
|
|
3946
|
+
"export const OPENAPI_JSON = /* @__PURE__ */ serializeOpenApiDocument();",
|
|
3947
|
+
""
|
|
3948
|
+
] : []
|
|
3944
3949
|
].join(`
|
|
3945
3950
|
`);
|
|
3946
3951
|
}
|
|
@@ -12084,12 +12089,18 @@ var init_time = __esm(() => {
|
|
|
12084
12089
|
|
|
12085
12090
|
// node_modules/typebox/build/format/date_time.mjs
|
|
12086
12091
|
function IsDateTime(value) {
|
|
12087
|
-
const
|
|
12088
|
-
|
|
12092
|
+
const index = value.indexOf("[");
|
|
12093
|
+
const datetime = index === -1 ? value : value.slice(0, index);
|
|
12094
|
+
if (index !== -1 && !DATE_TIME_SUFFIX.test(value.slice(index)))
|
|
12095
|
+
return false;
|
|
12096
|
+
const split = datetime.split(/T/i);
|
|
12097
|
+
return split.length === 2 && IsDate2(split[0]) && IsTime(split[1]);
|
|
12089
12098
|
}
|
|
12099
|
+
var DATE_TIME_SUFFIX;
|
|
12090
12100
|
var init_date_time = __esm(() => {
|
|
12091
12101
|
init_date();
|
|
12092
12102
|
init_time();
|
|
12103
|
+
DATE_TIME_SUFFIX = /^(?:\[!?(?:(?!\.{1,2}[/\]])[A-Za-z._][A-Za-z._0-9+-]{0,13}(?:\/(?!\.{1,2}[/\]])[A-Za-z._][A-Za-z._0-9+-]{0,13})*|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])\](?:\[!?[a-z_][a-z_0-9-]*=[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\])*|(?:\[!?[a-z_][a-z_0-9-]*=[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\])*)$/;
|
|
12093
12104
|
});
|
|
12094
12105
|
|
|
12095
12106
|
// node_modules/typebox/build/format/duration.mjs
|
|
@@ -16260,10 +16271,27 @@ function parseDeliveryOptions(value) {
|
|
|
16260
16271
|
throw new DeliveryConfigurationError;
|
|
16261
16272
|
}
|
|
16262
16273
|
for (const target of value.targets ?? []) {
|
|
16263
|
-
const invalidShape = target.kind === "function" ? target.function === undefined || target.
|
|
16274
|
+
const invalidShape = target.kind === "function" ? target.function === undefined || target.compute !== undefined : target.modules === undefined || target.function !== undefined;
|
|
16264
16275
|
if (invalidShape)
|
|
16265
16276
|
throw new DeliveryConfigurationError;
|
|
16266
16277
|
}
|
|
16278
|
+
const targetNames = new Set((value.targets ?? []).map((target) => target.name));
|
|
16279
|
+
const functionSlugs = new Set;
|
|
16280
|
+
for (const target of value.targets ?? []) {
|
|
16281
|
+
if (target.function !== undefined && functionSlugs.has(target.function.slug)) {
|
|
16282
|
+
throw new DeliveryConfigurationError;
|
|
16283
|
+
}
|
|
16284
|
+
if (target.function !== undefined)
|
|
16285
|
+
functionSlugs.add(target.function.slug);
|
|
16286
|
+
}
|
|
16287
|
+
for (const declared of value.functions ?? []) {
|
|
16288
|
+
const name = declared.name ?? declared.slug;
|
|
16289
|
+
if (targetNames.has(name) || functionSlugs.has(declared.slug)) {
|
|
16290
|
+
throw new DeliveryConfigurationError;
|
|
16291
|
+
}
|
|
16292
|
+
targetNames.add(name);
|
|
16293
|
+
functionSlugs.add(declared.slug);
|
|
16294
|
+
}
|
|
16267
16295
|
const migrations = value.build?.migrations ?? [];
|
|
16268
16296
|
try {
|
|
16269
16297
|
validateWorkerExecution(value.execution?.groups ?? []);
|
|
@@ -16273,14 +16301,30 @@ function parseDeliveryOptions(value) {
|
|
|
16273
16301
|
if (new Set(migrations.map((item) => item.version)).size !== migrations.length || new Set(migrations.map((item) => item.source)).size !== migrations.length || migrations.some((item) => BigInt(item.version) > 9223372036854775807n || !/\.sql$/i.test(item.source) || item.source.split("/").includes("node_modules"))) {
|
|
16274
16302
|
throw new DeliveryConfigurationError;
|
|
16275
16303
|
}
|
|
16276
|
-
|
|
16304
|
+
if (value.functions === undefined || value.functions.length === 0)
|
|
16305
|
+
return value;
|
|
16306
|
+
const targets = [...value.targets ?? []];
|
|
16307
|
+
for (const declared of value.functions) {
|
|
16308
|
+
targets.push({
|
|
16309
|
+
name: declared.name ?? declared.slug,
|
|
16310
|
+
kind: "function",
|
|
16311
|
+
modules: [...declared.modules],
|
|
16312
|
+
function: {
|
|
16313
|
+
slug: declared.slug,
|
|
16314
|
+
entrypoint: declared.entrypoint,
|
|
16315
|
+
verifyJwt: declared.verifyJwt
|
|
16316
|
+
}
|
|
16317
|
+
});
|
|
16318
|
+
}
|
|
16319
|
+
const { functions: _expandedFunctions, ...rest } = value;
|
|
16320
|
+
return { ...rest, targets };
|
|
16277
16321
|
}
|
|
16278
16322
|
function parseDeliveryPlanResult(value) {
|
|
16279
16323
|
if (!Check2(DeliveryPlanResultSchema, value))
|
|
16280
16324
|
throw new Error("Invalid delivery plan result.");
|
|
16281
16325
|
return value;
|
|
16282
16326
|
}
|
|
16283
|
-
var objectOptions, reference2, references, kind2, isolation, mode2, DeliveryFilePathSchema, functionTarget, DeliveryOptionsSchema, DeliveryDiagnosticSchema, routeSchema, jobSchema, DeliveryTargetSchema, DeliveryPlanSchema, DeliveryPlanResultSchema, DeliveryConfigurationError;
|
|
16327
|
+
var objectOptions, reference2, references, kind2, isolation, targetName, functionSlug, mode2, DeliveryFilePathSchema, functionTarget, automaticFunction, DeliveryOptionsSchema, DeliveryDiagnosticSchema, routeSchema, jobSchema, DeliveryTargetSchema, DeliveryPlanSchema, DeliveryPlanResultSchema, DeliveryConfigurationError;
|
|
16284
16328
|
var init_delivery_schema = __esm(() => {
|
|
16285
16329
|
init_build();
|
|
16286
16330
|
init_value2();
|
|
@@ -16290,13 +16334,22 @@ var init_delivery_schema = __esm(() => {
|
|
|
16290
16334
|
references = _Array_(reference2, { uniqueItems: true });
|
|
16291
16335
|
kind2 = Union([Literal("api"), Literal("jobs"), Literal("webhook"), Literal("function")]);
|
|
16292
16336
|
isolation = Union([Literal("shared"), Literal("process")]);
|
|
16337
|
+
targetName = String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" });
|
|
16338
|
+
functionSlug = String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" });
|
|
16293
16339
|
mode2 = Union([Literal("required"), Literal("none")]);
|
|
16294
16340
|
DeliveryFilePathSchema = String2({
|
|
16295
16341
|
maxLength: 512,
|
|
16296
16342
|
pattern: "^(?:[A-Za-z0-9_-][A-Za-z0-9_.-]*/)*[A-Za-z0-9_-][A-Za-z0-9_.-]*$"
|
|
16297
16343
|
});
|
|
16298
16344
|
functionTarget = _Object_({
|
|
16299
|
-
slug:
|
|
16345
|
+
slug: functionSlug,
|
|
16346
|
+
entrypoint: DeliveryFilePathSchema,
|
|
16347
|
+
verifyJwt: Boolean2()
|
|
16348
|
+
}, objectOptions);
|
|
16349
|
+
automaticFunction = _Object_({
|
|
16350
|
+
name: Optional(targetName),
|
|
16351
|
+
slug: functionSlug,
|
|
16352
|
+
modules: _Array_(reference2, { minItems: 1, uniqueItems: true }),
|
|
16300
16353
|
entrypoint: DeliveryFilePathSchema,
|
|
16301
16354
|
verifyJwt: Boolean2()
|
|
16302
16355
|
}, objectOptions);
|
|
@@ -16304,7 +16357,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
16304
16357
|
version: Literal(1),
|
|
16305
16358
|
execution: Optional(WorkerExecutionSchema),
|
|
16306
16359
|
targets: Optional(_Array_(_Object_({
|
|
16307
|
-
name:
|
|
16360
|
+
name: targetName,
|
|
16308
16361
|
kind: kind2,
|
|
16309
16362
|
modules: Optional(_Array_(reference2, { minItems: 1, uniqueItems: true })),
|
|
16310
16363
|
isolation: Optional(isolation),
|
|
@@ -16312,6 +16365,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
16312
16365
|
compute: Optional(ComputeResourcesSchema),
|
|
16313
16366
|
function: Optional(functionTarget)
|
|
16314
16367
|
}, objectOptions))),
|
|
16368
|
+
functions: Optional(_Array_(automaticFunction, { maxItems: 32 })),
|
|
16315
16369
|
runtime: Optional(_Object_({
|
|
16316
16370
|
processIsolation: Boolean2(),
|
|
16317
16371
|
durableQueue: Boolean2(),
|
|
@@ -16616,7 +16670,7 @@ function parseDeliveryBuildManifest(value) {
|
|
|
16616
16670
|
}
|
|
16617
16671
|
for (const object of value.objects) {
|
|
16618
16672
|
const target = value.plan.targets.find((target) => target.name === object.name);
|
|
16619
|
-
if (["bun-worker-application", "go-worker-application", "scriptc-worker-application"].includes(object.entryKind) && target?.kind !== "jobs" || object.entryKind === "bun-http-application" && target?.kind === "jobs") {
|
|
16673
|
+
if (["bun-worker-application", "go-worker-application", "scriptc-worker-application"].includes(object.entryKind) && target?.kind !== "jobs" || object.entryKind === "bun-http-application" && target?.kind === "jobs" || object.entryKind === "bun-function-application" && target?.kind !== "function" || target?.kind === "function" && object.entryKind !== "bun-function-application") {
|
|
16620
16674
|
throw new Error("Delivery executable kind does not match its target.");
|
|
16621
16675
|
}
|
|
16622
16676
|
if (new Set(object.files.map((file) => file.path)).size !== object.files.length || !object.files.some((file) => file.path === object.entrypoint) || deliveryObjectDigest(object) !== object.objectId) {
|
|
@@ -16660,6 +16714,7 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
16660
16714
|
Literal("compiled-module-factory"),
|
|
16661
16715
|
Literal("bun-http-application"),
|
|
16662
16716
|
Literal("bun-worker-application"),
|
|
16717
|
+
Literal("bun-function-application"),
|
|
16663
16718
|
Literal("go-worker-application"),
|
|
16664
16719
|
Literal("scriptc-worker-application")
|
|
16665
16720
|
]),
|
|
@@ -17104,7 +17159,7 @@ var init_application_release = __esm(() => {
|
|
|
17104
17159
|
});
|
|
17105
17160
|
|
|
17106
17161
|
// node_modules/@supacloud/delivery/src/application-configuration.ts
|
|
17107
|
-
var ApplicationConfigurationIdSchema,
|
|
17162
|
+
var ApplicationConfigurationIdSchema, targetName2, variableName2, kind3, hosts, bunVersion, ApplicationConfigurationSchema, ApplicationConfigurationWriteSchema, ApplicationConfigurationViewSchema, APPLICATION_RESERVED_ENVIRONMENT_NAMES;
|
|
17108
17163
|
var init_application_configuration = __esm(() => {
|
|
17109
17164
|
init_build();
|
|
17110
17165
|
init_value2();
|
|
@@ -17112,7 +17167,7 @@ var init_application_configuration = __esm(() => {
|
|
|
17112
17167
|
ApplicationConfigurationIdSchema = String2({
|
|
17113
17168
|
pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$"
|
|
17114
17169
|
});
|
|
17115
|
-
|
|
17170
|
+
targetName2 = String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" });
|
|
17116
17171
|
variableName2 = String2({ pattern: "^[A-Z][A-Z0-9_]{0,127}$" });
|
|
17117
17172
|
kind3 = Union([Literal("http"), Literal("worker")]);
|
|
17118
17173
|
hosts = _Array_(String2({ minLength: 1, maxLength: 253 }), { maxItems: 32, uniqueItems: true });
|
|
@@ -17120,7 +17175,7 @@ var init_application_configuration = __esm(() => {
|
|
|
17120
17175
|
ApplicationConfigurationSchema = _Object_({
|
|
17121
17176
|
bun_version: bunVersion,
|
|
17122
17177
|
targets: _Array_(_Object_({
|
|
17123
|
-
name:
|
|
17178
|
+
name: targetName2,
|
|
17124
17179
|
kind: kind3,
|
|
17125
17180
|
hosts,
|
|
17126
17181
|
environment: Record(variableName2, String2({ maxLength: 16384 }), {
|
|
@@ -17143,7 +17198,7 @@ var init_application_configuration = __esm(() => {
|
|
|
17143
17198
|
created_at: String2(),
|
|
17144
17199
|
bun_version: bunVersion,
|
|
17145
17200
|
targets: _Array_(_Object_({
|
|
17146
|
-
name:
|
|
17201
|
+
name: targetName2,
|
|
17147
17202
|
kind: kind3,
|
|
17148
17203
|
hosts,
|
|
17149
17204
|
environment_names: _Array_(variableName2, { maxItems: 128, uniqueItems: true })
|
|
@@ -17930,6 +17985,19 @@ var init_delivery_migration_archive = __esm(() => {
|
|
|
17930
17985
|
// node_modules/@supacloud/delivery/src/delivery-migration-plan.ts
|
|
17931
17986
|
var init_delivery_migration_plan = () => {};
|
|
17932
17987
|
|
|
17988
|
+
// node_modules/@supacloud/delivery/src/release-contract.ts
|
|
17989
|
+
var ALLOWED_PHASE_TRANSITIONS;
|
|
17990
|
+
var init_release_contract = __esm(() => {
|
|
17991
|
+
ALLOWED_PHASE_TRANSITIONS = new Map([
|
|
17992
|
+
["planned", ["mutating", "rollback-required"]],
|
|
17993
|
+
["mutating", ["applied", "rollback-required"]],
|
|
17994
|
+
["applied", ["reconciled", "rollback-required"]],
|
|
17995
|
+
["reconciled", []],
|
|
17996
|
+
["rollback-required", ["rolled-back", "reconciled"]],
|
|
17997
|
+
["rolled-back", []]
|
|
17998
|
+
]);
|
|
17999
|
+
});
|
|
18000
|
+
|
|
17933
18001
|
// node_modules/@supacloud/delivery/src/index.ts
|
|
17934
18002
|
var init_src = __esm(() => {
|
|
17935
18003
|
init_delivery_artifact();
|
|
@@ -17953,6 +18021,7 @@ var init_src = __esm(() => {
|
|
|
17953
18021
|
init_delivery_build_schema();
|
|
17954
18022
|
init_delivery_migration_archive();
|
|
17955
18023
|
init_delivery_migration_plan();
|
|
18024
|
+
init_release_contract();
|
|
17956
18025
|
});
|
|
17957
18026
|
|
|
17958
18027
|
// src/delivery-migration-archive.ts
|
|
@@ -23991,7 +24060,7 @@ function createDeliveryPlan(graph, input, validation) {
|
|
|
23991
24060
|
name: declaration.name,
|
|
23992
24061
|
kind: "function",
|
|
23993
24062
|
isolation: "shared",
|
|
23994
|
-
roots: [],
|
|
24063
|
+
roots: sorted(declaration.modules ?? []),
|
|
23995
24064
|
modules: [],
|
|
23996
24065
|
routes: [],
|
|
23997
24066
|
jobs: [],
|
|
@@ -24780,6 +24849,53 @@ interface DeliveryWorkerHost {
|
|
|
24780
24849
|
`;
|
|
24781
24850
|
}
|
|
24782
24851
|
|
|
24852
|
+
// src/delivery-function.ts
|
|
24853
|
+
function renderDeliveryFunctionEntry(generatedDirectory, hostPath) {
|
|
24854
|
+
const specifier = relativeImportPath(generatedDirectory, hostPath);
|
|
24855
|
+
return `
|
|
24856
|
+
import * as deliveryFunctionHostModule from ${JSON.stringify(specifier)};
|
|
24857
|
+
|
|
24858
|
+
type DeliveryFunctionHost = {
|
|
24859
|
+
fetch(request: Request): Response | Promise<Response>;
|
|
24860
|
+
};
|
|
24861
|
+
|
|
24862
|
+
const createDeliveryFunctionHost = (deliveryFunctionHostModule as {
|
|
24863
|
+
createDeliveryApplication?: (
|
|
24864
|
+
modules: ReturnType<typeof createCompiledModules>,
|
|
24865
|
+
lifecycle: { signal: AbortSignal },
|
|
24866
|
+
) => DeliveryFunctionHost | Promise<DeliveryFunctionHost>;
|
|
24867
|
+
}).createDeliveryApplication;
|
|
24868
|
+
if (typeof createDeliveryFunctionHost !== "function") {
|
|
24869
|
+
throw new Error("Invalid delivery Function host.");
|
|
24870
|
+
}
|
|
24871
|
+
const deliveryCreateHost = createDeliveryFunctionHost;
|
|
24872
|
+
|
|
24873
|
+
const deliveryFunctionLifecycle = new AbortController();
|
|
24874
|
+
let deliveryFunctionHost: Promise<DeliveryFunctionHost> | undefined;
|
|
24875
|
+
function deliveryHost(): Promise<DeliveryFunctionHost> {
|
|
24876
|
+
return deliveryFunctionHost ??= Promise.resolve(
|
|
24877
|
+
deliveryCreateHost(createCompiledModules(), { signal: deliveryFunctionLifecycle.signal }),
|
|
24878
|
+
);
|
|
24879
|
+
}
|
|
24880
|
+
|
|
24881
|
+
export default {
|
|
24882
|
+
async fetch(request: Request): Promise<Response> {
|
|
24883
|
+
return (await deliveryHost()).fetch(request);
|
|
24884
|
+
},
|
|
24885
|
+
};
|
|
24886
|
+
`;
|
|
24887
|
+
}
|
|
24888
|
+
function renderStandaloneFunctionEntry(generatedDirectory, entrypointPath) {
|
|
24889
|
+
const specifier = relativeImportPath(generatedDirectory, entrypointPath);
|
|
24890
|
+
return `
|
|
24891
|
+
import * as deliveryFunctionEntry from ${JSON.stringify(specifier)};
|
|
24892
|
+
|
|
24893
|
+
const deliveryFunctionDefault: unknown = (deliveryFunctionEntry as { default?: unknown }).default
|
|
24894
|
+
?? deliveryFunctionEntry;
|
|
24895
|
+
export default deliveryFunctionDefault;
|
|
24896
|
+
`;
|
|
24897
|
+
}
|
|
24898
|
+
|
|
24783
24899
|
// src/delivery-migrations.ts
|
|
24784
24900
|
init_delivery_files2();
|
|
24785
24901
|
import { resolve as resolve16 } from "node:path";
|
|
@@ -24875,14 +24991,6 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
24875
24991
|
const planned = createDeliveryPlan({ ...checked.graph, diagnostics: checked.diagnostics }, settings, options);
|
|
24876
24992
|
if (!planned.ok)
|
|
24877
24993
|
return failed(planned.diagnostics);
|
|
24878
|
-
if (planned.plan.targets.some((target) => target.kind === "function")) {
|
|
24879
|
-
return failed([{
|
|
24880
|
-
severity: "error",
|
|
24881
|
-
code: "delivery-function-build-unsupported",
|
|
24882
|
-
message: "Function target rendering is not implemented yet; the delivery build only produces HTTP and Worker application objects.",
|
|
24883
|
-
suggestion: "Declare HTTP/Worker application targets for now; Function and schedule delivery is tracked separately."
|
|
24884
|
-
}]);
|
|
24885
|
-
}
|
|
24886
24994
|
if (options.graphql && checked.mismatches.some((mismatch) => mismatch.startsWith("graphql"))) {
|
|
24887
24995
|
throw new Error("Refresh GraphQL artifacts with compile before building independent targets.");
|
|
24888
24996
|
}
|
|
@@ -24912,6 +25020,17 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
24912
25020
|
hosts.set(app.target, { path, kind, hash: digest(await readOwned(sourceRoot, path)) });
|
|
24913
25021
|
}
|
|
24914
25022
|
}
|
|
25023
|
+
for (const target of planned.plan.targets) {
|
|
25024
|
+
if (target.kind !== "function" || target.modules.length === 0 || target.function === undefined)
|
|
25025
|
+
continue;
|
|
25026
|
+
if (hosts.has(target.name))
|
|
25027
|
+
throw new Error("Duplicate delivery application host.");
|
|
25028
|
+
const path = resolve17(sourceRoot, target.function.entrypoint);
|
|
25029
|
+
if (inside(generatedRoot, path) || !/\.[cm]?ts$/.test(path)) {
|
|
25030
|
+
throw new Error("Function hosts require application TypeScript source.");
|
|
25031
|
+
}
|
|
25032
|
+
hosts.set(target.name, { path, kind: "function", hash: digest(await readOwned(sourceRoot, path)) });
|
|
25033
|
+
}
|
|
24915
25034
|
phase = "migration-inputs";
|
|
24916
25035
|
const migrations = await prepareDeliveryMigrations(project, generatedRoot, settings.build?.migrations);
|
|
24917
25036
|
phase = "output-ownership";
|
|
@@ -24966,19 +25085,38 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
24966
25085
|
const stage = await mkdtemp(join10(objectRoot, ".build-"));
|
|
24967
25086
|
temporary.push(stage);
|
|
24968
25087
|
const generatedDirectory = join10(objectRoot, "0".repeat(64), "generated");
|
|
24969
|
-
const
|
|
25088
|
+
const host = hosts.get(target.name);
|
|
25089
|
+
const standaloneFunction = target.kind === "function" && target.modules.length === 0;
|
|
25090
|
+
const rendered = standaloneFunction ? undefined : renderDeliveryTarget(checked.graph, target, {
|
|
24970
25091
|
...options,
|
|
24971
25092
|
rootDir: sourceRoot,
|
|
24972
25093
|
outDir: generatedDirectory
|
|
24973
25094
|
});
|
|
24974
|
-
|
|
24975
|
-
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
24980
|
-
|
|
24981
|
-
|
|
25095
|
+
let entryKind;
|
|
25096
|
+
let applicationCode;
|
|
25097
|
+
let generated;
|
|
25098
|
+
if (standaloneFunction) {
|
|
25099
|
+
if (target.function === undefined)
|
|
25100
|
+
throw new Error("Function target requires an entrypoint descriptor.");
|
|
25101
|
+
const entrypointPath = resolve17(sourceRoot, target.function.entrypoint);
|
|
25102
|
+
if (inside(generatedRoot, entrypointPath) || !/\.[cm]?ts$/.test(entrypointPath)) {
|
|
25103
|
+
throw new Error("Standalone Function entrypoints require application TypeScript source.");
|
|
25104
|
+
}
|
|
25105
|
+
entryKind = "bun-function-application";
|
|
25106
|
+
applicationCode = renderStandaloneFunctionEntry(generatedDirectory, entrypointPath);
|
|
25107
|
+
generated = { "function.ts": applicationCode };
|
|
25108
|
+
} else {
|
|
25109
|
+
if (target.kind === "function" && host?.kind !== "function") {
|
|
25110
|
+
throw new Error("Module-backed Function targets require an entrypoint host.");
|
|
25111
|
+
}
|
|
25112
|
+
entryKind = target.kind === "function" ? "bun-function-application" : host?.kind === "http" ? "bun-http-application" : host?.kind === "worker" ? "bun-worker-application" : "compiled-module-factory";
|
|
25113
|
+
applicationCode = rendered.applicationCode + (host?.kind === "http" ? renderDeliveryHttpEntry(generatedDirectory, host.path) : host?.kind === "worker" ? renderDeliveryWorkerEntry(generatedDirectory, host.path) : host?.kind === "function" ? renderDeliveryFunctionEntry(generatedDirectory, host.path) : "");
|
|
25114
|
+
generated = {
|
|
25115
|
+
"application.ts": applicationCode,
|
|
25116
|
+
...rendered.clientCode === undefined ? {} : { "client.ts": rendered.clientCode },
|
|
25117
|
+
...rendered.permissionsCode === undefined ? {} : { "permissions.ts": rendered.permissionsCode }
|
|
25118
|
+
};
|
|
25119
|
+
}
|
|
24982
25120
|
const unsafe = scanGeneratedArtifacts(generated, true);
|
|
24983
25121
|
if (unsafe.some((item) => item.severity === "error"))
|
|
24984
25122
|
return failed(unsafe);
|
|
@@ -25021,9 +25159,14 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
25021
25159
|
for (const [path, bytes] of bundled.files)
|
|
25022
25160
|
await writeArtifact(stage, path, bytes);
|
|
25023
25161
|
await writeArtifact(stage, "bundle/package.json", canonical2({ type: "module", private: true }));
|
|
25024
|
-
|
|
25025
|
-
|
|
25026
|
-
|
|
25162
|
+
if (target.kind === "function" && target.function !== undefined) {
|
|
25163
|
+
await writeArtifact(stage, "bundle/function.json", canonical2(target.function));
|
|
25164
|
+
}
|
|
25165
|
+
if (rendered !== undefined) {
|
|
25166
|
+
await writeArtifact(stage, "bundle/app.manifest.json", rendered.manifestJson);
|
|
25167
|
+
await writeArtifact(stage, "bundle/execution-context.json", rendered.executionSnapshot);
|
|
25168
|
+
await writeArtifact(stage, "bundle/application-development.json", rendered.applicationDevelopment);
|
|
25169
|
+
}
|
|
25027
25170
|
for (const [path, bytes] of migrations.files)
|
|
25028
25171
|
await writeArtifact(stage, path, bytes);
|
|
25029
25172
|
await writeArtifact(stage, "bundle/target.json", canonical2({
|
|
@@ -25157,10 +25300,10 @@ import { readFileSync as readFileSync4 } from "node:fs";
|
|
|
25157
25300
|
import { resolve as resolve18 } from "node:path";
|
|
25158
25301
|
|
|
25159
25302
|
// src/migration-app-version.ts
|
|
25160
|
-
var MIGRATION_APP_VERSION = "0.
|
|
25303
|
+
var MIGRATION_APP_VERSION = "0.34.1";
|
|
25161
25304
|
|
|
25162
25305
|
// src/migration-elysia-version.ts
|
|
25163
|
-
var MIGRATION_ELYSIA_VERSION = "0.36.
|
|
25306
|
+
var MIGRATION_ELYSIA_VERSION = "0.36.3";
|
|
25164
25307
|
|
|
25165
25308
|
// src/migration-policy.ts
|
|
25166
25309
|
var cachedCompilerVersion;
|
|
@@ -26039,7 +26182,11 @@ async function loadGeneratedOpenApiDocument(modulePath) {
|
|
|
26039
26182
|
const loaded = await import(moduleUrl.href);
|
|
26040
26183
|
if (!isRecord(loaded))
|
|
26041
26184
|
throw new OpenApiDocumentError;
|
|
26042
|
-
|
|
26185
|
+
if ("OPENAPI_DOCUMENT" in loaded)
|
|
26186
|
+
return parseOpenApiDocument(loaded["OPENAPI_DOCUMENT"]);
|
|
26187
|
+
if (typeof loaded["createOpenApiDocument"] !== "function")
|
|
26188
|
+
throw new OpenApiDocumentError;
|
|
26189
|
+
return parseOpenApiDocument(await loaded["createOpenApiDocument"]());
|
|
26043
26190
|
} catch (error) {
|
|
26044
26191
|
if (error instanceof OpenApiDocumentError)
|
|
26045
26192
|
throw error;
|
|
@@ -57,6 +57,13 @@ declare const requestSchema: Type.TObject<{
|
|
|
57
57
|
verifyJwt: Type.TBoolean;
|
|
58
58
|
}>>;
|
|
59
59
|
}>>>;
|
|
60
|
+
functions: Type.TOptional<Type.TArray<Type.TObject<{
|
|
61
|
+
name: Type.TOptional<Type.TString>;
|
|
62
|
+
slug: Type.TString;
|
|
63
|
+
modules: Type.TArray<Type.TString>;
|
|
64
|
+
entrypoint: Type.TString;
|
|
65
|
+
verifyJwt: Type.TBoolean;
|
|
66
|
+
}>>>;
|
|
60
67
|
runtime: Type.TOptional<Type.TObject<{
|
|
61
68
|
processIsolation: Type.TBoolean;
|
|
62
69
|
durableQueue: Type.TBoolean;
|