@prisma-next/cli 0.3.0-pr.99.6 → 0.4.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +381 -128
  3. package/dist/agent-skill-mongo.md +106 -0
  4. package/dist/agent-skill-postgres.md +106 -0
  5. package/dist/cli-errors-BDCYR5ap.mjs +4 -0
  6. package/dist/cli-errors-DStABy9d.d.mts +3 -0
  7. package/dist/cli.d.mts +1 -0
  8. package/dist/cli.js +1 -2910
  9. package/dist/cli.mjs +254 -0
  10. package/dist/cli.mjs.map +1 -0
  11. package/dist/client-DiUkJAeN.mjs +987 -0
  12. package/dist/client-DiUkJAeN.mjs.map +1 -0
  13. package/dist/commands/contract-emit.d.mts +7 -0
  14. package/dist/commands/contract-emit.d.mts.map +1 -0
  15. package/dist/commands/contract-emit.mjs +4 -0
  16. package/dist/commands/contract-infer.d.mts +7 -0
  17. package/dist/commands/contract-infer.d.mts.map +1 -0
  18. package/dist/commands/contract-infer.mjs +4 -0
  19. package/dist/commands/db-init.d.mts +7 -0
  20. package/dist/commands/db-init.d.mts.map +1 -0
  21. package/dist/commands/db-init.mjs +125 -0
  22. package/dist/commands/db-init.mjs.map +1 -0
  23. package/dist/commands/db-schema.d.mts +7 -0
  24. package/dist/commands/db-schema.d.mts.map +1 -0
  25. package/dist/commands/db-schema.mjs +53 -0
  26. package/dist/commands/db-schema.mjs.map +1 -0
  27. package/dist/commands/db-sign.d.mts +7 -0
  28. package/dist/commands/db-sign.d.mts.map +1 -0
  29. package/dist/commands/db-sign.mjs +136 -0
  30. package/dist/commands/db-sign.mjs.map +1 -0
  31. package/dist/commands/db-update.d.mts +7 -0
  32. package/dist/commands/db-update.d.mts.map +1 -0
  33. package/dist/commands/db-update.mjs +122 -0
  34. package/dist/commands/db-update.mjs.map +1 -0
  35. package/dist/commands/db-verify.d.mts +7 -0
  36. package/dist/commands/db-verify.d.mts.map +1 -0
  37. package/dist/commands/db-verify.mjs +322 -0
  38. package/dist/commands/db-verify.mjs.map +1 -0
  39. package/dist/commands/migration-apply.d.mts +36 -0
  40. package/dist/commands/migration-apply.d.mts.map +1 -0
  41. package/dist/commands/migration-apply.mjs +244 -0
  42. package/dist/commands/migration-apply.mjs.map +1 -0
  43. package/dist/commands/migration-new.d.mts +8 -0
  44. package/dist/commands/migration-new.d.mts.map +1 -0
  45. package/dist/commands/migration-new.mjs +152 -0
  46. package/dist/commands/migration-new.mjs.map +1 -0
  47. package/dist/commands/migration-plan.d.mts +47 -0
  48. package/dist/commands/migration-plan.d.mts.map +1 -0
  49. package/dist/commands/migration-plan.mjs +313 -0
  50. package/dist/commands/migration-plan.mjs.map +1 -0
  51. package/dist/commands/migration-ref.d.mts +43 -0
  52. package/dist/commands/migration-ref.d.mts.map +1 -0
  53. package/dist/commands/migration-ref.mjs +195 -0
  54. package/dist/commands/migration-ref.mjs.map +1 -0
  55. package/dist/commands/migration-show.d.mts +28 -0
  56. package/dist/commands/migration-show.d.mts.map +1 -0
  57. package/dist/commands/migration-show.mjs +140 -0
  58. package/dist/commands/migration-show.mjs.map +1 -0
  59. package/dist/commands/migration-status.d.mts +86 -0
  60. package/dist/commands/migration-status.d.mts.map +1 -0
  61. package/dist/commands/migration-status.mjs +4 -0
  62. package/dist/commands/migration-verify.d.mts +16 -0
  63. package/dist/commands/migration-verify.d.mts.map +1 -0
  64. package/dist/commands/migration-verify.mjs +110 -0
  65. package/dist/commands/migration-verify.mjs.map +1 -0
  66. package/dist/config-loader-C4VXKl8f.mjs +43 -0
  67. package/dist/config-loader-C4VXKl8f.mjs.map +1 -0
  68. package/dist/{config-loader.d.ts → config-loader.d.mts} +8 -3
  69. package/dist/config-loader.d.mts.map +1 -0
  70. package/dist/config-loader.mjs +3 -0
  71. package/dist/contract-emit-D2wDXfyo.mjs +191 -0
  72. package/dist/contract-emit-D2wDXfyo.mjs.map +1 -0
  73. package/dist/contract-emit-D9WOShFz.mjs +4 -0
  74. package/dist/contract-emit-Zm_sd1wQ.mjs +112 -0
  75. package/dist/contract-emit-Zm_sd1wQ.mjs.map +1 -0
  76. package/dist/contract-enrichment-CGW6mm-E.mjs +79 -0
  77. package/dist/contract-enrichment-CGW6mm-E.mjs.map +1 -0
  78. package/dist/contract-infer-DozZT511.mjs +90 -0
  79. package/dist/contract-infer-DozZT511.mjs.map +1 -0
  80. package/dist/exports/config-types.d.mts +2 -0
  81. package/dist/exports/config-types.mjs +3 -0
  82. package/dist/exports/control-api.d.mts +624 -0
  83. package/dist/exports/control-api.d.mts.map +1 -0
  84. package/dist/exports/control-api.mjs +6 -0
  85. package/dist/{load-ts-contract.d.ts → exports/index.d.mts} +12 -7
  86. package/dist/exports/index.d.mts.map +1 -0
  87. package/dist/exports/index.mjs +137 -0
  88. package/dist/exports/index.mjs.map +1 -0
  89. package/dist/extract-operation-statements-DZUJNmL3.mjs +13 -0
  90. package/dist/extract-operation-statements-DZUJNmL3.mjs.map +1 -0
  91. package/dist/extract-sql-ddl-DDMX-9mz.mjs +26 -0
  92. package/dist/extract-sql-ddl-DDMX-9mz.mjs.map +1 -0
  93. package/dist/framework-components-BAsliT4V.mjs +59 -0
  94. package/dist/framework-components-BAsliT4V.mjs.map +1 -0
  95. package/dist/init-DQ8auNB4.mjs +430 -0
  96. package/dist/init-DQ8auNB4.mjs.map +1 -0
  97. package/dist/inspect-live-schema-BYnhztxZ.mjs +91 -0
  98. package/dist/inspect-live-schema-BYnhztxZ.mjs.map +1 -0
  99. package/dist/migration-command-scaffold-CntCcntR.mjs +105 -0
  100. package/dist/migration-command-scaffold-CntCcntR.mjs.map +1 -0
  101. package/dist/migration-status-CJANY4yr.mjs +1583 -0
  102. package/dist/migration-status-CJANY4yr.mjs.map +1 -0
  103. package/dist/migrations-DTZBYXm1.mjs +173 -0
  104. package/dist/migrations-DTZBYXm1.mjs.map +1 -0
  105. package/dist/progress-adapter-B-YvmcDu.mjs +43 -0
  106. package/dist/progress-adapter-B-YvmcDu.mjs.map +1 -0
  107. package/dist/quick-reference-mongo.md +93 -0
  108. package/dist/quick-reference-postgres.md +91 -0
  109. package/dist/result-handler-oK_vA-Fn.mjs +697 -0
  110. package/dist/result-handler-oK_vA-Fn.mjs.map +1 -0
  111. package/dist/terminal-ui-C5k88MmW.mjs +274 -0
  112. package/dist/terminal-ui-C5k88MmW.mjs.map +1 -0
  113. package/dist/validate-contract-deps-esa-VQ0h.mjs +37 -0
  114. package/dist/validate-contract-deps-esa-VQ0h.mjs.map +1 -0
  115. package/dist/verify-DlFQ2FOw.mjs +385 -0
  116. package/dist/verify-DlFQ2FOw.mjs.map +1 -0
  117. package/package.json +87 -40
  118. package/src/cli.ts +118 -58
  119. package/src/commands/contract-emit.ts +101 -78
  120. package/src/commands/contract-infer-paths.ts +32 -0
  121. package/src/commands/contract-infer.ts +143 -0
  122. package/src/commands/db-init.ts +97 -219
  123. package/src/commands/db-schema.ts +77 -0
  124. package/src/commands/db-sign.ts +46 -73
  125. package/src/commands/db-update.ts +236 -0
  126. package/src/commands/db-verify.ts +409 -119
  127. package/src/commands/init/detect-package-manager.ts +47 -0
  128. package/src/commands/init/index.ts +21 -0
  129. package/src/commands/init/init.ts +203 -0
  130. package/src/commands/init/templates/agent-skill-mongo.md +106 -0
  131. package/src/commands/init/templates/agent-skill-postgres.md +106 -0
  132. package/src/commands/init/templates/agent-skill.ts +19 -0
  133. package/src/commands/init/templates/code-templates.ts +168 -0
  134. package/src/commands/init/templates/quick-reference-mongo.md +93 -0
  135. package/src/commands/init/templates/quick-reference-postgres.md +91 -0
  136. package/src/commands/init/templates/quick-reference.ts +19 -0
  137. package/src/commands/init/templates/render.ts +20 -0
  138. package/src/commands/init/templates/tsconfig.ts +35 -0
  139. package/src/commands/inspect-live-schema.ts +170 -0
  140. package/src/commands/migration-apply.ts +427 -0
  141. package/src/commands/migration-new.ts +260 -0
  142. package/src/commands/migration-plan.ts +519 -0
  143. package/src/commands/migration-ref.ts +305 -0
  144. package/src/commands/migration-show.ts +246 -0
  145. package/src/commands/migration-status.ts +864 -0
  146. package/src/commands/migration-verify.ts +180 -0
  147. package/src/config-loader.ts +13 -3
  148. package/src/control-api/client.ts +205 -183
  149. package/src/control-api/contract-enrichment.ts +119 -0
  150. package/src/control-api/errors.ts +9 -0
  151. package/src/control-api/operations/contract-emit.ts +181 -0
  152. package/src/control-api/operations/db-init.ts +53 -49
  153. package/src/control-api/operations/db-update.ts +220 -0
  154. package/src/control-api/operations/extract-operation-statements.ts +14 -0
  155. package/src/control-api/operations/extract-sql-ddl.ts +47 -0
  156. package/src/control-api/operations/migration-apply.ts +191 -0
  157. package/src/control-api/operations/migration-helpers.ts +49 -0
  158. package/src/control-api/types.ts +274 -52
  159. package/src/exports/config-types.ts +4 -3
  160. package/src/exports/control-api.ts +15 -5
  161. package/src/load-ts-contract.ts +30 -19
  162. package/src/utils/cli-errors.ts +14 -8
  163. package/src/utils/command-helpers.ts +302 -3
  164. package/src/utils/formatters/emit.ts +67 -0
  165. package/src/utils/formatters/errors.ts +82 -0
  166. package/src/utils/formatters/graph-migration-mapper.ts +240 -0
  167. package/src/utils/formatters/graph-render.ts +1323 -0
  168. package/src/utils/formatters/graph-types.ts +120 -0
  169. package/src/utils/formatters/help.ts +380 -0
  170. package/src/utils/formatters/helpers.ts +28 -0
  171. package/src/utils/formatters/migrations.ts +346 -0
  172. package/src/utils/formatters/styled.ts +212 -0
  173. package/src/utils/formatters/verify.ts +621 -0
  174. package/src/utils/framework-components.ts +13 -10
  175. package/src/utils/global-flags.ts +41 -23
  176. package/src/utils/migration-command-scaffold.ts +184 -0
  177. package/src/utils/migration-types.ts +12 -0
  178. package/src/utils/progress-adapter.ts +18 -29
  179. package/src/utils/result-handler.ts +12 -13
  180. package/src/utils/shutdown.ts +92 -0
  181. package/src/utils/suggest-command.ts +31 -0
  182. package/src/utils/terminal-ui.ts +276 -0
  183. package/src/utils/validate-contract-deps.ts +49 -0
  184. package/dist/chunk-AGOTG4L3.js +0 -965
  185. package/dist/chunk-AGOTG4L3.js.map +0 -1
  186. package/dist/chunk-HLLI4YL7.js +0 -180
  187. package/dist/chunk-HLLI4YL7.js.map +0 -1
  188. package/dist/chunk-HWYQOCAJ.js +0 -47
  189. package/dist/chunk-HWYQOCAJ.js.map +0 -1
  190. package/dist/chunk-VG2R7DGF.js +0 -735
  191. package/dist/chunk-VG2R7DGF.js.map +0 -1
  192. package/dist/cli.d.ts +0 -2
  193. package/dist/cli.d.ts.map +0 -1
  194. package/dist/cli.js.map +0 -1
  195. package/dist/commands/contract-emit.d.ts +0 -3
  196. package/dist/commands/contract-emit.d.ts.map +0 -1
  197. package/dist/commands/contract-emit.js +0 -10
  198. package/dist/commands/contract-emit.js.map +0 -1
  199. package/dist/commands/db-init.d.ts +0 -3
  200. package/dist/commands/db-init.d.ts.map +0 -1
  201. package/dist/commands/db-init.js +0 -257
  202. package/dist/commands/db-init.js.map +0 -1
  203. package/dist/commands/db-introspect.d.ts +0 -3
  204. package/dist/commands/db-introspect.d.ts.map +0 -1
  205. package/dist/commands/db-introspect.js +0 -155
  206. package/dist/commands/db-introspect.js.map +0 -1
  207. package/dist/commands/db-schema-verify.d.ts +0 -3
  208. package/dist/commands/db-schema-verify.d.ts.map +0 -1
  209. package/dist/commands/db-schema-verify.js +0 -171
  210. package/dist/commands/db-schema-verify.js.map +0 -1
  211. package/dist/commands/db-sign.d.ts +0 -3
  212. package/dist/commands/db-sign.d.ts.map +0 -1
  213. package/dist/commands/db-sign.js +0 -195
  214. package/dist/commands/db-sign.js.map +0 -1
  215. package/dist/commands/db-verify.d.ts +0 -3
  216. package/dist/commands/db-verify.d.ts.map +0 -1
  217. package/dist/commands/db-verify.js +0 -193
  218. package/dist/commands/db-verify.js.map +0 -1
  219. package/dist/config-loader.d.ts.map +0 -1
  220. package/dist/config-loader.js +0 -7
  221. package/dist/config-loader.js.map +0 -1
  222. package/dist/control-api/client.d.ts +0 -13
  223. package/dist/control-api/client.d.ts.map +0 -1
  224. package/dist/control-api/operations/db-init.d.ts +0 -29
  225. package/dist/control-api/operations/db-init.d.ts.map +0 -1
  226. package/dist/control-api/types.d.ts +0 -387
  227. package/dist/control-api/types.d.ts.map +0 -1
  228. package/dist/exports/config-types.d.ts +0 -3
  229. package/dist/exports/config-types.d.ts.map +0 -1
  230. package/dist/exports/config-types.js +0 -6
  231. package/dist/exports/config-types.js.map +0 -1
  232. package/dist/exports/control-api.d.ts +0 -13
  233. package/dist/exports/control-api.d.ts.map +0 -1
  234. package/dist/exports/control-api.js +0 -7
  235. package/dist/exports/control-api.js.map +0 -1
  236. package/dist/exports/index.d.ts +0 -4
  237. package/dist/exports/index.d.ts.map +0 -1
  238. package/dist/exports/index.js +0 -176
  239. package/dist/exports/index.js.map +0 -1
  240. package/dist/load-ts-contract.d.ts.map +0 -1
  241. package/dist/utils/cli-errors.d.ts +0 -7
  242. package/dist/utils/cli-errors.d.ts.map +0 -1
  243. package/dist/utils/command-helpers.d.ts +0 -12
  244. package/dist/utils/command-helpers.d.ts.map +0 -1
  245. package/dist/utils/framework-components.d.ts +0 -70
  246. package/dist/utils/framework-components.d.ts.map +0 -1
  247. package/dist/utils/global-flags.d.ts +0 -25
  248. package/dist/utils/global-flags.d.ts.map +0 -1
  249. package/dist/utils/output.d.ts +0 -142
  250. package/dist/utils/output.d.ts.map +0 -1
  251. package/dist/utils/progress-adapter.d.ts +0 -26
  252. package/dist/utils/progress-adapter.d.ts.map +0 -1
  253. package/dist/utils/result-handler.d.ts +0 -15
  254. package/dist/utils/result-handler.d.ts.map +0 -1
  255. package/src/commands/db-introspect.ts +0 -227
  256. package/src/commands/db-schema-verify.ts +0 -238
  257. package/src/utils/output.ts +0 -1471
