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.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as path5 from 'path';
|
|
2
2
|
import * as fs5 from 'fs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { randomBytes } from 'crypto';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
import ora from 'ora';
|
|
6
7
|
|
|
@@ -36,6 +37,18 @@ function extractRelationMetadata(description) {
|
|
|
36
37
|
}
|
|
37
38
|
return null;
|
|
38
39
|
}
|
|
40
|
+
var FIELD_METADATA_KEY = "__pocketbase_field__";
|
|
41
|
+
function extractFieldMetadata(description) {
|
|
42
|
+
if (!description) return null;
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(description);
|
|
45
|
+
if (parsed[FIELD_METADATA_KEY]) {
|
|
46
|
+
return parsed[FIELD_METADATA_KEY];
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
39
52
|
|
|
40
53
|
// src/migration/errors.ts
|
|
41
54
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -1274,6 +1287,38 @@ function isAuthCollection(fields) {
|
|
|
1274
1287
|
return hasEmail && hasPassword;
|
|
1275
1288
|
}
|
|
1276
1289
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1290
|
+
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1291
|
+
if (fieldMetadata) {
|
|
1292
|
+
let required2;
|
|
1293
|
+
if (fieldMetadata.type === "number") {
|
|
1294
|
+
if (fieldMetadata.options?.required !== void 0) {
|
|
1295
|
+
required2 = fieldMetadata.options.required;
|
|
1296
|
+
} else {
|
|
1297
|
+
required2 = false;
|
|
1298
|
+
}
|
|
1299
|
+
} else {
|
|
1300
|
+
required2 = isFieldRequired(zodType);
|
|
1301
|
+
}
|
|
1302
|
+
const { required: _required, ...options2 } = fieldMetadata.options || {};
|
|
1303
|
+
const fieldDef2 = {
|
|
1304
|
+
name: fieldName,
|
|
1305
|
+
type: fieldMetadata.type,
|
|
1306
|
+
required: required2,
|
|
1307
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1308
|
+
};
|
|
1309
|
+
if (fieldMetadata.type === "relation") {
|
|
1310
|
+
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
1311
|
+
if (relationMetadata2) {
|
|
1312
|
+
fieldDef2.relation = {
|
|
1313
|
+
collection: relationMetadata2.collection,
|
|
1314
|
+
maxSelect: relationMetadata2.maxSelect,
|
|
1315
|
+
minSelect: relationMetadata2.minSelect,
|
|
1316
|
+
cascadeDelete: relationMetadata2.cascadeDelete
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
return fieldDef2;
|
|
1321
|
+
}
|
|
1277
1322
|
const fieldType = mapZodTypeToPocketBase(zodType, fieldName);
|
|
1278
1323
|
const required = isFieldRequired(zodType);
|
|
1279
1324
|
const options = extractFieldOptions(zodType);
|
|
@@ -1429,6 +1474,65 @@ async function buildSchemaDefinition(config) {
|
|
|
1429
1474
|
async function parseSchemaFiles(config) {
|
|
1430
1475
|
return buildSchemaDefinition(config);
|
|
1431
1476
|
}
|
|
1477
|
+
function generateCollectionId() {
|
|
1478
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1479
|
+
const idLength = 15;
|
|
1480
|
+
const bytes = randomBytes(idLength);
|
|
1481
|
+
let id = "pb_";
|
|
1482
|
+
for (let i = 0; i < idLength; i++) {
|
|
1483
|
+
const index = bytes[i] % chars.length;
|
|
1484
|
+
id += chars[index];
|
|
1485
|
+
}
|
|
1486
|
+
return id;
|
|
1487
|
+
}
|
|
1488
|
+
var CollectionIdRegistry = class {
|
|
1489
|
+
ids;
|
|
1490
|
+
constructor() {
|
|
1491
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Generates a unique collection ID for a given collection name
|
|
1495
|
+
* Special case: Returns constant "_pb_users_auth_" for users collection
|
|
1496
|
+
* Retries up to 10 times if collision occurs (extremely rare)
|
|
1497
|
+
*
|
|
1498
|
+
* @param collectionName - The name of the collection
|
|
1499
|
+
* @returns A unique collection ID
|
|
1500
|
+
* @throws Error if unable to generate unique ID after max attempts
|
|
1501
|
+
*/
|
|
1502
|
+
generate(collectionName) {
|
|
1503
|
+
if (collectionName && collectionName.toLowerCase() === "users") {
|
|
1504
|
+
const usersId = "_pb_users_auth_";
|
|
1505
|
+
this.register(usersId);
|
|
1506
|
+
return usersId;
|
|
1507
|
+
}
|
|
1508
|
+
const maxAttempts = 10;
|
|
1509
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1510
|
+
const id = generateCollectionId();
|
|
1511
|
+
if (!this.has(id)) {
|
|
1512
|
+
this.register(id);
|
|
1513
|
+
return id;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
throw new Error("Failed to generate unique collection ID after maximum attempts");
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* Checks if an ID has already been registered
|
|
1520
|
+
*
|
|
1521
|
+
* @param id - The collection ID to check
|
|
1522
|
+
* @returns True if the ID exists in the registry
|
|
1523
|
+
*/
|
|
1524
|
+
has(id) {
|
|
1525
|
+
return this.ids.has(id);
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Registers a collection ID in the registry
|
|
1529
|
+
*
|
|
1530
|
+
* @param id - The collection ID to register
|
|
1531
|
+
*/
|
|
1532
|
+
register(id) {
|
|
1533
|
+
this.ids.add(id);
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1432
1536
|
|
|
1433
1537
|
// src/migration/diff.ts
|
|
1434
1538
|
var DEFAULT_CONFIG2 = {
|
|
@@ -1760,6 +1864,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1760
1864
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
1761
1865
|
(collection) => !isSystemCollection(collection.name, config)
|
|
1762
1866
|
);
|
|
1867
|
+
const registry = new CollectionIdRegistry();
|
|
1868
|
+
const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {
|
|
1869
|
+
if (collection.id) {
|
|
1870
|
+
registry.register(collection.id);
|
|
1871
|
+
return collection;
|
|
1872
|
+
}
|
|
1873
|
+
const id = registry.generate(collection.name);
|
|
1874
|
+
return {
|
|
1875
|
+
...collection,
|
|
1876
|
+
id
|
|
1877
|
+
};
|
|
1878
|
+
});
|
|
1763
1879
|
const collectionsToModify = [];
|
|
1764
1880
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
1765
1881
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -1769,7 +1885,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1769
1885
|
}
|
|
1770
1886
|
}
|
|
1771
1887
|
return {
|
|
1772
|
-
collectionsToCreate:
|
|
1888
|
+
collectionsToCreate: collectionsWithIds,
|
|
1773
1889
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
1774
1890
|
collectionsToModify
|
|
1775
1891
|
};
|
|
@@ -1852,42 +1968,48 @@ function generateTimestamp(config) {
|
|
|
1852
1968
|
}
|
|
1853
1969
|
return Math.floor(Date.now() / 1e3).toString();
|
|
1854
1970
|
}
|
|
1855
|
-
function
|
|
1856
|
-
const
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
if (diff.collectionsToDelete.length === 1) {
|
|
1866
|
-
parts.push(`deleted_${diff.collectionsToDelete[0].name}`);
|
|
1867
|
-
} else {
|
|
1868
|
-
parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
if (diff.collectionsToModify.length > 0) {
|
|
1872
|
-
if (diff.collectionsToModify.length === 1) {
|
|
1873
|
-
parts.push(`updated_${diff.collectionsToModify[0].collection}`);
|
|
1874
|
-
} else {
|
|
1875
|
-
parts.push(`updated_${diff.collectionsToModify.length}_collections`);
|
|
1876
|
-
}
|
|
1971
|
+
function splitDiffByCollection(diff, baseTimestamp) {
|
|
1972
|
+
const operations = [];
|
|
1973
|
+
let currentTimestamp = parseInt(baseTimestamp, 10);
|
|
1974
|
+
for (const collection of diff.collectionsToCreate) {
|
|
1975
|
+
operations.push({
|
|
1976
|
+
type: "create",
|
|
1977
|
+
collection,
|
|
1978
|
+
timestamp: currentTimestamp.toString()
|
|
1979
|
+
});
|
|
1980
|
+
currentTimestamp += 1;
|
|
1877
1981
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1982
|
+
for (const modification of diff.collectionsToModify) {
|
|
1983
|
+
operations.push({
|
|
1984
|
+
type: "modify",
|
|
1985
|
+
collection: modification.collection,
|
|
1986
|
+
modifications: modification,
|
|
1987
|
+
timestamp: currentTimestamp.toString()
|
|
1988
|
+
});
|
|
1989
|
+
currentTimestamp += 1;
|
|
1880
1990
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1991
|
+
for (const collection of diff.collectionsToDelete) {
|
|
1992
|
+
operations.push({
|
|
1993
|
+
type: "delete",
|
|
1994
|
+
collection: collection.name || collection,
|
|
1995
|
+
// Handle both object and string
|
|
1996
|
+
timestamp: currentTimestamp.toString()
|
|
1997
|
+
});
|
|
1998
|
+
currentTimestamp += 1;
|
|
1884
1999
|
}
|
|
1885
|
-
return
|
|
2000
|
+
return operations;
|
|
1886
2001
|
}
|
|
1887
|
-
function
|
|
1888
|
-
const timestamp =
|
|
1889
|
-
const
|
|
1890
|
-
|
|
2002
|
+
function generateCollectionMigrationFilename(operation) {
|
|
2003
|
+
const timestamp = operation.timestamp;
|
|
2004
|
+
const operationType = operation.type === "modify" ? "updated" : operation.type === "create" ? "created" : "deleted";
|
|
2005
|
+
let collectionName;
|
|
2006
|
+
if (typeof operation.collection === "string") {
|
|
2007
|
+
collectionName = operation.collection;
|
|
2008
|
+
} else {
|
|
2009
|
+
collectionName = operation.collection.name;
|
|
2010
|
+
}
|
|
2011
|
+
const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
2012
|
+
return `${timestamp}_${operationType}_${sanitizedName}.js`;
|
|
1891
2013
|
}
|
|
1892
2014
|
function createMigrationFileStructure(upCode, downCode, config) {
|
|
1893
2015
|
const mergedConfig = config ? mergeConfig3(config) : DEFAULT_CONFIG3;
|
|
@@ -1959,14 +2081,13 @@ function formatValue(value) {
|
|
|
1959
2081
|
return "null";
|
|
1960
2082
|
}
|
|
1961
2083
|
if (typeof value === "string") {
|
|
1962
|
-
return
|
|
2084
|
+
return JSON.stringify(value);
|
|
1963
2085
|
}
|
|
1964
2086
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
1965
2087
|
return String(value);
|
|
1966
2088
|
}
|
|
1967
2089
|
if (Array.isArray(value)) {
|
|
1968
|
-
|
|
1969
|
-
return `[${items}]`;
|
|
2090
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
1970
2091
|
}
|
|
1971
2092
|
if (typeof value === "object") {
|
|
1972
2093
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -1974,7 +2095,7 @@ function formatValue(value) {
|
|
|
1974
2095
|
}
|
|
1975
2096
|
return String(value);
|
|
1976
2097
|
}
|
|
1977
|
-
function generateFieldDefinitionObject(field) {
|
|
2098
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
1978
2099
|
const parts = [];
|
|
1979
2100
|
parts.push(` name: "${field.name}"`);
|
|
1980
2101
|
parts.push(` type: "${field.type}"`);
|
|
@@ -1982,34 +2103,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
1982
2103
|
if (field.unique !== void 0) {
|
|
1983
2104
|
parts.push(` unique: ${field.unique}`);
|
|
1984
2105
|
}
|
|
2106
|
+
if (field.type === "select") {
|
|
2107
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2108
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2109
|
+
const values = field.options?.values ?? [];
|
|
2110
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2111
|
+
}
|
|
1985
2112
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
1986
2113
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2114
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2115
|
+
continue;
|
|
2116
|
+
}
|
|
1987
2117
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
1988
2118
|
}
|
|
1989
2119
|
}
|
|
1990
2120
|
if (field.relation) {
|
|
1991
2121
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
}
|
|
2000
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2001
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2122
|
+
let collectionIdValue;
|
|
2123
|
+
if (isUsersCollection) {
|
|
2124
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2125
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2126
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2127
|
+
} else {
|
|
2128
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2002
2129
|
}
|
|
2130
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2131
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2132
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2133
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2134
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2135
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2136
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2003
2137
|
}
|
|
2004
2138
|
return ` {
|
|
2005
2139
|
${parts.join(",\n")},
|
|
2006
2140
|
}`;
|
|
2007
2141
|
}
|
|
2008
|
-
function generateFieldsArray(fields) {
|
|
2142
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
2009
2143
|
if (fields.length === 0) {
|
|
2010
2144
|
return "[]";
|
|
2011
2145
|
}
|
|
2012
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
2146
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
2013
2147
|
return `[
|
|
2014
2148
|
${fieldObjects.join(",\n")},
|
|
2015
2149
|
]`;
|
|
@@ -2068,7 +2202,7 @@ function generateIndexesArray(indexes) {
|
|
|
2068
2202
|
if (!indexes || indexes.length === 0) {
|
|
2069
2203
|
return "[]";
|
|
2070
2204
|
}
|
|
2071
|
-
const indexStrings = indexes.map((idx) =>
|
|
2205
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
2072
2206
|
return `[
|
|
2073
2207
|
${indexStrings.join(",\n ")},
|
|
2074
2208
|
]`;
|
|
@@ -2122,7 +2256,7 @@ function getSystemFields() {
|
|
|
2122
2256
|
}
|
|
2123
2257
|
];
|
|
2124
2258
|
}
|
|
2125
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2259
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
2126
2260
|
const lines = [];
|
|
2127
2261
|
lines.push(` const ${varName} = new Collection({`);
|
|
2128
2262
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2136,7 +2270,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
2136
2270
|
}
|
|
2137
2271
|
const systemFields = getSystemFields();
|
|
2138
2272
|
const allFields = [...systemFields, ...collection.fields];
|
|
2139
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
2273
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
2140
2274
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2141
2275
|
lines.push(` });`);
|
|
2142
2276
|
lines.push(``);
|
|
@@ -2158,42 +2292,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
2158
2292
|
};
|
|
2159
2293
|
return constructorMap[fieldType] || "TextField";
|
|
2160
2294
|
}
|
|
2161
|
-
function generateFieldConstructorOptions(field) {
|
|
2295
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
2162
2296
|
const parts = [];
|
|
2163
2297
|
parts.push(` name: "${field.name}"`);
|
|
2164
2298
|
parts.push(` required: ${field.required}`);
|
|
2165
2299
|
if (field.unique !== void 0) {
|
|
2166
2300
|
parts.push(` unique: ${field.unique}`);
|
|
2167
2301
|
}
|
|
2302
|
+
if (field.type === "select") {
|
|
2303
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2304
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2305
|
+
const values = field.options?.values ?? [];
|
|
2306
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2307
|
+
}
|
|
2168
2308
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2169
2309
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2170
|
-
|
|
2310
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2311
|
+
continue;
|
|
2312
|
+
}
|
|
2313
|
+
if (field.type === "number" && key === "noDecimal") {
|
|
2314
|
+
parts.push(` onlyInt: ${formatValue(value)}`);
|
|
2315
|
+
} else {
|
|
2316
|
+
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2317
|
+
}
|
|
2171
2318
|
}
|
|
2172
2319
|
}
|
|
2173
2320
|
if (field.relation && field.type === "relation") {
|
|
2174
2321
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
}
|
|
2183
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2184
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2322
|
+
let collectionIdValue;
|
|
2323
|
+
if (isUsersCollection) {
|
|
2324
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2325
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2326
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2327
|
+
} else {
|
|
2328
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2185
2329
|
}
|
|
2330
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2331
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2332
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2333
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2334
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2335
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2336
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2186
2337
|
}
|
|
2187
2338
|
return parts.join(",\n");
|
|
2188
2339
|
}
|
|
2189
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2340
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
2190
2341
|
const lines = [];
|
|
2191
2342
|
const constructorName = getFieldConstructorName(field.type);
|
|
2192
2343
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
2193
2344
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2194
2345
|
lines.push(``);
|
|
2195
2346
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
2196
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
2347
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
2197
2348
|
lines.push(` }));`);
|
|
2198
2349
|
lines.push(``);
|
|
2199
2350
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -2243,7 +2394,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
2243
2394
|
const lines = [];
|
|
2244
2395
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2245
2396
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2246
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
2397
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
2247
2398
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2248
2399
|
return lines.join("\n");
|
|
2249
2400
|
}
|
|
@@ -2252,7 +2403,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
2252
2403
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2253
2404
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
2254
2405
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2255
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
2406
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
2256
2407
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2257
2408
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2258
2409
|
lines.push(` }`);
|
|
@@ -2281,243 +2432,194 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
2281
2432
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
2282
2433
|
return lines.join("\n");
|
|
2283
2434
|
}
|
|
2284
|
-
function
|
|
2435
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
2285
2436
|
const lines = [];
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
lines.push(
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2302
|
-
lines.push(` // Add fields to ${collectionName}`);
|
|
2303
|
-
for (const field of modification.fieldsToAdd) {
|
|
2304
|
-
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2305
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2306
|
-
lines.push(``);
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2310
|
-
lines.push(` // Modify fields in ${collectionName}`);
|
|
2311
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2312
|
-
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2313
|
-
lines.push(generateFieldModification(collectionName, fieldMod, varName));
|
|
2314
|
-
lines.push(``);
|
|
2315
|
-
}
|
|
2316
|
-
}
|
|
2317
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2318
|
-
lines.push(` // Remove fields from ${collectionName}`);
|
|
2319
|
-
for (const field of modification.fieldsToRemove) {
|
|
2320
|
-
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2321
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2322
|
-
lines.push(``);
|
|
2323
|
-
}
|
|
2324
|
-
}
|
|
2325
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2326
|
-
lines.push(` // Add indexes to ${collectionName}`);
|
|
2327
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2328
|
-
const index = modification.indexesToAdd[i];
|
|
2329
|
-
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2330
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2331
|
-
lines.push(``);
|
|
2332
|
-
}
|
|
2333
|
-
}
|
|
2334
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2335
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2336
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2337
|
-
const index = modification.indexesToRemove[i];
|
|
2338
|
-
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2339
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2340
|
-
lines.push(``);
|
|
2341
|
-
}
|
|
2342
|
-
}
|
|
2343
|
-
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2344
|
-
lines.push(` // Update permissions for ${collectionName}`);
|
|
2345
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2346
|
-
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2347
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName));
|
|
2348
|
-
lines.push(``);
|
|
2349
|
-
}
|
|
2350
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2351
|
-
lines.push(` // Update rules for ${collectionName}`);
|
|
2352
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2353
|
-
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2354
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName));
|
|
2355
|
-
lines.push(``);
|
|
2356
|
-
}
|
|
2357
|
-
}
|
|
2437
|
+
if (operation.type === "create") {
|
|
2438
|
+
const collection = operation.collection;
|
|
2439
|
+
const varName = `collection_${collection.name}`;
|
|
2440
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2441
|
+
} else if (operation.type === "modify") {
|
|
2442
|
+
const modification = operation.modifications;
|
|
2443
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2444
|
+
let operationCount = 0;
|
|
2445
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2446
|
+
for (const field of modification.fieldsToAdd) {
|
|
2447
|
+
operationCount++;
|
|
2448
|
+
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2449
|
+
const isLast = operationCount === totalOperations;
|
|
2450
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2451
|
+
if (!isLast) lines.push("");
|
|
2358
2452
|
}
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
lines.push(generateCollectionDeletion(collection.name, varName));
|
|
2366
|
-
lines.push(``);
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
if (lines.length === 2) {
|
|
2370
|
-
lines.push(` // No changes detected`);
|
|
2371
|
-
lines.push(``);
|
|
2372
|
-
}
|
|
2373
|
-
let code = lines.join("\n");
|
|
2374
|
-
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2375
|
-
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2376
|
-
const saveMatches = [...code.matchAll(savePattern)];
|
|
2377
|
-
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2378
|
-
const allMatches = [
|
|
2379
|
-
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2380
|
-
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2381
|
-
].sort((a, b) => b.index - a.index);
|
|
2382
|
-
if (allMatches.length > 0) {
|
|
2383
|
-
const lastMatch = allMatches[0];
|
|
2384
|
-
if (lastMatch.type === "save") {
|
|
2385
|
-
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);
|
|
2386
|
-
} else {
|
|
2387
|
-
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);
|
|
2453
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2454
|
+
operationCount++;
|
|
2455
|
+
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2456
|
+
const isLast = operationCount === totalOperations;
|
|
2457
|
+
lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
|
|
2458
|
+
if (!isLast) lines.push("");
|
|
2388
2459
|
}
|
|
2460
|
+
for (const field of modification.fieldsToRemove) {
|
|
2461
|
+
operationCount++;
|
|
2462
|
+
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2463
|
+
const isLast = operationCount === totalOperations;
|
|
2464
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2465
|
+
if (!isLast) lines.push("");
|
|
2466
|
+
}
|
|
2467
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2468
|
+
operationCount++;
|
|
2469
|
+
const index = modification.indexesToAdd[i];
|
|
2470
|
+
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2471
|
+
const isLast = operationCount === totalOperations;
|
|
2472
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2473
|
+
if (!isLast) lines.push("");
|
|
2474
|
+
}
|
|
2475
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2476
|
+
operationCount++;
|
|
2477
|
+
const index = modification.indexesToRemove[i];
|
|
2478
|
+
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2479
|
+
const isLast = operationCount === totalOperations;
|
|
2480
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2481
|
+
if (!isLast) lines.push("");
|
|
2482
|
+
}
|
|
2483
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2484
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2485
|
+
operationCount++;
|
|
2486
|
+
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2487
|
+
const isLast = operationCount === totalOperations;
|
|
2488
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast));
|
|
2489
|
+
if (!isLast) lines.push("");
|
|
2490
|
+
}
|
|
2491
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2492
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2493
|
+
operationCount++;
|
|
2494
|
+
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2495
|
+
const isLast = operationCount === totalOperations;
|
|
2496
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast));
|
|
2497
|
+
if (!isLast) lines.push("");
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
} else if (operation.type === "delete") {
|
|
2501
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection.name;
|
|
2502
|
+
const varName = `collection_${collectionName}`;
|
|
2503
|
+
lines.push(generateCollectionDeletion(collectionName, varName, true));
|
|
2389
2504
|
}
|
|
2390
|
-
return
|
|
2505
|
+
return lines.join("\n");
|
|
2391
2506
|
}
|
|
2392
|
-
function
|
|
2507
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
2393
2508
|
const lines = [];
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
lines.push(
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2509
|
+
if (operation.type === "create") {
|
|
2510
|
+
const collection = operation.collection;
|
|
2511
|
+
const varName = `collection_${collection.name}`;
|
|
2512
|
+
lines.push(generateCollectionDeletion(collection.name, varName, true));
|
|
2513
|
+
} else if (operation.type === "modify") {
|
|
2514
|
+
const modification = operation.modifications;
|
|
2515
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2516
|
+
let operationCount = 0;
|
|
2517
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2518
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2519
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2520
|
+
operationCount++;
|
|
2521
|
+
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2522
|
+
const isLast = operationCount === totalOperations;
|
|
2523
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast));
|
|
2524
|
+
if (!isLast) lines.push("");
|
|
2525
|
+
}
|
|
2526
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2527
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2528
|
+
operationCount++;
|
|
2529
|
+
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2530
|
+
const isLast = operationCount === totalOperations;
|
|
2531
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast));
|
|
2532
|
+
if (!isLast) lines.push("");
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2536
|
+
operationCount++;
|
|
2537
|
+
const index = modification.indexesToRemove[i];
|
|
2538
|
+
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2539
|
+
const isLast = operationCount === totalOperations;
|
|
2540
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2541
|
+
if (!isLast) lines.push("");
|
|
2542
|
+
}
|
|
2543
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2544
|
+
operationCount++;
|
|
2545
|
+
const index = modification.indexesToAdd[i];
|
|
2546
|
+
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2547
|
+
const isLast = operationCount === totalOperations;
|
|
2548
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2549
|
+
if (!isLast) lines.push("");
|
|
2403
2550
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
if (
|
|
2410
|
-
lines.push(` // Revert permissions for ${collectionName}`);
|
|
2411
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2412
|
-
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2413
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName));
|
|
2414
|
-
lines.push(``);
|
|
2415
|
-
}
|
|
2416
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2417
|
-
lines.push(` // Revert rules for ${collectionName}`);
|
|
2418
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2419
|
-
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2420
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName));
|
|
2421
|
-
lines.push(``);
|
|
2422
|
-
}
|
|
2423
|
-
}
|
|
2424
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2425
|
-
lines.push(` // Restore indexes to ${collectionName}`);
|
|
2426
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2427
|
-
const index = modification.indexesToRemove[i];
|
|
2428
|
-
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2429
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2430
|
-
lines.push(``);
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2433
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2434
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2435
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2436
|
-
const index = modification.indexesToAdd[i];
|
|
2437
|
-
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2438
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2439
|
-
lines.push(``);
|
|
2440
|
-
}
|
|
2441
|
-
}
|
|
2442
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2443
|
-
lines.push(` // Restore fields to ${collectionName}`);
|
|
2444
|
-
for (const field of modification.fieldsToRemove) {
|
|
2445
|
-
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2446
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2447
|
-
lines.push(``);
|
|
2448
|
-
}
|
|
2449
|
-
}
|
|
2450
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2451
|
-
lines.push(` // Revert field modifications in ${collectionName}`);
|
|
2452
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2453
|
-
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2454
|
-
property: change.property,
|
|
2455
|
-
oldValue: change.newValue,
|
|
2456
|
-
newValue: change.oldValue
|
|
2457
|
-
}));
|
|
2458
|
-
const reverseMod = {
|
|
2459
|
-
fieldName: fieldMod.fieldName,
|
|
2460
|
-
currentDefinition: fieldMod.newDefinition,
|
|
2461
|
-
newDefinition: fieldMod.currentDefinition,
|
|
2462
|
-
changes: reverseChanges
|
|
2463
|
-
};
|
|
2464
|
-
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2465
|
-
lines.push(generateFieldModification(collectionName, reverseMod, varName));
|
|
2466
|
-
lines.push(``);
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2470
|
-
lines.push(` // Remove added fields from ${collectionName}`);
|
|
2471
|
-
for (const field of modification.fieldsToAdd) {
|
|
2472
|
-
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2473
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2474
|
-
lines.push(``);
|
|
2475
|
-
}
|
|
2476
|
-
}
|
|
2551
|
+
for (const field of modification.fieldsToRemove) {
|
|
2552
|
+
operationCount++;
|
|
2553
|
+
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2554
|
+
const isLast = operationCount === totalOperations;
|
|
2555
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2556
|
+
if (!isLast) lines.push("");
|
|
2477
2557
|
}
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2558
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2559
|
+
operationCount++;
|
|
2560
|
+
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2561
|
+
property: change.property,
|
|
2562
|
+
oldValue: change.newValue,
|
|
2563
|
+
newValue: change.oldValue
|
|
2564
|
+
}));
|
|
2565
|
+
const reverseMod = {
|
|
2566
|
+
fieldName: fieldMod.fieldName,
|
|
2567
|
+
currentDefinition: fieldMod.newDefinition,
|
|
2568
|
+
newDefinition: fieldMod.currentDefinition,
|
|
2569
|
+
changes: reverseChanges
|
|
2570
|
+
};
|
|
2571
|
+
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2572
|
+
const isLast = operationCount === totalOperations;
|
|
2573
|
+
lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast));
|
|
2574
|
+
if (!isLast) lines.push("");
|
|
2575
|
+
}
|
|
2576
|
+
for (const field of modification.fieldsToAdd) {
|
|
2577
|
+
operationCount++;
|
|
2578
|
+
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2579
|
+
const isLast = operationCount === totalOperations;
|
|
2580
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2581
|
+
if (!isLast) lines.push("");
|
|
2582
|
+
}
|
|
2583
|
+
} else if (operation.type === "delete") {
|
|
2584
|
+
const collection = operation.collection;
|
|
2585
|
+
if (typeof collection !== "string") {
|
|
2586
|
+
const varName = `collection_${collection.name}`;
|
|
2587
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2507
2588
|
}
|
|
2508
2589
|
}
|
|
2509
|
-
return
|
|
2590
|
+
return lines.join("\n");
|
|
2510
2591
|
}
|
|
2511
2592
|
function generate(diff, config) {
|
|
2512
2593
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
2513
2594
|
try {
|
|
2514
2595
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
2515
|
-
const
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
const
|
|
2520
|
-
|
|
2596
|
+
const hasChanges4 = diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;
|
|
2597
|
+
if (!hasChanges4) {
|
|
2598
|
+
return [];
|
|
2599
|
+
}
|
|
2600
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
2601
|
+
for (const collection of diff.collectionsToCreate) {
|
|
2602
|
+
if (collection.id) {
|
|
2603
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
for (const collection of diff.collectionsToDelete) {
|
|
2607
|
+
if (collection.id) {
|
|
2608
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
const baseTimestamp = generateTimestamp(normalizedConfig);
|
|
2612
|
+
const operations = splitDiffByCollection(diff, baseTimestamp);
|
|
2613
|
+
const filePaths = [];
|
|
2614
|
+
for (const operation of operations) {
|
|
2615
|
+
const upCode = generateOperationUpMigration(operation, collectionIdMap);
|
|
2616
|
+
const downCode = generateOperationDownMigration(operation, collectionIdMap);
|
|
2617
|
+
const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);
|
|
2618
|
+
const filename = generateCollectionMigrationFilename(operation);
|
|
2619
|
+
const filePath = writeMigrationFile(migrationDir, filename, content);
|
|
2620
|
+
filePaths.push(filePath);
|
|
2621
|
+
}
|
|
2622
|
+
return filePaths;
|
|
2521
2623
|
} catch (error) {
|
|
2522
2624
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
2523
2625
|
throw error;
|
|
@@ -3598,15 +3700,25 @@ async function executeGenerate(options) {
|
|
|
3598
3700
|
process.exit(1);
|
|
3599
3701
|
}
|
|
3600
3702
|
logSection("\u{1F4DD} Generating Migration");
|
|
3601
|
-
const
|
|
3703
|
+
const migrationPaths = await withProgress(
|
|
3602
3704
|
"Creating migration file...",
|
|
3603
3705
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
3604
3706
|
);
|
|
3605
|
-
|
|
3707
|
+
if (migrationPaths.length === 0) {
|
|
3708
|
+
logWarning("No migration files were generated (no changes detected).");
|
|
3709
|
+
return;
|
|
3710
|
+
}
|
|
3711
|
+
if (migrationPaths.length === 1) {
|
|
3712
|
+
logSuccess(`Migration file created: ${path5.basename(migrationPaths[0])}`);
|
|
3713
|
+
} else {
|
|
3714
|
+
logSuccess(`Created ${migrationPaths.length} migration files`);
|
|
3715
|
+
}
|
|
3606
3716
|
logSection("\u2705 Next Steps");
|
|
3607
3717
|
console.log();
|
|
3608
|
-
console.log(" 1. Review the generated migration file:");
|
|
3609
|
-
|
|
3718
|
+
console.log(" 1. Review the generated migration file(s):");
|
|
3719
|
+
migrationPaths.forEach((migrationPath) => {
|
|
3720
|
+
console.log(` ${migrationPath}`);
|
|
3721
|
+
});
|
|
3610
3722
|
console.log();
|
|
3611
3723
|
console.log(" 2. Apply the migration by running PocketBase:");
|
|
3612
3724
|
console.log(" yarn pb");
|