ts-prorm-orm 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/CHANGELOG.md +1111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/dist/audit/history-query.js +180 -0
  5. package/dist/audit/index.js +23 -0
  6. package/dist/audit/logger.js +236 -0
  7. package/dist/cache/cache-manager.js +84 -0
  8. package/dist/cache/index.js +16 -0
  9. package/dist/cache/redis-cluster-cache.js +557 -0
  10. package/dist/cli.js +2200 -0
  11. package/dist/compliance/audit-trail.js +68 -0
  12. package/dist/compliance/backup-verification.js +685 -0
  13. package/dist/compliance/breach-detector.js +505 -0
  14. package/dist/compliance/consent-record.js +227 -0
  15. package/dist/compliance/consent-versioning.js +331 -0
  16. package/dist/compliance/cross-border-log.js +530 -0
  17. package/dist/compliance/data-classifier.js +258 -0
  18. package/dist/compliance/data-lineage.js +565 -0
  19. package/dist/compliance/data-masker.js +303 -0
  20. package/dist/compliance/data-portability.js +265 -0
  21. package/dist/compliance/data-retention.js +195 -0
  22. package/dist/compliance/dsar-workflow.js +342 -0
  23. package/dist/compliance/field-encryption.js +223 -0
  24. package/dist/compliance/immutable-record.js +148 -0
  25. package/dist/compliance/index.js +260 -0
  26. package/dist/compliance/privacy-impact-assessment.js +364 -0
  27. package/dist/compliance/pseudonymization.js +269 -0
  28. package/dist/compliance/query-firewall.js +1182 -0
  29. package/dist/compliance/rate-limiter.js +580 -0
  30. package/dist/compliance/right-to-erasure.js +117 -0
  31. package/dist/compliance/row-level-security.js +246 -0
  32. package/dist/compliance/security-decorator.js +574 -0
  33. package/dist/compliance/security-monitor.js +525 -0
  34. package/dist/compliance/sensitive-data-discovery.js +476 -0
  35. package/dist/compliance/session-isolation.js +472 -0
  36. package/dist/compliance/tls-enforcer.js +108 -0
  37. package/dist/compliance/worm-storage.js +712 -0
  38. package/dist/connection-manager.js +198 -0
  39. package/dist/connection-pool.js +519 -0
  40. package/dist/decorators/audit.js +136 -0
  41. package/dist/decorators/belongs-to-many.js +115 -0
  42. package/dist/decorators/belongs-to.js +115 -0
  43. package/dist/decorators/check.js +435 -0
  44. package/dist/decorators/collate.js +329 -0
  45. package/dist/decorators/comment.js +205 -0
  46. package/dist/decorators/database-settings.js +236 -0
  47. package/dist/decorators/default.js +244 -0
  48. package/dist/decorators/encryption.js +235 -0
  49. package/dist/decorators/engine.js +97 -0
  50. package/dist/decorators/fk-constraints.js +594 -0
  51. package/dist/decorators/foreign-table.js +136 -0
  52. package/dist/decorators/generated.js +274 -0
  53. package/dist/decorators/has-many.js +127 -0
  54. package/dist/decorators/has-one.js +116 -0
  55. package/dist/decorators/hstore.js +129 -0
  56. package/dist/decorators/index.js +355 -0
  57. package/dist/decorators/json-column.js +83 -0
  58. package/dist/decorators/jsonb.js +101 -0
  59. package/dist/decorators/orm-decorators.js +425 -0
  60. package/dist/decorators/permissions.js +294 -0
  61. package/dist/decorators/procedure.js +210 -0
  62. package/dist/decorators/query-options.js +556 -0
  63. package/dist/decorators/range.js +167 -0
  64. package/dist/decorators/set-column.js +83 -0
  65. package/dist/decorators/spatial.js +114 -0
  66. package/dist/decorators/storage.js +580 -0
  67. package/dist/decorators/timezone.js +512 -0
  68. package/dist/decorators/trigger.js +90 -0
  69. package/dist/decorators/uuid.js +135 -0
  70. package/dist/decorators/view.js +258 -0
  71. package/dist/diagrams/chen-diagram.js +354 -0
  72. package/dist/diagrams/class-diagram.js +384 -0
  73. package/dist/diagrams/dependency-diagram.js +432 -0
  74. package/dist/diagrams/er-diagram.js +605 -0
  75. package/dist/diagrams/flow-diagram.js +394 -0
  76. package/dist/diagrams/gantt-diagram.js +411 -0
  77. package/dist/diagrams/index-diagram.js +353 -0
  78. package/dist/diagrams/index.js +184 -0
  79. package/dist/diagrams/migration-diagram.js +316 -0
  80. package/dist/diagrams/model-diagram.js +616 -0
  81. package/dist/diagrams/package-diagram.js +376 -0
  82. package/dist/diagrams/palette.js +85 -0
  83. package/dist/diagrams/relational-diagram.js +455 -0
  84. package/dist/diagrams/schemadoc-diagram.js +309 -0
  85. package/dist/diagrams/sequence-diagram.js +307 -0
  86. package/dist/diagrams/state-diagram.js +344 -0
  87. package/dist/diagrams/svg-dom.js +111 -0
  88. package/dist/diagrams/tree-diagram.js +250 -0
  89. package/dist/dialects/clickhouse/index.js +1742 -0
  90. package/dist/dialects/cockroachdb/index.js +4677 -0
  91. package/dist/dialects/cratedb/index.js +441 -0
  92. package/dist/dialects/databricks/index.js +517 -0
  93. package/dist/dialects/db2/index.js +2225 -0
  94. package/dist/dialects/dialect.js +720 -0
  95. package/dist/dialects/duckdb/index.js +2014 -0
  96. package/dist/dialects/exasol/index.js +357 -0
  97. package/dist/dialects/firebird/index.js +495 -0
  98. package/dist/dialects/greenplum/index.js +457 -0
  99. package/dist/dialects/hana/index.js +1741 -0
  100. package/dist/dialects/mariadb/index.js +3590 -0
  101. package/dist/dialects/mssql/index.js +2296 -0
  102. package/dist/dialects/mysql/index.js +4058 -0
  103. package/dist/dialects/oracle/index.js +2999 -0
  104. package/dist/dialects/postgres/index.js +5319 -0
  105. package/dist/dialects/query-stream-helper.js +152 -0
  106. package/dist/dialects/questdb/index.js +433 -0
  107. package/dist/dialects/redshift/index.js +2277 -0
  108. package/dist/dialects/singlestore/index.js +354 -0
  109. package/dist/dialects/snowflake/index.js +2082 -0
  110. package/dist/dialects/spanner/index.js +1768 -0
  111. package/dist/dialects/sqlite/index.js +3382 -0
  112. package/dist/dialects/tidb/index.js +377 -0
  113. package/dist/dialects/timescaledb/index.js +164 -0
  114. package/dist/dialects/trino/index.js +420 -0
  115. package/dist/dialects/turso/index.js +227 -0
  116. package/dist/dialects/vertica/index.js +317 -0
  117. package/dist/dialects/yugabytedb/index.js +424 -0
  118. package/dist/errors/index.js +472 -0
  119. package/dist/errors/utils.js +340 -0
  120. package/dist/errors.js +21 -0
  121. package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
  122. package/dist/extensions/catalog/mssql-features.js +147 -0
  123. package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
  124. package/dist/extensions/catalog/oracle-db2-features.js +196 -0
  125. package/dist/extensions/catalog/postgres-extensions.js +516 -0
  126. package/dist/extensions/index.js +71 -0
  127. package/dist/extensions/types.js +13 -0
  128. package/dist/foreign-data.js +173 -0
  129. package/dist/hooks/hooks-manager.js +350 -0
  130. package/dist/hooks/index.js +37 -0
  131. package/dist/index.js +463 -0
  132. package/dist/logging.js +335 -0
  133. package/dist/migrations/index.js +40 -0
  134. package/dist/migrations/migration.js +196 -0
  135. package/dist/migrations/migrator.js +411 -0
  136. package/dist/migrations/prormmigration.js +275 -0
  137. package/dist/migrations/query-interface.js +435 -0
  138. package/dist/migrations/seeder.js +353 -0
  139. package/dist/models/associations.js +852 -0
  140. package/dist/models/constraints.js +288 -0
  141. package/dist/models/data-types.js +2518 -0
  142. package/dist/models/decorators.js +445 -0
  143. package/dist/models/index.js +33 -0
  144. package/dist/models/indexes.js +531 -0
  145. package/dist/models/methods.js +382 -0
  146. package/dist/models/model-manager.js +103 -0
  147. package/dist/models/model.js +5349 -0
  148. package/dist/models/operators.js +67 -0
  149. package/dist/models/scopes.js +189 -0
  150. package/dist/models/typescript-types.js +26 -0
  151. package/dist/nosql/aerospike/index.js +205 -0
  152. package/dist/nosql/allegrograph/index.js +169 -0
  153. package/dist/nosql/arangodb/index.js +364 -0
  154. package/dist/nosql/azure-blob/index.js +206 -0
  155. package/dist/nosql/beanstalkd/index.js +231 -0
  156. package/dist/nosql/beequeue/index.js +210 -0
  157. package/dist/nosql/bigchaindb/index.js +195 -0
  158. package/dist/nosql/bigtable/index.js +224 -0
  159. package/dist/nosql/blazegraph/index.js +173 -0
  160. package/dist/nosql/bullmq/index.js +191 -0
  161. package/dist/nosql/cassandra/index.js +174 -0
  162. package/dist/nosql/chroma/index.js +190 -0
  163. package/dist/nosql/cloudflare-kv/index.js +220 -0
  164. package/dist/nosql/coherence/index.js +200 -0
  165. package/dist/nosql/cosmosdb/index.js +157 -0
  166. package/dist/nosql/couchbase/index.js +213 -0
  167. package/dist/nosql/dax/index.js +212 -0
  168. package/dist/nosql/deno-kv/index.js +206 -0
  169. package/dist/nosql/dgraph/index.js +171 -0
  170. package/dist/nosql/doris/index.js +169 -0
  171. package/dist/nosql/druid/index.js +162 -0
  172. package/dist/nosql/dynamodb/index.js +937 -0
  173. package/dist/nosql/elasticsearch/index.js +377 -0
  174. package/dist/nosql/etcd/index.js +502 -0
  175. package/dist/nosql/eventhubs/index.js +213 -0
  176. package/dist/nosql/eventstore/index.js +254 -0
  177. package/dist/nosql/faunadb/index.js +188 -0
  178. package/dist/nosql/firestore/index.js +177 -0
  179. package/dist/nosql/fluree/index.js +148 -0
  180. package/dist/nosql/fuseki/index.js +170 -0
  181. package/dist/nosql/gcs/index.js +172 -0
  182. package/dist/nosql/gearman/index.js +160 -0
  183. package/dist/nosql/geode/index.js +196 -0
  184. package/dist/nosql/graphdb/index.js +169 -0
  185. package/dist/nosql/graylog/index.js +188 -0
  186. package/dist/nosql/gridgain/index.js +171 -0
  187. package/dist/nosql/hazelcast/index.js +162 -0
  188. package/dist/nosql/hbase/index.js +230 -0
  189. package/dist/nosql/ignite/index.js +173 -0
  190. package/dist/nosql/immudb/index.js +184 -0
  191. package/dist/nosql/index.js +232 -0
  192. package/dist/nosql/infinispan/index.js +200 -0
  193. package/dist/nosql/influxdb/index.js +0 -0
  194. package/dist/nosql/kafka/index.js +234 -0
  195. package/dist/nosql/keyspaces/index.js +189 -0
  196. package/dist/nosql/kinesis/index.js +253 -0
  197. package/dist/nosql/leveldb/index.js +153 -0
  198. package/dist/nosql/lmdb/index.js +160 -0
  199. package/dist/nosql/loki/index.js +201 -0
  200. package/dist/nosql/marklogic/index.js +204 -0
  201. package/dist/nosql/materialize/index.js +145 -0
  202. package/dist/nosql/meilisearch/index.js +154 -0
  203. package/dist/nosql/memcached/index.js +223 -0
  204. package/dist/nosql/milvus/index.js +410 -0
  205. package/dist/nosql/minio/index.js +265 -0
  206. package/dist/nosql/momento/index.js +179 -0
  207. package/dist/nosql/mongodb/index.js +461 -0
  208. package/dist/nosql/nats/index.js +247 -0
  209. package/dist/nosql/nedb/index.js +164 -0
  210. package/dist/nosql/neo4j/index.js +450 -0
  211. package/dist/nosql/neptune/index.js +470 -0
  212. package/dist/nosql/nsq/index.js +200 -0
  213. package/dist/nosql/opensearch/index.js +186 -0
  214. package/dist/nosql/orientdb/index.js +175 -0
  215. package/dist/nosql/papertrail/index.js +200 -0
  216. package/dist/nosql/pinecone/index.js +0 -0
  217. package/dist/nosql/pinot/index.js +133 -0
  218. package/dist/nosql/pouchdb/index.js +172 -0
  219. package/dist/nosql/prometheus/index.js +174 -0
  220. package/dist/nosql/provendb/index.js +147 -0
  221. package/dist/nosql/pubsub/index.js +187 -0
  222. package/dist/nosql/pulsar/index.js +232 -0
  223. package/dist/nosql/qdrant/index.js +295 -0
  224. package/dist/nosql/qldb/index.js +192 -0
  225. package/dist/nosql/r2/index.js +281 -0
  226. package/dist/nosql/rabbitmq/index.js +237 -0
  227. package/dist/nosql/ravendb/index.js +175 -0
  228. package/dist/nosql/redis/index.js +607 -0
  229. package/dist/nosql/redpanda/index.js +237 -0
  230. package/dist/nosql/resque/index.js +203 -0
  231. package/dist/nosql/rethinkdb/index.js +232 -0
  232. package/dist/nosql/rocksdb/index.js +152 -0
  233. package/dist/nosql/rockset/index.js +126 -0
  234. package/dist/nosql/s3/index.js +298 -0
  235. package/dist/nosql/scylladb/index.js +178 -0
  236. package/dist/nosql/signoz/index.js +227 -0
  237. package/dist/nosql/sns/index.js +201 -0
  238. package/dist/nosql/solr/index.js +231 -0
  239. package/dist/nosql/splunk/index.js +227 -0
  240. package/dist/nosql/sqs/index.js +246 -0
  241. package/dist/nosql/stardog/index.js +169 -0
  242. package/dist/nosql/starrocks/index.js +170 -0
  243. package/dist/nosql/store.js +2 -0
  244. package/dist/nosql/sumologic/index.js +213 -0
  245. package/dist/nosql/surrealdb/index.js +179 -0
  246. package/dist/nosql/terminusdb/index.js +151 -0
  247. package/dist/nosql/tigergraph/index.js +469 -0
  248. package/dist/nosql/typesense/index.js +148 -0
  249. package/dist/nosql/unqlite/index.js +157 -0
  250. package/dist/nosql/upstash/index.js +167 -0
  251. package/dist/nosql/vercel-kv/index.js +166 -0
  252. package/dist/nosql/victoriametrics/index.js +213 -0
  253. package/dist/nosql/virtuoso/index.js +169 -0
  254. package/dist/nosql/weaviate/index.js +276 -0
  255. package/dist/operators/index.js +108 -0
  256. package/dist/operators.js +2690 -0
  257. package/dist/prisma-migrate/index.js +38 -0
  258. package/dist/prisma-migrate/migration-generator.js +125 -0
  259. package/dist/prisma-migrate/model-generator.js +172 -0
  260. package/dist/prisma-migrate/relations.js +100 -0
  261. package/dist/prisma-migrate/schema-parser.js +167 -0
  262. package/dist/prisma-migrate/type-mapper.js +40 -0
  263. package/dist/prorm.js +6832 -0
  264. package/dist/query-builders/cte-builder.js +80 -0
  265. package/dist/query-builders/functions/aggregate.js +390 -0
  266. package/dist/query-builders/functions/conditional.js +503 -0
  267. package/dist/query-builders/functions/datetime.js +695 -0
  268. package/dist/query-builders/functions/fulltext.js +439 -0
  269. package/dist/query-builders/functions/index.js +93 -0
  270. package/dist/query-builders/functions/json.js +427 -0
  271. package/dist/query-builders/functions/math.js +399 -0
  272. package/dist/query-builders/functions/string.js +518 -0
  273. package/dist/query-builders/functions/window.js +328 -0
  274. package/dist/query-builders/include-builder.js +323 -0
  275. package/dist/query-builders/index-expression-builder.js +242 -0
  276. package/dist/query-builders/index.js +161 -0
  277. package/dist/query-builders/insert-builder.js +164 -0
  278. package/dist/query-builders/model-helpers.js +38 -0
  279. package/dist/query-builders/order-limit-builder.js +239 -0
  280. package/dist/query-builders/sql-compiler.js +2040 -0
  281. package/dist/query-builders/subquery-builder.js +152 -0
  282. package/dist/query-builders/update-builder.js +182 -0
  283. package/dist/query-builders/view-builder.js +218 -0
  284. package/dist/query-builders/where-builder.js +1532 -0
  285. package/dist/query-interface.js +622 -0
  286. package/dist/query-optimizers/batch-optimizer.js +426 -0
  287. package/dist/query-optimizers/explain-plans.js +415 -0
  288. package/dist/query-optimizers/index.js +51 -0
  289. package/dist/query-optimizers/prepared-statement-cache.js +423 -0
  290. package/dist/query-optimizers/query-hints.js +438 -0
  291. package/dist/query-optimizers/query-optimizer.js +278 -0
  292. package/dist/query-optimizers/slow-query-logger.js +271 -0
  293. package/dist/replica-manager.js +507 -0
  294. package/dist/schema/index.js +15 -0
  295. package/dist/schema/migration-generator.js +374 -0
  296. package/dist/schema/schema-differ.js +549 -0
  297. package/dist/schema/types.js +6 -0
  298. package/dist/sql-constants.js +300 -0
  299. package/dist/sqlite-advanced.js +1047 -0
  300. package/dist/streams/index.js +12 -0
  301. package/dist/streams/transforms.js +178 -0
  302. package/dist/transaction.js +456 -0
  303. package/dist/types/index.js +180 -0
  304. package/dist/user-management.js +127 -0
  305. package/dist/utils/date.js +300 -0
  306. package/dist/utils/index.js +1079 -0
  307. package/dist/utils/string.js +161 -0
  308. package/dist/validators/index.js +19 -0
  309. package/dist/validators/validator.js +911 -0
  310. package/package.json +190 -0
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * Prisma schema.prisma → prorm converter. Pure functions only (no
4
+ * filesystem access) so this is unit-testable without touching disk — the
5
+ * CLI layer (see cli.ts's `prisma:import` command) owns reading the input
6
+ * file and writing the generated output.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.resolveRelations = exports.parsePrismaSchema = void 0;
10
+ exports.convertPrismaSchema = convertPrismaSchema;
11
+ const schema_parser_1 = require("./schema-parser");
12
+ const model_generator_1 = require("./model-generator");
13
+ const migration_generator_1 = require("./migration-generator");
14
+ const relations_1 = require("./relations");
15
+ var schema_parser_2 = require("./schema-parser");
16
+ Object.defineProperty(exports, "parsePrismaSchema", { enumerable: true, get: function () { return schema_parser_2.parsePrismaSchema; } });
17
+ var relations_2 = require("./relations");
18
+ Object.defineProperty(exports, "resolveRelations", { enumerable: true, get: function () { return relations_2.resolveRelations; } });
19
+ /**
20
+ * @throws if the schema uses a feature this tool doesn't support: implicit
21
+ * many-to-many relations, composite foreign keys, or a Prisma scalar type
22
+ * with no prorm equivalent (see relations.ts / type-mapper.ts for the exact
23
+ * conditions) — these throw rather than emit incorrect/guessed output.
24
+ */
25
+ function convertPrismaSchema(schemaSource) {
26
+ const schema = (0, schema_parser_1.parsePrismaSchema)(schemaSource);
27
+ const modelNames = new Set(schema.models.map((m) => m.name));
28
+ const relations = (0, relations_1.resolveRelations)(schema.models, modelNames);
29
+ const models = schema.models.map((model) => ({
30
+ name: model.name,
31
+ source: (0, model_generator_1.generateModelFile)(model, schema.models, schema.enums, relations),
32
+ }));
33
+ return {
34
+ models,
35
+ modelsIndex: (0, model_generator_1.generateModelsIndex)(schema.models),
36
+ migration: (0, migration_generator_1.generateInitialMigration)(schema.models, schema.enums, relations),
37
+ };
38
+ }
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ /**
3
+ * Generates a single "initial schema" prorm migration file from a parsed
4
+ * Prisma schema, using the QueryInterface API (see src/migrations/
5
+ * query-interface.ts and docs-next/docs/example/advanced/06-migrations.ts
6
+ * for the real shape this mirrors).
7
+ *
8
+ * Strategy: create every table with its scalar columns first (no foreign
9
+ * keys inline), then add every foreign key as a separate `addConstraint`
10
+ * call in a second pass. This sidesteps needing a topological sort over
11
+ * model dependencies — table creation order genuinely doesn't matter when
12
+ * no table references another yet.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.generateInitialMigration = generateInitialMigration;
16
+ const type_mapper_1 = require("./type-mapper");
17
+ function columnDefExpr(field, enumsByName, isPrimaryKey) {
18
+ const { dataTypeExpr } = (0, type_mapper_1.mapPrismaType)(field.type, enumsByName);
19
+ const props = [`type: ${dataTypeExpr}`];
20
+ if (isPrimaryKey)
21
+ props.push('primaryKey: true');
22
+ if (!field.isOptional)
23
+ props.push('allowNull: false');
24
+ const defaultAttr = field.attributes.find((a) => a.name === 'default');
25
+ if (defaultAttr) {
26
+ const raw = defaultAttr.rawArgs.trim();
27
+ if (raw === 'autoincrement()') {
28
+ props.push('autoIncrement: true');
29
+ }
30
+ else if (raw === 'now()') {
31
+ props.push("defaultValue: prorm.literal('CURRENT_TIMESTAMP')");
32
+ }
33
+ else if (raw === 'uuid()' || raw === 'cuid()') {
34
+ props.push('defaultValue: DataTypes.UUIDV4');
35
+ }
36
+ else {
37
+ // Numeric/boolean/string/enum-member literal — same forms resolveDefault()
38
+ // in model-generator.ts accepts, reused here as a plain SQL-ish JS value.
39
+ props.push(`defaultValue: ${/^\w+$/.test(raw) && !/^-?\d+(\.\d+)?$/.test(raw) && raw !== 'true' && raw !== 'false' ? `'${raw}'` : raw}`);
40
+ }
41
+ }
42
+ if (field.attributes.some((a) => a.name === 'unique'))
43
+ props.push('unique: true');
44
+ return `{ ${props.join(', ')} }`;
45
+ }
46
+ /** Generates one model's `createTable(...)` call body. */
47
+ function generateCreateTable(model, allModels, enums) {
48
+ const enumsByName = new Map(enums.map((e) => [e.name, e.values]));
49
+ const modelNames = new Set(allModels.map((m) => m.name));
50
+ const mapAttr = model.blockAttributes.find((a) => a.name === 'map');
51
+ const tableName = mapAttr ? mapAttr.rawArgs.replace(/"/g, '') : model.name;
52
+ const idFieldNames = new Set(model.blockAttributes
53
+ .filter((a) => a.name === 'id')
54
+ .flatMap((a) => a.rawArgs.replace(/\[|\]/g, '').split(',').map((s) => s.trim()))
55
+ .filter(Boolean));
56
+ const columns = model.fields
57
+ .filter((f) => !modelNames.has(f.type)) // skip relation fields, keep plain FK scalar columns
58
+ .map((f) => {
59
+ const isPk = f.attributes.some((a) => a.name === 'id') || idFieldNames.has(f.name);
60
+ return ` ${f.name}: ${columnDefExpr(f, enumsByName, isPk)},`;
61
+ })
62
+ .join('\n');
63
+ return ` await queryInterface.createTable('${tableName}', {\n${columns}\n });`;
64
+ }
65
+ function tableNameFor(model) {
66
+ const mapAttr = model.blockAttributes.find((a) => a.name === 'map');
67
+ return mapAttr ? mapAttr.rawArgs.replace(/"/g, '') : model.name;
68
+ }
69
+ function generateAddConstraint(rel, modelsByName) {
70
+ const sourceTable = tableNameFor(rel.model);
71
+ const targetTable = tableNameFor(modelsByName.get(rel.targetModel));
72
+ const constraintName = `${sourceTable}_${rel.foreignKey}_fk`;
73
+ return (` await queryInterface.addConstraint('${sourceTable}', ['${rel.foreignKey}'], {\n` +
74
+ ` type: 'foreign key',\n` +
75
+ ` name: '${constraintName}',\n` +
76
+ ` references: { table: '${targetTable}', field: 'id' },\n` +
77
+ ` onUpdate: 'CASCADE',\n` +
78
+ ` onDelete: 'CASCADE',\n` +
79
+ ` });`);
80
+ }
81
+ function generateRemoveConstraint(rel) {
82
+ const sourceTable = tableNameFor(rel.model);
83
+ const constraintName = `${sourceTable}_${rel.foreignKey}_fk`;
84
+ return ` await queryInterface.removeConstraint('${sourceTable}', '${constraintName}');`;
85
+ }
86
+ /**
87
+ * Generates the full migration file source (CommonJS, matching
88
+ * buildMigrationTemplate's output shape in src/migrations/migration.ts) for
89
+ * every model + relation in the schema, as a single "initial schema"
90
+ * migration.
91
+ */
92
+ function generateInitialMigration(models, enums, relations) {
93
+ const modelsByName = new Map(models.map((m) => [m.name, m]));
94
+ const belongsToRelations = relations.filter((r) => r.kind === 'belongsTo');
95
+ const createTableCalls = models.map((m) => generateCreateTable(m, models, enums)).join('\n\n');
96
+ const addConstraintCalls = belongsToRelations.map((r) => generateAddConstraint(r, modelsByName)).join('\n\n');
97
+ const removeConstraintCalls = belongsToRelations.map(generateRemoveConstraint).join('\n');
98
+ const dropTableCalls = [...models]
99
+ .reverse()
100
+ .map((m) => ` await queryInterface.dropTable('${tableNameFor(m)}');`)
101
+ .join('\n');
102
+ return `/**
103
+ * Auto-generated by prisma-migrate from schema.prisma. Review before running
104
+ * — in particular the foreign key naming, enum defaults, and any @updatedAt
105
+ * fields (see the comments left in the generated model files) were
106
+ * translated on a best-effort basis and are worth double-checking against
107
+ * your actual schema before this runs against a real database.
108
+ */
109
+ const { DataTypes } = require('prorm');
110
+
111
+ module.exports = {
112
+ up: async (queryInterface, prorm) => {
113
+ ${createTableCalls}
114
+
115
+ ${addConstraintCalls || ' // No relations to wire up.'}
116
+ },
117
+
118
+ down: async (queryInterface, prorm) => {
119
+ ${removeConstraintCalls || ' // No relations were added.'}
120
+
121
+ ${dropTableCalls}
122
+ },
123
+ };
124
+ `;
125
+ }
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ /**
3
+ * Generates prorm decorator-based model source files (`@Table`/`@Attribute`/
4
+ * `@PrimaryKey()`/etc., the actively-maintained model API — see
5
+ * src/models/decorators.ts, not the orphaned `src/decorators/` set) from a
6
+ * parsed Prisma schema.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.generateModelFile = generateModelFile;
10
+ exports.generateModelsIndex = generateModelsIndex;
11
+ const type_mapper_1 = require("./type-mapper");
12
+ /** Translates a Prisma `@default(...)` argument into either a prorm decorator override or a `@Default(...)` value expression. */
13
+ function resolveDefault(rawArgs, prismaType) {
14
+ const trimmed = rawArgs.trim();
15
+ if (trimmed === 'autoincrement()') {
16
+ return { decoratorOverride: '@AutoIncrement()', valueExpr: null };
17
+ }
18
+ if (trimmed === 'now()') {
19
+ return { decoratorOverride: null, valueExpr: 'DataTypes.NOW' };
20
+ }
21
+ if (trimmed === 'uuid()' || trimmed === 'cuid()') {
22
+ // prorm has no cuid() generator; uuid v4 is the closest built-in and
23
+ // this is flagged in the generated comment rather than silently
24
+ // swapping ID formats without telling the caller.
25
+ return { decoratorOverride: null, valueExpr: 'DataTypes.UUIDV4' };
26
+ }
27
+ if (trimmed === 'true' || trimmed === 'false') {
28
+ return { decoratorOverride: null, valueExpr: trimmed };
29
+ }
30
+ if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
31
+ return { decoratorOverride: null, valueExpr: trimmed };
32
+ }
33
+ if (/^"[^"]*"$/.test(trimmed)) {
34
+ return { decoratorOverride: null, valueExpr: trimmed };
35
+ }
36
+ // A bare identifier for an enum default (e.g. @default(ADMIN)) — Prisma
37
+ // enum member names are used as their own SQL values in prorm's ENUM type.
38
+ if (/^\w+$/.test(trimmed)) {
39
+ return { decoratorOverride: null, valueExpr: `'${trimmed}'` };
40
+ }
41
+ throw new Error(`prisma-migrate: don't know how to translate @default(${rawArgs}) for a ${prismaType} field — ` +
42
+ `unrecognized default-value expression. Remove the @default or set it manually in the generated model.`);
43
+ }
44
+ function pascalCase(name) {
45
+ return name.charAt(0).toUpperCase() + name.slice(1);
46
+ }
47
+ function propertyType(field, tsScalarType) {
48
+ const base = field.isOptional ? `${tsScalarType} | null` : tsScalarType;
49
+ return field.attributes.some((a) => a.name === 'id' || a.name === 'default')
50
+ ? `CreationOptional<${base}>`
51
+ : base;
52
+ }
53
+ const TS_SCALAR_TYPES = {
54
+ String: 'string',
55
+ Int: 'number',
56
+ BigInt: 'bigint',
57
+ Float: 'number',
58
+ Decimal: 'number',
59
+ Boolean: 'boolean',
60
+ DateTime: 'Date',
61
+ Json: 'unknown',
62
+ Bytes: 'Buffer',
63
+ };
64
+ function generateScalarField(field, enumsByName, isForeignKeyColumn) {
65
+ const { dataTypeExpr, isEnum } = (0, type_mapper_1.mapPrismaType)(field.type, enumsByName);
66
+ const decorators = [`@Attribute(${dataTypeExpr})`];
67
+ const idAttr = field.attributes.find((a) => a.name === 'id');
68
+ const defaultAttr = field.attributes.find((a) => a.name === 'default');
69
+ const uniqueAttr = field.attributes.find((a) => a.name === 'unique');
70
+ const updatedAtAttr = field.attributes.find((a) => a.name === 'updatedAt');
71
+ if (idAttr)
72
+ decorators.push('@PrimaryKey()');
73
+ let defaultOverrideDecorator = null;
74
+ if (defaultAttr) {
75
+ const resolved = resolveDefault(defaultAttr.rawArgs, field.type);
76
+ if (resolved.decoratorOverride) {
77
+ defaultOverrideDecorator = resolved.decoratorOverride;
78
+ }
79
+ else {
80
+ decorators.push(`@Default(${resolved.valueExpr})`);
81
+ }
82
+ }
83
+ if (defaultOverrideDecorator)
84
+ decorators.push(defaultOverrideDecorator);
85
+ if (uniqueAttr)
86
+ decorators.push('@Unique()');
87
+ if (!field.isOptional && !idAttr)
88
+ decorators.push('@NotNull()');
89
+ const tsType = isEnum
90
+ ? field.type // reuse the Prisma enum's own name as a TS union alias name; see the emitted `type <Enum> = ...` companion
91
+ : TS_SCALAR_TYPES[field.type] || 'unknown';
92
+ const declareType = propertyType(field, tsType);
93
+ const comment = updatedAtAttr
94
+ ? ' // @updatedAt in Prisma: prorm has no auto-touch-on-save decorator for an arbitrary column (only the built-in updatedAt timestamp column via @Table({ timestamps: true })) — update this field manually or wire it through Table({ updatedAt: \'' +
95
+ field.name +
96
+ "' }) if this is meant to be the model's standard updated-at column.\n"
97
+ : '';
98
+ const foreignKeyTypeWrap = isForeignKeyColumn ? `ForeignKey<${tsType}>` : declareType;
99
+ return `${comment} ${decorators.join('\n ')}\n declare ${field.name}: ${foreignKeyTypeWrap};`;
100
+ }
101
+ function generateAssociationField(rel) {
102
+ const target = rel.targetModel;
103
+ if (rel.kind === 'belongsTo') {
104
+ return ` @BelongsTo(() => ${target}, { foreignKey: '${rel.foreignKey}', as: '${rel.fieldName}' })\n declare ${rel.fieldName}: BelongsTo<${target}>;`;
105
+ }
106
+ if (rel.kind === 'hasMany') {
107
+ return ` @HasMany(() => ${target}, { foreignKey: '${rel.foreignKey}', as: '${rel.fieldName}' })\n declare ${rel.fieldName}: HasMany<${target}>;`;
108
+ }
109
+ return ` @HasOne(() => ${target}, { foreignKey: '${rel.foreignKey}', as: '${rel.fieldName}' })\n declare ${rel.fieldName}: HasOne<${target}>;`;
110
+ }
111
+ /** Generates the full TS source for one model file, including its imports. */
112
+ function generateModelFile(model, allModels, enums, relations) {
113
+ const enumsByName = new Map(enums.map((e) => [e.name, e.values]));
114
+ const modelNames = new Set(allModels.map((m) => m.name));
115
+ const relationsForModel = relations.filter((r) => r.model.name === model.name);
116
+ const relationFieldNames = new Set(relationsForModel.map((r) => r.fieldName));
117
+ const foreignKeyColumns = new Set(relations.filter((r) => r.kind === 'belongsTo' && r.model.name === model.name).map((r) => r.foreignKey));
118
+ const mapAttr = model.blockAttributes.find((a) => a.name === 'map');
119
+ const tableNameLiteral = mapAttr ? mapAttr.rawArgs.replace(/"/g, '') : model.name;
120
+ const scalarFieldBlocks = [];
121
+ for (const field of model.fields) {
122
+ if (modelNames.has(field.type))
123
+ continue; // relation field, handled separately
124
+ if (relationFieldNames.has(field.name))
125
+ continue;
126
+ scalarFieldBlocks.push(generateScalarField(field, enumsByName, foreignKeyColumns.has(field.name)));
127
+ }
128
+ const associationBlocks = relationsForModel.map(generateAssociationField);
129
+ const relatedModelImports = Array.from(new Set(relationsForModel.map((r) => r.targetModel).filter((name) => name !== model.name)));
130
+ const enumTypeAliases = Array.from(new Set(model.fields
131
+ .map((f) => f.type)
132
+ .filter((t) => enumsByName.has(t))))
133
+ .map((enumName) => `type ${enumName} = ${enumsByName.get(enumName).map((v) => `'${v}'`).join(' | ')};`)
134
+ .join('\n');
135
+ const needsForeignKeyImport = foreignKeyColumns.size > 0;
136
+ const needsAssociationImports = relationsForModel.length > 0;
137
+ const importedDecorators = ['Table', 'Attribute', 'PrimaryKey', 'NotNull', 'Default', 'Unique']
138
+ .concat(model.fields.some((f) => f.attributes.some((a) => a.name === 'default' && a.rawArgs.trim() === 'autoincrement()')) ? ['AutoIncrement'] : [])
139
+ .concat(needsAssociationImports ? Array.from(new Set(relationsForModel.map((r) => pascalCase(r.kind)))) : []);
140
+ const importedTypescriptTypes = ['CreationOptional', 'InferAttributes', 'InferCreationAttributes'].concat(needsForeignKeyImport ? ['ForeignKey'] : []);
141
+ const lines = [
142
+ `import { Model, DataTypes, ${importedDecorators.join(', ')} } from 'prorm';`,
143
+ `import { ${importedTypescriptTypes.join(', ')} } from 'prorm';`,
144
+ ...relatedModelImports.map((name) => `import { ${name} } from './${name}';`),
145
+ '',
146
+ enumTypeAliases,
147
+ enumTypeAliases ? '' : null,
148
+ `@Table({ tableName: '${tableNameLiteral}', timestamps: false })`,
149
+ `export class ${model.name} extends Model<InferAttributes<${model.name}>, InferCreationAttributes<${model.name}>> {`,
150
+ scalarFieldBlocks.join('\n\n'),
151
+ associationBlocks.length ? '\n' + associationBlocks.join('\n\n') : null,
152
+ '}',
153
+ '',
154
+ ].filter((l) => l !== null);
155
+ return lines.join('\n');
156
+ }
157
+ /** Generates a barrel file that imports every model and calls `prorm.addModels([...])`, matching the registration pattern real prorm projects use (see docs-next/docs/example/basic/user-model.ts). */
158
+ function generateModelsIndex(models) {
159
+ const imports = models.map((m) => `import { ${m.name} } from './${m.name}';`).join('\n');
160
+ const names = models.map((m) => m.name).join(', ');
161
+ return [
162
+ imports,
163
+ '',
164
+ `export { ${names} };`,
165
+ '',
166
+ '/** Call this once after creating your Prorm instance, before syncing/querying. */',
167
+ 'export function registerModels(prorm: { addModels: (models: unknown[]) => void }): void {',
168
+ ` prorm.addModels([${names}]);`,
169
+ '}',
170
+ '',
171
+ ].join('\n');
172
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * Resolves Prisma relation fields (fields whose type names another model)
4
+ * into prorm association descriptors. Prisma always represents a relation
5
+ * as a *pair* of fields, one on each model — this module's job is to find
6
+ * each pair and figure out which side owns the foreign key.
7
+ *
8
+ * Scope: only explicit one-to-many / one-to-one relations (one side has
9
+ * `@relation(fields: [...], references: [...])`) are supported. Prisma's
10
+ * *implicit* many-to-many relations (both sides are plain `Model[]` with no
11
+ * `@relation` attribute and no join model) have no owning-FK side to
12
+ * resolve — Prisma auto-generates a hidden join table for these with a
13
+ * naming/column scheme this tool doesn't attempt to reverse-engineer.
14
+ * `resolveRelations` throws a clear error naming the two models instead of
15
+ * guessing at that join table's shape.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.resolveRelations = resolveRelations;
19
+ /** Parses `@relation(...)`'s raw argument text: an optional leading string (the relation name) plus `fields: [...]`/`references: [...]` named args. */
20
+ function parseRelationArgs(rawArgs) {
21
+ const result = {};
22
+ const nameMatch = rawArgs.match(/^\s*"([^"]*)"/);
23
+ if (nameMatch)
24
+ result.name = nameMatch[1];
25
+ const fieldsMatch = rawArgs.match(/fields\s*:\s*\[([^\]]*)\]/);
26
+ if (fieldsMatch) {
27
+ result.fields = fieldsMatch[1]
28
+ .split(',')
29
+ .map((s) => s.trim())
30
+ .filter(Boolean);
31
+ }
32
+ const referencesMatch = rawArgs.match(/references\s*:\s*\[([^\]]*)\]/);
33
+ if (referencesMatch) {
34
+ result.references = referencesMatch[1]
35
+ .split(',')
36
+ .map((s) => s.trim())
37
+ .filter(Boolean);
38
+ }
39
+ const namedNameMatch = rawArgs.match(/(?:^|,)\s*name\s*:\s*"([^"]*)"/);
40
+ if (namedNameMatch)
41
+ result.name = namedNameMatch[1];
42
+ return result;
43
+ }
44
+ /** Unordered pair key so `(A, B)` and `(B, A)` land in the same bucket. */
45
+ function pairKey(a, b, name) {
46
+ const [x, y] = [a, b].sort();
47
+ return name ? `named:${name}` : `pair:${x}:${y}`;
48
+ }
49
+ function resolveRelations(models, modelNames) {
50
+ const relations = [];
51
+ const buckets = new Map();
52
+ for (const model of models) {
53
+ for (const field of model.fields) {
54
+ if (!modelNames.has(field.type))
55
+ continue; // scalar/enum field, not a relation
56
+ const relationAttr = field.attributes.find((a) => a.name === 'relation');
57
+ const args = relationAttr ? parseRelationArgs(relationAttr.rawArgs) : {};
58
+ const key = pairKey(model.name, field.type, args.name);
59
+ if (!buckets.has(key))
60
+ buckets.set(key, []);
61
+ buckets.get(key).push({ model, field, args });
62
+ }
63
+ }
64
+ for (const [key, sides] of buckets) {
65
+ if (sides.length !== 2) {
66
+ // A one-sided relation field (no matching inverse) or an implicit
67
+ // many-to-many bucket that didn't pair up 1:1 falls here too.
68
+ throw new Error(`prisma-migrate: could not resolve relation "${key}" — expected exactly 2 matching relation fields (one on each model), found ${sides.length}. ` +
69
+ `Implicit many-to-many relations (both sides declared as plain arrays with no @relation attribute) aren't supported — add an explicit join model instead.`);
70
+ }
71
+ const owningSide = sides.find((s) => s.args.fields && s.args.references);
72
+ const inverseSide = sides.find((s) => s !== owningSide);
73
+ if (!owningSide || !inverseSide) {
74
+ const bothArrays = sides.every((s) => s.field.isArray);
75
+ const hint = bothArrays
76
+ ? ' This looks like an implicit many-to-many relation (both sides are plain arrays with no @relation attribute) — those aren\'t supported; add an explicit join model instead.'
77
+ : ' Add @relation(fields: [...], references: [...]) to whichever side owns the foreign key column.';
78
+ throw new Error(`prisma-migrate: relation between "${sides[0].model.name}" and "${sides[1].model.name}" has no side declaring @relation(fields: [...], references: [...]) — can't determine which side owns the foreign key.${hint}`);
79
+ }
80
+ if (owningSide.args.fields.length !== 1) {
81
+ throw new Error(`prisma-migrate: composite foreign keys aren't supported (relation on "${owningSide.model.name}.${owningSide.field.name}" references ${owningSide.args.fields.length} columns).`);
82
+ }
83
+ const foreignKey = owningSide.args.fields[0];
84
+ relations.push({
85
+ kind: 'belongsTo',
86
+ model: owningSide.model,
87
+ fieldName: owningSide.field.name,
88
+ targetModel: owningSide.field.type,
89
+ foreignKey,
90
+ });
91
+ relations.push({
92
+ kind: inverseSide.field.isArray ? 'hasMany' : 'hasOne',
93
+ model: inverseSide.model,
94
+ fieldName: inverseSide.field.name,
95
+ targetModel: inverseSide.field.type,
96
+ foreignKey,
97
+ });
98
+ }
99
+ return relations;
100
+ }
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * Minimal hand-rolled parser for Prisma's `schema.prisma` grammar, scoped to
4
+ * exactly what `model-generator.ts`/`migration-generator.ts` need: `model`
5
+ * and `enum` blocks, field declarations, and field-level (`@`) / block-level
6
+ * (`@@`) attributes. `datasource`/`generator` blocks are parsed only far
7
+ * enough to skip over them — this tool doesn't need a live DB connection or
8
+ * codegen config, only the schema shape.
9
+ *
10
+ * This is not a full Prisma schema validator: it assumes the input already
11
+ * parses with Prisma's own `prisma validate` (this tool is meant to run
12
+ * against a schema the user is already using with Prisma). Malformed input
13
+ * produces a best-effort partial result rather than a precise parse error.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.parsePrismaSchema = parsePrismaSchema;
17
+ /** Strips `//` line comments and `/* *\/` block comments without touching string literals that might contain `//`. */
18
+ function stripComments(source) {
19
+ let result = '';
20
+ let i = 0;
21
+ let inString = false;
22
+ while (i < source.length) {
23
+ const ch = source[i];
24
+ const next = source[i + 1];
25
+ if (inString) {
26
+ result += ch;
27
+ if (ch === '\\') {
28
+ result += next ?? '';
29
+ i += 2;
30
+ continue;
31
+ }
32
+ if (ch === '"')
33
+ inString = false;
34
+ i++;
35
+ continue;
36
+ }
37
+ if (ch === '"') {
38
+ inString = true;
39
+ result += ch;
40
+ i++;
41
+ continue;
42
+ }
43
+ if (ch === '/' && next === '/') {
44
+ while (i < source.length && source[i] !== '\n')
45
+ i++;
46
+ continue;
47
+ }
48
+ if (ch === '/' && next === '*') {
49
+ i += 2;
50
+ while (i < source.length && !(source[i] === '*' && source[i + 1] === '/'))
51
+ i++;
52
+ i += 2;
53
+ continue;
54
+ }
55
+ result += ch;
56
+ i++;
57
+ }
58
+ return result;
59
+ }
60
+ /** Extracts the body of every top-level `<keyword> <Name> { ... }` block (brace-depth aware, so nested `{}` in attribute args don't terminate the block early). */
61
+ function extractBlocks(source, keyword) {
62
+ const blocks = [];
63
+ const headerRe = new RegExp(`\\b${keyword}\\s+(\\w+)\\s*\\{`, 'g');
64
+ let match;
65
+ while ((match = headerRe.exec(source))) {
66
+ const name = match[1];
67
+ const start = match.index + match[0].length;
68
+ let depth = 1;
69
+ let end = start;
70
+ while (end < source.length && depth > 0) {
71
+ if (source[end] === '{')
72
+ depth++;
73
+ else if (source[end] === '}')
74
+ depth--;
75
+ end++;
76
+ }
77
+ blocks.push({ name, body: source.slice(start, end - 1) });
78
+ headerRe.lastIndex = end;
79
+ }
80
+ return blocks;
81
+ }
82
+ /**
83
+ * Splits an attribute-chain like `@id @default(autoincrement()) @map("user_id")`
84
+ * into individual attributes, correctly treating a `@@`-prefixed attribute as
85
+ * one attribute (not two `@` tokens) and respecting parens so a `)` inside a
86
+ * string/nested call doesn't end the argument list early.
87
+ */
88
+ function parseAttributes(text) {
89
+ const attributes = [];
90
+ let i = 0;
91
+ while (i < text.length) {
92
+ if (text[i] !== '@') {
93
+ i++;
94
+ continue;
95
+ }
96
+ let start = i;
97
+ i++;
98
+ if (text[i] === '@')
99
+ i++; // block-level @@attr
100
+ let name = '';
101
+ while (i < text.length && /[\w.]/.test(text[i])) {
102
+ name += text[i];
103
+ i++;
104
+ }
105
+ let rawArgs = '';
106
+ if (text[i] === '(') {
107
+ let depth = 1;
108
+ i++;
109
+ const argStart = i;
110
+ while (i < text.length && depth > 0) {
111
+ if (text[i] === '(')
112
+ depth++;
113
+ else if (text[i] === ')')
114
+ depth--;
115
+ if (depth > 0)
116
+ i++;
117
+ }
118
+ rawArgs = text.slice(argStart, i);
119
+ i++; // consume closing ')'
120
+ }
121
+ attributes.push({ name, rawArgs });
122
+ void start;
123
+ }
124
+ return attributes;
125
+ }
126
+ function parseModelBody(body) {
127
+ const fields = [];
128
+ const blockAttributes = [];
129
+ for (const rawLine of body.split('\n')) {
130
+ const line = rawLine.trim();
131
+ if (!line)
132
+ continue;
133
+ if (line.startsWith('@@')) {
134
+ blockAttributes.push(...parseAttributes(line));
135
+ continue;
136
+ }
137
+ // `name Type[]? @attr1 @attr2(...)` — type token ends at the first
138
+ // whitespace or `@`; everything after the type is attributes.
139
+ const fieldMatch = line.match(/^(\w+)\s+(\w+)(\[\])?(\?)?\s*(.*)$/);
140
+ if (!fieldMatch)
141
+ continue; // skip stray tokens (e.g. a lone closing brace artifact)
142
+ const [, name, type, arrayMark, optionalMark, rest] = fieldMatch;
143
+ fields.push({
144
+ name,
145
+ type,
146
+ isArray: Boolean(arrayMark),
147
+ isOptional: Boolean(optionalMark),
148
+ attributes: parseAttributes(rest),
149
+ });
150
+ }
151
+ return { fields, blockAttributes };
152
+ }
153
+ function parsePrismaSchema(source) {
154
+ const cleaned = stripComments(source);
155
+ const models = extractBlocks(cleaned, 'model').map(({ name, body }) => {
156
+ const { fields, blockAttributes } = parseModelBody(body);
157
+ return { name, fields, blockAttributes };
158
+ });
159
+ const enums = extractBlocks(cleaned, 'enum').map(({ name, body }) => ({
160
+ name,
161
+ values: body
162
+ .split('\n')
163
+ .map((l) => l.trim().split(/\s/)[0])
164
+ .filter((v) => v && !v.startsWith('@')),
165
+ }));
166
+ return { models, enums };
167
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SCALAR_TYPE_MAP = void 0;
4
+ exports.mapPrismaType = mapPrismaType;
5
+ /**
6
+ * Maps Prisma scalar types to prorm `DataTypes` expressions. Enum types
7
+ * aren't in this table — callers check `enumNames` first and build
8
+ * `DataTypes.ENUM(...)` from the enum's own values instead, since the
9
+ * mapping depends on data only the caller has (the parsed `PrismaEnum`).
10
+ */
11
+ const SCALAR_TYPE_MAP = {
12
+ String: 'DataTypes.STRING(191)',
13
+ Int: 'DataTypes.INTEGER()',
14
+ BigInt: 'DataTypes.BIGINT()',
15
+ Float: 'DataTypes.FLOAT()',
16
+ Decimal: 'DataTypes.DECIMAL(65, 30)',
17
+ Boolean: 'DataTypes.BOOLEAN()',
18
+ DateTime: 'DataTypes.DATE()',
19
+ Json: 'DataTypes.JSON()',
20
+ Bytes: 'DataTypes.BLOB()',
21
+ };
22
+ exports.SCALAR_TYPE_MAP = SCALAR_TYPE_MAP;
23
+ /**
24
+ * @param type - A Prisma scalar type name (`String`, `Int`, ...) or an enum name from the same schema.
25
+ * @param enumsByName - Every enum declared in the schema, keyed by name, so an enum reference can be expanded to its values.
26
+ * @throws if `type` is neither a known Prisma scalar nor a declared enum (e.g. an unresolved relation type reached this function by mistake, or a Prisma type this tool doesn't yet map — `Unsupported` rather than a guess, matching this codebase's convention of refusing to invent unverified SQL/type behavior).
27
+ */
28
+ function mapPrismaType(type, enumsByName) {
29
+ const enumValues = enumsByName.get(type);
30
+ if (enumValues) {
31
+ const valuesLiteral = enumValues.map((v) => `'${v.replace(/'/g, "\\'")}'`).join(', ');
32
+ return { dataTypeExpr: `DataTypes.ENUM(${valuesLiteral})`, isEnum: true };
33
+ }
34
+ const mapped = SCALAR_TYPE_MAP[type];
35
+ if (!mapped) {
36
+ throw new Error(`prisma-migrate: unsupported Prisma type "${type}" — no known prorm DataTypes equivalent, and it isn't one of this schema's enums. ` +
37
+ `Supported scalars: ${Object.keys(SCALAR_TYPE_MAP).join(', ')}.`);
38
+ }
39
+ return { dataTypeExpr: mapped, isEnum: false };
40
+ }