@nfjs/migrate
Advanced tools
| import fg from "fast-glob"; | ||
| import { readFile, writeFile, mkdir } from 'fs/promises'; | ||
| import { join, basename, dirname } from 'path'; | ||
| import { extension } from "@nfjs/core"; | ||
| import { NFMig, NFMigDat } from "./migration.js"; | ||
| import { exists, getSchemaModules } from "./utils.js"; | ||
| /** | ||
| * Найти все файлы миграции приложения | ||
| * @param {Object} [schemas=undefined] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @param {boolean} [sorted=false] - признак необходимости сортировки по имени файла миграции | ||
| * @returns {Promise<Object[]>} | ||
| */ | ||
| async function getAllMigrationFiles(schemas = undefined, sorted = false) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules').replace(/\\/g, '/'); | ||
| let dirMigPattern = '*/**/dbsrc/*/mig/*/**.sql'; | ||
| if (schemas) { | ||
| // dirMigPattern = `+(${Object.values(schemas).join('|')})/dbsrc/*/mig/*/**.sql`; | ||
| dirMigPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/mig/*/**.sql`; | ||
| } | ||
| let files = await fg( | ||
| dirMigPattern, | ||
| { cwd: modulesRoot, onlyFiles: true }, | ||
| ); | ||
| if (sorted) { | ||
| files = (files || []) | ||
| .sort((f1, f2) => { | ||
| const n1 = basename(f1); | ||
| const n2 = basename(f2); | ||
| if (n1 < n2) return -1; | ||
| if (n1 > n2) return 1; | ||
| return 0; | ||
| }); | ||
| } | ||
| return files.map(f => ({ | ||
| file: join(modulesRoot, f), | ||
| name: basename(f, '.sql'), | ||
| })); | ||
| } | ||
| /** | ||
| * Найти все файлы объектов базы данных приложения | ||
| * @param {Object} [schemas] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @returns {Promise<Object[]>} | ||
| */ | ||
| async function getAllObjFiles(schemas) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules').replace(/\\/g, '/'); | ||
| let dirObjPattern = '*/**/dbsrc/*/src/*/**.sql'; | ||
| if (schemas) { | ||
| dirObjPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/src/*/**.sql`; | ||
| } | ||
| const files = await fg( | ||
| dirObjPattern, | ||
| { cwd: modulesRoot, onlyFiles: true }, | ||
| ); | ||
| return files.map(f => ({ | ||
| name: basename(f, '.sql'), | ||
| type: basename(dirname(f)), | ||
| schema: basename(dirname(dirname(dirname(f)))), | ||
| file: join(modulesRoot, f) | ||
| })); | ||
| } | ||
| /** | ||
| * Найти все файлы данных со схемами экмпорта\импорта приложения | ||
| * @param {Object} [schemas] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @returns {Promise<Object[]>} | ||
| */ | ||
| async function getAllDatFiles(schemas = undefined) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules'); | ||
| let dirDatPattern = '*/**/dbsrc/*/dat/*'; | ||
| if (schemas) { | ||
| dirDatPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/dat/*`; | ||
| } | ||
| const files = await fg( | ||
| dirDatPattern, | ||
| { cwd: modulesRoot, onlyDirectories: true }, | ||
| ); | ||
| const res = []; | ||
| for (const df of files) { | ||
| const schema = basename(dirname(dirname(df))); | ||
| const table = basename(df); | ||
| const dataFile = join(modulesRoot, df, 'data.json'); | ||
| let iSchFile = join(modulesRoot, df, 'iSch.json'); | ||
| let eSchFile = join(modulesRoot, df, 'eSch.json'); | ||
| let eCommon = false; | ||
| const iSchExists = await exists(iSchFile); | ||
| if (!iSchExists) { | ||
| iSchFile = join(modulesRoot, '@nfjs', 'migrate', 'data_schemas', table, 'iSch.json'); | ||
| } | ||
| const eSchExists = await exists(eSchFile); | ||
| if (!eSchExists) { | ||
| eSchFile = join(modulesRoot, '@nfjs', 'migrate', 'data_schemas', table, 'eSch.json'); | ||
| eCommon = true; | ||
| } | ||
| res.push(new NFMigDat({ | ||
| iSchFile, | ||
| eSchFile, | ||
| dataFile, | ||
| schema, | ||
| table, | ||
| eCommon | ||
| })); | ||
| } | ||
| return res; | ||
| } | ||
| /** | ||
| * Найти все файлы системных объектов\настроек бд | ||
| * @param {Object} [schemas] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @returns {Object[]} | ||
| */ | ||
| async function getAllSysFiles(schemas = undefined) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules').replace(/\\/g, '/'); | ||
| let dirDatPattern = '*/**/dbsrc/*/sys.json'; | ||
| if (schemas) { | ||
| dirDatPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/sys.json`; | ||
| } | ||
| const files = await fg( | ||
| dirDatPattern, | ||
| { cwd: modulesRoot, onlyFiles: true}, | ||
| ); | ||
| const res = { | ||
| extensions: [] | ||
| }; | ||
| for (const df of files) { | ||
| const _f = await readFile(join(modulesRoot, df), 'utf8'); | ||
| const f = JSON.parse(_f); | ||
| if ('extensions' in f) res.extensions.push(...f.extensions); | ||
| } | ||
| res.extensions = [...new Set(res.extensions)]; | ||
| return res; | ||
| } | ||
| async function saveObjToFile(module, schema, objectName, objectType, content) { | ||
| const ext = extension.getExtensions(module); | ||
| let saveDir = ext.dirname; | ||
| saveDir = join(saveDir, 'dbsrc', schema, 'src', objectType); | ||
| try { | ||
| await mkdir(saveDir, { recursive: true }); | ||
| } catch (e) { | ||
| if (e.code !== 'EEXIST') throw (e); | ||
| } | ||
| return writeFile(join(saveDir, `${objectName}.sql`), content); | ||
| } | ||
| async function saveMigrationToFile(name, content) { | ||
| const ext = extension.getSortedExtensions(); | ||
| const parsed = NFMig.parseName(name); | ||
| const module = await getSchemaModules(parsed.schema); | ||
| const modulePath = ext.find(e => e.name === module).dirname; | ||
| let dateDir = name.split('-'); | ||
| dateDir = `${dateDir[0]}-${dateDir[1]}`; | ||
| const saveDir = join(modulePath, 'dbsrc', parsed.schema, 'mig', dateDir); | ||
| try { | ||
| await mkdir(saveDir, { recursive: true }); | ||
| } catch (e) { | ||
| if (!e.code === 'EEXIST') throw (e); | ||
| } | ||
| return writeFile(join(saveDir, name), content); | ||
| } | ||
| export { | ||
| getAllMigrationFiles, | ||
| getAllObjFiles, | ||
| getAllDatFiles, | ||
| getAllSysFiles, | ||
| saveObjToFile, | ||
| saveMigrationToFile, | ||
| } |
+1
-1
| export * as utils from './lib/utils.js'; | ||
| export { NFMig, NFMigObj, NFMigDat } from './lib/migration.js'; | ||
| export * as gather from './lib/gather.js'; | ||
| export * as sourceFiles from './lib/source-files.js'; |
+4
-3
@@ -5,7 +5,8 @@ /* eslint-disable no-await-in-loop */ | ||
| import prompts from 'prompts'; | ||
| import { writeFile } from 'fs/promises'; | ||
| import { dbapi } from '@nfjs/back'; | ||
| import {api, common, config as gConfig} from '@nfjs/core'; | ||
| import { api, common, config as gConfig } from '@nfjs/core'; | ||
| import { NFMigDb, NFMig, NFMigObj, NFMigDat } from './migration.js'; | ||
| import { writeFile, getSchemaModules, sortDependent } from './utils.js'; | ||
| import { getAllObjFiles, getAllMigrationFiles, getAllDatFiles, getAllSysFiles } from './gather.js'; | ||
| import { getSchemaModules, sortDependent } from './utils.js'; | ||
| import { getAllObjFiles, getAllMigrationFiles, getAllDatFiles, getAllSysFiles } from './source-files.js'; | ||
@@ -12,0 +13,0 @@ const MDL_NAME = '@nfjs/migrate'; |
+3
-42
| import { join } from 'path'; | ||
| import { createReadStream } from 'fs'; | ||
| import { api, common, config, extension } from '@nfjs/core'; | ||
| import { readFile } from 'fs/promises'; | ||
| import { api, common, config } from '@nfjs/core'; | ||
| import { DboSequence, DboTable } from '@nfjs/dbo-compare'; | ||
@@ -10,8 +11,4 @@ import { NFLoad, NFExtract } from '@nfjs/ei'; | ||
| random, | ||
| writeFile, | ||
| readFile, | ||
| mkdir, | ||
| getHash, | ||
| sortArrayByName, | ||
| getSchemaModules, | ||
| extractFunctionIdentity, | ||
@@ -337,10 +334,2 @@ extractFunctionReturns, | ||
| getInfo() { | ||
| return { | ||
| name: this.name, | ||
| file: this.file, | ||
| ...this.info, | ||
| }; | ||
| } | ||
| async getSrc() { | ||
@@ -382,19 +371,3 @@ this.src = await readFile(this.file, 'utf8'); | ||
| static async saveToFile(name, content) { | ||
| const ext = extension.getSortedExtensions(); | ||
| const parsed = NFMig._parseName(name); | ||
| const module = await getSchemaModules(parsed.schema); | ||
| const modulePath = ext.find(e => e.name === module).dirname; | ||
| let dateDir = name.split('-'); | ||
| dateDir = `${dateDir[0]}-${dateDir[1]}`; | ||
| const saveDir = join(modulePath, 'dbsrc', parsed.schema, 'mig', dateDir); | ||
| try { | ||
| await mkdir(saveDir, { recursive: true }); | ||
| } catch (e) { | ||
| if (!e.code === 'EEXIST') throw (e); | ||
| } | ||
| return writeFile(join(saveDir, name), content); | ||
| } | ||
| static _parseName(str) { | ||
| static parseName(str) { | ||
| let d = str.replace(/\.sql$/, ''); | ||
@@ -718,14 +691,2 @@ d = d.split('~'); | ||
| static async saveToFile(module, schema, objectName, objectType, content) { | ||
| const ext = extension.getExtensions(module); | ||
| let saveDir = ext.dirname; | ||
| saveDir = join(saveDir, 'dbsrc', schema, 'src', objectType); | ||
| try { | ||
| await mkdir(saveDir, { recursive: true }); | ||
| } catch (e) { | ||
| if (e.code !== 'EEXIST') throw (e); | ||
| } | ||
| return writeFile(join(saveDir, `${objectName}.sql`), content); | ||
| } | ||
| getTextName() { | ||
@@ -732,0 +693,0 @@ return `${this.type} ${this.fullname}`; |
+1
-10
@@ -1,13 +0,7 @@ | ||
| import { readFile as _readFile, writeFile as _writeFile, mkdir as _mkdir, stat } from 'fs'; | ||
| import { promisify } from 'util'; | ||
| import { stat } from 'fs'; | ||
| import crypto from 'crypto'; | ||
| import fg from 'fast-glob'; | ||
| import { join, basename, dirname } from 'path'; | ||
| import { extension } from '@nfjs/core'; | ||
| const readFile = promisify(_readFile); | ||
| const writeFile = promisify(_writeFile); | ||
| const mkdir = promisify(_mkdir); | ||
| /** | ||
@@ -189,5 +183,2 @@ * Проверка файла на существование по абсолютному пути | ||
| exists, | ||
| readFile, | ||
| writeFile, | ||
| mkdir, | ||
| random, | ||
@@ -194,0 +185,0 @@ getHash, |
+1
-1
| { | ||
| "name": "@nfjs/migrate", | ||
| "version": "1.0.1", | ||
| "version": "1.0.2", | ||
| "description": "Database migration tool", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
| COMMENT ON COLUMN public.nf_migrations.filename | ||
| IS 'Имя файла миграции'; |
-138
| import fg from "fast-glob"; | ||
| import { NFMigDat } from "./migration.js"; | ||
| import { exists, readFile } from "./utils.js"; | ||
| import { join, basename, dirname } from 'path'; | ||
| /** | ||
| * Найти все файлы миграции приложения | ||
| * @param {Object} [schemas=undefined] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @param {boolean} [sorted=false] - признак необходимости сортировки по имени файла миграции | ||
| * @returns {Promise<Object[]>} | ||
| */ | ||
| async function getAllMigrationFiles(schemas = undefined, sorted = false) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules').replace(/\\/g, '/'); | ||
| let dirMigPattern = '*/**/dbsrc/*/mig/*/**.sql'; | ||
| if (schemas) { | ||
| // dirMigPattern = `+(${Object.values(schemas).join('|')})/dbsrc/*/mig/*/**.sql`; | ||
| dirMigPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/mig/*/**.sql`; | ||
| } | ||
| let files = await fg( | ||
| dirMigPattern, | ||
| { cwd: modulesRoot, onlyFiles: true }, | ||
| ); | ||
| if (sorted) { | ||
| files = (files || []) | ||
| .sort((f1, f2) => { | ||
| const n1 = basename(f1); | ||
| const n2 = basename(f2); | ||
| if (n1 < n2) return -1; | ||
| if (n1 > n2) return 1; | ||
| return 0; | ||
| }); | ||
| } | ||
| return files.map(f => ({ | ||
| file: join(modulesRoot, f), | ||
| name: basename(f, '.sql'), | ||
| })); | ||
| } | ||
| /** | ||
| * Найти все файлы объектов базы данных приложения | ||
| * @param {Object} [schemas] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @returns {Promise<Object[]>} | ||
| */ | ||
| async function getAllObjFiles(schemas) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules').replace(/\\/g, '/'); | ||
| let dirObjPattern = '*/**/dbsrc/*/src/*/**.sql'; | ||
| if (schemas) { | ||
| dirObjPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/src/*/**.sql`; | ||
| } | ||
| const files = await fg( | ||
| dirObjPattern, | ||
| { cwd: modulesRoot, onlyFiles: true }, | ||
| ); | ||
| return files.map(f => ({ | ||
| name: basename(f, '.sql'), | ||
| type: basename(dirname(f)), | ||
| schema: basename(dirname(dirname(dirname(f)))), | ||
| file: join(modulesRoot, f) | ||
| })); | ||
| } | ||
| /** | ||
| * Найти все файлы данных со схемами экмпорта\импорта приложения | ||
| * @param {Object} [schemas] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @returns {Promise<Object[]>} | ||
| */ | ||
| async function getAllDatFiles(schemas = undefined) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules'); | ||
| let dirDatPattern = '*/**/dbsrc/*/dat/*'; | ||
| if (schemas) { | ||
| dirDatPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/dat/*`; | ||
| } | ||
| const files = await fg( | ||
| dirDatPattern, | ||
| { cwd: modulesRoot, onlyDirectories: true }, | ||
| ); | ||
| const res = []; | ||
| for (const df of files) { | ||
| const schema = basename(dirname(dirname(df))); | ||
| const table = basename(df); | ||
| const dataFile = join(modulesRoot, df, 'data.json'); | ||
| let iSchFile = join(modulesRoot, df, 'iSch.json'); | ||
| let eSchFile = join(modulesRoot, df, 'eSch.json'); | ||
| let eCommon = false; | ||
| const iSchExists = await exists(iSchFile); | ||
| if (!iSchExists) { | ||
| iSchFile = join(modulesRoot, '@nfjs', 'migrate', 'data_schemas', table, 'iSch.json'); | ||
| } | ||
| const eSchExists = await exists(eSchFile); | ||
| if (!eSchExists) { | ||
| eSchFile = join(modulesRoot, '@nfjs', 'migrate', 'data_schemas', table, 'eSch.json'); | ||
| eCommon = true; | ||
| } | ||
| res.push(new NFMigDat({ | ||
| iSchFile, | ||
| eSchFile, | ||
| dataFile, | ||
| schema, | ||
| table, | ||
| eCommon | ||
| })); | ||
| } | ||
| return res; | ||
| } | ||
| /** | ||
| * Найти все файлы системных объектов\настроек бд | ||
| * @param {Object} [schemas] - схемы базы данных и модули, в которых они содержат исходники {"nfc":"@nfjs/back-dbfw"} | ||
| * @returns {Object[]} | ||
| */ | ||
| async function getAllSysFiles(schemas = undefined) { | ||
| const modulesRoot = join(process.cwd(), 'node_modules').replace(/\\/g, '/'); | ||
| let dirDatPattern = '*/**/dbsrc/*/sys.json'; | ||
| if (schemas) { | ||
| dirDatPattern = `*/**/dbsrc/+(${Object.keys(schemas).join('|')})/sys.json`; | ||
| } | ||
| const files = await fg( | ||
| dirDatPattern, | ||
| { cwd: modulesRoot, onlyFiles: true}, | ||
| ); | ||
| const res = { | ||
| extensions: [] | ||
| }; | ||
| for (const df of files) { | ||
| const _f = await readFile(join(modulesRoot, df), 'utf8'); | ||
| const f = JSON.parse(_f); | ||
| if ('extensions' in f) res.extensions.push(...f.extensions); | ||
| } | ||
| res.extensions = [...new Set(res.extensions)]; | ||
| return res; | ||
| } | ||
| export { | ||
| getAllMigrationFiles, | ||
| getAllObjFiles, | ||
| getAllDatFiles, | ||
| getAllSysFiles | ||
| } |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
114773
-0.46%19
-5%2000
-0.6%6
100%1
Infinity%