@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.
Files changed (81) hide show
  1. package/README.md +137 -0
  2. package/lib/dist/activation-shim.mjs +237 -0
  3. package/lib/dist/actor.mjs +1129 -0
  4. package/lib/dist/deno-shim.mjs +2347 -0
  5. package/lib/src/actor-compat.d.ts +24 -0
  6. package/lib/src/actor-compat.js +302 -0
  7. package/lib/src/actor-compat.js.map +1 -0
  8. package/lib/src/bundler.d.ts +51 -0
  9. package/lib/src/bundler.js +321 -0
  10. package/lib/src/bundler.js.map +1 -0
  11. package/lib/src/contracts.d.ts +108 -0
  12. package/lib/src/contracts.js +39 -0
  13. package/lib/src/contracts.js.map +1 -0
  14. package/lib/src/deno-bundle.d.ts +30 -0
  15. package/lib/src/deno-bundle.js +146 -0
  16. package/lib/src/deno-bundle.js.map +1 -0
  17. package/lib/src/errors.d.ts +16 -0
  18. package/lib/src/errors.js +11 -0
  19. package/lib/src/errors.js.map +1 -0
  20. package/lib/src/esbuild/deno-resolver.d.ts +26 -0
  21. package/lib/src/esbuild/deno-resolver.js +436 -0
  22. package/lib/src/esbuild/deno-resolver.js.map +1 -0
  23. package/lib/src/esbuild/node-builtin-require.d.ts +2 -0
  24. package/lib/src/esbuild/node-builtin-require.js +33 -0
  25. package/lib/src/esbuild/node-builtin-require.js.map +1 -0
  26. package/lib/src/esbuild/private-data-sources-virtual.d.ts +3 -0
  27. package/lib/src/esbuild/private-data-sources-virtual.js +127 -0
  28. package/lib/src/esbuild/private-data-sources-virtual.js.map +1 -0
  29. package/lib/src/esbuild/runtime-context-virtual.d.ts +3 -0
  30. package/lib/src/esbuild/runtime-context-virtual.js +42 -0
  31. package/lib/src/esbuild/runtime-context-virtual.js.map +1 -0
  32. package/lib/src/esbuild/runtime-virtual.d.ts +2 -0
  33. package/lib/src/esbuild/runtime-virtual.js +52 -0
  34. package/lib/src/esbuild/runtime-virtual.js.map +1 -0
  35. package/lib/src/esbuild/user-files.d.ts +15 -0
  36. package/lib/src/esbuild/user-files.js +73 -0
  37. package/lib/src/esbuild/user-files.js.map +1 -0
  38. package/lib/src/fetch-guard.d.ts +26 -0
  39. package/lib/src/fetch-guard.js +67 -0
  40. package/lib/src/fetch-guard.js.map +1 -0
  41. package/lib/src/index.d.ts +12 -0
  42. package/lib/src/index.js +11 -0
  43. package/lib/src/index.js.map +1 -0
  44. package/lib/src/log.d.ts +7 -0
  45. package/lib/src/log.js +39 -0
  46. package/lib/src/log.js.map +1 -0
  47. package/lib/src/private-data-sources/build-http.ts +51 -0
  48. package/lib/src/private-data-sources/elasticsearch.ts +8 -0
  49. package/lib/src/private-data-sources/http-url.ts +23 -0
  50. package/lib/src/private-data-sources/http.ts +6 -0
  51. package/lib/src/private-data-sources/hyperdrive.ts +48 -0
  52. package/lib/src/private-data-sources/ioredis-adapter.ts +229 -0
  53. package/lib/src/private-data-sources/manifest.ts +150 -0
  54. package/lib/src/private-data-sources/mariadb.ts +8 -0
  55. package/lib/src/private-data-sources/mongodb.ts +70 -0
  56. package/lib/src/private-data-sources/mysql.ts +8 -0
  57. package/lib/src/private-data-sources/node-net-adapter.ts +244 -0
  58. package/lib/src/private-data-sources/postgres.ts +8 -0
  59. package/lib/src/private-data-sources/redis-auth.ts +83 -0
  60. package/lib/src/private-data-sources/redis.ts +47 -0
  61. package/lib/src/private-data-sources/runtime-environment.ts +4 -0
  62. package/lib/src/private-data-sources/runtime-manifest-store.ts +32 -0
  63. package/lib/src/private-data-sources/sqlserver.ts +22 -0
  64. package/lib/src/private-data-sources/tcp.ts +86 -0
  65. package/lib/src/private-data-sources/tedious-adapter.ts +67 -0
  66. package/lib/src/private-data-sources/types.ts +29 -0
  67. package/lib/src/runtime/index.ts +30 -0
  68. package/lib/src/runtime-context.ts +29 -0
  69. package/lib/src/static-egress-marker.d.ts +1 -0
  70. package/lib/src/static-egress-marker.js +7 -0
  71. package/lib/src/static-egress-marker.js.map +1 -0
  72. package/lib/src/telemetry.d.ts +32 -0
  73. package/lib/src/telemetry.js +84 -0
  74. package/lib/src/telemetry.js.map +1 -0
  75. package/lib/src/tracing.d.ts +9 -0
  76. package/lib/src/tracing.js +21 -0
  77. package/lib/src/tracing.js.map +1 -0
  78. package/lib/src/worker-entry.d.ts +36 -0
  79. package/lib/src/worker-entry.js +320 -0
  80. package/lib/src/worker-entry.js.map +1 -0
  81. 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
+ }