@prisma-psm/core 1.0.2 → 1.0.4

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.
Files changed (59) hide show
  1. package/README.md +190 -2
  2. package/package.json +14 -2
  3. package/src/configs.d.ts +20 -0
  4. package/src/configs.d.ts.map +1 -0
  5. package/src/configs.js +3 -0
  6. package/src/configs.js.map +1 -0
  7. package/src/configs.ts +19 -0
  8. package/src/driver.d.ts +1 -0
  9. package/src/driver.d.ts.map +1 -1
  10. package/src/driver.ts +2 -1
  11. package/src/index.d.ts.map +1 -1
  12. package/src/index.js +0 -158
  13. package/src/index.js.map +1 -1
  14. package/src/index.ts +1 -171
  15. package/src/launcher/commands/check.d.ts +4 -0
  16. package/src/launcher/commands/check.d.ts.map +1 -0
  17. package/src/launcher/commands/check.js +13 -0
  18. package/src/launcher/commands/check.js.map +1 -0
  19. package/src/launcher/commands/check.ts +17 -0
  20. package/src/launcher/commands/deploy.d.ts +5 -0
  21. package/src/launcher/commands/deploy.d.ts.map +1 -0
  22. package/src/launcher/commands/deploy.js +13 -0
  23. package/src/launcher/commands/deploy.js.map +1 -0
  24. package/src/launcher/commands/deploy.ts +17 -0
  25. package/src/launcher/commands/generate.d.ts +4 -0
  26. package/src/launcher/commands/generate.d.ts.map +1 -0
  27. package/src/launcher/commands/generate.js +14 -0
  28. package/src/launcher/commands/generate.js.map +1 -0
  29. package/src/launcher/commands/generate.ts +18 -0
  30. package/src/launcher/commands/migrate.d.ts +5 -0
  31. package/src/launcher/commands/migrate.d.ts.map +1 -0
  32. package/src/launcher/commands/migrate.js +29 -0
  33. package/src/launcher/commands/migrate.js.map +1 -0
  34. package/src/launcher/commands/migrate.ts +35 -0
  35. package/src/launcher/index.d.ts +3 -0
  36. package/src/launcher/index.d.ts.map +1 -0
  37. package/src/launcher/index.js +17 -0
  38. package/src/launcher/index.js.map +1 -0
  39. package/src/launcher/index.ts +14 -0
  40. package/src/tools/check.d.ts +2 -0
  41. package/src/tools/check.d.ts.map +1 -0
  42. package/src/tools/check.js +6 -0
  43. package/src/tools/check.js.map +1 -0
  44. package/src/tools/check.ts +3 -0
  45. package/src/tools/deploy.d.ts +7 -0
  46. package/src/tools/deploy.d.ts.map +1 -0
  47. package/src/tools/deploy.js +3 -0
  48. package/src/tools/deploy.js.map +1 -0
  49. package/src/tools/deploy.ts +6 -0
  50. package/src/tools/generate.d.ts +2 -0
  51. package/src/tools/generate.d.ts.map +1 -0
  52. package/src/tools/generate.js +158 -0
  53. package/src/tools/generate.js.map +1 -0
  54. package/src/tools/generate.ts +151 -0
  55. package/src/tools/migrate.d.ts +8 -0
  56. package/src/tools/migrate.d.ts.map +1 -0
  57. package/src/tools/migrate.js +137 -0
  58. package/src/tools/migrate.js.map +1 -0
  59. package/src/tools/migrate.ts +121 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["migrate.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC3B,MAAM,CAAC,EAAC,MAAM,CAAA;IACd,QAAQ,CAAC,EAAC,MAAM,CAAA;IAChB,KAAK,CAAC,EAAC,MAAM,CAAA;IACb,kBAAkB,EAAC,MAAM,CAAA;CAC5B;AACD,wBAAsB,OAAO,CAAE,IAAI,EAAC,cAAc,iBAiFjD"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.migrate = migrate;
36
+ const fs = __importStar(require("node:fs"));
37
+ const yaml = __importStar(require("yaml"));
38
+ const Path = __importStar(require("node:path"));
39
+ const node_child_process_1 = require("node:child_process");
40
+ const prisma = [
41
+ `${process.cwd()}/schema.prisma`,
42
+ `${process.cwd()}/prisma/schema.prisma`,
43
+ ];
44
+ function migrate(opts) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ require('dotenv').config();
47
+ console.log(opts);
48
+ if (opts.generate) {
49
+ let command = opts["generate-command"];
50
+ if (!command)
51
+ command = "prisma generate";
52
+ (0, node_child_process_1.spawnSync)("npx", [...command.split(" ")], {
53
+ cwd: process.cwd()
54
+ });
55
+ }
56
+ let schema = opts.schema;
57
+ if (!schema) {
58
+ schema = prisma.find(value => {
59
+ return fs.existsSync(value);
60
+ });
61
+ }
62
+ if (!schema) {
63
+ return console.error("Migrate error: schema.prisma file not found!");
64
+ }
65
+ console.log(`PSM migrate base do schema ${schema}`);
66
+ const home = Path.dirname(schema);
67
+ const psm_yml = Path.join(home, "psm.yml");
68
+ if (!fs.existsSync(psm_yml)) {
69
+ return console.error("Migrate error: psm.yml file not found!");
70
+ }
71
+ console.log(`PSM migrate using ${psm_yml}`);
72
+ const psm = yaml.parse(fs.readFileSync(psm_yml).toString());
73
+ const next = Path.join(psm.psm.output, "next/migration.next.sql");
74
+ const check = Path.join(psm.psm.output, "next/migration.next.check.sql");
75
+ if (!fs.existsSync(check)) {
76
+ return console.error("Migrate error: next/migration.next.check.sql file not found!");
77
+ }
78
+ if (!fs.existsSync(next)) {
79
+ return console.error("Migrate error: next/migration.next.sql file not found!");
80
+ }
81
+ const driver = yield Promise.resolve(`${psm.psm.driver}`).then(s => __importStar(require(s)));
82
+ const migrator = driver.migrator({
83
+ url: process.env[psm.psm.url],
84
+ migrate: fs.readFileSync(next).toString(),
85
+ check: fs.readFileSync(check).toString(),
86
+ });
87
+ let result = yield migrator.test();
88
+ if (!result.success) {
89
+ console.error(result.error);
90
+ result.messages.forEach(error => {
91
+ console.error(error);
92
+ });
93
+ return console.error("Migrate error: Check shadow failed!");
94
+ }
95
+ result = yield migrator.migrate();
96
+ if (!result.success) {
97
+ console.error(result.error);
98
+ result.messages.forEach(error => {
99
+ console.error(error);
100
+ });
101
+ return console.error("Migrate error: Check shadow failed!");
102
+ }
103
+ const moment = require('moment');
104
+ let label = "";
105
+ if (!!opts.label)
106
+ label = ` - ${sanitizeLabel(opts.label)}`;
107
+ psm.migration = {
108
+ instate: moment().format('YYYYMMDDHHmmss'),
109
+ preview: getLatestFolder(Path.join(home, `psm/revisions/schema`)),
110
+ label: opts.label
111
+ };
112
+ const nextRev = Path.join(home, `psm/revisions/schema/${psm.migration.instate}${label}`);
113
+ fs.mkdirSync(nextRev, { recursive: true });
114
+ fs.renameSync(next, Path.join(nextRev, "migration.sql"));
115
+ fs.writeFileSync(Path.join(nextRev, "psm.yml"), yaml.stringify(psm));
116
+ fs.unlinkSync(check);
117
+ });
118
+ }
119
+ // Função para obter a pasta com maior instante
120
+ function getLatestFolder(basePath) {
121
+ if (!fs.existsSync(basePath))
122
+ return null;
123
+ const dirs = fs.readdirSync(basePath, { withFileTypes: true })
124
+ .filter(d => d.isDirectory())
125
+ .map(d => d.name)
126
+ .filter(name => /^\d{14}( - .+)?$/.test(name))
127
+ .sort((a, b) => b.localeCompare(a));
128
+ return dirs[0] || null;
129
+ }
130
+ function sanitizeLabel(label) {
131
+ return label
132
+ .replace(/[<>:"/\\|?*\x00-\x1F]/g, '') // remove caracteres inválidos no Windows
133
+ .replace(/[\u{0080}-\u{FFFF}]/gu, '') // remove caracteres não ASCII (opcional)
134
+ .trim()
135
+ .replace(/\s+/g, ' '); // normaliza espaços
136
+ }
137
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ import * as fs from "node:fs";
2
+ import * as yaml from "yaml";
3
+ import * as Path from "node:path";
4
+ import {PSMConfigFile} from "../configs";
5
+ import {PSMDriver} from "../driver";
6
+ import { spawnSync } from "node:child_process";
7
+ import moment from "moment/moment";
8
+
9
+ const prisma = [
10
+ `${process.cwd()}/schema.prisma`,
11
+ `${process.cwd()}/prisma/schema.prisma`,
12
+ ];
13
+
14
+ export interface MigrateOptions {
15
+ schema?:string
16
+ generate?:string
17
+ label?:string
18
+ "generate-command":string
19
+ }
20
+ export async function migrate( opts:MigrateOptions ) {
21
+ require('dotenv').config();
22
+ console.log( opts )
23
+ if( opts.generate ) {
24
+ let command = opts["generate-command"];
25
+ if( !command) command = "prisma generate"
26
+ spawnSync( "npx", [ ...command.split(" ") ], {
27
+ cwd: process.cwd()
28
+ });
29
+ }
30
+ let schema = opts.schema;
31
+ if( !schema ) {
32
+ schema = prisma.find( value => {
33
+ return fs.existsSync( value );
34
+ })
35
+ }
36
+ if( !schema ) {
37
+ return console.error( "Migrate error: schema.prisma file not found!" );
38
+ }
39
+
40
+ console.log(`PSM migrate base do schema ${schema}`);
41
+
42
+ const home = Path.dirname( schema );
43
+ const psm_yml = Path.join( home, "psm.yml" );
44
+ if( !fs.existsSync( psm_yml ) ) {
45
+ return console.error( "Migrate error: psm.yml file not found!" );
46
+ }
47
+
48
+ console.log(`PSM migrate using ${psm_yml}`);
49
+ const psm = yaml.parse( fs.readFileSync( psm_yml ).toString() ) as PSMConfigFile;
50
+ const next = Path.join( psm.psm.output, "next/migration.next.sql");
51
+ const check = Path.join( psm.psm.output, "next/migration.next.check.sql");
52
+
53
+ if( !fs.existsSync( check) ) {
54
+ return console.error( "Migrate error: next/migration.next.check.sql file not found!" );
55
+ }
56
+ if( !fs.existsSync( next) ) {
57
+ return console.error( "Migrate error: next/migration.next.sql file not found!" );
58
+ }
59
+
60
+
61
+ const driver = await import( psm.psm.driver ) as PSMDriver;
62
+ const migrator = driver.migrator({
63
+ url: process.env[psm.psm.url],
64
+ migrate: fs.readFileSync( next ).toString(),
65
+ check: fs.readFileSync( check ).toString(),
66
+ });
67
+
68
+ let result = await migrator.test();
69
+ if( !result.success ) {
70
+ console.error( result.error );
71
+ result.messages.forEach( error => {
72
+ console.error( error );
73
+ });
74
+ return console.error( "Migrate error: Check shadow failed!" );
75
+ }
76
+
77
+ result = await migrator.migrate();
78
+ if( !result.success ) {
79
+ console.error( result.error );
80
+ result.messages.forEach( error => {
81
+ console.error( error );
82
+ });
83
+ return console.error( "Migrate error: Check shadow failed!" );
84
+ }
85
+
86
+ const moment = require('moment');
87
+ let label = "";
88
+ if( !!opts.label ) label = ` - ${sanitizeLabel( opts.label )}`
89
+ psm.migration = {
90
+ instate: moment().format( 'YYYYMMDDHHmmss' ),
91
+ preview: getLatestFolder( Path.join( home, `psm/revisions/schema`)),
92
+ label: opts.label
93
+ }
94
+ const nextRev = Path.join( home, `psm/revisions/schema/${psm.migration.instate}${label}`);
95
+
96
+
97
+ fs.mkdirSync( nextRev, { recursive: true });
98
+ fs.renameSync( next, Path.join( nextRev, "migration.sql" ) );
99
+ fs.writeFileSync( Path.join( nextRev, "psm.yml" ), yaml.stringify( psm ) );
100
+ fs.unlinkSync( check );
101
+ }
102
+
103
+
104
+ // Função para obter a pasta com maior instante
105
+ function getLatestFolder(basePath:string) {
106
+ if (!fs.existsSync(basePath)) return null;
107
+ const dirs = fs.readdirSync(basePath, { withFileTypes: true })
108
+ .filter(d => d.isDirectory())
109
+ .map(d => d.name)
110
+ .filter(name => /^\d{14}( - .+)?$/.test(name))
111
+ .sort((a, b) => b.localeCompare(a));
112
+ return dirs[0] || null;
113
+ }
114
+
115
+ function sanitizeLabel( label:string ) {
116
+ return label
117
+ .replace(/[<>:"/\\|?*\x00-\x1F]/g, '') // remove caracteres inválidos no Windows
118
+ .replace(/[\u{0080}-\u{FFFF}]/gu, '') // remove caracteres não ASCII (opcional)
119
+ .trim()
120
+ .replace(/\s+/g, ' '); // normaliza espaços
121
+ }