@prisma/composer 0.1.0 → 0.2.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 (55) hide show
  1. package/dist/app-config-DJdU4ubR-BwioNK8j.d.mts +411 -0
  2. package/dist/assertions.d.mts +1 -1
  3. package/dist/bin.mjs +166 -256
  4. package/dist/bin.mjs.map +1 -1
  5. package/dist/casts.d.mts +1 -1
  6. package/dist/config-ByZICgry.d.mts +1 -0
  7. package/dist/config.d.mts +3 -2
  8. package/dist/config.mjs +2 -1
  9. package/dist/config.mjs.map +1 -1
  10. package/dist/container-transport-DKmKg5JQ-DKWs0ubK.mjs +45 -0
  11. package/dist/container-transport-DKmKg5JQ-DKWs0ubK.mjs.map +1 -0
  12. package/dist/deploy-ByZICgry.d.mts +1 -0
  13. package/dist/deploy.d.mts +3 -2
  14. package/dist/deploy.mjs +181 -23
  15. package/dist/deploy.mjs.map +1 -1
  16. package/dist/{dist-zBU8ASQW.mjs → dist-B0axxnBf.mjs} +16 -4
  17. package/dist/dist-B0axxnBf.mjs.map +1 -0
  18. package/dist/graph-B7NcPiOr-aSUOCGTH.d.mts +18 -0
  19. package/dist/{graph-BYdCQKya-BI0njTow.mjs → graph-BmrUEdo9-6Oq1hSmS.mjs} +102 -9
  20. package/dist/graph-BmrUEdo9-6Oq1hSmS.mjs.map +1 -0
  21. package/dist/{config-ob5OhCSP-sP3GW3uu.d.mts → graph-types-BgT9UEdm-Bz-_OcJH.d.mts} +205 -114
  22. package/dist/{index-CZSc9drz.d.mts → index-B2DJ5CN4.d.mts} +5 -20
  23. package/dist/index.d.mts +4 -3
  24. package/dist/index.mjs +3 -3
  25. package/dist/{index-Dh4Zro0y.d.mts → nextjs-DLyeRR7M-B9ukbB2L.d.mts} +6 -5
  26. package/dist/nextjs-control.d.mts +6 -5
  27. package/dist/nextjs-control.mjs +7 -10
  28. package/dist/nextjs-control.mjs.map +1 -1
  29. package/dist/nextjs.d.mts +2 -2
  30. package/dist/nextjs.mjs.map +1 -1
  31. package/dist/node-control.d.mts +5 -3
  32. package/dist/node-control.mjs +96 -24
  33. package/dist/node-control.mjs.map +1 -1
  34. package/dist/node.d.mts +18 -5
  35. package/dist/node.mjs +2 -1
  36. package/dist/node.mjs.map +1 -1
  37. package/dist/report.d.mts +17 -0
  38. package/dist/report.mjs +79 -0
  39. package/dist/report.mjs.map +1 -0
  40. package/dist/service-rpc.d.mts +61 -0
  41. package/dist/service-rpc.mjs +353 -0
  42. package/dist/service-rpc.mjs.map +1 -0
  43. package/dist/testing.d.mts +2 -3
  44. package/package.json +18 -17
  45. package/dist/app-config-BUqyK6N6-CVq3uvHF.d.mts +0 -188
  46. package/dist/config-BVVgDSdq.d.mts +0 -1
  47. package/dist/deploy-BVVgDSdq.d.mts +0 -1
  48. package/dist/dist-zBU8ASQW.mjs.map +0 -1
  49. package/dist/graph-BYdCQKya-BI0njTow.mjs.map +0 -1
  50. package/dist/rpc.d.mts +0 -43
  51. package/dist/rpc.mjs +0 -132
  52. package/dist/rpc.mjs.map +0 -1
  53. package/dist/tsdown.d.mts +0 -9
  54. package/dist/tsdown.mjs +0 -35
  55. package/dist/tsdown.mjs.map +0 -1
