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/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var path5 = require('path');
|
|
4
4
|
var fs5 = require('fs');
|
|
5
5
|
var zod = require('zod');
|
|
6
|
+
var crypto = require('crypto');
|
|
6
7
|
var chalk = require('chalk');
|
|
7
8
|
var ora = require('ora');
|
|
8
9
|
|
|
@@ -63,6 +64,18 @@ function extractRelationMetadata(description) {
|
|
|
63
64
|
}
|
|
64
65
|
return null;
|
|
65
66
|
}
|
|
67
|
+
var FIELD_METADATA_KEY = "__pocketbase_field__";
|
|
68
|
+
function extractFieldMetadata(description) {
|
|
69
|
+
if (!description) return null;
|
|
70
|
+
try {
|
|
71
|
+
const parsed = JSON.parse(description);
|
|
72
|
+
if (parsed[FIELD_METADATA_KEY]) {
|
|
73
|
+
return parsed[FIELD_METADATA_KEY];
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
66
79
|
|
|
67
80
|
// src/migration/errors.ts
|
|
68
81
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -1301,6 +1314,38 @@ function isAuthCollection(fields) {
|
|
|
1301
1314
|
return hasEmail && hasPassword;
|
|
1302
1315
|
}
|
|
1303
1316
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1317
|
+
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1318
|
+
if (fieldMetadata) {
|
|
1319
|
+
let required2;
|
|
1320
|
+
if (fieldMetadata.type === "number") {
|
|
1321
|
+
if (fieldMetadata.options?.required !== void 0) {
|
|
1322
|
+
required2 = fieldMetadata.options.required;
|
|
1323
|
+
} else {
|
|
1324
|
+
required2 = false;
|
|
1325
|
+
}
|
|
1326
|
+
} else {
|
|
1327
|
+
required2 = isFieldRequired(zodType);
|
|
1328
|
+
}
|
|
1329
|
+
const { required: _required, ...options2 } = fieldMetadata.options || {};
|
|
1330
|
+
const fieldDef2 = {
|
|
1331
|
+
name: fieldName,
|
|
1332
|
+
type: fieldMetadata.type,
|
|
1333
|
+
required: required2,
|
|
1334
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1335
|
+
};
|
|
1336
|
+
if (fieldMetadata.type === "relation") {
|
|
1337
|
+
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
1338
|
+
if (relationMetadata2) {
|
|
1339
|
+
fieldDef2.relation = {
|
|
1340
|
+
collection: relationMetadata2.collection,
|
|
1341
|
+
maxSelect: relationMetadata2.maxSelect,
|
|
1342
|
+
minSelect: relationMetadata2.minSelect,
|
|
1343
|
+
cascadeDelete: relationMetadata2.cascadeDelete
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
return fieldDef2;
|
|
1348
|
+
}
|
|
1304
1349
|
const fieldType = mapZodTypeToPocketBase(zodType, fieldName);
|
|
1305
1350
|
const required = isFieldRequired(zodType);
|
|
1306
1351
|
const options = extractFieldOptions(zodType);
|
|
@@ -1456,6 +1501,65 @@ async function buildSchemaDefinition(config) {
|
|
|
1456
1501
|
async function parseSchemaFiles(config) {
|
|
1457
1502
|
return buildSchemaDefinition(config);
|
|
1458
1503
|
}
|
|
1504
|
+
function generateCollectionId() {
|
|
1505
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1506
|
+
const idLength = 15;
|
|
1507
|
+
const bytes = crypto.randomBytes(idLength);
|
|
1508
|
+
let id = "pb_";
|
|
1509
|
+
for (let i = 0; i < idLength; i++) {
|
|
1510
|
+
const index = bytes[i] % chars.length;
|
|
1511
|
+
id += chars[index];
|
|
1512
|
+
}
|
|
1513
|
+
return id;
|
|
1514
|
+
}
|
|
1515
|
+
var CollectionIdRegistry = class {
|
|
1516
|
+
ids;
|
|
1517
|
+
constructor() {
|
|
1518
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Generates a unique collection ID for a given collection name
|
|
1522
|
+
* Special case: Returns constant "_pb_users_auth_" for users collection
|
|
1523
|
+
* Retries up to 10 times if collision occurs (extremely rare)
|
|
1524
|
+
*
|
|
1525
|
+
* @param collectionName - The name of the collection
|
|
1526
|
+
* @returns A unique collection ID
|
|
1527
|
+
* @throws Error if unable to generate unique ID after max attempts
|
|
1528
|
+
*/
|
|
1529
|
+
generate(collectionName) {
|
|
1530
|
+
if (collectionName && collectionName.toLowerCase() === "users") {
|
|
1531
|
+
const usersId = "_pb_users_auth_";
|
|
1532
|
+
this.register(usersId);
|
|
1533
|
+
return usersId;
|
|
1534
|
+
}
|
|
1535
|
+
const maxAttempts = 10;
|
|
1536
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1537
|
+
const id = generateCollectionId();
|
|
1538
|
+
if (!this.has(id)) {
|
|
1539
|
+
this.register(id);
|
|
1540
|
+
return id;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
throw new Error("Failed to generate unique collection ID after maximum attempts");
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Checks if an ID has already been registered
|
|
1547
|
+
*
|
|
1548
|
+
* @param id - The collection ID to check
|
|
1549
|
+
* @returns True if the ID exists in the registry
|
|
1550
|
+
*/
|
|
1551
|
+
has(id) {
|
|
1552
|
+
return this.ids.has(id);
|
|
1553
|
+
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Registers a collection ID in the registry
|
|
1556
|
+
*
|
|
1557
|
+
* @param id - The collection ID to register
|
|
1558
|
+
*/
|
|
1559
|
+
register(id) {
|
|
1560
|
+
this.ids.add(id);
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1459
1563
|
|
|
1460
1564
|
// src/migration/diff.ts
|
|
1461
1565
|
var DEFAULT_CONFIG2 = {
|
|
@@ -1787,6 +1891,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1787
1891
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
1788
1892
|
(collection) => !isSystemCollection(collection.name, config)
|
|
1789
1893
|
);
|
|
1894
|
+
const registry = new CollectionIdRegistry();
|
|
1895
|
+
const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {
|
|
1896
|
+
if (collection.id) {
|
|
1897
|
+
registry.register(collection.id);
|
|
1898
|
+
return collection;
|
|
1899
|
+
}
|
|
1900
|
+
const id = registry.generate(collection.name);
|
|
1901
|
+
return {
|
|
1902
|
+
...collection,
|
|
1903
|
+
id
|
|
1904
|
+
};
|
|
1905
|
+
});
|
|
1790
1906
|
const collectionsToModify = [];
|
|
1791
1907
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
1792
1908
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -1796,7 +1912,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1796
1912
|
}
|
|
1797
1913
|
}
|
|
1798
1914
|
return {
|
|
1799
|
-
collectionsToCreate:
|
|
1915
|
+
collectionsToCreate: collectionsWithIds,
|
|
1800
1916
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
1801
1917
|
collectionsToModify
|
|
1802
1918
|
};
|
|
@@ -1879,42 +1995,48 @@ function generateTimestamp(config) {
|
|
|
1879
1995
|
}
|
|
1880
1996
|
return Math.floor(Date.now() / 1e3).toString();
|
|
1881
1997
|
}
|
|
1882
|
-
function
|
|
1883
|
-
const
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
if (diff.collectionsToDelete.length === 1) {
|
|
1893
|
-
parts.push(`deleted_${diff.collectionsToDelete[0].name}`);
|
|
1894
|
-
} else {
|
|
1895
|
-
parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
if (diff.collectionsToModify.length > 0) {
|
|
1899
|
-
if (diff.collectionsToModify.length === 1) {
|
|
1900
|
-
parts.push(`updated_${diff.collectionsToModify[0].collection}`);
|
|
1901
|
-
} else {
|
|
1902
|
-
parts.push(`updated_${diff.collectionsToModify.length}_collections`);
|
|
1903
|
-
}
|
|
1998
|
+
function splitDiffByCollection(diff, baseTimestamp) {
|
|
1999
|
+
const operations = [];
|
|
2000
|
+
let currentTimestamp = parseInt(baseTimestamp, 10);
|
|
2001
|
+
for (const collection of diff.collectionsToCreate) {
|
|
2002
|
+
operations.push({
|
|
2003
|
+
type: "create",
|
|
2004
|
+
collection,
|
|
2005
|
+
timestamp: currentTimestamp.toString()
|
|
2006
|
+
});
|
|
2007
|
+
currentTimestamp += 1;
|
|
1904
2008
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
2009
|
+
for (const modification of diff.collectionsToModify) {
|
|
2010
|
+
operations.push({
|
|
2011
|
+
type: "modify",
|
|
2012
|
+
collection: modification.collection,
|
|
2013
|
+
modifications: modification,
|
|
2014
|
+
timestamp: currentTimestamp.toString()
|
|
2015
|
+
});
|
|
2016
|
+
currentTimestamp += 1;
|
|
1907
2017
|
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
2018
|
+
for (const collection of diff.collectionsToDelete) {
|
|
2019
|
+
operations.push({
|
|
2020
|
+
type: "delete",
|
|
2021
|
+
collection: collection.name || collection,
|
|
2022
|
+
// Handle both object and string
|
|
2023
|
+
timestamp: currentTimestamp.toString()
|
|
2024
|
+
});
|
|
2025
|
+
currentTimestamp += 1;
|
|
1911
2026
|
}
|
|
1912
|
-
return
|
|
2027
|
+
return operations;
|
|
1913
2028
|
}
|
|
1914
|
-
function
|
|
1915
|
-
const timestamp =
|
|
1916
|
-
const
|
|
1917
|
-
|
|
2029
|
+
function generateCollectionMigrationFilename(operation) {
|
|
2030
|
+
const timestamp = operation.timestamp;
|
|
2031
|
+
const operationType = operation.type === "modify" ? "updated" : operation.type === "create" ? "created" : "deleted";
|
|
2032
|
+
let collectionName;
|
|
2033
|
+
if (typeof operation.collection === "string") {
|
|
2034
|
+
collectionName = operation.collection;
|
|
2035
|
+
} else {
|
|
2036
|
+
collectionName = operation.collection.name;
|
|
2037
|
+
}
|
|
2038
|
+
const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
2039
|
+
return `${timestamp}_${operationType}_${sanitizedName}.js`;
|
|
1918
2040
|
}
|
|
1919
2041
|
function createMigrationFileStructure(upCode, downCode, config) {
|
|
1920
2042
|
const mergedConfig = config ? mergeConfig3(config) : DEFAULT_CONFIG3;
|
|
@@ -1986,14 +2108,13 @@ function formatValue(value) {
|
|
|
1986
2108
|
return "null";
|
|
1987
2109
|
}
|
|
1988
2110
|
if (typeof value === "string") {
|
|
1989
|
-
return
|
|
2111
|
+
return JSON.stringify(value);
|
|
1990
2112
|
}
|
|
1991
2113
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
1992
2114
|
return String(value);
|
|
1993
2115
|
}
|
|
1994
2116
|
if (Array.isArray(value)) {
|
|
1995
|
-
|
|
1996
|
-
return `[${items}]`;
|
|
2117
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
1997
2118
|
}
|
|
1998
2119
|
if (typeof value === "object") {
|
|
1999
2120
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -2001,7 +2122,7 @@ function formatValue(value) {
|
|
|
2001
2122
|
}
|
|
2002
2123
|
return String(value);
|
|
2003
2124
|
}
|
|
2004
|
-
function generateFieldDefinitionObject(field) {
|
|
2125
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
2005
2126
|
const parts = [];
|
|
2006
2127
|
parts.push(` name: "${field.name}"`);
|
|
2007
2128
|
parts.push(` type: "${field.type}"`);
|
|
@@ -2009,34 +2130,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
2009
2130
|
if (field.unique !== void 0) {
|
|
2010
2131
|
parts.push(` unique: ${field.unique}`);
|
|
2011
2132
|
}
|
|
2133
|
+
if (field.type === "select") {
|
|
2134
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2135
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2136
|
+
const values = field.options?.values ?? [];
|
|
2137
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2138
|
+
}
|
|
2012
2139
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2013
2140
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2141
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2142
|
+
continue;
|
|
2143
|
+
}
|
|
2014
2144
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2015
2145
|
}
|
|
2016
2146
|
}
|
|
2017
2147
|
if (field.relation) {
|
|
2018
2148
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
}
|
|
2027
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2028
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2149
|
+
let collectionIdValue;
|
|
2150
|
+
if (isUsersCollection) {
|
|
2151
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2152
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2153
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2154
|
+
} else {
|
|
2155
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2029
2156
|
}
|
|
2157
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2158
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2159
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2160
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2161
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2162
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2163
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2030
2164
|
}
|
|
2031
2165
|
return ` {
|
|
2032
2166
|
${parts.join(",\n")},
|
|
2033
2167
|
}`;
|
|
2034
2168
|
}
|
|
2035
|
-
function generateFieldsArray(fields) {
|
|
2169
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
2036
2170
|
if (fields.length === 0) {
|
|
2037
2171
|
return "[]";
|
|
2038
2172
|
}
|
|
2039
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
2173
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
2040
2174
|
return `[
|
|
2041
2175
|
${fieldObjects.join(",\n")},
|
|
2042
2176
|
]`;
|
|
@@ -2095,7 +2229,7 @@ function generateIndexesArray(indexes) {
|
|
|
2095
2229
|
if (!indexes || indexes.length === 0) {
|
|
2096
2230
|
return "[]";
|
|
2097
2231
|
}
|
|
2098
|
-
const indexStrings = indexes.map((idx) =>
|
|
2232
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
2099
2233
|
return `[
|
|
2100
2234
|
${indexStrings.join(",\n ")},
|
|
2101
2235
|
]`;
|
|
@@ -2149,7 +2283,7 @@ function getSystemFields() {
|
|
|
2149
2283
|
}
|
|
2150
2284
|
];
|
|
2151
2285
|
}
|
|
2152
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2286
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
2153
2287
|
const lines = [];
|
|
2154
2288
|
lines.push(` const ${varName} = new Collection({`);
|
|
2155
2289
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2163,7 +2297,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
2163
2297
|
}
|
|
2164
2298
|
const systemFields = getSystemFields();
|
|
2165
2299
|
const allFields = [...systemFields, ...collection.fields];
|
|
2166
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
2300
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
2167
2301
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2168
2302
|
lines.push(` });`);
|
|
2169
2303
|
lines.push(``);
|
|
@@ -2185,42 +2319,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
2185
2319
|
};
|
|
2186
2320
|
return constructorMap[fieldType] || "TextField";
|
|
2187
2321
|
}
|
|
2188
|
-
function generateFieldConstructorOptions(field) {
|
|
2322
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
2189
2323
|
const parts = [];
|
|
2190
2324
|
parts.push(` name: "${field.name}"`);
|
|
2191
2325
|
parts.push(` required: ${field.required}`);
|
|
2192
2326
|
if (field.unique !== void 0) {
|
|
2193
2327
|
parts.push(` unique: ${field.unique}`);
|
|
2194
2328
|
}
|
|
2329
|
+
if (field.type === "select") {
|
|
2330
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2331
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2332
|
+
const values = field.options?.values ?? [];
|
|
2333
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2334
|
+
}
|
|
2195
2335
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2196
2336
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2197
|
-
|
|
2337
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2338
|
+
continue;
|
|
2339
|
+
}
|
|
2340
|
+
if (field.type === "number" && key === "noDecimal") {
|
|
2341
|
+
parts.push(` onlyInt: ${formatValue(value)}`);
|
|
2342
|
+
} else {
|
|
2343
|
+
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2344
|
+
}
|
|
2198
2345
|
}
|
|
2199
2346
|
}
|
|
2200
2347
|
if (field.relation && field.type === "relation") {
|
|
2201
2348
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
}
|
|
2210
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2211
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2349
|
+
let collectionIdValue;
|
|
2350
|
+
if (isUsersCollection) {
|
|
2351
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2352
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2353
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2354
|
+
} else {
|
|
2355
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2212
2356
|
}
|
|
2357
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2358
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2359
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2360
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2361
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2362
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2363
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2213
2364
|
}
|
|
2214
2365
|
return parts.join(",\n");
|
|
2215
2366
|
}
|
|
2216
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2367
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
2217
2368
|
const lines = [];
|
|
2218
2369
|
const constructorName = getFieldConstructorName(field.type);
|
|
2219
2370
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
2220
2371
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2221
2372
|
lines.push(``);
|
|
2222
2373
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
2223
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
2374
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
2224
2375
|
lines.push(` }));`);
|
|
2225
2376
|
lines.push(``);
|
|
2226
2377
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -2270,7 +2421,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
2270
2421
|
const lines = [];
|
|
2271
2422
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2272
2423
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2273
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
2424
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
2274
2425
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2275
2426
|
return lines.join("\n");
|
|
2276
2427
|
}
|
|
@@ -2279,7 +2430,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
2279
2430
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2280
2431
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
2281
2432
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2282
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
2433
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
2283
2434
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2284
2435
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2285
2436
|
lines.push(` }`);
|
|
@@ -2308,243 +2459,194 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
2308
2459
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
2309
2460
|
return lines.join("\n");
|
|
2310
2461
|
}
|
|
2311
|
-
function
|
|
2462
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
2312
2463
|
const lines = [];
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
lines.push(
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2329
|
-
lines.push(` // Add fields to ${collectionName}`);
|
|
2330
|
-
for (const field of modification.fieldsToAdd) {
|
|
2331
|
-
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2332
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2333
|
-
lines.push(``);
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2337
|
-
lines.push(` // Modify fields in ${collectionName}`);
|
|
2338
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2339
|
-
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2340
|
-
lines.push(generateFieldModification(collectionName, fieldMod, varName));
|
|
2341
|
-
lines.push(``);
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2345
|
-
lines.push(` // Remove fields from ${collectionName}`);
|
|
2346
|
-
for (const field of modification.fieldsToRemove) {
|
|
2347
|
-
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2348
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2349
|
-
lines.push(``);
|
|
2350
|
-
}
|
|
2351
|
-
}
|
|
2352
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2353
|
-
lines.push(` // Add indexes to ${collectionName}`);
|
|
2354
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2355
|
-
const index = modification.indexesToAdd[i];
|
|
2356
|
-
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2357
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2358
|
-
lines.push(``);
|
|
2359
|
-
}
|
|
2360
|
-
}
|
|
2361
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2362
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2363
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2364
|
-
const index = modification.indexesToRemove[i];
|
|
2365
|
-
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2366
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2367
|
-
lines.push(``);
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2371
|
-
lines.push(` // Update permissions for ${collectionName}`);
|
|
2372
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2373
|
-
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2374
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName));
|
|
2375
|
-
lines.push(``);
|
|
2376
|
-
}
|
|
2377
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2378
|
-
lines.push(` // Update rules for ${collectionName}`);
|
|
2379
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2380
|
-
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2381
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName));
|
|
2382
|
-
lines.push(``);
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2464
|
+
if (operation.type === "create") {
|
|
2465
|
+
const collection = operation.collection;
|
|
2466
|
+
const varName = `collection_${collection.name}`;
|
|
2467
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2468
|
+
} else if (operation.type === "modify") {
|
|
2469
|
+
const modification = operation.modifications;
|
|
2470
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2471
|
+
let operationCount = 0;
|
|
2472
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2473
|
+
for (const field of modification.fieldsToAdd) {
|
|
2474
|
+
operationCount++;
|
|
2475
|
+
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2476
|
+
const isLast = operationCount === totalOperations;
|
|
2477
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2478
|
+
if (!isLast) lines.push("");
|
|
2385
2479
|
}
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
lines.push(generateCollectionDeletion(collection.name, varName));
|
|
2393
|
-
lines.push(``);
|
|
2394
|
-
}
|
|
2395
|
-
}
|
|
2396
|
-
if (lines.length === 2) {
|
|
2397
|
-
lines.push(` // No changes detected`);
|
|
2398
|
-
lines.push(``);
|
|
2399
|
-
}
|
|
2400
|
-
let code = lines.join("\n");
|
|
2401
|
-
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2402
|
-
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2403
|
-
const saveMatches = [...code.matchAll(savePattern)];
|
|
2404
|
-
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2405
|
-
const allMatches = [
|
|
2406
|
-
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2407
|
-
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2408
|
-
].sort((a, b) => b.index - a.index);
|
|
2409
|
-
if (allMatches.length > 0) {
|
|
2410
|
-
const lastMatch = allMatches[0];
|
|
2411
|
-
if (lastMatch.type === "save") {
|
|
2412
|
-
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);
|
|
2413
|
-
} else {
|
|
2414
|
-
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);
|
|
2480
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2481
|
+
operationCount++;
|
|
2482
|
+
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2483
|
+
const isLast = operationCount === totalOperations;
|
|
2484
|
+
lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
|
|
2485
|
+
if (!isLast) lines.push("");
|
|
2415
2486
|
}
|
|
2487
|
+
for (const field of modification.fieldsToRemove) {
|
|
2488
|
+
operationCount++;
|
|
2489
|
+
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2490
|
+
const isLast = operationCount === totalOperations;
|
|
2491
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2492
|
+
if (!isLast) lines.push("");
|
|
2493
|
+
}
|
|
2494
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2495
|
+
operationCount++;
|
|
2496
|
+
const index = modification.indexesToAdd[i];
|
|
2497
|
+
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2498
|
+
const isLast = operationCount === totalOperations;
|
|
2499
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2500
|
+
if (!isLast) lines.push("");
|
|
2501
|
+
}
|
|
2502
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2503
|
+
operationCount++;
|
|
2504
|
+
const index = modification.indexesToRemove[i];
|
|
2505
|
+
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2506
|
+
const isLast = operationCount === totalOperations;
|
|
2507
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2508
|
+
if (!isLast) lines.push("");
|
|
2509
|
+
}
|
|
2510
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2511
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2512
|
+
operationCount++;
|
|
2513
|
+
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2514
|
+
const isLast = operationCount === totalOperations;
|
|
2515
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast));
|
|
2516
|
+
if (!isLast) lines.push("");
|
|
2517
|
+
}
|
|
2518
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2519
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2520
|
+
operationCount++;
|
|
2521
|
+
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2522
|
+
const isLast = operationCount === totalOperations;
|
|
2523
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast));
|
|
2524
|
+
if (!isLast) lines.push("");
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
} else if (operation.type === "delete") {
|
|
2528
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection.name;
|
|
2529
|
+
const varName = `collection_${collectionName}`;
|
|
2530
|
+
lines.push(generateCollectionDeletion(collectionName, varName, true));
|
|
2416
2531
|
}
|
|
2417
|
-
return
|
|
2532
|
+
return lines.join("\n");
|
|
2418
2533
|
}
|
|
2419
|
-
function
|
|
2534
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
2420
2535
|
const lines = [];
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
lines.push(
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2536
|
+
if (operation.type === "create") {
|
|
2537
|
+
const collection = operation.collection;
|
|
2538
|
+
const varName = `collection_${collection.name}`;
|
|
2539
|
+
lines.push(generateCollectionDeletion(collection.name, varName, true));
|
|
2540
|
+
} else if (operation.type === "modify") {
|
|
2541
|
+
const modification = operation.modifications;
|
|
2542
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2543
|
+
let operationCount = 0;
|
|
2544
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2545
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2546
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2547
|
+
operationCount++;
|
|
2548
|
+
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2549
|
+
const isLast = operationCount === totalOperations;
|
|
2550
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast));
|
|
2551
|
+
if (!isLast) lines.push("");
|
|
2552
|
+
}
|
|
2553
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2554
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2555
|
+
operationCount++;
|
|
2556
|
+
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2557
|
+
const isLast = operationCount === totalOperations;
|
|
2558
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast));
|
|
2559
|
+
if (!isLast) lines.push("");
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2563
|
+
operationCount++;
|
|
2564
|
+
const index = modification.indexesToRemove[i];
|
|
2565
|
+
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2566
|
+
const isLast = operationCount === totalOperations;
|
|
2567
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2568
|
+
if (!isLast) lines.push("");
|
|
2569
|
+
}
|
|
2570
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2571
|
+
operationCount++;
|
|
2572
|
+
const index = modification.indexesToAdd[i];
|
|
2573
|
+
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2574
|
+
const isLast = operationCount === totalOperations;
|
|
2575
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2576
|
+
if (!isLast) lines.push("");
|
|
2430
2577
|
}
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
if (
|
|
2437
|
-
lines.push(` // Revert permissions for ${collectionName}`);
|
|
2438
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2439
|
-
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2440
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName));
|
|
2441
|
-
lines.push(``);
|
|
2442
|
-
}
|
|
2443
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2444
|
-
lines.push(` // Revert rules for ${collectionName}`);
|
|
2445
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2446
|
-
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2447
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName));
|
|
2448
|
-
lines.push(``);
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2452
|
-
lines.push(` // Restore indexes to ${collectionName}`);
|
|
2453
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2454
|
-
const index = modification.indexesToRemove[i];
|
|
2455
|
-
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2456
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2457
|
-
lines.push(``);
|
|
2458
|
-
}
|
|
2459
|
-
}
|
|
2460
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2461
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2462
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2463
|
-
const index = modification.indexesToAdd[i];
|
|
2464
|
-
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2465
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2466
|
-
lines.push(``);
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2470
|
-
lines.push(` // Restore fields to ${collectionName}`);
|
|
2471
|
-
for (const field of modification.fieldsToRemove) {
|
|
2472
|
-
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2473
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2474
|
-
lines.push(``);
|
|
2475
|
-
}
|
|
2476
|
-
}
|
|
2477
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2478
|
-
lines.push(` // Revert field modifications in ${collectionName}`);
|
|
2479
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2480
|
-
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2481
|
-
property: change.property,
|
|
2482
|
-
oldValue: change.newValue,
|
|
2483
|
-
newValue: change.oldValue
|
|
2484
|
-
}));
|
|
2485
|
-
const reverseMod = {
|
|
2486
|
-
fieldName: fieldMod.fieldName,
|
|
2487
|
-
currentDefinition: fieldMod.newDefinition,
|
|
2488
|
-
newDefinition: fieldMod.currentDefinition,
|
|
2489
|
-
changes: reverseChanges
|
|
2490
|
-
};
|
|
2491
|
-
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2492
|
-
lines.push(generateFieldModification(collectionName, reverseMod, varName));
|
|
2493
|
-
lines.push(``);
|
|
2494
|
-
}
|
|
2495
|
-
}
|
|
2496
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2497
|
-
lines.push(` // Remove added fields from ${collectionName}`);
|
|
2498
|
-
for (const field of modification.fieldsToAdd) {
|
|
2499
|
-
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2500
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2501
|
-
lines.push(``);
|
|
2502
|
-
}
|
|
2503
|
-
}
|
|
2578
|
+
for (const field of modification.fieldsToRemove) {
|
|
2579
|
+
operationCount++;
|
|
2580
|
+
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2581
|
+
const isLast = operationCount === totalOperations;
|
|
2582
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2583
|
+
if (!isLast) lines.push("");
|
|
2504
2584
|
}
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2585
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2586
|
+
operationCount++;
|
|
2587
|
+
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2588
|
+
property: change.property,
|
|
2589
|
+
oldValue: change.newValue,
|
|
2590
|
+
newValue: change.oldValue
|
|
2591
|
+
}));
|
|
2592
|
+
const reverseMod = {
|
|
2593
|
+
fieldName: fieldMod.fieldName,
|
|
2594
|
+
currentDefinition: fieldMod.newDefinition,
|
|
2595
|
+
newDefinition: fieldMod.currentDefinition,
|
|
2596
|
+
changes: reverseChanges
|
|
2597
|
+
};
|
|
2598
|
+
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2599
|
+
const isLast = operationCount === totalOperations;
|
|
2600
|
+
lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast));
|
|
2601
|
+
if (!isLast) lines.push("");
|
|
2602
|
+
}
|
|
2603
|
+
for (const field of modification.fieldsToAdd) {
|
|
2604
|
+
operationCount++;
|
|
2605
|
+
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2606
|
+
const isLast = operationCount === totalOperations;
|
|
2607
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2608
|
+
if (!isLast) lines.push("");
|
|
2609
|
+
}
|
|
2610
|
+
} else if (operation.type === "delete") {
|
|
2611
|
+
const collection = operation.collection;
|
|
2612
|
+
if (typeof collection !== "string") {
|
|
2613
|
+
const varName = `collection_${collection.name}`;
|
|
2614
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2534
2615
|
}
|
|
2535
2616
|
}
|
|
2536
|
-
return
|
|
2617
|
+
return lines.join("\n");
|
|
2537
2618
|
}
|
|
2538
2619
|
function generate(diff, config) {
|
|
2539
2620
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
2540
2621
|
try {
|
|
2541
2622
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
2542
|
-
const
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
const
|
|
2547
|
-
|
|
2623
|
+
const hasChanges4 = diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;
|
|
2624
|
+
if (!hasChanges4) {
|
|
2625
|
+
return [];
|
|
2626
|
+
}
|
|
2627
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
2628
|
+
for (const collection of diff.collectionsToCreate) {
|
|
2629
|
+
if (collection.id) {
|
|
2630
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
for (const collection of diff.collectionsToDelete) {
|
|
2634
|
+
if (collection.id) {
|
|
2635
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
const baseTimestamp = generateTimestamp(normalizedConfig);
|
|
2639
|
+
const operations = splitDiffByCollection(diff, baseTimestamp);
|
|
2640
|
+
const filePaths = [];
|
|
2641
|
+
for (const operation of operations) {
|
|
2642
|
+
const upCode = generateOperationUpMigration(operation, collectionIdMap);
|
|
2643
|
+
const downCode = generateOperationDownMigration(operation, collectionIdMap);
|
|
2644
|
+
const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);
|
|
2645
|
+
const filename = generateCollectionMigrationFilename(operation);
|
|
2646
|
+
const filePath = writeMigrationFile(migrationDir, filename, content);
|
|
2647
|
+
filePaths.push(filePath);
|
|
2648
|
+
}
|
|
2649
|
+
return filePaths;
|
|
2548
2650
|
} catch (error) {
|
|
2549
2651
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
2550
2652
|
throw error;
|
|
@@ -3625,15 +3727,25 @@ async function executeGenerate(options) {
|
|
|
3625
3727
|
process.exit(1);
|
|
3626
3728
|
}
|
|
3627
3729
|
logSection("\u{1F4DD} Generating Migration");
|
|
3628
|
-
const
|
|
3730
|
+
const migrationPaths = await withProgress(
|
|
3629
3731
|
"Creating migration file...",
|
|
3630
3732
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
3631
3733
|
);
|
|
3632
|
-
|
|
3734
|
+
if (migrationPaths.length === 0) {
|
|
3735
|
+
logWarning("No migration files were generated (no changes detected).");
|
|
3736
|
+
return;
|
|
3737
|
+
}
|
|
3738
|
+
if (migrationPaths.length === 1) {
|
|
3739
|
+
logSuccess(`Migration file created: ${path5__namespace.basename(migrationPaths[0])}`);
|
|
3740
|
+
} else {
|
|
3741
|
+
logSuccess(`Created ${migrationPaths.length} migration files`);
|
|
3742
|
+
}
|
|
3633
3743
|
logSection("\u2705 Next Steps");
|
|
3634
3744
|
console.log();
|
|
3635
|
-
console.log(" 1. Review the generated migration file:");
|
|
3636
|
-
|
|
3745
|
+
console.log(" 1. Review the generated migration file(s):");
|
|
3746
|
+
migrationPaths.forEach((migrationPath) => {
|
|
3747
|
+
console.log(` ${migrationPath}`);
|
|
3748
|
+
});
|
|
3637
3749
|
console.log();
|
|
3638
3750
|
console.log(" 2. Apply the migration by running PocketBase:");
|
|
3639
3751
|
console.log(" yarn pb");
|