@base44/functions-compiler 0.1.0
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/README.md +137 -0
- package/lib/dist/activation-shim.mjs +237 -0
- package/lib/dist/actor.mjs +1129 -0
- package/lib/dist/deno-shim.mjs +2347 -0
- package/lib/src/actor-compat.d.ts +24 -0
- package/lib/src/actor-compat.js +302 -0
- package/lib/src/actor-compat.js.map +1 -0
- package/lib/src/bundler.d.ts +51 -0
- package/lib/src/bundler.js +321 -0
- package/lib/src/bundler.js.map +1 -0
- package/lib/src/contracts.d.ts +108 -0
- package/lib/src/contracts.js +39 -0
- package/lib/src/contracts.js.map +1 -0
- package/lib/src/deno-bundle.d.ts +30 -0
- package/lib/src/deno-bundle.js +146 -0
- package/lib/src/deno-bundle.js.map +1 -0
- package/lib/src/errors.d.ts +16 -0
- package/lib/src/errors.js +11 -0
- package/lib/src/errors.js.map +1 -0
- package/lib/src/esbuild/deno-resolver.d.ts +26 -0
- package/lib/src/esbuild/deno-resolver.js +436 -0
- package/lib/src/esbuild/deno-resolver.js.map +1 -0
- package/lib/src/esbuild/node-builtin-require.d.ts +2 -0
- package/lib/src/esbuild/node-builtin-require.js +33 -0
- package/lib/src/esbuild/node-builtin-require.js.map +1 -0
- package/lib/src/esbuild/private-data-sources-virtual.d.ts +3 -0
- package/lib/src/esbuild/private-data-sources-virtual.js +127 -0
- package/lib/src/esbuild/private-data-sources-virtual.js.map +1 -0
- package/lib/src/esbuild/runtime-context-virtual.d.ts +3 -0
- package/lib/src/esbuild/runtime-context-virtual.js +42 -0
- package/lib/src/esbuild/runtime-context-virtual.js.map +1 -0
- package/lib/src/esbuild/runtime-virtual.d.ts +2 -0
- package/lib/src/esbuild/runtime-virtual.js +52 -0
- package/lib/src/esbuild/runtime-virtual.js.map +1 -0
- package/lib/src/esbuild/user-files.d.ts +15 -0
- package/lib/src/esbuild/user-files.js +73 -0
- package/lib/src/esbuild/user-files.js.map +1 -0
- package/lib/src/fetch-guard.d.ts +26 -0
- package/lib/src/fetch-guard.js +67 -0
- package/lib/src/fetch-guard.js.map +1 -0
- package/lib/src/index.d.ts +12 -0
- package/lib/src/index.js +11 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/log.d.ts +7 -0
- package/lib/src/log.js +39 -0
- package/lib/src/log.js.map +1 -0
- package/lib/src/private-data-sources/build-http.ts +51 -0
- package/lib/src/private-data-sources/elasticsearch.ts +8 -0
- package/lib/src/private-data-sources/http-url.ts +23 -0
- package/lib/src/private-data-sources/http.ts +6 -0
- package/lib/src/private-data-sources/hyperdrive.ts +48 -0
- package/lib/src/private-data-sources/ioredis-adapter.ts +229 -0
- package/lib/src/private-data-sources/manifest.ts +150 -0
- package/lib/src/private-data-sources/mariadb.ts +8 -0
- package/lib/src/private-data-sources/mongodb.ts +70 -0
- package/lib/src/private-data-sources/mysql.ts +8 -0
- package/lib/src/private-data-sources/node-net-adapter.ts +244 -0
- package/lib/src/private-data-sources/postgres.ts +8 -0
- package/lib/src/private-data-sources/redis-auth.ts +83 -0
- package/lib/src/private-data-sources/redis.ts +47 -0
- package/lib/src/private-data-sources/runtime-environment.ts +4 -0
- package/lib/src/private-data-sources/runtime-manifest-store.ts +32 -0
- package/lib/src/private-data-sources/sqlserver.ts +22 -0
- package/lib/src/private-data-sources/tcp.ts +86 -0
- package/lib/src/private-data-sources/tedious-adapter.ts +67 -0
- package/lib/src/private-data-sources/types.ts +29 -0
- package/lib/src/runtime/index.ts +30 -0
- package/lib/src/runtime-context.ts +29 -0
- package/lib/src/static-egress-marker.d.ts +1 -0
- package/lib/src/static-egress-marker.js +7 -0
- package/lib/src/static-egress-marker.js.map +1 -0
- package/lib/src/telemetry.d.ts +32 -0
- package/lib/src/telemetry.js +84 -0
- package/lib/src/telemetry.js.map +1 -0
- package/lib/src/tracing.d.ts +9 -0
- package/lib/src/tracing.js +21 -0
- package/lib/src/tracing.js.map +1 -0
- package/lib/src/worker-entry.d.ts +36 -0
- package/lib/src/worker-entry.js +320 -0
- package/lib/src/worker-entry.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Leaf module: no imports, so the server graph never reaches worker-only code.
|
|
2
|
+
// `static-egress.ts` imports the runtime-context virtual specifier, which only
|
|
3
|
+
// esbuild (or the vitest alias) can resolve — importing it from a server module
|
|
4
|
+
// crashes Node at startup with ERR_UNSUPPORTED_ESM_URL_SCHEME.
|
|
5
|
+
// Keep in sync with STATIC_EGRESS_ARTIFACT_MARKER in backend/app/static_egress/config.py.
|
|
6
|
+
export const STATIC_EGRESS_ARTIFACT_MARKER = "base44.static-egress.request-env.v2";
|
|
7
|
+
//# sourceMappingURL=static-egress-marker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-egress-marker.js","sourceRoot":"","sources":["../../src/static-egress-marker.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,gFAAgF;AAChF,+DAA+D;AAC/D,0FAA0F;AAC1F,MAAM,CAAC,MAAM,6BAA6B,GACxC,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-response detached-work telemetry for generated Worker entries — a
|
|
3
|
+
* usage gauge for fetches that outlive the handler's Response
|
|
4
|
+
* (docs/features/post-response-telemetry.md). workerd cancels such fetches
|
|
5
|
+
* (Deno Deploy tolerated them), so the Deno→CFW migration breaks apps that
|
|
6
|
+
* rely on the pattern.
|
|
7
|
+
*
|
|
8
|
+
* When the bundle request carries `postResponseTelemetry: true` (backend
|
|
9
|
+
* evaluates the app-keyed `post-response-telemetry` flag at deploy time),
|
|
10
|
+
* the entry templates append this prelude and route the handler's response
|
|
11
|
+
* through `_b44AttachTelemetry`. Flag off appends nothing — the generated
|
|
12
|
+
* entry stays byte-identical to the pre-telemetry prod baseline.
|
|
13
|
+
*
|
|
14
|
+
* A request that returns with fetches pending logs one `inflight_at_response`
|
|
15
|
+
* line (through the console patch, so it carries function attribution) naming
|
|
16
|
+
* the target origins (refcounted, cap 10) and mirrors it onto the
|
|
17
|
+
* `X-B44-Post-Response-Telemetry` response header; the platform proxy relays
|
|
18
|
+
* that to Datadog and strips it before the client. Every observed fetch also
|
|
19
|
+
* rides ctx.waitUntil platform-side, so pending fetches complete (bounded by
|
|
20
|
+
* the waitUntil budget) instead of being cancelled, keeping the detached
|
|
21
|
+
* chain alive — its follow-up fetches log `fetch_started_post_response`
|
|
22
|
+
* without user code ever calling Base44.waitUntil. Clean traffic emits
|
|
23
|
+
* nothing and carries no header.
|
|
24
|
+
*
|
|
25
|
+
* Must be self-contained JS (no imports) — inlined into the generated entry
|
|
26
|
+
* after CONSOLE_PATCH. The entry provides `_b44Context` and the patched console.
|
|
27
|
+
*/
|
|
28
|
+
export declare const TELEMETRY_PATCH: string;
|
|
29
|
+
/** Request-store fields the flag-ON entry seeds. Flag-OFF entries omit them
|
|
30
|
+
* and every telemetry call site — control must stay byte-identical to the
|
|
31
|
+
* pre-telemetry prod entry. */
|
|
32
|
+
export declare const TELEMETRY_STORE_FIELDS = "reqId: crypto.randomUUID(), respondedAt: null, inflight: new Map(), inflightTotal: 0, hadRejection: false, hadNonOk: false, logBudget: 5";
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-response detached-work telemetry for generated Worker entries — a
|
|
3
|
+
* usage gauge for fetches that outlive the handler's Response
|
|
4
|
+
* (docs/features/post-response-telemetry.md). workerd cancels such fetches
|
|
5
|
+
* (Deno Deploy tolerated them), so the Deno→CFW migration breaks apps that
|
|
6
|
+
* rely on the pattern.
|
|
7
|
+
*
|
|
8
|
+
* When the bundle request carries `postResponseTelemetry: true` (backend
|
|
9
|
+
* evaluates the app-keyed `post-response-telemetry` flag at deploy time),
|
|
10
|
+
* the entry templates append this prelude and route the handler's response
|
|
11
|
+
* through `_b44AttachTelemetry`. Flag off appends nothing — the generated
|
|
12
|
+
* entry stays byte-identical to the pre-telemetry prod baseline.
|
|
13
|
+
*
|
|
14
|
+
* A request that returns with fetches pending logs one `inflight_at_response`
|
|
15
|
+
* line (through the console patch, so it carries function attribution) naming
|
|
16
|
+
* the target origins (refcounted, cap 10) and mirrors it onto the
|
|
17
|
+
* `X-B44-Post-Response-Telemetry` response header; the platform proxy relays
|
|
18
|
+
* that to Datadog and strips it before the client. Every observed fetch also
|
|
19
|
+
* rides ctx.waitUntil platform-side, so pending fetches complete (bounded by
|
|
20
|
+
* the waitUntil budget) instead of being cancelled, keeping the detached
|
|
21
|
+
* chain alive — its follow-up fetches log `fetch_started_post_response`
|
|
22
|
+
* without user code ever calling Base44.waitUntil. Clean traffic emits
|
|
23
|
+
* nothing and carries no header.
|
|
24
|
+
*
|
|
25
|
+
* Must be self-contained JS (no imports) — inlined into the generated entry
|
|
26
|
+
* after CONSOLE_PATCH. The entry provides `_b44Context` and the patched console.
|
|
27
|
+
*/
|
|
28
|
+
export const TELEMETRY_PATCH = [
|
|
29
|
+
"const _b44Tele = (c, event, fields) => {",
|
|
30
|
+
" if (!(c.logBudget > 0)) return;",
|
|
31
|
+
" c.logBudget -= 1;",
|
|
32
|
+
" try { console.log(JSON.stringify({ b44_telemetry: 'post_response_work', event, request_id: c.reqId, ...fields })); } catch (e) {}",
|
|
33
|
+
"};",
|
|
34
|
+
// origin only — both query strings and paths can carry secrets (Slack
|
|
35
|
+
// webhook URLs, Telegram bot tokens); the census only needs the host.
|
|
36
|
+
"const _b44Target = (input) => { try { const u = typeof input === 'string' ? new URL(input) : (input instanceof URL ? input : new URL(input.url)); return u.origin; } catch (e) { return 'unknown'; } };",
|
|
37
|
+
"const _b44OrigFetch = globalThis.fetch.bind(globalThis);",
|
|
38
|
+
"globalThis.fetch = (input, init) => {",
|
|
39
|
+
" const c = _b44Context();",
|
|
40
|
+
" if (!c || c.respondedAt === undefined) return _b44OrigFetch(input, init);",
|
|
41
|
+
" const t = _b44Target(input);",
|
|
42
|
+
" if (c.respondedAt !== null) _b44Tele(c, 'fetch_started_post_response', { target: t, ms_after_response: Date.now() - c.respondedAt });",
|
|
43
|
+
// Refcounted (cap 10 distinct): same-target siblings must not lose the
|
|
44
|
+
// target when the first settles.
|
|
45
|
+
" const tracked = c.inflight.has(t) || c.inflight.size < 10;",
|
|
46
|
+
" if (tracked) c.inflight.set(t, (c.inflight.get(t) ?? 0) + 1);",
|
|
47
|
+
" c.inflightTotal += 1;",
|
|
48
|
+
" const done = () => { c.inflightTotal -= 1; if (tracked) { const n = c.inflight.get(t); if (n !== undefined) { if (n <= 1) c.inflight.delete(t); else c.inflight.set(t, n - 1); } } };",
|
|
49
|
+
// Ride ctx.waitUntil on every observed fetch (platform-side — user code
|
|
50
|
+
// needs no Base44.waitUntil): workerd then keeps the request context alive
|
|
51
|
+
// until the fetch settles, so a fetch pending at response completes instead
|
|
52
|
+
// of being cancelled, and follow-up fetches in the detached chain run and
|
|
53
|
+
// get logged. Bounded by Cloudflare's waitUntil budget; a no-op for fetches
|
|
54
|
+
// that settle in-request.
|
|
55
|
+
// Fail-fast discriminators: a pre-response rejection, or a pre-response
|
|
56
|
+
// non-ok resolution (an SDK/helper throws on !res.ok and the rejection
|
|
57
|
+
// fail-fasts Promise.all), marks the request as likely orphaning fallout
|
|
58
|
+
// rather than deliberate fire-and-forget — which has neither.
|
|
59
|
+
" const failed = () => { if (c.respondedAt === null) c.hadRejection = true; done(); };",
|
|
60
|
+
" const settled = (res) => { if (c.respondedAt === null && res && res.ok === false) c.hadNonOk = true; done(); };",
|
|
61
|
+
" try { const p = _b44OrigFetch(input, init); p.then(settled, failed); if (c.waitUntil) { try { c.waitUntil(p.then(() => {}, () => {})); } catch (e) {} } return p; } catch (e) { failed(); throw e; }",
|
|
62
|
+
"};",
|
|
63
|
+
"const _b44AttachTelemetry = (res) => {",
|
|
64
|
+
" const c = _b44Context();",
|
|
65
|
+
" if (!c || c.respondedAt === undefined) return res;",
|
|
66
|
+
" c.respondedAt = Date.now();",
|
|
67
|
+
// Upgrade responses can't be reconstructed; a live socket's fetches
|
|
68
|
+
// aren't post-response work anyway.
|
|
69
|
+
" if (c.inflightTotal <= 0 || res.status === 101 || res.webSocket) return res;",
|
|
70
|
+
" const pending = { request_id: c.reqId, inflight: c.inflightTotal, targets: [...c.inflight.keys()], rejected_pre_response: c.hadRejection, non_ok_pre_response: c.hadNonOk };",
|
|
71
|
+
" _b44Tele(c, 'inflight_at_response', pending);",
|
|
72
|
+
// Once the wrap exists the original body stream is transferred — always
|
|
73
|
+
// return the wrap then; fall back to res only if construction itself threw.
|
|
74
|
+
" let wrapped;",
|
|
75
|
+
" try { wrapped = new Response(res.body, res); } catch (e) { return res; }",
|
|
76
|
+
" try { wrapped.headers.set('X-B44-Post-Response-Telemetry', JSON.stringify({ pending })); } catch (e) {}",
|
|
77
|
+
" return wrapped;",
|
|
78
|
+
"};",
|
|
79
|
+
].join("\n");
|
|
80
|
+
/** Request-store fields the flag-ON entry seeds. Flag-OFF entries omit them
|
|
81
|
+
* and every telemetry call site — control must stay byte-identical to the
|
|
82
|
+
* pre-telemetry prod entry. */
|
|
83
|
+
export const TELEMETRY_STORE_FIELDS = "reqId: crypto.randomUUID(), respondedAt: null, inflight: new Map(), inflightTotal: 0, hadRejection: false, hadNonOk: false, logBudget: 5";
|
|
84
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,0CAA0C;IAC1C,mCAAmC;IACnC,qBAAqB;IACrB,qIAAqI;IACrI,IAAI;IACJ,sEAAsE;IACtE,sEAAsE;IACtE,yMAAyM;IACzM,0DAA0D;IAC1D,uCAAuC;IACvC,4BAA4B;IAC5B,6EAA6E;IAC7E,gCAAgC;IAChC,yIAAyI;IACzI,uEAAuE;IACvE,iCAAiC;IACjC,8DAA8D;IAC9D,iEAAiE;IACjE,yBAAyB;IACzB,yLAAyL;IACzL,wEAAwE;IACxE,2EAA2E;IAC3E,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,0BAA0B;IAC1B,wEAAwE;IACxE,uEAAuE;IACvE,yEAAyE;IACzE,8DAA8D;IAC9D,wFAAwF;IACxF,mHAAmH;IACnH,wMAAwM;IACxM,IAAI;IACJ,wCAAwC;IACxC,4BAA4B;IAC5B,sDAAsD;IACtD,+BAA+B;IAC/B,oEAAoE;IACpE,oCAAoC;IACpC,gFAAgF;IAChF,gLAAgL;IAChL,iDAAiD;IACjD,wEAAwE;IACxE,4EAA4E;IAC5E,gBAAgB;IAChB,4EAA4E;IAC5E,2GAA2G;IAC3G,mBAAmB;IACnB,IAAI;CACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;gCAEgC;AAChC,MAAM,CAAC,MAAM,sBAAsB,GACjC,0IAA0I,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface CompilerTracer {
|
|
2
|
+
withSpan<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
|
3
|
+
setSpanTags(tags: Record<string, string | number | undefined>): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
/** Register the host's tracer; `null` restores the no-op. Must be called in the
|
|
6
|
+
* same thread that runs the compile — spans are process-local. */
|
|
7
|
+
export declare function setCompilerTracer(next: CompilerTracer | null): void;
|
|
8
|
+
export declare function withSpan<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
|
9
|
+
export declare function setSpanTags(tags: Record<string, string | number | undefined>): Promise<void>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// The compiler emits spans through whatever tracer the host registers. Apper's
|
|
2
|
+
// bundler service registers its dd-trace adapter at worker startup; a CLI-local
|
|
3
|
+
// build leaves the no-op in place. Keeps dd-trace and its initialization out of
|
|
4
|
+
// the compiler's own dependencies.
|
|
5
|
+
const noopTracer = {
|
|
6
|
+
withSpan: (_name, fn) => fn(),
|
|
7
|
+
setSpanTags: async () => { },
|
|
8
|
+
};
|
|
9
|
+
let tracer = noopTracer;
|
|
10
|
+
/** Register the host's tracer; `null` restores the no-op. Must be called in the
|
|
11
|
+
* same thread that runs the compile — spans are process-local. */
|
|
12
|
+
export function setCompilerTracer(next) {
|
|
13
|
+
tracer = next ?? noopTracer;
|
|
14
|
+
}
|
|
15
|
+
export function withSpan(name, fn) {
|
|
16
|
+
return tracer.withSpan(name, fn);
|
|
17
|
+
}
|
|
18
|
+
export function setSpanTags(tags) {
|
|
19
|
+
return tracer.setSpanTags(tags);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=tracing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.js","sourceRoot":"","sources":["../../src/tracing.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,gFAAgF;AAChF,mCAAmC;AAOnC,MAAM,UAAU,GAAmB;IACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;IAC7B,WAAW,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;CAC5B,CAAC;AAEF,IAAI,MAAM,GAAmB,UAAU,CAAC;AAExC;mEACmE;AACnE,MAAM,UAAU,iBAAiB,CAAC,IAA2B;IAC3D,MAAM,GAAG,IAAI,IAAI,UAAU,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAI,IAAY,EAAE,EAAoB;IAC5D,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,IAAiD;IAEjD,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assembles user functions into the input the bundler compiles: the user
|
|
3
|
+
* sources (passed through verbatim — the Deno resolver understands their
|
|
4
|
+
* `npm:`/`jsr:`/`https:` specifiers) plus an injected shim and a generated
|
|
5
|
+
* Worker entry. This is the layer that understands "functions" and "an app".
|
|
6
|
+
*/
|
|
7
|
+
import type { AppFunctionInput } from "./contracts.js";
|
|
8
|
+
export declare const SHIM_FILENAME = "__base44_deno_shim.mjs";
|
|
9
|
+
export declare const ACTIVATION_FILENAME = "__base44_activation.mjs";
|
|
10
|
+
export interface PreparedWorker {
|
|
11
|
+
entry: string;
|
|
12
|
+
files: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export declare function workerRuntimeFiles(): Record<string, string>;
|
|
15
|
+
/** Shared console-patching prelude injected into every generated Worker entry.
|
|
16
|
+
* Exported so tests can build minimal bundles with the same patch applied. */
|
|
17
|
+
export declare const CONSOLE_PATCH: string;
|
|
18
|
+
/** Assemble a single Deno function into a bundle-ready Worker. */
|
|
19
|
+
export declare function prepareFunction(entry: string, files: Record<string, string>, postResponseTelemetry?: boolean, runtimeSecrets?: boolean): Promise<PreparedWorker>;
|
|
20
|
+
/** One app function paired with the stable key its files and diagnostics are
|
|
21
|
+
* namespaced under (`fn_<index>`). The index is the function's original
|
|
22
|
+
* position so attribution stays correct across an exclude-and-rebuild. */
|
|
23
|
+
export interface AppFunctionEntry {
|
|
24
|
+
index: number;
|
|
25
|
+
fn: AppFunctionInput;
|
|
26
|
+
}
|
|
27
|
+
/** Assemble the whole app into ONE bundle-ready Worker: every function's files
|
|
28
|
+
* namespaced under `fn_<index>/`, one shared shim, and a router that routes by
|
|
29
|
+
* function name. A single compile resolves and DEDUPES npm deps across all
|
|
30
|
+
* functions (vs one inlined copy per chunk) — but esbuild fails the whole build
|
|
31
|
+
* on any unresolved import, so the caller excludes the offending functions
|
|
32
|
+
* (identified by their `fn_<index>/` path) and rebuilds the survivors. Each
|
|
33
|
+
* function is sealed to its own `fn_<index>/` keyspace, so one can't import
|
|
34
|
+
* another's files. */
|
|
35
|
+
export declare function prepareApp(entries: AppFunctionEntry[], postResponseTelemetry?: boolean, runtimeSecrets?: boolean): PreparedWorker;
|
|
36
|
+
export declare function assertNoReservedFilenames(files: Record<string, string>): void;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assembles user functions into the input the bundler compiles: the user
|
|
3
|
+
* sources (passed through verbatim — the Deno resolver understands their
|
|
4
|
+
* `npm:`/`jsr:`/`https:` specifiers) plus an injected shim and a generated
|
|
5
|
+
* Worker entry. This is the layer that understands "functions" and "an app".
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { DenoCompatError } from "./errors.js";
|
|
9
|
+
import { RUNTIME_CONTEXT_SPECIFIER } from "./esbuild/runtime-context-virtual.js";
|
|
10
|
+
import { TELEMETRY_PATCH, TELEMETRY_STORE_FIELDS } from "./telemetry.js";
|
|
11
|
+
// Pre-built by scripts/build-shim.ts; regenerate it after changing the shim.
|
|
12
|
+
// Read LAZILY, not at module load: build-shim.ts transitively imports this
|
|
13
|
+
// module through the esbuild plugins, and on a fresh checkout dist/ doesn't
|
|
14
|
+
// exist yet — a load-time read would crash the very script that produces these
|
|
15
|
+
// files (and only pass locally where dist/ already exists).
|
|
16
|
+
let _denoShimSource;
|
|
17
|
+
function denoShimSource() {
|
|
18
|
+
_denoShimSource ??= readFileSync(new URL("../dist/deno-shim.mjs", import.meta.url), "utf8");
|
|
19
|
+
return _denoShimSource;
|
|
20
|
+
}
|
|
21
|
+
let _activationShimSource;
|
|
22
|
+
function activationShimSource() {
|
|
23
|
+
_activationShimSource ??= readFileSync(new URL("../dist/activation-shim.mjs", import.meta.url), "utf8");
|
|
24
|
+
return _activationShimSource;
|
|
25
|
+
}
|
|
26
|
+
// Synthetic files injected into the bundle; asserted absent from user input.
|
|
27
|
+
export const SHIM_FILENAME = "__base44_deno_shim.mjs";
|
|
28
|
+
const ENTRY_FILENAME = "__base44_entry.mjs";
|
|
29
|
+
// Injected only for runtime-secrets bundles — old-mode output stays byte-identical.
|
|
30
|
+
export const ACTIVATION_FILENAME = "__base44_activation.mjs";
|
|
31
|
+
// Actor shim filename is also reserved (handled by actor-compat.ts).
|
|
32
|
+
const ACTOR_ENTRY_FILENAME = "__base44_actor_entry.mjs";
|
|
33
|
+
export function workerRuntimeFiles() {
|
|
34
|
+
return { [SHIM_FILENAME]: denoShimSource() };
|
|
35
|
+
}
|
|
36
|
+
/** Shared console-patching prelude injected into every generated Worker entry.
|
|
37
|
+
* Exported so tests can build minimal bundles with the same patch applied. */
|
|
38
|
+
// Runs at module scope before any user code so module-level logs are captured.
|
|
39
|
+
// Generated entries import `_b44Context` from the private runtime module.
|
|
40
|
+
export const CONSOLE_PATCH = [
|
|
41
|
+
"const _b44Orig = console.log;",
|
|
42
|
+
"const _b44S = x => { if (x instanceof Error) return x.stack || x.message; try { return typeof x === 'string' ? x : (JSON.stringify(x) ?? String(x)); } catch (e) { return String(x); } };",
|
|
43
|
+
"const _b44Fmt = (a) => {",
|
|
44
|
+
" if (typeof a[0] !== 'string' || !a[0].includes('%')) return a.map(_b44S).join(' ');",
|
|
45
|
+
" let i = 1;",
|
|
46
|
+
" const s = a[0].replace(/%([sdifoOc])/g, (_, t) => {",
|
|
47
|
+
" if (i >= a.length) return '%' + t;",
|
|
48
|
+
" const v = a[i++];",
|
|
49
|
+
" if (t === 'd' || t === 'i') { try { return String(Math.trunc(+v)); } catch(_) { return _b44S(v); } }",
|
|
50
|
+
" if (t === 'f') { try { return String(+v); } catch(_) { return _b44S(v); } }",
|
|
51
|
+
" if (t === 'c') return '';",
|
|
52
|
+
" return _b44S(v);",
|
|
53
|
+
" });",
|
|
54
|
+
" const tail = a.slice(i).map(_b44S).join(' ');",
|
|
55
|
+
" return tail ? s + ' ' + tail : s;",
|
|
56
|
+
"};",
|
|
57
|
+
// The store holds { env, fn, secrets, workerEnv, waitUntil }; fn is set only
|
|
58
|
+
// by per-app bundles, where one script serves every function and log queries
|
|
59
|
+
// need per-function attribution. `secrets` and `workerEnv` reference the
|
|
60
|
+
// request's authoritative Worker env binding.
|
|
61
|
+
"const _b44Wrap = (lvl, a) => { const _c = _b44Context() ?? {}; _b44Orig({ _b44_env: _c.env ?? 'preview', ...(_c.fn ? { _b44_function: _c.fn } : {}), level: lvl, message: _b44Fmt(a) }); };",
|
|
62
|
+
"console.log = (...a) => _b44Wrap('info', a);",
|
|
63
|
+
"console.info = (...a) => _b44Wrap('info', a);",
|
|
64
|
+
"console.warn = (...a) => _b44Wrap('warn', a);",
|
|
65
|
+
"console.error = (...a) => _b44Wrap('error', a);",
|
|
66
|
+
"console.debug = (...a) => _b44Wrap('debug', a);",
|
|
67
|
+
// Request-scoped background-work hook. Cloudflare cancels promises left
|
|
68
|
+
// pending after the response unless they ride ctx.waitUntil, and user code
|
|
69
|
+
// has no other path to ctx — expose it via the same store as env/fn so
|
|
70
|
+
// functions can ack fast and finish work reliably afterwards. The global
|
|
71
|
+
// reads the store per call, so concurrent requests get their own ctx.
|
|
72
|
+
// `secrets` reads the request's Worker env binding the same way. Two filters:
|
|
73
|
+
// - reserved platform keys (the private-data-sources manifest, which carries
|
|
74
|
+
// plaintext VPC DB credentials) are denied — user code reaches data sources
|
|
75
|
+
// via the base44:private-data-sources/* imports, never the raw manifest;
|
|
76
|
+
// - only string values are returned, so non-secret bindings (Hyperdrive
|
|
77
|
+
// objects, etc.) stay hidden.
|
|
78
|
+
// This global is the internal bridge behind the "base44:runtime" virtual
|
|
79
|
+
// module (src/runtime/index.ts) — keep the two shapes in sync (the actor
|
|
80
|
+
// shim installs the same bridge from the DO env: src/shim/actor.ts).
|
|
81
|
+
"const _b44ReservedSecrets = new Set(['BASE44_ACTOR_PRIVATE_KEY', 'BASE44_ACTOR_PUBLIC_KEY', 'BASE44_ACTOR_SCRIPT_ID', 'BASE44_PRIVATE_DATA_SOURCES']);",
|
|
82
|
+
// Coerce to a primitive string BEFORE the reserved-key check: a boxed
|
|
83
|
+
// `new String('BASE44_PRIVATE_DATA_SOURCES')` fails Set.has (object identity)
|
|
84
|
+
// but would coerce back to the reserved key on the `env[...]` lookup, leaking
|
|
85
|
+
// the manifest. `String(n)` normalizes both the check and the lookup.
|
|
86
|
+
"globalThis.Base44 = Object.assign(globalThis.Base44 ?? {}, { waitUntil: (p) => { const _c = _b44Context(); if (_c?.waitUntil) { _c.waitUntil(p); } else { Promise.resolve(p).catch(() => {}); } }, secrets: { get: (n) => { const _k = String(n); if (_b44ReservedSecrets.has(_k)) return undefined; const _v = _b44Context()?.secrets?.[_k]; return typeof _v === 'string' ? _v : undefined; } } });",
|
|
87
|
+
// Supabase-compat alias so copy-pasted EdgeRuntime.waitUntil code works.
|
|
88
|
+
"globalThis.EdgeRuntime = globalThis.EdgeRuntime ?? { waitUntil: (p) => globalThis.Base44.waitUntil(p) };",
|
|
89
|
+
].join("\n");
|
|
90
|
+
/** Assemble a single Deno function into a bundle-ready Worker. */
|
|
91
|
+
export async function prepareFunction(entry, files, postResponseTelemetry = false, runtimeSecrets = false) {
|
|
92
|
+
assertNoReservedFilenames(files);
|
|
93
|
+
return {
|
|
94
|
+
entry: ENTRY_FILENAME,
|
|
95
|
+
files: {
|
|
96
|
+
...userFiles(files),
|
|
97
|
+
...workerRuntimeFiles(),
|
|
98
|
+
...(runtimeSecrets
|
|
99
|
+
? { [ACTIVATION_FILENAME]: activationShimSource() }
|
|
100
|
+
: {}),
|
|
101
|
+
[ENTRY_FILENAME]: buildEntrySource(entry, postResponseTelemetry, runtimeSecrets),
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/** Assemble the whole app into ONE bundle-ready Worker: every function's files
|
|
106
|
+
* namespaced under `fn_<index>/`, one shared shim, and a router that routes by
|
|
107
|
+
* function name. A single compile resolves and DEDUPES npm deps across all
|
|
108
|
+
* functions (vs one inlined copy per chunk) — but esbuild fails the whole build
|
|
109
|
+
* on any unresolved import, so the caller excludes the offending functions
|
|
110
|
+
* (identified by their `fn_<index>/` path) and rebuilds the survivors. Each
|
|
111
|
+
* function is sealed to its own `fn_<index>/` keyspace, so one can't import
|
|
112
|
+
* another's files. */
|
|
113
|
+
export function prepareApp(entries, postResponseTelemetry = false, runtimeSecrets = false) {
|
|
114
|
+
const files = {
|
|
115
|
+
...workerRuntimeFiles(),
|
|
116
|
+
...(runtimeSecrets
|
|
117
|
+
? { [ACTIVATION_FILENAME]: activationShimSource() }
|
|
118
|
+
: {}),
|
|
119
|
+
};
|
|
120
|
+
const moduleFiles = entries.map(({ index, fn }) => {
|
|
121
|
+
assertNoReservedFilenames(fn.files);
|
|
122
|
+
const dir = `fn_${index}`;
|
|
123
|
+
for (const [filePath, content] of Object.entries(userFiles(fn.files))) {
|
|
124
|
+
files[`${dir}/${filePath}`] = content;
|
|
125
|
+
}
|
|
126
|
+
const wrapper = `__base44_fn_${index}.mjs`;
|
|
127
|
+
files[wrapper] = buildFunctionModuleSource(fn.name, `${dir}/${fn.entry}`);
|
|
128
|
+
return wrapper;
|
|
129
|
+
});
|
|
130
|
+
files[ENTRY_FILENAME] = buildAppEntrySource(moduleFiles, postResponseTelemetry, runtimeSecrets);
|
|
131
|
+
return { entry: ENTRY_FILENAME, files };
|
|
132
|
+
}
|
|
133
|
+
// Activation prelude for runtime-secrets bundles: gate on the encrypted
|
|
134
|
+
// handshake BEFORE any user module is imported (so a needs-activation response
|
|
135
|
+
// implies no user side effect ran), then strip the envelope from the request.
|
|
136
|
+
const ACTIVATION_GATE = ` const _b44Activation = await ensureActivation(request, env);
|
|
137
|
+
if (_b44Activation) return _b44Activation;
|
|
138
|
+
request = withoutRuntimeSecretsHeader(request);
|
|
139
|
+
`;
|
|
140
|
+
function activationImport(runtimeSecrets) {
|
|
141
|
+
return runtimeSecrets
|
|
142
|
+
? `\nimport { ensureActivation, withoutActivationSignal, withoutRuntimeSecretsHeader } from "./${ACTIVATION_FILENAME}";`
|
|
143
|
+
: "";
|
|
144
|
+
}
|
|
145
|
+
/** Build the wrapper entry that loads the shim, lazily imports the user module
|
|
146
|
+
* on the first request (so init logs are tagged with the real request env),
|
|
147
|
+
* then exports a standard Worker fetch that delegates to that handler. */
|
|
148
|
+
function buildEntrySource(userEntry, telemetry, runtimeSecrets = false) {
|
|
149
|
+
const userImport = `./${userEntry.replace(/^\.\//, "")}`;
|
|
150
|
+
// Handler responses get the activation-signal header stripped (user code must
|
|
151
|
+
// not be able to forge a signal after side effects and cause a re-execution).
|
|
152
|
+
const handlerExpr = telemetry
|
|
153
|
+
? "_b44AttachTelemetry(await handler(request, info))"
|
|
154
|
+
: runtimeSecrets
|
|
155
|
+
? "await handler(request, info)"
|
|
156
|
+
: "handler(request, info)";
|
|
157
|
+
const returnExpr = runtimeSecrets
|
|
158
|
+
? `withoutActivationSignal(${handlerExpr})`
|
|
159
|
+
: handlerExpr;
|
|
160
|
+
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
161
|
+
|
|
162
|
+
import { currentWorkerRuntimeContext as _b44Context, runWithWorkerEnvironment as _b44Run } from ${JSON.stringify(RUNTIME_CONTEXT_SPECIFIER)};
|
|
163
|
+
import { getRegisteredHandler, installStaticEgressFetch } from "./${SHIM_FILENAME}";${activationImport(runtimeSecrets)}
|
|
164
|
+
|
|
165
|
+
${CONSOLE_PATCH}
|
|
166
|
+
// Static egress reads workerEnv from the active request store. Install it
|
|
167
|
+
// before telemetry so telemetry remains the outermost fetch wrapper.
|
|
168
|
+
installStaticEgressFetch();
|
|
169
|
+
${telemetry ? TELEMETRY_PATCH : ""}
|
|
170
|
+
|
|
171
|
+
let _b44Init = null;
|
|
172
|
+
export default {
|
|
173
|
+
async fetch(request, env, ctx) {
|
|
174
|
+
const _b44Env = (request.headers.get('base44-functions-version') ?? '') === 'prod' ? 'prod' : 'preview';
|
|
175
|
+
return _b44Run({ env: _b44Env, secrets: ${runtimeSecrets ? "process.env" : "env"}, workerEnv: env, waitUntil: (p) => ctx.waitUntil(p)${telemetry ? `, ${TELEMETRY_STORE_FIELDS}` : ""} }, async () => {
|
|
176
|
+
${runtimeSecrets ? ACTIVATION_GATE : ""} if (!_b44Init) _b44Init = import(${JSON.stringify(userImport)}).catch(e => { _b44Init = null; throw e; });
|
|
177
|
+
const _b44Mod = await _b44Init;
|
|
178
|
+
// Deno.serve capture wins (legacy contract, zero behavior change);
|
|
179
|
+
// a default-exported handler is the new-contract fallback.
|
|
180
|
+
const handler = getRegisteredHandler() ?? (typeof _b44Mod?.default === 'function' ? _b44Mod.default : null);
|
|
181
|
+
if (!handler) {
|
|
182
|
+
return new Response(
|
|
183
|
+
"The function must export default a request handler or call Deno.serve()",
|
|
184
|
+
{ status: 503 },
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
// Deno's handler signature is (request, info). Cloudflare doesn't expose a
|
|
188
|
+
// connection address the same way; pass a best-effort placeholder. Real
|
|
189
|
+
// client IP is available via the "cf-connecting-ip" request header.
|
|
190
|
+
const info = {
|
|
191
|
+
remoteAddr: { transport: "tcp", hostname: "0.0.0.0", port: 0 },
|
|
192
|
+
};
|
|
193
|
+
return ${returnExpr};
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
function buildFunctionModuleSource(functionName, userEntry) {
|
|
200
|
+
const userImport = `./${userEntry.replace(/^\.\//, "")}`;
|
|
201
|
+
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
202
|
+
import { registerLazy } from "./${SHIM_FILENAME}";
|
|
203
|
+
|
|
204
|
+
registerLazy(${JSON.stringify(functionName)}, () => import(${JSON.stringify(userImport)}));
|
|
205
|
+
`;
|
|
206
|
+
}
|
|
207
|
+
function buildAppEntrySource(functionModules, telemetry, runtimeSecrets = false) {
|
|
208
|
+
const moduleImports = functionModules
|
|
209
|
+
.map((file) => `import "./${file}";`)
|
|
210
|
+
.join("\n");
|
|
211
|
+
const handlerExpr = telemetry
|
|
212
|
+
? "_b44AttachTelemetry(await handler(request, info))"
|
|
213
|
+
: "await handler(request, info)";
|
|
214
|
+
const returnExpr = runtimeSecrets
|
|
215
|
+
? `withoutActivationSignal(${handlerExpr})`
|
|
216
|
+
: handlerExpr;
|
|
217
|
+
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
218
|
+
|
|
219
|
+
import { currentWorkerRuntimeContext as _b44Context, runWithWorkerEnvironment as _b44Run } from ${JSON.stringify(RUNTIME_CONTEXT_SPECIFIER)};
|
|
220
|
+
import { installStaticEgressFetch, resolveHandler } from "./${SHIM_FILENAME}";${activationImport(runtimeSecrets)}
|
|
221
|
+
${moduleImports}
|
|
222
|
+
|
|
223
|
+
${CONSOLE_PATCH}
|
|
224
|
+
// Static egress reads workerEnv from the active request store. Install it
|
|
225
|
+
// before telemetry so telemetry remains the outermost fetch wrapper.
|
|
226
|
+
installStaticEgressFetch();
|
|
227
|
+
${telemetry ? TELEMETRY_PATCH : ""}
|
|
228
|
+
|
|
229
|
+
export default {
|
|
230
|
+
async fetch(request, env, ctx) {
|
|
231
|
+
const _b44Env = (request.headers.get('base44-functions-version') ?? '') === 'prod' ? 'prod' : 'preview';
|
|
232
|
+
const functionName = request.headers.get("Base44-Function-Name");
|
|
233
|
+
return _b44Run({ env: _b44Env, fn: functionName ?? '', secrets: ${runtimeSecrets ? "process.env" : "env"}, workerEnv: env, waitUntil: (p) => ctx.waitUntil(p)${telemetry ? `, ${TELEMETRY_STORE_FIELDS}` : ""} }, async () => {
|
|
234
|
+
${runtimeSecrets ? ACTIVATION_GATE : ""} // Each early return below logs through the patch first: per-function log
|
|
235
|
+
// queries on per-app scripts keep only stamped lines, so a bare return
|
|
236
|
+
// would leave the failing invocation with no trace in its own logs.
|
|
237
|
+
const pendingHandler = functionName ? resolveHandler(functionName) : undefined;
|
|
238
|
+
if (pendingHandler === undefined) {
|
|
239
|
+
const message = \`No function registered for "\${functionName ?? ""}"\`;
|
|
240
|
+
console.error(message);
|
|
241
|
+
return new Response(message, { status: 404 });
|
|
242
|
+
}
|
|
243
|
+
let handler;
|
|
244
|
+
try {
|
|
245
|
+
handler = await pendingHandler;
|
|
246
|
+
} catch (e) {
|
|
247
|
+
console.error(\`Function "\${functionName}" failed to initialize:\`, e);
|
|
248
|
+
return new Response(
|
|
249
|
+
\`Function "\${functionName}" failed to initialize: \${e instanceof Error ? e.message : String(e)}\`,
|
|
250
|
+
{ status: 500 },
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
if (handler === null) {
|
|
254
|
+
const message = \`Function "\${functionName}" must export default a request handler or call Deno.serve()\`;
|
|
255
|
+
console.error(message);
|
|
256
|
+
return new Response(message, { status: 503 });
|
|
257
|
+
}
|
|
258
|
+
// Real client IP is in the "cf-connecting-ip" header, not this placeholder.
|
|
259
|
+
const info = {
|
|
260
|
+
remoteAddr: { transport: "tcp", hostname: "0.0.0.0", port: 0 },
|
|
261
|
+
};
|
|
262
|
+
// Cloudflare reports uncaught exceptions as its own log events, outside
|
|
263
|
+
// the console patch and therefore without function attribution. Log the
|
|
264
|
+
// crash through the patch (stamped with _b44_function) before
|
|
265
|
+
// rethrowing; per-function log queries on per-app scripts keep only
|
|
266
|
+
// stamped lines (see log_query.event_matches_function). Known gap:
|
|
267
|
+
// exceptions thrown while a response body streams happen after this
|
|
268
|
+
// frame returns and cannot be stamped — those crash events are
|
|
269
|
+
// dropped from per-function views.
|
|
270
|
+
try {
|
|
271
|
+
return ${returnExpr};
|
|
272
|
+
} catch (e) {
|
|
273
|
+
console.error(e);
|
|
274
|
+
throw e;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
`;
|
|
280
|
+
}
|
|
281
|
+
export function assertNoReservedFilenames(files) {
|
|
282
|
+
// Shim/entry/actor are reserved as exact root keys (unchanged — a flag-off
|
|
283
|
+
// bundle accepts exactly what prod accepts today).
|
|
284
|
+
if (SHIM_FILENAME in files ||
|
|
285
|
+
ENTRY_FILENAME in files ||
|
|
286
|
+
ACTOR_ENTRY_FILENAME in files) {
|
|
287
|
+
throw new DenoCompatError(`Reserved filenames "${SHIM_FILENAME}" / "${ENTRY_FILENAME}" / "${ACTOR_ENTRY_FILENAME}" must not be present in the function files.`);
|
|
288
|
+
}
|
|
289
|
+
// The activation shim is the ONLY importer allowed to reach the private
|
|
290
|
+
// PDS-manifest store (plaintext VPC/DB creds), and that gate keys on the
|
|
291
|
+
// ACTIVATION_FILENAME basename. Reserve that basename at ANY depth in EVERY
|
|
292
|
+
// mode — not just runtime-secrets. In flag-off / actor bundles no shim is
|
|
293
|
+
// injected, but a user file named `__base44_activation.mjs` would still match
|
|
294
|
+
// the store gate's allow-list and could forge the manifest to retarget a VPC
|
|
295
|
+
// binding; reserving it unconditionally (like shim/entry above) closes that.
|
|
296
|
+
for (const filePath of Object.keys(files)) {
|
|
297
|
+
if (filePath.slice(filePath.lastIndexOf("/") + 1) === ACTIVATION_FILENAME) {
|
|
298
|
+
throw new DenoCompatError(`Reserved filename "${ACTIVATION_FILENAME}" must not be present in the function files (found "${filePath}").`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/** Pass user sources through verbatim, dropping any build-config files: we own
|
|
303
|
+
* the `deno.json` (written into the bundle temp dir) and never honor a
|
|
304
|
+
* user-supplied one, so it can't change dependency resolution. */
|
|
305
|
+
function userFiles(files) {
|
|
306
|
+
const out = {};
|
|
307
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
308
|
+
if (isBuildConfig(filePath))
|
|
309
|
+
continue;
|
|
310
|
+
out[filePath] = content;
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
}
|
|
314
|
+
function isBuildConfig(filePath) {
|
|
315
|
+
return (filePath === "package.json" ||
|
|
316
|
+
filePath.endsWith("/package.json") ||
|
|
317
|
+
filePath === "deno.json" ||
|
|
318
|
+
filePath.endsWith("/deno.json"));
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=worker-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/worker-entry.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@base44/functions-compiler",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Production compiler for Base44 backend functions — turns function sources into a single Cloudflare Workers module.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./lib/src/index.d.ts",
|
|
13
|
+
"default": "./lib/src/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"lib",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "bun run clean && bun run build:shim && tsc -p tsconfig.build.json && bun run scripts/copy-assets.ts",
|
|
22
|
+
"build:shim": "bun run scripts/build-shim.ts",
|
|
23
|
+
"clean": "rm -rf dist lib",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"test": "bun run build:shim && vitest run"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@deno/loader": "npm:@jsr/deno__loader@0.5.0",
|
|
29
|
+
"esbuild": "0.28.0",
|
|
30
|
+
"zod": "3.25.76"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@deno/shim-deno": "0.19.2",
|
|
34
|
+
"@types/node": "^22.10.0",
|
|
35
|
+
"miniflare": "^4.20260529.0",
|
|
36
|
+
"partyserver": "0.0.56",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^4.0.16"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20.19.0"
|
|
42
|
+
}
|
|
43
|
+
}
|