@@ -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};\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAS,cAAc,YAAY;CAClC,OAAO,WAAW,SAAS,YAAY,YAAY,cAAc,OAAO,WAAW,WAAW;AAC/F;;;;;;;;;AASA,SAAS,WAAW,QAAQ;CAC3B,MAAM,eAAe,KAAK,KAAK,QAAQ,SAAS,4BAA4B;CAC5E,IAAI,CAAC,GAAG,WAAW,YAAY,GAAG,MAAM,IAAI,MAAM,MAAM,KAAK,KAAK,SAAS,4BAA4B,EAAE,SAAS,OAAO,uDAAuD;CAChL,MAAM,WAAW,KAAK,MAAM,GAAG,aAAa,cAAc,MAAM,CAAC;CACjE,MAAM,iBAAiB,UAAU;CACjC,MAAM,cAAc,UAAU,QAAQ;CACtC,MAAM,WAAW,OAAO,mBAAmB,WAAW,iBAAiB,OAAO,gBAAgB,WAAW,KAAK,SAAS,aAAa,MAAM,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK;CAC7K,IAAI,aAAa,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,aAAa,uGAAuG;CAChK,OAAO,SAAS,MAAM,GAAG,CAAC,CAAC,KAAK,KAAK,GAAG;AACzC;;AAEA,SAAS,qBAAqB,OAAO;CACpC,MAAM,SAAS,KAAK,QAAQ,KAAK,QAAQ,cAAc,MAAM,MAAM,CAAC,GAAG,MAAM,MAAM;CACnF,OAAO,KAAK,KAAK,QAAQ,SAAS,cAAc,WAAW,MAAM,GAAG,WAAW;AAChF;AACA,eAAe,SAAS,OAAO;CAC9B,IAAI,CAAC,cAAc,MAAM,KAAK,GAAG,MAAM,IAAI,MAAM,0FAA0F,MAAM,MAAM,KAAK,GAAG;CAC/J,MAAM,kBAAkB,MAAM;CAC9B,MAAM,SAAS,KAAK,QAAQ,KAAK,QAAQ,cAAc,gBAAgB,MAAM,CAAC,GAAG,gBAAgB,MAAM;CACvG,MAAM,iBAAiB,KAAK,KAAK,QAAQ,SAAS,YAAY;CAC9D,IAAI,CAAC,GAAG,WAAW,cAAc,GAAG,MAAM,IAAI,MAAM,MAAM,KAAK,KAAK,SAAS,YAAY,EAAE,SAAS,OAAO,uDAAuD;CAClK,MAAM,SAAS,WAAW,MAAM;CAChC,MAAM,UAAU,KAAK,KAAK,MAAM,KAAK,oBAAoB,aAAa,MAAM,OAAO;CACnF,MAAM,GAAG,SAAS,GAAG,SAAS;EAC7B,WAAW;EACX,OAAO;CACR,CAAC;CACD,MAAM,GAAG,SAAS,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CACpD,MAAM,YAAY,KAAK,KAAK,SAAS,QAAQ;CAC7C,MAAM,GAAG,SAAS,GAAG,gBAAgB,WAAW,EAAE,WAAW,KAAK,CAAC;CACnE,MAAM,SAAS,KAAK,KAAK,WAAW,MAAM;CAC1C,MAAM,YAAY,KAAK,KAAK,QAAQ,SAAS,QAAQ;CACrD,IAAI,GAAG,WAAW,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,KAAK,KAAK,QAAQ,SAAS,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;CACvH,MAAM,YAAY,KAAK,KAAK,QAAQ,QAAQ;CAC5C,IAAI,GAAG,WAAW,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,KAAK,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;CAC9G,MAAM,MAAM;EACX,aAAa,EAAE,MAAM,cAAc,gBAAgB,MAAM,EAAE;EAC3D,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,OAAO;EACN,KAAK;EACL,OAAO,KAAK,MAAM,KAAK,UAAU,OAAO,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,WAAW;CAC/E;AACD;;AAEA,MAAM,qBAAqB;CAC1B,IAAI;CACJ,OAAO,EAAE,QAAQ;EAChB,MAAM;EACN;CACD,EAAE;AACH"}
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-B9ukbB2L.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-DJdU4ubR-BwioNK8j.mjs";
2
+ import "./config-ByZICgry.mjs";
3
+ import "./deploy-ByZICgry.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
@@ -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,108 @@ 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/`.
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
+ /**
50
+ * The directory form: `dir` is the built tree, resolved against dirname(module)
51
+ * (ADR-0004) and copied whole; `entry` resolves inside `dir` and names the file
52
+ * that boots. An `entry` that resolves outside `dir` is rejected rather than
53
+ * followed — only `dir` is ever copied.
23
54
  */
55
+ async function resolveDir(dirSpec, entrySpec, moduleDir) {
56
+ const dirPath = path.resolve(moduleDir, dirSpec);
57
+ if (!fs.existsSync(dirPath)) throw new Error(`no built directory at ${dirPath} — run your build first (the build adapter's dir, "${dirSpec}", resolves against dirname(module)).`);
58
+ if (!fs.statSync(dirPath).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.`);
59
+ const entryPath = path.resolve(dirPath, entrySpec);
60
+ 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.`);
61
+ 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}").`);
62
+ await assertNoSymlinks(dirPath);
63
+ return {
64
+ source: dirPath,
65
+ sourceField: "dir",
66
+ entry: path.relative(dirPath, entryPath).split(path.sep).join("/"),
67
+ copyInto: (bundleDir) => fs.promises.cp(dirPath, bundleDir, { recursive: true })
68
+ };
69
+ }
70
+ /**
71
+ * Compute's packager rejects symlinks, so a tree containing one cannot deploy.
72
+ * We fail here, naming the links, rather than dereferencing them on the copy:
73
+ * the artifact must be what the author's build produced (ADR-0005), and
74
+ * following a link that points outside `dir` would pull in files the author
75
+ * never named. The walk reads dirents (lstat semantics), so a symlinked
76
+ * directory is reported and never descended into.
77
+ */
78
+ async function assertNoSymlinks(dirPath) {
79
+ const found = [];
80
+ const walk = async (current) => {
81
+ for (const entry of await fs.promises.readdir(current, { withFileTypes: true })) {
82
+ const full = path.join(current, entry.name);
83
+ if (entry.isSymbolicLink()) found.push(full);
84
+ else if (entry.isDirectory()) await walk(full);
85
+ }
86
+ };
87
+ await walk(dirPath);
88
+ if (found.length === 0) return;
89
+ const listed = found.slice(0, 5).join(", ");
90
+ throw 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).`);
91
+ }
92
+ /**
93
+ * The working dir is cleared on every assemble, so it must not overlap the copy
94
+ * source: inside it, the rm would delete the source before the copy; the other
95
+ * way round, the copy would recurse into its own output.
96
+ */
97
+ function assertOutsideWorkDir(runnable, workDir) {
98
+ const { source, sourceField } = runnable;
99
+ 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.`);
100
+ 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.`);
101
+ }
24
102
  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);
103
+ if (!isNodeBuild(input.build)) throw new Error(`@prisma/composer/node/control: expected a "node" build adapter, got "${input.build.type}".`);
104
+ const buildDescriptor = input.build;
105
+ const serviceModule = fileURLToPath(buildDescriptor.module);
27
106
  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)).`);
