nextly 0.0.1 → 0.0.2-alpha.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 (268) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +122 -0
  3. package/dist/_dts-chunks/collections-handler.d-DjgO74Wt.d.ts +20540 -0
  4. package/dist/_dts-chunks/config.d-DNwsDnjs.d.ts +2589 -0
  5. package/dist/_dts-chunks/define-component.d-BUgTHmt3.d.ts +1149 -0
  6. package/dist/_dts-chunks/image-processor.d-OO1PmMrv.d.ts +335 -0
  7. package/dist/_dts-chunks/index.d-axCAzZ7m.d.ts +17842 -0
  8. package/dist/_dts-chunks/media.d-DjDOZo4B.d.ts +117 -0
  9. package/dist/_dts-chunks/on-error.d-CHIKWNxd.d.ts +38 -0
  10. package/dist/_dts-chunks/storage.d-BUhQ2we_.d.ts +404 -0
  11. package/dist/actions/index.d.ts +239 -0
  12. package/dist/actions/index.mjs +281 -0
  13. package/dist/api/auth-state.d.ts +5 -0
  14. package/dist/api/auth-state.mjs +131 -0
  15. package/dist/api/collections-schema-detail.d.ts +56 -0
  16. package/dist/api/collections-schema-detail.mjs +244 -0
  17. package/dist/api/collections-schema-export.d.ts +56 -0
  18. package/dist/api/collections-schema-export.mjs +129 -0
  19. package/dist/api/collections-schema.d.ts +59 -0
  20. package/dist/api/collections-schema.mjs +207 -0
  21. package/dist/api/components-detail.d.ts +50 -0
  22. package/dist/api/components-detail.mjs +132 -0
  23. package/dist/api/components.d.ts +69 -0
  24. package/dist/api/components.mjs +144 -0
  25. package/dist/api/email-providers-default.d.ts +40 -0
  26. package/dist/api/email-providers-default.mjs +75 -0
  27. package/dist/api/email-providers-detail.d.ts +81 -0
  28. package/dist/api/email-providers-detail.mjs +109 -0
  29. package/dist/api/email-providers-test.d.ts +43 -0
  30. package/dist/api/email-providers-test.mjs +114 -0
  31. package/dist/api/email-providers.d.ts +69 -0
  32. package/dist/api/email-providers.mjs +110 -0
  33. package/dist/api/email-send-template.d.ts +41 -0
  34. package/dist/api/email-send-template.mjs +58 -0
  35. package/dist/api/email-send.d.ts +42 -0
  36. package/dist/api/email-send.mjs +58 -0
  37. package/dist/api/email-templates-detail.d.ts +74 -0
  38. package/dist/api/email-templates-detail.mjs +112 -0
  39. package/dist/api/email-templates-layout.d.ts +55 -0
  40. package/dist/api/email-templates-layout.mjs +92 -0
  41. package/dist/api/email-templates-preview.d.ts +48 -0
  42. package/dist/api/email-templates-preview.mjs +93 -0
  43. package/dist/api/email-templates.d.ts +61 -0
  44. package/dist/api/email-templates.mjs +118 -0
  45. package/dist/api/health.d.ts +68 -0
  46. package/dist/api/health.mjs +67 -0
  47. package/dist/api/index.d.ts +54 -0
  48. package/dist/api/index.mjs +16 -0
  49. package/dist/api/media-bulk.d.ts +74 -0
  50. package/dist/api/media-bulk.mjs +196 -0
  51. package/dist/api/media-folders.d.ts +112 -0
  52. package/dist/api/media-folders.mjs +187 -0
  53. package/dist/api/media-handlers.d.ts +102 -0
  54. package/dist/api/media-handlers.mjs +437 -0
  55. package/dist/api/media.d.ts +117 -0
  56. package/dist/api/media.mjs +242 -0
  57. package/dist/api/singles-detail.d.ts +87 -0
  58. package/dist/api/singles-detail.mjs +170 -0
  59. package/dist/api/singles-schema-detail.d.ts +54 -0
  60. package/dist/api/singles-schema-detail.mjs +182 -0
  61. package/dist/api/singles.d.ts +34 -0
  62. package/dist/api/singles.mjs +94 -0
  63. package/dist/api/storage-upload-url.d.ts +48 -0
  64. package/dist/api/storage-upload-url.mjs +202 -0
  65. package/dist/api/uploads.d.ts +109 -0
  66. package/dist/api/uploads.mjs +359 -0
  67. package/dist/auth/index.d.ts +425 -0
  68. package/dist/auth/index.mjs +199 -0
  69. package/dist/boot-apply-PQSYLDIN.mjs +7 -0
  70. package/dist/chunk-2OALJTK6.mjs +489 -0
  71. package/dist/chunk-2Q2SX2CS.mjs +365 -0
  72. package/dist/chunk-2TFX4ND3.mjs +13 -0
  73. package/dist/chunk-2TWPDSYD.mjs +87 -0
  74. package/dist/chunk-2W3DVD7S.mjs +647 -0
  75. package/dist/chunk-2ZFKXPQM.mjs +88 -0
  76. package/dist/chunk-3FA7FKAV.mjs +832 -0
  77. package/dist/chunk-3NZ2KMBL.mjs +58 -0
  78. package/dist/chunk-4MJLT6PZ.mjs +0 -0
  79. package/dist/chunk-56WO4WX7.mjs +0 -0
  80. package/dist/chunk-5APFUGAD.mjs +89 -0
  81. package/dist/chunk-5HMZ644B.mjs +108 -0
  82. package/dist/chunk-67GXH6PR.mjs +32 -0
  83. package/dist/chunk-6JNEPWRW.mjs +14368 -0
  84. package/dist/chunk-6NFHQIJD.mjs +45 -0
  85. package/dist/chunk-7P6ASYW6.mjs +9 -0
  86. package/dist/chunk-A3WPLSDT.mjs +1364 -0
  87. package/dist/chunk-AGJ6F2T3.mjs +144 -0
  88. package/dist/chunk-AK6Z23OX.mjs +1464 -0
  89. package/dist/chunk-APKKRD2G.mjs +102 -0
  90. package/dist/chunk-B2GV2BWH.mjs +73 -0
  91. package/dist/chunk-D5HQBNUB.mjs +74 -0
  92. package/dist/chunk-DNNG377Z.mjs +204 -0
  93. package/dist/chunk-DP3G27G5.mjs +135 -0
  94. package/dist/chunk-DV6WVX2Q.mjs +0 -0
  95. package/dist/chunk-DXGGXIUZ.mjs +57 -0
  96. package/dist/chunk-EGXBZCGC.mjs +943 -0
  97. package/dist/chunk-ERCNLX3V.mjs +176 -0
  98. package/dist/chunk-FQULBZ53.mjs +850 -0
  99. package/dist/chunk-G2AA4QLC.mjs +262 -0
  100. package/dist/chunk-GDBJ5JCU.mjs +488 -0
  101. package/dist/chunk-GJNSJU4S.mjs +19 -0
  102. package/dist/chunk-GZ6DCQKC.mjs +69 -0
  103. package/dist/chunk-H26B4FYG.mjs +167 -0
  104. package/dist/chunk-I4JMR3UR.mjs +21 -0
  105. package/dist/chunk-INV7QKLG.mjs +508 -0
  106. package/dist/chunk-IUDOC7N7.mjs +46 -0
  107. package/dist/chunk-IZWPRDC3.mjs +206 -0
  108. package/dist/chunk-KIMNCZGV.mjs +15 -0
  109. package/dist/chunk-L6HW2DA7.mjs +15 -0
  110. package/dist/chunk-LAZXX4HR.mjs +100 -0
  111. package/dist/chunk-LDKCUMHK.mjs +95 -0
  112. package/dist/chunk-LRXMECUA.mjs +0 -0
  113. package/dist/chunk-M52VMPGA.mjs +119 -0
  114. package/dist/chunk-MGUWEEI6.mjs +160 -0
  115. package/dist/chunk-NRUWQ5Z7.mjs +419 -0
  116. package/dist/chunk-NSEFNNU4.mjs +25360 -0
  117. package/dist/chunk-NTHVDFGO.mjs +138 -0
  118. package/dist/chunk-O3QHXMOX.mjs +3166 -0
  119. package/dist/chunk-P7NH2OSC.mjs +2605 -0
  120. package/dist/chunk-PKMABBB5.mjs +184 -0
  121. package/dist/chunk-PWS6XGJK.mjs +76 -0
  122. package/dist/chunk-R6JJQHFC.mjs +20 -0
  123. package/dist/chunk-RJLLGGPG.mjs +0 -0
  124. package/dist/chunk-SBACDPNX.mjs +689 -0
  125. package/dist/chunk-TO5AFLVQ.mjs +124 -0
  126. package/dist/chunk-TS7GHTG2.mjs +5436 -0
  127. package/dist/chunk-UJ2IMJ4W.mjs +133 -0
  128. package/dist/chunk-UOP63Q54.mjs +102 -0
  129. package/dist/chunk-UUOFWCM6.mjs +78 -0
  130. package/dist/chunk-V4EQTOA4.mjs +893 -0
  131. package/dist/chunk-VJ66NCL4.mjs +193 -0
  132. package/dist/chunk-VQJQHVEV.mjs +29 -0
  133. package/dist/chunk-VTJADRO3.mjs +141 -0
  134. package/dist/chunk-VWF3JO32.mjs +0 -0
  135. package/dist/chunk-W4MGXIRR.mjs +27 -0
  136. package/dist/chunk-W5KKPZT5.mjs +1204 -0
  137. package/dist/chunk-WD34YQ6T.mjs +381 -0
  138. package/dist/chunk-WZBYMYVW.mjs +14 -0
  139. package/dist/chunk-X23WKS3Z.mjs +50 -0
  140. package/dist/chunk-X7TXCYYN.mjs +6496 -0
  141. package/dist/chunk-XGI4EMS3.mjs +140 -0
  142. package/dist/chunk-XZKLBMN6.mjs +1153 -0
  143. package/dist/chunk-YB7INWPY.mjs +0 -0
  144. package/dist/chunk-YV4Y7SDL.mjs +83 -0
  145. package/dist/chunk-YZNBLFIW.mjs +1688 -0
  146. package/dist/chunk-YZZCTONM.mjs +263 -0
  147. package/dist/chunk-ZE6A3FYH.mjs +289 -0
  148. package/dist/cli/nextly.mjs +68 -0
  149. package/dist/cli/utils/index.d.ts +449 -0
  150. package/dist/cli/utils/index.mjs +49 -0
  151. package/dist/component-schema-service-5577KVW6.mjs +11 -0
  152. package/dist/config-loader-23YEMC3Z.mjs +23 -0
  153. package/dist/config.d.ts +44 -0
  154. package/dist/config.mjs +109 -0
  155. package/dist/container-ORGFGYSZ.mjs +9 -0
  156. package/dist/database/index.d.ts +12 -0
  157. package/dist/database/index.mjs +40 -0
  158. package/dist/database/seeders/index.d.ts +93 -0
  159. package/dist/database/seeders/index.mjs +47 -0
  160. package/dist/db-sync-demote-LJGKLB3S.mjs +117 -0
  161. package/dist/db-sync-promote-B26VSYQF.mjs +113 -0
  162. package/dist/dev-reload-broadcaster-B73IQ53V.mjs +25 -0
  163. package/dist/dist-M2NOU37V.mjs +19 -0
  164. package/dist/drizzle-kit-lazy-D2M2PXR2.mjs +13 -0
  165. package/dist/dynamic-collection-schema-service-IEXTPIZ7.mjs +8 -0
  166. package/dist/errors/index.d.ts +159 -0
  167. package/dist/errors/index.mjs +10 -0
  168. package/dist/factory-IWMBKUJM.mjs +15 -0
  169. package/dist/first-run-QIVKWJIF.mjs +63 -0
  170. package/dist/fresh-push-NR67DC3R.mjs +8 -0
  171. package/dist/index.d.ts +4175 -0
  172. package/dist/index.mjs +1336 -0
  173. package/dist/local-plugin-PTET4NAT.mjs +7 -0
  174. package/dist/logger-NU46DXNY.mjs +15 -0
  175. package/dist/logger-YE4TC7ZN.mjs +9 -0
  176. package/dist/migration-journal-EP532Y4L.mjs +139 -0
  177. package/dist/migrations/mysql/0000_eager_sentry.sql +174 -0
  178. package/dist/migrations/mysql/0001_soft_giant_girl.sql +27 -0
  179. package/dist/migrations/mysql/0002_media_table.sql +24 -0
  180. package/dist/migrations/mysql/0003_dynamic_singles.sql +37 -0
  181. package/dist/migrations/mysql/0004_dynamic_components.sql +35 -0
  182. package/dist/migrations/mysql/0005_user_management_tables.sql +92 -0
  183. package/dist/migrations/mysql/0006_api_keys.sql +36 -0
  184. package/dist/migrations/mysql/0007_general_settings.sql +20 -0
  185. package/dist/migrations/mysql/0008_site_settings_logo_url.sql +9 -0
  186. package/dist/migrations/mysql/0009_activity_log.sql +30 -0
  187. package/dist/migrations/mysql/0010_site_settings_sidebar.sql +13 -0
  188. package/dist/migrations/mysql/0011_missing_tables_and_columns.sql +54 -0
  189. package/dist/migrations/mysql/0012_image_sizes_and_focal_point.sql +30 -0
  190. package/dist/migrations/mysql/0012_media_folders.sql +43 -0
  191. package/dist/migrations/mysql/0013_user_brute_force_protection.sql +31 -0
  192. package/dist/migrations/mysql/0014_email_template_attachments.sql +12 -0
  193. package/dist/migrations/mysql/0015_media_uploaded_by_nullable.sql +15 -0
  194. package/dist/migrations/mysql/20260429_000000_000_initial_journal.sql +22 -0
  195. package/dist/migrations/mysql/20260501_000000_journal_batch.sql +17 -0
  196. package/dist/migrations/mysql/20260501_000001_audit_log.sql +24 -0
  197. package/dist/migrations/mysql/20260504_000000_nextly_meta.sql +21 -0
  198. package/dist/migrations/mysql/meta/0000_snapshot.json +1005 -0
  199. package/dist/migrations/mysql/meta/0001_snapshot.json +1099 -0
  200. package/dist/migrations/mysql/meta/_journal.json +41 -0
  201. package/dist/migrations/postgresql/0000_misty_king_bedlam.sql +169 -0
  202. package/dist/migrations/postgresql/0001_perpetual_captain_marvel.sql +8 -0
  203. package/dist/migrations/postgresql/0002_sad_spectrum.sql +16 -0
  204. package/dist/migrations/postgresql/0003_hesitant_ultron.sql +17 -0
  205. package/dist/migrations/postgresql/0004_media_table.sql +24 -0
  206. package/dist/migrations/postgresql/0005_media_folders.sql +36 -0
  207. package/dist/migrations/postgresql/0006_dynamic_collections_update.sql +50 -0
  208. package/dist/migrations/postgresql/0007_dynamic_singles.sql +38 -0
  209. package/dist/migrations/postgresql/0008_dynamic_components.sql +37 -0
  210. package/dist/migrations/postgresql/0009_user_management_tables.sql +95 -0
  211. package/dist/migrations/postgresql/0010_api_keys.sql +34 -0
  212. package/dist/migrations/postgresql/0011_general_settings.sql +20 -0
  213. package/dist/migrations/postgresql/0012_site_settings_logo_url.sql +9 -0
  214. package/dist/migrations/postgresql/0013_activity_log.sql +29 -0
  215. package/dist/migrations/postgresql/0014_image_sizes_and_focal_point.sql +33 -0
  216. package/dist/migrations/postgresql/0014_site_settings_sidebar.sql +13 -0
  217. package/dist/migrations/postgresql/0015_user_brute_force_protection.sql +29 -0
  218. package/dist/migrations/postgresql/0016_email_template_attachments.sql +12 -0
  219. package/dist/migrations/postgresql/0017_media_uploaded_by_nullable.sql +15 -0
  220. package/dist/migrations/postgresql/20260429_000000_000_initial_journal.sql +24 -0
  221. package/dist/migrations/postgresql/20260501_000000_journal_batch.sql +17 -0
  222. package/dist/migrations/postgresql/20260501_000001_audit_log.sql +24 -0
  223. package/dist/migrations/postgresql/20260504_000000_nextly_meta.sql +22 -0
  224. package/dist/migrations/postgresql/meta/0000_snapshot.json +1286 -0
  225. package/dist/migrations/postgresql/meta/0001_snapshot.json +1407 -0
  226. package/dist/migrations/postgresql/meta/0002_snapshot.json +1552 -0
  227. package/dist/migrations/postgresql/meta/0003_snapshot.json +1695 -0
  228. package/dist/migrations/postgresql/meta/0010_snapshot.json +2345 -0
  229. package/dist/migrations/postgresql/meta/_journal.json +90 -0
  230. package/dist/migrations/sqlite/0000_api_keys.sql +34 -0
  231. package/dist/migrations/sqlite/0001_general_settings.sql +20 -0
  232. package/dist/migrations/sqlite/0002_site_settings_logo_url.sql +9 -0
  233. package/dist/migrations/sqlite/0003_activity_log.sql +29 -0
  234. package/dist/migrations/sqlite/0004_image_sizes_and_focal_point.sql +29 -0
  235. package/dist/migrations/sqlite/0004_site_settings_sidebar.sql +11 -0
  236. package/dist/migrations/sqlite/0005_user_brute_force_protection.sql +29 -0
  237. package/dist/migrations/sqlite/0006_email_template_attachments.sql +12 -0
  238. package/dist/migrations/sqlite/0007_media_uploaded_by_nullable.sql +111 -0
  239. package/dist/migrations/sqlite/20260429_000000_000_initial_journal.sql +24 -0
  240. package/dist/migrations/sqlite/20260501_000000_journal_batch.sql +19 -0
  241. package/dist/migrations/sqlite/20260501_000001_audit_log.sql +24 -0
  242. package/dist/migrations/sqlite/20260504_000000_nextly_meta.sql +21 -0
  243. package/dist/migrations/sqlite/20260505_000000_user_management_tables.sql +77 -0
  244. package/dist/next.d.ts +57 -0
  245. package/dist/next.mjs +55 -0
  246. package/dist/observability/index.d.ts +87 -0
  247. package/dist/observability/index.mjs +57 -0
  248. package/dist/permissions-3DZZQZMI.mjs +39 -0
  249. package/dist/pipeline-YOML7SWF.mjs +29 -0
  250. package/dist/preview-ZZTR3QGS.mjs +9 -0
  251. package/dist/program-PW6UB2ZC.mjs +5934 -0
  252. package/dist/reconcile-single-tables-7ENVXJGB.mjs +7 -0
  253. package/dist/register-SF6E6FVU.mjs +49 -0
  254. package/dist/reload-config-HWQ4G5MM.mjs +23 -0
  255. package/dist/resolve-single-table-name-JSOMUB3R.mjs +7 -0
  256. package/dist/routeHandler-UNMMJIBM.mjs +77 -0
  257. package/dist/runtime-schema-generator-NRA6A6Z6.mjs +8 -0
  258. package/dist/runtime.d.ts +120 -0
  259. package/dist/runtime.mjs +73 -0
  260. package/dist/schema-hash-FMMG6VPJ.mjs +13 -0
  261. package/dist/schema-registry-EQ36FZDP.mjs +7 -0
  262. package/dist/scripts/load-env.mjs +42 -0
  263. package/dist/storage/index.d.ts +566 -0
  264. package/dist/storage/index.mjs +45 -0
  265. package/dist/super-admin-G5ZK5F4T.mjs +39 -0
  266. package/dist/system-table-service-WGSRVEGT.mjs +17 -0
  267. package/dist/users-7KELGRYJ.mjs +38 -0
  268. package/package.json +308 -9
