pocketbase-zod-schema 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +209 -24
- package/dist/cli/index.cjs +406 -294
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -1
- package/dist/cli/index.d.ts +3 -1
- package/dist/cli/index.js +406 -294
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +406 -294
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +406 -294
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/utils/index.d.cts +3 -1
- package/dist/cli/utils/index.d.ts +3 -1
- package/dist/fields-UcOPu1OQ.d.cts +364 -0
- package/dist/fields-UcOPu1OQ.d.ts +364 -0
- package/dist/index.cjs +633 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +619 -101
- package/dist/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +44 -0
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.d.cts +2 -1
- package/dist/migration/analyzer.d.ts +2 -1
- package/dist/migration/analyzer.js +44 -0
- package/dist/migration/analyzer.js.map +1 -1
- package/dist/migration/diff.cjs +76 -1
- package/dist/migration/diff.cjs.map +1 -1
- package/dist/migration/diff.d.cts +3 -1
- package/dist/migration/diff.d.ts +3 -1
- package/dist/migration/diff.js +76 -1
- package/dist/migration/diff.js.map +1 -1
- package/dist/migration/generator.cjs +323 -46
- package/dist/migration/generator.cjs.map +1 -1
- package/dist/migration/generator.d.cts +60 -11
- package/dist/migration/generator.d.ts +60 -11
- package/dist/migration/generator.js +319 -47
- package/dist/migration/generator.js.map +1 -1
- package/dist/migration/index.cjs +433 -47
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +3 -2
- package/dist/migration/index.d.ts +3 -2
- package/dist/migration/index.js +432 -48
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +3 -1
- package/dist/migration/snapshot.d.ts +3 -1
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/migration/utils/index.cjs +80 -0
- package/dist/migration/utils/index.cjs.map +1 -1
- package/dist/migration/utils/index.d.cts +39 -202
- package/dist/migration/utils/index.d.ts +39 -202
- package/dist/migration/utils/index.js +77 -1
- package/dist/migration/utils/index.js.map +1 -1
- package/dist/schema.cjs +200 -61
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -85
- package/dist/schema.d.ts +2 -85
- package/dist/schema.js +186 -50
- package/dist/schema.js.map +1 -1
- package/dist/type-mapper-DrQmtznD.d.cts +208 -0
- package/dist/type-mapper-n231Fspm.d.ts +208 -0
- package/dist/{types-z1Dkjg8m.d.ts → types-Ds3NQvny.d.ts} +33 -2
- package/dist/{types-BbTgmg6H.d.cts → types-YoBjsa-A.d.cts} +33 -2
- package/package.json +1 -1
package/dist/cli/migrate.js
CHANGED
|
@@ -7,6 +7,7 @@ import * as path5 from 'path';
|
|
|
7
7
|
import { dirname, join } from 'path';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
import { z } from 'zod';
|
|
10
|
+
import { randomBytes } from 'crypto';
|
|
10
11
|
import ora from 'ora';
|
|
11
12
|
|
|
12
13
|
({
|
|
@@ -40,6 +41,18 @@ function extractRelationMetadata(description) {
|
|
|
40
41
|
}
|
|
41
42
|
return null;
|
|
42
43
|
}
|
|
44
|
+
var FIELD_METADATA_KEY = "__pocketbase_field__";
|
|
45
|
+
function extractFieldMetadata(description) {
|
|
46
|
+
if (!description) return null;
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(description);
|
|
49
|
+
if (parsed[FIELD_METADATA_KEY]) {
|
|
50
|
+
return parsed[FIELD_METADATA_KEY];
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
43
56
|
|
|
44
57
|
// src/migration/errors.ts
|
|
45
58
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -1278,6 +1291,38 @@ function isAuthCollection(fields) {
|
|
|
1278
1291
|
return hasEmail && hasPassword;
|
|
1279
1292
|
}
|
|
1280
1293
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1294
|
+
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1295
|
+
if (fieldMetadata) {
|
|
1296
|
+
let required2;
|
|
1297
|
+
if (fieldMetadata.type === "number") {
|
|
1298
|
+
if (fieldMetadata.options?.required !== void 0) {
|
|
1299
|
+
required2 = fieldMetadata.options.required;
|
|
1300
|
+
} else {
|
|
1301
|
+
required2 = false;
|
|
1302
|
+
}
|
|
1303
|
+
} else {
|
|
1304
|
+
required2 = isFieldRequired(zodType);
|
|
1305
|
+
}
|
|
1306
|
+
const { required: _required, ...options2 } = fieldMetadata.options || {};
|
|
1307
|
+
const fieldDef2 = {
|
|
1308
|
+
name: fieldName,
|
|
1309
|
+
type: fieldMetadata.type,
|
|
1310
|
+
required: required2,
|
|
1311
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1312
|
+
};
|
|
1313
|
+
if (fieldMetadata.type === "relation") {
|
|
1314
|
+
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
1315
|
+
if (relationMetadata2) {
|
|
1316
|
+
fieldDef2.relation = {
|
|
1317
|
+
collection: relationMetadata2.collection,
|
|
1318
|
+
maxSelect: relationMetadata2.maxSelect,
|
|
1319
|
+
minSelect: relationMetadata2.minSelect,
|
|
1320
|
+
cascadeDelete: relationMetadata2.cascadeDelete
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
return fieldDef2;
|
|
1325
|
+
}
|
|
1281
1326
|
const fieldType = mapZodTypeToPocketBase(zodType, fieldName);
|
|
1282
1327
|
const required = isFieldRequired(zodType);
|
|
1283
1328
|
const options = extractFieldOptions(zodType);
|
|
@@ -1433,6 +1478,65 @@ async function buildSchemaDefinition(config) {
|
|
|
1433
1478
|
async function parseSchemaFiles(config) {
|
|
1434
1479
|
return buildSchemaDefinition(config);
|
|
1435
1480
|
}
|
|
1481
|
+
function generateCollectionId() {
|
|
1482
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
1483
|
+
const idLength = 15;
|
|
1484
|
+
const bytes = randomBytes(idLength);
|
|
1485
|
+
let id = "pb_";
|
|
1486
|
+
for (let i = 0; i < idLength; i++) {
|
|
1487
|
+
const index = bytes[i] % chars.length;
|
|
1488
|
+
id += chars[index];
|
|
1489
|
+
}
|
|
1490
|
+
return id;
|
|
1491
|
+
}
|
|
1492
|
+
var CollectionIdRegistry = class {
|
|
1493
|
+
ids;
|
|
1494
|
+
constructor() {
|
|
1495
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Generates a unique collection ID for a given collection name
|
|
1499
|
+
* Special case: Returns constant "_pb_users_auth_" for users collection
|
|
1500
|
+
* Retries up to 10 times if collision occurs (extremely rare)
|
|
1501
|
+
*
|
|
1502
|
+
* @param collectionName - The name of the collection
|
|
1503
|
+
* @returns A unique collection ID
|
|
1504
|
+
* @throws Error if unable to generate unique ID after max attempts
|
|
1505
|
+
*/
|
|
1506
|
+
generate(collectionName) {
|
|
1507
|
+
if (collectionName && collectionName.toLowerCase() === "users") {
|
|
1508
|
+
const usersId = "_pb_users_auth_";
|
|
1509
|
+
this.register(usersId);
|
|
1510
|
+
return usersId;
|
|
1511
|
+
}
|
|
1512
|
+
const maxAttempts = 10;
|
|
1513
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
1514
|
+
const id = generateCollectionId();
|
|
1515
|
+
if (!this.has(id)) {
|
|
1516
|
+
this.register(id);
|
|
1517
|
+
return id;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
throw new Error("Failed to generate unique collection ID after maximum attempts");
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Checks if an ID has already been registered
|
|
1524
|
+
*
|
|
1525
|
+
* @param id - The collection ID to check
|
|
1526
|
+
* @returns True if the ID exists in the registry
|
|
1527
|
+
*/
|
|
1528
|
+
has(id) {
|
|
1529
|
+
return this.ids.has(id);
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Registers a collection ID in the registry
|
|
1533
|
+
*
|
|
1534
|
+
* @param id - The collection ID to register
|
|
1535
|
+
*/
|
|
1536
|
+
register(id) {
|
|
1537
|
+
this.ids.add(id);
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1436
1540
|
|
|
1437
1541
|
// src/migration/diff.ts
|
|
1438
1542
|
var DEFAULT_CONFIG2 = {
|
|
@@ -1764,6 +1868,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1764
1868
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
1765
1869
|
(collection) => !isSystemCollection(collection.name, config)
|
|
1766
1870
|
);
|
|
1871
|
+
const registry = new CollectionIdRegistry();
|
|
1872
|
+
const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {
|
|
1873
|
+
if (collection.id) {
|
|
1874
|
+
registry.register(collection.id);
|
|
1875
|
+
return collection;
|
|
1876
|
+
}
|
|
1877
|
+
const id = registry.generate(collection.name);
|
|
1878
|
+
return {
|
|
1879
|
+
...collection,
|
|
1880
|
+
id
|
|
1881
|
+
};
|
|
1882
|
+
});
|
|
1767
1883
|
const collectionsToModify = [];
|
|
1768
1884
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
1769
1885
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -1773,7 +1889,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
1773
1889
|
}
|
|
1774
1890
|
}
|
|
1775
1891
|
return {
|
|
1776
|
-
collectionsToCreate:
|
|
1892
|
+
collectionsToCreate: collectionsWithIds,
|
|
1777
1893
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
1778
1894
|
collectionsToModify
|
|
1779
1895
|
};
|
|
@@ -1856,42 +1972,48 @@ function generateTimestamp(config) {
|
|
|
1856
1972
|
}
|
|
1857
1973
|
return Math.floor(Date.now() / 1e3).toString();
|
|
1858
1974
|
}
|
|
1859
|
-
function
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
if (diff.collectionsToDelete.length === 1) {
|
|
1870
|
-
parts.push(`deleted_${diff.collectionsToDelete[0].name}`);
|
|
1871
|
-
} else {
|
|
1872
|
-
parts.push(`deleted_${diff.collectionsToDelete.length}_collections`);
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
if (diff.collectionsToModify.length > 0) {
|
|
1876
|
-
if (diff.collectionsToModify.length === 1) {
|
|
1877
|
-
parts.push(`updated_${diff.collectionsToModify[0].collection}`);
|
|
1878
|
-
} else {
|
|
1879
|
-
parts.push(`updated_${diff.collectionsToModify.length}_collections`);
|
|
1880
|
-
}
|
|
1975
|
+
function splitDiffByCollection(diff, baseTimestamp) {
|
|
1976
|
+
const operations = [];
|
|
1977
|
+
let currentTimestamp = parseInt(baseTimestamp, 10);
|
|
1978
|
+
for (const collection of diff.collectionsToCreate) {
|
|
1979
|
+
operations.push({
|
|
1980
|
+
type: "create",
|
|
1981
|
+
collection,
|
|
1982
|
+
timestamp: currentTimestamp.toString()
|
|
1983
|
+
});
|
|
1984
|
+
currentTimestamp += 1;
|
|
1881
1985
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1986
|
+
for (const modification of diff.collectionsToModify) {
|
|
1987
|
+
operations.push({
|
|
1988
|
+
type: "modify",
|
|
1989
|
+
collection: modification.collection,
|
|
1990
|
+
modifications: modification,
|
|
1991
|
+
timestamp: currentTimestamp.toString()
|
|
1992
|
+
});
|
|
1993
|
+
currentTimestamp += 1;
|
|
1884
1994
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1995
|
+
for (const collection of diff.collectionsToDelete) {
|
|
1996
|
+
operations.push({
|
|
1997
|
+
type: "delete",
|
|
1998
|
+
collection: collection.name || collection,
|
|
1999
|
+
// Handle both object and string
|
|
2000
|
+
timestamp: currentTimestamp.toString()
|
|
2001
|
+
});
|
|
2002
|
+
currentTimestamp += 1;
|
|
1888
2003
|
}
|
|
1889
|
-
return
|
|
2004
|
+
return operations;
|
|
1890
2005
|
}
|
|
1891
|
-
function
|
|
1892
|
-
const timestamp =
|
|
1893
|
-
const
|
|
1894
|
-
|
|
2006
|
+
function generateCollectionMigrationFilename(operation) {
|
|
2007
|
+
const timestamp = operation.timestamp;
|
|
2008
|
+
const operationType = operation.type === "modify" ? "updated" : operation.type === "create" ? "created" : "deleted";
|
|
2009
|
+
let collectionName;
|
|
2010
|
+
if (typeof operation.collection === "string") {
|
|
2011
|
+
collectionName = operation.collection;
|
|
2012
|
+
} else {
|
|
2013
|
+
collectionName = operation.collection.name;
|
|
2014
|
+
}
|
|
2015
|
+
const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
2016
|
+
return `${timestamp}_${operationType}_${sanitizedName}.js`;
|
|
1895
2017
|
}
|
|
1896
2018
|
function createMigrationFileStructure(upCode, downCode, config) {
|
|
1897
2019
|
const mergedConfig = config ? mergeConfig3(config) : DEFAULT_CONFIG3;
|
|
@@ -1963,14 +2085,13 @@ function formatValue(value) {
|
|
|
1963
2085
|
return "null";
|
|
1964
2086
|
}
|
|
1965
2087
|
if (typeof value === "string") {
|
|
1966
|
-
return
|
|
2088
|
+
return JSON.stringify(value);
|
|
1967
2089
|
}
|
|
1968
2090
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
1969
2091
|
return String(value);
|
|
1970
2092
|
}
|
|
1971
2093
|
if (Array.isArray(value)) {
|
|
1972
|
-
|
|
1973
|
-
return `[${items}]`;
|
|
2094
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
1974
2095
|
}
|
|
1975
2096
|
if (typeof value === "object") {
|
|
1976
2097
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -1978,7 +2099,7 @@ function formatValue(value) {
|
|
|
1978
2099
|
}
|
|
1979
2100
|
return String(value);
|
|
1980
2101
|
}
|
|
1981
|
-
function generateFieldDefinitionObject(field) {
|
|
2102
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
1982
2103
|
const parts = [];
|
|
1983
2104
|
parts.push(` name: "${field.name}"`);
|
|
1984
2105
|
parts.push(` type: "${field.type}"`);
|
|
@@ -1986,34 +2107,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
1986
2107
|
if (field.unique !== void 0) {
|
|
1987
2108
|
parts.push(` unique: ${field.unique}`);
|
|
1988
2109
|
}
|
|
2110
|
+
if (field.type === "select") {
|
|
2111
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2112
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2113
|
+
const values = field.options?.values ?? [];
|
|
2114
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2115
|
+
}
|
|
1989
2116
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
1990
2117
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2118
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2119
|
+
continue;
|
|
2120
|
+
}
|
|
1991
2121
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
1992
2122
|
}
|
|
1993
2123
|
}
|
|
1994
2124
|
if (field.relation) {
|
|
1995
2125
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
}
|
|
2004
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2005
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2126
|
+
let collectionIdValue;
|
|
2127
|
+
if (isUsersCollection) {
|
|
2128
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2129
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2130
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2131
|
+
} else {
|
|
2132
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2006
2133
|
}
|
|
2134
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2135
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2136
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2137
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2138
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2139
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2140
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2007
2141
|
}
|
|
2008
2142
|
return ` {
|
|
2009
2143
|
${parts.join(",\n")},
|
|
2010
2144
|
}`;
|
|
2011
2145
|
}
|
|
2012
|
-
function generateFieldsArray(fields) {
|
|
2146
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
2013
2147
|
if (fields.length === 0) {
|
|
2014
2148
|
return "[]";
|
|
2015
2149
|
}
|
|
2016
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
2150
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
2017
2151
|
return `[
|
|
2018
2152
|
${fieldObjects.join(",\n")},
|
|
2019
2153
|
]`;
|
|
@@ -2072,7 +2206,7 @@ function generateIndexesArray(indexes) {
|
|
|
2072
2206
|
if (!indexes || indexes.length === 0) {
|
|
2073
2207
|
return "[]";
|
|
2074
2208
|
}
|
|
2075
|
-
const indexStrings = indexes.map((idx) =>
|
|
2209
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
2076
2210
|
return `[
|
|
2077
2211
|
${indexStrings.join(",\n ")},
|
|
2078
2212
|
]`;
|
|
@@ -2126,7 +2260,7 @@ function getSystemFields() {
|
|
|
2126
2260
|
}
|
|
2127
2261
|
];
|
|
2128
2262
|
}
|
|
2129
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2263
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
2130
2264
|
const lines = [];
|
|
2131
2265
|
lines.push(` const ${varName} = new Collection({`);
|
|
2132
2266
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2140,7 +2274,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
2140
2274
|
}
|
|
2141
2275
|
const systemFields = getSystemFields();
|
|
2142
2276
|
const allFields = [...systemFields, ...collection.fields];
|
|
2143
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
2277
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
2144
2278
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2145
2279
|
lines.push(` });`);
|
|
2146
2280
|
lines.push(``);
|
|
@@ -2162,42 +2296,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
2162
2296
|
};
|
|
2163
2297
|
return constructorMap[fieldType] || "TextField";
|
|
2164
2298
|
}
|
|
2165
|
-
function generateFieldConstructorOptions(field) {
|
|
2299
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
2166
2300
|
const parts = [];
|
|
2167
2301
|
parts.push(` name: "${field.name}"`);
|
|
2168
2302
|
parts.push(` required: ${field.required}`);
|
|
2169
2303
|
if (field.unique !== void 0) {
|
|
2170
2304
|
parts.push(` unique: ${field.unique}`);
|
|
2171
2305
|
}
|
|
2306
|
+
if (field.type === "select") {
|
|
2307
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
2308
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2309
|
+
const values = field.options?.values ?? [];
|
|
2310
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
2311
|
+
}
|
|
2172
2312
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
2173
2313
|
for (const [key, value] of Object.entries(field.options)) {
|
|
2174
|
-
|
|
2314
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
2315
|
+
continue;
|
|
2316
|
+
}
|
|
2317
|
+
if (field.type === "number" && key === "noDecimal") {
|
|
2318
|
+
parts.push(` onlyInt: ${formatValue(value)}`);
|
|
2319
|
+
} else {
|
|
2320
|
+
parts.push(` ${key}: ${formatValue(value)}`);
|
|
2321
|
+
}
|
|
2175
2322
|
}
|
|
2176
2323
|
}
|
|
2177
2324
|
if (field.relation && field.type === "relation") {
|
|
2178
2325
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
}
|
|
2187
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
2188
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
2326
|
+
let collectionIdValue;
|
|
2327
|
+
if (isUsersCollection) {
|
|
2328
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
2329
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
2330
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
2331
|
+
} else {
|
|
2332
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2189
2333
|
}
|
|
2334
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
2335
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
2336
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
2337
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
2338
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
2339
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
2340
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
2190
2341
|
}
|
|
2191
2342
|
return parts.join(",\n");
|
|
2192
2343
|
}
|
|
2193
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2344
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
2194
2345
|
const lines = [];
|
|
2195
2346
|
const constructorName = getFieldConstructorName(field.type);
|
|
2196
2347
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
2197
2348
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2198
2349
|
lines.push(``);
|
|
2199
2350
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
2200
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
2351
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
2201
2352
|
lines.push(` }));`);
|
|
2202
2353
|
lines.push(``);
|
|
2203
2354
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -2247,7 +2398,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
2247
2398
|
const lines = [];
|
|
2248
2399
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2249
2400
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2250
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
2401
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
2251
2402
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2252
2403
|
return lines.join("\n");
|
|
2253
2404
|
}
|
|
@@ -2256,7 +2407,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
2256
2407
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2257
2408
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
2258
2409
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2259
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
2410
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
2260
2411
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2261
2412
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2262
2413
|
lines.push(` }`);
|
|
@@ -2285,243 +2436,194 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
2285
2436
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
2286
2437
|
return lines.join("\n");
|
|
2287
2438
|
}
|
|
2288
|
-
function
|
|
2439
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
2289
2440
|
const lines = [];
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
lines.push(
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2306
|
-
lines.push(` // Add fields to ${collectionName}`);
|
|
2307
|
-
for (const field of modification.fieldsToAdd) {
|
|
2308
|
-
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2309
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2310
|
-
lines.push(``);
|
|
2311
|
-
}
|
|
2312
|
-
}
|
|
2313
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2314
|
-
lines.push(` // Modify fields in ${collectionName}`);
|
|
2315
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2316
|
-
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2317
|
-
lines.push(generateFieldModification(collectionName, fieldMod, varName));
|
|
2318
|
-
lines.push(``);
|
|
2319
|
-
}
|
|
2320
|
-
}
|
|
2321
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2322
|
-
lines.push(` // Remove fields from ${collectionName}`);
|
|
2323
|
-
for (const field of modification.fieldsToRemove) {
|
|
2324
|
-
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2325
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2326
|
-
lines.push(``);
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2330
|
-
lines.push(` // Add indexes to ${collectionName}`);
|
|
2331
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2332
|
-
const index = modification.indexesToAdd[i];
|
|
2333
|
-
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2334
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2335
|
-
lines.push(``);
|
|
2336
|
-
}
|
|
2337
|
-
}
|
|
2338
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2339
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2340
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2341
|
-
const index = modification.indexesToRemove[i];
|
|
2342
|
-
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2343
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2344
|
-
lines.push(``);
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2348
|
-
lines.push(` // Update permissions for ${collectionName}`);
|
|
2349
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2350
|
-
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2351
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName));
|
|
2352
|
-
lines.push(``);
|
|
2353
|
-
}
|
|
2354
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2355
|
-
lines.push(` // Update rules for ${collectionName}`);
|
|
2356
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2357
|
-
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2358
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName));
|
|
2359
|
-
lines.push(``);
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2441
|
+
if (operation.type === "create") {
|
|
2442
|
+
const collection = operation.collection;
|
|
2443
|
+
const varName = `collection_${collection.name}`;
|
|
2444
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2445
|
+
} else if (operation.type === "modify") {
|
|
2446
|
+
const modification = operation.modifications;
|
|
2447
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2448
|
+
let operationCount = 0;
|
|
2449
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2450
|
+
for (const field of modification.fieldsToAdd) {
|
|
2451
|
+
operationCount++;
|
|
2452
|
+
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
2453
|
+
const isLast = operationCount === totalOperations;
|
|
2454
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2455
|
+
if (!isLast) lines.push("");
|
|
2362
2456
|
}
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
lines.push(generateCollectionDeletion(collection.name, varName));
|
|
2370
|
-
lines.push(``);
|
|
2371
|
-
}
|
|
2372
|
-
}
|
|
2373
|
-
if (lines.length === 2) {
|
|
2374
|
-
lines.push(` // No changes detected`);
|
|
2375
|
-
lines.push(``);
|
|
2376
|
-
}
|
|
2377
|
-
let code = lines.join("\n");
|
|
2378
|
-
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2379
|
-
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2380
|
-
const saveMatches = [...code.matchAll(savePattern)];
|
|
2381
|
-
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2382
|
-
const allMatches = [
|
|
2383
|
-
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2384
|
-
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2385
|
-
].sort((a, b) => b.index - a.index);
|
|
2386
|
-
if (allMatches.length > 0) {
|
|
2387
|
-
const lastMatch = allMatches[0];
|
|
2388
|
-
if (lastMatch.type === "save") {
|
|
2389
|
-
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);
|
|
2390
|
-
} else {
|
|
2391
|
-
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);
|
|
2457
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2458
|
+
operationCount++;
|
|
2459
|
+
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
2460
|
+
const isLast = operationCount === totalOperations;
|
|
2461
|
+
lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
|
|
2462
|
+
if (!isLast) lines.push("");
|
|
2392
2463
|
}
|
|
2464
|
+
for (const field of modification.fieldsToRemove) {
|
|
2465
|
+
operationCount++;
|
|
2466
|
+
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
2467
|
+
const isLast = operationCount === totalOperations;
|
|
2468
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2469
|
+
if (!isLast) lines.push("");
|
|
2470
|
+
}
|
|
2471
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2472
|
+
operationCount++;
|
|
2473
|
+
const index = modification.indexesToAdd[i];
|
|
2474
|
+
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
2475
|
+
const isLast = operationCount === totalOperations;
|
|
2476
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2477
|
+
if (!isLast) lines.push("");
|
|
2478
|
+
}
|
|
2479
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2480
|
+
operationCount++;
|
|
2481
|
+
const index = modification.indexesToRemove[i];
|
|
2482
|
+
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
2483
|
+
const isLast = operationCount === totalOperations;
|
|
2484
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2485
|
+
if (!isLast) lines.push("");
|
|
2486
|
+
}
|
|
2487
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2488
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2489
|
+
operationCount++;
|
|
2490
|
+
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
2491
|
+
const isLast = operationCount === totalOperations;
|
|
2492
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast));
|
|
2493
|
+
if (!isLast) lines.push("");
|
|
2494
|
+
}
|
|
2495
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2496
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2497
|
+
operationCount++;
|
|
2498
|
+
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
2499
|
+
const isLast = operationCount === totalOperations;
|
|
2500
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast));
|
|
2501
|
+
if (!isLast) lines.push("");
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
} else if (operation.type === "delete") {
|
|
2505
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection.name;
|
|
2506
|
+
const varName = `collection_${collectionName}`;
|
|
2507
|
+
lines.push(generateCollectionDeletion(collectionName, varName, true));
|
|
2393
2508
|
}
|
|
2394
|
-
return
|
|
2509
|
+
return lines.join("\n");
|
|
2395
2510
|
}
|
|
2396
|
-
function
|
|
2511
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
2397
2512
|
const lines = [];
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
lines.push(
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2513
|
+
if (operation.type === "create") {
|
|
2514
|
+
const collection = operation.collection;
|
|
2515
|
+
const varName = `collection_${collection.name}`;
|
|
2516
|
+
lines.push(generateCollectionDeletion(collection.name, varName, true));
|
|
2517
|
+
} else if (operation.type === "modify") {
|
|
2518
|
+
const modification = operation.modifications;
|
|
2519
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
2520
|
+
let operationCount = 0;
|
|
2521
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
2522
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
2523
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
2524
|
+
operationCount++;
|
|
2525
|
+
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2526
|
+
const isLast = operationCount === totalOperations;
|
|
2527
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast));
|
|
2528
|
+
if (!isLast) lines.push("");
|
|
2529
|
+
}
|
|
2530
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
2531
|
+
for (const rule of modification.rulesToUpdate) {
|
|
2532
|
+
operationCount++;
|
|
2533
|
+
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2534
|
+
const isLast = operationCount === totalOperations;
|
|
2535
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast));
|
|
2536
|
+
if (!isLast) lines.push("");
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2540
|
+
operationCount++;
|
|
2541
|
+
const index = modification.indexesToRemove[i];
|
|
2542
|
+
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2543
|
+
const isLast = operationCount === totalOperations;
|
|
2544
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
2545
|
+
if (!isLast) lines.push("");
|
|
2546
|
+
}
|
|
2547
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2548
|
+
operationCount++;
|
|
2549
|
+
const index = modification.indexesToAdd[i];
|
|
2550
|
+
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2551
|
+
const isLast = operationCount === totalOperations;
|
|
2552
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
2553
|
+
if (!isLast) lines.push("");
|
|
2407
2554
|
}
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
if (
|
|
2414
|
-
lines.push(` // Revert permissions for ${collectionName}`);
|
|
2415
|
-
for (const permission of modification.permissionsToUpdate) {
|
|
2416
|
-
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
2417
|
-
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName));
|
|
2418
|
-
lines.push(``);
|
|
2419
|
-
}
|
|
2420
|
-
} else if (modification.rulesToUpdate.length > 0) {
|
|
2421
|
-
lines.push(` // Revert rules for ${collectionName}`);
|
|
2422
|
-
for (const rule of modification.rulesToUpdate) {
|
|
2423
|
-
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
2424
|
-
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName));
|
|
2425
|
-
lines.push(``);
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
if (modification.indexesToRemove.length > 0) {
|
|
2429
|
-
lines.push(` // Restore indexes to ${collectionName}`);
|
|
2430
|
-
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
2431
|
-
const index = modification.indexesToRemove[i];
|
|
2432
|
-
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
2433
|
-
lines.push(generateIndexAddition(collectionName, index, varName));
|
|
2434
|
-
lines.push(``);
|
|
2435
|
-
}
|
|
2436
|
-
}
|
|
2437
|
-
if (modification.indexesToAdd.length > 0) {
|
|
2438
|
-
lines.push(` // Remove indexes from ${collectionName}`);
|
|
2439
|
-
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
2440
|
-
const index = modification.indexesToAdd[i];
|
|
2441
|
-
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
2442
|
-
lines.push(generateIndexRemoval(collectionName, index, varName));
|
|
2443
|
-
lines.push(``);
|
|
2444
|
-
}
|
|
2445
|
-
}
|
|
2446
|
-
if (modification.fieldsToRemove.length > 0) {
|
|
2447
|
-
lines.push(` // Restore fields to ${collectionName}`);
|
|
2448
|
-
for (const field of modification.fieldsToRemove) {
|
|
2449
|
-
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2450
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
2451
|
-
lines.push(``);
|
|
2452
|
-
}
|
|
2453
|
-
}
|
|
2454
|
-
if (modification.fieldsToModify.length > 0) {
|
|
2455
|
-
lines.push(` // Revert field modifications in ${collectionName}`);
|
|
2456
|
-
for (const fieldMod of modification.fieldsToModify) {
|
|
2457
|
-
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2458
|
-
property: change.property,
|
|
2459
|
-
oldValue: change.newValue,
|
|
2460
|
-
newValue: change.oldValue
|
|
2461
|
-
}));
|
|
2462
|
-
const reverseMod = {
|
|
2463
|
-
fieldName: fieldMod.fieldName,
|
|
2464
|
-
currentDefinition: fieldMod.newDefinition,
|
|
2465
|
-
newDefinition: fieldMod.currentDefinition,
|
|
2466
|
-
changes: reverseChanges
|
|
2467
|
-
};
|
|
2468
|
-
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2469
|
-
lines.push(generateFieldModification(collectionName, reverseMod, varName));
|
|
2470
|
-
lines.push(``);
|
|
2471
|
-
}
|
|
2472
|
-
}
|
|
2473
|
-
if (modification.fieldsToAdd.length > 0) {
|
|
2474
|
-
lines.push(` // Remove added fields from ${collectionName}`);
|
|
2475
|
-
for (const field of modification.fieldsToAdd) {
|
|
2476
|
-
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2477
|
-
lines.push(generateFieldDeletion(collectionName, field.name, varName));
|
|
2478
|
-
lines.push(``);
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2555
|
+
for (const field of modification.fieldsToRemove) {
|
|
2556
|
+
operationCount++;
|
|
2557
|
+
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
2558
|
+
const isLast = operationCount === totalOperations;
|
|
2559
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
2560
|
+
if (!isLast) lines.push("");
|
|
2481
2561
|
}
|
|
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
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2562
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
2563
|
+
operationCount++;
|
|
2564
|
+
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
2565
|
+
property: change.property,
|
|
2566
|
+
oldValue: change.newValue,
|
|
2567
|
+
newValue: change.oldValue
|
|
2568
|
+
}));
|
|
2569
|
+
const reverseMod = {
|
|
2570
|
+
fieldName: fieldMod.fieldName,
|
|
2571
|
+
currentDefinition: fieldMod.newDefinition,
|
|
2572
|
+
newDefinition: fieldMod.currentDefinition,
|
|
2573
|
+
changes: reverseChanges
|
|
2574
|
+
};
|
|
2575
|
+
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
2576
|
+
const isLast = operationCount === totalOperations;
|
|
2577
|
+
lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast));
|
|
2578
|
+
if (!isLast) lines.push("");
|
|
2579
|
+
}
|
|
2580
|
+
for (const field of modification.fieldsToAdd) {
|
|
2581
|
+
operationCount++;
|
|
2582
|
+
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
2583
|
+
const isLast = operationCount === totalOperations;
|
|
2584
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
2585
|
+
if (!isLast) lines.push("");
|
|
2586
|
+
}
|
|
2587
|
+
} else if (operation.type === "delete") {
|
|
2588
|
+
const collection = operation.collection;
|
|
2589
|
+
if (typeof collection !== "string") {
|
|
2590
|
+
const varName = `collection_${collection.name}`;
|
|
2591
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
2511
2592
|
}
|
|
2512
2593
|
}
|
|
2513
|
-
return
|
|
2594
|
+
return lines.join("\n");
|
|
2514
2595
|
}
|
|
2515
2596
|
function generate(diff, config) {
|
|
2516
2597
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
2517
2598
|
try {
|
|
2518
2599
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
2519
|
-
const
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
const
|
|
2524
|
-
|
|
2600
|
+
const hasChanges4 = diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;
|
|
2601
|
+
if (!hasChanges4) {
|
|
2602
|
+
return [];
|
|
2603
|
+
}
|
|
2604
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
2605
|
+
for (const collection of diff.collectionsToCreate) {
|
|
2606
|
+
if (collection.id) {
|
|
2607
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
for (const collection of diff.collectionsToDelete) {
|
|
2611
|
+
if (collection.id) {
|
|
2612
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
const baseTimestamp = generateTimestamp(normalizedConfig);
|
|
2616
|
+
const operations = splitDiffByCollection(diff, baseTimestamp);
|
|
2617
|
+
const filePaths = [];
|
|
2618
|
+
for (const operation of operations) {
|
|
2619
|
+
const upCode = generateOperationUpMigration(operation, collectionIdMap);
|
|
2620
|
+
const downCode = generateOperationDownMigration(operation, collectionIdMap);
|
|
2621
|
+
const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);
|
|
2622
|
+
const filename = generateCollectionMigrationFilename(operation);
|
|
2623
|
+
const filePath = writeMigrationFile(migrationDir, filename, content);
|
|
2624
|
+
filePaths.push(filePath);
|
|
2625
|
+
}
|
|
2626
|
+
return filePaths;
|
|
2525
2627
|
} catch (error) {
|
|
2526
2628
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
2527
2629
|
throw error;
|
|
@@ -3542,15 +3644,25 @@ async function executeGenerate(options) {
|
|
|
3542
3644
|
process.exit(1);
|
|
3543
3645
|
}
|
|
3544
3646
|
logSection("\u{1F4DD} Generating Migration");
|
|
3545
|
-
const
|
|
3647
|
+
const migrationPaths = await withProgress(
|
|
3546
3648
|
"Creating migration file...",
|
|
3547
3649
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
3548
3650
|
);
|
|
3549
|
-
|
|
3651
|
+
if (migrationPaths.length === 0) {
|
|
3652
|
+
logWarning("No migration files were generated (no changes detected).");
|
|
3653
|
+
return;
|
|
3654
|
+
}
|
|
3655
|
+
if (migrationPaths.length === 1) {
|
|
3656
|
+
logSuccess(`Migration file created: ${path5.basename(migrationPaths[0])}`);
|
|
3657
|
+
} else {
|
|
3658
|
+
logSuccess(`Created ${migrationPaths.length} migration files`);
|
|
3659
|
+
}
|
|
3550
3660
|
logSection("\u2705 Next Steps");
|
|
3551
3661
|
console.log();
|
|
3552
|
-
console.log(" 1. Review the generated migration file:");
|
|
3553
|
-
|
|
3662
|
+
console.log(" 1. Review the generated migration file(s):");
|
|
3663
|
+
migrationPaths.forEach((migrationPath) => {
|
|
3664
|
+
console.log(` ${migrationPath}`);
|
|
3665
|
+
});
|
|
3554
3666
|
console.log();
|
|
3555
3667
|
console.log(" 2. Apply the migration by running PocketBase:");
|
|
3556
3668
|
console.log(" yarn pb");
|