@strapi/database 5.55.1 → 5.57.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 (196) hide show
  1. package/dist/dialects/dialect.d.ts +28 -0
  2. package/dist/dialects/dialect.d.ts.map +1 -1
  3. package/dist/dialects/dialect.js +29 -0
  4. package/dist/dialects/dialect.js.map +1 -1
  5. package/dist/dialects/dialect.mjs +29 -0
  6. package/dist/dialects/dialect.mjs.map +1 -1
  7. package/dist/dialects/mysql/index.d.ts +9 -0
  8. package/dist/dialects/mysql/index.d.ts.map +1 -1
  9. package/dist/dialects/mysql/index.js +37 -0
  10. package/dist/dialects/mysql/index.js.map +1 -1
  11. package/dist/dialects/mysql/index.mjs +37 -0
  12. package/dist/dialects/mysql/index.mjs.map +1 -1
  13. package/dist/dialects/postgresql/index.d.ts +7 -0
  14. package/dist/dialects/postgresql/index.d.ts.map +1 -1
  15. package/dist/dialects/postgresql/index.js +50 -0
  16. package/dist/dialects/postgresql/index.js.map +1 -1
  17. package/dist/dialects/postgresql/index.mjs +50 -0
  18. package/dist/dialects/postgresql/index.mjs.map +1 -1
  19. package/dist/dialects/sqlite/index.d.ts +9 -0
  20. package/dist/dialects/sqlite/index.d.ts.map +1 -1
  21. package/dist/dialects/sqlite/index.js +16 -0
  22. package/dist/dialects/sqlite/index.js.map +1 -1
  23. package/dist/dialects/sqlite/index.mjs +16 -0
  24. package/dist/dialects/sqlite/index.mjs.map +1 -1
  25. package/dist/entity-manager/entity-repository.js +1 -1
  26. package/dist/entity-manager/entity-repository.js.map +1 -1
  27. package/dist/entity-manager/entity-repository.mjs +1 -1
  28. package/dist/entity-manager/entity-repository.mjs.map +1 -1
  29. package/dist/entity-manager/index.d.ts.map +1 -1
  30. package/dist/entity-manager/index.js +38 -36
  31. package/dist/entity-manager/index.js.map +1 -1
  32. package/dist/entity-manager/index.mjs +38 -36
  33. package/dist/entity-manager/index.mjs.map +1 -1
  34. package/dist/entity-manager/morph-relations.d.ts.map +1 -1
  35. package/dist/entity-manager/morph-relations.js +3 -5
  36. package/dist/entity-manager/morph-relations.js.map +1 -1
  37. package/dist/entity-manager/morph-relations.mjs +3 -5
  38. package/dist/entity-manager/morph-relations.mjs.map +1 -1
  39. package/dist/entity-manager/regular-relations.js +3 -3
  40. package/dist/entity-manager/regular-relations.js.map +1 -1
  41. package/dist/entity-manager/regular-relations.mjs +3 -3
  42. package/dist/entity-manager/regular-relations.mjs.map +1 -1
  43. package/dist/entity-manager/relations-orderer.d.ts.map +1 -1
  44. package/dist/entity-manager/relations-orderer.js +4 -5
  45. package/dist/entity-manager/relations-orderer.js.map +1 -1
  46. package/dist/entity-manager/relations-orderer.mjs +2 -3
  47. package/dist/entity-manager/relations-orderer.mjs.map +1 -1
  48. package/dist/fields/biginteger.js +1 -1
  49. package/dist/fields/biginteger.js.map +1 -1
  50. package/dist/fields/biginteger.mjs +1 -1
  51. package/dist/fields/biginteger.mjs.map +1 -1
  52. package/dist/fields/boolean.js +1 -1
  53. package/dist/fields/boolean.js.map +1 -1
  54. package/dist/fields/boolean.mjs +1 -1
  55. package/dist/fields/boolean.mjs.map +1 -1
  56. package/dist/fields/number.js +1 -1
  57. package/dist/fields/number.js.map +1 -1
  58. package/dist/fields/number.mjs +1 -1
  59. package/dist/fields/number.mjs.map +1 -1
  60. package/dist/fields/shared/parsers.js +2 -2
  61. package/dist/fields/shared/parsers.js.map +1 -1
  62. package/dist/fields/shared/parsers.mjs +2 -2
  63. package/dist/fields/shared/parsers.mjs.map +1 -1
  64. package/dist/fields/string.js +1 -1
  65. package/dist/fields/string.js.map +1 -1
  66. package/dist/fields/string.mjs +1 -1
  67. package/dist/fields/string.mjs.map +1 -1
  68. package/dist/index.d.ts +9 -5
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +2 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/index.mjs +1 -0
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/metadata/attribute-naming.d.ts +31 -0
  75. package/dist/metadata/attribute-naming.d.ts.map +1 -0
  76. package/dist/metadata/attribute-naming.js +39 -0
  77. package/dist/metadata/attribute-naming.js.map +1 -0
  78. package/dist/metadata/attribute-naming.mjs +37 -0
  79. package/dist/metadata/attribute-naming.mjs.map +1 -0
  80. package/dist/metadata/index.d.ts +5 -2
  81. package/dist/metadata/index.d.ts.map +1 -1
  82. package/dist/metadata/index.js +3 -0
  83. package/dist/metadata/index.js.map +1 -1
  84. package/dist/metadata/index.mjs +3 -1
  85. package/dist/metadata/index.mjs.map +1 -1
  86. package/dist/metadata/metadata.d.ts +10 -0
  87. package/dist/metadata/metadata.d.ts.map +1 -1
  88. package/dist/metadata/metadata.js +10 -2
  89. package/dist/metadata/metadata.js.map +1 -1
  90. package/dist/metadata/metadata.mjs +10 -2
  91. package/dist/metadata/metadata.mjs.map +1 -1
  92. package/dist/metadata/relations.d.ts.map +1 -1
  93. package/dist/metadata/relations.js +6 -5
  94. package/dist/metadata/relations.js.map +1 -1
  95. package/dist/metadata/relations.mjs +6 -5
  96. package/dist/metadata/relations.mjs.map +1 -1
  97. package/dist/migrations/common.d.ts +2 -0
  98. package/dist/migrations/common.d.ts.map +1 -1
  99. package/dist/migrations/common.js.map +1 -1
  100. package/dist/migrations/common.mjs.map +1 -1
  101. package/dist/migrations/file-builder.d.ts +97 -0
  102. package/dist/migrations/file-builder.d.ts.map +1 -0
  103. package/dist/migrations/file-builder.js +251 -0
  104. package/dist/migrations/file-builder.js.map +1 -0
  105. package/dist/migrations/file-builder.mjs +240 -0
  106. package/dist/migrations/file-builder.mjs.map +1 -0
  107. package/dist/migrations/index.d.ts +3 -2
  108. package/dist/migrations/index.d.ts.map +1 -1
  109. package/dist/migrations/index.js +6 -0
  110. package/dist/migrations/index.js.map +1 -1
  111. package/dist/migrations/index.mjs +6 -0
  112. package/dist/migrations/index.mjs.map +1 -1
  113. package/dist/migrations/internal-migrations/5.0.0-02-document-id.js +1 -1
  114. package/dist/migrations/internal-migrations/5.0.0-02-document-id.js.map +1 -1
  115. package/dist/migrations/internal-migrations/5.0.0-02-document-id.mjs +1 -1
  116. package/dist/migrations/internal-migrations/5.0.0-02-document-id.mjs.map +1 -1
  117. package/dist/migrations/resolver.d.ts.map +1 -1
  118. package/dist/migrations/resolver.js +4 -1
  119. package/dist/migrations/resolver.js.map +1 -1
  120. package/dist/migrations/resolver.mjs +4 -1
  121. package/dist/migrations/resolver.mjs.map +1 -1
  122. package/dist/query/helpers/order-by.d.ts.map +1 -1
  123. package/dist/query/helpers/order-by.js +3 -4
  124. package/dist/query/helpers/order-by.js.map +1 -1
  125. package/dist/query/helpers/order-by.mjs +3 -4
  126. package/dist/query/helpers/order-by.mjs.map +1 -1
  127. package/dist/query/helpers/populate/apply.d.ts.map +1 -1
  128. package/dist/query/helpers/populate/apply.js +46 -30
  129. package/dist/query/helpers/populate/apply.js.map +1 -1
  130. package/dist/query/helpers/populate/apply.mjs +46 -30
  131. package/dist/query/helpers/populate/apply.mjs.map +1 -1
  132. package/dist/query/helpers/populate/process.js +3 -3
  133. package/dist/query/helpers/populate/process.js.map +1 -1
  134. package/dist/query/helpers/populate/process.mjs +3 -3
  135. package/dist/query/helpers/populate/process.mjs.map +1 -1
  136. package/dist/query/helpers/search.js +2 -2
  137. package/dist/query/helpers/search.js.map +1 -1
  138. package/dist/query/helpers/search.mjs +2 -2
  139. package/dist/query/helpers/search.mjs.map +1 -1
  140. package/dist/query/helpers/streams/readable.js +3 -3
  141. package/dist/query/helpers/streams/readable.js.map +1 -1
  142. package/dist/query/helpers/streams/readable.mjs +3 -3
  143. package/dist/query/helpers/streams/readable.mjs.map +1 -1
  144. package/dist/query/helpers/transform.d.ts.map +1 -1
  145. package/dist/query/helpers/transform.js +6 -13
  146. package/dist/query/helpers/transform.js.map +1 -1
  147. package/dist/query/helpers/transform.mjs +6 -9
  148. package/dist/query/helpers/transform.mjs.map +1 -1
  149. package/dist/query/helpers/where.js +13 -9
  150. package/dist/query/helpers/where.js.map +1 -1
  151. package/dist/query/helpers/where.mjs +13 -9
  152. package/dist/query/helpers/where.mjs.map +1 -1
  153. package/dist/query/query-builder.d.ts.map +1 -1
  154. package/dist/query/query-builder.js +35 -29
  155. package/dist/query/query-builder.js.map +1 -1
  156. package/dist/query/query-builder.mjs +35 -29
  157. package/dist/query/query-builder.mjs.map +1 -1
  158. package/dist/schema/builder.js +5 -5
  159. package/dist/schema/builder.js.map +1 -1
  160. package/dist/schema/builder.mjs +5 -5
  161. package/dist/schema/builder.mjs.map +1 -1
  162. package/dist/schema/diff.js +12 -12
  163. package/dist/schema/diff.js.map +1 -1
  164. package/dist/schema/diff.mjs +12 -12
  165. package/dist/schema/diff.mjs.map +1 -1
  166. package/dist/schema/index.d.ts +3 -1
  167. package/dist/schema/index.d.ts.map +1 -1
  168. package/dist/schema/index.js +6 -0
  169. package/dist/schema/index.js.map +1 -1
  170. package/dist/schema/index.mjs +6 -0
  171. package/dist/schema/index.mjs.map +1 -1
  172. package/dist/schema/rename-helpers.d.ts +78 -0
  173. package/dist/schema/rename-helpers.d.ts.map +1 -0
  174. package/dist/schema/rename-helpers.js +235 -0
  175. package/dist/schema/rename-helpers.js.map +1 -0
  176. package/dist/schema/rename-helpers.mjs +233 -0
  177. package/dist/schema/rename-helpers.mjs.map +1 -0
  178. package/dist/utils/async-curry.d.ts.map +1 -1
  179. package/dist/utils/async-curry.js +1 -2
  180. package/dist/utils/async-curry.js.map +1 -1
  181. package/dist/utils/async-curry.mjs +1 -2
  182. package/dist/utils/async-curry.mjs.map +1 -1
  183. package/dist/utils/identifiers/hash.d.ts.map +1 -1
  184. package/dist/utils/identifiers/hash.js +1 -2
  185. package/dist/utils/identifiers/hash.js.map +1 -1
  186. package/dist/utils/identifiers/hash.mjs +1 -2
  187. package/dist/utils/identifiers/hash.mjs.map +1 -1
  188. package/dist/utils/identifiers/index.js +8 -10
  189. package/dist/utils/identifiers/index.js.map +1 -1
  190. package/dist/utils/identifiers/index.mjs +8 -6
  191. package/dist/utils/identifiers/index.mjs.map +1 -1
  192. package/dist/validations/relations/bidirectional.js +1 -1
  193. package/dist/validations/relations/bidirectional.js.map +1 -1
  194. package/dist/validations/relations/bidirectional.mjs +1 -1
  195. package/dist/validations/relations/bidirectional.mjs.map +1 -1
  196. package/package.json +6 -5