@@ -0,0 +1,93 @@
1
+ # Welcome to Prisma Next!
2
+
3
+ Prisma Next lets you query your database in simple, easy-to-read TypeScript. Define what your data looks like, and Prisma Next gives you a fully typed client — with autocomplete for every collection, field, and relation.
4
+
5
+ This project is set up for MongoDB. Prisma Next also supports other databases.
6
+
7
+ ## Your data contract
8
+
9
+ Your data contract is the heart of your application. It lives at [`{{schemaPath}}`]({{schemaPath}}) and describes your models:
10
+
11
+ ```prisma
12
+ model User {
13
+ id ObjectId @id @map("_id")
14
+ email String @unique
15
+ name String?
16
+ posts Post[]
17
+ @@map("users")
18
+ }
19
+ ```
20
+
21
+ Every model you define in your contract can be queried from your app. Your editor will autocomplete the query methods and show you what type each field is:
22
+
23
+ ```typescript
24
+ import { db } from '{{dbImportPath}}';
25
+
26
+ const client = await db.connect(process.env['DATABASE_URL']!, 'mydb');
27
+
28
+ const user = await client.orm.User
29
+ .where({ email: 'alice@example.com' })
30
+ .first();
31
+
32
+ // Your editor will show the type of user as
33
+ // { id: ObjectId; email: string; name: string | null; posts: Post[] } | null
34
+ ```
35
+
36
+ Your contract has two companion files in the same directory:
37
+
38
+ - **`contract.json`** — this tells your application what models exist, just like `package-lock.json` tells your package manager what dependencies your project has
39
+ - **`contract.d.ts`** — this powers autocomplete and type checking in your editor
40
+
41
+ Commit both files to git. When you change your contract, run `{{pkgRun}} contract emit` to update them.
42
+
43
+ If you use a framework like Next.js or Vite, the Prisma Next plugin will do this for you automatically.
44
+
45
+ ## Configuration
46
+
47
+ [`prisma-next.config.ts`](prisma-next.config.ts) tells the CLI where your contract lives and how to connect to your database. It loads environment variables from `.env` automatically:
48
+
49
+ ```typescript
50
+ import 'dotenv/config';
51
+ import { defineConfig } from '@prisma-next/mongo/config';
52
+
53
+ export default defineConfig({
54
+ contract: './{{schemaPath}}',
55
+ db: {
56
+ connection: process.env['DATABASE_URL']!,
57
+ },
58
+ });
59
+ ```
60
+
61
+ Notice the `DATABASE_URL` above? It's defined in your [`.env`](./.env) file:
62
+
63
+ ```env
64
+ DATABASE_URL="mongodb://localhost:27017/mydb"
65
+ ```
66
+
67
+ You can customize how your environment variables are loaded by changing or removing the `import 'dotenv/config'` line.
68
+
69
+ ## Quick reference
70
+
71
+ ### Commands
72
+
73
+ ```bash
74
+ {{pkgRun}} contract emit # Update contract.json and contract.d.ts
75
+ {{pkgRun}} db init # Create collections in the database
76
+ {{pkgRun}} migration status # Show migration status
77
+ ```
78
+
79
+ ### Files
80
+
81
+ | File | Purpose |
82
+ |---|---|
83
+ | [`{{schemaPath}}`]({{schemaPath}}) | Your data contract — define your models here |
84
+ | [`prisma-next.config.ts`](prisma-next.config.ts) | CLI configuration |
85
+ | [`{{schemaDir}}/db.ts`]({{schemaDir}}/db.ts) | Database client — `import { db } from '{{dbImportPath}}'` |
86
+ | `{{schemaDir}}/contract.json` | Compiled contract (generated) |
87
+ | `{{schemaDir}}/contract.d.ts` | Contract types (generated) |
88
+
89
+ ### Workflow
90
+
91
+ 1. Edit [`{{schemaPath}}`]({{schemaPath}}) to add or change models.
92
+ 2. Run `{{pkgRun}} contract emit` to regenerate the contract.
93
+ 3. Query your models — your IDE will autocomplete everything.
@@ -0,0 +1,91 @@
1
+ # Welcome to Prisma Next!
2
+
3
+ Prisma Next lets you query your database in simple, easy-to-read TypeScript. Define what your data looks like, and Prisma Next gives you a fully typed client — with autocomplete for every table, column, and relation.
4
+
5
+ This project is set up for PostgreSQL. Prisma Next also supports other databases.
6
+
7
+ ## Your data contract
8
+
9
+ Your data contract is the heart of your application. It lives at [`{{schemaPath}}`]({{schemaPath}}) and describes your models:
10
+
11
+ ```prisma
12
+ model User {
13
+ id Int @id @default(autoincrement())
14
+ email String @unique
15
+ name String?
16
+ posts Post[]
17
+ createdAt DateTime @default(now())
18
+ }
19
+ ```
20
+
21
+ Every model you define in your contract can be queried from your app. Your editor will autocomplete the query methods and show you what type each model field is:
22
+
23
+ ```typescript
24
+ import { db } from '{{dbImportPath}}';
25
+
26
+ const user = await db.orm.User
27
+ .where({ email: 'alice@example.com' })
28
+ .first();
29
+
30
+ // Your editor will show the type of user as
31
+ // { id: number; email: string; createdAt: Date, name: string, posts: Post[] } | null
32
+ ```
33
+
34
+ Your contract has two companion files in the same directory:
35
+
36
+ - **`contract.json`** — this tells your application what models exist, just like `package-lock.json` tells your package manager what dependencies your project has
37
+ - **`contract.d.ts`** — this powers autocomplete and type checking in your editor
38
+
39
+ Commit both files to git. When you change your contract, run `{{pkgRun}} contract emit` to update them.
40
+
41
+ If you use a framework like Next.js or Vite, the Prisma Next plugin will do this for you automatically.
42
+
43
+ ## Configuration
44
+
45
+ [`prisma-next.config.ts`](prisma-next.config.ts) tells the CLI where your contract lives and how to connect to your database. It loads environment variables from `.env` automatically:
46
+
47
+ ```typescript
48
+ import 'dotenv/config';
49
+ import { defineConfig } from '@prisma-next/postgres/config';
50
+
51
+ export default defineConfig({
52
+ contract: './{{schemaPath}}',
53
+ db: {
54
+ connection: process.env['DATABASE_URL']!,
55
+ },
56
+ });
57
+ ```
58
+
59
+ Notice the `DATABASE_URL` above? It's defined in your [`.env`](./.env) file:
60
+
61
+ ```env
62
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
63
+ ```
64
+
65
+ You can customize how your environment variables are loaded by changing or removing the `import 'dotenv/config'` line.
66
+
67
+ ## Quick reference
68
+
69
+ ### Commands
70
+
71
+ ```bash
72
+ {{pkgRun}} contract emit # Update contract.json and contract.d.ts
73
+ {{pkgRun}} db init # Create tables in the database
74
+ {{pkgRun}} migration status # Show migration status
75
+ ```
76
+
77
+ ### Files
78
+
79
+ | File | Purpose |
80
+ |---|---|
81
+ | [`{{schemaPath}}`]({{schemaPath}}) | Your data contract — define your models here |
82
+ | [`prisma-next.config.ts`](prisma-next.config.ts) | CLI configuration |
83
+ | [`{{schemaDir}}/db.ts`]({{schemaDir}}/db.ts) | Database client — `import { db } from '{{dbImportPath}}'` |
84
+ | `{{schemaDir}}/contract.json` | Compiled contract (generated) |
85
+ | `{{schemaDir}}/contract.d.ts` | Contract types (generated) |
86
+
87
+ ### Workflow
88
+
89
+ 1. Edit [`{{schemaPath}}`]({{schemaPath}}) to add or change models.
90
+ 2. Run `{{pkgRun}} contract emit` to regenerate the contract.
91
+ 3. Query your models — your IDE will autocomplete everything.
@@ -0,0 +1,19 @@
1
+ import { dirname } from 'pathe';
2
+ import type { TargetId } from './code-templates';
3
+ import { renderTemplate } from './render';
4
+
5
+ export const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;
6
+
7
+ type TemplateVars = Record<(typeof variables)[number], string>;
8
+
9
+ export function quickReferenceMd(target: TargetId, schemaPath: string, pkgRun: string): string {
10
+ const schemaDir = dirname(schemaPath);
11
+ const vars: TemplateVars = {
12
+ schemaPath,
13
+ schemaDir,
14
+ dbImportPath: `./${schemaDir}/db`,
15
+ pkgRun,
16
+ };
17
+ const templateFile = `quick-reference-${target}.md`;
18
+ return renderTemplate(templateFile, variables, vars);
19
+ }
@@ -0,0 +1,20 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'pathe';
3
+
4
+ export function renderTemplate(
5
+ templateFile: string,
6
+ variableNames: readonly string[],
7
+ vars: Record<string, string>,
8
+ ): string {
9
+ const templatePath = join(import.meta.dirname, templateFile);
10
+ const raw = readFileSync(templatePath, 'utf-8');
11
+ let result = raw;
12
+ for (const key of variableNames) {
13
+ const value = vars[key];
14
+ if (value === undefined) {
15
+ throw new Error(`Template variable '${key}' is not defined`);
16
+ }
17
+ result = result.replaceAll(`{{${key}}}`, value);
18
+ }
19
+ return result;
20
+ }
@@ -0,0 +1,35 @@
1
+ export const REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean> = {
2
+ module: 'preserve',
3
+ moduleResolution: 'bundler',
4
+ resolveJsonModule: true,
5
+ };
6
+
7
+ export function defaultTsConfig(): string {
8
+ return JSON.stringify(
9
+ {
10
+ compilerOptions: {
11
+ target: 'ES2022',
12
+ ...REQUIRED_COMPILER_OPTIONS,
13
+ strict: true,
14
+ skipLibCheck: true,
15
+ esModuleInterop: true,
16
+ outDir: 'dist',
17
+ },
18
+ include: ['**/*.ts'],
19
+ },
20
+ null,
21
+ 2,
22
+ );
23
+ }
24
+
25
+ export function mergeTsConfig(existing: string): string {
26
+ const config = JSON.parse(existing) as Record<string, unknown>;
27
+ const compilerOptions = (config['compilerOptions'] ?? {}) as Record<string, unknown>;
28
+
29
+ for (const [key, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) {
30
+ compilerOptions[key] = value;
31
+ }
32
+
33
+ config['compilerOptions'] = compilerOptions;
34
+ return JSON.stringify(config, null, 2);
35
+ }
@@ -0,0 +1,170 @@
1
+ import type { CoreSchemaView } from '@prisma-next/framework-components/control';
2
+ import { validatePrintableSqlSchemaIR } from '@prisma-next/psl-printer';
3
+ import { notOk, ok, type Result } from '@prisma-next/utils/result';
4
+ import { relative, resolve } from 'pathe';
5
+ import { loadConfig } from '../config-loader';
6
+ import { createControlClient } from '../control-api/client';
7
+ import {
8
+ CliStructuredError,
9
+ errorDatabaseConnectionRequired,
10
+ errorDriverRequired,
11
+ errorUnexpected,
12
+ } from '../utils/cli-errors';
13
+ import { maskConnectionUrl, sanitizeErrorMessage } from '../utils/command-helpers';
14
+ import { formatStyledHeader } from '../utils/formatters/styled';
15
+ import type { CommonCommandOptions, GlobalFlags } from '../utils/global-flags';
16
+ import { createProgressAdapter } from '../utils/progress-adapter';
17
+ import type { TerminalUI } from '../utils/terminal-ui';
18
+
19
+ export interface InspectLiveSchemaOptions extends CommonCommandOptions {
20
+ readonly db?: string;
21
+ readonly config?: string;
22
+ }
23
+
24
+ interface InspectLiveSchemaContext {
25
+ readonly commandName: string;
26
+ readonly description: string;
27
+ readonly url: string;
28
+ }
29
+
30
+ type LoadedCliConfig = Awaited<ReturnType<typeof loadConfig>>;
31
+
32
+ export interface InspectLiveSchemaResult {
33
+ readonly config: LoadedCliConfig;
34
+ readonly schema: unknown;
35
+ readonly schemaView: CoreSchemaView | undefined;
36
+ readonly target: {
37
+ readonly familyId: string;
38
+ readonly id: string;
39
+ };
40
+ readonly meta: {
41
+ readonly configPath?: string;
42
+ readonly dbUrl?: string;
43
+ };
44
+ readonly timings: {
45
+ readonly total: number;
46
+ };
47
+ }
48
+
49
+ export async function inspectLiveSchema(
50
+ options: InspectLiveSchemaOptions,
51
+ flags: GlobalFlags,
52
+ ui: TerminalUI,
53
+ startTime: number,
54
+ context: InspectLiveSchemaContext,
55
+ ): Promise<Result<InspectLiveSchemaResult, CliStructuredError>> {
56
+ let config: LoadedCliConfig;
57
+ try {
58
+ config = await loadConfig(options.config);
59
+ } catch (error) {
60
+ if (CliStructuredError.is(error)) {
61
+ return notOk(error);
62
+ }
63
+
64
+ return notOk(
65
+ errorUnexpected(error instanceof Error ? error.message : String(error), {
66
+ why: 'Failed to load config',
67
+ }),
68
+ );
69
+ }
70
+
71
+ const configPath = options.config
72
+ ? relative(process.cwd(), resolve(options.config))
73
+ : 'prisma-next.config.ts';
74
+
75
+ if (!flags.json && !flags.quiet) {
76
+ const details: Array<{ label: string; value: string }> = [
77
+ { label: 'config', value: configPath },
78
+ ];
79
+
80
+ if (options.db) {
81
+ details.push({ label: 'database', value: maskConnectionUrl(options.db) });
82
+ } else if (config.db?.connection && typeof config.db.connection === 'string') {
83
+ details.push({ label: 'database', value: maskConnectionUrl(config.db.connection) });
84
+ }
85
+
86
+ ui.stderr(
87
+ formatStyledHeader({
88
+ command: context.commandName,
89
+ description: context.description,
90
+ url: context.url,
91
+ details,
92
+ flags,
93
+ }),
94
+ );
95
+ }
96
+
97
+ const dbConnection = options.db ?? config.db?.connection;
98
+ if (!dbConnection) {
99
+ return notOk(
100
+ errorDatabaseConnectionRequired({
101
+ why: `Database connection is required for ${context.commandName} (set db.connection in ${configPath}, or pass --db <url>)`,
102
+ commandName: context.commandName,
103
+ }),
104
+ );
105
+ }
106
+
107
+ if (!config.driver) {
108
+ return notOk(
109
+ errorDriverRequired({
110
+ why: `Config.driver is required for ${context.commandName}`,
111
+ }),
112
+ );
113
+ }
114
+
115
+ const client = createControlClient({
116
+ family: config.family,
117
+ target: config.target,
118
+ adapter: config.adapter,
119
+ driver: config.driver,
120
+ extensionPacks: config.extensionPacks ?? [],
121
+ });
122
+ const onProgress = createProgressAdapter({ ui, flags });
123
+
124
+ try {
125
+ const schemaIR = await client.introspect({
126
+ connection: dbConnection,
127
+ onProgress,
128
+ });
129
+ // TODO(TML-2251): Remove SQL-specific branching — SQL should use the same family-agnostic path as Mongo.
130
+ const schema =
131
+ config.family.familyId === 'sql' ? validatePrintableSqlSchemaIR(schemaIR) : schemaIR;
132
+ const schemaView = client.toSchemaView(schema);
133
+
134
+ const dbUrl = typeof dbConnection === 'string' ? maskConnectionUrl(dbConnection) : undefined;
135
+
136
+ return ok({
137
+ config,
138
+ schema,
139
+ schemaView,
140
+ target: {
141
+ familyId: config.family.familyId,
142
+ id: config.target.targetId,
143
+ },
144
+ meta: {
145
+ configPath,
146
+ ...(dbUrl ? { dbUrl } : {}),
147
+ },
148
+ timings: {
149
+ total: Date.now() - startTime,
150
+ },
151
+ });
152
+ } catch (error) {
153
+ if (CliStructuredError.is(error)) {
154
+ return notOk(error);
155
+ }
156
+
157
+ const rawMessage = error instanceof Error ? error.message : String(error);
158
+ const safeMessage = sanitizeErrorMessage(
159
+ rawMessage,
160
+ typeof dbConnection === 'string' ? dbConnection : undefined,
161
+ );
162
+ return notOk(
163
+ errorUnexpected(safeMessage, {
164
+ why: `Unexpected error during ${context.commandName}: ${safeMessage}`,
165
+ }),
166
+ );
167
+ } finally {
168
+ await client.close();
169
+ }
170
+ }