@oliasoft-open-source/node-json-migrator 2.3.10 → 3.0.0-beta-1

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.
@@ -1,216 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.warnIfFilesHaveBeenRemovedFromPlan = exports.validatePlan = exports.validateFileName = exports.validateFileDescription = exports.throwIfSequenceNotUnique = exports.throwIfSequenceHasIntegerGaps = exports.throwIfSequenceHasChanged = exports.throwIfFilesNotFound = exports.throwIfFilesHaveChanged = exports.throwIfFileNamesNotUnique = exports.throwIfFileNamesInvalid = void 0;
7
- var _chalk = _interopRequireDefault(require("chalk"));
8
- var _lodash = require("lodash");
9
- var _ajv = _interopRequireDefault(require("ajv"));
10
- var _ajvErrors = _interopRequireDefault(require("ajv-errors"));
11
- var _planSchema = _interopRequireDefault(require("./plan.schema.json"));
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
- const isNonEmptyString = input => (0, _lodash.isString)(input) && input.length > 0;
14
- const ajv = new _ajv.default({
15
- allErrors: true
16
- });
17
- (0, _ajvErrors.default)(ajv);
18
-
19
- //sequence pattern: https://regex101.com/r/4qHZLm/1
20
- const planValidator = ajv.compile(_planSchema.default);
21
-
22
- /**
23
- * Validates if a plan matches the schema
24
- *
25
- * @param {Array<Object>} plan
26
- * @returns {Boolean} valid
27
- */
28
-
29
- const validatePlan = plan => {
30
- const valid = planValidator(plan);
31
- const {
32
- errors
33
- } = planValidator;
34
- if (errors?.length) {
35
- errors.forEach(e => console.error(`${e.message}${e.instancePath ? `at ${e.instancePath}` : ''}`));
36
- }
37
- return valid;
38
- };
39
-
40
- /**
41
- * Validates if file description format is valid
42
- *
43
- * @param {String} description
44
- * @returns {Boolean} valid
45
- */
46
- exports.validatePlan = validatePlan;
47
- const validateFileDescription = description => {
48
- if (!description) {
49
- return false;
50
- }
51
- //https://regex101.com/r/IO0dzF/1
52
- const validFileName = /^([a-z]+|(([a-z]+-)+[a-z]+))$/g;
53
- return validFileName.test(description);
54
- };
55
-
56
- /**
57
- * Validates if fileName format is valid
58
- *
59
- * @param {String} fileName
60
- * @returns {Boolean} valid
61
- */
62
- exports.validateFileDescription = validateFileDescription;
63
- const validateFileName = fileName => {
64
- //https://regex101.com/r/EX2RlS/1
65
- const validFileName = /^([a-z]+|(([a-z]+-)+[a-z]+))(.js|.skip.js)$/g;
66
- return validFileName.test(fileName);
67
- };
68
-
69
- /**
70
- * Throws if file names are invalid
71
- *
72
- * @param {Array<Object>} migrationEntries
73
- */
74
- exports.validateFileName = validateFileName;
75
- const throwIfFileNamesInvalid = fileEntries => {
76
- const invalidFileNames = fileEntries.filter(f => !f.isValidFileName).map(f => f.fileName);
77
- if (invalidFileNames.length) {
78
- invalidFileNames.forEach(name => console.error(_chalk.default.red(name)));
79
- throw new Error('Invalid migration filename format (use kebab-case)');
80
- }
81
- };
82
-
83
- /**
84
- * Warns if files have been removed
85
- *
86
- * @param {Array<Object>} migrationEntries
87
- * @param {Array<Object>} historicalMigrations
88
- */
89
- exports.throwIfFileNamesInvalid = throwIfFileNamesInvalid;
90
- const warnIfFilesHaveBeenRemovedFromPlan = (migrationEntries, historicalMigrations) => {
91
- const fileNames = migrationEntries.map(f => f.fileName);
92
- const deletedFilesNames = historicalMigrations.filter(e => !fileNames.includes(e.fileName)).map(e => e.fileName);
93
- if (deletedFilesNames.length) {
94
- deletedFilesNames.forEach(name => console.warn(_chalk.default.yellow(name)));
95
- console.warn(_chalk.default.yellow('Previously executed migration files have been deleted from plan.json (rename file to .skip.js and replace with a new file instead)'));
96
- }
97
- };
98
-
99
- /**
100
- * Throws error if any pre-existing file has changed
101
- *
102
- * @param {Array<Object>} migrationEntries
103
- */
104
- exports.warnIfFilesHaveBeenRemovedFromPlan = warnIfFilesHaveBeenRemovedFromPlan;
105
- const throwIfFilesHaveChanged = migrationEntries => {
106
- const changedFilesNames = migrationEntries.filter(m => {
107
- const {
108
- fileHash,
109
- fileHashFromPlan,
110
- fileHashFromHistory,
111
- skippedFileHashes
112
- } = m;
113
- const matchesHistory = !isNonEmptyString(fileHashFromHistory) || [fileHash].concat(skippedFileHashes).includes(fileHashFromHistory);
114
- const matchesPlan = !isNonEmptyString(fileHashFromPlan) || [fileHash].concat(skippedFileHashes).includes(fileHashFromPlan);
115
- return !(matchesHistory && matchesPlan);
116
- }).map(f => f.fileName);
117
- if (changedFilesNames.length) {
118
- changedFilesNames.forEach(name => console.error(_chalk.default.red(name)));
119
- throw new Error('Not allowed to change migration files (for unreleased local work, you can use the `force` option)');
120
- }
121
- };
122
-
123
- /**
124
- * Throws error if previous sequence numbers have changed
125
- *
126
- * @param {Array<Object>} migrationEntries
127
- */
128
- exports.throwIfFilesHaveChanged = throwIfFilesHaveChanged;
129
- const throwIfSequenceHasChanged = migrationEntries => {
130
- const changeSequences = migrationEntries.filter(m => {
131
- const {
132
- sequence,
133
- sequenceFromHistory
134
- } = m;
135
- const changed = (0, _lodash.isString)(sequenceFromHistory) && sequenceFromHistory !== sequence;
136
- return changed;
137
- }).map(f => f.fileName);
138
- if (changeSequences.length) {
139
- changeSequences.forEach(name => console.error(_chalk.default.red(name)));
140
- throw new Error('Not allowed to change migration sequences in plan.json');
141
- }
142
- };
143
-
144
- /**
145
- * Throws error if sequence numbers are not unique
146
- *
147
- * @param {Array<Object>} migrationEntries
148
- */
149
- exports.throwIfSequenceHasChanged = throwIfSequenceHasChanged;
150
- const throwIfSequenceNotUnique = migrationEntries => {
151
- const sequenceNumbers = migrationEntries.map(f => f.sequence);
152
- const repeatedSequenceNumbers = sequenceNumbers.filter(
153
- //https://stackoverflow.com/a/59517965/942635
154
- (s => v => s.has(v) || !s.add(v))(new Set()));
155
- const duplicates = migrationEntries.filter(f => repeatedSequenceNumbers.includes(f.sequence)).map(f => f.fileName);
156
- if (duplicates.length) {
157
- duplicates.forEach(fileName => console.error(_chalk.default.red(fileName)));
158
- throw new Error('Migrations must have unique sequence numbers in plan.json');
159
- }
160
- };
161
-
162
- /**
163
- * Throws error if sequence numbers are not unique
164
- *
165
- * @param {Array<Object>} migrationEntries
166
- */
167
- exports.throwIfSequenceNotUnique = throwIfSequenceNotUnique;
168
- const throwIfSequenceHasIntegerGaps = migrationEntries => {
169
- const toInteger = sequence => parseInt(sequence.split('.')[0], 10);
170
- const unique = arr => Array.from(new Set(arr));
171
- const sequences = migrationEntries.map(s => s.sequence);
172
- const sequenceIntegers = sequences.map(s => toInteger(s));
173
- const uniqueSequenceIntegers = unique(sequenceIntegers);
174
- const orderedUniqueSequenceIntegers = uniqueSequenceIntegers.sort((a, b) => a - b);
175
- const max = orderedUniqueSequenceIntegers[orderedUniqueSequenceIntegers.length - 1];
176
- const expected = Array.from({
177
- length: max
178
- }, (v, k) => k + 1);
179
- const missing = (0, _lodash.xor)(orderedUniqueSequenceIntegers, expected);
180
- if (missing.length) {
181
- throw new Error(`Migration sequence numbers in plan.json have unexpected gaps: ${missing.join(', ')}`);
182
- }
183
- };
184
-
185
- /**
186
- * Throws error if file names are not unique
187
- *
188
- * @param {Array<Object>} migrationEntries
189
- */
190
- exports.throwIfSequenceHasIntegerGaps = throwIfSequenceHasIntegerGaps;
191
- const throwIfFileNamesNotUnique = migrationEntries => {
192
- const fileNames = migrationEntries.map(f => f.fileName);
193
- const repeatedFileNames = fileNames.filter(
194
- //https://stackoverflow.com/a/59517965/942635
195
- (s => v => s.has(v) || !s.add(v))(new Set()));
196
- if (repeatedFileNames.length) {
197
- repeatedFileNames.forEach(fileName => console.error(_chalk.default.red(fileName)));
198
- throw new Error('Migration file names must be unique');
199
- }
200
- };
201
-
202
- /**
203
- * Throws error if files listed in plan.json are found
204
- *
205
- * @param {Array<Object>} migrationEntries
206
- * @param {Boolean} importModule
207
- */
208
- exports.throwIfFileNamesNotUnique = throwIfFileNamesNotUnique;
209
- const throwIfFilesNotFound = (migrationEntries, importModule) => {
210
- const migrationsWithoutFiles = migrationEntries.filter(m => !m.script || importModule && !m.script && !m.migrator);
211
- if (migrationsWithoutFiles.length) {
212
- migrationsWithoutFiles.forEach(migration => console.error(_chalk.default.red(migration.fileName)));
213
- throw new Error('Migration files from plan.json are missing from filesystem');
214
- }
215
- };
216
- exports.throwIfFilesNotFound = throwIfFilesNotFound;