107
+ const runnable = buildDescriptor.dir === void 0 ? resolveFile(buildDescriptor.entry, moduleDir) : await resolveDir(buildDescriptor.dir, buildDescriptor.entry, moduleDir);
30
108
  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.`);
109
+ assertOutsideWorkDir(runnable, workDir);
32
110
  await fs.promises.rm(workDir, {
33
111
  recursive: true,
34
112
  force: true
35
113
  });
36
114
  await fs.promises.mkdir(workDir, { recursive: true });
37
115
  await build({
38
- entry: { main: serviceModule },
39
- outDir: workDir,
116
+ entryPoints: { main: serviceModule },
117
+ outdir: workDir,
118
+ bundle: true,
40
119
  format: "esm",
41
120
  platform: "node",
42
- external: ["bun"],
43
- noExternal: [/^@prisma\//, ...input.wrapperNoExternal ?? []],
44
- dts: false,
45
- sourcemap: false,
46
- clean: false,
47
- config: false
121
+ external: ["bun", "bun:*"],
122
+ outExtension: { ".js": ".mjs" }
48
123
  });
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));
124
+ if (!fs.existsSync(path.join(workDir, "main.mjs"))) throw new Error(`esbuild produced no main.mjs in ${workDir}`);
125
+ await runnable.copyInto(path.join(workDir, "bundle"));
54
126
  return {
55
127
  dir: workDir,
56
- entry: path.posix.join("bundle", entryFile)
128
+ entry: path.posix.join("bundle", runnable.entry)
57
129
  };
58
130
  }
59
131
  /** 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/**\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*/\nasync function resolveDir(dirSpec, entrySpec, moduleDir) {\n\tconst dirPath = path.resolve(moduleDir, dirSpec);\n\tif (!fs.existsSync(dirPath)) throw new Error(`no built directory at ${dirPath} — run your build first (the build adapter's dir, \"${dirSpec}\", resolves against dirname(module)).`);\n\tif (!fs.statSync(dirPath).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* 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.\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) return;\n\tconst listed = found.slice(0, 5).join(\", \");\n\tthrow 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* 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};\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":"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"}
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-BgT9UEdm-Bz-_OcJH.mjs";
2
+ import "./index-B2DJ5CN4.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
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-DJdU4ubR-BwioNK8j.mjs";
2
+ import "./deploy-ByZICgry.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,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 { P as RunnableServiceNode, k as ProvisionNeed, o as Contract, s as DependencyEnd } from "./graph-types-BgT9UEdm-Bz-_OcJH.mjs";
2
+ import "./index-B2DJ5CN4.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