@@ -0,0 +1,251 @@
1
+ 'use strict';
2
+
3
+ var path = require('node:path');
4
+ var fse = require('fs-extra');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var path__default = /*#__PURE__*/_interopDefault(path);
9
+ var fse__default = /*#__PURE__*/_interopDefault(fse);
10
+
11
+ const FILE_EXTENSIONS = {
12
+ javascript: 'js',
13
+ typescript: 'ts'
14
+ };
15
+ /**
16
+ * Produces a sortable, filesystem-safe UTC timestamp (e.g. `2026.06.11T15.16.00.123`).
17
+ *
18
+ * Based on the migration generator's format but keeps milliseconds: generated
19
+ * migrations can be written multiple times in the same second, so second
20
+ * precision would produce colliding filenames. UTC (not local time) so that
21
+ * files generated by developers in different time zones still sort in the
22
+ * order they were created.
23
+ */ const getFormattedTimestamp = (date = new Date())=>{
24
+ return date.toJSON().replace(/[-:]/g, '.').replace(/Z$/, '');
25
+ };
26
+ const HEADER_COMMENT = `/**
27
+ * Auto-generated by Strapi on {{timestamp}}.
28
+ *
29
+ * Every step goes through the database rename helpers, which check that the
30
+ * source table/column exists and the target does not before touching anything,
31
+ * so this file is a safe no-op on a fresh database (the tables are created by
32
+ * schema sync afterwards). Skipped steps are logged at startup.
33
+ */`;
34
+ const JS_TEMPLATE = `'use strict';
35
+
36
+ ${HEADER_COMMENT}
37
+ module.exports = {
38
+ async up(knex, db) {
39
+ {{body}}
40
+ },
41
+ async down(knex, db) {
42
+ // Down migrations are not generated for automatically generated migrations.
43
+ },
44
+ };
45
+ `;
46
+ const TS_TEMPLATE = `import type { Knex } from 'knex';
47
+ import type { Core } from '@strapi/strapi';
48
+
49
+ ${HEADER_COMMENT}
50
+ export default {
51
+ async up(knex: Knex, db: Core.Strapi['db']) {
52
+ {{body}}
53
+ },
54
+ async down(knex: Knex, db: Core.Strapi['db']) {
55
+ // Down migrations are not generated for automatically generated migrations.
56
+ },
57
+ };
58
+ `;
59
+ const TEMPLATES = {
60
+ javascript: JS_TEMPLATE,
61
+ typescript: TS_TEMPLATE
62
+ };
63
+ const RENAME_COLUMN_SNIPPET = ` // {{comment}}
64
+ await db.schema.renameColumn(knex, { table: {{table}}, from: {{from}}, to: {{to}} });`;
65
+ const RENAME_TABLE_SNIPPET = ` // {{comment}}
66
+ await db.schema.renameTable(knex, { from: {{from}}, to: {{to}} });`;
67
+ const UPDATE_ROWS_SNIPPET = ` // {{comment}}
68
+ await db.schema.updateRows(knex, {
69
+ table: {{table}},
70
+ guardColumn: {{guardColumn}},
71
+ where: {{where}},
72
+ set: {{set}},
73
+ });`;
74
+ const ATTRIBUTE_RENAMES_SNIPPET = ` // {{comment}}
75
+ await db.schema.applyAttributeRenames(knex, {
76
+ renames: {{renames}},
77
+ });`;
78
+ const interpolate = (template, values)=>{
79
+ return template.replace(/\{\{\s*(\w+)\s*\}\}/g, (_match, key)=>{
80
+ return key in values ? values[key] : `{{${key}}}`;
81
+ });
82
+ };
83
+ const quote = (value)=>`'${value.replaceAll('\\', String.raw`\\`).replaceAll("'", String.raw`\'`).replaceAll('\r', String.raw`\r`).replaceAll('\n', String.raw`\n`).replaceAll('\u2028', String.raw`\u2028`).replaceAll('\u2029', String.raw`\u2029`)}'`;
84
+ const IDENTIFIER_KEY = /^[A-Za-z_$][\w$]*$/;
85
+ const renderKey = (key)=>IDENTIFIER_KEY.test(key) ? key : quote(key);
86
+ const renderObject = (values)=>{
87
+ return `{ ${Object.entries(values).map(([key, value])=>`${renderKey(key)}: ${quote(value)}`).join(', ')} }`;
88
+ };
89
+ /**
90
+ * Renders `{ uid: { from: to } }` one entry per line, every key and value
91
+ * quoted (uids contain `:` and `.`).
92
+ */ const renderNestedObject = (values)=>{
93
+ const lines = Object.entries(values).map(([key, inner])=>{
94
+ const entries = Object.entries(inner).map(([from, to])=>`${quote(from)}: ${quote(to)}`).join(', ');
95
+ return ` ${quote(key)}: { ${entries} },`;
96
+ });
97
+ if (lines.length === 0) {
98
+ return '{}';
99
+ }
100
+ return `{\n${lines.join('\n')}\n }`;
101
+ };
102
+ /**
103
+ * Comments are rendered after `//`; a line break (including the JS line
104
+ * separators U+2028 / U+2029) would end the comment and let the rest run as
105
+ * code, so every comment is flattened to a single line.
106
+ */ const sanitizeComment = (comment)=>comment.replace(/[\r\n\u2028\u2029]/g, ' ');
107
+ const getDefaultOperationComment = (op)=>{
108
+ switch(op.kind){
109
+ case 'attributeRenames':
110
+ return "Update stores keyed by attribute name (admin field permissions) for this save's renames";
111
+ case 'renameTable':
112
+ return `Rename table ${op.from} to ${op.to}`;
113
+ case 'updateRows':
114
+ return `Update rows in ${op.table}`;
115
+ case 'renameColumn':
116
+ default:
117
+ return `Rename column ${op.table}.${op.from} to ${op.to}`;
118
+ }
119
+ };
120
+ const getOperationComment = (op)=>{
121
+ return sanitizeComment(op.comment || getDefaultOperationComment(op));
122
+ };
123
+ const renderMigrationFileOperation = (op)=>{
124
+ const comment = getOperationComment(op);
125
+ switch(op.kind){
126
+ case 'attributeRenames':
127
+ return interpolate(ATTRIBUTE_RENAMES_SNIPPET, {
128
+ comment,
129
+ renames: renderNestedObject(op.renames)
130
+ });
131
+ case 'renameTable':
132
+ return interpolate(RENAME_TABLE_SNIPPET, {
133
+ comment,
134
+ from: quote(op.from),
135
+ to: quote(op.to)
136
+ });
137
+ case 'updateRows':
138
+ {
139
+ const [firstSetColumn] = Object.keys(op.set);
140
+ return interpolate(UPDATE_ROWS_SNIPPET, {
141
+ comment,
142
+ table: quote(op.table),
143
+ guardColumn: quote(op.guardColumn ?? firstSetColumn),
144
+ where: renderObject(op.where),
145
+ set: renderObject(op.set)
146
+ });
147
+ }
148
+ case 'renameColumn':
149
+ default:
150
+ return interpolate(RENAME_COLUMN_SNIPPET, {
151
+ comment,
152
+ table: quote(op.table),
153
+ from: quote(op.from),
154
+ to: quote(op.to)
155
+ });
156
+ }
157
+ };
158
+ const renderMigrationFile = ({ timestamp, operations, format = 'javascript' })=>{
159
+ const body = operations.map(renderMigrationFileOperation).join('\n\n');
160
+ return interpolate(TEMPLATES[format], {
161
+ timestamp,
162
+ body
163
+ });
164
+ };
165
+ const MAX_WRITE_ATTEMPTS = 1000;
166
+ const createMigrationFileBuilder = ({ db })=>{
167
+ const operations = [];
168
+ const resolveMigrationsDir = ()=>{
169
+ return db.config?.settings?.migrations?.dir ?? path__default.default.join(process.cwd(), 'database', 'migrations');
170
+ };
171
+ return {
172
+ renameColumn (op) {
173
+ operations.push({
174
+ kind: 'renameColumn',
175
+ ...op
176
+ });
177
+ },
178
+ renameTable (op) {
179
+ operations.push({
180
+ kind: 'renameTable',
181
+ ...op
182
+ });
183
+ },
184
+ updateRows (op) {
185
+ operations.push({
186
+ kind: 'updateRows',
187
+ ...op
188
+ });
189
+ },
190
+ attributeRenames (op) {
191
+ operations.push({
192
+ kind: 'attributeRenames',
193
+ ...op
194
+ });
195
+ },
196
+ hasChanges () {
197
+ return operations.length > 0;
198
+ },
199
+ getOperations () {
200
+ return [
201
+ ...operations
202
+ ];
203
+ },
204
+ build ({ name, format = 'javascript' }, date = new Date()) {
205
+ if (operations.length === 0) {
206
+ return null;
207
+ }
208
+ const timestamp = getFormattedTimestamp(date);
209
+ const content = renderMigrationFile({
210
+ timestamp,
211
+ operations,
212
+ format
213
+ });
214
+ const filename = `${timestamp}.${name}.${FILE_EXTENSIONS[format]}`;
215
+ return {
216
+ filename,
217
+ content
218
+ };
219
+ },
220
+ async writeFiles (options) {
221
+ const dir = options.dir ?? resolveMigrationsDir();
222
+ const start = Date.now();
223
+ // On a collision, bump the timestamp by 1ms (filename and header) rather
224
+ // than suffixing the name: `…000.name-1.js` would sort before
225
+ // `…000.name.js` and run first.
226
+ for(let attempt = 0; attempt < MAX_WRITE_ATTEMPTS; attempt += 1){
227
+ const built = this.build(options, new Date(start + attempt));
228
+ if (!built) {
229
+ return null;
230
+ }
231
+ if (attempt === 0) {
232
+ await fse__default.default.ensureDir(dir);
233
+ }
234
+ const filePath = path__default.default.join(dir, built.filename);
235
+ if (await fse__default.default.pathExists(filePath)) {
236
+ continue;
237
+ }
238
+ await fse__default.default.writeFile(filePath, built.content, 'utf8');
239
+ return filePath;
240
+ }
241
+ throw new Error(`Could not find a free migration filename in "${dir}" after ${MAX_WRITE_ATTEMPTS} attempts`);
242
+ }
243
+ };
244
+ };
245
+
246
+ exports.createMigrationFileBuilder = createMigrationFileBuilder;
247
+ exports.getFormattedTimestamp = getFormattedTimestamp;
248
+ exports.getOperationComment = getOperationComment;
249
+ exports.renderMigrationFile = renderMigrationFile;
250
+ exports.renderMigrationFileOperation = renderMigrationFileOperation;
251
+ //# sourceMappingURL=file-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-builder.js","sources":["../../src/migrations/file-builder.ts"],"sourcesContent":["import path from 'node:path';\nimport fse from 'fs-extra';\n\nimport type { Database } from '..';\n\nexport interface BuiltMigrationFile {\n filename: string;\n content: string;\n}\n\nexport interface RenameColumnOperation {\n table: string;\n from: string;\n to: string;\n comment?: string;\n}\n\nexport interface RenameTableOperation {\n from: string;\n to: string;\n comment?: string;\n}\n\nexport interface UpdateRowsOperation {\n table: string;\n where: Record<string, string>;\n set: Record<string, string>;\n guardColumn?: string;\n comment?: string;\n}\n\n/**\n * One logical operation per generated file: the composed `origin -> final`\n * attribute renames of every model that received hops, keyed by model uid.\n * Dispatched at runtime to the handlers registered on `db.schema` (e.g. admin\n * field permissions); the database package itself stores nothing by attribute\n * name.\n */\nexport interface AttributeRenamesOperation {\n renames: Record<string, Record<string, string>>;\n comment?: string;\n}\n\nexport type MigrationFileOperation =\n | ({ kind: 'renameColumn' } & RenameColumnOperation)\n | ({ kind: 'renameTable' } & RenameTableOperation)\n | ({ kind: 'updateRows' } & UpdateRowsOperation)\n | ({ kind: 'attributeRenames' } & AttributeRenamesOperation);\n\nexport type MigrationFileFormat = 'javascript' | 'typescript';\n\nconst FILE_EXTENSIONS: Record<MigrationFileFormat, string> = {\n javascript: 'js',\n typescript: 'ts',\n};\n\n/**\n * Produces a sortable, filesystem-safe UTC timestamp (e.g. `2026.06.11T15.16.00.123`).\n *\n * Based on the migration generator's format but keeps milliseconds: generated\n * migrations can be written multiple times in the same second, so second\n * precision would produce colliding filenames. UTC (not local time) so that\n * files generated by developers in different time zones still sort in the\n * order they were created.\n */\nexport const getFormattedTimestamp = (date: Date = new Date()): string => {\n return date.toJSON().replace(/[-:]/g, '.').replace(/Z$/, '');\n};\n\nconst HEADER_COMMENT = `/**\n * Auto-generated by Strapi on {{timestamp}}.\n *\n * Every step goes through the database rename helpers, which check that the\n * source table/column exists and the target does not before touching anything,\n * so this file is a safe no-op on a fresh database (the tables are created by\n * schema sync afterwards). Skipped steps are logged at startup.\n */`;\n\nconst JS_TEMPLATE = `'use strict';\n\n${HEADER_COMMENT}\nmodule.exports = {\n async up(knex, db) {\n{{body}}\n },\n async down(knex, db) {\n // Down migrations are not generated for automatically generated migrations.\n },\n};\n`;\n\nconst TS_TEMPLATE = `import type { Knex } from 'knex';\nimport type { Core } from '@strapi/strapi';\n\n${HEADER_COMMENT}\nexport default {\n async up(knex: Knex, db: Core.Strapi['db']) {\n{{body}}\n },\n async down(knex: Knex, db: Core.Strapi['db']) {\n // Down migrations are not generated for automatically generated migrations.\n },\n};\n`;\n\nconst TEMPLATES: Record<MigrationFileFormat, string> = {\n javascript: JS_TEMPLATE,\n typescript: TS_TEMPLATE,\n};\n\nconst RENAME_COLUMN_SNIPPET = ` // {{comment}}\n await db.schema.renameColumn(knex, { table: {{table}}, from: {{from}}, to: {{to}} });`;\n\nconst RENAME_TABLE_SNIPPET = ` // {{comment}}\n await db.schema.renameTable(knex, { from: {{from}}, to: {{to}} });`;\n\nconst UPDATE_ROWS_SNIPPET = ` // {{comment}}\n await db.schema.updateRows(knex, {\n table: {{table}},\n guardColumn: {{guardColumn}},\n where: {{where}},\n set: {{set}},\n });`;\n\nconst ATTRIBUTE_RENAMES_SNIPPET = ` // {{comment}}\n await db.schema.applyAttributeRenames(knex, {\n renames: {{renames}},\n });`;\n\nconst interpolate = (template: string, values: Record<string, string>): string => {\n return template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (_match, key: string) => {\n return key in values ? values[key] : `{{${key}}}`;\n });\n};\n\nconst quote = (value: string): string =>\n `'${value\n .replaceAll('\\\\', String.raw`\\\\`)\n .replaceAll(\"'\", String.raw`\\'`)\n .replaceAll('\\r', String.raw`\\r`)\n .replaceAll('\\n', String.raw`\\n`)\n .replaceAll('\\u2028', String.raw`\\u2028`)\n .replaceAll('\\u2029', String.raw`\\u2029`)}'`;\n\nconst IDENTIFIER_KEY = /^[A-Za-z_$][\\w$]*$/;\n\nconst renderKey = (key: string): string => (IDENTIFIER_KEY.test(key) ? key : quote(key));\n\nconst renderObject = (values: Record<string, string>): string => {\n return `{ ${Object.entries(values)\n .map(([key, value]) => `${renderKey(key)}: ${quote(value)}`)\n .join(', ')} }`;\n};\n\n/**\n * Renders `{ uid: { from: to } }` one entry per line, every key and value\n * quoted (uids contain `:` and `.`).\n */\nconst renderNestedObject = (values: Record<string, Record<string, string>>): string => {\n const lines = Object.entries(values).map(([key, inner]) => {\n const entries = Object.entries(inner)\n .map(([from, to]) => `${quote(from)}: ${quote(to)}`)\n .join(', ');\n return ` ${quote(key)}: { ${entries} },`;\n });\n\n if (lines.length === 0) {\n return '{}';\n }\n\n return `{\\n${lines.join('\\n')}\\n }`;\n};\n\n/**\n * Comments are rendered after `//`; a line break (including the JS line\n * separators U+2028 / U+2029) would end the comment and let the rest run as\n * code, so every comment is flattened to a single line.\n */\nconst sanitizeComment = (comment: string): string => comment.replace(/[\\r\\n\\u2028\\u2029]/g, ' ');\n\nconst getDefaultOperationComment = (op: MigrationFileOperation): string => {\n switch (op.kind) {\n case 'attributeRenames':\n return \"Update stores keyed by attribute name (admin field permissions) for this save's renames\";\n case 'renameTable':\n return `Rename table ${op.from} to ${op.to}`;\n case 'updateRows':\n return `Update rows in ${op.table}`;\n case 'renameColumn':\n default:\n return `Rename column ${op.table}.${op.from} to ${op.to}`;\n }\n};\n\nexport const getOperationComment = (op: MigrationFileOperation): string => {\n return sanitizeComment(op.comment || getDefaultOperationComment(op));\n};\n\nexport const renderMigrationFileOperation = (op: MigrationFileOperation): string => {\n const comment = getOperationComment(op);\n\n switch (op.kind) {\n case 'attributeRenames':\n return interpolate(ATTRIBUTE_RENAMES_SNIPPET, {\n comment,\n renames: renderNestedObject(op.renames),\n });\n case 'renameTable':\n return interpolate(RENAME_TABLE_SNIPPET, {\n comment,\n from: quote(op.from),\n to: quote(op.to),\n });\n case 'updateRows': {\n const [firstSetColumn] = Object.keys(op.set);\n return interpolate(UPDATE_ROWS_SNIPPET, {\n comment,\n table: quote(op.table),\n guardColumn: quote(op.guardColumn ?? firstSetColumn),\n where: renderObject(op.where),\n set: renderObject(op.set),\n });\n }\n case 'renameColumn':\n default:\n return interpolate(RENAME_COLUMN_SNIPPET, {\n comment,\n table: quote(op.table),\n from: quote(op.from),\n to: quote(op.to),\n });\n }\n};\n\nexport const renderMigrationFile = ({\n timestamp,\n operations,\n format = 'javascript',\n}: {\n timestamp: string;\n operations: MigrationFileOperation[];\n format?: MigrationFileFormat;\n}): string => {\n const body = operations.map(renderMigrationFileOperation).join('\\n\\n');\n return interpolate(TEMPLATES[format], { timestamp, body });\n};\n\ninterface BuildOptions {\n name: string;\n /**\n * Module format of the generated file. `typescript` emits an ES module with\n * typed `up`/`down` signatures and a `.ts` extension so the app's `tsc` build\n * compiles it into `dist/database/migrations`, which is where migrations are\n * discovered when `useTypescriptMigrations` is enabled. Defaults to\n * `javascript` (CommonJS).\n */\n format?: MigrationFileFormat;\n}\n\ninterface WriteOptions extends BuildOptions {\n /**\n * Directory the migration file is written to. Defaults to the database's\n * configured migrations directory. The Content-Type Builder passes the app's\n * source `database/migrations` explicitly so the file is never written into\n * build output (e.g. `dist/` when `useTypescriptMigrations` is enabled).\n */\n dir?: string;\n}\n\nconst MAX_WRITE_ATTEMPTS = 1000;\n\ninterface MigrationFileBuilderDeps {\n db: Database;\n}\n\nexport const createMigrationFileBuilder = ({ db }: MigrationFileBuilderDeps) => {\n const operations: MigrationFileOperation[] = [];\n\n const resolveMigrationsDir = (): string => {\n return (\n db.config?.settings?.migrations?.dir ?? path.join(process.cwd(), 'database', 'migrations')\n );\n };\n\n return {\n renameColumn(op: RenameColumnOperation): void {\n operations.push({ kind: 'renameColumn', ...op });\n },\n\n renameTable(op: RenameTableOperation): void {\n operations.push({ kind: 'renameTable', ...op });\n },\n\n updateRows(op: UpdateRowsOperation): void {\n operations.push({ kind: 'updateRows', ...op });\n },\n\n attributeRenames(op: AttributeRenamesOperation): void {\n operations.push({ kind: 'attributeRenames', ...op });\n },\n\n hasChanges(): boolean {\n return operations.length > 0;\n },\n\n getOperations(): MigrationFileOperation[] {\n return [...operations];\n },\n\n build(\n { name, format = 'javascript' }: BuildOptions,\n date: Date = new Date()\n ): BuiltMigrationFile | null {\n if (operations.length === 0) {\n return null;\n }\n\n const timestamp = getFormattedTimestamp(date);\n const content = renderMigrationFile({ timestamp, operations, format });\n const filename = `${timestamp}.${name}.${FILE_EXTENSIONS[format]}`;\n\n return { filename, content };\n },\n\n async writeFiles(options: WriteOptions): Promise<string | null> {\n const dir = options.dir ?? resolveMigrationsDir();\n const start = Date.now();\n\n // On a collision, bump the timestamp by 1ms (filename and header) rather\n // than suffixing the name: `…000.name-1.js` would sort before\n // `…000.name.js` and run first.\n for (let attempt = 0; attempt < MAX_WRITE_ATTEMPTS; attempt += 1) {\n const built = this.build(options, new Date(start + attempt));\n if (!built) {\n return null;\n }\n\n if (attempt === 0) {\n await fse.ensureDir(dir);\n }\n\n const filePath = path.join(dir, built.filename);\n if (await fse.pathExists(filePath)) {\n continue;\n }\n\n await fse.writeFile(filePath, built.content, 'utf8');\n return filePath;\n }\n\n throw new Error(\n `Could not find a free migration filename in \"${dir}\" after ${MAX_WRITE_ATTEMPTS} attempts`\n );\n },\n };\n};\n\nexport type MigrationFileBuilder = ReturnType<typeof createMigrationFileBuilder>;\n"],"names":["FILE_EXTENSIONS","javascript","typescript","getFormattedTimestamp","date","Date","toJSON","replace","HEADER_COMMENT","JS_TEMPLATE","TS_TEMPLATE","TEMPLATES","RENAME_COLUMN_SNIPPET","RENAME_TABLE_SNIPPET","UPDATE_ROWS_SNIPPET","ATTRIBUTE_RENAMES_SNIPPET","interpolate","template","values","_match","key","quote","value","replaceAll","String","raw","IDENTIFIER_KEY","renderKey","test","renderObject","Object","entries","map","join","renderNestedObject","lines","inner","from","to","length","sanitizeComment","comment","getDefaultOperationComment","op","kind","table","getOperationComment","renderMigrationFileOperation","renames","firstSetColumn","keys","set","guardColumn","where","renderMigrationFile","timestamp","operations","format","body","MAX_WRITE_ATTEMPTS","createMigrationFileBuilder","db","resolveMigrationsDir","config","settings","migrations","dir","path","process","cwd","renameColumn","push","renameTable","updateRows","attributeRenames","hasChanges","getOperations","build","name","content","filename","writeFiles","options","start","now","attempt","built","fse","ensureDir","filePath","pathExists","writeFile","Error"],"mappings":"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"}
@@ -0,0 +1,240 @@
1
+ import path from 'node:path';
2
+ import fse from 'fs-extra';
3
+
4
+ const FILE_EXTENSIONS = {
5
+ javascript: 'js',
6
+ typescript: 'ts'
7
+ };
8
+ /**
9
+ * Produces a sortable, filesystem-safe UTC timestamp (e.g. `2026.06.11T15.16.00.123`).
10
+ *
11
+ * Based on the migration generator's format but keeps milliseconds: generated
12
+ * migrations can be written multiple times in the same second, so second
13
+ * precision would produce colliding filenames. UTC (not local time) so that
14
+ * files generated by developers in different time zones still sort in the
15
+ * order they were created.
16
+ */ const getFormattedTimestamp = (date = new Date())=>{
17
+ return date.toJSON().replace(/[-:]/g, '.').replace(/Z$/, '');
18
+ };
19
+ const HEADER_COMMENT = `/**
20
+ * Auto-generated by Strapi on {{timestamp}}.
21
+ *
22
+ * Every step goes through the database rename helpers, which check that the
23
+ * source table/column exists and the target does not before touching anything,
24
+ * so this file is a safe no-op on a fresh database (the tables are created by
25
+ * schema sync afterwards). Skipped steps are logged at startup.
26
+ */`;
27
+ const JS_TEMPLATE = `'use strict';
28
+
29
+ ${HEADER_COMMENT}
30
+ module.exports = {
31
+ async up(knex, db) {
32
+ {{body}}
33
+ },
34
+ async down(knex, db) {
35
+ // Down migrations are not generated for automatically generated migrations.
36
+ },
37
+ };
38
+ `;
39
+ const TS_TEMPLATE = `import type { Knex } from 'knex';
40
+ import type { Core } from '@strapi/strapi';
41
+
42
+ ${HEADER_COMMENT}
43
+ export default {
44
+ async up(knex: Knex, db: Core.Strapi['db']) {
45
+ {{body}}
46
+ },
47
+ async down(knex: Knex, db: Core.Strapi['db']) {
48
+ // Down migrations are not generated for automatically generated migrations.
49
+ },
50
+ };
51
+ `;
52
+ const TEMPLATES = {
53
+ javascript: JS_TEMPLATE,
54
+ typescript: TS_TEMPLATE
55
+ };
56
+ const RENAME_COLUMN_SNIPPET = ` // {{comment}}
57
+ await db.schema.renameColumn(knex, { table: {{table}}, from: {{from}}, to: {{to}} });`;
58
+ const RENAME_TABLE_SNIPPET = ` // {{comment}}
59
+ await db.schema.renameTable(knex, { from: {{from}}, to: {{to}} });`;
60
+ const UPDATE_ROWS_SNIPPET = ` // {{comment}}
61
+ await db.schema.updateRows(knex, {
62
+ table: {{table}},
63
+ guardColumn: {{guardColumn}},
64
+ where: {{where}},
65
+ set: {{set}},
66
+ });`;
67
+ const ATTRIBUTE_RENAMES_SNIPPET = ` // {{comment}}
68
+ await db.schema.applyAttributeRenames(knex, {
69
+ renames: {{renames}},
70
+ });`;
71
+ const interpolate = (template, values)=>{
72
+ return template.replace(/\{\{\s*(\w+)\s*\}\}/g, (_match, key)=>{
73
+ return key in values ? values[key] : `{{${key}}}`;
74
+ });
75
+ };
76
+ const quote = (value)=>`'${value.replaceAll('\\', String.raw`\\`).replaceAll("'", String.raw`\'`).replaceAll('\r', String.raw`\r`).replaceAll('\n', String.raw`\n`).replaceAll('\u2028', String.raw`\u2028`).replaceAll('\u2029', String.raw`\u2029`)}'`;
77
+ const IDENTIFIER_KEY = /^[A-Za-z_$][\w$]*$/;
78
+ const renderKey = (key)=>IDENTIFIER_KEY.test(key) ? key : quote(key);
79
+ const renderObject = (values)=>{
80
+ return `{ ${Object.entries(values).map(([key, value])=>`${renderKey(key)}: ${quote(value)}`).join(', ')} }`;
81
+ };
82
+ /**
83
+ * Renders `{ uid: { from: to } }` one entry per line, every key and value
84
+ * quoted (uids contain `:` and `.`).
85
+ */ const renderNestedObject = (values)=>{
86
+ const lines = Object.entries(values).map(([key, inner])=>{
87
+ const entries = Object.entries(inner).map(([from, to])=>`${quote(from)}: ${quote(to)}`).join(', ');
88
+ return ` ${quote(key)}: { ${entries} },`;
89
+ });
90
+ if (lines.length === 0) {
91
+ return '{}';
92
+ }
93
+ return `{\n${lines.join('\n')}\n }`;
94
+ };
95
+ /**
96
+ * Comments are rendered after `//`; a line break (including the JS line
97
+ * separators U+2028 / U+2029) would end the comment and let the rest run as
98
+ * code, so every comment is flattened to a single line.
99
+ */ const sanitizeComment = (comment)=>comment.replace(/[\r\n\u2028\u2029]/g, ' ');
100
+ const getDefaultOperationComment = (op)=>{
101
+ switch(op.kind){
102
+ case 'attributeRenames':
103
+ return "Update stores keyed by attribute name (admin field permissions) for this save's renames";
104
+ case 'renameTable':
105
+ return `Rename table ${op.from} to ${op.to}`;
106
+ case 'updateRows':
107
+ return `Update rows in ${op.table}`;
108
+ case 'renameColumn':
109
+ default:
110
+ return `Rename column ${op.table}.${op.from} to ${op.to}`;
111
+ }
112
+ };
113
+ const getOperationComment = (op)=>{
114
+ return sanitizeComment(op.comment || getDefaultOperationComment(op));
115
+ };
116
+ const renderMigrationFileOperation = (op)=>{
117
+ const comment = getOperationComment(op);
118
+ switch(op.kind){
119
+ case 'attributeRenames':
120
+ return interpolate(ATTRIBUTE_RENAMES_SNIPPET, {
121
+ comment,
122
+ renames: renderNestedObject(op.renames)
123
+ });
124
+ case 'renameTable':
125
+ return interpolate(RENAME_TABLE_SNIPPET, {
126
+ comment,
127
+ from: quote(op.from),
128
+ to: quote(op.to)
129
+ });
130
+ case 'updateRows':
131
+ {
132
+ const [firstSetColumn] = Object.keys(op.set);
133
+ return interpolate(UPDATE_ROWS_SNIPPET, {
134
+ comment,
135
+ table: quote(op.table),
136
+ guardColumn: quote(op.guardColumn ?? firstSetColumn),
137
+ where: renderObject(op.where),
138
+ set: renderObject(op.set)
139
+ });
140
+ }
141
+ case 'renameColumn':
142
+ default:
143
+ return interpolate(RENAME_COLUMN_SNIPPET, {
144
+ comment,
145
+ table: quote(op.table),
146
+ from: quote(op.from),
147
+ to: quote(op.to)
148
+ });
149
+ }
150
+ };
151
+ const renderMigrationFile = ({ timestamp, operations, format = 'javascript' })=>{
152
+ const body = operations.map(renderMigrationFileOperation).join('\n\n');
153
+ return interpolate(TEMPLATES[format], {
154
+ timestamp,
155
+ body
156
+ });
157
+ };
158
+ const MAX_WRITE_ATTEMPTS = 1000;
159
+ const createMigrationFileBuilder = ({ db })=>{
160
+ const operations = [];
161
+ const resolveMigrationsDir = ()=>{
162
+ return db.config?.settings?.migrations?.dir ?? path.join(process.cwd(), 'database', 'migrations');
163
+ };
164
+ return {
165
+ renameColumn (op) {
166
+ operations.push({
167
+ kind: 'renameColumn',
168
+ ...op
169
+ });
170
+ },
171
+ renameTable (op) {
172
+ operations.push({
173
+ kind: 'renameTable',
174
+ ...op
175
+ });
176
+ },
177
+ updateRows (op) {
178
+ operations.push({
179
+ kind: 'updateRows',
180
+ ...op
181
+ });
182
+ },
183
+ attributeRenames (op) {
184
+ operations.push({
185
+ kind: 'attributeRenames',
186
+ ...op
187
+ });
188
+ },
189
+ hasChanges () {
190
+ return operations.length > 0;
191
+ },
192
+ getOperations () {
193
+ return [
194
+ ...operations
195
+ ];
196
+ },
197
+ build ({ name, format = 'javascript' }, date = new Date()) {
198
+ if (operations.length === 0) {
199
+ return null;
200
+ }
201
+ const timestamp = getFormattedTimestamp(date);
202
+ const content = renderMigrationFile({
203
+ timestamp,
204
+ operations,
205
+ format
206
+ });
207
+ const filename = `${timestamp}.${name}.${FILE_EXTENSIONS[format]}`;
208
+ return {
209
+ filename,
210
+ content
211
+ };
212
+ },
213
+ async writeFiles (options) {
214
+ const dir = options.dir ?? resolveMigrationsDir();
215
+ const start = Date.now();
216
+ // On a collision, bump the timestamp by 1ms (filename and header) rather
217
+ // than suffixing the name: `…000.name-1.js` would sort before
218
+ // `…000.name.js` and run first.
219
+ for(let attempt = 0; attempt < MAX_WRITE_ATTEMPTS; attempt += 1){
220
+ const built = this.build(options, new Date(start + attempt));
221
+ if (!built) {
222
+ return null;
223
+ }
224
+ if (attempt === 0) {
225
+ await fse.ensureDir(dir);
226
+ }
227
+ const filePath = path.join(dir, built.filename);
228
+ if (await fse.pathExists(filePath)) {
229
+ continue;
230
+ }
231
+ await fse.writeFile(filePath, built.content, 'utf8');
232
+ return filePath;
233
+ }
234
+ throw new Error(`Could not find a free migration filename in "${dir}" after ${MAX_WRITE_ATTEMPTS} attempts`);
235
+ }
236
+ };
237
+ };
238
+
239
+ export { createMigrationFileBuilder, getFormattedTimestamp, getOperationComment, renderMigrationFile, renderMigrationFileOperation };
240
+ //# sourceMappingURL=file-builder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-builder.mjs","sources":["../../src/migrations/file-builder.ts"],"sourcesContent":["import path from 'node:path';\nimport fse from 'fs-extra';\n\nimport type { Database } from '..';\n\nexport interface BuiltMigrationFile {\n filename: string;\n content: string;\n}\n\nexport interface RenameColumnOperation {\n table: string;\n from: string;\n to: string;\n comment?: string;\n}\n\nexport interface RenameTableOperation {\n from: string;\n to: string;\n comment?: string;\n}\n\nexport interface UpdateRowsOperation {\n table: string;\n where: Record<string, string>;\n set: Record<string, string>;\n guardColumn?: string;\n comment?: string;\n}\n\n/**\n * One logical operation per generated file: the composed `origin -> final`\n * attribute renames of every model that received hops, keyed by model uid.\n * Dispatched at runtime to the handlers registered on `db.schema` (e.g. admin\n * field permissions); the database package itself stores nothing by attribute\n * name.\n */\nexport interface AttributeRenamesOperation {\n renames: Record<string, Record<string, string>>;\n comment?: string;\n}\n\nexport type MigrationFileOperation =\n | ({ kind: 'renameColumn' } & RenameColumnOperation)\n | ({ kind: 'renameTable' } & RenameTableOperation)\n | ({ kind: 'updateRows' } & UpdateRowsOperation)\n | ({ kind: 'attributeRenames' } & AttributeRenamesOperation);\n\nexport type MigrationFileFormat = 'javascript' | 'typescript';\n\nconst FILE_EXTENSIONS: Record<MigrationFileFormat, string> = {\n javascript: 'js',\n typescript: 'ts',\n};\n\n/**\n * Produces a sortable, filesystem-safe UTC timestamp (e.g. `2026.06.11T15.16.00.123`).\n *\n * Based on the migration generator's format but keeps milliseconds: generated\n * migrations can be written multiple times in the same second, so second\n * precision would produce colliding filenames. UTC (not local time) so that\n * files generated by developers in different time zones still sort in the\n * order they were created.\n */\nexport const getFormattedTimestamp = (date: Date = new Date()): string => {\n return date.toJSON().replace(/[-:]/g, '.').replace(/Z$/, '');\n};\n\nconst HEADER_COMMENT = `/**\n * Auto-generated by Strapi on {{timestamp}}.\n *\n * Every step goes through the database rename helpers, which check that the\n * source table/column exists and the target does not before touching anything,\n * so this file is a safe no-op on a fresh database (the tables are created by\n * schema sync afterwards). Skipped steps are logged at startup.\n */`;\n\nconst JS_TEMPLATE = `'use strict';\n\n${HEADER_COMMENT}\nmodule.exports = {\n async up(knex, db) {\n{{body}}\n },\n async down(knex, db) {\n // Down migrations are not generated for automatically generated migrations.\n },\n};\n`;\n\nconst TS_TEMPLATE = `import type { Knex } from 'knex';\nimport type { Core } from '@strapi/strapi';\n\n${HEADER_COMMENT}\nexport default {\n async up(knex: Knex, db: Core.Strapi['db']) {\n{{body}}\n },\n async down(knex: Knex, db: Core.Strapi['db']) {\n // Down migrations are not generated for automatically generated migrations.\n },\n};\n`;\n\nconst TEMPLATES: Record<MigrationFileFormat, string> = {\n javascript: JS_TEMPLATE,\n typescript: TS_TEMPLATE,\n};\n\nconst RENAME_COLUMN_SNIPPET = ` // {{comment}}\n await db.schema.renameColumn(knex, { table: {{table}}, from: {{from}}, to: {{to}} });`;\n\nconst RENAME_TABLE_SNIPPET = ` // {{comment}}\n await db.schema.renameTable(knex, { from: {{from}}, to: {{to}} });`;\n\nconst UPDATE_ROWS_SNIPPET = ` // {{comment}}\n await db.schema.updateRows(knex, {\n table: {{table}},\n guardColumn: {{guardColumn}},\n where: {{where}},\n set: {{set}},\n });`;\n\nconst ATTRIBUTE_RENAMES_SNIPPET = ` // {{comment}}\n await db.schema.applyAttributeRenames(knex, {\n renames: {{renames}},\n });`;\n\nconst interpolate = (template: string, values: Record<string, string>): string => {\n return template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (_match, key: string) => {\n return key in values ? values[key] : `{{${key}}}`;\n });\n};\n\nconst quote = (value: string): string =>\n `'${value\n .replaceAll('\\\\', String.raw`\\\\`)\n .replaceAll(\"'\", String.raw`\\'`)\n .replaceAll('\\r', String.raw`\\r`)\n .replaceAll('\\n', String.raw`\\n`)\n .replaceAll('\\u2028', String.raw`\\u2028`)\n .replaceAll('\\u2029', String.raw`\\u2029`)}'`;\n\nconst IDENTIFIER_KEY = /^[A-Za-z_$][\\w$]*$/;\n\nconst renderKey = (key: string): string => (IDENTIFIER_KEY.test(key) ? key : quote(key));\n\nconst renderObject = (values: Record<string, string>): string => {\n return `{ ${Object.entries(values)\n .map(([key, value]) => `${renderKey(key)}: ${quote(value)}`)\n .join(', ')} }`;\n};\n\n/**\n * Renders `{ uid: { from: to } }` one entry per line, every key and value\n * quoted (uids contain `:` and `.`).\n */\nconst renderNestedObject = (values: Record<string, Record<string, string>>): string => {\n const lines = Object.entries(values).map(([key, inner]) => {\n const entries = Object.entries(inner)\n .map(([from, to]) => `${quote(from)}: ${quote(to)}`)\n .join(', ');\n return ` ${quote(key)}: { ${entries} },`;\n });\n\n if (lines.length === 0) {\n return '{}';\n }\n\n return `{\\n${lines.join('\\n')}\\n }`;\n};\n\n/**\n * Comments are rendered after `//`; a line break (including the JS line\n * separators U+2028 / U+2029) would end the comment and let the rest run as\n * code, so every comment is flattened to a single line.\n */\nconst sanitizeComment = (comment: string): string => comment.replace(/[\\r\\n\\u2028\\u2029]/g, ' ');\n\nconst getDefaultOperationComment = (op: MigrationFileOperation): string => {\n switch (op.kind) {\n case 'attributeRenames':\n return \"Update stores keyed by attribute name (admin field permissions) for this save's renames\";\n case 'renameTable':\n return `Rename table ${op.from} to ${op.to}`;\n case 'updateRows':\n return `Update rows in ${op.table}`;\n case 'renameColumn':\n default:\n return `Rename column ${op.table}.${op.from} to ${op.to}`;\n }\n};\n\nexport const getOperationComment = (op: MigrationFileOperation): string => {\n return sanitizeComment(op.comment || getDefaultOperationComment(op));\n};\n\nexport const renderMigrationFileOperation = (op: MigrationFileOperation): string => {\n const comment = getOperationComment(op);\n\n switch (op.kind) {\n case 'attributeRenames':\n return interpolate(ATTRIBUTE_RENAMES_SNIPPET, {\n comment,\n renames: renderNestedObject(op.renames),\n });\n case 'renameTable':\n return interpolate(RENAME_TABLE_SNIPPET, {\n comment,\n from: quote(op.from),\n to: quote(op.to),\n });\n case 'updateRows': {\n const [firstSetColumn] = Object.keys(op.set);\n return interpolate(UPDATE_ROWS_SNIPPET, {\n comment,\n table: quote(op.table),\n guardColumn: quote(op.guardColumn ?? firstSetColumn),\n where: renderObject(op.where),\n set: renderObject(op.set),\n });\n }\n case 'renameColumn':\n default:\n return interpolate(RENAME_COLUMN_SNIPPET, {\n comment,\n table: quote(op.table),\n from: quote(op.from),\n to: quote(op.to),\n });\n }\n};\n\nexport const renderMigrationFile = ({\n timestamp,\n operations,\n format = 'javascript',\n}: {\n timestamp: string;\n operations: MigrationFileOperation[];\n format?: MigrationFileFormat;\n}): string => {\n const body = operations.map(renderMigrationFileOperation).join('\\n\\n');\n return interpolate(TEMPLATES[format], { timestamp, body });\n};\n\ninterface BuildOptions {\n name: string;\n /**\n * Module format of the generated file. `typescript` emits an ES module with\n * typed `up`/`down` signatures and a `.ts` extension so the app's `tsc` build\n * compiles it into `dist/database/migrations`, which is where migrations are\n * discovered when `useTypescriptMigrations` is enabled. Defaults to\n * `javascript` (CommonJS).\n */\n format?: MigrationFileFormat;\n}\n\ninterface WriteOptions extends BuildOptions {\n /**\n * Directory the migration file is written to. Defaults to the database's\n * configured migrations directory. The Content-Type Builder passes the app's\n * source `database/migrations` explicitly so the file is never written into\n * build output (e.g. `dist/` when `useTypescriptMigrations` is enabled).\n */\n dir?: string;\n}\n\nconst MAX_WRITE_ATTEMPTS = 1000;\n\ninterface MigrationFileBuilderDeps {\n db: Database;\n}\n\nexport const createMigrationFileBuilder = ({ db }: MigrationFileBuilderDeps) => {\n const operations: MigrationFileOperation[] = [];\n\n const resolveMigrationsDir = (): string => {\n return (\n db.config?.settings?.migrations?.dir ?? path.join(process.cwd(), 'database', 'migrations')\n );\n };\n\n return {\n renameColumn(op: RenameColumnOperation): void {\n operations.push({ kind: 'renameColumn', ...op });\n },\n\n renameTable(op: RenameTableOperation): void {\n operations.push({ kind: 'renameTable', ...op });\n },\n\n updateRows(op: UpdateRowsOperation): void {\n operations.push({ kind: 'updateRows', ...op });\n },\n\n attributeRenames(op: AttributeRenamesOperation): void {\n operations.push({ kind: 'attributeRenames', ...op });\n },\n\n hasChanges(): boolean {\n return operations.length > 0;\n },\n\n getOperations(): MigrationFileOperation[] {\n return [...operations];\n },\n\n build(\n { name, format = 'javascript' }: BuildOptions,\n date: Date = new Date()\n ): BuiltMigrationFile | null {\n if (operations.length === 0) {\n return null;\n }\n\n const timestamp = getFormattedTimestamp(date);\n const content = renderMigrationFile({ timestamp, operations, format });\n const filename = `${timestamp}.${name}.${FILE_EXTENSIONS[format]}`;\n\n return { filename, content };\n },\n\n async writeFiles(options: WriteOptions): Promise<string | null> {\n const dir = options.dir ?? resolveMigrationsDir();\n const start = Date.now();\n\n // On a collision, bump the timestamp by 1ms (filename and header) rather\n // than suffixing the name: `…000.name-1.js` would sort before\n // `…000.name.js` and run first.\n for (let attempt = 0; attempt < MAX_WRITE_ATTEMPTS; attempt += 1) {\n const built = this.build(options, new Date(start + attempt));\n if (!built) {\n return null;\n }\n\n if (attempt === 0) {\n await fse.ensureDir(dir);\n }\n\n const filePath = path.join(dir, built.filename);\n if (await fse.pathExists(filePath)) {\n continue;\n }\n\n await fse.writeFile(filePath, built.content, 'utf8');\n return filePath;\n }\n\n throw new Error(\n `Could not find a free migration filename in \"${dir}\" after ${MAX_WRITE_ATTEMPTS} attempts`\n );\n },\n };\n};\n\nexport type MigrationFileBuilder = ReturnType<typeof createMigrationFileBuilder>;\n"],"names":["FILE_EXTENSIONS","javascript","typescript","getFormattedTimestamp","date","Date","toJSON","replace","HEADER_COMMENT","JS_TEMPLATE","TS_TEMPLATE","TEMPLATES","RENAME_COLUMN_SNIPPET","RENAME_TABLE_SNIPPET","UPDATE_ROWS_SNIPPET","ATTRIBUTE_RENAMES_SNIPPET","interpolate","template","values","_match","key","quote","value","replaceAll","String","raw","IDENTIFIER_KEY","renderKey","test","renderObject","Object","entries","map","join","renderNestedObject","lines","inner","from","to","length","sanitizeComment","comment","getDefaultOperationComment","op","kind","table","getOperationComment","renderMigrationFileOperation","renames","firstSetColumn","keys","set","guardColumn","where","renderMigrationFile","timestamp","operations","format","body","MAX_WRITE_ATTEMPTS","createMigrationFileBuilder","db","resolveMigrationsDir","config","settings","migrations","dir","path","process","cwd","renameColumn","push","renameTable","updateRows","attributeRenames","hasChanges","getOperations","build","name","content","filename","writeFiles","options","start","now","attempt","built","fse","ensureDir","filePath","pathExists","writeFile","Error"],"mappings":";;;AAmDA,MAAMA,eAAAA,GAAuD;IAC3DC,UAAAA,EAAY,IAAA;IACZC,UAAAA,EAAY;AACd,CAAA;AAEA;;;;;;;;AAQC,IACM,MAAMC,qBAAAA,GAAwB,CAACC,IAAAA,GAAa,IAAIC,IAAAA,EAAM,GAAA;IAC3D,OAAOD,IAAAA,CAAKE,MAAM,EAAA,CAAGC,OAAO,CAAC,OAAA,EAAS,GAAA,CAAA,CAAKA,OAAO,CAAC,IAAA,EAAM,EAAA,CAAA;AAC3D;AAEA,MAAMC,iBAAiB,CAAC;;;;;;;GAOrB,CAAC;AAEJ,MAAMC,cAAc,CAAC;;AAErB,EAAED,cAAAA;;;;;;;;;AASF,CAAC;AAED,MAAME,cAAc,CAAC;;;AAGrB,EAAEF,cAAAA;;;;;;;;;AASF,CAAC;AAED,MAAMG,SAAAA,GAAiD;IACrDV,UAAAA,EAAYQ,WAAAA;IACZP,UAAAA,EAAYQ;AACd,CAAA;AAEA,MAAME,wBAAwB,CAAC;yFAC0D,CAAC;AAE1F,MAAMC,uBAAuB,CAAC;sEACwC,CAAC;AAEvE,MAAMC,sBAAsB,CAAC;;;;;;OAMtB,CAAC;AAER,MAAMC,4BAA4B,CAAC;;;OAG5B,CAAC;AAER,MAAMC,WAAAA,GAAc,CAACC,QAAAA,EAAkBC,MAAAA,GAAAA;AACrC,IAAA,OAAOD,QAAAA,CAASV,OAAO,CAAC,sBAAA,EAAwB,CAACY,MAAAA,EAAQC,GAAAA,GAAAA;QACvD,OAAOA,GAAAA,IAAOF,MAAAA,GAASA,MAAM,CAACE,GAAAA,CAAI,GAAG,CAAC,EAAE,EAAEA,GAAAA,CAAI,EAAE,CAAC;AACnD,IAAA,CAAA,CAAA;AACF,CAAA;AAEA,MAAMC,KAAAA,GAAQ,CAACC,KAAAA,GACb,CAAC,CAAC,EAAEA,KAAAA,CACDC,UAAU,CAAC,IAAA,EAAMC,MAAAA,CAAOC,GAAG,CAAC,EAAE,CAAC,CAAA,CAC/BF,UAAU,CAAC,GAAA,EAAKC,MAAAA,CAAOC,GAAG,CAAC,EAAE,CAAC,CAAA,CAC9BF,UAAU,CAAC,IAAA,EAAMC,OAAOC,GAAG,CAAC,EAAE,CAAC,CAAA,CAC/BF,UAAU,CAAC,IAAA,EAAMC,MAAAA,CAAOC,GAAG,CAAC,EAAE,CAAC,CAAA,CAC/BF,UAAU,CAAC,QAAA,EAAUC,MAAAA,CAAOC,GAAG,CAAC,MAAM,CAAC,CAAA,CACvCF,UAAU,CAAC,QAAA,EAAUC,MAAAA,CAAOC,GAAG,CAAC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC;AAEhD,MAAMC,cAAAA,GAAiB,oBAAA;AAEvB,MAAMC,SAAAA,GAAY,CAACP,GAAAA,GAAyBM,cAAAA,CAAeE,IAAI,CAACR,GAAAA,CAAAA,GAAOA,MAAMC,KAAAA,CAAMD,GAAAA,CAAAA;AAEnF,MAAMS,eAAe,CAACX,MAAAA,GAAAA;IACpB,OAAO,CAAC,EAAE,EAAEY,MAAAA,CAAOC,OAAO,CAACb,MAAAA,CAAAA,CACxBc,GAAG,CAAC,CAAC,CAACZ,GAAAA,EAAKE,KAAAA,CAAM,GAAK,CAAA,EAAGK,SAAAA,CAAUP,GAAAA,CAAAA,CAAK,EAAE,EAAEC,KAAAA,CAAMC,KAAAA,CAAAA,CAAAA,CAAQ,CAAA,CAC1DW,IAAI,CAAC,IAAA,CAAA,CAAM,EAAE,CAAC;AACnB,CAAA;AAEA;;;IAIA,MAAMC,qBAAqB,CAAChB,MAAAA,GAAAA;IAC1B,MAAMiB,KAAAA,GAAQL,MAAAA,CAAOC,OAAO,CAACb,MAAAA,CAAAA,CAAQc,GAAG,CAAC,CAAC,CAACZ,GAAAA,EAAKgB,KAAAA,CAAM,GAAA;QACpD,MAAML,OAAAA,GAAUD,OAAOC,OAAO,CAACK,OAC5BJ,GAAG,CAAC,CAAC,CAACK,IAAAA,EAAMC,GAAG,GAAK,CAAA,EAAGjB,MAAMgB,IAAAA,CAAAA,CAAM,EAAE,EAAEhB,KAAAA,CAAMiB,EAAAA,CAAAA,CAAAA,CAAK,CAAA,CAClDL,IAAI,CAAC,IAAA,CAAA;QACR,OAAO,CAAC,QAAQ,EAAEZ,KAAAA,CAAMD,KAAK,IAAI,EAAEW,OAAAA,CAAQ,GAAG,CAAC;AACjD,IAAA,CAAA,CAAA;IAEA,IAAII,KAAAA,CAAMI,MAAM,KAAK,CAAA,EAAG;QACtB,OAAO,IAAA;AACT,IAAA;IAEA,OAAO,CAAC,GAAG,EAAEJ,KAAAA,CAAMF,IAAI,CAAC,IAAA,CAAA,CAAM,SAAS,CAAC;AAC1C,CAAA;AAEA;;;;AAIC,IACD,MAAMO,eAAAA,GAAkB,CAACC,UAA4BA,OAAAA,CAAQlC,OAAO,CAAC,qBAAA,EAAuB,GAAA,CAAA;AAE5F,MAAMmC,6BAA6B,CAACC,EAAAA,GAAAA;AAClC,IAAA,OAAQA,GAAGC,IAAI;QACb,KAAK,kBAAA;YACH,OAAO,yFAAA;QACT,KAAK,aAAA;YACH,OAAO,CAAC,aAAa,EAAED,EAAAA,CAAGN,IAAI,CAAC,IAAI,EAAEM,EAAAA,CAAGL,EAAE,CAAA,CAAE;QAC9C,KAAK,YAAA;AACH,YAAA,OAAO,CAAC,eAAe,EAAEK,EAAAA,CAAGE,KAAK,CAAA,CAAE;QACrC,KAAK,cAAA;AACL,QAAA;AACE,YAAA,OAAO,CAAC,cAAc,EAAEF,EAAAA,CAAGE,KAAK,CAAC,CAAC,EAAEF,EAAAA,CAAGN,IAAI,CAAC,IAAI,EAAEM,EAAAA,CAAGL,EAAE,CAAA,CAAE;AAC7D;AACF,CAAA;AAEO,MAAMQ,sBAAsB,CAACH,EAAAA,GAAAA;AAClC,IAAA,OAAOH,eAAAA,CAAgBG,EAAAA,CAAGF,OAAO,IAAIC,0BAAAA,CAA2BC,EAAAA,CAAAA,CAAAA;AAClE;AAEO,MAAMI,+BAA+B,CAACJ,EAAAA,GAAAA;AAC3C,IAAA,MAAMF,UAAUK,mBAAAA,CAAoBH,EAAAA,CAAAA;AAEpC,IAAA,OAAQA,GAAGC,IAAI;QACb,KAAK,kBAAA;AACH,YAAA,OAAO5B,YAAYD,yBAAAA,EAA2B;AAC5C0B,gBAAAA,OAAAA;gBACAO,OAAAA,EAASd,kBAAAA,CAAmBS,GAAGK,OAAO;AACxC,aAAA,CAAA;QACF,KAAK,aAAA;AACH,YAAA,OAAOhC,YAAYH,oBAAAA,EAAsB;AACvC4B,gBAAAA,OAAAA;gBACAJ,IAAAA,EAAMhB,KAAAA,CAAMsB,GAAGN,IAAI,CAAA;gBACnBC,EAAAA,EAAIjB,KAAAA,CAAMsB,GAAGL,EAAE;AACjB,aAAA,CAAA;QACF,KAAK,YAAA;AAAc,YAAA;AACjB,gBAAA,MAAM,CAACW,cAAAA,CAAe,GAAGnB,OAAOoB,IAAI,CAACP,GAAGQ,GAAG,CAAA;AAC3C,gBAAA,OAAOnC,YAAYF,mBAAAA,EAAqB;AACtC2B,oBAAAA,OAAAA;oBACAI,KAAAA,EAAOxB,KAAAA,CAAMsB,GAAGE,KAAK,CAAA;oBACrBO,WAAAA,EAAa/B,KAAAA,CAAMsB,EAAAA,CAAGS,WAAW,IAAIH,cAAAA,CAAAA;oBACrCI,KAAAA,EAAOxB,YAAAA,CAAac,GAAGU,KAAK,CAAA;oBAC5BF,GAAAA,EAAKtB,YAAAA,CAAac,GAAGQ,GAAG;AAC1B,iBAAA,CAAA;AACF,YAAA;QACA,KAAK,cAAA;AACL,QAAA;AACE,YAAA,OAAOnC,YAAYJ,qBAAAA,EAAuB;AACxC6B,gBAAAA,OAAAA;gBACAI,KAAAA,EAAOxB,KAAAA,CAAMsB,GAAGE,KAAK,CAAA;gBACrBR,IAAAA,EAAMhB,KAAAA,CAAMsB,GAAGN,IAAI,CAAA;gBACnBC,EAAAA,EAAIjB,KAAAA,CAAMsB,GAAGL,EAAE;AACjB,aAAA,CAAA;AACJ;AACF;AAEO,MAAMgB,mBAAAA,GAAsB,CAAC,EAClCC,SAAS,EACTC,UAAU,EACVC,MAAAA,GAAS,YAAY,EAKtB,GAAA;AACC,IAAA,MAAMC,OAAOF,UAAAA,CAAWxB,GAAG,CAACe,4BAAAA,CAAAA,CAA8Bd,IAAI,CAAC,MAAA,CAAA;AAC/D,IAAA,OAAOjB,WAAAA,CAAYL,SAAS,CAAC8C,MAAAA,CAAO,EAAE;AAAEF,QAAAA,SAAAA;AAAWG,QAAAA;AAAK,KAAA,CAAA;AAC1D;AAwBA,MAAMC,kBAAAA,GAAqB,IAAA;AAMpB,MAAMC,0BAAAA,GAA6B,CAAC,EAAEC,EAAE,EAA4B,GAAA;AACzE,IAAA,MAAML,aAAuC,EAAE;AAE/C,IAAA,MAAMM,oBAAAA,GAAuB,IAAA;AAC3B,QAAA,OACED,EAAAA,CAAGE,MAAM,EAAEC,QAAAA,EAAUC,UAAAA,EAAYC,GAAAA,IAAOC,IAAAA,CAAKlC,IAAI,CAACmC,OAAAA,CAAQC,GAAG,EAAA,EAAI,UAAA,EAAY,YAAA,CAAA;AAEjF,IAAA,CAAA;IAEA,OAAO;AACLC,QAAAA,YAAAA,CAAAA,CAAa3B,EAAyB,EAAA;AACpCa,YAAAA,UAAAA,CAAWe,IAAI,CAAC;gBAAE3B,IAAAA,EAAM,cAAA;AAAgB,gBAAA,GAAGD;AAAG,aAAA,CAAA;AAChD,QAAA,CAAA;AAEA6B,QAAAA,WAAAA,CAAAA,CAAY7B,EAAwB,EAAA;AAClCa,YAAAA,UAAAA,CAAWe,IAAI,CAAC;gBAAE3B,IAAAA,EAAM,aAAA;AAAe,gBAAA,GAAGD;AAAG,aAAA,CAAA;AAC/C,QAAA,CAAA;AAEA8B,QAAAA,UAAAA,CAAAA,CAAW9B,EAAuB,EAAA;AAChCa,YAAAA,UAAAA,CAAWe,IAAI,CAAC;gBAAE3B,IAAAA,EAAM,YAAA;AAAc,gBAAA,GAAGD;AAAG,aAAA,CAAA;AAC9C,QAAA,CAAA;AAEA+B,QAAAA,gBAAAA,CAAAA,CAAiB/B,EAA6B,EAAA;AAC5Ca,YAAAA,UAAAA,CAAWe,IAAI,CAAC;gBAAE3B,IAAAA,EAAM,kBAAA;AAAoB,gBAAA,GAAGD;AAAG,aAAA,CAAA;AACpD,QAAA,CAAA;AAEAgC,QAAAA,UAAAA,CAAAA,GAAAA;YACE,OAAOnB,UAAAA,CAAWjB,MAAM,GAAG,CAAA;AAC7B,QAAA,CAAA;AAEAqC,QAAAA,aAAAA,CAAAA,GAAAA;YACE,OAAO;AAAIpB,gBAAAA,GAAAA;AAAW,aAAA;AACxB,QAAA,CAAA;QAEAqB,KAAAA,CAAAA,CACE,EAAEC,IAAI,EAAErB,MAAAA,GAAS,YAAY,EAAgB,EAC7CrD,IAAAA,GAAa,IAAIC,IAAAA,EAAM,EAAA;YAEvB,IAAImD,UAAAA,CAAWjB,MAAM,KAAK,CAAA,EAAG;gBAC3B,OAAO,IAAA;AACT,YAAA;AAEA,YAAA,MAAMgB,YAAYpD,qBAAAA,CAAsBC,IAAAA,CAAAA;AACxC,YAAA,MAAM2E,UAAUzB,mBAAAA,CAAoB;AAAEC,gBAAAA,SAAAA;AAAWC,gBAAAA,UAAAA;AAAYC,gBAAAA;AAAO,aAAA,CAAA;YACpE,MAAMuB,QAAAA,GAAW,CAAA,EAAGzB,SAAAA,CAAU,CAAC,EAAEuB,IAAAA,CAAK,CAAC,EAAE9E,eAAe,CAACyD,MAAAA,CAAO,CAAA,CAAE;YAElE,OAAO;AAAEuB,gBAAAA,QAAAA;AAAUD,gBAAAA;AAAQ,aAAA;AAC7B,QAAA,CAAA;AAEA,QAAA,MAAME,YAAWC,OAAqB,EAAA;YACpC,MAAMhB,GAAAA,GAAMgB,OAAAA,CAAQhB,GAAG,IAAIJ,oBAAAA,EAAAA;YAC3B,MAAMqB,KAAAA,GAAQ9E,KAAK+E,GAAG,EAAA;;;;AAKtB,YAAA,IAAK,IAAIC,OAAAA,GAAU,CAAA,EAAGA,OAAAA,GAAU1B,kBAAAA,EAAoB0B,WAAW,CAAA,CAAG;gBAChE,MAAMC,KAAAA,GAAQ,IAAI,CAACT,KAAK,CAACK,OAAAA,EAAS,IAAI7E,KAAK8E,KAAAA,GAAQE,OAAAA,CAAAA,CAAAA;AACnD,gBAAA,IAAI,CAACC,KAAAA,EAAO;oBACV,OAAO,IAAA;AACT,gBAAA;AAEA,gBAAA,IAAID,YAAY,CAAA,EAAG;oBACjB,MAAME,GAAAA,CAAIC,SAAS,CAACtB,GAAAA,CAAAA;AACtB,gBAAA;AAEA,gBAAA,MAAMuB,WAAWtB,IAAAA,CAAKlC,IAAI,CAACiC,GAAAA,EAAKoB,MAAMN,QAAQ,CAAA;AAC9C,gBAAA,IAAI,MAAMO,GAAAA,CAAIG,UAAU,CAACD,QAAAA,CAAAA,EAAW;AAClC,oBAAA;AACF,gBAAA;AAEA,gBAAA,MAAMF,IAAII,SAAS,CAACF,QAAAA,EAAUH,KAAAA,CAAMP,OAAO,EAAE,MAAA,CAAA;gBAC7C,OAAOU,QAAAA;AACT,YAAA;YAEA,MAAM,IAAIG,KAAAA,CACR,CAAC,6CAA6C,EAAE1B,IAAI,QAAQ,EAAEP,kBAAAA,CAAmB,SAAS,CAAC,CAAA;AAE/F,QAAA;AACF,KAAA;AACF;;;;"}
@@ -1,5 +1,6 @@
1
- import type { MigrationProvider, Migration } from './common';
1
+ import type { MigrationProvider } from './common';
2
2
  import type { Database } from '..';