@@ -0,0 +1,689 @@
1
+ import {
2
+ getColumnDescriptor,
3
+ getSystemColumnDescriptors
4
+ } from "./chunk-DNNG377Z.mjs";
5
+
6
+ // src/domains/schema/pipeline/classifier/count-helpers.ts
7
+ import { sql } from "drizzle-orm";
8
+ var SAFE_IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
9
+ function quoteIdent(name, dialect) {
10
+ if (!SAFE_IDENT.test(name)) {
11
+ throw new Error(
12
+ `unsafe identifier: ${name} (only [A-Za-z_][A-Za-z0-9_]* allowed)`
13
+ );
14
+ }
15
+ return dialect === "mysql" ? `\`${name}\`` : `"${name}"`;
16
+ }
17
+ function asNumber(raw) {
18
+ if (raw === void 0) return 0;
19
+ return typeof raw === "string" ? parseInt(raw, 10) : raw;
20
+ }
21
+ function extractCount(raw, dialect) {
22
+ if (dialect === "postgresql") {
23
+ const rows = raw.rows;
24
+ if (!Array.isArray(rows) || rows.length === 0) {
25
+ throw new Error("PG count query returned no rows");
26
+ }
27
+ return asNumber(rows[0].count);
28
+ }
29
+ if (dialect === "mysql") {
30
+ if (Array.isArray(raw) && raw.length > 0 && Array.isArray(raw[0])) {
31
+ const rows = raw[0];
32
+ if (rows.length === 0)
33
+ throw new Error("MySQL count query returned no rows");
34
+ return asNumber(rows[0].count);
35
+ }
36
+ if (Array.isArray(raw)) {
37
+ const rows = raw;
38
+ if (rows.length === 0)
39
+ throw new Error("MySQL count query returned no rows");
40
+ return asNumber(rows[0].count);
41
+ }
42
+ throw new Error("MySQL count query returned unrecognized shape");
43
+ }
44
+ throw new Error(`unrecognized dialect for extractCount: ${dialect}`);
45
+ }
46
+ async function countNulls(db, dialect, table, column) {
47
+ const tbl = quoteIdent(table, dialect);
48
+ const col = quoteIdent(column, dialect);
49
+ const query = sql.raw(
50
+ `SELECT COUNT(*) AS count FROM ${tbl} WHERE ${col} IS NULL`
51
+ );
52
+ if (dialect === "sqlite") {
53
+ const dbTyped2 = db;
54
+ const rows = dbTyped2.all(query);
55
+ if (rows.length === 0)
56
+ throw new Error("SQLite count query returned no rows");
57
+ return asNumber(rows[0].count);
58
+ }
59
+ const dbTyped = db;
60
+ const result = await dbTyped.execute(query);
61
+ return extractCount(result, dialect);
62
+ }
63
+ async function countRows(db, dialect, table) {
64
+ const tbl = quoteIdent(table, dialect);
65
+ const query = sql.raw(`SELECT COUNT(*) AS count FROM ${tbl}`);
66
+ if (dialect === "sqlite") {
67
+ const dbTyped2 = db;
68
+ const rows = dbTyped2.all(query);
69
+ if (rows.length === 0)
70
+ throw new Error("SQLite count query returned no rows");
71
+ return asNumber(rows[0].count);
72
+ }
73
+ const dbTyped = db;
74
+ const result = await dbTyped.execute(query);
75
+ return extractCount(result, dialect);
76
+ }
77
+
78
+ // src/domains/schema/pipeline/resolution/types.ts
79
+ function formatEventId(kind, table, column) {
80
+ return `${kind}:${table}.${column}`;
81
+ }
82
+
83
+ // src/domains/schema/pipeline/classifier/type-warnings.ts
84
+ function buildPerDialectWarning(fromType, toType) {
85
+ const change = `${fromType} -> ${toType}`;
86
+ return {
87
+ pg: `Postgres: ${change} will fail if any value cannot be cast to ${toType}. Failed apply rolls back the entire transaction.`,
88
+ mysql: `MySQL: ${change} silently coerces non-conforming values (numeric -> 0, invalid date -> 0000-00-00, truncated strings). No error raised.`,
89
+ sqlite: `SQLite: ${change} uses storage-class affinity \u2014 values that don't match the new affinity are silently coerced (e.g. text "abc" stored as "abc" in an integer column, "42" stored as 42). No error raised.`
90
+ };
91
+ }
92
+
93
+ // src/domains/schema/pipeline/classifier/type-widening.ts
94
+ var VARCHAR_RE = /^varchar\((\d+)\)$/i;
95
+ var CHAR_RE = /^char\((\d+)\)$/i;
96
+ var PG_INT_RANK = {
97
+ smallint: 1,
98
+ int2: 1,
99
+ int: 2,
100
+ integer: 2,
101
+ int4: 2,
102
+ bigint: 3,
103
+ int8: 3
104
+ };
105
+ var MYSQL_INT_RANK = {
106
+ tinyint: 1,
107
+ smallint: 2,
108
+ mediumint: 3,
109
+ int: 4,
110
+ integer: 4,
111
+ bigint: 5
112
+ };
113
+ var MYSQL_TEXT_RANK = {
114
+ tinytext: 1,
115
+ text: 2,
116
+ mediumtext: 3,
117
+ longtext: 4
118
+ };
119
+ function widensVarchar(from, to) {
120
+ const fm = VARCHAR_RE.exec(from);
121
+ const tm = VARCHAR_RE.exec(to);
122
+ if (fm && tm) return parseInt(tm[1], 10) >= parseInt(fm[1], 10);
123
+ return null;
124
+ }
125
+ function isWideningChange(fromType, toType, dialect) {
126
+ const from = fromType.toLowerCase().trim();
127
+ const to = toType.toLowerCase().trim();
128
+ if (from === to) return true;
129
+ if (dialect === "sqlite") return false;
130
+ const vw = widensVarchar(from, to);
131
+ if (vw !== null) return vw;
132
+ const fromIsCharFamily = CHAR_RE.test(from) || from === "bpchar";
133
+ if (fromIsCharFamily && (to === "varchar" || VARCHAR_RE.test(to))) {
134
+ return true;
135
+ }
136
+ if (dialect === "postgresql" && from === "bpchar" && to === "text") {
137
+ return true;
138
+ }
139
+ if (dialect === "postgresql" && (from === "varchar" || VARCHAR_RE.test(from)) && to === "text") {
140
+ return true;
141
+ }
142
+ if (dialect === "mysql" && VARCHAR_RE.test(from) && MYSQL_TEXT_RANK[to] !== void 0) {
143
+ return true;
144
+ }
145
+ const intRank = dialect === "postgresql" ? PG_INT_RANK : MYSQL_INT_RANK;
146
+ if (intRank[from] !== void 0 && intRank[to] !== void 0) {
147
+ return intRank[to] >= intRank[from];
148
+ }
149
+ if (dialect === "mysql" && MYSQL_TEXT_RANK[from] !== void 0 && MYSQL_TEXT_RANK[to] !== void 0) {
150
+ return MYSQL_TEXT_RANK[to] >= MYSQL_TEXT_RANK[from];
151
+ }
152
+ return false;
153
+ }
154
+
155
+ // src/domains/schema/pipeline/classifier/classifier.ts
156
+ var RealClassifier = class {
157
+ async classify(args) {
158
+ const events = [];
159
+ for (const op of args.operations) {
160
+ if (op.type === "change_column_nullable" && op.fromNullable === true && op.toNullable === false) {
161
+ const nullCount = await args.countNulls(op.tableName, op.columnName);
162
+ if (nullCount > 0) {
163
+ const tableRowCount = await args.countRows(op.tableName);
164
+ events.push({
165
+ id: formatEventId(
166
+ "add_not_null_with_nulls",
167
+ op.tableName,
168
+ op.columnName
169
+ ),
170
+ kind: "add_not_null_with_nulls",
171
+ tableName: op.tableName,
172
+ columnName: op.columnName,
173
+ nullCount,
174
+ tableRowCount,
175
+ applicableResolutions: [
176
+ "provide_default",
177
+ "make_optional",
178
+ "delete_nonconforming",
179
+ "abort"
180
+ ]
181
+ });
182
+ }
183
+ } else if (op.type === "change_column_type") {
184
+ const widening = isWideningChange(op.fromType, op.toType, args.dialect);
185
+ if (!widening) {
186
+ events.push({
187
+ id: formatEventId("type_change", op.tableName, op.columnName),
188
+ kind: "type_change",
189
+ tableName: op.tableName,
190
+ columnName: op.columnName,
191
+ fromType: op.fromType,
192
+ toType: op.toType,
193
+ isWidening: false,
194
+ perDialectWarning: buildPerDialectWarning(op.fromType, op.toType)
195
+ });
196
+ }
197
+ } else if (op.type === "add_column" && op.column.nullable === false && op.column.default === void 0) {
198
+ const tableRowCount = await args.countRows(op.tableName);
199
+ if (tableRowCount > 0) {
200
+ events.push({
201
+ id: formatEventId(
202
+ "add_required_field_no_default",
203
+ op.tableName,
204
+ op.column.name
205
+ ),
206
+ kind: "add_required_field_no_default",
207
+ tableName: op.tableName,
208
+ columnName: op.column.name,
209
+ tableRowCount,
210
+ applicableResolutions: [
211
+ "provide_default",
212
+ "make_optional",
213
+ "abort"
214
+ ]
215
+ });
216
+ }
217
+ }
218
+ }
219
+ const hasInteractive = events.some((e) => e.kind !== "type_change");
220
+ const level = hasInteractive ? "interactive" : events.length > 0 ? "destructive" : "safe";
221
+ return { level, events };
222
+ }
223
+ };
224
+
225
+ // src/domains/schema/pipeline/diff/build-from-fields.ts
226
+ function buildDesiredTableFromFields(tableName, fields, dialect, options = {}) {
227
+ const columns = [];
228
+ const hasTitleField = fields.some((f) => f.name === "title");
229
+ const hasSlugField = fields.some((f) => f.name === "slug");
230
+ for (const reserved of getSystemColumnDescriptors(dialect, {
231
+ hasTitleField,
232
+ hasSlugField,
233
+ hasStatus: options.hasStatus
234
+ })) {
235
+ columns.push({
236
+ name: reserved.name,
237
+ type: reserved.dialectType,
238
+ nullable: reserved.nullable,
239
+ default: void 0
240
+ });
241
+ }
242
+ for (const field of fields) {
243
+ const desc = getColumnDescriptor(
244
+ // The descriptor's input type is FieldDefinition; this util is
245
+ // structurally compatible (same name/type/required/hasMany/relationTo
246
+ // keys). Cast through unknown to bridge the two surface types
247
+ // without leaking either back through the module graph.
248
+ field,
249
+ dialect
250
+ );
251
+ if (!desc) continue;
252
+ columns.push({
253
+ name: desc.name,
254
+ type: desc.dialectType,
255
+ nullable: desc.nullable,
256
+ default: void 0
257
+ });
258
+ }
259
+ return { name: tableName, columns };
260
+ }
261
+ function buildDesiredTableFromComponentFields(tableName, fields, dialect) {
262
+ const columns = [];
263
+ if (dialect === "postgresql") {
264
+ columns.push({ name: "id", type: "text", nullable: false, default: void 0 });
265
+ columns.push({ name: "_parent_id", type: "text", nullable: false, default: void 0 });
266
+ columns.push({ name: "_parent_table", type: "varchar", nullable: false, default: void 0 });
267
+ columns.push({ name: "_parent_field", type: "varchar", nullable: false, default: void 0 });
268
+ columns.push({ name: "_order", type: "int4", nullable: true, default: void 0 });
269
+ columns.push({ name: "_component_type", type: "varchar", nullable: true, default: void 0 });
270
+ } else if (dialect === "mysql") {
271
+ columns.push({ name: "id", type: "varchar(36)", nullable: false, default: void 0 });
272
+ columns.push({ name: "_parent_id", type: "varchar(36)", nullable: false, default: void 0 });
273
+ columns.push({ name: "_parent_table", type: "varchar(255)", nullable: false, default: void 0 });
274
+ columns.push({ name: "_parent_field", type: "varchar(255)", nullable: false, default: void 0 });
275
+ columns.push({ name: "_order", type: "int(11)", nullable: true, default: void 0 });
276
+ columns.push({ name: "_component_type", type: "varchar(255)", nullable: true, default: void 0 });
277
+ } else {
278
+ columns.push({ name: "id", type: "text", nullable: false, default: void 0 });
279
+ columns.push({ name: "_parent_id", type: "text", nullable: false, default: void 0 });
280
+ columns.push({ name: "_parent_table", type: "text", nullable: false, default: void 0 });
281
+ columns.push({ name: "_parent_field", type: "text", nullable: false, default: void 0 });
282
+ columns.push({ name: "_order", type: "integer", nullable: true, default: void 0 });
283
+ columns.push({ name: "_component_type", type: "text", nullable: true, default: void 0 });
284
+ }
285
+ for (const field of fields) {
286
+ const desc = getColumnDescriptor(
287
+ field,
288
+ dialect
289
+ );
290
+ if (!desc) continue;
291
+ columns.push({
292
+ name: desc.name,
293
+ type: desc.dialectType,
294
+ nullable: desc.nullable,
295
+ default: void 0
296
+ });
297
+ }
298
+ if (dialect === "postgresql") {
299
+ columns.push({ name: "created_at", type: "timestamp", nullable: false, default: void 0 });
300
+ columns.push({ name: "updated_at", type: "timestamp", nullable: false, default: void 0 });
301
+ } else if (dialect === "mysql") {
302
+ columns.push({ name: "created_at", type: "datetime", nullable: false, default: void 0 });
303
+ columns.push({ name: "updated_at", type: "datetime", nullable: false, default: void 0 });
304
+ } else {
305
+ columns.push({ name: "created_at", type: "integer", nullable: false, default: void 0 });
306
+ columns.push({ name: "updated_at", type: "integer", nullable: false, default: void 0 });
307
+ }
308
+ return { name: tableName, columns };
309
+ }
310
+
311
+ // src/domains/schema/pipeline/diff/diff.ts
312
+ function diffSnapshots(prev, cur) {
313
+ const prevByName = /* @__PURE__ */ new Map();
314
+ for (const t of prev.tables) prevByName.set(t.name, t);
315
+ const curByName = /* @__PURE__ */ new Map();
316
+ for (const t of cur.tables) curByName.set(t.name, t);
317
+ const tableOps = [];
318
+ const columnOps = [];
319
+ const allTableNames = [
320
+ .../* @__PURE__ */ new Set([...prevByName.keys(), ...curByName.keys()])
321
+ ].sort();
322
+ for (const name of allTableNames) {
323
+ const prevT = prevByName.get(name);
324
+ const curT = curByName.get(name);
325
+ if (!prevT && curT) {
326
+ tableOps.push({ type: "add_table", table: curT });
327
+ continue;
328
+ }
329
+ if (prevT && !curT) {
330
+ tableOps.push({
331
+ type: "drop_table",
332
+ tableName: name
333
+ });
334
+ continue;
335
+ }
336
+ if (prevT && curT) {
337
+ columnOps.push(...diffColumns(name, prevT.columns, curT.columns));
338
+ }
339
+ }
340
+ return [...tableOps, ...columnOps];
341
+ }
342
+ function diffColumns(tableName, prev, cur) {
343
+ const prevByName = /* @__PURE__ */ new Map();
344
+ for (const c of prev) prevByName.set(c.name, c);
345
+ const curByName = /* @__PURE__ */ new Map();
346
+ for (const c of cur) curByName.set(c.name, c);
347
+ const drops = [];
348
+ const adds = [];
349
+ const typeChanges = [];
350
+ const nullableChanges = [];
351
+ const defaultChanges = [];
352
+ const allColumnNames = [
353
+ .../* @__PURE__ */ new Set([...prevByName.keys(), ...curByName.keys()])
354
+ ].sort();
355
+ for (const name of allColumnNames) {
356
+ const prevC = prevByName.get(name);
357
+ const curC = curByName.get(name);
358
+ if (!prevC && curC) {
359
+ adds.push({ type: "add_column", tableName, column: curC });
360
+ continue;
361
+ }
362
+ if (prevC && !curC) {
363
+ drops.push({
364
+ type: "drop_column",
365
+ tableName,
366
+ columnName: name,
367
+ columnType: prevC.type
368
+ });
369
+ continue;
370
+ }
371
+ if (prevC && curC) {
372
+ if (prevC.type !== curC.type) {
373
+ typeChanges.push({
374
+ type: "change_column_type",
375
+ tableName,
376
+ columnName: name,
377
+ fromType: prevC.type,
378
+ toType: curC.type
379
+ });
380
+ }
381
+ if (prevC.nullable !== curC.nullable) {
382
+ nullableChanges.push({
383
+ type: "change_column_nullable",
384
+ tableName,
385
+ columnName: name,
386
+ fromNullable: prevC.nullable,
387
+ toNullable: curC.nullable
388
+ });
389
+ }
390
+ if (prevC.default !== curC.default) {
391
+ defaultChanges.push({
392
+ type: "change_column_default",
393
+ tableName,
394
+ columnName: name,
395
+ fromDefault: prevC.default,
396
+ toDefault: curC.default
397
+ });
398
+ }
399
+ }
400
+ }
401
+ return [
402
+ ...drops,
403
+ ...adds,
404
+ ...typeChanges,
405
+ ...nullableChanges,
406
+ ...defaultChanges
407
+ ];
408
+ }
409
+
410
+ // src/domains/schema/pipeline/diff/introspect-live.ts
411
+ import { sql as sql2 } from "drizzle-orm";
412
+ async function introspectLiveSnapshot(db, dialect, tableNames) {
413
+ if (tableNames.length === 0) return { tables: [] };
414
+ const tableNamesIn = sql2.join(
415
+ tableNames.map((t) => sql2`${t}`),
416
+ sql2`, `
417
+ );
418
+ if (dialect === "postgresql") {
419
+ const dbTyped2 = db;
420
+ const result = await dbTyped2.execute(
421
+ sql2`SELECT table_name, column_name, udt_name, is_nullable, column_default
422
+ FROM information_schema.columns
423
+ WHERE table_schema = 'public'
424
+ AND table_name IN (${tableNamesIn})
425
+ ORDER BY table_name, ordinal_position`
426
+ );
427
+ return buildSnapshotFromPgRows(result.rows);
428
+ }
429
+ if (dialect === "mysql") {
430
+ const dbTyped2 = db;
431
+ const result = await dbTyped2.execute(
432
+ sql2`SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT
433
+ FROM information_schema.columns
434
+ WHERE TABLE_SCHEMA = DATABASE()
435
+ AND TABLE_NAME IN (${tableNamesIn})
436
+ ORDER BY TABLE_NAME, ORDINAL_POSITION`
437
+ );
438
+ const rows = Array.isArray(result) && result.length > 0 && Array.isArray(result[0]) ? result[0] : result;
439
+ return buildSnapshotFromMysqlRows(rows);
440
+ }
441
+ const dbTyped = db;
442
+ const tables = [];
443
+ for (const table of tableNames) {
444
+ const rows = await dbTyped.all(
445
+ sql2`PRAGMA table_info(${sql2.identifier(table)})`
446
+ );
447
+ if (rows.length === 0) continue;
448
+ tables.push({
449
+ name: table,
450
+ columns: rows.map(
451
+ (r) => ({
452
+ name: r.name,
453
+ // SQLite's PRAGMA table_info auto-uppercases the type name
454
+ // ("text" becomes "TEXT"), even though Drizzle emits lowercase
455
+ // declarations in CREATE TABLE. The
456
+ // `field-column-descriptor` (the desired-side source of
457
+ // truth) renders lowercase tokens to match drizzle-orm's
458
+ // own introspection convention. Without this lowercase
459
+ // pass, every boot/HMR diff sees fake `TEXT -> text`
460
+ // type-change events on every column and classifies the
461
+ // collection as "needs review", which silently blocks
462
+ // legitimate code-first applies (rename, add, drop) from
463
+ // ever running. Lowercasing here is safe because SQLite
464
+ // type names are case-insensitive at the engine level.
465
+ type: r.type.toLowerCase(),
466
+ // SQLite stores notnull as 0/1 integer.
467
+ nullable: r.notnull === 0,
468
+ // dflt_value can be string, number, null, or undefined.
469
+ // Coerce primitives to string; treat anything non-primitive as
470
+ // missing (defensive - SQLite never returns object defaults).
471
+ default: stringifyDefault(r.dflt_value)
472
+ })
473
+ )
474
+ });
475
+ }
476
+ return { tables };
477
+ }
478
+ function stringifyDefault(value) {
479
+ if (value === null || value === void 0) return void 0;
480
+ if (typeof value === "string") return value;
481
+ if (typeof value === "number") return value.toString();
482
+ if (typeof value === "boolean") return value ? "true" : "false";
483
+ if (typeof value === "bigint") return value.toString();
484
+ return void 0;
485
+ }
486
+ function buildSnapshotFromPgRows(rows) {
487
+ const byTable = /* @__PURE__ */ new Map();
488
+ for (const r of rows) {
489
+ let cols = byTable.get(r.table_name);
490
+ if (!cols) {
491
+ cols = [];
492
+ byTable.set(r.table_name, cols);
493
+ }
494
+ cols.push({
495
+ name: r.column_name,
496
+ type: r.udt_name,
497
+ nullable: r.is_nullable === "YES",
498
+ default: r.column_default ?? void 0
499
+ });
500
+ }
501
+ return {
502
+ tables: [...byTable.entries()].map(
503
+ ([name, columns]) => ({ name, columns })
504
+ )
505
+ };
506
+ }
507
+ function buildSnapshotFromMysqlRows(rows) {
508
+ const byTable = /* @__PURE__ */ new Map();
509
+ for (const r of rows) {
510
+ let cols = byTable.get(r.TABLE_NAME);
511
+ if (!cols) {
512
+ cols = [];
513
+ byTable.set(r.TABLE_NAME, cols);
514
+ }
515
+ cols.push({
516
+ name: r.COLUMN_NAME,
517
+ type: r.COLUMN_TYPE,
518
+ nullable: r.IS_NULLABLE === "YES",
519
+ default: r.COLUMN_DEFAULT ?? void 0
520
+ });
521
+ }
522
+ return {
523
+ tables: [...byTable.entries()].map(
524
+ ([name, columns]) => ({ name, columns })
525
+ )
526
+ };
527
+ }
528
+
529
+ // src/domains/schema/pipeline/rename-detector-type-families.ts
530
+ var PG_FAMILIES = {
531
+ // bpchar is what PG's information_schema.columns.udt_name returns for
532
+ // char(N) columns (blank-padded char). Without it here, a legitimate
533
+ // char(N) -> text rename would default to drop_and_add.
534
+ text: ["text", "varchar", "char", "bpchar", "character", "character varying"],
535
+ integer: [
536
+ "smallint",
537
+ "integer",
538
+ "int",
539
+ "int2",
540
+ "int4",
541
+ "int8",
542
+ "bigint",
543
+ "serial",
544
+ "bigserial",
545
+ "smallserial"
546
+ ],
547
+ decimal: [
548
+ "decimal",
549
+ "numeric",
550
+ "real",
551
+ "double precision",
552
+ "double",
553
+ "float"
554
+ ],
555
+ boolean: ["boolean", "bool"],
556
+ uuid: ["uuid"],
557
+ json: ["json", "jsonb"],
558
+ date_only: ["date"],
559
+ time_only: [
560
+ "time",
561
+ "timetz",
562
+ "time with time zone",
563
+ "time without time zone"
564
+ ],
565
+ timestamp: [
566
+ "timestamp",
567
+ "timestamptz",
568
+ "timestamp with time zone",
569
+ "timestamp without time zone"
570
+ ],
571
+ binary: ["bytea"]
572
+ };
573
+ var MYSQL_FAMILIES = {
574
+ text: ["text", "varchar", "char", "tinytext", "mediumtext", "longtext"],
575
+ integer: ["tinyint", "smallint", "mediumint", "int", "integer", "bigint"],
576
+ decimal: ["decimal", "numeric", "float", "double", "real"],
577
+ boolean: ["boolean", "bool"],
578
+ uuid: [],
579
+ json: ["json"],
580
+ date_only: ["date"],
581
+ time_only: ["time"],
582
+ timestamp: ["timestamp", "datetime"],
583
+ binary: ["binary", "varbinary", "tinyblob", "blob", "mediumblob", "longblob"]
584
+ };
585
+ var SQLITE_FAMILIES = {
586
+ text: ["text", "varchar", "char", "character"],
587
+ integer: ["integer", "int", "tinyint", "smallint", "mediumint", "bigint"],
588
+ decimal: ["real", "double", "decimal", "numeric", "float"],
589
+ boolean: ["boolean", "bool"],
590
+ uuid: [],
591
+ json: [],
592
+ date_only: [],
593
+ time_only: [],
594
+ timestamp: [],
595
+ binary: ["blob"]
596
+ };
597
+ var FAMILY_TABLES = {
598
+ postgresql: PG_FAMILIES,
599
+ mysql: MYSQL_FAMILIES,
600
+ sqlite: SQLITE_FAMILIES
601
+ };
602
+ function leadingToken(rawType) {
603
+ const trimmed = rawType.trim().toLowerCase();
604
+ if (trimmed.length === 0) return null;
605
+ const parenIdx = trimmed.indexOf("(");
606
+ const modifierMatch = trimmed.match(
607
+ /\s(?:not|null|default|references|primary|unique|collate|check)\b/
608
+ );
609
+ const modifierIdx = modifierMatch?.index ?? -1;
610
+ let endIdx = trimmed.length;
611
+ if (parenIdx >= 0) endIdx = Math.min(endIdx, parenIdx);
612
+ if (modifierIdx >= 0) endIdx = Math.min(endIdx, modifierIdx);
613
+ return trimmed.slice(0, endIdx).trim();
614
+ }
615
+ function typeFamilyOf(rawType, dialect) {
616
+ const token = leadingToken(rawType);
617
+ if (!token) return null;
618
+ const table = FAMILY_TABLES[dialect];
619
+ for (const family of Object.keys(table)) {
620
+ if (table[family].includes(token)) return family;
621
+ }
622
+ return null;
623
+ }
624
+ function isTypesCompatible(fromType, toType, dialect) {
625
+ const fromFamily = typeFamilyOf(fromType, dialect);
626
+ const toFamily = typeFamilyOf(toType, dialect);
627
+ if (fromFamily === null || toFamily === null) return false;
628
+ return fromFamily === toFamily;
629
+ }
630
+
631
+ // src/domains/schema/pipeline/rename-detector.ts
632
+ var RegexRenameDetector = class {
633
+ detect(operations, dialect) {
634
+ const dropsByTable = /* @__PURE__ */ new Map();
635
+ const addsByTable = /* @__PURE__ */ new Map();
636
+ for (const op of operations) {
637
+ if (op.type === "drop_column") {
638
+ const list = dropsByTable.get(op.tableName) ?? [];
639
+ list.push(op);
640
+ dropsByTable.set(op.tableName, list);
641
+ } else if (op.type === "add_column") {
642
+ const list = addsByTable.get(op.tableName) ?? [];
643
+ list.push(op);
644
+ addsByTable.set(op.tableName, list);
645
+ }
646
+ }
647
+ const candidates = [];
648
+ for (const [tableName, drops] of dropsByTable) {
649
+ const adds = addsByTable.get(tableName);
650
+ if (!adds || adds.length === 0) continue;
651
+ for (const drop of drops) {
652
+ for (const add of adds) {
653
+ const fromType = drop.columnType;
654
+ const toType = add.column.type;
655
+ const compatible = fromType === "" ? false : isTypesCompatible(fromType, toType, dialect);
656
+ candidates.push({
657
+ tableName,
658
+ fromColumn: drop.columnName,
659
+ toColumn: add.column.name,
660
+ fromType,
661
+ toType,
662
+ typesCompatible: compatible,
663
+ defaultSuggestion: compatible ? "rename" : "drop_and_add"
664
+ });
665
+ }
666
+ }
667
+ }
668
+ candidates.sort((a, b) => {
669
+ if (a.tableName !== b.tableName)
670
+ return a.tableName < b.tableName ? -1 : 1;
671
+ if (a.fromColumn !== b.fromColumn)
672
+ return a.fromColumn < b.fromColumn ? -1 : 1;
673
+ if (a.toColumn !== b.toColumn) return a.toColumn < b.toColumn ? -1 : 1;
674
+ return 0;
675
+ });
676
+ return candidates;
677
+ }
678
+ };
679
+
680
+ export {
681
+ countNulls,
682
+ countRows,
683
+ RealClassifier,
684
+ buildDesiredTableFromFields,
685
+ buildDesiredTableFromComponentFields,
686
+ diffSnapshots,
687
+ introspectLiveSnapshot,
688
+ RegexRenameDetector
689
+ };