@verdant-web/common 1.15.2 → 1.15.3-next.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/dist/cjs/EventSubscriber.d.ts +17 -17
- package/dist/cjs/EventSubscriber.js +66 -66
- package/dist/cjs/baseline.d.ts +5 -5
- package/dist/cjs/baseline.js +2 -2
- package/dist/cjs/batching.d.ts +42 -42
- package/dist/cjs/batching.js +91 -91
- package/dist/cjs/files.d.ts +19 -19
- package/dist/cjs/files.js +18 -18
- package/dist/cjs/files.test.d.ts +1 -0
- package/dist/cjs/files.test.js +81 -0
- package/dist/cjs/files.test.js.map +1 -0
- package/dist/cjs/index.d.ts +19 -18
- package/dist/cjs/index.js +41 -36
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/indexes.d.ts +17 -17
- package/dist/cjs/indexes.js +142 -142
- package/dist/cjs/indexes.test.d.ts +1 -1
- package/dist/cjs/indexes.test.js +127 -127
- package/dist/cjs/migration.d.ts +172 -172
- package/dist/cjs/migration.js +301 -301
- package/dist/cjs/oids.d.ts +100 -96
- package/dist/cjs/oids.js +457 -439
- package/dist/cjs/oids.js.map +1 -1
- package/dist/cjs/oids.test.d.ts +1 -1
- package/dist/cjs/oids.test.js +348 -272
- package/dist/cjs/oids.test.js.map +1 -1
- package/dist/cjs/operation.d.ts +139 -139
- package/dist/cjs/operation.js +545 -545
- package/dist/cjs/operation.test.d.ts +1 -1
- package/dist/cjs/operation.test.js +529 -529
- package/dist/cjs/patch.d.ts +26 -26
- package/dist/cjs/patch.js +226 -226
- package/dist/cjs/presence.d.ts +27 -27
- package/dist/cjs/presence.js +2 -2
- package/dist/cjs/protocol.d.ts +145 -145
- package/dist/cjs/protocol.js +3 -3
- package/dist/cjs/refs.d.ts +7 -5
- package/dist/cjs/refs.js +29 -21
- package/dist/cjs/refs.js.map +1 -1
- package/dist/cjs/replica.d.ts +28 -28
- package/dist/cjs/replica.js +28 -28
- package/dist/cjs/schema/defaults.d.ts +4 -0
- package/dist/cjs/schema/defaults.js +72 -0
- package/dist/cjs/schema/defaults.js.map +1 -0
- package/dist/cjs/schema/defaults.test.d.ts +1 -1
- package/dist/cjs/schema/defaults.test.js +20 -20
- package/dist/cjs/schema/fields.d.ts +9 -9
- package/dist/cjs/schema/fields.js +144 -144
- package/dist/cjs/schema/index.d.ts +8 -8
- package/dist/cjs/schema/index.js +51 -51
- package/dist/cjs/schema/indexFilters.d.ts +6 -6
- package/dist/cjs/schema/indexFilters.js +30 -30
- package/dist/cjs/schema/types/collection.d.ts +23 -23
- package/dist/cjs/schema/types/collection.js +2 -2
- package/dist/cjs/schema/types/compounds.d.ts +11 -11
- package/dist/cjs/schema/types/compounds.js +2 -2
- package/dist/cjs/schema/types/fields.d.ts +75 -75
- package/dist/cjs/schema/types/fields.js +2 -2
- package/dist/cjs/schema/types/filters.d.ts +29 -29
- package/dist/cjs/schema/types/filters.js +2 -2
- package/dist/cjs/schema/types/shapes.d.ts +21 -21
- package/dist/cjs/schema/types/shapes.js +2 -2
- package/dist/cjs/schema/types/synthetics.d.ts +37 -37
- package/dist/cjs/schema/types/synthetics.js +2 -2
- package/dist/cjs/schema/types.d.ts +18 -18
- package/dist/cjs/schema/types.js +22 -22
- package/dist/cjs/schema/validation.d.ts +3 -3
- package/dist/cjs/schema/validation.js +86 -86
- package/dist/cjs/timestamp.d.ts +50 -50
- package/dist/cjs/timestamp.js +251 -251
- package/dist/cjs/timestamp.test.d.ts +1 -1
- package/dist/cjs/timestamp.test.js +104 -104
- package/dist/cjs/undo.d.ts +3 -3
- package/dist/cjs/undo.js +198 -198
- package/dist/cjs/utils.d.ts +20 -20
- package/dist/cjs/utils.js +145 -145
- package/dist/cjs/utils.test.d.ts +1 -1
- package/dist/cjs/utils.test.js +36 -36
- package/dist/esm/EventSubscriber.d.ts +17 -17
- package/dist/esm/EventSubscriber.js +62 -62
- package/dist/esm/baseline.d.ts +5 -5
- package/dist/esm/baseline.js +1 -1
- package/dist/esm/batching.d.ts +42 -42
- package/dist/esm/batching.js +86 -86
- package/dist/esm/files.d.ts +19 -19
- package/dist/esm/files.js +12 -12
- package/dist/esm/files.test.d.ts +1 -0
- package/dist/esm/files.test.js +79 -0
- package/dist/esm/files.test.js.map +1 -0
- package/dist/esm/index.d.ts +19 -18
- package/dist/esm/index.js +16 -15
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/indexes.d.ts +17 -17
- package/dist/esm/indexes.js +130 -130
- package/dist/esm/indexes.test.d.ts +1 -1
- package/dist/esm/indexes.test.js +125 -125
- package/dist/esm/migration.d.ts +172 -172
- package/dist/esm/migration.js +294 -294
- package/dist/esm/oids.d.ts +100 -96
- package/dist/esm/oids.js +422 -407
- package/dist/esm/oids.js.map +1 -1
- package/dist/esm/oids.test.d.ts +1 -1
- package/dist/esm/oids.test.js +346 -270
- package/dist/esm/oids.test.js.map +1 -1
- package/dist/esm/operation.d.ts +139 -139
- package/dist/esm/operation.js +530 -530
- package/dist/esm/operation.test.d.ts +1 -1
- package/dist/esm/operation.test.js +527 -527
- package/dist/esm/patch.d.ts +26 -26
- package/dist/esm/patch.js +222 -222
- package/dist/esm/presence.d.ts +27 -27
- package/dist/esm/presence.js +1 -1
- package/dist/esm/protocol.d.ts +145 -145
- package/dist/esm/protocol.js +2 -2
- package/dist/esm/refs.d.ts +7 -5
- package/dist/esm/refs.js +22 -16
- package/dist/esm/refs.js.map +1 -1
- package/dist/esm/replica.d.ts +28 -28
- package/dist/esm/replica.js +25 -25
- package/dist/esm/schema/defaults.d.ts +4 -0
- package/dist/esm/schema/defaults.js +66 -0
- package/dist/esm/schema/defaults.js.map +1 -0
- package/dist/esm/schema/defaults.test.d.ts +1 -1
- package/dist/esm/schema/defaults.test.js +18 -18
- package/dist/esm/schema/fields.d.ts +9 -9
- package/dist/esm/schema/fields.js +133 -133
- package/dist/esm/schema/index.d.ts +8 -8
- package/dist/esm/schema/index.js +32 -32
- package/dist/esm/schema/indexFilters.d.ts +6 -6
- package/dist/esm/schema/indexFilters.js +22 -22
- package/dist/esm/schema/types/collection.d.ts +23 -23
- package/dist/esm/schema/types/collection.js +1 -1
- package/dist/esm/schema/types/compounds.d.ts +11 -11
- package/dist/esm/schema/types/compounds.js +1 -1
- package/dist/esm/schema/types/fields.d.ts +75 -75
- package/dist/esm/schema/types/fields.js +1 -1
- package/dist/esm/schema/types/filters.d.ts +29 -29
- package/dist/esm/schema/types/filters.js +1 -1
- package/dist/esm/schema/types/shapes.d.ts +21 -21
- package/dist/esm/schema/types/shapes.js +1 -1
- package/dist/esm/schema/types/synthetics.d.ts +37 -37
- package/dist/esm/schema/types/synthetics.js +1 -1
- package/dist/esm/schema/types.d.ts +18 -18
- package/dist/esm/schema/types.js +6 -6
- package/dist/esm/schema/validation.d.ts +3 -3
- package/dist/esm/schema/validation.js +81 -81
- package/dist/esm/timestamp.d.ts +50 -50
- package/dist/esm/timestamp.js +234 -234
- package/dist/esm/timestamp.test.d.ts +1 -1
- package/dist/esm/timestamp.test.js +102 -102
- package/dist/esm/undo.d.ts +3 -3
- package/dist/esm/undo.js +194 -194
- package/dist/esm/utils.d.ts +20 -20
- package/dist/esm/utils.js +127 -127
- package/dist/esm/utils.test.d.ts +1 -1
- package/dist/esm/utils.test.js +34 -34
- package/dist/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/oids.test.ts +82 -0
- package/src/oids.ts +17 -0
- package/src/refs.ts +8 -0
package/dist/cjs/migration.js
CHANGED
|
@@ -1,302 +1,302 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createMigration = exports.createDefaultMigration = exports.migrationRange = exports.migrate = void 0;
|
|
4
|
-
const index_js_1 = require("./index.js");
|
|
5
|
-
const emptySchema = {
|
|
6
|
-
version: 0,
|
|
7
|
-
collections: {},
|
|
8
|
-
};
|
|
9
|
-
function migrate(oldSchemaOrNewSchema, newSchemaOrProcedure, procedureIfTwoSchemas) {
|
|
10
|
-
const isProcedureSecondArgument = typeof newSchemaOrProcedure === 'function';
|
|
11
|
-
const oldSchema = isProcedureSecondArgument
|
|
12
|
-
? emptySchema
|
|
13
|
-
: oldSchemaOrNewSchema;
|
|
14
|
-
const newSchema = isProcedureSecondArgument
|
|
15
|
-
? oldSchemaOrNewSchema
|
|
16
|
-
: newSchemaOrProcedure;
|
|
17
|
-
const procedure = isProcedureSecondArgument
|
|
18
|
-
? newSchemaOrProcedure
|
|
19
|
-
: procedureIfTwoSchemas;
|
|
20
|
-
// diff to determine changed collections
|
|
21
|
-
const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
|
|
22
|
-
(0, index_js_1.stableStringify)(oldSchema.collections[key]) !==
|
|
23
|
-
(0, index_js_1.stableStringify)(newSchema.collections[key]));
|
|
24
|
-
const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
|
|
25
|
-
const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
|
|
26
|
-
// collections which added one or more field defaults
|
|
27
|
-
const autoMigratedCollections = new Set();
|
|
28
|
-
for (const collection of changedCollections) {
|
|
29
|
-
const oldFields = oldSchema.collections[collection].fields;
|
|
30
|
-
const newFields = newSchema.collections[collection].fields;
|
|
31
|
-
// a new default was added - we can auto-migrate it
|
|
32
|
-
if (Object.keys(newFields).some((key) => { var _a, _b; return !((_a = oldFields[key]) === null || _a === void 0 ? void 0 : _a.default) && ((_b = newFields[key]) === null || _b === void 0 ? void 0 : _b.default); })) {
|
|
33
|
-
autoMigratedCollections.add(collection);
|
|
34
|
-
}
|
|
35
|
-
// a field was removed - we can auto-migrate it
|
|
36
|
-
if (Object.keys(oldFields).some((key) => !newFields[key])) {
|
|
37
|
-
autoMigratedCollections.add(collection);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
const addedIndexes = {};
|
|
41
|
-
const removedIndexes = {};
|
|
42
|
-
for (const changed of [...changedCollections, ...addedCollections]) {
|
|
43
|
-
const oldIndexes = getIndexes(oldSchema.collections[changed]);
|
|
44
|
-
const newIndexes = getIndexes(newSchema.collections[changed]);
|
|
45
|
-
const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
|
|
46
|
-
const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
|
|
47
|
-
if (added.length > 0) {
|
|
48
|
-
addedIndexes[changed] = added;
|
|
49
|
-
// FIXME: don't o(n^2) this
|
|
50
|
-
if (changedCollections.includes(changed)) {
|
|
51
|
-
autoMigratedCollections.add(changed);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (removed.length > 0) {
|
|
55
|
-
removedIndexes[changed] = removed;
|
|
56
|
-
// FIXME: don't o(n^2) this
|
|
57
|
-
if (changedCollections.includes(changed)) {
|
|
58
|
-
autoMigratedCollections.add(changed);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
const withDefaults = (collectionName, val) => {
|
|
63
|
-
return (0, index_js_1.addFieldDefaults)(newSchema.collections[collectionName], val);
|
|
64
|
-
};
|
|
65
|
-
const autoMigration = (collectionName) => (val) => {
|
|
66
|
-
const collection = newSchema.collections[collectionName];
|
|
67
|
-
return (0, index_js_1.addFieldDefaults)(collection, (0, index_js_1.removeExtraProperties)(collection, val));
|
|
68
|
-
};
|
|
69
|
-
return {
|
|
70
|
-
version: newSchema.version,
|
|
71
|
-
migrate: async (engine) => {
|
|
72
|
-
const migratedCollections = [];
|
|
73
|
-
await procedure({
|
|
74
|
-
migrate: async (collection, strategy) => {
|
|
75
|
-
const auto = autoMigration(collection);
|
|
76
|
-
const wrapped = async (val) => {
|
|
77
|
-
const baseValue = await strategy(val);
|
|
78
|
-
// assign OID from original value in case user's strategy
|
|
79
|
-
// involves cloning
|
|
80
|
-
(0, index_js_1.assignOid)(baseValue, (0, index_js_1.getOid)(val));
|
|
81
|
-
const result = auto(baseValue);
|
|
82
|
-
return result;
|
|
83
|
-
};
|
|
84
|
-
// @ts-ignore
|
|
85
|
-
await engine.migrate(collection, wrapped);
|
|
86
|
-
migratedCollections.push(collection);
|
|
87
|
-
// since the user migrated this one and we wrap their
|
|
88
|
-
// strategy with auto-migration, we can remove it from
|
|
89
|
-
// the auto-migration list
|
|
90
|
-
autoMigratedCollections.delete(collection);
|
|
91
|
-
},
|
|
92
|
-
identity: (val) => val,
|
|
93
|
-
withDefaults,
|
|
94
|
-
info: {
|
|
95
|
-
changedCollections,
|
|
96
|
-
addedCollections,
|
|
97
|
-
removedCollections,
|
|
98
|
-
},
|
|
99
|
-
queries: engine.queries,
|
|
100
|
-
mutations: engine.mutations,
|
|
101
|
-
});
|
|
102
|
-
// mandatory migration of fields which had defaults added or
|
|
103
|
-
// fields removed but weren't migrated by the user
|
|
104
|
-
if (newSchema.version > 1) {
|
|
105
|
-
engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
|
|
106
|
-
for (const name of autoMigratedCollections) {
|
|
107
|
-
await engine.migrate(name, autoMigration(name));
|
|
108
|
-
migratedCollections.push(name);
|
|
109
|
-
}
|
|
110
|
-
const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
|
|
111
|
-
if (unmigrated.length > 0) {
|
|
112
|
-
// TODO: does this deserve a full-on error?
|
|
113
|
-
console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
removedCollections,
|
|
118
|
-
addedIndexes,
|
|
119
|
-
removedIndexes,
|
|
120
|
-
allCollections: Object.keys(newSchema.collections),
|
|
121
|
-
changedCollections,
|
|
122
|
-
addedCollections,
|
|
123
|
-
oldCollections: Object.keys(oldSchema.collections),
|
|
124
|
-
oldSchema,
|
|
125
|
-
newSchema,
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
exports.migrate = migrate;
|
|
129
|
-
function migrationRange(from, to) {
|
|
130
|
-
return [...Array(to - from).keys()].map((i) => 1 + i + from);
|
|
131
|
-
}
|
|
132
|
-
exports.migrationRange = migrationRange;
|
|
133
|
-
function getIndexes(collection) {
|
|
134
|
-
if (!collection)
|
|
135
|
-
return [];
|
|
136
|
-
return [
|
|
137
|
-
...Object.keys(collection.indexes || {}).map((key) => ({
|
|
138
|
-
name: key,
|
|
139
|
-
multiEntry: ['array', 'string[]', 'number[]', 'boolean[]'].includes(collection.indexes[key].type),
|
|
140
|
-
synthetic: true,
|
|
141
|
-
compound: false,
|
|
142
|
-
})),
|
|
143
|
-
...Object.keys(collection.compounds || {}).map((key) => ({
|
|
144
|
-
name: key,
|
|
145
|
-
multiEntry: collection.compounds[key].of.some((fieldName) => (collection.fields[fieldName] || collection.indexes[fieldName])
|
|
146
|
-
.type === 'array'),
|
|
147
|
-
synthetic: false,
|
|
148
|
-
compound: true,
|
|
149
|
-
})),
|
|
150
|
-
];
|
|
151
|
-
}
|
|
152
|
-
function createDefaultMigration(schema, newSchema) {
|
|
153
|
-
let oldSchema = newSchema
|
|
154
|
-
? schema
|
|
155
|
-
: {
|
|
156
|
-
version: 0,
|
|
157
|
-
collections: {},
|
|
158
|
-
};
|
|
159
|
-
return migrate(oldSchema, newSchema || schema, async ({ migrate, info }) => {
|
|
160
|
-
if ((newSchema || schema).version === 1)
|
|
161
|
-
return;
|
|
162
|
-
for (const collection of info.changedCollections) {
|
|
163
|
-
// @ts-ignore indefinite type resolution
|
|
164
|
-
await migrate(collection, (old) => old);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
exports.createDefaultMigration = createDefaultMigration;
|
|
169
|
-
function createMigration(maybeOldSchema, maybeNewSchemaOrProcedure, maybeProcedure) {
|
|
170
|
-
const isProcedureSecondArgument = typeof maybeNewSchemaOrProcedure === 'function' ||
|
|
171
|
-
maybeNewSchemaOrProcedure === undefined;
|
|
172
|
-
const oldSchema = isProcedureSecondArgument ? emptySchema : maybeOldSchema;
|
|
173
|
-
const newSchema = isProcedureSecondArgument
|
|
174
|
-
? maybeOldSchema
|
|
175
|
-
: maybeNewSchemaOrProcedure;
|
|
176
|
-
const procedure = isProcedureSecondArgument
|
|
177
|
-
? maybeNewSchemaOrProcedure
|
|
178
|
-
: maybeProcedure;
|
|
179
|
-
(0, index_js_1.assert)(oldSchema, 'Invalid arguments to createMigration');
|
|
180
|
-
(0, index_js_1.assert)(newSchema, 'Invalid arguments to createMigration');
|
|
181
|
-
const { changedCollections, addedCollections, removedCollections, addedIndexes, removedIndexes, autoMigratedCollections, autoMigration, } = getMigrationInfo(oldSchema, newSchema);
|
|
182
|
-
return {
|
|
183
|
-
version: newSchema.version,
|
|
184
|
-
migrate: async (engine) => {
|
|
185
|
-
const migratedCollections = [];
|
|
186
|
-
const migrate = async (collection, strategy) => {
|
|
187
|
-
const auto = autoMigration(collection);
|
|
188
|
-
const wrapped = async (val) => {
|
|
189
|
-
const baseValue = await strategy(val);
|
|
190
|
-
// assign OID from original value in case user's strategy
|
|
191
|
-
// involves cloning
|
|
192
|
-
(0, index_js_1.assignOid)(baseValue, (0, index_js_1.getOid)(val));
|
|
193
|
-
const result = auto(baseValue);
|
|
194
|
-
return result;
|
|
195
|
-
};
|
|
196
|
-
// @ts-ignore
|
|
197
|
-
await engine.migrate(collection, wrapped);
|
|
198
|
-
migratedCollections.push(collection);
|
|
199
|
-
// since the user migrated this one and we wrap their
|
|
200
|
-
// strategy with auto-migration, we can remove it from
|
|
201
|
-
// the auto-migration list
|
|
202
|
-
autoMigratedCollections.delete(collection);
|
|
203
|
-
};
|
|
204
|
-
await (procedure === null || procedure === void 0 ? void 0 : procedure({
|
|
205
|
-
migrate,
|
|
206
|
-
info: {
|
|
207
|
-
changedCollections,
|
|
208
|
-
addedCollections,
|
|
209
|
-
removedCollections,
|
|
210
|
-
},
|
|
211
|
-
queries: engine.queries,
|
|
212
|
-
mutations: engine.mutations,
|
|
213
|
-
}));
|
|
214
|
-
// mandatory migration of fields which had defaults added or
|
|
215
|
-
// fields removed but weren't migrated by the user
|
|
216
|
-
if (newSchema.version > 1) {
|
|
217
|
-
engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
|
|
218
|
-
for (const name of autoMigratedCollections) {
|
|
219
|
-
await engine.migrate(name, autoMigration(name));
|
|
220
|
-
migratedCollections.push(name);
|
|
221
|
-
}
|
|
222
|
-
const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
|
|
223
|
-
if (unmigrated.length > 0) {
|
|
224
|
-
// TODO: does this deserve a full-on error?
|
|
225
|
-
console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
removedCollections,
|
|
230
|
-
addedIndexes,
|
|
231
|
-
removedIndexes,
|
|
232
|
-
allCollections: Object.keys(newSchema.collections),
|
|
233
|
-
changedCollections,
|
|
234
|
-
addedCollections,
|
|
235
|
-
oldCollections: Object.keys(oldSchema.collections),
|
|
236
|
-
oldSchema,
|
|
237
|
-
newSchema,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
exports.createMigration = createMigration;
|
|
241
|
-
// common tools
|
|
242
|
-
function getMigrationInfo(oldSchema, newSchema) {
|
|
243
|
-
const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
|
|
244
|
-
(0, index_js_1.stableStringify)(oldSchema.collections[key]) !==
|
|
245
|
-
(0, index_js_1.stableStringify)(newSchema.collections[key]));
|
|
246
|
-
const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
|
|
247
|
-
const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
|
|
248
|
-
// collections which added one or more field defaults
|
|
249
|
-
const autoMigratedCollections = new Set();
|
|
250
|
-
for (const collection of changedCollections) {
|
|
251
|
-
const oldFields = oldSchema.collections[collection].fields;
|
|
252
|
-
const newFields = newSchema.collections[collection].fields;
|
|
253
|
-
// a new default was added - we can auto-migrate it
|
|
254
|
-
if (Object.keys(newFields).some((key) => !(0, index_js_1.hasDefault)(oldFields[key]) && (0, index_js_1.hasDefault)(newFields[key]))) {
|
|
255
|
-
autoMigratedCollections.add(collection);
|
|
256
|
-
}
|
|
257
|
-
// a field was removed - we can auto-migrate it
|
|
258
|
-
if (Object.keys(oldFields).some((key) => !newFields[key])) {
|
|
259
|
-
autoMigratedCollections.add(collection);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
const addedIndexes = {};
|
|
263
|
-
const removedIndexes = {};
|
|
264
|
-
for (const changed of [...changedCollections, ...addedCollections]) {
|
|
265
|
-
const oldIndexes = getIndexes(oldSchema.collections[changed]);
|
|
266
|
-
const newIndexes = getIndexes(newSchema.collections[changed]);
|
|
267
|
-
const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
|
|
268
|
-
const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
|
|
269
|
-
if (added.length > 0) {
|
|
270
|
-
addedIndexes[changed] = added;
|
|
271
|
-
// FIXME: don't o(n^2) this
|
|
272
|
-
if (changedCollections.includes(changed)) {
|
|
273
|
-
autoMigratedCollections.add(changed);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
if (removed.length > 0) {
|
|
277
|
-
removedIndexes[changed] = removed;
|
|
278
|
-
// FIXME: don't o(n^2) this
|
|
279
|
-
if (changedCollections.includes(changed)) {
|
|
280
|
-
autoMigratedCollections.add(changed);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
const withDefaults = (collectionName, val) => {
|
|
285
|
-
return (0, index_js_1.addFieldDefaults)(newSchema.collections[collectionName], val);
|
|
286
|
-
};
|
|
287
|
-
const autoMigration = (collectionName) => (val) => {
|
|
288
|
-
const collection = newSchema.collections[collectionName];
|
|
289
|
-
return (0, index_js_1.addFieldDefaults)(collection, (0, index_js_1.removeExtraProperties)(collection, val));
|
|
290
|
-
};
|
|
291
|
-
return {
|
|
292
|
-
changedCollections,
|
|
293
|
-
addedCollections,
|
|
294
|
-
removedCollections,
|
|
295
|
-
addedIndexes,
|
|
296
|
-
removedIndexes,
|
|
297
|
-
autoMigratedCollections,
|
|
298
|
-
withDefaults,
|
|
299
|
-
autoMigration,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMigration = exports.createDefaultMigration = exports.migrationRange = exports.migrate = void 0;
|
|
4
|
+
const index_js_1 = require("./index.js");
|
|
5
|
+
const emptySchema = {
|
|
6
|
+
version: 0,
|
|
7
|
+
collections: {},
|
|
8
|
+
};
|
|
9
|
+
function migrate(oldSchemaOrNewSchema, newSchemaOrProcedure, procedureIfTwoSchemas) {
|
|
10
|
+
const isProcedureSecondArgument = typeof newSchemaOrProcedure === 'function';
|
|
11
|
+
const oldSchema = isProcedureSecondArgument
|
|
12
|
+
? emptySchema
|
|
13
|
+
: oldSchemaOrNewSchema;
|
|
14
|
+
const newSchema = isProcedureSecondArgument
|
|
15
|
+
? oldSchemaOrNewSchema
|
|
16
|
+
: newSchemaOrProcedure;
|
|
17
|
+
const procedure = isProcedureSecondArgument
|
|
18
|
+
? newSchemaOrProcedure
|
|
19
|
+
: procedureIfTwoSchemas;
|
|
20
|
+
// diff to determine changed collections
|
|
21
|
+
const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
|
|
22
|
+
(0, index_js_1.stableStringify)(oldSchema.collections[key]) !==
|
|
23
|
+
(0, index_js_1.stableStringify)(newSchema.collections[key]));
|
|
24
|
+
const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
|
|
25
|
+
const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
|
|
26
|
+
// collections which added one or more field defaults
|
|
27
|
+
const autoMigratedCollections = new Set();
|
|
28
|
+
for (const collection of changedCollections) {
|
|
29
|
+
const oldFields = oldSchema.collections[collection].fields;
|
|
30
|
+
const newFields = newSchema.collections[collection].fields;
|
|
31
|
+
// a new default was added - we can auto-migrate it
|
|
32
|
+
if (Object.keys(newFields).some((key) => { var _a, _b; return !((_a = oldFields[key]) === null || _a === void 0 ? void 0 : _a.default) && ((_b = newFields[key]) === null || _b === void 0 ? void 0 : _b.default); })) {
|
|
33
|
+
autoMigratedCollections.add(collection);
|
|
34
|
+
}
|
|
35
|
+
// a field was removed - we can auto-migrate it
|
|
36
|
+
if (Object.keys(oldFields).some((key) => !newFields[key])) {
|
|
37
|
+
autoMigratedCollections.add(collection);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const addedIndexes = {};
|
|
41
|
+
const removedIndexes = {};
|
|
42
|
+
for (const changed of [...changedCollections, ...addedCollections]) {
|
|
43
|
+
const oldIndexes = getIndexes(oldSchema.collections[changed]);
|
|
44
|
+
const newIndexes = getIndexes(newSchema.collections[changed]);
|
|
45
|
+
const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
|
|
46
|
+
const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
|
|
47
|
+
if (added.length > 0) {
|
|
48
|
+
addedIndexes[changed] = added;
|
|
49
|
+
// FIXME: don't o(n^2) this
|
|
50
|
+
if (changedCollections.includes(changed)) {
|
|
51
|
+
autoMigratedCollections.add(changed);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (removed.length > 0) {
|
|
55
|
+
removedIndexes[changed] = removed;
|
|
56
|
+
// FIXME: don't o(n^2) this
|
|
57
|
+
if (changedCollections.includes(changed)) {
|
|
58
|
+
autoMigratedCollections.add(changed);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const withDefaults = (collectionName, val) => {
|
|
63
|
+
return (0, index_js_1.addFieldDefaults)(newSchema.collections[collectionName], val);
|
|
64
|
+
};
|
|
65
|
+
const autoMigration = (collectionName) => (val) => {
|
|
66
|
+
const collection = newSchema.collections[collectionName];
|
|
67
|
+
return (0, index_js_1.addFieldDefaults)(collection, (0, index_js_1.removeExtraProperties)(collection, val));
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
version: newSchema.version,
|
|
71
|
+
migrate: async (engine) => {
|
|
72
|
+
const migratedCollections = [];
|
|
73
|
+
await procedure({
|
|
74
|
+
migrate: async (collection, strategy) => {
|
|
75
|
+
const auto = autoMigration(collection);
|
|
76
|
+
const wrapped = async (val) => {
|
|
77
|
+
const baseValue = await strategy(val);
|
|
78
|
+
// assign OID from original value in case user's strategy
|
|
79
|
+
// involves cloning
|
|
80
|
+
(0, index_js_1.assignOid)(baseValue, (0, index_js_1.getOid)(val));
|
|
81
|
+
const result = auto(baseValue);
|
|
82
|
+
return result;
|
|
83
|
+
};
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
await engine.migrate(collection, wrapped);
|
|
86
|
+
migratedCollections.push(collection);
|
|
87
|
+
// since the user migrated this one and we wrap their
|
|
88
|
+
// strategy with auto-migration, we can remove it from
|
|
89
|
+
// the auto-migration list
|
|
90
|
+
autoMigratedCollections.delete(collection);
|
|
91
|
+
},
|
|
92
|
+
identity: (val) => val,
|
|
93
|
+
withDefaults,
|
|
94
|
+
info: {
|
|
95
|
+
changedCollections,
|
|
96
|
+
addedCollections,
|
|
97
|
+
removedCollections,
|
|
98
|
+
},
|
|
99
|
+
queries: engine.queries,
|
|
100
|
+
mutations: engine.mutations,
|
|
101
|
+
});
|
|
102
|
+
// mandatory migration of fields which had defaults added or
|
|
103
|
+
// fields removed but weren't migrated by the user
|
|
104
|
+
if (newSchema.version > 1) {
|
|
105
|
+
engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
|
|
106
|
+
for (const name of autoMigratedCollections) {
|
|
107
|
+
await engine.migrate(name, autoMigration(name));
|
|
108
|
+
migratedCollections.push(name);
|
|
109
|
+
}
|
|
110
|
+
const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
|
|
111
|
+
if (unmigrated.length > 0) {
|
|
112
|
+
// TODO: does this deserve a full-on error?
|
|
113
|
+
console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
removedCollections,
|
|
118
|
+
addedIndexes,
|
|
119
|
+
removedIndexes,
|
|
120
|
+
allCollections: Object.keys(newSchema.collections),
|
|
121
|
+
changedCollections,
|
|
122
|
+
addedCollections,
|
|
123
|
+
oldCollections: Object.keys(oldSchema.collections),
|
|
124
|
+
oldSchema,
|
|
125
|
+
newSchema,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
exports.migrate = migrate;
|
|
129
|
+
function migrationRange(from, to) {
|
|
130
|
+
return [...Array(to - from).keys()].map((i) => 1 + i + from);
|
|
131
|
+
}
|
|
132
|
+
exports.migrationRange = migrationRange;
|
|
133
|
+
function getIndexes(collection) {
|
|
134
|
+
if (!collection)
|
|
135
|
+
return [];
|
|
136
|
+
return [
|
|
137
|
+
...Object.keys(collection.indexes || {}).map((key) => ({
|
|
138
|
+
name: key,
|
|
139
|
+
multiEntry: ['array', 'string[]', 'number[]', 'boolean[]'].includes(collection.indexes[key].type),
|
|
140
|
+
synthetic: true,
|
|
141
|
+
compound: false,
|
|
142
|
+
})),
|
|
143
|
+
...Object.keys(collection.compounds || {}).map((key) => ({
|
|
144
|
+
name: key,
|
|
145
|
+
multiEntry: collection.compounds[key].of.some((fieldName) => (collection.fields[fieldName] || collection.indexes[fieldName])
|
|
146
|
+
.type === 'array'),
|
|
147
|
+
synthetic: false,
|
|
148
|
+
compound: true,
|
|
149
|
+
})),
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
function createDefaultMigration(schema, newSchema) {
|
|
153
|
+
let oldSchema = newSchema
|
|
154
|
+
? schema
|
|
155
|
+
: {
|
|
156
|
+
version: 0,
|
|
157
|
+
collections: {},
|
|
158
|
+
};
|
|
159
|
+
return migrate(oldSchema, newSchema || schema, async ({ migrate, info }) => {
|
|
160
|
+
if ((newSchema || schema).version === 1)
|
|
161
|
+
return;
|
|
162
|
+
for (const collection of info.changedCollections) {
|
|
163
|
+
// @ts-ignore indefinite type resolution
|
|
164
|
+
await migrate(collection, (old) => old);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
exports.createDefaultMigration = createDefaultMigration;
|
|
169
|
+
function createMigration(maybeOldSchema, maybeNewSchemaOrProcedure, maybeProcedure) {
|
|
170
|
+
const isProcedureSecondArgument = typeof maybeNewSchemaOrProcedure === 'function' ||
|
|
171
|
+
maybeNewSchemaOrProcedure === undefined;
|
|
172
|
+
const oldSchema = isProcedureSecondArgument ? emptySchema : maybeOldSchema;
|
|
173
|
+
const newSchema = isProcedureSecondArgument
|
|
174
|
+
? maybeOldSchema
|
|
175
|
+
: maybeNewSchemaOrProcedure;
|
|
176
|
+
const procedure = isProcedureSecondArgument
|
|
177
|
+
? maybeNewSchemaOrProcedure
|
|
178
|
+
: maybeProcedure;
|
|
179
|
+
(0, index_js_1.assert)(oldSchema, 'Invalid arguments to createMigration');
|
|
180
|
+
(0, index_js_1.assert)(newSchema, 'Invalid arguments to createMigration');
|
|
181
|
+
const { changedCollections, addedCollections, removedCollections, addedIndexes, removedIndexes, autoMigratedCollections, autoMigration, } = getMigrationInfo(oldSchema, newSchema);
|
|
182
|
+
return {
|
|
183
|
+
version: newSchema.version,
|
|
184
|
+
migrate: async (engine) => {
|
|
185
|
+
const migratedCollections = [];
|
|
186
|
+
const migrate = async (collection, strategy) => {
|
|
187
|
+
const auto = autoMigration(collection);
|
|
188
|
+
const wrapped = async (val) => {
|
|
189
|
+
const baseValue = await strategy(val);
|
|
190
|
+
// assign OID from original value in case user's strategy
|
|
191
|
+
// involves cloning
|
|
192
|
+
(0, index_js_1.assignOid)(baseValue, (0, index_js_1.getOid)(val));
|
|
193
|
+
const result = auto(baseValue);
|
|
194
|
+
return result;
|
|
195
|
+
};
|
|
196
|
+
// @ts-ignore
|
|
197
|
+
await engine.migrate(collection, wrapped);
|
|
198
|
+
migratedCollections.push(collection);
|
|
199
|
+
// since the user migrated this one and we wrap their
|
|
200
|
+
// strategy with auto-migration, we can remove it from
|
|
201
|
+
// the auto-migration list
|
|
202
|
+
autoMigratedCollections.delete(collection);
|
|
203
|
+
};
|
|
204
|
+
await (procedure === null || procedure === void 0 ? void 0 : procedure({
|
|
205
|
+
migrate,
|
|
206
|
+
info: {
|
|
207
|
+
changedCollections,
|
|
208
|
+
addedCollections,
|
|
209
|
+
removedCollections,
|
|
210
|
+
},
|
|
211
|
+
queries: engine.queries,
|
|
212
|
+
mutations: engine.mutations,
|
|
213
|
+
}));
|
|
214
|
+
// mandatory migration of fields which had defaults added or
|
|
215
|
+
// fields removed but weren't migrated by the user
|
|
216
|
+
if (newSchema.version > 1) {
|
|
217
|
+
engine.log('debug', 'auto-migrating collections with new defaults', autoMigratedCollections);
|
|
218
|
+
for (const name of autoMigratedCollections) {
|
|
219
|
+
await engine.migrate(name, autoMigration(name));
|
|
220
|
+
migratedCollections.push(name);
|
|
221
|
+
}
|
|
222
|
+
const unmigrated = changedCollections.filter((collection) => !migratedCollections.includes(collection));
|
|
223
|
+
if (unmigrated.length > 0) {
|
|
224
|
+
// TODO: does this deserve a full-on error?
|
|
225
|
+
console.error(`Unmigrated changed collections from version ${oldSchema.version} to version ${newSchema.version}:`, unmigrated);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
removedCollections,
|
|
230
|
+
addedIndexes,
|
|
231
|
+
removedIndexes,
|
|
232
|
+
allCollections: Object.keys(newSchema.collections),
|
|
233
|
+
changedCollections,
|
|
234
|
+
addedCollections,
|
|
235
|
+
oldCollections: Object.keys(oldSchema.collections),
|
|
236
|
+
oldSchema,
|
|
237
|
+
newSchema,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
exports.createMigration = createMigration;
|
|
241
|
+
// common tools
|
|
242
|
+
function getMigrationInfo(oldSchema, newSchema) {
|
|
243
|
+
const changedCollections = Object.keys(newSchema.collections).filter((key) => oldSchema.collections[key] &&
|
|
244
|
+
(0, index_js_1.stableStringify)(oldSchema.collections[key]) !==
|
|
245
|
+
(0, index_js_1.stableStringify)(newSchema.collections[key]));
|
|
246
|
+
const removedCollections = Object.keys(oldSchema.collections).filter((key) => !newSchema.collections[key]);
|
|
247
|
+
const addedCollections = Object.keys(newSchema.collections).filter((key) => !oldSchema.collections[key]);
|
|
248
|
+
// collections which added one or more field defaults
|
|
249
|
+
const autoMigratedCollections = new Set();
|
|
250
|
+
for (const collection of changedCollections) {
|
|
251
|
+
const oldFields = oldSchema.collections[collection].fields;
|
|
252
|
+
const newFields = newSchema.collections[collection].fields;
|
|
253
|
+
// a new default was added - we can auto-migrate it
|
|
254
|
+
if (Object.keys(newFields).some((key) => !(0, index_js_1.hasDefault)(oldFields[key]) && (0, index_js_1.hasDefault)(newFields[key]))) {
|
|
255
|
+
autoMigratedCollections.add(collection);
|
|
256
|
+
}
|
|
257
|
+
// a field was removed - we can auto-migrate it
|
|
258
|
+
if (Object.keys(oldFields).some((key) => !newFields[key])) {
|
|
259
|
+
autoMigratedCollections.add(collection);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const addedIndexes = {};
|
|
263
|
+
const removedIndexes = {};
|
|
264
|
+
for (const changed of [...changedCollections, ...addedCollections]) {
|
|
265
|
+
const oldIndexes = getIndexes(oldSchema.collections[changed]);
|
|
266
|
+
const newIndexes = getIndexes(newSchema.collections[changed]);
|
|
267
|
+
const added = newIndexes.filter((index) => !oldIndexes.find((i) => i.name === index.name));
|
|
268
|
+
const removed = oldIndexes.filter((index) => !newIndexes.find((i) => i.name === index.name));
|
|
269
|
+
if (added.length > 0) {
|
|
270
|
+
addedIndexes[changed] = added;
|
|
271
|
+
// FIXME: don't o(n^2) this
|
|
272
|
+
if (changedCollections.includes(changed)) {
|
|
273
|
+
autoMigratedCollections.add(changed);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (removed.length > 0) {
|
|
277
|
+
removedIndexes[changed] = removed;
|
|
278
|
+
// FIXME: don't o(n^2) this
|
|
279
|
+
if (changedCollections.includes(changed)) {
|
|
280
|
+
autoMigratedCollections.add(changed);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const withDefaults = (collectionName, val) => {
|
|
285
|
+
return (0, index_js_1.addFieldDefaults)(newSchema.collections[collectionName], val);
|
|
286
|
+
};
|
|
287
|
+
const autoMigration = (collectionName) => (val) => {
|
|
288
|
+
const collection = newSchema.collections[collectionName];
|
|
289
|
+
return (0, index_js_1.addFieldDefaults)(collection, (0, index_js_1.removeExtraProperties)(collection, val));
|
|
290
|
+
};
|
|
291
|
+
return {
|
|
292
|
+
changedCollections,
|
|
293
|
+
addedCollections,
|
|
294
|
+
removedCollections,
|
|
295
|
+
addedIndexes,
|
|
296
|
+
removedIndexes,
|
|
297
|
+
autoMigratedCollections,
|
|
298
|
+
withDefaults,
|
|
299
|
+
autoMigration,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
302
|
//# sourceMappingURL=migration.js.map
|