pocketbase-zod-schema 0.2.5 → 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 +8 -0
- package/dist/cli/index.cjs +374 -296
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +374 -296
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +374 -296
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +374 -296
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/utils/index.d.cts +2 -2
- package/dist/cli/utils/index.d.ts +2 -2
- package/dist/{fields-YjcpBXVp.d.cts → fields-UcOPu1OQ.d.cts} +16 -0
- package/dist/{fields-YjcpBXVp.d.ts → fields-UcOPu1OQ.d.ts} +16 -0
- package/dist/index.cjs +413 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +414 -103
- package/dist/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +12 -2
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.d.cts +2 -2
- package/dist/migration/analyzer.d.ts +2 -2
- package/dist/migration/analyzer.js +12 -2
- 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 +2 -2
- package/dist/migration/diff.d.ts +2 -2
- 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 +59 -12
- package/dist/migration/generator.d.ts +59 -12
- package/dist/migration/generator.js +319 -47
- package/dist/migration/generator.js.map +1 -1
- package/dist/migration/index.cjs +399 -49
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +3 -3
- package/dist/migration/index.d.ts +3 -3
- package/dist/migration/index.js +399 -49
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +2 -2
- package/dist/migration/snapshot.d.ts +2 -2
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/migration/utils/index.cjs +64 -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 +63 -1
- package/dist/migration/utils/index.js.map +1 -1
- package/dist/schema.cjs +0 -61
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -86
- package/dist/schema.d.ts +2 -86
- package/dist/schema.js +1 -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-LFBGHl9Y.d.ts → types-Ds3NQvny.d.ts} +33 -2
- package/dist/{types-mhQXWNi3.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
|
|
|
@@ -1288,12 +1289,22 @@ function isAuthCollection(fields) {
|
|
|
1288
1289
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1289
1290
|
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1290
1291
|
if (fieldMetadata) {
|
|
1291
|
-
|
|
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 || {};
|
|
1292
1303
|
const fieldDef2 = {
|
|
1293
1304
|
name: fieldName,
|
|
1294
1305
|
type: fieldMetadata.type,
|
|
1295
1306
|
required: required2,
|
|
1296
|
-
options:
|
|
1307
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1297
1308
|
};
|
|
1298
1309
|
if (fieldMetadata.type === "relation") {
|
|
1299
1310
|
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
@@ -1463,6 +1474,65 @@ async function buildSchemaDefinition(config) {
|
|
|
1463
1474
|
async function parseSchemaFiles(config) {
|
|
1464
1475
|
return buildSchemaDefinition(config);
|
|
1465
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
|
+
};
|
|
1466
1536
|
|
|
1467
1537
|
// src/migration/diff.ts
|
|
1468
1538
|
var DEFAULT_CONFIG2 = {
|
|
@@ -1794,6 +1864,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1794
1864
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
1795
1865
|
(collection) => !isSystemCollection(collection.name, config)
|
|
1796
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
|
+
});
|
|
1797
1879
|
const collectionsToModify = [];
|
|
1798
1880
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
1799
1881
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -1803,7 +1885,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1803
1885
|
}
|
|
1804
1886
|
}
|
|
1805
1887
|
return {
|
|
1806
|
-
collectionsToCreate:
|
|
1888
|
+
collectionsToCreate: collectionsWithIds,
|
|
1807
1889
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
1808
1890
|
collectionsToModify
|
|
1809
1891
|
};
|
|
@@ -1886,42 +1968,48 @@ function generateTimestamp(config) {
|
|
|
1886
1968
|
}
|
|
1887
1969
|
return Math.floor(Date.now() / 1e3).toString();
|
|
1888
1970
|
}
|
|
1889
|
-
function
|
|
1890
|
-
const
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
if (diff.collectionsToDelete.length === 1) {
|
|
1900
|
-
parts.push(`deleted_${diff.collectionsToDelete[0].name}`);
|
|
1901
|
-
} else {
|
|
1902
|
-
parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
if (diff.collectionsToModify.length > 0) {
|
|
1906
|
-
if (diff.collectionsToModify.length === 1) {
|
|
1907
|
-
parts.push(`updated_${diff.collectionsToModify[0].collection}`);
|
|
1908
|
-
} else {
|
|
1909
|
-
parts.push(`updated_${diff.collectionsToModify.length}_collections`);
|
|
1910
|
-
}
|
|
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;
|
|
1911
1981
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
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;
|
|
1914
1990
|
}
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
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;
|
|
1918
1999
|
}
|
|
1919
|
-
return
|
|
2000
|
+
return operations;
|
|
1920
2001
|
}
|
|
1921
|
-
function
|
|
1922
|
-
const timestamp =
|
|
1923
|
-
const
|
|
1924
|
-
|
|
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`;
|
|
1925
2013
|
}
|
|
1926
2014
|
function createMigrationFileStructure(upCode, downCode, config) {
|
|
1927
2015
|
const mergedConfig = config ? mergeConfig3(config) : DEFAULT_CONFIG3;
|
|
@@ -1993,14 +2081,13 @@ function formatValue(value) {
|
|
|
1993
2081
|
return "null";
|
|
1994
2082
|
}
|
|
1995
2083
|
if (typeof value === "string") {
|
|
1996
|
-
return
|
|
2084
|
+
return JSON.stringify(value);
|
|
1997
2085
|
}
|
|
1998
2086
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
1999
2087
|
return String(value);
|
|
2000
2088
|
}
|
|
2001
2089
|
if (Array.isArray(value)) {
|
|
2002
|
-
|
|
2003
|
-
return `[${items}]`;
|
|
2090
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
2004
2091
|
}
|
|
2005
2092
|
if (typeof value === "object") {
|
|
2006
2093
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -2008,7 +2095,7 @@ function formatValue(value) {
|
|
|
2008
2095
|
}
|
|
2009
2096
|
return String(value);
|
|
2010
2097
|
}
|
|
2011
|
-
function generateFieldDefinitionObject(field) {
|
|
2098
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
2012
2099
|
const parts = [];
|
|
2013
2100
|
parts.push(` name: "${field.name}"`);
|
|
2014
2101
|
parts.push(` type: "${field.type}"`);
|
|
@@ -2016,34 +2103,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
2016
2103
|
if (field.unique !== void 0) {
|
|
2017
2104
|
parts.push(` unique: ${field.unique}`);
|
|
2018
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
|
+
}
|
|
2019
2112
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2020
2113
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2114
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2115
|
+
continue;
|
|
2116
|
+
}
|
|
2021
2117
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2022
2118
|
}
|
|
2023
2119
|
}
|
|
2024
2120
|
if (field.relation) {
|
|
2025
2121
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
}
|
|
2034
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2035
|
-
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`;
|
|
2036
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}`);
|
|
2037
2137
|
}
|
|
2038
2138
|
return ` {
|
|
2039
2139
|
${parts.join(",\n")},
|
|
2040
2140
|
}`;
|
|
2041
2141
|
}
|
|
2042
|
-
function generateFieldsArray(fields) {
|
|
2142
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
2043
2143
|
if (fields.length === 0) {
|
|
2044
2144
|
return "[]";
|
|
2045
2145
|
}
|
|
2046
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
2146
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
2047
2147
|
return `[
|
|
2048
2148
|
${fieldObjects.join(",\n")},
|
|
2049
2149
|
]`;
|
|
@@ -2102,7 +2202,7 @@ function generateIndexesArray(indexes) {
|
|
|
2102
2202
|
if (!indexes || indexes.length === 0) {
|
|
2103
2203
|
return "[]";
|
|
2104
2204
|
}
|
|
2105
|
-
const indexStrings = indexes.map((idx) =>
|
|
2205
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
2106
2206
|
return `[
|
|
2107
2207
|
${indexStrings.join(",\n ")},
|
|
2108
2208
|
]`;
|
|
@@ -2156,7 +2256,7 @@ function getSystemFields() {
|
|
|
2156
2256
|
}
|
|
2157
2257
|
];
|
|
2158
2258
|
}
|
|
2159
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2259
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
2160
2260
|
const lines = [];
|
|
2161
2261
|
lines.push(` const ${varName} = new Collection({`);
|
|
2162
2262
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2170,7 +2270,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
2170
2270
|
}
|
|
2171
2271
|
const systemFields = getSystemFields();
|
|
2172
2272
|
const allFields = [...systemFields, ...collection.fields];
|
|
2173
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
2273
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
2174
2274
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2175
2275
|
lines.push(` });`);
|
|
2176
2276
|
lines.push(``);
|
|
@@ -2192,42 +2292,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
2192
2292
|
};
|
|
2193
2293
|
return constructorMap[fieldType] || "TextField";
|
|
2194
2294
|
}
|
|
2195
|
-
function generateFieldConstructorOptions(field) {
|
|
2295
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
2196
2296
|
const parts = [];
|
|
2197
2297
|
parts.push(` name: "${field.name}"`);
|
|
2198
2298
|
parts.push(` required: ${field.required}`);
|
|
2199
2299
|
if (field.unique !== void 0) {
|
|
2200
2300
|
parts.push(` unique: ${field.unique}`);
|
|
2201
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
|
+
}
|
|
2202
2308
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2203
2309
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2204
|
-
|
|
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
|
+
}
|
|
2205
2318
|
}
|
|
2206
2319
|
}
|
|
2207
2320
|
if (field.relation && field.type === "relation") {
|
|
2208
2321
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
}
|
|
2217
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2218
|
-
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`;
|
|
2219
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}`);
|
|
2220
2337
|
}
|
|
2221
2338
|
return parts.join(",\n");
|
|
2222
2339
|
}
|
|
2223
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2340
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
2224
2341
|
const lines = [];
|
|
2225
2342
|
const constructorName = getFieldConstructorName(field.type);
|
|
2226
2343
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
2227
2344
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2228
2345
|
lines.push(``);
|
|
2229
2346
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
2230
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
2347
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
2231
2348
|
lines.push(` }));`);
|
|
2232
2349
|
lines.push(``);
|
|
2233
2350
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -2277,7 +2394,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
2277
2394
|
const lines = [];
|
|
2278
2395
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2279
2396
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2280
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
2397
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
2281
2398
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2282
2399
|
return lines.join("\n");
|
|
2283
2400
|
}
|
|
@@ -2286,7 +2403,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
2286
2403
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2287
2404
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
2288
2405
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2289
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
2406
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
2290
2407
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2291
2408
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2292
2409
|
lines.push(` }`);
|
|
@@ -2315,243 +2432,194 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
2315
2432
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
2316
2433
|
return lines.join("\n");
|
|
2317
2434
|
}
|
|
2318
|
-
function
|
|
2435
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
2319
2436
|
const lines = [];
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
lines.push(
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2336
|
-
lines.push(` // Add fields to ${collectionName}`);
|
|
2337
|
-
for (const field of modification.fieldsToAdd) {
|
|
2338
|
-
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2339
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2340
|
-
lines.push(``);
|
|
2341
|
-
}
|
|
2342
|
-
}
|
|
2343
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2344
|
-
lines.push(` // Modify fields in ${collectionName}`);
|
|
2345
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2346
|
-
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2347
|
-
lines.push(generateFieldModification(collectionName, fieldMod, varName));
|
|
2348
|
-
lines.push(``);
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2352
|
-
lines.push(` // Remove fields from ${collectionName}`);
|
|
2353
|
-
for (const field of modification.fieldsToRemove) {
|
|
2354
|
-
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2355
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2356
|
-
lines.push(``);
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2360
|
-
lines.push(` // Add indexes to ${collectionName}`);
|
|
2361
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2362
|
-
const index = modification.indexesToAdd[i];
|
|
2363
|
-
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2364
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2365
|
-
lines.push(``);
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2369
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2370
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2371
|
-
const index = modification.indexesToRemove[i];
|
|
2372
|
-
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2373
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2374
|
-
lines.push(``);
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2378
|
-
lines.push(` // Update permissions for ${collectionName}`);
|
|
2379
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2380
|
-
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2381
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName));
|
|
2382
|
-
lines.push(``);
|
|
2383
|
-
}
|
|
2384
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2385
|
-
lines.push(` // Update rules for ${collectionName}`);
|
|
2386
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2387
|
-
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2388
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName));
|
|
2389
|
-
lines.push(``);
|
|
2390
|
-
}
|
|
2391
|
-
}
|
|
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("");
|
|
2392
2452
|
}
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
lines.push(generateCollectionDeletion(collection.name, varName));
|
|
2400
|
-
lines.push(``);
|
|
2401
|
-
}
|
|
2402
|
-
}
|
|
2403
|
-
if (lines.length === 2) {
|
|
2404
|
-
lines.push(` // No changes detected`);
|
|
2405
|
-
lines.push(``);
|
|
2406
|
-
}
|
|
2407
|
-
let code = lines.join("\n");
|
|
2408
|
-
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2409
|
-
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2410
|
-
const saveMatches = [...code.matchAll(savePattern)];
|
|
2411
|
-
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2412
|
-
const allMatches = [
|
|
2413
|
-
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2414
|
-
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2415
|
-
].sort((a, b) => b.index - a.index);
|
|
2416
|
-
if (allMatches.length > 0) {
|
|
2417
|
-
const lastMatch = allMatches[0];
|
|
2418
|
-
if (lastMatch.type === "save") {
|
|
2419
|
-
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);
|
|
2420
|
-
} else {
|
|
2421
|
-
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("");
|
|
2422
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));
|
|
2423
2504
|
}
|
|
2424
|
-
return
|
|
2505
|
+
return lines.join("\n");
|
|
2425
2506
|
}
|
|
2426
|
-
function
|
|
2507
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
2427
2508
|
const lines = [];
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
lines.push(
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
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("");
|
|
2437
2550
|
}
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
if (
|
|
2444
|
-
lines.push(` // Revert permissions for ${collectionName}`);
|
|
2445
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2446
|
-
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2447
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName));
|
|
2448
|
-
lines.push(``);
|
|
2449
|
-
}
|
|
2450
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2451
|
-
lines.push(` // Revert rules for ${collectionName}`);
|
|
2452
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2453
|
-
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2454
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName));
|
|
2455
|
-
lines.push(``);
|
|
2456
|
-
}
|
|
2457
|
-
}
|
|
2458
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2459
|
-
lines.push(` // Restore indexes to ${collectionName}`);
|
|
2460
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2461
|
-
const index = modification.indexesToRemove[i];
|
|
2462
|
-
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2463
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2464
|
-
lines.push(``);
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2468
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2469
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2470
|
-
const index = modification.indexesToAdd[i];
|
|
2471
|
-
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2472
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2473
|
-
lines.push(``);
|
|
2474
|
-
}
|
|
2475
|
-
}
|
|
2476
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2477
|
-
lines.push(` // Restore fields to ${collectionName}`);
|
|
2478
|
-
for (const field of modification.fieldsToRemove) {
|
|
2479
|
-
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2480
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2481
|
-
lines.push(``);
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2485
|
-
lines.push(` // Revert field modifications in ${collectionName}`);
|
|
2486
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2487
|
-
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2488
|
-
property: change.property,
|
|
2489
|
-
oldValue: change.newValue,
|
|
2490
|
-
newValue: change.oldValue
|
|
2491
|
-
}));
|
|
2492
|
-
const reverseMod = {
|
|
2493
|
-
fieldName: fieldMod.fieldName,
|
|
2494
|
-
currentDefinition: fieldMod.newDefinition,
|
|
2495
|
-
newDefinition: fieldMod.currentDefinition,
|
|
2496
|
-
changes: reverseChanges
|
|
2497
|
-
};
|
|
2498
|
-
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2499
|
-
lines.push(generateFieldModification(collectionName, reverseMod, varName));
|
|
2500
|
-
lines.push(``);
|
|
2501
|
-
}
|
|
2502
|
-
}
|
|
2503
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2504
|
-
lines.push(` // Remove added fields from ${collectionName}`);
|
|
2505
|
-
for (const field of modification.fieldsToAdd) {
|
|
2506
|
-
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2507
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2508
|
-
lines.push(``);
|
|
2509
|
-
}
|
|
2510
|
-
}
|
|
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("");
|
|
2511
2557
|
}
|
|
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
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
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));
|
|
2541
2588
|
}
|
|
2542
2589
|
}
|
|
2543
|
-
return
|
|
2590
|
+
return lines.join("\n");
|
|
2544
2591
|
}
|
|
2545
2592
|
function generate(diff, config) {
|
|
2546
2593
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
2547
2594
|
try {
|
|
2548
2595
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
const
|
|
2554
|
-
|
|
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;
|
|
2555
2623
|
} catch (error) {
|
|
2556
2624
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
2557
2625
|
throw error;
|
|
@@ -3632,15 +3700,25 @@ async function executeGenerate(options) {
|
|
|
3632
3700
|
process.exit(1);
|
|
3633
3701
|
}
|
|
3634
3702
|
logSection("\u{1F4DD} Generating Migration");
|
|
3635
|
-
const
|
|
3703
|
+
const migrationPaths = await withProgress(
|
|
3636
3704
|
"Creating migration file...",
|
|
3637
3705
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
3638
3706
|
);
|
|
3639
|
-
|
|
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
|
+
}
|
|
3640
3716
|
logSection("\u2705 Next Steps");
|
|
3641
3717
|
console.log();
|
|
3642
|
-
console.log(" 1. Review the generated migration file:");
|
|
3643
|
-
|
|
3718
|
+
console.log(" 1. Review the generated migration file(s):");
|
|
3719
|
+
migrationPaths.forEach((migrationPath) => {
|
|
3720
|
+
console.log(` ${migrationPath}`);
|
|
3721
|
+
});
|
|
3644
3722
|
console.log();
|
|
3645
3723
|
console.log(" 2. Apply the migration by running PocketBase:");
|
|
3646
3724
|
console.log(" yarn pb");
|