3
- export type { MigrationProvider, Migration };
3
+ export type { MigrationProvider, Migration } from './common';
4
+ export type { AttributeRenamesOperation, BuiltMigrationFile, MigrationFileBuilder, MigrationFileFormat, MigrationFileOperation, } from './file-builder';
4
5
  export declare const createMigrationsProvider: (db: Database) => MigrationProvider;
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAEnC,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC;AAE7C,eAAO,MAAM,wBAAwB,GAAI,IAAI,QAAQ,KAAG,iBA+BvD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAEnC,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7D,YAAY,EACV,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,wBAAwB,GAAI,IAAI,QAAQ,KAAG,iBAkCvD,CAAC"}
@@ -2,6 +2,7 @@
2
2
 
3
3
  var users = require('./users.js');
4
4
  var internal = require('./internal.js');
5
+ var fileBuilder = require('./file-builder.js');
5
6
 
6
7
  const createMigrationsProvider = (db)=>{
7
8
  const userProvider = users.createUserMigrationProvider(db);
@@ -14,6 +15,11 @@ const createMigrationsProvider = (db)=>{
14
15
  providers: {
15
16
  internal: internalProvider
16
17
  },
18
+ createFileBuilder () {
19
+ return fileBuilder.createMigrationFileBuilder({
20
+ db
21
+ });
22
+ },
17
23
  async shouldRun () {
18
24
  const shouldRunResponses = await Promise.all(providers.map((provider)=>provider.shouldRun()));
19
25
  return shouldRunResponses.some((shouldRun)=>shouldRun);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/migrations/index.ts"],"sourcesContent":["import { createUserMigrationProvider } from './users';\nimport { createInternalMigrationProvider } from './internal';\n\nimport type { MigrationProvider, Migration } from './common';\nimport type { Database } from '..';\n\nexport type { MigrationProvider, Migration };\n\nexport const createMigrationsProvider = (db: Database): MigrationProvider => {\n const userProvider = createUserMigrationProvider(db);\n const internalProvider = createInternalMigrationProvider(db);\n const providers = [userProvider, internalProvider];\n\n return {\n providers: {\n internal: internalProvider,\n },\n async shouldRun() {\n const shouldRunResponses = await Promise.all(\n providers.map((provider) => provider.shouldRun())\n );\n\n return shouldRunResponses.some((shouldRun) => shouldRun);\n },\n async up() {\n for (const provider of providers) {\n if (await provider.shouldRun()) {\n await provider.up();\n }\n }\n },\n async down() {\n for (const provider of providers) {\n if (await provider.shouldRun()) {\n await provider.down();\n }\n }\n },\n };\n};\n"],"names":["createMigrationsProvider","db","userProvider","createUserMigrationProvider","internalProvider","createInternalMigrationProvider","providers","internal","shouldRun","shouldRunResponses","Promise","all","map","provider","some","up","down"],"mappings":";;;;;AAQO,MAAMA,2BAA2B,CAACC,EAAAA,GAAAA;AACvC,IAAA,MAAMC,eAAeC,iCAAAA,CAA4BF,EAAAA,CAAAA;AACjD,IAAA,MAAMG,mBAAmBC,wCAAAA,CAAgCJ,EAAAA,CAAAA;AACzD,IAAA,MAAMK,SAAAA,GAAY;AAACJ,QAAAA,YAAAA;AAAcE,QAAAA;AAAiB,KAAA;IAElD,OAAO;QACLE,SAAAA,EAAW;YACTC,QAAAA,EAAUH;AACZ,SAAA;QACA,MAAMI,SAAAA,CAAAA,GAAAA;YACJ,MAAMC,kBAAAA,GAAqB,MAAMC,OAAAA,CAAQC,GAAG,CAC1CL,SAAAA,CAAUM,GAAG,CAAC,CAACC,QAAAA,GAAaA,QAAAA,CAASL,SAAS,EAAA,CAAA,CAAA;AAGhD,YAAA,OAAOC,kBAAAA,CAAmBK,IAAI,CAAC,CAACN,SAAAA,GAAcA,SAAAA,CAAAA;AAChD,QAAA,CAAA;QACA,MAAMO,EAAAA,CAAAA,GAAAA;YACJ,KAAK,MAAMF,YAAYP,SAAAA,CAAW;gBAChC,IAAI,MAAMO,QAAAA,CAASL,SAAS,EAAA,EAAI;AAC9B,oBAAA,MAAMK,SAASE,EAAE,EAAA;AACnB,gBAAA;AACF,YAAA;AACF,QAAA,CAAA;QACA,MAAMC,IAAAA,CAAAA,GAAAA;YACJ,KAAK,MAAMH,YAAYP,SAAAA,CAAW;gBAChC,IAAI,MAAMO,QAAAA,CAASL,SAAS,EAAA,EAAI;AAC9B,oBAAA,MAAMK,SAASG,IAAI,EAAA;AACrB,gBAAA;AACF,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/migrations/index.ts"],"sourcesContent":["import { createUserMigrationProvider } from './users';\nimport { createInternalMigrationProvider } from './internal';\nimport { createMigrationFileBuilder } from './file-builder';\n\nimport type { MigrationProvider } from './common';\nimport type { Database } from '..';\n\nexport type { MigrationProvider, Migration } from './common';\nexport type {\n AttributeRenamesOperation,\n BuiltMigrationFile,\n MigrationFileBuilder,\n MigrationFileFormat,\n MigrationFileOperation,\n} from './file-builder';\n\nexport const createMigrationsProvider = (db: Database): MigrationProvider => {\n const userProvider = createUserMigrationProvider(db);\n const internalProvider = createInternalMigrationProvider(db);\n const providers = [userProvider, internalProvider];\n\n return {\n providers: {\n internal: internalProvider,\n },\n createFileBuilder() {\n return createMigrationFileBuilder({ db });\n },\n async shouldRun() {\n const shouldRunResponses = await Promise.all(\n providers.map((provider) => provider.shouldRun())\n );\n\n return shouldRunResponses.some((shouldRun) => shouldRun);\n },\n async up() {\n for (const provider of providers) {\n if (await provider.shouldRun()) {\n await provider.up();\n }\n }\n },\n async down() {\n for (const provider of providers) {\n if (await provider.shouldRun()) {\n await provider.down();\n }\n }\n },\n };\n};\n"],"names":["createMigrationsProvider","db","userProvider","createUserMigrationProvider","internalProvider","createInternalMigrationProvider","providers","internal","createFileBuilder","createMigrationFileBuilder","shouldRun","shouldRunResponses","Promise","all","map","provider","some","up","down"],"mappings":";;;;;;AAgBO,MAAMA,2BAA2B,CAACC,EAAAA,GAAAA;AACvC,IAAA,MAAMC,eAAeC,iCAAAA,CAA4BF,EAAAA,CAAAA;AACjD,IAAA,MAAMG,mBAAmBC,wCAAAA,CAAgCJ,EAAAA,CAAAA;AACzD,IAAA,MAAMK,SAAAA,GAAY;AAACJ,QAAAA,YAAAA;AAAcE,QAAAA;AAAiB,KAAA;IAElD,OAAO;QACLE,SAAAA,EAAW;YACTC,QAAAA,EAAUH;AACZ,SAAA;AACAI,QAAAA,iBAAAA,CAAAA,GAAAA;AACE,YAAA,OAAOC,sCAAAA,CAA2B;AAAER,gBAAAA;AAAG,aAAA,CAAA;AACzC,QAAA,CAAA;QACA,MAAMS,SAAAA,CAAAA,GAAAA;YACJ,MAAMC,kBAAAA,GAAqB,MAAMC,OAAAA,CAAQC,GAAG,CAC1CP,SAAAA,CAAUQ,GAAG,CAAC,CAACC,QAAAA,GAAaA,QAAAA,CAASL,SAAS,EAAA,CAAA,CAAA;AAGhD,YAAA,OAAOC,kBAAAA,CAAmBK,IAAI,CAAC,CAACN,SAAAA,GAAcA,SAAAA,CAAAA;AAChD,QAAA,CAAA;QACA,MAAMO,EAAAA,CAAAA,GAAAA;YACJ,KAAK,MAAMF,YAAYT,SAAAA,CAAW;gBAChC,IAAI,MAAMS,QAAAA,CAASL,SAAS,EAAA,EAAI;AAC9B,oBAAA,MAAMK,SAASE,EAAE,EAAA;AACnB,gBAAA;AACF,YAAA;AACF,QAAA,CAAA;QACA,MAAMC,IAAAA,CAAAA,GAAAA;YACJ,KAAK,MAAMH,YAAYT,SAAAA,CAAW;gBAChC,IAAI,MAAMS,QAAAA,CAASL,SAAS,EAAA,EAAI;AAC9B,oBAAA,MAAMK,SAASG,IAAI,EAAA;AACrB,gBAAA;AACF,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
@@ -1,5 +1,6 @@
1
1
  import { createUserMigrationProvider } from './users.mjs';
2
2
  import { createInternalMigrationProvider } from './internal.mjs';
3
+ import { createMigrationFileBuilder } from './file-builder.mjs';
3
4
 
4
5
  const createMigrationsProvider = (db)=>{
5
6
  const userProvider = createUserMigrationProvider(db);
@@ -12,6 +13,11 @@ const createMigrationsProvider = (db)=>{
12
13
  providers: {
13
14
  internal: internalProvider
14
15
  },
16
+ createFileBuilder () {
17
+ return createMigrationFileBuilder({
18
+ db
19
+ });
20
+ },
15
21
  async shouldRun () {
16
22
  const shouldRunResponses = await Promise.all(providers.map((provider)=>provider.shouldRun()));
17
23
  return shouldRunResponses.some((shouldRun)=>shouldRun);