@prisma/composer 0.1.0 → 0.2.0-dev.10

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 (80) hide show
  1. package/dist/app-config-CVyObaOe-PF94uVBK.d.mts +419 -0
  2. package/dist/app-config-CVyObaOe-PF94uVBK.d.mts.map +1 -0
  3. package/dist/assertions.d.mts +1 -1
  4. package/dist/assertions.d.mts.map +1 -0
  5. package/dist/bin.mjs +220 -258
  6. package/dist/bin.mjs.map +1 -1
  7. package/dist/casts.d.mts +1 -1
  8. package/dist/casts.d.mts.map +1 -0
  9. package/dist/config-BP2DrIX_.d.mts +1 -0
  10. package/dist/config.d.mts +3 -2
  11. package/dist/config.mjs +2 -1
  12. package/dist/config.mjs.map +1 -1
  13. package/dist/container-transport-DKmKg5JQ-DKWs0ubK.mjs +45 -0
  14. package/dist/container-transport-DKmKg5JQ-DKWs0ubK.mjs.map +1 -0
  15. package/dist/deploy-BP2DrIX_.d.mts +1 -0
  16. package/dist/deploy.d.mts +3 -2
  17. package/dist/deploy.mjs +181 -23
  18. package/dist/deploy.mjs.map +1 -1
  19. package/dist/{dist-zBU8ASQW.mjs → dist-BkSJOwTm.mjs} +16 -4
  20. package/dist/dist-BkSJOwTm.mjs.map +1 -0
  21. package/dist/{graph-BYdCQKya-BI0njTow.mjs → graph-CP16cJyH-D5IW87Y-.mjs} +118 -21
  22. package/dist/graph-CP16cJyH-D5IW87Y-.mjs.map +1 -0
  23. package/dist/graph-DUSgjmzA-DhtkTqoz.d.mts +18 -0
  24. package/dist/graph-DUSgjmzA-DhtkTqoz.d.mts.map +1 -0
  25. package/dist/{config-ob5OhCSP-sP3GW3uu.d.mts → graph-types-BcbVhojU-C3fhxjPK.d.mts} +205 -114
  26. package/dist/graph-types-BcbVhojU-C3fhxjPK.d.mts.map +1 -0
  27. package/dist/{index-CZSc9drz.d.mts → index-BFBNz7Aw.d.mts} +5 -20
  28. package/dist/index-BFBNz7Aw.d.mts.map +1 -0
  29. package/dist/index.d.mts +4 -3
  30. package/dist/index.mjs +3 -3
  31. package/dist/{index-Dh4Zro0y.d.mts → nextjs-DLyeRR7M-DwnBjryZ.d.mts} +6 -5
  32. package/dist/nextjs-DLyeRR7M-DwnBjryZ.d.mts.map +1 -0
  33. package/dist/nextjs-control.d.mts +6 -5
  34. package/dist/nextjs-control.d.mts.map +1 -0
  35. package/dist/nextjs-control.mjs +9 -11
  36. package/dist/nextjs-control.mjs.map +1 -1
  37. package/dist/nextjs.d.mts +2 -2
  38. package/dist/nextjs.mjs.map +1 -1
  39. package/dist/node-control.d.mts +5 -3
  40. package/dist/node-control.d.mts.map +1 -0
  41. package/dist/node-control.mjs +115 -24
  42. package/dist/node-control.mjs.map +1 -1
  43. package/dist/node.d.mts +18 -5
  44. package/dist/node.d.mts.map +1 -0
  45. package/dist/node.mjs +2 -1
  46. package/dist/node.mjs.map +1 -1
  47. package/dist/report.d.mts +17 -0
  48. package/dist/report.d.mts.map +1 -0
  49. package/dist/report.mjs +79 -0
  50. package/dist/report.mjs.map +1 -0
  51. package/dist/service-rpc.d.mts +61 -0
  52. package/dist/service-rpc.d.mts.map +1 -0
  53. package/dist/service-rpc.mjs +353 -0
  54. package/dist/service-rpc.mjs.map +1 -0
  55. package/dist/testing.d.mts +2 -3
  56. package/dist/testing.d.mts.map +1 -0
  57. package/package.json +20 -18
  58. package/src/exports/assertions.ts +1 -0
  59. package/src/exports/casts.ts +1 -0
  60. package/src/exports/config.ts +1 -0
  61. package/src/exports/deploy.ts +1 -0
  62. package/src/exports/index.ts +1 -0
  63. package/src/exports/nextjs-control.ts +1 -0
  64. package/src/exports/nextjs.ts +2 -0
  65. package/src/exports/node-control.ts +1 -0
  66. package/src/exports/node.ts +2 -0
  67. package/src/exports/report.ts +1 -0
  68. package/src/exports/service-rpc.ts +1 -0
  69. package/src/exports/testing.ts +1 -0
  70. package/dist/app-config-BUqyK6N6-CVq3uvHF.d.mts +0 -188
  71. package/dist/config-BVVgDSdq.d.mts +0 -1
  72. package/dist/deploy-BVVgDSdq.d.mts +0 -1
  73. package/dist/dist-zBU8ASQW.mjs.map +0 -1
  74. package/dist/graph-BYdCQKya-BI0njTow.mjs.map +0 -1
  75. package/dist/rpc.d.mts +0 -43
  76. package/dist/rpc.mjs +0 -132
  77. package/dist/rpc.mjs.map +0 -1
  78. package/dist/tsdown.d.mts +0 -9
  79. package/dist/tsdown.mjs +0 -35
  80. package/dist/tsdown.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { build } from "tsdown";
4
+ import { build } from "esbuild";
5
5
  //#region ../../0-framework/2-authoring/nextjs/dist/control.mjs
6
6
  /**
7
7
  * The extension's control entry (ADR-0017): `nextjsBuild()` returns the build
@@ -77,21 +77,19 @@ async function assemble(input) {
77
77
  const publicSrc = path.join(appDir, "public");
78
78
  if (fs.existsSync(publicSrc)) await fs.promises.cp(publicSrc, path.join(appOut, "public"), { recursive: true });
79
79
  await build({
80
- entry: { main: fileURLToPath(buildDescriptor.module) },
81
- outDir: workDir,
80
+ entryPoints: { main: fileURLToPath(buildDescriptor.module) },
81
+ outdir: workDir,
82
+ bundle: true,
82
83
  format: "esm",
83
84
  platform: "node",
84
- external: ["bun"],
85
- noExternal: [/^@prisma\//, ...input.wrapperNoExternal ?? []],
86
- dts: false,
87
- sourcemap: false,
88
- clean: false,
89
- config: false
85
+ external: ["bun", "bun:*"],
86
+ outExtension: { ".js": ".mjs" }
90
87
  });
91
- if (!fs.existsSync(path.join(workDir, "main.mjs"))) throw new Error(`tsdown produced no main.mjs in ${workDir}`);
88
+ if (!fs.existsSync(path.join(workDir, "main.mjs"))) throw new Error(`esbuild produced no main.mjs in ${workDir}`);
92
89
  return {
93
90
  dir: workDir,
94
- entry: path.posix.join("bundle", appRel.split(path.sep).join("/"), "server.js")
91
+ entry: path.posix.join("bundle", appRel.split(path.sep).join("/"), "server.js"),
92
+ watch: [standaloneRoot]
95
93
  };
96
94
  }
97
95
  /** The nextjs build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs-control.mjs","names":[],"sources":["../../../0-framework/2-authoring/nextjs/dist/control.mjs"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { build } from \"tsdown\";\n//#region src/control.ts\n/**\n* The extension's control entry (ADR-0017): `nextjsBuild()` returns the build\n* descriptor `prisma-composer.config.ts` lists. Deploy-only (ADR-0005): the user\n* runs `next build` (`output: \"standalone\"`); `assemble` then performs the\n* *documented* Next standalone deploy — it ships the standalone tree and copies\n* in the client assets Next deliberately omits (`.next/static`, `public/`) — and\n* adds the framework's boot wrapper. This is the canonical `cp` step from the\n* Next docs, run at deploy so no app needs a build-script for it.\n*\n* It does not guess: the app's location inside the standalone tree (deep, when\n* `outputFileTracingRoot` is the monorepo root) is *read from Next's own build\n* manifest* (`.next/required-server-files.json`'s `relativeAppDir`), never walked\n* for or computed from a hardcoded depth. It does not launder: node_modules is\n* shipped exactly as `next build` produced it, so a symlinked (non-hoisted)\n* node_modules is the packager's hard error — the same misconfiguration crashes\n* the standalone server at boot, so it must be a flat install (npm, or pnpm/bun\n* with a hoisted node-linker).\n*\n* Artifact layout: `<workDir>/main.mjs` (our wrapper) + `<workDir>/bundle/`\n* (the standalone tree, with static/public copied in). The packager adds\n* `bootstrap.js` + the manifest at the root; bootstrap imports main.mjs, whose\n* run() dynamically imports `./bundle/<relativeAppDir>/server.js`.\n*\n* Paths are file-relative (ADR-0004): `appDir` resolves against\n* `dirname(build.module)`.\n*/\n/** Narrows the shared BuildAdapter to this extension's own descriptor — the value-level mirror of the registry routing on (extension, type). */\nfunction isNextjsBuild(descriptor) {\n\treturn descriptor.type === \"nextjs\" && \"appDir\" in descriptor && typeof descriptor.appDir === \"string\";\n}\n/**\n* The app's own subpath within `.next/standalone`, as an OS-relative path. Next\n* mirrors the app's location under `outputFileTracingRoot` (deep, when that's the\n* monorepo root); rather than walk the tree for `server.js`, we read where Next\n* put it from `.next/required-server-files.json` — `relativeAppDir` is exactly\n* that subpath. Older Next lacks the field; fall back to computing it from the\n* same manifest's `config.outputFileTracingRoot`.\n*/\nfunction nextAppRel(appDir) {\n\tconst manifestPath = path.join(appDir, \".next\", \"required-server-files.json\");\n\tif (!fs.existsSync(manifestPath)) throw new Error(`no ${path.join(\".next\", \"required-server-files.json\")} under ${appDir} — run \\`next build\\` with output: \"standalone\" first.`);\n\tconst manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\"));\n\tconst relativeAppDir = manifest?.relativeAppDir;\n\tconst tracingRoot = manifest?.config?.outputFileTracingRoot;\n\tconst posixRel = typeof relativeAppDir === \"string\" ? relativeAppDir : typeof tracingRoot === \"string\" ? path.relative(tracingRoot, appDir).split(path.sep).join(\"/\") : void 0;\n\tif (posixRel === void 0) throw new Error(`${manifestPath} records neither relativeAppDir nor config.outputFileTracingRoot — cannot locate the standalone server`);\n\treturn posixRel.split(\"/\").join(path.sep);\n}\n/** The built standalone server.js for a nextjs build — `appDir`'s standalone root plus the app subpath Next recorded. Single-sourced so `assemble()` (deploy) and the integration-test seam can't drift. */\nfunction standaloneServerPath(build) {\n\tconst appDir = path.resolve(path.dirname(fileURLToPath(build.module)), build.appDir);\n\treturn path.join(appDir, \".next\", \"standalone\", nextAppRel(appDir), \"server.js\");\n}\nasync function assemble(input) {\n\tif (!isNextjsBuild(input.build)) throw new Error(`@prisma/composer/nextjs/control: expected a \"nextjs\" build adapter (with appDir), got \"${input.build.type}\".`);\n\tconst buildDescriptor = input.build;\n\tconst appDir = path.resolve(path.dirname(fileURLToPath(buildDescriptor.module)), buildDescriptor.appDir);\n\tconst standaloneRoot = path.join(appDir, \".next\", \"standalone\");\n\tif (!fs.existsSync(standaloneRoot)) throw new Error(`no ${path.join(\".next\", \"standalone\")} under ${appDir} — run \\`next build\\` with output: \"standalone\" first.`);\n\tconst appRel = nextAppRel(appDir);\n\tconst workDir = path.join(input.cwd, \".prisma-composer\", \"artifacts\", input.address);\n\tawait fs.promises.rm(workDir, {\n\t\trecursive: true,\n\t\tforce: true\n\t});\n\tawait fs.promises.mkdir(workDir, { recursive: true });\n\tconst bundleDir = path.join(workDir, \"bundle\");\n\tawait fs.promises.cp(standaloneRoot, bundleDir, { recursive: true });\n\tconst appOut = path.join(bundleDir, appRel);\n\tconst staticSrc = path.join(appDir, \".next\", \"static\");\n\tif (fs.existsSync(staticSrc)) await fs.promises.cp(staticSrc, path.join(appOut, \".next\", \"static\"), { recursive: true });\n\tconst publicSrc = path.join(appDir, \"public\");\n\tif (fs.existsSync(publicSrc)) await fs.promises.cp(publicSrc, path.join(appOut, \"public\"), { recursive: true });\n\tawait build({\n\t\tentry: { main: fileURLToPath(buildDescriptor.module) },\n\t\toutDir: workDir,\n\t\tformat: \"esm\",\n\t\tplatform: \"node\",\n\t\texternal: [\"bun\"],\n\t\tnoExternal: [/^@prisma\\//, ...input.wrapperNoExternal ?? []],\n\t\tdts: false,\n\t\tsourcemap: false,\n\t\tclean: false,\n\t\tconfig: false\n\t});\n\tif (!fs.existsSync(path.join(workDir, \"main.mjs\"))) throw new Error(`tsdown produced no main.mjs in ${workDir}`);\n\treturn {\n\t\tdir: workDir,\n\t\tentry: path.posix.join(\"bundle\", appRel.split(path.sep).join(\"/\"), \"server.js\")\n\t};\n}\n/** The nextjs build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */\nconst nextjsBuild = () => ({\n\tid: \"@prisma/composer/nextjs\",\n\tnodes: { nextjs: {\n\t\tkind: \"build\",\n\t\tassemble\n\t} }\n});\n//#endregion\nexport { assemble, nextjsBuild, standaloneServerPath };\n\n//# sourceMappingURL=control.mjs.map"],"mappings":"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"}
