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

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oliasoft-open-source/node-json-migrator",
3
- "version": "2.3.10",
3
+ "version": "3.0.0-beta-2",
4
4
  "description": "A library for JSON migrations",
5
5
  "homepage": "https://oliasoft-open-source.gitlab.io/node-postgresql-migrator",
6
6
  "bugs": {
@@ -12,77 +12,69 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "author": "Oliasoft AS and contributors",
15
- "main": "./dist/index.js",
15
+ "type": "module",
16
+ "exports": {
17
+ "require": {
18
+ "types": "./dist/index.d.cts",
19
+ "default": "./dist/index.cjs"
20
+ },
21
+ "import": {
22
+ "types": "./dist/index.d.mts",
23
+ "default": "./dist/index.mjs"
24
+ }
25
+ },
26
+ "main": "./dist/index.cjs",
27
+ "module": "./dist/index.mjs",
28
+ "types": "./dist/index.d.cts",
16
29
  "files": [
17
30
  "dist"
18
31
  ],
19
32
  "scripts": {
20
- "build": "npx babel src --ignore 'src/**/*.test.js' --out-dir dist --copy-files --no-copy-ignored && cp ./LICENSE ./dist && cp ./README.md ./dist",
21
- "lint:check": "eslint \"**/*.{js,jsx}\"",
22
- "lint:fix": "eslint --fix \"**/*.{js,jsx}\"",
23
- "prepare": "husky install",
24
- "prettier:check": "prettier --check \"**/*.{js,jsx,json,css,less}\"",
25
- "prettier:fix": "prettier --write \"**/*.{js,jsx,json,css,less}\"",
26
- "test": "yarn run prettier:check && yarn run lint:check && yarn run test:unit:coverage",
27
- "test:unit": "jest --silent=true",
28
- "test:unit:coverage": "jest --silent=true --collectCoverage=true",
29
- "test:unit:verbose": "jest --silent=false --verbose"
33
+ "build": "pkgroll --clean-dist && cp ./LICENSE ./dist && cp ./README.md ./dist",
34
+ "lint:check": "npx eslint '**/*.{js,ts,json}'",
35
+ "lint:fix": "npx eslint --fix '**/*.{js,ts,json}'",
36
+ "prepare": "husky",
37
+ "prettier:check": "prettier --check \"**/*.{js,ts,json}\"",
38
+ "prettier:fix": "prettier --write \"**/*.{js,ts,json}\"",
39
+ "test": "yarn run prettier:check && yarn run lint:check && yarn run test:unit",
40
+ "test:integration": "tsx --test \"test/integration.test.ts\"",
41
+ "test:unit": "tsx --test --experimental-test-coverage \"src/**/*.test.ts\"",
42
+ "types:check": "tsc"
30
43
  },
31
44
  "lint-staged": {
32
45
  "*.js": "eslint --cache --fix",
33
- "*.{js,jsx,json,css,less}": [
46
+ "*.{js,ts,json}": [
34
47
  "prettier --write"
35
48
  ]
36
49
  },
37
50
  "dependencies": {
38
- "ajv": "^8.6.3",
39
- "ajv-errors": "^3.0.0",
40
- "chalk": "^4.1.2",
41
- "glob-promise": "^4.2.0",
42
- "module-from-string": "^3.3.1"
51
+ "module-from-string": "^3.3.1",
52
+ "pg-promise": "^10||^11"
43
53
  },
44
54
  "devDependencies": {
45
- "@babel/cli": "^7.15.7",
46
- "@babel/core": "^7.15.0",
47
- "@babel/eslint-parser": "^7.15.0",
48
- "@babel/node": "^7.14.9",
49
- "@babel/plugin-proposal-class-properties": "^7.14.5",
50
- "@babel/plugin-proposal-decorators": "^7.14.5",
51
- "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
52
- "@babel/plugin-proposal-function-sent": "^7.14.5",
53
- "@babel/plugin-proposal-json-strings": "^7.14.5",
54
- "@babel/plugin-proposal-numeric-separator": "^7.14.5",
55
- "@babel/plugin-proposal-object-rest-spread": "^7.14.7",
56
- "@babel/plugin-proposal-throw-expressions": "^7.14.5",
57
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
58
- "@babel/plugin-syntax-import-meta": "^7.10.4",
59
- "@babel/preset-env": "^7.15.0",
60
- "@babel/runtime": "^7.15.3",
61
- "@types/lodash": "^4.14.172",
62
- "babel-eslint": "^10.1.0",
63
- "babel-jest": "^27.1.0",
64
- "babel-loader": "^8.2.2",
65
- "eslint": "^7.32.0",
66
- "eslint-config-airbnb": "^18.2.1",
67
- "eslint-config-prettier": "^8.3.0",
68
- "eslint-import-resolver-alias": "^1.1.2",
69
- "eslint-plugin-import": "^2.24.2",
70
- "husky": "^7.0.2",
71
- "immer": "^9",
72
- "jest": "^27.1.0",
73
- "jest-diff": "^27.3.1",
74
- "jest-matcher-utils": "^27.3.1",
75
- "lint-staged": "^11.1.2",
76
- "lodash": "^4",
77
- "mock-fs": "^5.1.1",
78
- "pg-mem": "^1.9.17",
79
- "pg-promise": "^10",
80
- "prettier": "2.3.2"
55
+ "@types/lodash-es": "^4.17.12",
56
+ "@types/mock-fs": "^4.13.4",
57
+ "@types/node": "^22.13.10",
58
+ "ajv": "^8.17.1",
59
+ "ajv-errors": "^3.0.0",
60
+ "chalk": "^5.4.1",
61
+ "eslint": "^9.22.0",
62
+ "eslint-config-prettier": "^10.1.1",
63
+ "glob": "^11.0.1",
64
+ "husky": "^9.1.7",
65
+ "immer": "^10.1.1",
66
+ "lint-staged": "^15.5.0",
67
+ "lodash-es": "^4.17.21",
68
+ "mock-fs": "^5.5.0",
69
+ "pg-mem": "^3.0.5",
70
+ "pkgroll": "^2.11.2",
71
+ "prettier": "3.5.3",
72
+ "tsx": "^4.19.3",
73
+ "typescript": "^5.8.2",
74
+ "typescript-eslint": "^8.26.1"
81
75
  },
82
76
  "peerDependencies": {
83
- "immer": "^9",
84
- "lodash": "^4",
85
- "pg-promise": "^10"
77
+ "pg-promise": "^10||^11"
86
78
  },
87
79
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
88
80
  }
@@ -1,76 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.createMigration = void 0;
7
- var _path = _interopRequireDefault(require("path"));
8
- var _fs = require("fs");
9
- var _chalk = _interopRequireDefault(require("chalk"));
10
- var _validator = require("../plan/validator");
11
- var _plan = require("../plan/plan");
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
- const templateMigrationFile = `import produce from 'immer';
14
- //other imports not allowed
15
-
16
- export default (dataset) => produce(dataset, (draft) => {
17
- // https://immerjs.github.io/immer/produce#example
18
- });
19
- `;
20
- const templateTestFile = fileName => `import migrate from './${fileName}';
21
-
22
- describe('describe dataset change', () => {
23
- test('describe test', () => {
24
- //arrange
25
- const dataset = {};
26
-
27
- //act
28
- const nextDataset = migrate(dataset);
29
-
30
- //assert
31
- });
32
- });
33
- `;
34
-
35
- /**
36
- * Generate a new dataset migration
37
- *
38
- * @param {String} directory path to migrations directory
39
- * @param {String} description description of change-set / migration
40
- */
41
-
42
- const createMigration = async (directory, description) => {
43
- if (!(0, _validator.validateFileDescription)(description)) {
44
- throw new Error('Invalid migration description');
45
- }
46
- try {
47
- const directoryFullPath = _path.default.resolve(directory, description);
48
- const fileName = `${description}.js`;
49
- const testFileName = `${description}.test.js`;
50
- const filePath = _path.default.resolve(directoryFullPath, fileName);
51
- const testFilePath = _path.default.resolve(directoryFullPath, testFileName);
52
- await _fs.promises.mkdir(directoryFullPath, {
53
- recursive: true
54
- });
55
- await _fs.promises.writeFile(filePath, templateMigrationFile, {
56
- encoding: 'utf8'
57
- });
58
- await _fs.promises.writeFile(testFilePath, templateTestFile(fileName), {
59
- encoding: 'utf8'
60
- });
61
- const rawPlan = await (0, _plan.readPlan)(directory);
62
- const plannedMigrations = (0, _plan.parsePlan)(rawPlan);
63
- const nextPlannedMigrations = plannedMigrations.concat({
64
- fileHash: '',
65
- fileName,
66
- sequence: (0, _plan.getNextSequenceString)(plannedMigrations)
67
- });
68
- const nextPlan = JSON.stringify(nextPlannedMigrations, null, 2);
69
- await (0, _plan.writePlan)(directory, nextPlan);
70
- console.log(_chalk.default.green(`Created new dataset migration ${fileName} ✓`));
71
- } catch (error) {
72
- console.log(_chalk.default.red(error));
73
- throw new Error('Unable to create migration file');
74
- }
75
- };
76
- exports.createMigration = createMigration;
@@ -1,102 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.replaceMigrationsRecords = exports.migrationTablesExist = exports.insertVersions = exports.insertMigrationsRecords = exports.getVersions = exports.getPlanFromVersion = exports.getMigrationRecords = exports.createMigrationsTables = void 0;
7
- const migrationTablesExist = (db, entity) => {
8
- const query = `
9
- SELECT EXISTS (
10
- SELECT FROM information_schema.tables
11
- WHERE table_schema = 'public'
12
- AND table_name = '${entity}_migrations'
13
- )
14
- `;
15
- return db.any(query);
16
- };
17
- exports.migrationTablesExist = migrationTablesExist;
18
- const createMigrationsTables = (db, entity) => {
19
- const query = `
20
- CREATE TABLE IF NOT EXISTS ${entity}_migrations (
21
- file_hash TEXT NOT NULL PRIMARY KEY,
22
- file_name TEXT NOT NULL,
23
- sequence TEXT NOT NULL,
24
- created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
25
- UNIQUE (file_name),
26
- UNIQUE (sequence)
27
- );
28
- CREATE TABLE IF NOT EXISTS ${entity}_versions (
29
- version TEXT NOT NULL PRIMARY KEY,
30
- plan TEXT NOT NULL,
31
- created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
32
- );
33
- `;
34
- return db.any(query);
35
- };
36
- exports.createMigrationsTables = createMigrationsTables;
37
- const getMigrationRecords = (db, entity) => {
38
- const query = `
39
- SELECT file_hash, file_name, sequence FROM ${entity}_migrations
40
- ORDER BY sequence
41
- `;
42
- return db.manyOrNone(query).then(data => data.map(r => ({
43
- fileHash: r.file_hash,
44
- fileName: r.file_name,
45
- sequence: r.sequence
46
- })));
47
- };
48
- exports.getMigrationRecords = getMigrationRecords;
49
- const insertMigrationsRecords = (db, pgpHelpers, entity, migrations) => {
50
- if (migrations.length) {
51
- const toInsert = migrations.map(m => ({
52
- file_name: m.fileName,
53
- file_hash: m.fileHash,
54
- sequence: m.sequence
55
- })).filter(m => m.file_hash !== null); //can't insert null file hash
56
- const cs = new pgpHelpers.ColumnSet(['file_name', 'file_hash', 'sequence'], {
57
- table: `${entity}_migrations`
58
- });
59
- const onConflict = ' ON CONFLICT(file_name) DO NOTHING';
60
- const query = pgpHelpers.insert(toInsert, cs) + onConflict;
61
- return db.none(query);
62
- }
63
- };
64
- exports.insertMigrationsRecords = insertMigrationsRecords;
65
- const replaceMigrationsRecords = async (db, pgpHelpers, entity, migrations) => {
66
- /*
67
- OW-9043: Table is used for change detection/tracking. DELETE ALL not
68
- TRUNCATE here so that fewer permissions are needed in downstream
69
- environments.
70
- */
71
- const truncate = `DELETE FROM ${entity}_migrations`;
72
- await db.none(truncate);
73
- await insertMigrationsRecords(db, pgpHelpers, entity, migrations);
74
- };
75
- exports.replaceMigrationsRecords = replaceMigrationsRecords;
76
- const insertVersions = (db, pgpHelpers, entity, records) => {
77
- const cs = new pgpHelpers.ColumnSet(['version', 'plan'], {
78
- table: `${entity}_versions`
79
- });
80
- const onConflict = ' ON CONFLICT(version) DO NOTHING';
81
- const query = pgpHelpers.insert(records, cs) + onConflict;
82
- return db.none(query);
83
- };
84
- exports.insertVersions = insertVersions;
85
- const getPlanFromVersion = (db, entity, version) => {
86
- const query = `
87
- SELECT plan FROM ${entity}_versions
88
- WHERE version=$1;
89
- `;
90
- return db.oneOrNone(query, [version], r => r?.plan || null);
91
- };
92
- exports.getPlanFromVersion = getPlanFromVersion;
93
- const getVersions = async (db, entity) => {
94
- const query = `
95
- SELECT
96
- version,
97
- plan
98
- FROM ${entity}_versions ORDER BY created_on DESC
99
- `;
100
- return db.any(query);
101
- };
102
- exports.getVersions = getVersions;
@@ -1,68 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getExecutedMigrationsFromVersion = void 0;
7
- var _chalk = _interopRequireDefault(require("chalk"));
8
- var _database = require("../database/database");
9
- var _validator = require("../plan/validator");
10
- var _git = require("../git/git");
11
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
- /**
13
- * Get the executed migrations for a given payload version
14
- *
15
- * @param {Object} database database connection object
16
- * @param {Object} pgpHelpers pg-promise helpers
17
- * @param {String} entity entity name for payload
18
- * @param {String} directory path to migrations directory
19
- * @param {String} currentVersion
20
- * @param {String} plannedVersion
21
- * @param {Array<Object>} plannedMigrations planned migration entries
22
- * returns Promise<Array<Object>> executed migration entries
23
- */
24
-
25
- const getExecutedMigrationsFromVersion = async (database, pgpHelpers, entity, directory, currentVersion, plannedVersion, plannedMigrations) => {
26
- if (!currentVersion) {
27
- //when there is no current version, payload has never been migrated
28
- //so executed entries is empty
29
- return [];
30
- }
31
- if (currentVersion === plannedVersion) {
32
- //when planned version matches current version, there is nothing to migrate
33
- return plannedMigrations;
34
- } else {
35
- //otherwise we look up the historical plan file for that version from the DB
36
- let planFromVersion = await (0, _database.getPlanFromVersion)(database, entity, currentVersion);
37
- if (planFromVersion === null) {
38
- //if not in database, try to get it from the git history
39
- console.warn(_chalk.default.yellow(`Version not found in ${entity}_version table, trying git history instead`));
40
- const planFilePath = `${directory}/plan.json`;
41
- const {
42
- historicalPlans
43
- } = await (0, _git.getHistoricalPlansFromGit)(planFilePath);
44
- //cache the response in the entity versions table
45
- if (historicalPlans.length) {
46
- await (0, _database.insertVersions)(database, pgpHelpers, entity, historicalPlans);
47
- planFromVersion = historicalPlans.find(p => p.version === currentVersion)?.plan || null;
48
- }
49
- }
50
- if (planFromVersion !== null) {
51
- let migrationsFromHistory = null;
52
- try {
53
- migrationsFromHistory = JSON.parse(planFromVersion);
54
- } catch {
55
- throw new Error(`Invalid record in ${entity}_version table (cannot parse JSON)`);
56
- }
57
- if (!(0, _validator.validatePlan)(migrationsFromHistory)) {
58
- throw new Error(`Invalid plan in ${entity}_version table (does not match schema)`);
59
- } else {
60
- return migrationsFromHistory;
61
- }
62
- } else {
63
- console.error(_chalk.default.red(_git.historyError));
64
- throw new Error(`Unable to migrate, could not find version history`);
65
- }
66
- }
67
- };
68
- exports.getExecutedMigrationsFromVersion = getExecutedMigrationsFromVersion;
package/dist/git/git.js DELETED
@@ -1,130 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.terminals = exports.isWindows = exports.historyError = exports.gitAvailable = exports.getTerminal = exports.getPlanRevisionsFromGit = exports.getPlanFromGit = exports.getHistoricalPlansFromGit = exports.exec = exports.commandAvailable = exports.cmdAvailable = exports.bashAvailable = void 0;
7
- var _chalk = _interopRequireDefault(require("chalk"));
8
- var _process = _interopRequireDefault(require("process"));
9
- var _child_process = require("child_process");
10
- var _hash = require("../hash/hash");
11
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
- const {
13
- platform
14
- } = _process.default;
15
- const isWindows = platform === 'win32';
16
- exports.isWindows = isWindows;
17
- const terminals = Object.freeze({
18
- bash: 'bash',
19
- cmd: 'cmd'
20
- });
21
- exports.terminals = terminals;
22
- const historyError = `Unable to fetch git history. Possible reasons:
23
- - Have you merged latest master branch into your environment (pull latest migrations)?
24
- - Are you trying to downgrade data (not allowed), e.g. newer data into an older environment?
25
- - Not allowed to export from TEST and import to PROD
26
- - Not allowed to export datasets generated from migration feature branches into TEST, PROD or master ENVs
27
- - On Windows? Do you have git and a terminal (bash or cmd) in your PATH? Try cmder.app, gitforwindows.org, or WSL
28
- `;
29
- exports.historyError = historyError;
30
- const commandAvailable = command => {
31
- try {
32
- const exists = isWindows ? 'where' : 'which';
33
- (0, _child_process.execSync)(`${exists} ${command}`);
34
- return true;
35
- } catch (error) {
36
- return false;
37
- }
38
- };
39
- exports.commandAvailable = commandAvailable;
40
- const gitAvailable = () => commandAvailable('git');
41
- exports.gitAvailable = gitAvailable;
42
- const cmdAvailable = () => isWindows && commandAvailable('cmd');
43
- exports.cmdAvailable = cmdAvailable;
44
- const bashAvailable = () => {
45
- if (commandAvailable('bash')) {
46
- try {
47
- const response = (0, _child_process.execSync)('bash --version').toString();
48
- return response.includes('version');
49
- } catch (error) {
50
- return false;
51
- }
52
- }
53
- return false;
54
- };
55
- exports.bashAvailable = bashAvailable;
56
- const getTerminal = () => {
57
- const bashActive = bashAvailable();
58
- const cmdActive = cmdAvailable();
59
- if (!(bashActive || cmdActive)) {
60
- throw new Error('bash terminal (or cmd.exe on Windows) must be installed and in PATH');
61
- }
62
- return isWindows && !bashActive ? terminals.cmd : terminals.bash;
63
- };
64
- exports.getTerminal = getTerminal;
65
- const exec = (command, terminal) => new Promise((resolve, reject) => {
66
- const useWinCmd = terminal === terminals.cmd;
67
- const args = useWinCmd ? ['/c', command] : ['-c', command];
68
- const thread = (0, _child_process.spawn)(terminal, args, {
69
- stdio: ['inherit', 'pipe', 'pipe']
70
- });
71
- const stdOut = [];
72
- const stdErr = [];
73
- thread.stdout.on('data', data => {
74
- stdOut.push(data.toString());
75
- });
76
- thread.stderr.on('data', data => {
77
- stdErr.push(data.toString());
78
- });
79
- thread.on('close', () => {
80
- if (stdErr.length) {
81
- reject(stdErr.join(''));
82
- }
83
- resolve(stdOut.join(''));
84
- });
85
- });
86
- exports.exec = exec;
87
- const getPlanRevisionsFromGit = async (planFilePath, terminal) => {
88
- const command = terminal === terminals.bash ? `git rev-list --pretty="format:%H|%ad" HEAD ${planFilePath}` : `git rev-list --pretty="%H|%ad" HEAD ${planFilePath}`;
89
- const stdOut = await exec(command, terminal);
90
- const lines = stdOut.split(/\r\n|\r|\n/).filter(r => r?.includes('|')).map(r => r?.replace(/"/g, '')); //trim extra double quotes in Windows output
91
- return lines.map(line => {
92
- const [version, timeStamp] = line.split('|');
93
- const utcTimeStamp = new Date(timeStamp).toISOString();
94
- return {
95
- version,
96
- timeStamp: utcTimeStamp
97
- };
98
- });
99
- };
100
- exports.getPlanRevisionsFromGit = getPlanRevisionsFromGit;
101
- const getPlanFromGit = async (planFilePath, revision, terminal) => {
102
- return exec(`git show ${revision}:${planFilePath}`, terminal);
103
- };
104
- exports.getPlanFromGit = getPlanFromGit;
105
- const getHistoricalPlansFromGit = async planFilePath => {
106
- try {
107
- const gitActive = gitAvailable();
108
- if (!gitActive) {
109
- throw new Error('git must be installed and in PATH');
110
- }
111
- const terminal = getTerminal();
112
- const revisions = await getPlanRevisionsFromGit(planFilePath, terminal);
113
- const historicalPlans = await Promise.all(revisions.map(async revision => {
114
- const plan = await getPlanFromGit(planFilePath, revision.version, terminal);
115
- const version = (0, _hash.hash)(plan);
116
- return {
117
- revision,
118
- version,
119
- plan
120
- };
121
- }));
122
- return {
123
- historicalPlans
124
- };
125
- } catch (error) {
126
- console.error(_chalk.default.red(error));
127
- throw new Error('Unable to fetch plan.json history from git');
128
- }
129
- };
130
- exports.getHistoricalPlansFromGit = getHistoricalPlansFromGit;
package/dist/glob/glob.js DELETED
@@ -1,58 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.sortFilePathsByFilename = exports.getUniqueSkippedFileNames = exports.getSkippedFilePaths = exports.getMigrationFilePaths = void 0;
7
- var _path = _interopRequireDefault(require("path"));
8
- var _globPromise = _interopRequireDefault(require("glob-promise"));
9
- var _lodash = require("lodash");
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
- const matchSkip = /(.skip|.skip\d+).js$/g;
12
-
13
- /**
14
- * Sorts migration file paths
15
- *
16
- * @param {Array<String>} filePaths
17
- * @returns {Array<String>} sorted files
18
- */
19
-
20
- const sortFilePathsByFilename = filePaths => (0, _lodash.sortBy)(filePaths, file => {
21
- return _path.default.parse(file).base;
22
- });
23
-
24
- /**
25
- * Gets paths to entity migrations in a directory
26
- *
27
- * @param {String} pathToMigrations
28
- * @returns {Promise<Array<String>>} matching migration filePaths
29
- */
30
- exports.sortFilePathsByFilename = sortFilePathsByFilename;
31
- const getMigrationFilePaths = async pathToMigrations => {
32
- const filePath = pattern => `${pathToMigrations}${pattern}`;
33
- const filePaths = await (0, _globPromise.default)(filePath('/**/*.js'), {
34
- ignore: [filePath('/**/*.skip?([0-9]*).js'), filePath('/**/index.js'), filePath('/**/plan.json'), filePath('/**/*.bundle.js'), filePath('/**/*.test.js'), filePath('/**/*.spec.js'), filePath('/**/__tests__/*'), filePath('/**/__test__/*')]
35
- });
36
- return sortFilePathsByFilename(filePaths);
37
- };
38
-
39
- /**
40
- * Gets paths to skipped migrations in a directory
41
- *
42
- * @param {String} pathToMigrations
43
- * @returns {Promise<Array<String>>} skipped migration filePaths
44
- */
45
- exports.getMigrationFilePaths = getMigrationFilePaths;
46
- const getSkippedFilePaths = async pathToMigrations => {
47
- const filePath = pattern => `${pathToMigrations}${pattern}`;
48
- const filePaths = await (0, _globPromise.default)(filePath('/**/*.skip?([0-9]*).js'), {
49
- ignore: [filePath('/**/index.js'), filePath('/**/plan.json'), filePath('/**/*.bundle.js'), filePath('/**/*.test.js'), filePath('/**/*.spec.js'), filePath('/**/__tests__/*'), filePath('/**/__test__/*')]
50
- });
51
- return sortFilePathsByFilename(filePaths);
52
- };
53
- exports.getSkippedFilePaths = getSkippedFilePaths;
54
- const getUniqueSkippedFileNames = skippedPaths => {
55
- const fileNames = skippedPaths.map(p => _path.default.parse(p).base.replace(matchSkip, '.js'));
56
- return Array.from(new Set(fileNames));
57
- };
58
- exports.getUniqueSkippedFileNames = getUniqueSkippedFileNames;
package/dist/hash/hash.js DELETED
@@ -1,16 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.hash = void 0;
7
- var _crypto = require("crypto");
8
- /**
9
- * Generate SHA256 hash from a string
10
- *
11
- * @param {String} string
12
- * @returns {String} SHA256 hash
13
- */
14
-
15
- const hash = string => (0, _crypto.createHash)('sha256').update(string).digest('hex');
16
- exports.hash = hash;
@@ -1,90 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.printVersionHistory = void 0;
7
- var _chalk = _interopRequireDefault(require("chalk"));
8
- var _git = require("../git/git");
9
- var _database = require("../database/database");
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
- /**
12
- * Parse plan.json
13
- *
14
- * @param {string} plan
15
- * @returns object|null parsed plan
16
- */
17
- const parsePlan = plan => {
18
- return (() => {
19
- try {
20
- return JSON.parse(plan);
21
- } catch (e) {
22
- console.error('Unable to parse plan.json');
23
- return null;
24
- }
25
- })();
26
- };
27
-
28
- /**
29
- * @typedef {Object} Configuration
30
- * @property {string} directory (path to migrations directory)
31
- * @property {string} entity (entity name for payload, e.g. dataset)
32
- * @property {Object} database (connected pg-promise database)
33
- */
34
-
35
- /**
36
- * Prints the version history of plan.json (for debugging)
37
- *
38
- * @param {Object} args
39
- * @param {Configuration} args.config
40
- */
41
- const printVersionHistory = async ({
42
- config
43
- }) => {
44
- const {
45
- database,
46
- entity,
47
- directory
48
- } = config;
49
- try {
50
- const planFilePath = `${directory}/plan.json`;
51
-
52
- //read version history from database cache
53
- const versionHistoryFromDatabase = await (0, _database.getVersions)(database, entity);
54
- const fullDatabaseVersionHistory = versionHistoryFromDatabase.map(d => {
55
- const plan = parsePlan(d?.plan);
56
- const finalMigration = plan?.length ? plan[plan.length - 1] : null;
57
- return {
58
- planVersion: d?.version,
59
- lastFileName: finalMigration?.fileName || null,
60
- lastSequence: finalMigration?.sequence || null
61
- };
62
- });
63
-
64
- //read full version history from git logs (back to beginning of time)
65
- const {
66
- historicalPlans: fullHistoricalPlans
67
- } = await (0, _git.getHistoricalPlansFromGit)(planFilePath);
68
- const fullGitVersionHistory = fullHistoricalPlans.map(p => {
69
- const plan = parsePlan(p?.plan);
70
- const finalMigration = plan?.length ? plan[plan.length - 1] : null;
71
- return {
72
- gitCommitHash: p?.revision?.version,
73
- planVersion: p?.version,
74
- timeStamp: p?.revision?.timeStamp,
75
- lastFileName: finalMigration?.fileName || null,
76
- lastSequence: finalMigration?.sequence || null
77
- };
78
- });
79
- const output = {
80
- fullDatabaseVersionHistory,
81
- fullGitVersionHistory
82
- };
83
- console.log(JSON.stringify(output, null, 2));
84
- } catch (error) {
85
- console.error(_chalk.default.red(error));
86
- console.error(_chalk.default.red(_git.historyError));
87
- throw new Error('Unable to print debug history');
88
- }
89
- };
90
- exports.printVersionHistory = printVersionHistory;