pocketbase-zod-schema 0.1.3 → 0.2.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 +14 -0
- package/README.md +233 -98
- package/dist/cli/index.cjs +449 -108
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +447 -106
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +452 -111
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +447 -106
- package/dist/cli/migrate.js.map +1 -1
- package/dist/index.cjs +593 -175
- 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 +583 -172
- package/dist/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +44 -6
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.d.cts +11 -1
- package/dist/migration/analyzer.d.ts +11 -1
- package/dist/migration/analyzer.js +44 -7
- package/dist/migration/analyzer.js.map +1 -1
- package/dist/migration/diff.cjs +21 -3
- package/dist/migration/diff.cjs.map +1 -1
- package/dist/migration/diff.js +21 -3
- package/dist/migration/diff.js.map +1 -1
- package/dist/migration/index.cjs +500 -129
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +1 -1
- package/dist/migration/index.d.ts +1 -1
- package/dist/migration/index.js +499 -129
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs +432 -118
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +34 -12
- package/dist/migration/snapshot.d.ts +34 -12
- package/dist/migration/snapshot.js +430 -117
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/mutator.cjs +20 -21
- package/dist/mutator.cjs.map +1 -1
- package/dist/mutator.d.cts +4 -4
- package/dist/mutator.d.ts +4 -4
- package/dist/mutator.js +20 -21
- package/dist/mutator.js.map +1 -1
- package/dist/schema.cjs +69 -10
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +98 -8
- package/dist/schema.d.ts +98 -8
- package/dist/schema.js +62 -9
- package/dist/schema.js.map +1 -1
- package/dist/types.d.cts +5 -2
- package/dist/types.d.ts +5 -2
- package/dist/user-DTJQIj4K.d.cts +149 -0
- package/dist/user-DTJQIj4K.d.ts +149 -0
- package/package.json +3 -3
- package/dist/user-C39DQ40N.d.cts +0 -53
- package/dist/user-C39DQ40N.d.ts +0 -53
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
2
|
+
import * as fs3 from 'fs';
|
|
3
|
+
import * as path5 from 'path';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import ora from 'ora';
|
|
6
6
|
|
|
@@ -78,7 +78,7 @@ function filesField(options) {
|
|
|
78
78
|
return schema;
|
|
79
79
|
}
|
|
80
80
|
var RELATION_METADATA_KEY = "__pocketbase_relation__";
|
|
81
|
-
function
|
|
81
|
+
function RelationField(config) {
|
|
82
82
|
const metadata = {
|
|
83
83
|
[RELATION_METADATA_KEY]: {
|
|
84
84
|
type: "single",
|
|
@@ -90,7 +90,7 @@ function relationField(config) {
|
|
|
90
90
|
};
|
|
91
91
|
return z.string().describe(JSON.stringify(metadata));
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function RelationsField(config) {
|
|
94
94
|
const metadata = {
|
|
95
95
|
[RELATION_METADATA_KEY]: {
|
|
96
96
|
type: "multiple",
|
|
@@ -149,6 +149,22 @@ function withIndexes(schema, indexes) {
|
|
|
149
149
|
};
|
|
150
150
|
return schema.describe(JSON.stringify(metadata));
|
|
151
151
|
}
|
|
152
|
+
function defineCollection(config) {
|
|
153
|
+
const { collectionName, schema, permissions, indexes, ...futureOptions } = config;
|
|
154
|
+
const metadata = {
|
|
155
|
+
collectionName
|
|
156
|
+
};
|
|
157
|
+
if (permissions) {
|
|
158
|
+
metadata.permissions = permissions;
|
|
159
|
+
}
|
|
160
|
+
if (indexes) {
|
|
161
|
+
metadata.indexes = indexes;
|
|
162
|
+
}
|
|
163
|
+
if (Object.keys(futureOptions).length > 0) {
|
|
164
|
+
Object.assign(metadata, futureOptions);
|
|
165
|
+
}
|
|
166
|
+
return schema.describe(JSON.stringify(metadata));
|
|
167
|
+
}
|
|
152
168
|
|
|
153
169
|
// src/utils/permission-templates.ts
|
|
154
170
|
var PermissionTemplates = {
|
|
@@ -369,6 +385,28 @@ function mergePermissions(...schemas) {
|
|
|
369
385
|
}
|
|
370
386
|
return merged;
|
|
371
387
|
}
|
|
388
|
+
var ProjectInputSchema = z.object({
|
|
389
|
+
// Required fields
|
|
390
|
+
title: z.string(),
|
|
391
|
+
content: z.string(),
|
|
392
|
+
status: StatusEnum,
|
|
393
|
+
summary: z.string().optional(),
|
|
394
|
+
OwnerUser: RelationField({ collection: "Users" }),
|
|
395
|
+
SubscriberUsers: RelationsField({ collection: "Users" })
|
|
396
|
+
}).extend(inputImageFileSchema);
|
|
397
|
+
var ProjectSchema = ProjectInputSchema.omit(omitImageFilesSchema).extend(baseImageFileSchema);
|
|
398
|
+
var ProjectCollection = defineCollection({
|
|
399
|
+
collectionName: "Projects",
|
|
400
|
+
schema: ProjectSchema,
|
|
401
|
+
permissions: {
|
|
402
|
+
template: "owner-only",
|
|
403
|
+
ownerField: "OwnerUser",
|
|
404
|
+
customRules: {
|
|
405
|
+
listRule: '@request.auth.id != ""',
|
|
406
|
+
viewRule: '@request.auth.id != "" && (OwnerUser = @request.auth.id || SubscriberUsers ?= @request.auth.id)'
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
});
|
|
372
410
|
var UserInputSchema = z.object({
|
|
373
411
|
name: z.string().optional(),
|
|
374
412
|
email: z.string().email(),
|
|
@@ -376,14 +414,17 @@ var UserInputSchema = z.object({
|
|
|
376
414
|
passwordConfirm: z.string(),
|
|
377
415
|
avatar: z.instanceof(File).optional()
|
|
378
416
|
});
|
|
379
|
-
var
|
|
417
|
+
var UserCollectionSchema = z.object({
|
|
380
418
|
name: z.string().optional(),
|
|
381
419
|
email: z.string().email(),
|
|
382
420
|
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
383
421
|
avatar: z.instanceof(File).optional()
|
|
384
422
|
});
|
|
385
|
-
var UserSchema =
|
|
386
|
-
|
|
423
|
+
var UserSchema = UserCollectionSchema.extend(baseSchema);
|
|
424
|
+
var UserCollection = defineCollection({
|
|
425
|
+
collectionName: "Users",
|
|
426
|
+
schema: UserSchema,
|
|
427
|
+
permissions: {
|
|
387
428
|
// Users can list their own profile
|
|
388
429
|
listRule: "id = @request.auth.id",
|
|
389
430
|
// Users can view their own profile
|
|
@@ -395,13 +436,13 @@ var UserSchema = withIndexes(
|
|
|
395
436
|
// Users can only delete their own account
|
|
396
437
|
deleteRule: "id = @request.auth.id"
|
|
397
438
|
// manageRule is null in PocketBase default (not set)
|
|
398
|
-
}
|
|
399
|
-
[
|
|
439
|
+
},
|
|
440
|
+
indexes: [
|
|
400
441
|
// PocketBase's default indexes for auth collections
|
|
401
442
|
"CREATE UNIQUE INDEX `idx_tokenKey__pb_users_auth_` ON `users` (`tokenKey`)",
|
|
402
443
|
"CREATE UNIQUE INDEX `idx_email__pb_users_auth_` ON `users` (`email`) WHERE `email` != ''"
|
|
403
444
|
]
|
|
404
|
-
);
|
|
445
|
+
});
|
|
405
446
|
var BaseMutator = class {
|
|
406
447
|
pb;
|
|
407
448
|
// Define a default property that subclasses will override
|
|
@@ -844,10 +885,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
|
|
|
844
885
|
operation;
|
|
845
886
|
code;
|
|
846
887
|
originalError;
|
|
847
|
-
constructor(message,
|
|
888
|
+
constructor(message, path7, operation, code, originalError) {
|
|
848
889
|
super(message);
|
|
849
890
|
this.name = "FileSystemError";
|
|
850
|
-
this.path =
|
|
891
|
+
this.path = path7;
|
|
851
892
|
this.operation = operation;
|
|
852
893
|
this.code = code;
|
|
853
894
|
this.originalError = originalError;
|
|
@@ -1923,6 +1964,16 @@ function getFieldTypeInfo(zodType, fieldName) {
|
|
|
1923
1964
|
}
|
|
1924
1965
|
|
|
1925
1966
|
// src/migration/analyzer.ts
|
|
1967
|
+
var tsxLoaderRegistered = false;
|
|
1968
|
+
async function ensureTsxLoader() {
|
|
1969
|
+
if (tsxLoaderRegistered) return;
|
|
1970
|
+
try {
|
|
1971
|
+
await import('tsx/esm');
|
|
1972
|
+
tsxLoaderRegistered = true;
|
|
1973
|
+
} catch {
|
|
1974
|
+
tsxLoaderRegistered = false;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1926
1977
|
var DEFAULT_CONFIG = {
|
|
1927
1978
|
workspaceRoot: process.cwd(),
|
|
1928
1979
|
excludePatterns: [
|
|
@@ -1950,20 +2001,20 @@ function mergeConfig(config) {
|
|
|
1950
2001
|
}
|
|
1951
2002
|
function resolveSchemaDir(config) {
|
|
1952
2003
|
const workspaceRoot = config.workspaceRoot || process.cwd();
|
|
1953
|
-
if (
|
|
2004
|
+
if (path5.isAbsolute(config.schemaDir)) {
|
|
1954
2005
|
return config.schemaDir;
|
|
1955
2006
|
}
|
|
1956
|
-
return
|
|
2007
|
+
return path5.join(workspaceRoot, config.schemaDir);
|
|
1957
2008
|
}
|
|
1958
2009
|
function discoverSchemaFiles(config) {
|
|
1959
2010
|
const normalizedConfig = typeof config === "string" ? { schemaDir: config } : config;
|
|
1960
2011
|
const mergedConfig = mergeConfig(normalizedConfig);
|
|
1961
2012
|
const schemaDir = resolveSchemaDir(normalizedConfig);
|
|
1962
2013
|
try {
|
|
1963
|
-
if (!
|
|
2014
|
+
if (!fs3.existsSync(schemaDir)) {
|
|
1964
2015
|
throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
|
|
1965
2016
|
}
|
|
1966
|
-
const files =
|
|
2017
|
+
const files = fs3.readdirSync(schemaDir);
|
|
1967
2018
|
const schemaFiles = files.filter((file) => {
|
|
1968
2019
|
const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
|
|
1969
2020
|
if (!hasValidExtension) return false;
|
|
@@ -1979,7 +2030,7 @@ function discoverSchemaFiles(config) {
|
|
|
1979
2030
|
});
|
|
1980
2031
|
return schemaFiles.map((file) => {
|
|
1981
2032
|
const ext = mergedConfig.includeExtensions.find((ext2) => file.endsWith(ext2)) || ".ts";
|
|
1982
|
-
return
|
|
2033
|
+
return path5.join(schemaDir, file.replace(new RegExp(`\\${ext}$`), ""));
|
|
1983
2034
|
});
|
|
1984
2035
|
} catch (error) {
|
|
1985
2036
|
if (error instanceof FileSystemError) {
|
|
@@ -2013,40 +2064,66 @@ async function importSchemaModule(filePath, config) {
|
|
|
2013
2064
|
let resolvedPath = null;
|
|
2014
2065
|
const jsPath = `${importPath}.js`;
|
|
2015
2066
|
const tsPath = `${importPath}.ts`;
|
|
2016
|
-
if (
|
|
2067
|
+
if (fs3.existsSync(jsPath)) {
|
|
2017
2068
|
resolvedPath = jsPath;
|
|
2018
|
-
} else if (
|
|
2069
|
+
} else if (fs3.existsSync(tsPath)) {
|
|
2019
2070
|
resolvedPath = tsPath;
|
|
2020
2071
|
} else {
|
|
2021
2072
|
resolvedPath = jsPath;
|
|
2022
2073
|
}
|
|
2023
|
-
|
|
2074
|
+
if (resolvedPath.endsWith(".ts")) {
|
|
2075
|
+
await ensureTsxLoader();
|
|
2076
|
+
if (!tsxLoaderRegistered) {
|
|
2077
|
+
throw new SchemaParsingError(
|
|
2078
|
+
`Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.
|
|
2079
|
+
Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)
|
|
2080
|
+
Alternatively, compile your schema files to JavaScript first.`,
|
|
2081
|
+
filePath
|
|
2082
|
+
);
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
const fileUrl = new URL(`file://${path5.resolve(resolvedPath)}`);
|
|
2024
2086
|
const module = await import(fileUrl.href);
|
|
2025
2087
|
return module;
|
|
2026
2088
|
} catch (error) {
|
|
2027
2089
|
const tsPath = `${filePath}.ts`;
|
|
2028
|
-
const isTypeScriptFile =
|
|
2090
|
+
const isTypeScriptFile = fs3.existsSync(tsPath);
|
|
2091
|
+
if (isTypeScriptFile && error instanceof SchemaParsingError) {
|
|
2092
|
+
throw error;
|
|
2093
|
+
}
|
|
2029
2094
|
if (isTypeScriptFile) {
|
|
2030
2095
|
throw new SchemaParsingError(
|
|
2031
|
-
`Failed to import TypeScript schema file.
|
|
2032
|
-
Please
|
|
2033
|
-
|
|
2034
|
-
2. Use tsx to run the migration tool (e.g., "npx tsx package/dist/cli/migrate.js status" or "tsx package/dist/cli/migrate.js status")`,
|
|
2096
|
+
`Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.
|
|
2097
|
+
Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)
|
|
2098
|
+
Alternatively, compile your schema files to JavaScript first.`,
|
|
2035
2099
|
filePath,
|
|
2036
2100
|
error
|
|
2037
2101
|
);
|
|
2038
2102
|
}
|
|
2039
2103
|
throw new SchemaParsingError(
|
|
2040
|
-
`Failed to import schema module. Make sure the schema files
|
|
2104
|
+
`Failed to import schema module. Make sure the schema files exist and are valid.`,
|
|
2041
2105
|
filePath,
|
|
2042
2106
|
error
|
|
2043
2107
|
);
|
|
2044
2108
|
}
|
|
2045
2109
|
}
|
|
2046
2110
|
function getCollectionNameFromFile(filePath) {
|
|
2047
|
-
const filename =
|
|
2111
|
+
const filename = path5.basename(filePath).replace(/\.(ts|js)$/, "");
|
|
2048
2112
|
return toCollectionName(filename);
|
|
2049
2113
|
}
|
|
2114
|
+
function extractCollectionNameFromSchema(zodSchema) {
|
|
2115
|
+
if (!zodSchema.description) {
|
|
2116
|
+
return null;
|
|
2117
|
+
}
|
|
2118
|
+
try {
|
|
2119
|
+
const metadata = JSON.parse(zodSchema.description);
|
|
2120
|
+
if (metadata.collectionName && typeof metadata.collectionName === "string") {
|
|
2121
|
+
return metadata.collectionName;
|
|
2122
|
+
}
|
|
2123
|
+
} catch {
|
|
2124
|
+
}
|
|
2125
|
+
return null;
|
|
2126
|
+
}
|
|
2050
2127
|
function extractSchemaDefinitions(module, patterns = ["Schema", "InputSchema"]) {
|
|
2051
2128
|
const result = {};
|
|
2052
2129
|
for (const [key, value] of Object.entries(module)) {
|
|
@@ -2209,7 +2286,7 @@ async function buildSchemaDefinition(config) {
|
|
|
2209
2286
|
importPath = normalizedConfig.pathTransformer(filePath);
|
|
2210
2287
|
} else if (mergedConfig.useCompiledFiles) {
|
|
2211
2288
|
const distPath = filePath.replace(/\/src\//, "/dist/");
|
|
2212
|
-
if (
|
|
2289
|
+
if (fs3.existsSync(`${distPath}.js`) || fs3.existsSync(`${distPath}.mjs`)) {
|
|
2213
2290
|
importPath = distPath;
|
|
2214
2291
|
} else {
|
|
2215
2292
|
importPath = filePath;
|
|
@@ -2222,7 +2299,8 @@ async function buildSchemaDefinition(config) {
|
|
|
2222
2299
|
console.warn(`No valid schema found in ${filePath}, skipping...`);
|
|
2223
2300
|
continue;
|
|
2224
2301
|
}
|
|
2225
|
-
const
|
|
2302
|
+
const collectionNameFromSchema = extractCollectionNameFromSchema(zodSchema);
|
|
2303
|
+
const collectionName = collectionNameFromSchema ?? getCollectionNameFromFile(filePath);
|
|
2226
2304
|
const collectionSchema = convertZodSchemaToCollectionSchema(collectionName, zodSchema);
|
|
2227
2305
|
collections.set(collectionName, collectionSchema);
|
|
2228
2306
|
} catch (error) {
|
|
@@ -2265,7 +2343,359 @@ var SchemaAnalyzer = class {
|
|
|
2265
2343
|
return convertZodSchemaToCollectionSchema(name, schema);
|
|
2266
2344
|
}
|
|
2267
2345
|
};
|
|
2346
|
+
|
|
2347
|
+
// src/migration/pocketbase-converter.ts
|
|
2268
2348
|
var SNAPSHOT_VERSION = "1.0.0";
|
|
2349
|
+
function resolveCollectionIdToName(collectionId) {
|
|
2350
|
+
if (collectionId === "_pb_users_auth_") {
|
|
2351
|
+
return "Users";
|
|
2352
|
+
}
|
|
2353
|
+
const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
2354
|
+
if (nameMatch) {
|
|
2355
|
+
return nameMatch[1];
|
|
2356
|
+
}
|
|
2357
|
+
return collectionId;
|
|
2358
|
+
}
|
|
2359
|
+
function convertPocketBaseCollection(pbCollection) {
|
|
2360
|
+
const fields = [];
|
|
2361
|
+
const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
|
|
2362
|
+
const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
|
|
2363
|
+
if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
|
|
2364
|
+
for (const pbField of pbCollection.fields) {
|
|
2365
|
+
if (pbField.system || systemFieldNames.includes(pbField.name)) {
|
|
2366
|
+
continue;
|
|
2367
|
+
}
|
|
2368
|
+
if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
|
|
2369
|
+
continue;
|
|
2370
|
+
}
|
|
2371
|
+
const field = {
|
|
2372
|
+
name: pbField.name,
|
|
2373
|
+
type: pbField.type,
|
|
2374
|
+
required: pbField.required || false
|
|
2375
|
+
};
|
|
2376
|
+
field.options = pbField.options ? { ...pbField.options } : {};
|
|
2377
|
+
if (pbField.type === "select") {
|
|
2378
|
+
if (pbField.values && Array.isArray(pbField.values)) {
|
|
2379
|
+
field.options.values = pbField.values;
|
|
2380
|
+
} else if (pbField.options?.values && Array.isArray(pbField.options.values)) {
|
|
2381
|
+
field.options.values = pbField.options.values;
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
if (pbField.type === "relation") {
|
|
2385
|
+
const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
|
|
2386
|
+
const collectionName = resolveCollectionIdToName(collectionId);
|
|
2387
|
+
field.relation = {
|
|
2388
|
+
collection: collectionName,
|
|
2389
|
+
cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,
|
|
2390
|
+
maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,
|
|
2391
|
+
minSelect: pbField.minSelect ?? pbField.options?.minSelect
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== void 0;
|
|
2395
|
+
if (Object.keys(field.options).length === 0) {
|
|
2396
|
+
delete field.options;
|
|
2397
|
+
} else if (pbField.type === "select" && hasOnlyValues) ;
|
|
2398
|
+
fields.push(field);
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
const schema = {
|
|
2402
|
+
name: pbCollection.name,
|
|
2403
|
+
type: pbCollection.type || "base",
|
|
2404
|
+
fields
|
|
2405
|
+
};
|
|
2406
|
+
if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
|
|
2407
|
+
schema.indexes = pbCollection.indexes;
|
|
2408
|
+
}
|
|
2409
|
+
const rules = {};
|
|
2410
|
+
if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
|
|
2411
|
+
if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
|
|
2412
|
+
if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
|
|
2413
|
+
if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
|
|
2414
|
+
if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
|
|
2415
|
+
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
2416
|
+
if (Object.keys(rules).length > 0) {
|
|
2417
|
+
schema.rules = rules;
|
|
2418
|
+
schema.permissions = { ...rules };
|
|
2419
|
+
}
|
|
2420
|
+
return schema;
|
|
2421
|
+
}
|
|
2422
|
+
function convertPocketBaseMigration(migrationContent) {
|
|
2423
|
+
try {
|
|
2424
|
+
const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
|
|
2425
|
+
if (!snapshotMatch) {
|
|
2426
|
+
throw new Error("Could not find snapshot array in migration file");
|
|
2427
|
+
}
|
|
2428
|
+
const snapshotArrayStr = snapshotMatch[1];
|
|
2429
|
+
let snapshotArray;
|
|
2430
|
+
try {
|
|
2431
|
+
snapshotArray = new Function(`return ${snapshotArrayStr}`)();
|
|
2432
|
+
} catch (parseError) {
|
|
2433
|
+
throw new Error(`Failed to parse snapshot array: ${parseError}`);
|
|
2434
|
+
}
|
|
2435
|
+
if (!Array.isArray(snapshotArray)) {
|
|
2436
|
+
throw new Error("Snapshot is not an array");
|
|
2437
|
+
}
|
|
2438
|
+
const collections = /* @__PURE__ */ new Map();
|
|
2439
|
+
for (const pbCollection of snapshotArray) {
|
|
2440
|
+
if (!pbCollection.name) {
|
|
2441
|
+
console.warn("Skipping collection without name");
|
|
2442
|
+
continue;
|
|
2443
|
+
}
|
|
2444
|
+
const schema = convertPocketBaseCollection(pbCollection);
|
|
2445
|
+
collections.set(pbCollection.name, schema);
|
|
2446
|
+
}
|
|
2447
|
+
return {
|
|
2448
|
+
version: SNAPSHOT_VERSION,
|
|
2449
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2450
|
+
collections
|
|
2451
|
+
};
|
|
2452
|
+
} catch (error) {
|
|
2453
|
+
throw new SnapshotError(
|
|
2454
|
+
`Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
2455
|
+
void 0,
|
|
2456
|
+
"parse",
|
|
2457
|
+
error instanceof Error ? error : void 0
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
// src/migration/migration-parser.ts
|
|
2463
|
+
function extractTimestampFromFilename(filename) {
|
|
2464
|
+
const match = filename.match(/^(\d+)_/);
|
|
2465
|
+
if (match) {
|
|
2466
|
+
return parseInt(match[1], 10);
|
|
2467
|
+
}
|
|
2468
|
+
return null;
|
|
2469
|
+
}
|
|
2470
|
+
function findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp) {
|
|
2471
|
+
try {
|
|
2472
|
+
if (!fs3.existsSync(migrationsPath)) {
|
|
2473
|
+
return [];
|
|
2474
|
+
}
|
|
2475
|
+
const files = fs3.readdirSync(migrationsPath);
|
|
2476
|
+
const migrationFiles = [];
|
|
2477
|
+
for (const file of files) {
|
|
2478
|
+
if (file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")) {
|
|
2479
|
+
continue;
|
|
2480
|
+
}
|
|
2481
|
+
if (!file.endsWith(".js")) {
|
|
2482
|
+
continue;
|
|
2483
|
+
}
|
|
2484
|
+
const timestamp = extractTimestampFromFilename(file);
|
|
2485
|
+
if (timestamp && timestamp > snapshotTimestamp) {
|
|
2486
|
+
migrationFiles.push({
|
|
2487
|
+
path: path5.join(migrationsPath, file),
|
|
2488
|
+
timestamp
|
|
2489
|
+
});
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
migrationFiles.sort((a, b) => a.timestamp - b.timestamp);
|
|
2493
|
+
return migrationFiles.map((f) => f.path);
|
|
2494
|
+
} catch (error) {
|
|
2495
|
+
console.warn(`Error finding migrations after snapshot: ${error}`);
|
|
2496
|
+
return [];
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
function parseMigrationOperationsFromContent(content) {
|
|
2500
|
+
const collectionsToCreate = [];
|
|
2501
|
+
const collectionsToDelete = [];
|
|
2502
|
+
try {
|
|
2503
|
+
let searchIndex = 0;
|
|
2504
|
+
while (true) {
|
|
2505
|
+
const collectionStart = content.indexOf("new Collection(", searchIndex);
|
|
2506
|
+
if (collectionStart === -1) {
|
|
2507
|
+
break;
|
|
2508
|
+
}
|
|
2509
|
+
const openParen = collectionStart + "new Collection(".length;
|
|
2510
|
+
let braceCount = 0;
|
|
2511
|
+
let parenCount = 1;
|
|
2512
|
+
let inString = false;
|
|
2513
|
+
let stringChar = null;
|
|
2514
|
+
let i = openParen;
|
|
2515
|
+
while (i < content.length && /\s/.test(content[i])) {
|
|
2516
|
+
i++;
|
|
2517
|
+
}
|
|
2518
|
+
if (content[i] !== "{") {
|
|
2519
|
+
searchIndex = i + 1;
|
|
2520
|
+
continue;
|
|
2521
|
+
}
|
|
2522
|
+
const objectStart = i;
|
|
2523
|
+
braceCount = 1;
|
|
2524
|
+
i++;
|
|
2525
|
+
while (i < content.length && (braceCount > 0 || parenCount > 0)) {
|
|
2526
|
+
const char = content[i];
|
|
2527
|
+
const prevChar = i > 0 ? content[i - 1] : "";
|
|
2528
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2529
|
+
inString = true;
|
|
2530
|
+
stringChar = char;
|
|
2531
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2532
|
+
inString = false;
|
|
2533
|
+
stringChar = null;
|
|
2534
|
+
}
|
|
2535
|
+
if (!inString) {
|
|
2536
|
+
if (char === "{") braceCount++;
|
|
2537
|
+
if (char === "}") braceCount--;
|
|
2538
|
+
if (char === "(") parenCount++;
|
|
2539
|
+
if (char === ")") parenCount--;
|
|
2540
|
+
}
|
|
2541
|
+
i++;
|
|
2542
|
+
}
|
|
2543
|
+
if (braceCount === 0 && parenCount === 0) {
|
|
2544
|
+
const objectContent = content.substring(objectStart, i - 1);
|
|
2545
|
+
try {
|
|
2546
|
+
const collectionObj = new Function(`return ${objectContent}`)();
|
|
2547
|
+
if (collectionObj && collectionObj.name) {
|
|
2548
|
+
const schema = convertPocketBaseCollection(collectionObj);
|
|
2549
|
+
collectionsToCreate.push(schema);
|
|
2550
|
+
}
|
|
2551
|
+
} catch (error) {
|
|
2552
|
+
console.warn(`Failed to parse collection definition: ${error}`);
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
searchIndex = i;
|
|
2556
|
+
}
|
|
2557
|
+
const deleteMatches = content.matchAll(
|
|
2558
|
+
/app\.delete\s*\(\s*(?:collection_\w+|app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\))\s*\)/g
|
|
2559
|
+
);
|
|
2560
|
+
for (const match of deleteMatches) {
|
|
2561
|
+
if (match[1]) {
|
|
2562
|
+
collectionsToDelete.push(match[1]);
|
|
2563
|
+
} else {
|
|
2564
|
+
const varNameMatch = match[0].match(/collection_(\w+)/);
|
|
2565
|
+
if (varNameMatch) {
|
|
2566
|
+
const varName = `collection_${varNameMatch[1]}`;
|
|
2567
|
+
const deleteIndex = content.indexOf(match[0]);
|
|
2568
|
+
const beforeDelete = content.substring(0, deleteIndex);
|
|
2569
|
+
const varDefMatch = beforeDelete.match(
|
|
2570
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`, "g")
|
|
2571
|
+
);
|
|
2572
|
+
if (varDefMatch && varDefMatch.length > 0) {
|
|
2573
|
+
const collectionDefMatch = beforeDelete.match(
|
|
2574
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`)
|
|
2575
|
+
);
|
|
2576
|
+
if (collectionDefMatch) {
|
|
2577
|
+
try {
|
|
2578
|
+
const collectionDefStr = collectionDefMatch[1];
|
|
2579
|
+
const collectionObj = new Function(`return ${collectionDefStr}`)();
|
|
2580
|
+
if (collectionObj && collectionObj.name) {
|
|
2581
|
+
collectionsToDelete.push(collectionObj.name);
|
|
2582
|
+
}
|
|
2583
|
+
} catch {
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
const findAndDeleteMatches = content.matchAll(
|
|
2591
|
+
/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)[\s\S]*?app\.delete/g
|
|
2592
|
+
);
|
|
2593
|
+
for (const match of findAndDeleteMatches) {
|
|
2594
|
+
collectionsToDelete.push(match[1]);
|
|
2595
|
+
}
|
|
2596
|
+
} catch (error) {
|
|
2597
|
+
console.warn(`Failed to parse migration operations from content: ${error}`);
|
|
2598
|
+
}
|
|
2599
|
+
return { collectionsToCreate, collectionsToDelete };
|
|
2600
|
+
}
|
|
2601
|
+
function parseMigrationOperations(migrationContent) {
|
|
2602
|
+
try {
|
|
2603
|
+
const migrateMatch = migrationContent.match(/migrate\s*\(\s*/);
|
|
2604
|
+
if (!migrateMatch) {
|
|
2605
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2606
|
+
}
|
|
2607
|
+
const startIndex = migrateMatch.index + migrateMatch[0].length;
|
|
2608
|
+
let i = startIndex;
|
|
2609
|
+
let parenCount = 0;
|
|
2610
|
+
let foundFirstParen = false;
|
|
2611
|
+
while (i < migrationContent.length) {
|
|
2612
|
+
const char = migrationContent[i];
|
|
2613
|
+
if (char === "(") {
|
|
2614
|
+
parenCount++;
|
|
2615
|
+
foundFirstParen = true;
|
|
2616
|
+
i++;
|
|
2617
|
+
break;
|
|
2618
|
+
}
|
|
2619
|
+
i++;
|
|
2620
|
+
}
|
|
2621
|
+
if (!foundFirstParen) {
|
|
2622
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2623
|
+
}
|
|
2624
|
+
let inString = false;
|
|
2625
|
+
let stringChar = null;
|
|
2626
|
+
let foundBrace = false;
|
|
2627
|
+
let braceStart = -1;
|
|
2628
|
+
while (i < migrationContent.length && !foundBrace) {
|
|
2629
|
+
const char = migrationContent[i];
|
|
2630
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
2631
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2632
|
+
inString = true;
|
|
2633
|
+
stringChar = char;
|
|
2634
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2635
|
+
inString = false;
|
|
2636
|
+
stringChar = null;
|
|
2637
|
+
}
|
|
2638
|
+
if (!inString) {
|
|
2639
|
+
if (char === "(") parenCount++;
|
|
2640
|
+
if (char === ")") {
|
|
2641
|
+
parenCount--;
|
|
2642
|
+
if (parenCount === 0) {
|
|
2643
|
+
i++;
|
|
2644
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
2645
|
+
i++;
|
|
2646
|
+
}
|
|
2647
|
+
if (i < migrationContent.length - 1 && migrationContent[i] === "=" && migrationContent[i + 1] === ">") {
|
|
2648
|
+
i += 2;
|
|
2649
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
2650
|
+
i++;
|
|
2651
|
+
}
|
|
2652
|
+
if (i < migrationContent.length && migrationContent[i] === "{") {
|
|
2653
|
+
foundBrace = true;
|
|
2654
|
+
braceStart = i + 1;
|
|
2655
|
+
break;
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
i++;
|
|
2662
|
+
}
|
|
2663
|
+
if (!foundBrace || braceStart === -1) {
|
|
2664
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2665
|
+
}
|
|
2666
|
+
let braceCount = 1;
|
|
2667
|
+
i = braceStart;
|
|
2668
|
+
inString = false;
|
|
2669
|
+
stringChar = null;
|
|
2670
|
+
while (i < migrationContent.length && braceCount > 0) {
|
|
2671
|
+
const char = migrationContent[i];
|
|
2672
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
2673
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2674
|
+
inString = true;
|
|
2675
|
+
stringChar = char;
|
|
2676
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2677
|
+
inString = false;
|
|
2678
|
+
stringChar = null;
|
|
2679
|
+
}
|
|
2680
|
+
if (!inString) {
|
|
2681
|
+
if (char === "{") braceCount++;
|
|
2682
|
+
if (char === "}") braceCount--;
|
|
2683
|
+
}
|
|
2684
|
+
i++;
|
|
2685
|
+
}
|
|
2686
|
+
if (braceCount === 0) {
|
|
2687
|
+
const upMigrationContent = migrationContent.substring(braceStart, i - 1);
|
|
2688
|
+
return parseMigrationOperationsFromContent(upMigrationContent);
|
|
2689
|
+
}
|
|
2690
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2691
|
+
} catch (error) {
|
|
2692
|
+
console.warn(`Failed to parse migration operations: ${error}`);
|
|
2693
|
+
return { collectionsToCreate: [], collectionsToDelete: [] };
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
// src/migration/snapshot.ts
|
|
2698
|
+
var SNAPSHOT_VERSION2 = "1.0.0";
|
|
2269
2699
|
var DEFAULT_SNAPSHOT_FILENAME = ".migration-snapshot.json";
|
|
2270
2700
|
var SNAPSHOT_MIGRATIONS = [
|
|
2271
2701
|
// Add migrations here as the format evolves
|
|
@@ -2280,7 +2710,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
2280
2710
|
snapshotPath: DEFAULT_SNAPSHOT_FILENAME,
|
|
2281
2711
|
workspaceRoot: process.cwd(),
|
|
2282
2712
|
autoMigrate: true,
|
|
2283
|
-
version:
|
|
2713
|
+
version: SNAPSHOT_VERSION2
|
|
2284
2714
|
};
|
|
2285
2715
|
function mergeConfig2(config = {}) {
|
|
2286
2716
|
return {
|
|
@@ -2292,15 +2722,15 @@ function getSnapshotPath(config = {}) {
|
|
|
2292
2722
|
const mergedConfig = mergeConfig2(config);
|
|
2293
2723
|
const workspaceRoot = mergedConfig.workspaceRoot;
|
|
2294
2724
|
const snapshotFilename = mergedConfig.snapshotPath;
|
|
2295
|
-
if (
|
|
2725
|
+
if (path5.isAbsolute(snapshotFilename)) {
|
|
2296
2726
|
return snapshotFilename;
|
|
2297
2727
|
}
|
|
2298
|
-
return
|
|
2728
|
+
return path5.join(workspaceRoot, snapshotFilename);
|
|
2299
2729
|
}
|
|
2300
2730
|
function snapshotExists(config = {}) {
|
|
2301
2731
|
try {
|
|
2302
2732
|
const snapshotPath = getSnapshotPath(config);
|
|
2303
|
-
return
|
|
2733
|
+
return fs3.existsSync(snapshotPath);
|
|
2304
2734
|
} catch {
|
|
2305
2735
|
return false;
|
|
2306
2736
|
}
|
|
@@ -2359,13 +2789,13 @@ function addSnapshotMetadata(schema, config) {
|
|
|
2359
2789
|
function saveSnapshot(schema, config = {}) {
|
|
2360
2790
|
const snapshotPath = getSnapshotPath(config);
|
|
2361
2791
|
try {
|
|
2362
|
-
const snapshotDir =
|
|
2363
|
-
if (!
|
|
2364
|
-
|
|
2792
|
+
const snapshotDir = path5.dirname(snapshotPath);
|
|
2793
|
+
if (!fs3.existsSync(snapshotDir)) {
|
|
2794
|
+
fs3.mkdirSync(snapshotDir, { recursive: true });
|
|
2365
2795
|
}
|
|
2366
2796
|
const snapshotData = addSnapshotMetadata(schema, config);
|
|
2367
2797
|
const jsonContent = JSON.stringify(snapshotData, null, 2);
|
|
2368
|
-
|
|
2798
|
+
fs3.writeFileSync(snapshotPath, jsonContent, "utf-8");
|
|
2369
2799
|
} catch (error) {
|
|
2370
2800
|
handleFileSystemError(error, "write", snapshotPath);
|
|
2371
2801
|
}
|
|
@@ -2460,7 +2890,7 @@ function deserializeSnapshot(data) {
|
|
|
2460
2890
|
function loadSnapshot(config = {}) {
|
|
2461
2891
|
const snapshotPath = getSnapshotPath(config);
|
|
2462
2892
|
try {
|
|
2463
|
-
const jsonContent =
|
|
2893
|
+
const jsonContent = fs3.readFileSync(snapshotPath, "utf-8");
|
|
2464
2894
|
const data = parseAndValidateSnapshot(jsonContent, snapshotPath);
|
|
2465
2895
|
const migratedData = migrateSnapshotFormat(data, config);
|
|
2466
2896
|
return deserializeSnapshot(migratedData);
|
|
@@ -2495,10 +2925,10 @@ function mergeSnapshots(baseSnapshot, customSnapshot) {
|
|
|
2495
2925
|
}
|
|
2496
2926
|
function findLatestSnapshot(migrationsPath) {
|
|
2497
2927
|
try {
|
|
2498
|
-
if (!
|
|
2928
|
+
if (!fs3.existsSync(migrationsPath)) {
|
|
2499
2929
|
return null;
|
|
2500
2930
|
}
|
|
2501
|
-
const files =
|
|
2931
|
+
const files = fs3.readdirSync(migrationsPath);
|
|
2502
2932
|
const snapshotFiles = files.filter(
|
|
2503
2933
|
(file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
|
|
2504
2934
|
);
|
|
@@ -2510,20 +2940,74 @@ function findLatestSnapshot(migrationsPath) {
|
|
|
2510
2940
|
if (!latestSnapshot) {
|
|
2511
2941
|
return null;
|
|
2512
2942
|
}
|
|
2513
|
-
return
|
|
2943
|
+
return path5.join(migrationsPath, latestSnapshot);
|
|
2514
2944
|
} catch (error) {
|
|
2515
2945
|
console.warn(`Error finding latest snapshot: ${error}`);
|
|
2516
2946
|
return null;
|
|
2517
2947
|
}
|
|
2518
2948
|
}
|
|
2949
|
+
function applyMigrationOperations(snapshot, operations) {
|
|
2950
|
+
const updatedCollections = new Map(snapshot.collections);
|
|
2951
|
+
for (const collectionName of operations.collectionsToDelete) {
|
|
2952
|
+
updatedCollections.delete(collectionName);
|
|
2953
|
+
}
|
|
2954
|
+
for (const collection of operations.collectionsToCreate) {
|
|
2955
|
+
updatedCollections.set(collection.name, collection);
|
|
2956
|
+
}
|
|
2957
|
+
return {
|
|
2958
|
+
...snapshot,
|
|
2959
|
+
collections: updatedCollections
|
|
2960
|
+
};
|
|
2961
|
+
}
|
|
2962
|
+
function loadSnapshotWithMigrations(config = {}) {
|
|
2963
|
+
const migrationsPath = config.migrationsPath;
|
|
2964
|
+
if (!migrationsPath) {
|
|
2965
|
+
return null;
|
|
2966
|
+
}
|
|
2967
|
+
if (fs3.existsSync(migrationsPath) && fs3.statSync(migrationsPath).isFile()) {
|
|
2968
|
+
try {
|
|
2969
|
+
const migrationContent = fs3.readFileSync(migrationsPath, "utf-8");
|
|
2970
|
+
return convertPocketBaseMigration(migrationContent);
|
|
2971
|
+
} catch (error) {
|
|
2972
|
+
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
2973
|
+
return null;
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
2977
|
+
if (!latestSnapshotPath) {
|
|
2978
|
+
return null;
|
|
2979
|
+
}
|
|
2980
|
+
try {
|
|
2981
|
+
const migrationContent = fs3.readFileSync(latestSnapshotPath, "utf-8");
|
|
2982
|
+
let snapshot = convertPocketBaseMigration(migrationContent);
|
|
2983
|
+
const snapshotFilename = path5.basename(latestSnapshotPath);
|
|
2984
|
+
const snapshotTimestamp = extractTimestampFromFilename(snapshotFilename);
|
|
2985
|
+
if (snapshotTimestamp) {
|
|
2986
|
+
const migrationFiles = findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp);
|
|
2987
|
+
for (const migrationFile of migrationFiles) {
|
|
2988
|
+
try {
|
|
2989
|
+
const migrationContent2 = fs3.readFileSync(migrationFile, "utf-8");
|
|
2990
|
+
const operations = parseMigrationOperations(migrationContent2);
|
|
2991
|
+
snapshot = applyMigrationOperations(snapshot, operations);
|
|
2992
|
+
} catch (error) {
|
|
2993
|
+
console.warn(`Failed to apply migration ${migrationFile}: ${error}`);
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
return snapshot;
|
|
2998
|
+
} catch (error) {
|
|
2999
|
+
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
3000
|
+
return null;
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
2519
3003
|
function loadSnapshotIfExists(config = {}) {
|
|
2520
3004
|
const migrationsPath = config.migrationsPath;
|
|
2521
3005
|
if (!migrationsPath) {
|
|
2522
3006
|
return null;
|
|
2523
3007
|
}
|
|
2524
|
-
if (
|
|
3008
|
+
if (fs3.existsSync(migrationsPath) && fs3.statSync(migrationsPath).isFile()) {
|
|
2525
3009
|
try {
|
|
2526
|
-
const migrationContent =
|
|
3010
|
+
const migrationContent = fs3.readFileSync(migrationsPath, "utf-8");
|
|
2527
3011
|
return convertPocketBaseMigration(migrationContent);
|
|
2528
3012
|
} catch (error) {
|
|
2529
3013
|
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
@@ -2533,7 +3017,7 @@ function loadSnapshotIfExists(config = {}) {
|
|
|
2533
3017
|
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
2534
3018
|
if (latestSnapshotPath) {
|
|
2535
3019
|
try {
|
|
2536
|
-
const migrationContent =
|
|
3020
|
+
const migrationContent = fs3.readFileSync(latestSnapshotPath, "utf-8");
|
|
2537
3021
|
return convertPocketBaseMigration(migrationContent);
|
|
2538
3022
|
} catch (error) {
|
|
2539
3023
|
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
@@ -2542,100 +3026,9 @@ function loadSnapshotIfExists(config = {}) {
|
|
|
2542
3026
|
}
|
|
2543
3027
|
return null;
|
|
2544
3028
|
}
|
|
2545
|
-
function convertPocketBaseCollection(pbCollection) {
|
|
2546
|
-
const fields = [];
|
|
2547
|
-
const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
|
|
2548
|
-
const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
|
|
2549
|
-
if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
|
|
2550
|
-
for (const pbField of pbCollection.fields) {
|
|
2551
|
-
if (pbField.system || systemFieldNames.includes(pbField.name)) {
|
|
2552
|
-
continue;
|
|
2553
|
-
}
|
|
2554
|
-
if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
|
|
2555
|
-
continue;
|
|
2556
|
-
}
|
|
2557
|
-
const field = {
|
|
2558
|
-
name: pbField.name,
|
|
2559
|
-
type: pbField.type,
|
|
2560
|
-
required: pbField.required || false
|
|
2561
|
-
};
|
|
2562
|
-
if (pbField.options) {
|
|
2563
|
-
field.options = pbField.options;
|
|
2564
|
-
}
|
|
2565
|
-
if (pbField.type === "relation") {
|
|
2566
|
-
field.relation = {
|
|
2567
|
-
collection: pbField.options?.collectionId || "",
|
|
2568
|
-
cascadeDelete: pbField.options?.cascadeDelete || false,
|
|
2569
|
-
maxSelect: pbField.options?.maxSelect,
|
|
2570
|
-
minSelect: pbField.options?.minSelect
|
|
2571
|
-
};
|
|
2572
|
-
}
|
|
2573
|
-
fields.push(field);
|
|
2574
|
-
}
|
|
2575
|
-
}
|
|
2576
|
-
const schema = {
|
|
2577
|
-
name: pbCollection.name,
|
|
2578
|
-
type: pbCollection.type || "base",
|
|
2579
|
-
fields
|
|
2580
|
-
};
|
|
2581
|
-
if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
|
|
2582
|
-
schema.indexes = pbCollection.indexes;
|
|
2583
|
-
}
|
|
2584
|
-
const rules = {};
|
|
2585
|
-
if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
|
|
2586
|
-
if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
|
|
2587
|
-
if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
|
|
2588
|
-
if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
|
|
2589
|
-
if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
|
|
2590
|
-
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
2591
|
-
if (Object.keys(rules).length > 0) {
|
|
2592
|
-
schema.rules = rules;
|
|
2593
|
-
schema.permissions = { ...rules };
|
|
2594
|
-
}
|
|
2595
|
-
return schema;
|
|
2596
|
-
}
|
|
2597
|
-
function convertPocketBaseMigration(migrationContent) {
|
|
2598
|
-
try {
|
|
2599
|
-
const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
|
|
2600
|
-
if (!snapshotMatch) {
|
|
2601
|
-
throw new Error("Could not find snapshot array in migration file");
|
|
2602
|
-
}
|
|
2603
|
-
const snapshotArrayStr = snapshotMatch[1];
|
|
2604
|
-
let snapshotArray;
|
|
2605
|
-
try {
|
|
2606
|
-
snapshotArray = new Function(`return ${snapshotArrayStr}`)();
|
|
2607
|
-
} catch (parseError) {
|
|
2608
|
-
throw new Error(`Failed to parse snapshot array: ${parseError}`);
|
|
2609
|
-
}
|
|
2610
|
-
if (!Array.isArray(snapshotArray)) {
|
|
2611
|
-
throw new Error("Snapshot is not an array");
|
|
2612
|
-
}
|
|
2613
|
-
const collections = /* @__PURE__ */ new Map();
|
|
2614
|
-
for (const pbCollection of snapshotArray) {
|
|
2615
|
-
if (!pbCollection.name) {
|
|
2616
|
-
console.warn("Skipping collection without name");
|
|
2617
|
-
continue;
|
|
2618
|
-
}
|
|
2619
|
-
const schema = convertPocketBaseCollection(pbCollection);
|
|
2620
|
-
collections.set(pbCollection.name, schema);
|
|
2621
|
-
}
|
|
2622
|
-
return {
|
|
2623
|
-
version: SNAPSHOT_VERSION,
|
|
2624
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2625
|
-
collections
|
|
2626
|
-
};
|
|
2627
|
-
} catch (error) {
|
|
2628
|
-
throw new SnapshotError(
|
|
2629
|
-
`Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
2630
|
-
void 0,
|
|
2631
|
-
"parse",
|
|
2632
|
-
error instanceof Error ? error : void 0
|
|
2633
|
-
);
|
|
2634
|
-
}
|
|
2635
|
-
}
|
|
2636
3029
|
function loadBaseMigration(migrationPath) {
|
|
2637
3030
|
try {
|
|
2638
|
-
if (!
|
|
3031
|
+
if (!fs3.existsSync(migrationPath)) {
|
|
2639
3032
|
throw new SnapshotError(
|
|
2640
3033
|
`Base migration file not found: ${migrationPath}
|
|
2641
3034
|
|
|
@@ -2646,7 +3039,7 @@ If the file exists in a different location, update the configuration.`,
|
|
|
2646
3039
|
"read"
|
|
2647
3040
|
);
|
|
2648
3041
|
}
|
|
2649
|
-
const migrationContent =
|
|
3042
|
+
const migrationContent = fs3.readFileSync(migrationPath, "utf-8");
|
|
2650
3043
|
const snapshot = convertPocketBaseMigration(migrationContent);
|
|
2651
3044
|
return snapshot;
|
|
2652
3045
|
} catch (error) {
|
|
@@ -2682,14 +3075,14 @@ Please ensure PocketBase is properly set up by running 'yarn setup'.`,
|
|
|
2682
3075
|
}
|
|
2683
3076
|
}
|
|
2684
3077
|
function getSnapshotVersion() {
|
|
2685
|
-
return
|
|
3078
|
+
return SNAPSHOT_VERSION2;
|
|
2686
3079
|
}
|
|
2687
3080
|
function validateSnapshot(snapshot) {
|
|
2688
3081
|
const issues = [];
|
|
2689
3082
|
if (!snapshot.version) {
|
|
2690
3083
|
issues.push("Missing version field");
|
|
2691
|
-
} else if (compareVersions(snapshot.version,
|
|
2692
|
-
issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${
|
|
3084
|
+
} else if (compareVersions(snapshot.version, SNAPSHOT_VERSION2) > 0) {
|
|
3085
|
+
issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION2}`);
|
|
2693
3086
|
}
|
|
2694
3087
|
if (!snapshot.timestamp) {
|
|
2695
3088
|
issues.push("Missing timestamp field");
|
|
@@ -2908,6 +3301,9 @@ function compareFieldOptions(currentField, previousField) {
|
|
|
2908
3301
|
for (const key of allKeys) {
|
|
2909
3302
|
const currentValue = currentOptions[key];
|
|
2910
3303
|
const previousValue = previousOptions[key];
|
|
3304
|
+
if (currentValue === void 0 && previousValue === void 0) {
|
|
3305
|
+
continue;
|
|
3306
|
+
}
|
|
2911
3307
|
if (!areValuesEqual(currentValue, previousValue)) {
|
|
2912
3308
|
changes.push({
|
|
2913
3309
|
property: `options.${key}`,
|
|
@@ -2928,11 +3324,26 @@ function compareRelationConfigurations(currentField, previousField) {
|
|
|
2928
3324
|
if (!currentRelation || !previousRelation) {
|
|
2929
3325
|
return changes;
|
|
2930
3326
|
}
|
|
2931
|
-
|
|
3327
|
+
const normalizeCollection = (collection) => {
|
|
3328
|
+
if (!collection) return collection;
|
|
3329
|
+
if (collection === "_pb_users_auth_") {
|
|
3330
|
+
return "Users";
|
|
3331
|
+
}
|
|
3332
|
+
const nameMatch = collection.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
3333
|
+
if (nameMatch) {
|
|
3334
|
+
return nameMatch[1];
|
|
3335
|
+
}
|
|
3336
|
+
return collection;
|
|
3337
|
+
};
|
|
3338
|
+
const normalizedCurrent = normalizeCollection(currentRelation.collection);
|
|
3339
|
+
const normalizedPrevious = normalizeCollection(previousRelation.collection);
|
|
3340
|
+
if (normalizedCurrent !== normalizedPrevious) {
|
|
2932
3341
|
changes.push({
|
|
2933
3342
|
property: "relation.collection",
|
|
2934
|
-
oldValue:
|
|
2935
|
-
|
|
3343
|
+
oldValue: normalizedPrevious,
|
|
3344
|
+
// Use normalized value for clarity
|
|
3345
|
+
newValue: normalizedCurrent
|
|
3346
|
+
// Use normalized value for clarity
|
|
2936
3347
|
});
|
|
2937
3348
|
}
|
|
2938
3349
|
if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
|
|
@@ -3305,10 +3716,10 @@ function mergeConfig4(config) {
|
|
|
3305
3716
|
}
|
|
3306
3717
|
function resolveMigrationDir(config) {
|
|
3307
3718
|
const workspaceRoot = config.workspaceRoot || process.cwd();
|
|
3308
|
-
if (
|
|
3719
|
+
if (path5.isAbsolute(config.migrationDir)) {
|
|
3309
3720
|
return config.migrationDir;
|
|
3310
3721
|
}
|
|
3311
|
-
return
|
|
3722
|
+
return path5.join(workspaceRoot, config.migrationDir);
|
|
3312
3723
|
}
|
|
3313
3724
|
function generateTimestamp(config) {
|
|
3314
3725
|
if (config?.timestampGenerator) {
|
|
@@ -3366,9 +3777,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
|
|
|
3366
3777
|
}
|
|
3367
3778
|
function writeMigrationFile(migrationDir, filename, content) {
|
|
3368
3779
|
try {
|
|
3369
|
-
if (!
|
|
3780
|
+
if (!fs3.existsSync(migrationDir)) {
|
|
3370
3781
|
try {
|
|
3371
|
-
|
|
3782
|
+
fs3.mkdirSync(migrationDir, { recursive: true });
|
|
3372
3783
|
} catch (error) {
|
|
3373
3784
|
const fsError = error;
|
|
3374
3785
|
if (fsError.code === "EACCES" || fsError.code === "EPERM") {
|
|
@@ -3389,15 +3800,15 @@ function writeMigrationFile(migrationDir, filename, content) {
|
|
|
3389
3800
|
);
|
|
3390
3801
|
}
|
|
3391
3802
|
}
|
|
3392
|
-
const filePath =
|
|
3393
|
-
|
|
3803
|
+
const filePath = path5.join(migrationDir, filename);
|
|
3804
|
+
fs3.writeFileSync(filePath, content, "utf-8");
|
|
3394
3805
|
return filePath;
|
|
3395
3806
|
} catch (error) {
|
|
3396
3807
|
if (error instanceof FileSystemError) {
|
|
3397
3808
|
throw error;
|
|
3398
3809
|
}
|
|
3399
3810
|
const fsError = error;
|
|
3400
|
-
const filePath =
|
|
3811
|
+
const filePath = path5.join(migrationDir, filename);
|
|
3401
3812
|
if (fsError.code === "EACCES" || fsError.code === "EPERM") {
|
|
3402
3813
|
throw new FileSystemError(
|
|
3403
3814
|
`Permission denied writing migration file. Check file and directory permissions.`,
|
|
@@ -4141,8 +4552,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
4141
4552
|
};
|
|
4142
4553
|
function findConfigFile(directory) {
|
|
4143
4554
|
for (const fileName of CONFIG_FILE_NAMES) {
|
|
4144
|
-
const filePath =
|
|
4145
|
-
if (
|
|
4555
|
+
const filePath = path5.join(directory, fileName);
|
|
4556
|
+
if (fs3.existsSync(filePath)) {
|
|
4146
4557
|
return filePath;
|
|
4147
4558
|
}
|
|
4148
4559
|
}
|
|
@@ -4150,7 +4561,7 @@ function findConfigFile(directory) {
|
|
|
4150
4561
|
}
|
|
4151
4562
|
function loadJsonConfig(configPath) {
|
|
4152
4563
|
try {
|
|
4153
|
-
const content =
|
|
4564
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
4154
4565
|
return JSON.parse(content);
|
|
4155
4566
|
} catch (error) {
|
|
4156
4567
|
if (error instanceof SyntaxError) {
|
|
@@ -4179,10 +4590,10 @@ async function loadJsConfig(configPath) {
|
|
|
4179
4590
|
}
|
|
4180
4591
|
}
|
|
4181
4592
|
async function loadConfigFile(configPath) {
|
|
4182
|
-
if (!
|
|
4593
|
+
if (!fs3.existsSync(configPath)) {
|
|
4183
4594
|
return null;
|
|
4184
4595
|
}
|
|
4185
|
-
const ext =
|
|
4596
|
+
const ext = path5.extname(configPath).toLowerCase();
|
|
4186
4597
|
if (ext === ".json") {
|
|
4187
4598
|
return loadJsonConfig(configPath);
|
|
4188
4599
|
} else if (ext === ".js" || ext === ".mjs") {
|
|
@@ -4249,10 +4660,10 @@ function validateConfig(config, configPath) {
|
|
|
4249
4660
|
}
|
|
4250
4661
|
const cwd = process.cwd();
|
|
4251
4662
|
const possiblePaths = [
|
|
4252
|
-
|
|
4253
|
-
|
|
4663
|
+
path5.resolve(cwd, config.schema.directory),
|
|
4664
|
+
path5.resolve(cwd, "shared", config.schema.directory)
|
|
4254
4665
|
];
|
|
4255
|
-
const schemaDir = possiblePaths.find((p) =>
|
|
4666
|
+
const schemaDir = possiblePaths.find((p) => fs3.existsSync(p));
|
|
4256
4667
|
if (!schemaDir) {
|
|
4257
4668
|
throw new ConfigurationError(`Schema directory not found. Tried: ${possiblePaths.join(", ")}`, configPath, [
|
|
4258
4669
|
"schema.directory"
|
|
@@ -4264,15 +4675,15 @@ async function loadConfig(options = {}) {
|
|
|
4264
4675
|
let configFilePath;
|
|
4265
4676
|
const cwd = process.cwd();
|
|
4266
4677
|
if (options.config) {
|
|
4267
|
-
const explicitPath =
|
|
4268
|
-
if (!
|
|
4678
|
+
const explicitPath = path5.resolve(cwd, options.config);
|
|
4679
|
+
if (!fs3.existsSync(explicitPath)) {
|
|
4269
4680
|
throw new ConfigurationError(`Configuration file not found: ${explicitPath}`, explicitPath);
|
|
4270
4681
|
}
|
|
4271
4682
|
configFilePath = explicitPath;
|
|
4272
4683
|
} else {
|
|
4273
|
-
const searchDirs = [cwd,
|
|
4684
|
+
const searchDirs = [cwd, path5.join(cwd, "shared")];
|
|
4274
4685
|
for (const dir of searchDirs) {
|
|
4275
|
-
if (
|
|
4686
|
+
if (fs3.existsSync(dir)) {
|
|
4276
4687
|
const found = findConfigFile(dir);
|
|
4277
4688
|
if (found) {
|
|
4278
4689
|
configFilePath = found;
|
|
@@ -4301,18 +4712,18 @@ async function loadConfig(options = {}) {
|
|
|
4301
4712
|
function getSchemaDirectory(config) {
|
|
4302
4713
|
const cwd = process.cwd();
|
|
4303
4714
|
const possiblePaths = [
|
|
4304
|
-
|
|
4305
|
-
|
|
4715
|
+
path5.resolve(cwd, config.schema.directory),
|
|
4716
|
+
path5.resolve(cwd, "shared", config.schema.directory)
|
|
4306
4717
|
];
|
|
4307
|
-
return possiblePaths.find((p) =>
|
|
4718
|
+
return possiblePaths.find((p) => fs3.existsSync(p)) || possiblePaths[0];
|
|
4308
4719
|
}
|
|
4309
4720
|
function getMigrationsDirectory(config) {
|
|
4310
4721
|
const cwd = process.cwd();
|
|
4311
4722
|
const possiblePaths = [
|
|
4312
|
-
|
|
4313
|
-
|
|
4723
|
+
path5.resolve(cwd, config.migrations.directory),
|
|
4724
|
+
path5.resolve(cwd, "shared", config.migrations.directory)
|
|
4314
4725
|
];
|
|
4315
|
-
return possiblePaths.find((p) =>
|
|
4726
|
+
return possiblePaths.find((p) => fs3.existsSync(p)) || possiblePaths[0];
|
|
4316
4727
|
}
|
|
4317
4728
|
var currentVerbosity = "normal";
|
|
4318
4729
|
function setVerbosity(level) {
|
|
@@ -4529,7 +4940,7 @@ async function executeGenerate(options) {
|
|
|
4529
4940
|
const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
|
|
4530
4941
|
logSuccess(`Found ${currentSchema.collections.size} collection(s)`);
|
|
4531
4942
|
logInfo("Loading previous snapshot...");
|
|
4532
|
-
const previousSnapshot =
|
|
4943
|
+
const previousSnapshot = loadSnapshotWithMigrations({
|
|
4533
4944
|
migrationsPath: migrationsDir,
|
|
4534
4945
|
workspaceRoot: process.cwd()
|
|
4535
4946
|
});
|
|
@@ -4556,7 +4967,7 @@ async function executeGenerate(options) {
|
|
|
4556
4967
|
"Creating migration file...",
|
|
4557
4968
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
4558
4969
|
);
|
|
4559
|
-
logSuccess(`Migration file created: ${
|
|
4970
|
+
logSuccess(`Migration file created: ${path5.basename(migrationPath)}`);
|
|
4560
4971
|
logSection("\u2705 Next Steps");
|
|
4561
4972
|
console.log();
|
|
4562
4973
|
console.log(" 1. Review the generated migration file:");
|
|
@@ -4722,7 +5133,7 @@ async function executeStatus(options) {
|
|
|
4722
5133
|
const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
|
|
4723
5134
|
logSuccess(`Found ${currentSchema.collections.size} collection(s) in schema`);
|
|
4724
5135
|
logInfo("Loading previous snapshot...");
|
|
4725
|
-
const previousSnapshot =
|
|
5136
|
+
const previousSnapshot = loadSnapshotWithMigrations({
|
|
4726
5137
|
migrationsPath: migrationsDir,
|
|
4727
5138
|
workspaceRoot: process.cwd()
|
|
4728
5139
|
});
|
|
@@ -4823,6 +5234,6 @@ async function executeStatus(options) {
|
|
|
4823
5234
|
}
|
|
4824
5235
|
}
|
|
4825
5236
|
|
|
4826
|
-
export { CLIUsageError, ConfigurationError, DiffEngine, FIELD_TYPE_INFO, FileSystemError, MigrationError, MigrationGenerationError, MigrationGenerator, POCKETBASE_FIELD_TYPES, PermissionTemplates, SchemaAnalyzer, SchemaParsingError, SnapshotError, SnapshotManager, StatusEnum, UserInputSchema, UserMutator, UserSchema, aggregateChanges, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, boolField, buildFieldDefinition, buildSchemaDefinition, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, convertPocketBaseMigration, convertZodSchemaToCollectionSchema, createMigrationFileStructure, createPermissions, dateField, detectDestructiveChanges, detectFieldChanges, discoverSchemaFiles, editorField, emailField, extractComprehensiveFieldOptions, extractFieldDefinitions, extractFieldOptions, extractIndexes, extractRelationMetadata, extractSchemaDefinitions, fileField, filesField, filterSystemCollections, findLatestSnapshot, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, formatChangeSummary, generate, generateChangeSummary, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, executeGenerate as generateMigration, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, geoPointField, getArrayElementType, getCollectionNameFromFile, getDefaultValue, getFieldTypeInfo, getMaxSelect, executeStatus as getMigrationStatus, getMinSelect, getSnapshotPath, getSnapshotVersion, getUsersSystemFields, importSchemaModule, inputImageFileSchema, isArrayType, isAuthCollection, isEditorField, isFieldRequired, isFileFieldByName, isGeoPointType, isMultipleRelationField, isPermissionSchema, isRelationField, isSingleRelationField, isSystemCollection, isTemplateConfig, jsonField, loadBaseMigration, loadConfig, loadSnapshot, loadSnapshotIfExists, logError, logInfo, logSection, logSuccess, logWarning, mapZodArrayType, mapZodBooleanType, mapZodDateType, mapZodEnumType, mapZodNumberType, mapZodRecordType, mapZodStringType, mapZodTypeToPocketBase, matchCollectionsByName, matchFieldsByName, mergePermissions, mergeSnapshots, numberField, omitImageFilesSchema, parseSchemaFiles, pluralize,
|
|
5237
|
+
export { CLIUsageError, ConfigurationError, DiffEngine, FIELD_TYPE_INFO, FileSystemError, MigrationError, MigrationGenerationError, MigrationGenerator, POCKETBASE_FIELD_TYPES, PermissionTemplates, ProjectCollection, ProjectInputSchema, ProjectSchema, RelationField, RelationsField, SchemaAnalyzer, SchemaParsingError, SnapshotError, SnapshotManager, StatusEnum, UserCollection, UserCollectionSchema, UserInputSchema, UserMutator, UserSchema, aggregateChanges, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, boolField, buildFieldDefinition, buildSchemaDefinition, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, convertPocketBaseMigration, convertZodSchemaToCollectionSchema, createMigrationFileStructure, createPermissions, dateField, defineCollection, detectDestructiveChanges, detectFieldChanges, discoverSchemaFiles, editorField, emailField, extractComprehensiveFieldOptions, extractFieldDefinitions, extractFieldOptions, extractIndexes, extractRelationMetadata, extractSchemaDefinitions, fileField, filesField, filterSystemCollections, findLatestSnapshot, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, formatChangeSummary, generate, generateChangeSummary, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, executeGenerate as generateMigration, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, geoPointField, getArrayElementType, getCollectionNameFromFile, getDefaultValue, getFieldTypeInfo, getMaxSelect, executeStatus as getMigrationStatus, getMinSelect, getSnapshotPath, getSnapshotVersion, getUsersSystemFields, importSchemaModule, inputImageFileSchema, isArrayType, isAuthCollection, isEditorField, isFieldRequired, isFileFieldByName, isGeoPointType, isMultipleRelationField, isPermissionSchema, isRelationField, isSingleRelationField, isSystemCollection, isTemplateConfig, jsonField, loadBaseMigration, loadConfig, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, logError, logInfo, logSection, logSuccess, logWarning, mapZodArrayType, mapZodBooleanType, mapZodDateType, mapZodEnumType, mapZodNumberType, mapZodRecordType, mapZodStringType, mapZodTypeToPocketBase, matchCollectionsByName, matchFieldsByName, mergePermissions, mergeSnapshots, numberField, omitImageFilesSchema, parseSchemaFiles, pluralize, requiresForceFlag, resolveTargetCollection, resolveTemplate, saveSnapshot, selectField, selectSchemaForCollection, singularize, snapshotExists, textField, toCollectionName, unwrapZodType, urlField, validatePermissionConfig, validateRuleExpression, validateSnapshot, withIndexes, withPermissions, withProgress, writeMigrationFile };
|
|
4827
5238
|
//# sourceMappingURL=index.js.map
|
|
4828
5239
|
//# sourceMappingURL=index.js.map
|