1
+ {"version":3,"file":"nextjs-control.mjs","names":[],"sources":["../../../0-framework/2-authoring/nextjs/dist/control.mjs"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { build } from \"esbuild\";\n//#region src/control/build.ts\n/**\n* The extension's control entry (ADR-0017): `nextjsBuild()` returns the build\n* descriptor `prisma-composer.config.ts` lists. Deploy-only (ADR-0005): the user\n* runs `next build` (`output: \"standalone\"`); `assemble` then performs the\n* *documented* Next standalone deploy — it ships the standalone tree and copies\n* in the client assets Next deliberately omits (`.next/static`, `public/`) — and\n* adds the framework's boot wrapper. This is the canonical `cp` step from the\n* Next docs, run at deploy so no app needs a build-script for it.\n*\n* It does not guess: the app's location inside the standalone tree (deep, when\n* `outputFileTracingRoot` is the monorepo root) is *read from Next's own build\n* manifest* (`.next/required-server-files.json`'s `relativeAppDir`), never walked\n* for or computed from a hardcoded depth. It does not launder: node_modules is\n* shipped exactly as `next build` produced it, so a symlinked (non-hoisted)\n* node_modules is the packager's hard error — the same misconfiguration crashes\n* the standalone server at boot, so it must be a flat install (npm, or pnpm/bun\n* with a hoisted node-linker).\n*\n* Artifact layout: `<workDir>/main.mjs` (our wrapper) + `<workDir>/bundle/`\n* (the standalone tree, with static/public copied in). The packager adds\n* `bootstrap.js` + the manifest at the root; bootstrap imports main.mjs, whose\n* run() dynamically imports `./bundle/<relativeAppDir>/server.js`.\n*\n* Paths are file-relative (ADR-0004): `appDir` resolves against\n* `dirname(build.module)`.\n*/\n/** Narrows the shared BuildAdapter to this extension's own descriptor — the value-level mirror of the registry routing on (extension, type). */\nfunction isNextjsBuild(descriptor) {\n\treturn descriptor.type === \"nextjs\" && \"appDir\" in descriptor && typeof descriptor.appDir === \"string\";\n}\n/**\n* The app's own subpath within `.next/standalone`, as an OS-relative path. Next\n* mirrors the app's location under `outputFileTracingRoot` (deep, when that's the\n* monorepo root); rather than walk the tree for `server.js`, we read where Next\n* put it from `.next/required-server-files.json` — `relativeAppDir` is exactly\n* that subpath. Older Next lacks the field; fall back to computing it from the\n* same manifest's `config.outputFileTracingRoot`.\n*/\nfunction nextAppRel(appDir) {\n\tconst manifestPath = path.join(appDir, \".next\", \"required-server-files.json\");\n\tif (!fs.existsSync(manifestPath)) throw new Error(`no ${path.join(\".next\", \"required-server-files.json\")} under ${appDir} — run \\`next build\\` with output: \"standalone\" first.`);\n\tconst manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\"));\n\tconst relativeAppDir = manifest?.relativeAppDir;\n\tconst tracingRoot = manifest?.config?.outputFileTracingRoot;\n\tconst posixRel = typeof relativeAppDir === \"string\" ? relativeAppDir : typeof tracingRoot === \"string\" ? path.relative(tracingRoot, appDir).split(path.sep).join(\"/\") : void 0;\n\tif (posixRel === void 0) throw new Error(`${manifestPath} records neither relativeAppDir nor config.outputFileTracingRoot — cannot locate the standalone server`);\n\treturn posixRel.split(\"/\").join(path.sep);\n}\n/** The built standalone server.js for a nextjs build — `appDir`'s standalone root plus the app subpath Next recorded. Single-sourced so `assemble()` (deploy) and the integration-test seam can't drift. */\nfunction standaloneServerPath(build) {\n\tconst appDir = path.resolve(path.dirname(fileURLToPath(build.module)), build.appDir);\n\treturn path.join(appDir, \".next\", \"standalone\", nextAppRel(appDir), \"server.js\");\n}\nasync function assemble(input) {\n\tif (!isNextjsBuild(input.build)) throw new Error(`@prisma/composer/nextjs/control: expected a \"nextjs\" build adapter (with appDir), got \"${input.build.type}\".`);\n\tconst buildDescriptor = input.build;\n\tconst appDir = path.resolve(path.dirname(fileURLToPath(buildDescriptor.module)), buildDescriptor.appDir);\n\tconst standaloneRoot = path.join(appDir, \".next\", \"standalone\");\n\tif (!fs.existsSync(standaloneRoot)) throw new Error(`no ${path.join(\".next\", \"standalone\")} under ${appDir} — run \\`next build\\` with output: \"standalone\" first.`);\n\tconst appRel = nextAppRel(appDir);\n\tconst workDir = path.join(input.cwd, \".prisma-composer\", \"artifacts\", input.address);\n\tawait fs.promises.rm(workDir, {\n\t\trecursive: true,\n\t\tforce: true\n\t});\n\tawait fs.promises.mkdir(workDir, { recursive: true });\n\tconst bundleDir = path.join(workDir, \"bundle\");\n\tawait fs.promises.cp(standaloneRoot, bundleDir, { recursive: true });\n\tconst appOut = path.join(bundleDir, appRel);\n\tconst staticSrc = path.join(appDir, \".next\", \"static\");\n\tif (fs.existsSync(staticSrc)) await fs.promises.cp(staticSrc, path.join(appOut, \".next\", \"static\"), { recursive: true });\n\tconst publicSrc = path.join(appDir, \"public\");\n\tif (fs.existsSync(publicSrc)) await fs.promises.cp(publicSrc, path.join(appOut, \"public\"), { recursive: true });\n\tawait build({\n\t\tentryPoints: { main: fileURLToPath(buildDescriptor.module) },\n\t\toutdir: workDir,\n\t\tbundle: true,\n\t\tformat: \"esm\",\n\t\tplatform: \"node\",\n\t\texternal: [\"bun\", \"bun:*\"],\n\t\toutExtension: { \".js\": \".mjs\" }\n\t});\n\tif (!fs.existsSync(path.join(workDir, \"main.mjs\"))) throw new Error(`esbuild produced no main.mjs in ${workDir}`);\n\treturn {\n\t\tdir: workDir,\n\t\tentry: path.posix.join(\"bundle\", appRel.split(path.sep).join(\"/\"), \"server.js\"),\n\t\twatch: [standaloneRoot]\n\t};\n}\n/** The nextjs build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */\nconst nextjsBuild = () => ({\n\tid: \"@prisma/composer/nextjs\",\n\tnodes: { nextjs: {\n\t\tkind: \"build\",\n\t\tassemble\n\t} }\n});\n//#endregion\nexport { assemble, nextjsBuild, standaloneServerPath };\n\n//# sourceMappingURL=control.mjs.map"],"mappings":"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"}
package/dist/nextjs.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { n as nextjsBuild, t as NextjsBuildAdapter } from "./index-Dh4Zro0y.mjs";
2
- export { NextjsBuildAdapter, nextjsBuild as default };
1
+ import { n as nextjsBuild, t as NextjsBuildAdapter } from "./nextjs-DLyeRR7M-DwnBjryZ.mjs";
2
+ export { type NextjsBuildAdapter, nextjsBuild as default };
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs.mjs","names":[],"sources":["../../../0-framework/2-authoring/nextjs/dist/index.mjs"],"sourcesContent":["//#region src/index.ts\nconst nextjsBuild = (opts) => ({\n\textension: \"@prisma/composer/nextjs\",\n\ttype: \"nextjs\",\n\tmodule: opts.module,\n\tappDir: opts.appDir,\n\tentry: \"server.js\"\n});\n//#endregion\nexport { nextjsBuild as default };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":";AACA,MAAM,eAAe,UAAU;CAC9B,WAAW;CACX,MAAM;CACN,QAAQ,KAAK;CACb,QAAQ,KAAK;CACb,OAAO;AACR"}
1
+ {"version":3,"file":"nextjs.mjs","names":[],"sources":["../../../0-framework/2-authoring/nextjs/dist/index.mjs"],"sourcesContent":["//#region src/nextjs.ts\nconst nextjsBuild = (opts) => ({\n\textension: \"@prisma/composer/nextjs\",\n\ttype: \"nextjs\",\n\tmodule: opts.module,\n\tappDir: opts.appDir,\n\tentry: \"server.js\"\n});\n//#endregion\nexport { nextjsBuild as default };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":";AACA,MAAM,eAAe,UAAU;CAC9B,WAAW;CACX,MAAM;CACN,QAAQ,KAAK;CACb,QAAQ,KAAK;CACb,OAAO;AACR"}
@@ -1,9 +1,11 @@
1
- import { a as Bundle, i as AssembleInput, o as ExtensionDescriptor } from "./app-config-BUqyK6N6-CVq3uvHF.mjs";
1
+ import { a as Bundle, d as ExtensionDescriptor, i as AssembleInput } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
+ import "./config-BP2DrIX_.mjs";
3
+ import "./deploy-BP2DrIX_.mjs";
2
4
  //#region ../../0-framework/2-authoring/node/dist/control.d.mts
3
- //#region src/control.d.ts
5
+ //#region src/control/build.d.ts
4
6
  declare function assemble(input: AssembleInput): Promise<Bundle>;
5
7
  /** The node build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */
6
- declare const nodeBuild: () => ExtensionDescriptor; //#endregion
8
+ declare const nodeBuild: () => ExtensionDescriptor;
7
9
  //#endregion
8
10
  export { type AssembleInput, type Bundle, assemble, nodeBuild };
9
11
  //# sourceMappingURL=node-control.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-control.d.mts","names":[],"sources":["../../../0-framework/2-authoring/node/dist/control.d.mts"],"mappings":";;;;;iBAGiB,SAAS,OAAO,gBAAkB,QAAQ;;cAE7C,iBAAiB"}
@@ -1,16 +1,22 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { build } from "tsdown";
4
+ import { build } from "esbuild";
5
5
  //#region ../../0-framework/2-authoring/node/dist/control.mjs
6
6
  /**
7
7
  * The extension's control entry (ADR-0017): `nodeBuild()` returns the build
8
8
  * descriptor `prisma-composer.config.ts` lists. Deploy-only (ADR-0005): the user
9
- * builds their own runnable; `assemble` copies that built entry under `bundle/`
9
+ * builds their own runnable; `assemble` copies what they built under `bundle/`
10
10
  * and adds the framework's boot wrapper — it never bundles or transforms the
11
11
  * app's code.
12
12
  *
13
- * The wrapper is a SEPARATE tsdown build of the service module (declarations
13
+ * Two forms, chosen by the descriptor: without `dir`, `entry` is a single
14
+ * self-contained file and only that file is copied. With `dir`, the whole
15
+ * directory is copied verbatim and `entry` names the file inside it that boots.
16
+ * Neither form discovers anything — no tree-walking for an entry, no filename
17
+ * heuristics; the author states the paths and we copy exactly those.
18
+ *
19
+ * The wrapper is a SEPARATE esbuild build of the service module (declarations
14
20
  * only, whose node carries run()/load()), emitted as `main.mjs` at the
15
21
  * working-dir root — a dictated name (object entry `{ main }`), not a
16
22
  * discovered one. run() and the app entry must be independent module instances
@@ -18,42 +24,127 @@ import { build } from "tsdown";
18
24
  * build; `@prisma/*` is inlined, `bun` is a Compute built-in.
19
25
  *
20
26
  * Artifact layout: `<cwd>/.prisma-composer/artifacts/<address>/` (deploy-owned,
21
- * ADR-0005) holds `main.mjs` at the root and the app's entry under `bundle/`.
22
- * `entry` is file-relative to `dirname(build.module)` (ADR-0004).
27
+ * ADR-0005) holds `main.mjs` at the root and the app's built runnable under
28
+ * `bundle/`.
23
29
  */
30
+ /** Narrows the shared BuildAdapter to this extension's own descriptor — the value-level mirror of the registry routing on (extension, type). `dir` is optional: absent is the single-file form. */
31
+ function isNodeBuild(descriptor) {
32
+ return descriptor.type === "node" && (!("dir" in descriptor) || typeof descriptor.dir === "string");
33
+ }
34
+ /** The single-file form: `entry` is the whole built runnable, resolved against dirname(module) (ADR-0004). */
35
+ function resolveFile(entrySpec, moduleDir) {
36
+ const entryPath = path.resolve(moduleDir, entrySpec);
37
+ if (!fs.existsSync(entryPath)) throw new Error(`no built entry at ${entryPath} — run your build first (the build adapter's entry, "${entrySpec}", resolves against dirname(module)).`);
38
+ const entryFile = path.basename(entryPath);
39
+ return {
40
+ source: entryPath,
41
+ sourceField: "entry",
42
+ entry: entryFile,
43
+ copyInto: async (bundleDir) => {
44
+ await fs.promises.mkdir(bundleDir, { recursive: true });
45
+ await fs.promises.copyFile(entryPath, path.join(bundleDir, entryFile));
46
+ }
47
+ };
48
+ }
49
+ /** The shared "dir contains symlinks" error, reused by both the root-is-a-symlink case and the nested-symlink walk below — one message shape, never two to drift apart. */
50
+ function symlinksFoundError(dirPath, found) {
51
+ const listed = found.slice(0, 5).join(", ");
52
+ return /* @__PURE__ */ new Error(`the build adapter's dir ("${dirPath}") contains symlinks, which the platform's packager rejects: ${listed}${found.length > 5 ? `, and ${found.length - 5} more` : ""}. The tree is copied verbatim, so make your build emit real files in dir (for example, a hoisted node_modules, or dereference the links into dir with cp -RL).`);
53
+ }
54
+ /**
55
+ * Compute's packager rejects symlinks, so a tree containing one cannot deploy.
56
+ * We fail here, naming the links, rather than dereferencing them on the copy:
57
+ * the artifact must be what the author's build produced (ADR-0005), and
58
+ * following a link that points outside `dir` would pull in files the author
59
+ * never named. The walk reads dirents (lstat semantics), so a symlinked
60
+ * directory is reported and never descended into. Checks only `dirPath`'s
61
+ * children — the caller (`resolveDir`) checks `dirPath` itself before this
62
+ * runs, since that check also decides "not a directory" vs "is a symlink"
63
+ * and must happen before any dereferencing stat.
64
+ */
65
+ async function assertNoSymlinks(dirPath) {
66
+ const found = [];
67
+ const walk = async (current) => {
68
+ for (const entry of await fs.promises.readdir(current, { withFileTypes: true })) {
69
+ const full = path.join(current, entry.name);
70
+ if (entry.isSymbolicLink()) found.push(full);
71
+ else if (entry.isDirectory()) await walk(full);
72
+ }
73
+ };
74
+ await walk(dirPath);
75
+ if (found.length > 0) throw symlinksFoundError(dirPath, found);
76
+ }
77
+ /**
78
+ * The directory form: `dir` is the built tree, resolved against dirname(module)
79
+ * (ADR-0004) and copied whole; `entry` resolves inside `dir` and names the file
80
+ * that boots. An `entry` that resolves outside `dir` is rejected rather than
81
+ * followed — only `dir` is ever copied.
82
+ *
83
+ * `dir` itself can be a symlink — not just something inside it. `lstat` it
84
+ * before anything else so that case hard-errors identically whether the link
85
+ * points at a real directory (which a dereferencing `stat` would otherwise
86
+ * accept as "is a directory") or at a file: neither is ever silently
87
+ * dereferenced and copied (ADR-0005).
88
+ */
89
+ async function resolveDir(dirSpec, entrySpec, moduleDir) {
90
+ const dirPath = path.resolve(moduleDir, dirSpec);
91
+ let dirLstat;
92
+ try {
93
+ dirLstat = await fs.promises.lstat(dirPath);
94
+ } catch {
95
+ throw new Error(`no built directory at ${dirPath} — run your build first (the build adapter's dir, "${dirSpec}", resolves against dirname(module)).`);
96
+ }
97
+ if (dirLstat.isSymbolicLink()) throw symlinksFoundError(dirPath, [dirPath]);
98
+ if (!dirLstat.isDirectory()) throw new Error(`the build adapter's dir ("${dirPath}") is not a directory — drop dir to deploy a single built file, naming it as entry.`);
99
+ const entryPath = path.resolve(dirPath, entrySpec);
100
+ if (!entryPath.startsWith(dirPath + path.sep)) throw new Error(`the build adapter's entry ("${entrySpec}") resolves to ${entryPath}, which is not inside dir ("${dirPath}") — in the directory form entry names a file inside dir, and only dir is copied.`);
101
+ if (!fs.existsSync(entryPath) || !fs.statSync(entryPath).isFile()) throw new Error(`no built entry at ${entryPath} — run your build first (the build adapter's entry, "${entrySpec}", resolves inside dir, "${dirPath}").`);
102
+ await assertNoSymlinks(dirPath);
103
+ return {
104
+ source: dirPath,
105
+ sourceField: "dir",
106
+ entry: path.relative(dirPath, entryPath).split(path.sep).join("/"),
107
+ copyInto: (bundleDir) => fs.promises.cp(dirPath, bundleDir, { recursive: true })
108
+ };
109
+ }
110
+ /**
111
+ * The working dir is cleared on every assemble, so it must not overlap the copy
112
+ * source: inside it, the rm would delete the source before the copy; the other
113
+ * way round, the copy would recurse into its own output.
114
+ */
115
+ function assertOutsideWorkDir(runnable, workDir) {
116
+ const { source, sourceField } = runnable;
117
+ if (source === workDir || source.startsWith(workDir + path.sep)) throw new Error(`the build adapter's ${sourceField} ("${source}") resolves inside the deploy working dir ("${workDir}"), which is cleared on every assemble — point ${sourceField} at your build output elsewhere.`);
118
+ if (workDir.startsWith(source + path.sep)) throw new Error(`the deploy working dir ("${workDir}") sits inside the build adapter's ${sourceField} ("${source}"), so assembling would copy the artifact into itself — point ${sourceField} at your build output elsewhere.`);
119
+ }
24
120
  async function assemble(input) {
25
- if (input.build.type !== "node") throw new Error(`@prisma/composer/node/control: expected a "node" build adapter, got "${input.build.type}".`);
26
- const serviceModule = fileURLToPath(input.build.module);
121
+ if (!isNodeBuild(input.build)) throw new Error(`@prisma/composer/node/control: expected a "node" build adapter, got "${input.build.type}".`);
122
+ const buildDescriptor = input.build;
123
+ const serviceModule = fileURLToPath(buildDescriptor.module);
27
124
  const moduleDir = path.dirname(serviceModule);
28
- const entryPath = path.resolve(moduleDir, input.build.entry);
29
- if (!fs.existsSync(entryPath)) throw new Error(`no built entry at ${entryPath} — run your build first (the build adapter's entry, "${input.build.entry}", resolves against dirname(module)).`);
125
+ const runnable = buildDescriptor.dir === void 0 ? resolveFile(buildDescriptor.entry, moduleDir) : await resolveDir(buildDescriptor.dir, buildDescriptor.entry, moduleDir);
30
126
  const workDir = path.join(input.cwd, ".prisma-composer", "artifacts", input.address);
31
- if (entryPath === workDir || entryPath.startsWith(workDir + path.sep)) throw new Error(`the build adapter's entry ("${entryPath}") resolves inside the deploy working dir ("${workDir}"), which is cleared on every assemble — point entry at your build output elsewhere.`);
127
+ assertOutsideWorkDir(runnable, workDir);
32
128
  await fs.promises.rm(workDir, {
33
129
  recursive: true,
34
130
  force: true
35
131
  });
36
132
  await fs.promises.mkdir(workDir, { recursive: true });
37
133
  await build({
38
- entry: { main: serviceModule },
39
- outDir: workDir,
134
+ entryPoints: { main: serviceModule },
135
+ outdir: workDir,
136
+ bundle: true,
40
137
  format: "esm",
41
138
  platform: "node",
42
- external: ["bun"],
43
- noExternal: [/^@prisma\//, ...input.wrapperNoExternal ?? []],
44
- dts: false,
45
- sourcemap: false,
46
- clean: false,
47
- config: false
139
+ external: ["bun", "bun:*"],
140
+ outExtension: { ".js": ".mjs" }
48
141
  });
49
- if (!fs.existsSync(path.join(workDir, "main.mjs"))) throw new Error(`tsdown produced no main.mjs in ${workDir}`);
50
- const entryFile = path.basename(entryPath);
51
- const bundleDir = path.join(workDir, "bundle");
52
- await fs.promises.mkdir(bundleDir, { recursive: true });
53
- await fs.promises.copyFile(entryPath, path.join(bundleDir, entryFile));
142
+ if (!fs.existsSync(path.join(workDir, "main.mjs"))) throw new Error(`esbuild produced no main.mjs in ${workDir}`);
143
+ await runnable.copyInto(path.join(workDir, "bundle"));
54
144
  return {
55
145
  dir: workDir,
56
- entry: path.posix.join("bundle", entryFile)
146
+ entry: path.posix.join("bundle", runnable.entry),
147
+ watch: [runnable.source]
57
148
  };
58
149
  }
59
150
  /** The node build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */
@@ -1 +1 @@
1
- {"version":3,"file":"node-control.mjs","names":[],"sources":["../../../0-framework/2-authoring/node/dist/control.mjs"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { build } from \"tsdown\";\n//#region src/control.ts\n/**\n* The extension's control entry (ADR-0017): `nodeBuild()` returns the build\n* descriptor `prisma-composer.config.ts` lists. Deploy-only (ADR-0005): the user\n* builds their own runnable; `assemble` copies that built entry under `bundle/`\n* and adds the framework's boot wrapper — it never bundles or transforms the\n* app's code.\n*\n* The wrapper is a SEPARATE tsdown build of the service module (declarations\n* only, whose node carries run()/load()), emitted as `main.mjs` at the\n* working-dir root — a dictated name (object entry `{ main }`), not a\n* discovered one. run() and the app entry must be independent module instances\n* that hand off through process.env, so the wrapper is its own self-contained\n* build; `@prisma/*` is inlined, `bun` is a Compute built-in.\n*\n* Artifact layout: `<cwd>/.prisma-composer/artifacts/<address>/` (deploy-owned,\n* ADR-0005) holds `main.mjs` at the root and the app's entry under `bundle/`.\n* `entry` is file-relative to `dirname(build.module)` (ADR-0004).\n*/\nasync function assemble(input) {\n\tif (input.build.type !== \"node\") throw new Error(`@prisma/composer/node/control: expected a \"node\" build adapter, got \"${input.build.type}\".`);\n\tconst serviceModule = fileURLToPath(input.build.module);\n\tconst moduleDir = path.dirname(serviceModule);\n\tconst entryPath = path.resolve(moduleDir, input.build.entry);\n\tif (!fs.existsSync(entryPath)) throw new Error(`no built entry at ${entryPath} — run your build first (the build adapter's entry, \"${input.build.entry}\", resolves against dirname(module)).`);\n\tconst workDir = path.join(input.cwd, \".prisma-composer\", \"artifacts\", input.address);\n\tif (entryPath === workDir || entryPath.startsWith(workDir + path.sep)) throw new Error(`the build adapter's entry (\"${entryPath}\") resolves inside the deploy working dir (\"${workDir}\"), which is cleared on every assemble — point entry at your build output elsewhere.`);\n\tawait fs.promises.rm(workDir, {\n\t\trecursive: true,\n\t\tforce: true\n\t});\n\tawait fs.promises.mkdir(workDir, { recursive: true });\n\tawait build({\n\t\tentry: { main: serviceModule },\n\t\toutDir: workDir,\n\t\tformat: \"esm\",\n\t\tplatform: \"node\",\n\t\texternal: [\"bun\"],\n\t\tnoExternal: [/^@prisma\\//, ...input.wrapperNoExternal ?? []],\n\t\tdts: false,\n\t\tsourcemap: false,\n\t\tclean: false,\n\t\tconfig: false\n\t});\n\tif (!fs.existsSync(path.join(workDir, \"main.mjs\"))) throw new Error(`tsdown produced no main.mjs in ${workDir}`);\n\tconst entryFile = path.basename(entryPath);\n\tconst bundleDir = path.join(workDir, \"bundle\");\n\tawait fs.promises.mkdir(bundleDir, { recursive: true });\n\tawait fs.promises.copyFile(entryPath, path.join(bundleDir, entryFile));\n\treturn {\n\t\tdir: workDir,\n\t\tentry: path.posix.join(\"bundle\", entryFile)\n\t};\n}\n/** The node build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */\nconst nodeBuild = () => ({\n\tid: \"@prisma/composer/node\",\n\tnodes: { node: {\n\t\tkind: \"build\",\n\t\tassemble\n\t} }\n});\n//#endregion\nexport { assemble, nodeBuild };\n\n//# sourceMappingURL=control.mjs.map"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,eAAe,SAAS,OAAO;CAC9B,IAAI,MAAM,MAAM,SAAS,QAAQ,MAAM,IAAI,MAAM,wEAAwE,MAAM,MAAM,KAAK,GAAG;CAC7I,MAAM,gBAAgB,cAAc,MAAM,MAAM,MAAM;CACtD,MAAM,YAAY,KAAK,QAAQ,aAAa;CAC5C,MAAM,YAAY,KAAK,QAAQ,WAAW,MAAM,MAAM,KAAK;CAC3D,IAAI,CAAC,GAAG,WAAW,SAAS,GAAG,MAAM,IAAI,MAAM,qBAAqB,UAAU,uDAAuD,MAAM,MAAM,MAAM,sCAAsC;CAC7L,MAAM,UAAU,KAAK,KAAK,MAAM,KAAK,oBAAoB,aAAa,MAAM,OAAO;CACnF,IAAI,cAAc,WAAW,UAAU,WAAW,UAAU,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,+BAA+B,UAAU,8CAA8C,QAAQ,qFAAqF;CAC3Q,MAAM,GAAG,SAAS,GAAG,SAAS;EAC7B,WAAW;EACX,OAAO;CACR,CAAC;CACD,MAAM,GAAG,SAAS,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CACpD,MAAM,MAAM;EACX,OAAO,EAAE,MAAM,cAAc;EAC7B,QAAQ;EACR,QAAQ;EACR,UAAU;EACV,UAAU,CAAC,KAAK;EAChB,YAAY,CAAC,cAAc,GAAG,MAAM,qBAAqB,CAAC,CAAC;EAC3D,KAAK;EACL,WAAW;EACX,OAAO;EACP,QAAQ;CACT,CAAC;CACD,IAAI,CAAC,GAAG,WAAW,KAAK,KAAK,SAAS,UAAU,CAAC,GAAG,MAAM,IAAI,MAAM,kCAAkC,SAAS;CAC/G,MAAM,YAAY,KAAK,SAAS,SAAS;CACzC,MAAM,YAAY,KAAK,KAAK,SAAS,QAAQ;CAC7C,MAAM,GAAG,SAAS,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;CACtD,MAAM,GAAG,SAAS,SAAS,WAAW,KAAK,KAAK,WAAW,SAAS,CAAC;CACrE,OAAO;EACN,KAAK;EACL,OAAO,KAAK,MAAM,KAAK,UAAU,SAAS;CAC3C;AACD;;AAEA,MAAM,mBAAmB;CACxB,IAAI;CACJ,OAAO,EAAE,MAAM;EACd,MAAM;EACN;CACD,EAAE;AACH"}
1
+ {"version":3,"file":"node-control.mjs","names":[],"sources":["../../../0-framework/2-authoring/node/dist/control.mjs"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { build } from \"esbuild\";\n//#region src/control/build.ts\n/**\n* The extension's control entry (ADR-0017): `nodeBuild()` returns the build\n* descriptor `prisma-composer.config.ts` lists. Deploy-only (ADR-0005): the user\n* builds their own runnable; `assemble` copies what they built under `bundle/`\n* and adds the framework's boot wrapper — it never bundles or transforms the\n* app's code.\n*\n* Two forms, chosen by the descriptor: without `dir`, `entry` is a single\n* self-contained file and only that file is copied. With `dir`, the whole\n* directory is copied verbatim and `entry` names the file inside it that boots.\n* Neither form discovers anything — no tree-walking for an entry, no filename\n* heuristics; the author states the paths and we copy exactly those.\n*\n* The wrapper is a SEPARATE esbuild build of the service module (declarations\n* only, whose node carries run()/load()), emitted as `main.mjs` at the\n* working-dir root — a dictated name (object entry `{ main }`), not a\n* discovered one. run() and the app entry must be independent module instances\n* that hand off through process.env, so the wrapper is its own self-contained\n* build; `@prisma/*` is inlined, `bun` is a Compute built-in.\n*\n* Artifact layout: `<cwd>/.prisma-composer/artifacts/<address>/` (deploy-owned,\n* ADR-0005) holds `main.mjs` at the root and the app's built runnable under\n* `bundle/`.\n*/\n/** Narrows the shared BuildAdapter to this extension's own descriptor — the value-level mirror of the registry routing on (extension, type). `dir` is optional: absent is the single-file form. */\nfunction isNodeBuild(descriptor) {\n\treturn descriptor.type === \"node\" && (!(\"dir\" in descriptor) || typeof descriptor.dir === \"string\");\n}\n/** The single-file form: `entry` is the whole built runnable, resolved against dirname(module) (ADR-0004). */\nfunction resolveFile(entrySpec, moduleDir) {\n\tconst entryPath = path.resolve(moduleDir, entrySpec);\n\tif (!fs.existsSync(entryPath)) throw new Error(`no built entry at ${entryPath} — run your build first (the build adapter's entry, \"${entrySpec}\", resolves against dirname(module)).`);\n\tconst entryFile = path.basename(entryPath);\n\treturn {\n\t\tsource: entryPath,\n\t\tsourceField: \"entry\",\n\t\tentry: entryFile,\n\t\tcopyInto: async (bundleDir) => {\n\t\t\tawait fs.promises.mkdir(bundleDir, { recursive: true });\n\t\t\tawait fs.promises.copyFile(entryPath, path.join(bundleDir, entryFile));\n\t\t}\n\t};\n}\n/** The shared \"dir contains symlinks\" error, reused by both the root-is-a-symlink case and the nested-symlink walk below — one message shape, never two to drift apart. */\nfunction symlinksFoundError(dirPath, found) {\n\tconst listed = found.slice(0, 5).join(\", \");\n\treturn /* @__PURE__ */ new Error(`the build adapter's dir (\"${dirPath}\") contains symlinks, which the platform's packager rejects: ${listed}${found.length > 5 ? `, and ${found.length - 5} more` : \"\"}. The tree is copied verbatim, so make your build emit real files in dir (for example, a hoisted node_modules, or dereference the links into dir with cp -RL).`);\n}\n/**\n* Compute's packager rejects symlinks, so a tree containing one cannot deploy.\n* We fail here, naming the links, rather than dereferencing them on the copy:\n* the artifact must be what the author's build produced (ADR-0005), and\n* following a link that points outside `dir` would pull in files the author\n* never named. The walk reads dirents (lstat semantics), so a symlinked\n* directory is reported and never descended into. Checks only `dirPath`'s\n* children — the caller (`resolveDir`) checks `dirPath` itself before this\n* runs, since that check also decides \"not a directory\" vs \"is a symlink\"\n* and must happen before any dereferencing stat.\n*/\nasync function assertNoSymlinks(dirPath) {\n\tconst found = [];\n\tconst walk = async (current) => {\n\t\tfor (const entry of await fs.promises.readdir(current, { withFileTypes: true })) {\n\t\t\tconst full = path.join(current, entry.name);\n\t\t\tif (entry.isSymbolicLink()) found.push(full);\n\t\t\telse if (entry.isDirectory()) await walk(full);\n\t\t}\n\t};\n\tawait walk(dirPath);\n\tif (found.length > 0) throw symlinksFoundError(dirPath, found);\n}\n/**\n* The directory form: `dir` is the built tree, resolved against dirname(module)\n* (ADR-0004) and copied whole; `entry` resolves inside `dir` and names the file\n* that boots. An `entry` that resolves outside `dir` is rejected rather than\n* followed — only `dir` is ever copied.\n*\n* `dir` itself can be a symlink — not just something inside it. `lstat` it\n* before anything else so that case hard-errors identically whether the link\n* points at a real directory (which a dereferencing `stat` would otherwise\n* accept as \"is a directory\") or at a file: neither is ever silently\n* dereferenced and copied (ADR-0005).\n*/\nasync function resolveDir(dirSpec, entrySpec, moduleDir) {\n\tconst dirPath = path.resolve(moduleDir, dirSpec);\n\tlet dirLstat;\n\ttry {\n\t\tdirLstat = await fs.promises.lstat(dirPath);\n\t} catch {\n\t\tthrow new Error(`no built directory at ${dirPath} — run your build first (the build adapter's dir, \"${dirSpec}\", resolves against dirname(module)).`);\n\t}\n\tif (dirLstat.isSymbolicLink()) throw symlinksFoundError(dirPath, [dirPath]);\n\tif (!dirLstat.isDirectory()) throw new Error(`the build adapter's dir (\"${dirPath}\") is not a directory — drop dir to deploy a single built file, naming it as entry.`);\n\tconst entryPath = path.resolve(dirPath, entrySpec);\n\tif (!entryPath.startsWith(dirPath + path.sep)) throw new Error(`the build adapter's entry (\"${entrySpec}\") resolves to ${entryPath}, which is not inside dir (\"${dirPath}\") — in the directory form entry names a file inside dir, and only dir is copied.`);\n\tif (!fs.existsSync(entryPath) || !fs.statSync(entryPath).isFile()) throw new Error(`no built entry at ${entryPath} — run your build first (the build adapter's entry, \"${entrySpec}\", resolves inside dir, \"${dirPath}\").`);\n\tawait assertNoSymlinks(dirPath);\n\treturn {\n\t\tsource: dirPath,\n\t\tsourceField: \"dir\",\n\t\tentry: path.relative(dirPath, entryPath).split(path.sep).join(\"/\"),\n\t\tcopyInto: (bundleDir) => fs.promises.cp(dirPath, bundleDir, { recursive: true })\n\t};\n}\n/**\n* The working dir is cleared on every assemble, so it must not overlap the copy\n* source: inside it, the rm would delete the source before the copy; the other\n* way round, the copy would recurse into its own output.\n*/\nfunction assertOutsideWorkDir(runnable, workDir) {\n\tconst { source, sourceField } = runnable;\n\tif (source === workDir || source.startsWith(workDir + path.sep)) throw new Error(`the build adapter's ${sourceField} (\"${source}\") resolves inside the deploy working dir (\"${workDir}\"), which is cleared on every assemble — point ${sourceField} at your build output elsewhere.`);\n\tif (workDir.startsWith(source + path.sep)) throw new Error(`the deploy working dir (\"${workDir}\") sits inside the build adapter's ${sourceField} (\"${source}\"), so assembling would copy the artifact into itself — point ${sourceField} at your build output elsewhere.`);\n}\nasync function assemble(input) {\n\tif (!isNodeBuild(input.build)) throw new Error(`@prisma/composer/node/control: expected a \"node\" build adapter, got \"${input.build.type}\".`);\n\tconst buildDescriptor = input.build;\n\tconst serviceModule = fileURLToPath(buildDescriptor.module);\n\tconst moduleDir = path.dirname(serviceModule);\n\tconst runnable = buildDescriptor.dir === void 0 ? resolveFile(buildDescriptor.entry, moduleDir) : await resolveDir(buildDescriptor.dir, buildDescriptor.entry, moduleDir);\n\tconst workDir = path.join(input.cwd, \".prisma-composer\", \"artifacts\", input.address);\n\tassertOutsideWorkDir(runnable, workDir);\n\tawait fs.promises.rm(workDir, {\n\t\trecursive: true,\n\t\tforce: true\n\t});\n\tawait fs.promises.mkdir(workDir, { recursive: true });\n\tawait build({\n\t\tentryPoints: { main: serviceModule },\n\t\toutdir: workDir,\n\t\tbundle: true,\n\t\tformat: \"esm\",\n\t\tplatform: \"node\",\n\t\texternal: [\"bun\", \"bun:*\"],\n\t\toutExtension: { \".js\": \".mjs\" }\n\t});\n\tif (!fs.existsSync(path.join(workDir, \"main.mjs\"))) throw new Error(`esbuild produced no main.mjs in ${workDir}`);\n\tawait runnable.copyInto(path.join(workDir, \"bundle\"));\n\treturn {\n\t\tdir: workDir,\n\t\tentry: path.posix.join(\"bundle\", runnable.entry),\n\t\twatch: [runnable.source]\n\t};\n}\n/** The node build extension descriptor — `prisma-composer.config.ts` lists it under `extensions`. */\nconst nodeBuild = () => ({\n\tid: \"@prisma/composer/node\",\n\tnodes: { node: {\n\t\tkind: \"build\",\n\t\tassemble\n\t} }\n});\n//#endregion\nexport { assemble, nodeBuild };\n\n//# sourceMappingURL=control.mjs.map"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAS,YAAY,YAAY;CAChC,OAAO,WAAW,SAAS,WAAW,EAAE,SAAS,eAAe,OAAO,WAAW,QAAQ;AAC3F;;AAEA,SAAS,YAAY,WAAW,WAAW;CAC1C,MAAM,YAAY,KAAK,QAAQ,WAAW,SAAS;CACnD,IAAI,CAAC,GAAG,WAAW,SAAS,GAAG,MAAM,IAAI,MAAM,qBAAqB,UAAU,uDAAuD,UAAU,sCAAsC;CACrL,MAAM,YAAY,KAAK,SAAS,SAAS;CACzC,OAAO;EACN,QAAQ;EACR,aAAa;EACb,OAAO;EACP,UAAU,OAAO,cAAc;GAC9B,MAAM,GAAG,SAAS,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,GAAG,SAAS,SAAS,WAAW,KAAK,KAAK,WAAW,SAAS,CAAC;EACtE;CACD;AACD;;AAEA,SAAS,mBAAmB,SAAS,OAAO;CAC3C,MAAM,SAAS,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;CAC1C,uBAAuB,IAAI,MAAM,6BAA6B,QAAQ,+DAA+D,SAAS,MAAM,SAAS,IAAI,SAAS,MAAM,SAAS,EAAE,SAAS,GAAG,+JAA+J;AACvW;;;;;;;;;;;;AAYA,eAAe,iBAAiB,SAAS;CACxC,MAAM,QAAQ,CAAC;CACf,MAAM,OAAO,OAAO,YAAY;EAC/B,KAAK,MAAM,SAAS,MAAM,GAAG,SAAS,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC,GAAG;GAChF,MAAM,OAAO,KAAK,KAAK,SAAS,MAAM,IAAI;GAC1C,IAAI,MAAM,eAAe,GAAG,MAAM,KAAK,IAAI;QACtC,IAAI,MAAM,YAAY,GAAG,MAAM,KAAK,IAAI;EAC9C;CACD;CACA,MAAM,KAAK,OAAO;CAClB,IAAI,MAAM,SAAS,GAAG,MAAM,mBAAmB,SAAS,KAAK;AAC9D;;;;;;;;;;;;;AAaA,eAAe,WAAW,SAAS,WAAW,WAAW;CACxD,MAAM,UAAU,KAAK,QAAQ,WAAW,OAAO;CAC/C,IAAI;CACJ,IAAI;EACH,WAAW,MAAM,GAAG,SAAS,MAAM,OAAO;CAC3C,QAAQ;EACP,MAAM,IAAI,MAAM,yBAAyB,QAAQ,qDAAqD,QAAQ,sCAAsC;CACrJ;CACA,IAAI,SAAS,eAAe,GAAG,MAAM,mBAAmB,SAAS,CAAC,OAAO,CAAC;CAC1E,IAAI,CAAC,SAAS,YAAY,GAAG,MAAM,IAAI,MAAM,6BAA6B,QAAQ,oFAAoF;CACtK,MAAM,YAAY,KAAK,QAAQ,SAAS,SAAS;CACjD,IAAI,CAAC,UAAU,WAAW,UAAU,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,+BAA+B,UAAU,iBAAiB,UAAU,8BAA8B,QAAQ,kFAAkF;CAC3P,IAAI,CAAC,GAAG,WAAW,SAAS,KAAK,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC,OAAO,GAAG,MAAM,IAAI,MAAM,qBAAqB,UAAU,uDAAuD,UAAU,2BAA2B,QAAQ,IAAI;CAC1N,MAAM,iBAAiB,OAAO;CAC9B,OAAO;EACN,QAAQ;EACR,aAAa;EACb,OAAO,KAAK,SAAS,SAAS,SAAS,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG;EACjE,WAAW,cAAc,GAAG,SAAS,GAAG,SAAS,WAAW,EAAE,WAAW,KAAK,CAAC;CAChF;AACD;;;;;;AAMA,SAAS,qBAAqB,UAAU,SAAS;CAChD,MAAM,EAAE,QAAQ,gBAAgB;CAChC,IAAI,WAAW,WAAW,OAAO,WAAW,UAAU,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,uBAAuB,YAAY,KAAK,OAAO,8CAA8C,QAAQ,iDAAiD,YAAY,iCAAiC;CACpR,IAAI,QAAQ,WAAW,SAAS,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,4BAA4B,QAAQ,qCAAqC,YAAY,KAAK,OAAO,gEAAgE,YAAY,iCAAiC;AAC1Q;AACA,eAAe,SAAS,OAAO;CAC9B,IAAI,CAAC,YAAY,MAAM,KAAK,GAAG,MAAM,IAAI,MAAM,wEAAwE,MAAM,MAAM,KAAK,GAAG;CAC3I,MAAM,kBAAkB,MAAM;CAC9B,MAAM,gBAAgB,cAAc,gBAAgB,MAAM;CAC1D,MAAM,YAAY,KAAK,QAAQ,aAAa;CAC5C,MAAM,WAAW,gBAAgB,QAAQ,KAAK,IAAI,YAAY,gBAAgB,OAAO,SAAS,IAAI,MAAM,WAAW,gBAAgB,KAAK,gBAAgB,OAAO,SAAS;CACxK,MAAM,UAAU,KAAK,KAAK,MAAM,KAAK,oBAAoB,aAAa,MAAM,OAAO;CACnF,qBAAqB,UAAU,OAAO;CACtC,MAAM,GAAG,SAAS,GAAG,SAAS;EAC7B,WAAW;EACX,OAAO;CACR,CAAC;CACD,MAAM,GAAG,SAAS,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CACpD,MAAM,MAAM;EACX,aAAa,EAAE,MAAM,cAAc;EACnC,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,UAAU;EACV,UAAU,CAAC,OAAO,OAAO;EACzB,cAAc,EAAE,OAAO,OAAO;CAC/B,CAAC;CACD,IAAI,CAAC,GAAG,WAAW,KAAK,KAAK,SAAS,UAAU,CAAC,GAAG,MAAM,IAAI,MAAM,mCAAmC,SAAS;CAChH,MAAM,SAAS,SAAS,KAAK,KAAK,SAAS,QAAQ,CAAC;CACpD,OAAO;EACN,KAAK;EACL,OAAO,KAAK,MAAM,KAAK,UAAU,SAAS,KAAK;EAC/C,OAAO,CAAC,SAAS,MAAM;CACxB;AACD;;AAEA,MAAM,mBAAmB;CACxB,IAAI;CACJ,OAAO,EAAE,MAAM;EACd,MAAM;EACN;CACD,EAAE;AACH"}
package/dist/node.d.mts CHANGED
@@ -1,10 +1,23 @@
1
- import { t as BuildAdapter } from "./config-ob5OhCSP-sP3GW3uu.mjs";
1
+ import { t as BuildAdapter } from "./graph-types-BcbVhojU-C3fhxjPK.mjs";
2
+ import "./index-BFBNz7Aw.mjs";
2
3
  //#region ../../0-framework/2-authoring/node/dist/index.d.mts
3
- //#region src/index.d.ts
4
- declare const nodeBuild: (opts: {
4
+ //#region src/node.d.ts
5
+ /** The node build adapter's descriptor. `dir` is the directory form's own extra path input (the built tree to copy verbatim), beyond the shared `{ extension, type, module, entry }`; absent, `entry` is the whole built runnable. */
6
+ interface NodeBuildAdapter extends BuildAdapter {
7
+ readonly type: 'node';
8
+ readonly dir?: string;
9
+ }
10
+ /** The two forms an author may write. `dir?: never` on the single-file branch is what makes them exclusive: with `dir`, `entry` is required and names a file inside it. */
11
+ type NodeBuildOptions = {
5
12
  module: string;
6
13
  entry: string;
7
- }) => BuildAdapter; //#endregion
14
+ dir?: never;
15
+ } | {
16
+ module: string;
17
+ dir: string;
18
+ entry: string;
19
+ };
20
+ declare const nodeBuild: (opts: NodeBuildOptions) => NodeBuildAdapter;
8
21
  //#endregion
9
- export { nodeBuild as default };
22
+ export { type NodeBuildAdapter, nodeBuild as default };
10
23
  //# sourceMappingURL=node.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.mts","names":[],"sources":["../../../0-framework/2-authoring/node/dist/index.d.mts"],"mappings":";;;;;UAGU,yBAAyB;WACxB;WACA;;;KAGN;EACH;EACA;EACA;;EAEA;EACA;EACA;;cAEY,YAAY,MAAM,qBAAqB"}
package/dist/node.mjs CHANGED
@@ -3,7 +3,8 @@ const nodeBuild = (opts) => ({
3
3
  extension: "@prisma/composer/node",
4
4
  type: "node",
5
5
  module: opts.module,
6
- entry: opts.entry
6
+ entry: opts.entry,
7
+ ...opts.dir === void 0 ? {} : { dir: opts.dir }
7
8
  });
8
9
  //#endregion
9
10
  export { nodeBuild as default };
package/dist/node.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.mjs","names":[],"sources":["../../../0-framework/2-authoring/node/dist/index.mjs"],"sourcesContent":["//#region src/index.ts\nconst nodeBuild = (opts) => ({\n\textension: \"@prisma/composer/node\",\n\ttype: \"node\",\n\tmodule: opts.module,\n\tentry: opts.entry\n});\n//#endregion\nexport { nodeBuild as default };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":";AACA,MAAM,aAAa,UAAU;CAC5B,WAAW;CACX,MAAM;CACN,QAAQ,KAAK;CACb,OAAO,KAAK;AACb"}
1
+ {"version":3,"file":"node.mjs","names":[],"sources":["../../../0-framework/2-authoring/node/dist/index.mjs"],"sourcesContent":["//#region src/node.ts\nconst nodeBuild = (opts) => ({\n\textension: \"@prisma/composer/node\",\n\ttype: \"node\",\n\tmodule: opts.module,\n\tentry: opts.entry,\n\t...opts.dir === void 0 ? {} : { dir: opts.dir }\n});\n//#endregion\nexport { nodeBuild as default };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":";AACA,MAAM,aAAa,UAAU;CAC5B,WAAW;CACX,MAAM;CACN,QAAQ,KAAK;CACb,OAAO,KAAK;CACZ,GAAG,KAAK,QAAQ,KAAK,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI;AAC/C"}
@@ -0,0 +1,17 @@
1
+ import { u as DeploymentResult } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
+ import "./deploy-BP2DrIX_.mjs";
3
+ //#region ../../0-framework/3-tooling/cli/dist/report.d.mts
4
+ //#region src/render-deployment.d.ts
5
+ /**
6
+ * Renders a deploy's result as the app's own topology. Pure — returns the
7
+ * string; the caller prints.
8
+ */
9
+ declare function renderDeployment(result: DeploymentResult): string;
10
+ /**
11
+ * The report hook the generated stack file wires into `LowerOptions`. Prints a
12
+ * leading blank line so the summary separates from alchemy's own apply output.
13
+ */
14
+ declare function deploymentReport(result: DeploymentResult): void;
15
+ //#endregion
16
+ export { deploymentReport, renderDeployment };
17
+ //# sourceMappingURL=report.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.mts","names":[],"sources":["../../../0-framework/3-tooling/cli/dist/report.d.mts"],"mappings":";;;;;;;;iBAMiB,iBAAiB,QAAQ;;;;;iBAKzB,iBAAiB,QAAQ"}
@@ -0,0 +1,79 @@
1
+ //#region ../../0-framework/3-tooling/cli/dist/report.mjs
2
+ /** Gap between the deepest tree label and the entity column. */
3
+ const LABEL_GAP = 3;
4
+ const emptyNode = (segment) => ({
5
+ segment,
6
+ children: /* @__PURE__ */ new Map()
7
+ });
8
+ /** Builds the address tree, splitting each dot-address into its segments. */
9
+ function buildTree(nodes) {
10
+ const root = emptyNode("");
11
+ for (const deployed of nodes) {
12
+ let node = root;
13
+ for (const segment of deployed.address.split(".")) {
14
+ let child = node.children.get(segment);
15
+ if (child === void 0) {
16
+ child = emptyNode(segment);
17
+ node.children.set(segment, child);
18
+ }
19
+ node = child;
20
+ }
21
+ node.deployed = deployed;
22
+ }
23
+ return root;
24
+ }
25
+ /** Flattens the tree to rows in address order, drawing the box guides. */
26
+ function toRows(node, guides, rows) {
27
+ const children = Array.from(node.children.values());
28
+ children.forEach((child, index) => {
29
+ const isLast = index === children.length - 1;
30
+ rows.push({
31
+ label: `${guides}${isLast ? "└─ " : "├─ "}${child.segment}`,
32
+ continuation: `${guides}${isLast ? " " : "│ "}`,
33
+ deployed: child.deployed
34
+ });
35
+ toRows(child, `${guides}${isLast ? " " : "│ "}`, rows);
36
+ });
37
+ }
38
+ /** `kind id` — the one line an entity gets. */
39
+ const entityLine = (entity) => `${entity.kind} ${entity.id}`;
40
+ /** Pads `prefix` out to `width`, so every entity starts in the same column. */
41
+ const pad = (prefix, width) => prefix.padEnd(width, " ");
42
+ /**
43
+ * Renders a deploy's result as the app's own topology. Pure — returns the
44
+ * string; the caller prints.
45
+ */
46
+ function renderDeployment(result) {
47
+ const rows = [];
48
+ toRows(buildTree(result.nodes), "", rows);
49
+ const column = Math.max(0, ...rows.map((row) => row.label.length)) + LABEL_GAP;
50
+ const lines = [result.app];
51
+ for (const row of rows) {
52
+ if (row.deployed === void 0) {
53
+ lines.push(row.label);
54
+ continue;
55
+ }
56
+ if (row.deployed.entities.length === 0) {
57
+ lines.push(`${pad(row.label, column)}(no entities reported)`);
58
+ continue;
59
+ }
60
+ row.deployed.entities.forEach((entity, index) => {
61
+ const prefix = index === 0 ? row.label : row.continuation;
62
+ lines.push(`${pad(prefix, column)}${entityLine(entity)}`);
63
+ if (entity.url !== void 0) lines.push(`${pad(row.continuation, column)}${entity.url}`);
64
+ });
65
+ }
66
+ return lines.join("\n");
67
+ }
68
+ /**
69
+ * The report hook the generated stack file wires into `LowerOptions`. Prints a
70
+ * leading blank line so the summary separates from alchemy's own apply output.
71
+ */
72
+ function deploymentReport(result) {
73
+ console.log("");
74
+ console.log(renderDeployment(result));
75
+ }
76
+ //#endregion
77
+ export { deploymentReport, renderDeployment };
78
+
79
+ //# sourceMappingURL=report.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.mjs","names":[],"sources":["../../../0-framework/3-tooling/cli/dist/report.mjs"],"sourcesContent":["//#region src/render-deployment.ts\n/** Gap between the deepest tree label and the entity column. */\nconst LABEL_GAP = 3;\nconst emptyNode = (segment) => ({\n\tsegment,\n\tchildren: /* @__PURE__ */ new Map()\n});\n/** Builds the address tree, splitting each dot-address into its segments. */\nfunction buildTree(nodes) {\n\tconst root = emptyNode(\"\");\n\tfor (const deployed of nodes) {\n\t\tlet node = root;\n\t\tfor (const segment of deployed.address.split(\".\")) {\n\t\t\tlet child = node.children.get(segment);\n\t\t\tif (child === void 0) {\n\t\t\t\tchild = emptyNode(segment);\n\t\t\t\tnode.children.set(segment, child);\n\t\t\t}\n\t\t\tnode = child;\n\t\t}\n\t\tnode.deployed = deployed;\n\t}\n\treturn root;\n}\n/** Flattens the tree to rows in address order, drawing the box guides. */\nfunction toRows(node, guides, rows) {\n\tconst children = Array.from(node.children.values());\n\tchildren.forEach((child, index) => {\n\t\tconst isLast = index === children.length - 1;\n\t\trows.push({\n\t\t\tlabel: `${guides}${isLast ? \"└─ \" : \"├─ \"}${child.segment}`,\n\t\t\tcontinuation: `${guides}${isLast ? \" \" : \"│ \"}`,\n\t\t\tdeployed: child.deployed\n\t\t});\n\t\ttoRows(child, `${guides}${isLast ? \" \" : \"│ \"}`, rows);\n\t});\n}\n/** `kind id` — the one line an entity gets. */\nconst entityLine = (entity) => `${entity.kind} ${entity.id}`;\n/** Pads `prefix` out to `width`, so every entity starts in the same column. */\nconst pad = (prefix, width) => prefix.padEnd(width, \" \");\n/**\n* Renders a deploy's result as the app's own topology. Pure — returns the\n* string; the caller prints.\n*/\nfunction renderDeployment(result) {\n\tconst rows = [];\n\ttoRows(buildTree(result.nodes), \"\", rows);\n\tconst column = Math.max(0, ...rows.map((row) => row.label.length)) + LABEL_GAP;\n\tconst lines = [result.app];\n\tfor (const row of rows) {\n\t\tif (row.deployed === void 0) {\n\t\t\tlines.push(row.label);\n\t\t\tcontinue;\n\t\t}\n\t\tif (row.deployed.entities.length === 0) {\n\t\t\tlines.push(`${pad(row.label, column)}(no entities reported)`);\n\t\t\tcontinue;\n\t\t}\n\t\trow.deployed.entities.forEach((entity, index) => {\n\t\t\tconst prefix = index === 0 ? row.label : row.continuation;\n\t\t\tlines.push(`${pad(prefix, column)}${entityLine(entity)}`);\n\t\t\tif (entity.url !== void 0) lines.push(`${pad(row.continuation, column)}${entity.url}`);\n\t\t});\n\t}\n\treturn lines.join(\"\\n\");\n}\n/**\n* The report hook the generated stack file wires into `LowerOptions`. Prints a\n* leading blank line so the summary separates from alchemy's own apply output.\n*/\nfunction deploymentReport(result) {\n\tconsole.log(\"\");\n\tconsole.log(renderDeployment(result));\n}\n//#endregion\nexport { deploymentReport, renderDeployment };\n\n//# sourceMappingURL=report.mjs.map"],"mappings":";;AAEA,MAAM,YAAY;AAClB,MAAM,aAAa,aAAa;CAC/B;CACA,0BAA0B,IAAI,IAAI;AACnC;;AAEA,SAAS,UAAU,OAAO;CACzB,MAAM,OAAO,UAAU,EAAE;CACzB,KAAK,MAAM,YAAY,OAAO;EAC7B,IAAI,OAAO;EACX,KAAK,MAAM,WAAW,SAAS,QAAQ,MAAM,GAAG,GAAG;GAClD,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO;GACrC,IAAI,UAAU,KAAK,GAAG;IACrB,QAAQ,UAAU,OAAO;IACzB,KAAK,SAAS,IAAI,SAAS,KAAK;GACjC;GACA,OAAO;EACR;EACA,KAAK,WAAW;CACjB;CACA,OAAO;AACR;;AAEA,SAAS,OAAO,MAAM,QAAQ,MAAM;CACnC,MAAM,WAAW,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;CAClD,SAAS,SAAS,OAAO,UAAU;EAClC,MAAM,SAAS,UAAU,SAAS,SAAS;EAC3C,KAAK,KAAK;GACT,OAAO,GAAG,SAAS,SAAS,QAAQ,QAAQ,MAAM;GAClD,cAAc,GAAG,SAAS,SAAS,QAAQ;GAC3C,UAAU,MAAM;EACjB,CAAC;EACD,OAAO,OAAO,GAAG,SAAS,SAAS,QAAQ,SAAS,IAAI;CACzD,CAAC;AACF;;AAEA,MAAM,cAAc,WAAW,GAAG,OAAO,KAAK,GAAG,OAAO;;AAExD,MAAM,OAAO,QAAQ,UAAU,OAAO,OAAO,OAAO,GAAG;;;;;AAKvD,SAAS,iBAAiB,QAAQ;CACjC,MAAM,OAAO,CAAC;CACd,OAAO,UAAU,OAAO,KAAK,GAAG,IAAI,IAAI;CACxC,MAAM,SAAS,KAAK,IAAI,GAAG,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,MAAM,CAAC,IAAI;CACrE,MAAM,QAAQ,CAAC,OAAO,GAAG;CACzB,KAAK,MAAM,OAAO,MAAM;EACvB,IAAI,IAAI,aAAa,KAAK,GAAG;GAC5B,MAAM,KAAK,IAAI,KAAK;GACpB;EACD;EACA,IAAI,IAAI,SAAS,SAAS,WAAW,GAAG;GACvC,MAAM,KAAK,GAAG,IAAI,IAAI,OAAO,MAAM,EAAE,uBAAuB;GAC5D;EACD;EACA,IAAI,SAAS,SAAS,SAAS,QAAQ,UAAU;GAChD,MAAM,SAAS,UAAU,IAAI,IAAI,QAAQ,IAAI;GAC7C,MAAM,KAAK,GAAG,IAAI,QAAQ,MAAM,IAAI,WAAW,MAAM,GAAG;GACxD,IAAI,OAAO,QAAQ,KAAK,GAAG,MAAM,KAAK,GAAG,IAAI,IAAI,cAAc,MAAM,IAAI,OAAO,KAAK;EACtF,CAAC;CACF;CACA,OAAO,MAAM,KAAK,IAAI;AACvB;;;;;AAKA,SAAS,iBAAiB,QAAQ;CACjC,QAAQ,IAAI,EAAE;CACd,QAAQ,IAAI,iBAAiB,MAAM,CAAC;AACrC"}
@@ -0,0 +1,61 @@
1
+ import { A as ProvisionNeed, F as RunnableServiceNode, o as Contract, s as DependencyEnd } from "./graph-types-BcbVhojU-C3fhxjPK.mjs";
2
+ import "./index-BFBNz7Aw.mjs";
3
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
+ //#region ../../0-framework/2-authoring/service-rpc/dist/index.d.mts
5
+ //#region src/rpc.d.ts
6
+ /** ADR-0031's need brand for RPC's per-binding service key — the target registers a provisioner under this. */
7
+ declare const RPC_PEER_KEY: unique symbol;
8
+ /** The provisioning need `rpc()`'s `serviceKey` param declares (ADR-0030): a shared, unguessable value the target mints per consumer edge. */
9
+ declare const perBindingToken: () => ProvisionNeed;
10
+ /** The concrete function-map bound every RPC Contract's Cmp must fit. */
11
+ type RpcFns = Record<string, (input: any) => Promise<any>>;
12
+ declare function rpc<I extends StandardSchemaV1, O extends StandardSchemaV1>(m: {
13
+ input: I;
14
+ output: O;
15
+ }): (input: StandardSchemaV1.InferInput<I>) => Promise<StandardSchemaV1.InferOutput<O>>;
16
+ declare function rpc<C extends Contract<'rpc', RpcFns>>(contract: C): DependencyEnd<Client<C>, C>;
17
+ /** The typed client a consumer's `rpc(contract)` dependency hydrates to. */
18
+ type Client<C> = C extends Contract<string, infer Cmp> ? Cmp : never;
19
+ //#endregion
20
+ //#region src/client.d.ts
21
+ /**
22
+ * A fetch-shaped transport. Defaults to the real `fetch`; a served handler
23
+ * (`serve()`'s return value) works too — the binding does not have to be a
24
+ * network hop.
25
+ */
26
+ type Transport = (req: Request) => Promise<Response>;
27
+ declare function makeClient<C extends Contract<'rpc', RpcFns>>(contract: C, url: string, opts?: {
28
+ fetch?: Transport;
29
+ serviceKey?: string;
30
+ }): Client<C>;
31
+ //#endregion
32
+ //#region src/contract.d.ts
33
+ declare function contract<Fns extends Record<string, (input: any) => Promise<any>>>(fns: Fns): Contract<'rpc', Fns>;
34
+ //#endregion
35
+ //#region src/serve.d.ts
36
+ /** The reserved env var the target (slice 2) writes the accepted key set to. */
37
+ declare const RPC_ACCEPTED_KEYS_ENV = "COMPOSER_RPC_ACCEPTED_KEYS";
38
+ type AnyRunnable = RunnableServiceNode<any, any, any>;
39
+ type CmpOf<C> = C extends Contract<string, infer Cmp> ? Cmp : never;
40
+ /** A handler's optional third argument. Handlers may ignore it. */
41
+ interface RpcHandlerContext {
42
+ /** The call's idempotency key (same across its retries), or `undefined` for a keyless caller that opted out of dedup. */
43
+ readonly idempotencyKey: string | undefined;
44
+ }
45
+ type HandlerFor<Fn, LoadedDeps> = Fn extends ((input: infer I) => Promise<infer O>) ? (input: I, deps: LoadedDeps, ctx: RpcHandlerContext) => Promise<O> : never;
46
+ /** Every exposed port's methods, turned into a handler map typed off S's own `expose` and `load()`. */
47
+ type Handlers<S extends AnyRunnable> = { [Port in keyof NonNullable<S['expose']>]: { [M in keyof CmpOf<NonNullable<S['expose']>[Port]>]: HandlerFor<CmpOf<NonNullable<S['expose']>[Port]>[M], ReturnType<S['load']>>; }; };
48
+ /**
49
+ * Routes `POST /rpc/<method>`: checks the service key, requires an
50
+ * Idempotency-Key, single-flights/replays through `IdempotencyStore`, and —
51
+ * per call — parses JSON within the body cap, validates input, calls the
52
+ * handler with `service.load()`'s deps plus `{ idempotencyKey }`, validates
53
+ * the output, and responds JSON. A handler or output-validation failure
54
+ * masks its message behind a generic 500 and logs the real error; an
55
+ * unknown method or invalid input is a 4xx. `load()` is called exactly
56
+ * once, here, before the handler ever runs.
57
+ */
58
+ declare function serve<S extends AnyRunnable, H extends Handlers<S>>(service: S, handlers: H): (req: Request) => Promise<Response>;
59
+ //#endregion
60
+ export { type Client, type Handlers, RPC_ACCEPTED_KEYS_ENV, RPC_PEER_KEY, type RpcHandlerContext, type Transport, contract, makeClient, perBindingToken, rpc, serve };
61
+ //# sourceMappingURL=service-rpc.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-rpc.d.mts","names":[],"sources":["../../../0-framework/2-authoring/service-rpc/dist/index.d.mts"],"mappings":";;;;;;cAIc;;cAEA,uBAAuB;;KAEhC,SAAS,gBAAgB,eAAe;iBAC5B,IAAI,UAAU,kBAAkB,UAAU,kBAAkB;EAC3E,OAAO;EACP,QAAQ;KACL,OAAO,iBAAiB,WAAW,OAAO,QAAQ,iBAAiB,YAAY;iBACnE,IAAI,UAAU,gBAAgB,SAAS,UAAU,IAAI,cAAc,OAAO,IAAI;;KAE1F,OAAO,KAAK,UAAU,uBAAuB,OAAO;;;;;;;;KAQpD,aAAa,KAAK,YAAY,QAAQ;iBAC1B,WAAW,UAAU,gBAAgB,SAAS,UAAU,GAAG,aAAa;EACvF,QAAQ;EACR;IACE,OAAO;;;iBAGM,SAAS,YAAY,gBAAgB,eAAe,eAAe,KAAK,MAAM,gBAAgB;;;;cAIjG;KACT,cAAc;KACd,MAAM,KAAK,UAAU,uBAAuB,OAAO;;UAE9C;;WAEC;;KAEN,WAAW,IAAI,cAAc,aAAa,aAAa,MAAM,cAAc,OAAO,OAAO,GAAG,MAAM,YAAY,KAAK,sBAAsB,QAAQ;;KAEjJ,SAAS,UAAU,kBAAkB,cAAc,YAAY,kBAAkB,WAAW,MAAM,YAAY,aAAa,SAAS,WAAW,MAAM,YAAY,aAAa,OAAO,IAAI,WAAW;;;;;;;;;;;iBAWxL,MAAM,UAAU,aAAa,UAAU,SAAS,IAAI,SAAS,GAAG,UAAU,KAAK,KAAK,YAAY,QAAQ"}