pocketbase-zod-schema 0.2.4 → 0.3.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.
- package/CHANGELOG.md +15 -0
- package/README.md +209 -24
- package/dist/cli/index.cjs +406 -294
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -1
- package/dist/cli/index.d.ts +3 -1
- package/dist/cli/index.js +406 -294
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +406 -294
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +406 -294
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/utils/index.d.cts +3 -1
- package/dist/cli/utils/index.d.ts +3 -1
- package/dist/fields-UcOPu1OQ.d.cts +364 -0
- package/dist/fields-UcOPu1OQ.d.ts +364 -0
- package/dist/index.cjs +633 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +619 -101
- package/dist/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +44 -0
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.d.cts +2 -1
- package/dist/migration/analyzer.d.ts +2 -1
- package/dist/migration/analyzer.js +44 -0
- package/dist/migration/analyzer.js.map +1 -1
- package/dist/migration/diff.cjs +76 -1
- package/dist/migration/diff.cjs.map +1 -1
- package/dist/migration/diff.d.cts +3 -1
- package/dist/migration/diff.d.ts +3 -1
- package/dist/migration/diff.js +76 -1
- package/dist/migration/diff.js.map +1 -1
- package/dist/migration/generator.cjs +323 -46
- package/dist/migration/generator.cjs.map +1 -1
- package/dist/migration/generator.d.cts +60 -11
- package/dist/migration/generator.d.ts +60 -11
- package/dist/migration/generator.js +319 -47
- package/dist/migration/generator.js.map +1 -1
- package/dist/migration/index.cjs +433 -47
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +3 -2
- package/dist/migration/index.d.ts +3 -2
- package/dist/migration/index.js +432 -48
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +3 -1
- package/dist/migration/snapshot.d.ts +3 -1
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/migration/utils/index.cjs +80 -0
- package/dist/migration/utils/index.cjs.map +1 -1
- package/dist/migration/utils/index.d.cts +39 -202
- package/dist/migration/utils/index.d.ts +39 -202
- package/dist/migration/utils/index.js +77 -1
- package/dist/migration/utils/index.js.map +1 -1
- package/dist/schema.cjs +200 -61
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -85
- package/dist/schema.d.ts +2 -85
- package/dist/schema.js +186 -50
- package/dist/schema.js.map +1 -1
- package/dist/type-mapper-DrQmtznD.d.cts +208 -0
- package/dist/type-mapper-n231Fspm.d.ts +208 -0
- package/dist/{types-z1Dkjg8m.d.ts → types-Ds3NQvny.d.ts} +33 -2
- package/dist/{types-BbTgmg6H.d.cts → types-YoBjsa-A.d.cts} +33 -2
- package/package.json +1 -1
package/dist/cli/migrate.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var fs5 = require('fs');
|
|
|
7
7
|
var path5 = require('path');
|
|
8
8
|
var url = require('url');
|
|
9
9
|
var zod = require('zod');
|
|
10
|
+
var crypto = require('crypto');
|
|
10
11
|
var ora = require('ora');
|
|
11
12
|
|
|
12
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -68,6 +69,18 @@ function extractRelationMetadata(description) {
|
|
|
68
69
|
}
|
|
69
70
|
return null;
|
|
70
71
|
}
|
|
72
|
+
var FIELD_METADATA_KEY = "__pocketbase_field__";
|
|
73
|
+
function extractFieldMetadata(description) {
|
|
74
|
+
if (!description) return null;
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(description);
|
|
77
|
+
if (parsed[FIELD_METADATA_KEY]) {
|
|
78
|
+
return parsed[FIELD_METADATA_KEY];
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
71
84
|
|
|
72
85
|
// src/migration/errors.ts
|
|
73
86
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -1306,6 +1319,38 @@ function isAuthCollection(fields) {
|
|
|
1306
1319
|
return hasEmail && hasPassword;
|
|
1307
1320
|
}
|
|
1308
1321
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1322
|
+
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1323
|
+
if (fieldMetadata) {
|
|
1324
|
+
let required2;
|
|
1325
|
+
if (fieldMetadata.type === "number") {
|
|
1326
|
+
if (fieldMetadata.options?.required !== void 0) {
|
|
1327
|
+
required2 = fieldMetadata.options.required;
|
|
1328
|
+
} else {
|
|
1329
|
+
required2 = false;
|
|
1330
|
+
}
|
|
1331
|
+
} else {
|
|
1332
|
+
required2 = isFieldRequired(zodType);
|
|
1333
|
+
}
|
|
1334
|
+
const { required: _required, ...options2 } = fieldMetadata.options || {};
|
|
1335
|
+
const fieldDef2 = {
|
|
1336
|
+
name: fieldName,
|
|
1337
|
+
type: fieldMetadata.type,
|
|
1338
|
+
required: required2,
|
|
1339
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1340
|
+
};
|
|
1341
|
+
if (fieldMetadata.type === "relation") {
|
|
1342
|
+
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
1343
|
+
if (relationMetadata2) {
|
|
1344
|
+
fieldDef2.relation = {
|
|
1345
|
+
collection: relationMetadata2.collection,
|
|
1346
|
+
maxSelect: relationMetadata2.maxSelect,
|
|
1347
|
+
minSelect: relationMetadata2.minSelect,
|
|
1348
|
+
cascadeDelete: relationMetadata2.cascadeDelete
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
return fieldDef2;
|
|
1353
|
+
}
|
|
1309
1354
|
const fieldType = mapZodTypeToPocketBase(zodType, fieldName);
|
|
1310
1355
|
const required = isFieldRequired(zodType);
|
|
1311
1356
|
const options = extractFieldOptions(zodType);
|
|
@@ -1461,6 +1506,65 @@ async function buildSchemaDefinition(config) {
|
|
|
1461
1506
|
async function parseSchemaFiles(config) {
|
|
1462
1507
|
return buildSchemaDefinition(config);
|
|
1463
1508
|
}
|
|
1509
|
+
function generateCollectionId() {
|
|
1510
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1511
|
+
const idLength = 15;
|
|
1512
|
+
const bytes = crypto.randomBytes(idLength);
|
|
1513
|
+
let id = "pb_";
|
|
1514
|
+
for (let i = 0; i < idLength; i++) {
|
|
1515
|
+
const index = bytes[i] % chars.length;
|
|
1516
|
+
id += chars[index];
|
|
1517
|
+
}
|
|
1518
|
+
return id;
|
|
1519
|
+
}
|
|
1520
|
+
var CollectionIdRegistry = class {
|
|
1521
|
+
ids;
|
|
1522
|
+
constructor() {
|
|
1523
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Generates a unique collection ID for a given collection name
|
|
1527
|
+
* Special case: Returns constant "_pb_users_auth_" for users collection
|
|
1528
|
+
* Retries up to 10 times if collision occurs (extremely rare)
|
|
1529
|
+
*
|
|
1530
|
+
* @param collectionName - The name of the collection
|
|
1531
|
+
* @returns A unique collection ID
|
|
1532
|
+
* @throws Error if unable to generate unique ID after max attempts
|
|
1533
|
+
*/
|
|
1534
|
+
generate(collectionName) {
|
|
1535
|
+
if (collectionName && collectionName.toLowerCase() === "users") {
|
|
1536
|
+
const usersId = "_pb_users_auth_";
|
|
1537
|
+
this.register(usersId);
|
|
1538
|
+
return usersId;
|
|
1539
|
+
}
|
|
1540
|
+
const maxAttempts = 10;
|
|
1541
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1542
|
+
const id = generateCollectionId();
|
|
1543
|
+
if (!this.has(id)) {
|
|
1544
|
+
this.register(id);
|
|
1545
|
+
return id;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
throw new Error("Failed to generate unique collection ID after maximum attempts");
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Checks if an ID has already been registered
|
|
1552
|
+
*
|
|
1553
|
+
* @param id - The collection ID to check
|
|
1554
|
+
* @returns True if the ID exists in the registry
|
|
1555
|
+
*/
|
|
1556
|
+
has(id) {
|
|
1557
|
+
return this.ids.has(id);
|
|
1558
|
+
}
|
|
1559
|
+
/**
|
|
1560
|
+
* Registers a collection ID in the registry
|
|
1561
|
+
*
|
|
1562
|
+
* @param id - The collection ID to register
|
|
1563
|
+
*/
|
|
1564
|
+
register(id) {
|
|
1565
|
+
this.ids.add(id);
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1464
1568
|
|
|
1465
1569
|
// src/migration/diff.ts
|
|
1466
1570
|
var DEFAULT_CONFIG2 = {
|
|
@@ -1792,6 +1896,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1792
1896
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
1793
1897
|
(collection) => !isSystemCollection(collection.name, config)
|
|
1794
1898
|
);
|
|
1899
|
+
const registry = new CollectionIdRegistry();
|
|
1900
|
+
const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {
|
|
1901
|
+
if (collection.id) {
|
|
1902
|
+
registry.register(collection.id);
|
|
1903
|
+
return collection;
|
|
1904
|
+
}
|
|
1905
|
+
const id = registry.generate(collection.name);
|
|
1906
|
+
return {
|
|
1907
|
+
...collection,
|
|
1908
|
+
id
|
|
1909
|
+
};
|
|
1910
|
+
});
|
|
1795
1911
|
const collectionsToModify = [];
|
|
1796
1912
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
1797
1913
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -1801,7 +1917,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1801
1917
|
}
|
|
1802
1918
|
}
|
|
1803
1919
|
return {
|
|
1804
|
-
collectionsToCreate:
|
|
1920
|
+
collectionsToCreate: collectionsWithIds,
|
|
1805
1921
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
1806
1922
|
collectionsToModify
|
|
1807
1923
|
};
|
|
@@ -1884,42 +2000,48 @@ function generateTimestamp(config) {
|
|
|
1884
2000
|
}
|
|
1885
2001
|
return Math.floor(Date.now() / 1e3).toString();
|
|
1886
2002
|
}
|
|
1887
|
-
function
|
|
1888
|
-
const
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
if (diff.collectionsToDelete.length === 1) {
|
|
1898
|
-
parts.push(`deleted_${diff.collectionsToDelete[0].name}`);
|
|
1899
|
-
} else {
|
|
1900
|
-
parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
if (diff.collectionsToModify.length > 0) {
|
|
1904
|
-
if (diff.collectionsToModify.length === 1) {
|
|
1905
|
-
parts.push(`updated_${diff.collectionsToModify[0].collection}`);
|
|
1906
|
-
} else {
|
|
1907
|
-
parts.push(`updated_${diff.collectionsToModify.length}_collections`);
|
|
1908
|
-
}
|
|
2003
|
+
function splitDiffByCollection(diff, baseTimestamp) {
|
|
2004
|
+
const operations = [];
|
|
2005
|
+
let currentTimestamp = parseInt(baseTimestamp, 10);
|
|
2006
|
+
for (const collection of diff.collectionsToCreate) {
|
|
2007
|
+
operations.push({
|
|
2008
|
+
type: "create",
|
|
2009
|
+
collection,
|
|
2010
|
+
timestamp: currentTimestamp.toString()
|
|
2011
|
+
});
|
|
2012
|
+
currentTimestamp += 1;
|
|
1909
2013
|
}
|
|
1910
|
-
|
|
1911
|
-
|
|
2014
|
+
for (const modification of diff.collectionsToModify) {
|
|
2015
|
+
operations.push({
|
|
2016
|
+
type: "modify",
|
|
2017
|
+
collection: modification.collection,
|
|
2018
|
+
modifications: modification,
|
|
2019
|
+
timestamp: currentTimestamp.toString()
|
|
2020
|
+
});
|
|
2021
|
+
currentTimestamp += 1;
|
|
1912
2022
|
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
2023
|
+
for (const collection of diff.collectionsToDelete) {
|
|
2024
|
+
operations.push({
|
|
2025
|
+
type: "delete",
|
|
2026
|
+
collection: collection.name || collection,
|
|
2027
|
+
// Handle both object and string
|
|
2028
|
+
timestamp: currentTimestamp.toString()
|
|
2029
|
+
});
|
|
2030
|
+
currentTimestamp += 1;
|
|
1916
2031
|
}
|
|
1917
|
-
return
|
|
2032
|
+
return operations;
|
|
1918
2033
|
}
|
|
1919
|
-
function
|
|
1920
|
-
const timestamp =
|
|
1921
|
-
const
|
|
1922
|
-
|
|
2034
|
+
function generateCollectionMigrationFilename(operation) {
|
|
2035
|
+
const timestamp = operation.timestamp;
|
|
2036
|
+
const operationType = operation.type === "modify" ? "updated" : operation.type === "create" ? "created" : "deleted";
|
|
2037
|
+
let collectionName;
|
|
2038
|
+
if (typeof operation.collection === "string") {
|
|
2039
|
+
collectionName = operation.collection;
|
|
2040
|
+
} else {
|
|
2041
|
+
collectionName = operation.collection.name;
|
|
2042
|
+
}
|
|
2043
|
+
const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
2044
|
+
return `${timestamp}_${operationType}_${sanitizedName}.js`;
|
|
1923
2045
|
}
|
|
1924
2046
|
function createMigrationFileStructure(upCode, downCode, config) {
|
|
1925
2047
|
const mergedConfig = config ? mergeConfig3(config) : DEFAULT_CONFIG3;
|
|
@@ -1991,14 +2113,13 @@ function formatValue(value) {
|
|
|
1991
2113
|
return "null";
|
|
1992
2114
|
}
|
|
1993
2115
|
if (typeof value === "string") {
|
|
1994
|
-
return
|
|
2116
|
+
return JSON.stringify(value);
|
|
1995
2117
|
}
|
|
1996
2118
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
1997
2119
|
return String(value);
|
|
1998
2120
|
}
|
|
1999
2121
|
if (Array.isArray(value)) {
|
|
2000
|
-
|
|
2001
|
-
return `[${items}]`;
|
|
2122
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
2002
2123
|
}
|
|
2003
2124
|
if (typeof value === "object") {
|
|
2004
2125
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -2006,7 +2127,7 @@ function formatValue(value) {
|
|
|
2006
2127
|
}
|
|
2007
2128
|
return String(value);
|
|
2008
2129
|
}
|
|
2009
|
-
function generateFieldDefinitionObject(field) {
|
|
2130
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
2010
2131
|
const parts = [];
|
|
2011
2132
|
parts.push(` name: "${field.name}"`);
|
|
2012
2133
|
parts.push(` type: "${field.type}"`);
|
|
@@ -2014,34 +2135,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
2014
2135
|
if (field.unique !== void 0) {
|
|
2015
2136
|
parts.push(` unique: ${field.unique}`);
|
|
2016
2137
|
}
|
|
2138
|
+
if (field.type === "select") {
|
|
2139
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2140
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2141
|
+
const values = field.options?.values ?? [];
|
|
2142
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2143
|
+
}
|
|
2017
2144
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2018
2145
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2146
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2147
|
+
continue;
|
|
2148
|
+
}
|
|
2019
2149
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2020
2150
|
}
|
|
2021
2151
|
}
|
|
2022
2152
|
if (field.relation) {
|
|
2023
2153
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
}
|
|
2032
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2033
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2154
|
+
let collectionIdValue;
|
|
2155
|
+
if (isUsersCollection) {
|
|
2156
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2157
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2158
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2159
|
+
} else {
|
|
2160
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2034
2161
|
}
|
|
2162
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2163
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2164
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2165
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2166
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2167
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2168
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2035
2169
|
}
|
|
2036
2170
|
return ` {
|
|
2037
2171
|
${parts.join(",\n")},
|
|
2038
2172
|
}`;
|
|
2039
2173
|
}
|
|
2040
|
-
function generateFieldsArray(fields) {
|
|
2174
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
2041
2175
|
if (fields.length === 0) {
|
|
2042
2176
|
return "[]";
|
|
2043
2177
|
}
|
|
2044
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
2178
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
2045
2179
|
return `[
|
|
2046
2180
|
${fieldObjects.join(",\n")},
|
|
2047
2181
|
]`;
|
|
@@ -2100,7 +2234,7 @@ function generateIndexesArray(indexes) {
|
|
|
2100
2234
|
if (!indexes || indexes.length === 0) {
|
|
2101
2235
|
return "[]";
|
|
2102
2236
|
}
|
|
2103
|
-
const indexStrings = indexes.map((idx) =>
|
|
2237
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
2104
2238
|
return `[
|
|
2105
2239
|
${indexStrings.join(",\n ")},
|
|
2106
2240
|
]`;
|
|
@@ -2154,7 +2288,7 @@ function getSystemFields() {
|
|
|
2154
2288
|
}
|
|
2155
2289
|
];
|
|
2156
2290
|
}
|
|
2157
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2291
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
2158
2292
|
const lines = [];
|
|
2159
2293
|
lines.push(` const ${varName} = new Collection({`);
|
|
2160
2294
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2168,7 +2302,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
2168
2302
|
}
|
|
2169
2303
|
const systemFields = getSystemFields();
|
|
2170
2304
|
const allFields = [...systemFields, ...collection.fields];
|
|
2171
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
2305
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
2172
2306
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2173
2307
|
lines.push(` });`);
|
|
2174
2308
|
lines.push(``);
|
|
@@ -2190,42 +2324,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
2190
2324
|
};
|
|
2191
2325
|
return constructorMap[fieldType] || "TextField";
|
|
2192
2326
|
}
|
|
2193
|
-
function generateFieldConstructorOptions(field) {
|
|
2327
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
2194
2328
|
const parts = [];
|
|
2195
2329
|
parts.push(` name: "${field.name}"`);
|
|
2196
2330
|
parts.push(` required: ${field.required}`);
|
|
2197
2331
|
if (field.unique !== void 0) {
|
|
2198
2332
|
parts.push(` unique: ${field.unique}`);
|
|
2199
2333
|
}
|
|
2334
|
+
if (field.type === "select") {
|
|
2335
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2336
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2337
|
+
const values = field.options?.values ?? [];
|
|
2338
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2339
|
+
}
|
|
2200
2340
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2201
2341
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2202
|
-
|
|
2342
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2343
|
+
continue;
|
|
2344
|
+
}
|
|
2345
|
+
if (field.type === "number" && key === "noDecimal") {
|
|
2346
|
+
parts.push(` onlyInt: ${formatValue(value)}`);
|
|
2347
|
+
} else {
|
|
2348
|
+
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2349
|
+
}
|
|
2203
2350
|
}
|
|
2204
2351
|
}
|
|
2205
2352
|
if (field.relation && field.type === "relation") {
|
|
2206
2353
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
}
|
|
2215
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2216
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2354
|
+
let collectionIdValue;
|
|
2355
|
+
if (isUsersCollection) {
|
|
2356
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2357
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2358
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2359
|
+
} else {
|
|
2360
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2217
2361
|
}
|
|
2362
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2363
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2364
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2365
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2366
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2367
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2368
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2218
2369
|
}
|
|
2219
2370
|
return parts.join(",\n");
|
|
2220
2371
|
}
|
|
2221
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2372
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
2222
2373
|
const lines = [];
|
|
2223
2374
|
const constructorName = getFieldConstructorName(field.type);
|
|
2224
2375
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
2225
2376
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2226
2377
|
lines.push(``);
|
|
2227
2378
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
2228
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
2379
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
2229
2380
|
lines.push(` }));`);
|
|
2230
2381
|
lines.push(``);
|
|
2231
2382
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -2275,7 +2426,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
2275
2426
|
const lines = [];
|
|
2276
2427
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2277
2428
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2278
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
2429
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
2279
2430
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2280
2431
|
return lines.join("\n");
|
|
2281
2432
|
}
|
|
@@ -2284,7 +2435,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
2284
2435
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2285
2436
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
2286
2437
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2287
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
2438
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
2288
2439
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2289
2440
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2290
2441
|
lines.push(` }`);
|
|
@@ -2313,243 +2464,194 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
2313
2464
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
2314
2465
|
return lines.join("\n");
|
|
2315
2466
|
}
|
|
2316
|
-
function
|
|
2467
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
2317
2468
|
const lines = [];
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
lines.push(
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2334
|
-
lines.push(` // Add fields to ${collectionName}`);
|
|
2335
|
-
for (const field of modification.fieldsToAdd) {
|
|
2336
|
-
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2337
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2338
|
-
lines.push(``);
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2342
|
-
lines.push(` // Modify fields in ${collectionName}`);
|
|
2343
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2344
|
-
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2345
|
-
lines.push(generateFieldModification(collectionName, fieldMod, varName));
|
|
2346
|
-
lines.push(``);
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2350
|
-
lines.push(` // Remove fields from ${collectionName}`);
|
|
2351
|
-
for (const field of modification.fieldsToRemove) {
|
|
2352
|
-
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2353
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2354
|
-
lines.push(``);
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2358
|
-
lines.push(` // Add indexes to ${collectionName}`);
|
|
2359
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2360
|
-
const index = modification.indexesToAdd[i];
|
|
2361
|
-
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2362
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2363
|
-
lines.push(``);
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2367
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2368
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2369
|
-
const index = modification.indexesToRemove[i];
|
|
2370
|
-
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2371
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2372
|
-
lines.push(``);
|
|
2373
|
-
}
|
|
2374
|
-
}
|
|
2375
|
-
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2376
|
-
lines.push(` // Update permissions for ${collectionName}`);
|
|
2377
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2378
|
-
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2379
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName));
|
|
2380
|
-
lines.push(``);
|
|
2381
|
-
}
|
|
2382
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2383
|
-
lines.push(` // Update rules for ${collectionName}`);
|
|
2384
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2385
|
-
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2386
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName));
|
|
2387
|
-
lines.push(``);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2469
|
+
if (operation.type === "create") {
|
|
2470
|
+
const collection = operation.collection;
|
|
2471
|
+
const varName = `collection_${collection.name}`;
|
|
2472
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2473
|
+
} else if (operation.type === "modify") {
|
|
2474
|
+
const modification = operation.modifications;
|
|
2475
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2476
|
+
let operationCount = 0;
|
|
2477
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2478
|
+
for (const field of modification.fieldsToAdd) {
|
|
2479
|
+
operationCount++;
|
|
2480
|
+
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2481
|
+
const isLast = operationCount === totalOperations;
|
|
2482
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2483
|
+
if (!isLast) lines.push("");
|
|
2390
2484
|
}
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
lines.push(generateCollectionDeletion(collection.name, varName));
|
|
2398
|
-
lines.push(``);
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
|
-
if (lines.length === 2) {
|
|
2402
|
-
lines.push(` // No changes detected`);
|
|
2403
|
-
lines.push(``);
|
|
2404
|
-
}
|
|
2405
|
-
let code = lines.join("\n");
|
|
2406
|
-
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2407
|
-
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2408
|
-
const saveMatches = [...code.matchAll(savePattern)];
|
|
2409
|
-
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2410
|
-
const allMatches = [
|
|
2411
|
-
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2412
|
-
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2413
|
-
].sort((a, b) => b.index - a.index);
|
|
2414
|
-
if (allMatches.length > 0) {
|
|
2415
|
-
const lastMatch = allMatches[0];
|
|
2416
|
-
if (lastMatch.type === "save") {
|
|
2417
|
-
code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.save(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
|
|
2418
|
-
} else {
|
|
2419
|
-
code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.delete(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
|
|
2485
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2486
|
+
operationCount++;
|
|
2487
|
+
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2488
|
+
const isLast = operationCount === totalOperations;
|
|
2489
|
+
lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
|
|
2490
|
+
if (!isLast) lines.push("");
|
|
2420
2491
|
}
|
|
2492
|
+
for (const field of modification.fieldsToRemove) {
|
|
2493
|
+
operationCount++;
|
|
2494
|
+
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2495
|
+
const isLast = operationCount === totalOperations;
|
|
2496
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2497
|
+
if (!isLast) lines.push("");
|
|
2498
|
+
}
|
|
2499
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2500
|
+
operationCount++;
|
|
2501
|
+
const index = modification.indexesToAdd[i];
|
|
2502
|
+
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2503
|
+
const isLast = operationCount === totalOperations;
|
|
2504
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2505
|
+
if (!isLast) lines.push("");
|
|
2506
|
+
}
|
|
2507
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2508
|
+
operationCount++;
|
|
2509
|
+
const index = modification.indexesToRemove[i];
|
|
2510
|
+
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2511
|
+
const isLast = operationCount === totalOperations;
|
|
2512
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2513
|
+
if (!isLast) lines.push("");
|
|
2514
|
+
}
|
|
2515
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2516
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2517
|
+
operationCount++;
|
|
2518
|
+
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2519
|
+
const isLast = operationCount === totalOperations;
|
|
2520
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast));
|
|
2521
|
+
if (!isLast) lines.push("");
|
|
2522
|
+
}
|
|
2523
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2524
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2525
|
+
operationCount++;
|
|
2526
|
+
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2527
|
+
const isLast = operationCount === totalOperations;
|
|
2528
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast));
|
|
2529
|
+
if (!isLast) lines.push("");
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
} else if (operation.type === "delete") {
|
|
2533
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection.name;
|
|
2534
|
+
const varName = `collection_${collectionName}`;
|
|
2535
|
+
lines.push(generateCollectionDeletion(collectionName, varName, true));
|
|
2421
2536
|
}
|
|
2422
|
-
return
|
|
2537
|
+
return lines.join("\n");
|
|
2423
2538
|
}
|
|
2424
|
-
function
|
|
2539
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
2425
2540
|
const lines = [];
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
lines.push(
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2541
|
+
if (operation.type === "create") {
|
|
2542
|
+
const collection = operation.collection;
|
|
2543
|
+
const varName = `collection_${collection.name}`;
|
|
2544
|
+
lines.push(generateCollectionDeletion(collection.name, varName, true));
|
|
2545
|
+
} else if (operation.type === "modify") {
|
|
2546
|
+
const modification = operation.modifications;
|
|
2547
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2548
|
+
let operationCount = 0;
|
|
2549
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2550
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2551
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2552
|
+
operationCount++;
|
|
2553
|
+
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2554
|
+
const isLast = operationCount === totalOperations;
|
|
2555
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast));
|
|
2556
|
+
if (!isLast) lines.push("");
|
|
2557
|
+
}
|
|
2558
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2559
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2560
|
+
operationCount++;
|
|
2561
|
+
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2562
|
+
const isLast = operationCount === totalOperations;
|
|
2563
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast));
|
|
2564
|
+
if (!isLast) lines.push("");
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2568
|
+
operationCount++;
|
|
2569
|
+
const index = modification.indexesToRemove[i];
|
|
2570
|
+
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2571
|
+
const isLast = operationCount === totalOperations;
|
|
2572
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2573
|
+
if (!isLast) lines.push("");
|
|
2574
|
+
}
|
|
2575
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2576
|
+
operationCount++;
|
|
2577
|
+
const index = modification.indexesToAdd[i];
|
|
2578
|
+
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2579
|
+
const isLast = operationCount === totalOperations;
|
|
2580
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2581
|
+
if (!isLast) lines.push("");
|
|
2435
2582
|
}
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
if (
|
|
2442
|
-
lines.push(` // Revert permissions for ${collectionName}`);
|
|
2443
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2444
|
-
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2445
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName));
|
|
2446
|
-
lines.push(``);
|
|
2447
|
-
}
|
|
2448
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2449
|
-
lines.push(` // Revert rules for ${collectionName}`);
|
|
2450
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2451
|
-
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2452
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName));
|
|
2453
|
-
lines.push(``);
|
|
2454
|
-
}
|
|
2455
|
-
}
|
|
2456
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2457
|
-
lines.push(` // Restore indexes to ${collectionName}`);
|
|
2458
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2459
|
-
const index = modification.indexesToRemove[i];
|
|
2460
|
-
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2461
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2462
|
-
lines.push(``);
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2465
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2466
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2467
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2468
|
-
const index = modification.indexesToAdd[i];
|
|
2469
|
-
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2470
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2471
|
-
lines.push(``);
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2475
|
-
lines.push(` // Restore fields to ${collectionName}`);
|
|
2476
|
-
for (const field of modification.fieldsToRemove) {
|
|
2477
|
-
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2478
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2479
|
-
lines.push(``);
|
|
2480
|
-
}
|
|
2481
|
-
}
|
|
2482
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2483
|
-
lines.push(` // Revert field modifications in ${collectionName}`);
|
|
2484
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2485
|
-
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2486
|
-
property: change.property,
|
|
2487
|
-
oldValue: change.newValue,
|
|
2488
|
-
newValue: change.oldValue
|
|
2489
|
-
}));
|
|
2490
|
-
const reverseMod = {
|
|
2491
|
-
fieldName: fieldMod.fieldName,
|
|
2492
|
-
currentDefinition: fieldMod.newDefinition,
|
|
2493
|
-
newDefinition: fieldMod.currentDefinition,
|
|
2494
|
-
changes: reverseChanges
|
|
2495
|
-
};
|
|
2496
|
-
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2497
|
-
lines.push(generateFieldModification(collectionName, reverseMod, varName));
|
|
2498
|
-
lines.push(``);
|
|
2499
|
-
}
|
|
2500
|
-
}
|
|
2501
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2502
|
-
lines.push(` // Remove added fields from ${collectionName}`);
|
|
2503
|
-
for (const field of modification.fieldsToAdd) {
|
|
2504
|
-
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2505
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2506
|
-
lines.push(``);
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2583
|
+
for (const field of modification.fieldsToRemove) {
|
|
2584
|
+
operationCount++;
|
|
2585
|
+
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2586
|
+
const isLast = operationCount === totalOperations;
|
|
2587
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2588
|
+
if (!isLast) lines.push("");
|
|
2509
2589
|
}
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2590
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2591
|
+
operationCount++;
|
|
2592
|
+
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2593
|
+
property: change.property,
|
|
2594
|
+
oldValue: change.newValue,
|
|
2595
|
+
newValue: change.oldValue
|
|
2596
|
+
}));
|
|
2597
|
+
const reverseMod = {
|
|
2598
|
+
fieldName: fieldMod.fieldName,
|
|
2599
|
+
currentDefinition: fieldMod.newDefinition,
|
|
2600
|
+
newDefinition: fieldMod.currentDefinition,
|
|
2601
|
+
changes: reverseChanges
|
|
2602
|
+
};
|
|
2603
|
+
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2604
|
+
const isLast = operationCount === totalOperations;
|
|
2605
|
+
lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast));
|
|
2606
|
+
if (!isLast) lines.push("");
|
|
2607
|
+
}
|
|
2608
|
+
for (const field of modification.fieldsToAdd) {
|
|
2609
|
+
operationCount++;
|
|
2610
|
+
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2611
|
+
const isLast = operationCount === totalOperations;
|
|
2612
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2613
|
+
if (!isLast) lines.push("");
|
|
2614
|
+
}
|
|
2615
|
+
} else if (operation.type === "delete") {
|
|
2616
|
+
const collection = operation.collection;
|
|
2617
|
+
if (typeof collection !== "string") {
|
|
2618
|
+
const varName = `collection_${collection.name}`;
|
|
2619
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2539
2620
|
}
|
|
2540
2621
|
}
|
|
2541
|
-
return
|
|
2622
|
+
return lines.join("\n");
|
|
2542
2623
|
}
|
|
2543
2624
|
function generate(diff, config) {
|
|
2544
2625
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
2545
2626
|
try {
|
|
2546
2627
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
2547
|
-
const
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
const
|
|
2552
|
-
|
|
2628
|
+
const hasChanges4 = diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;
|
|
2629
|
+
if (!hasChanges4) {
|
|
2630
|
+
return [];
|
|
2631
|
+
}
|
|
2632
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
2633
|
+
for (const collection of diff.collectionsToCreate) {
|
|
2634
|
+
if (collection.id) {
|
|
2635
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
for (const collection of diff.collectionsToDelete) {
|
|
2639
|
+
if (collection.id) {
|
|
2640
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
const baseTimestamp = generateTimestamp(normalizedConfig);
|
|
2644
|
+
const operations = splitDiffByCollection(diff, baseTimestamp);
|
|
2645
|
+
const filePaths = [];
|
|
2646
|
+
for (const operation of operations) {
|
|
2647
|
+
const upCode = generateOperationUpMigration(operation, collectionIdMap);
|
|
2648
|
+
const downCode = generateOperationDownMigration(operation, collectionIdMap);
|
|
2649
|
+
const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);
|
|
2650
|
+
const filename = generateCollectionMigrationFilename(operation);
|
|
2651
|
+
const filePath = writeMigrationFile(migrationDir, filename, content);
|
|
2652
|
+
filePaths.push(filePath);
|
|
2653
|
+
}
|
|
2654
|
+
return filePaths;
|
|
2553
2655
|
} catch (error) {
|
|
2554
2656
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
2555
2657
|
throw error;
|
|
@@ -3570,15 +3672,25 @@ async function executeGenerate(options) {
|
|
|
3570
3672
|
process.exit(1);
|
|
3571
3673
|
}
|
|
3572
3674
|
logSection("\u{1F4DD} Generating Migration");
|
|
3573
|
-
const
|
|
3675
|
+
const migrationPaths = await withProgress(
|
|
3574
3676
|
"Creating migration file...",
|
|
3575
3677
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
3576
3678
|
);
|
|
3577
|
-
|
|
3679
|
+
if (migrationPaths.length === 0) {
|
|
3680
|
+
logWarning("No migration files were generated (no changes detected).");
|
|
3681
|
+
return;
|
|
3682
|
+
}
|
|
3683
|
+
if (migrationPaths.length === 1) {
|
|
3684
|
+
logSuccess(`Migration file created: ${path5__namespace.basename(migrationPaths[0])}`);
|
|
3685
|
+
} else {
|
|
3686
|
+
logSuccess(`Created ${migrationPaths.length} migration files`);
|
|
3687
|
+
}
|
|
3578
3688
|
logSection("\u2705 Next Steps");
|
|
3579
3689
|
console.log();
|
|
3580
|
-
console.log(" 1. Review the generated migration file:");
|
|
3581
|
-
|
|
3690
|
+
console.log(" 1. Review the generated migration file(s):");
|
|
3691
|
+
migrationPaths.forEach((migrationPath) => {
|
|
3692
|
+
console.log(` ${migrationPath}`);
|
|
3693
|
+
});
|
|
3582
3694
|
console.log();
|
|
3583
3695
|
console.log(" 2. Apply the migration by running PocketBase:");
|
|
3584
3696
|
console.log(" yarn pb");
|