@prisma-psm/core 1.0.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/driver.ts ADDED
@@ -0,0 +1,130 @@
1
+ export interface PSMField {
2
+ comment?:string
3
+ restore?: {
4
+ expression?:string
5
+ }
6
+ }
7
+
8
+
9
+ export interface UniqueOptions {
10
+ name:string,
11
+ fields:string[]
12
+ indexes:[]
13
+ }
14
+
15
+ export interface IndexOptions {
16
+ model:string,
17
+ type:"id"|"unique"|"normal"
18
+ name?:string
19
+ dbName?:string
20
+ isDefinedOnField?:boolean
21
+ algorithm:string
22
+ fields: ({ name:string })[]
23
+ }
24
+ export interface FieldOption {
25
+ "name": string
26
+ documentation?: string
27
+ psm?: PSMField
28
+ dbName?: string
29
+ "kind": "scalar"|"object"
30
+ "isList": boolean,
31
+ "isRequired": boolean,
32
+ "isUnique": boolean,
33
+ "isId": boolean,
34
+ "isReadOnly": boolean,
35
+ "hasDefaultValue": boolean,
36
+ "type": string,
37
+ "isGenerated": boolean,
38
+ "isUpdatedAt": boolean,
39
+ relationName?:string
40
+ relationFromFields?:string[]
41
+ relationToFields?:string[]
42
+ "default"?: {
43
+ "name": string,
44
+ "args": []
45
+ },
46
+ "nativeType"?: [
47
+ string,
48
+ [
49
+ "6"
50
+ ]
51
+ ],
52
+ }
53
+
54
+ export interface PSMParserOptions {
55
+ models:ModelOptions[]
56
+ indexes:IndexOptions[]
57
+ backup:string
58
+ sys:string
59
+ migration:string
60
+ shadow:string
61
+ }
62
+
63
+ export interface PSMModel {
64
+ view?:boolean
65
+ query?:{
66
+ [p:string]:string
67
+ }
68
+ backup?:{
69
+ skip?:boolean
70
+ clean?:boolean,
71
+ rev?:{
72
+ version?:string
73
+ apply?:"ALWAYS"|"WHEN"|"WHEN_EXCEPTION",
74
+ from?: "query"|"query:linked"|"relation"|"model"
75
+ expression?:string
76
+ when?:string
77
+ }
78
+ }
79
+ comment?:string
80
+ }
81
+
82
+ export interface ModelOptions {
83
+ name:string,
84
+ model:string,
85
+ index:number
86
+ documentation?:string,
87
+ psm?:PSMModel,
88
+ dbName?:string,
89
+ schema:string,
90
+ temp:string,
91
+ fields:FieldOption[]
92
+ primaryKey:FieldOption[]
93
+ uniqueFields:string[][]
94
+ uniqueIndexes:UniqueOptions[]
95
+ isGenerated:FieldOption[]
96
+ indexes:IndexOptions[]
97
+ }
98
+
99
+ export interface MigrationOptions {
100
+ sql:string
101
+ url:string
102
+ }
103
+
104
+
105
+ export interface PSMMigrationOptions {
106
+ check:string,
107
+ url:string,
108
+ migrate:string
109
+ }
110
+
111
+ export interface PSMMigrationResult {
112
+ success?:boolean
113
+ messages?:string[]
114
+ error?:any
115
+ }
116
+
117
+
118
+ export type PSMGenerator = ( opts:PSMParserOptions )=>{ check():string, migrate():string}
119
+ export type PSMMigrator = ( opts:PSMMigrationOptions )=>{ test():Promise<PSMMigrationResult>, migrate():Promise<PSMMigrationResult>}
120
+ export interface PSMDriver {
121
+ generator:PSMGenerator,
122
+ migrator:PSMMigrator,
123
+ prepare: ( model:ModelOptions )=>Promise<any>|void
124
+ }
125
+
126
+ export interface DriverConfigs {
127
+ driver:string,
128
+ url:string,
129
+ }
130
+
@@ -0,0 +1,41 @@
1
+ import { GeneratorOptions } from '@prisma/generator-helper';
2
+ export declare function extractModels(options: GeneratorOptions, dirname: string): {
3
+ models: readonly import("@prisma/dmmf/dist/util").ReadonlyDeep<import("@prisma/dmmf/dist/util").ReadonlyDeep<import("@prisma/dmmf/dist/util").ReadonlyDeep<{
4
+ name: string;
5
+ dbName: string | null;
6
+ schema: string | null;
7
+ fields: import("@prisma/dmmf").Field[];
8
+ uniqueFields: string[][];
9
+ uniqueIndexes: import("@prisma/dmmf").uniqueIndex[];
10
+ documentation?: string;
11
+ primaryKey: import("@prisma/dmmf").PrimaryKey | null;
12
+ isGenerated?: boolean;
13
+ }>>>[];
14
+ enums: readonly import("@prisma/dmmf/dist/util").ReadonlyDeep<import("@prisma/dmmf/dist/util").ReadonlyDeep<import("@prisma/dmmf/dist/util").ReadonlyDeep<{
15
+ name: string;
16
+ values: import("@prisma/dmmf").EnumValue[];
17
+ dbName?: string | null;
18
+ documentation?: string;
19
+ }>>>[];
20
+ datamodels: any;
21
+ schema: import("@prisma/dmmf/dist/util").ReadonlyDeep<import("@prisma/dmmf/dist/util").ReadonlyDeep<{
22
+ rootQueryType?: string;
23
+ rootMutationType?: string;
24
+ inputObjectTypes: {
25
+ model?: import("@prisma/dmmf").InputType[];
26
+ prisma: import("@prisma/dmmf").InputType[];
27
+ };
28
+ outputObjectTypes: {
29
+ model: import("@prisma/dmmf").OutputType[];
30
+ prisma: import("@prisma/dmmf").OutputType[];
31
+ };
32
+ enumTypes: {
33
+ model?: import("@prisma/dmmf").SchemaEnum[];
34
+ prisma: import("@prisma/dmmf").SchemaEnum[];
35
+ };
36
+ fieldRefTypes: {
37
+ prisma?: import("@prisma/dmmf").FieldRefType[];
38
+ };
39
+ }>>;
40
+ };
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAG3D,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAC,MAAM;;;;;;;;;;;;;;;;;;gBAY1C,GAAG;;;;;iBAI8hF,CAAC;;;;;;;;iBAA4K,CAAC;;;;kBAAwF,CAAC;;;EADp0F"}
@@ -0,0 +1,53 @@
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 __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.extractModels = extractModels;
38
+ const fs = __importStar(require("fs"));
39
+ function extractModels(options, dirname) {
40
+ const { datamodel, schema } = options.dmmf;
41
+ const { models, enums } = datamodel, extras = __rest(datamodel, ["models", "enums"]);
42
+ fs.writeFileSync(dirname + "/models.json", JSON.stringify(models, null, 2));
43
+ fs.writeFileSync(dirname + "/enums.json", JSON.stringify(enums, null, 2));
44
+ fs.writeFileSync(dirname + "/datamodel.json", JSON.stringify(extras, null, 2));
45
+ fs.writeFileSync(dirname + "/schema.json", JSON.stringify(schema, null, 2));
46
+ return {
47
+ models,
48
+ enums,
49
+ datamodels: extras,
50
+ schema
51
+ };
52
+ }
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,sCAeC;AAjBD,uCAAwB;AAExB,SAAgB,aAAa,CAAC,OAAyB,EAAE,OAAc;IAEnE,MAAM,EAAC,SAAS,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,IAAI,CAAA;IACxC,MAAM,EAAC,MAAM,EAAE,KAAK,KAAe,SAAS,EAAnB,MAAM,UAAI,SAAS,EAAtC,mBAA0B,CAAY,CAAC;IAC7C,EAAE,CAAC,aAAa,CAAE,OAAO,GAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAA;IAC5E,EAAE,CAAC,aAAa,CAAE,OAAO,GAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAA;IAC1E,EAAE,CAAC,aAAa,CAAE,OAAO,GAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAA;IAC/E,EAAE,CAAC,aAAa,CAAE,OAAO,GAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAA;IAE5E,OAAO;QACH,MAAM;QACN,KAAK;QACL,UAAU,EAAC,MAAa;QACxB,MAAM;KACT,CAAA;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { GeneratorOptions } from '@prisma/generator-helper'
2
+ import * as fs from 'fs'
3
+
4
+ export function extractModels(options: GeneratorOptions, dirname:string) {
5
+
6
+ const {datamodel, schema} = options.dmmf
7
+ const {models, enums, ...extras} = datamodel;
8
+ fs.writeFileSync( dirname+"/models.json", JSON.stringify( models, null, 2) )
9
+ fs.writeFileSync( dirname+"/enums.json", JSON.stringify( enums, null, 2) )
10
+ fs.writeFileSync( dirname+"/datamodel.json", JSON.stringify( extras, null, 2) )
11
+ fs.writeFileSync( dirname+"/schema.json", JSON.stringify( schema, null, 2) )
12
+
13
+ return {
14
+ models,
15
+ enums,
16
+ datamodels:extras as any,
17
+ schema
18
+ }
19
+ }
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./driver";
2
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAmBA,cAAc,UAAU,CAAA"}
package/index.js ADDED
@@ -0,0 +1,176 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
+ };
28
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
+ return new (P || (P = Promise))(function (resolve, reject) {
31
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
35
+ });
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ const generator_helper_1 = require("@prisma/generator-helper");
39
+ const fs = __importStar(require("fs"));
40
+ const extractor_1 = require("./extractor");
41
+ const Path = __importStar(require("node:path"));
42
+ const nanoid_1 = require("nanoid");
43
+ const docs_1 = require("./docs");
44
+ const JSON5 = __importStar(require("json5"));
45
+ const process = __importStar(require("node:process"));
46
+ __exportStar(require("./driver"), exports);
47
+ function write(sql, dirname, file) {
48
+ fs.writeFileSync(Path.join(dirname, file), sql);
49
+ }
50
+ (0, generator_helper_1.generatorHandler)({
51
+ onManifest() {
52
+ return {
53
+ version: '1.0.0',
54
+ defaultOutput: './psm',
55
+ prettyName: 'PSM - Prisma Safe Migration',
56
+ };
57
+ },
58
+ onGenerate(options) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ var _a, _b;
61
+ try {
62
+ const home = ((_a = options.generator.output) === null || _a === void 0 ? void 0 : _a.value) || "./psm";
63
+ const definition = Path.join(home, "definitions");
64
+ const revisions = Path.join(home, "revisions");
65
+ const next = Path.join(home, "next");
66
+ fs.mkdirSync(definition, { recursive: true });
67
+ fs.mkdirSync(revisions, { recursive: true });
68
+ fs.mkdirSync(next, { recursive: true });
69
+ const { datamodels, models, enums, schema } = (0, extractor_1.extractModels)(options, definition);
70
+ let rand = (0, nanoid_1.customRandom)("abcdefghijklmnopqrstuvwxyz0123456789", 8, nanoid_1.random);
71
+ const migration = rand();
72
+ const configs = options.generator.config;
73
+ const url = process.env[configs.url];
74
+ const driver = yield Promise.resolve(`${configs.driver}`).then(s => __importStar(require(s)));
75
+ let usePrepare = (model) => {
76
+ return Promise.resolve(driver.prepare(model));
77
+ };
78
+ for (let i = 0; i < models.length; i++) {
79
+ const model = models[i];
80
+ model.model = model.name;
81
+ model.name = model.dbName || model.model;
82
+ if (!!model.documentation) {
83
+ model.psm = (0, docs_1.parsePsmDoc)(model.documentation);
84
+ }
85
+ model.fields.forEach(field => {
86
+ if (!!field.documentation)
87
+ field.psm = (0, docs_1.parsePsmDoc)(field.documentation);
88
+ });
89
+ yield usePrepare(model);
90
+ }
91
+ const opts = {
92
+ models: models,
93
+ indexes: datamodels.indexes,
94
+ migration: migration,
95
+ shadow: `psm_shadow_${rand()}`,
96
+ backup: "backup",
97
+ sys: "sys",
98
+ };
99
+ const generator = driver.generator(opts);
100
+ const check = generator.check();
101
+ const migrate = generator.migrate();
102
+ write(check, next, "migration.next.check.sql");
103
+ let test;
104
+ if (!!url) {
105
+ test = yield driver.migrator({
106
+ migrate: migrate,
107
+ check: check,
108
+ url: url
109
+ }).test();
110
+ }
111
+ if (!configs.url) {
112
+ write(migrate, next, "migration.next.sql");
113
+ }
114
+ else if (!!test && test.success) {
115
+ write(migrate, next, "migration.next.sql");
116
+ }
117
+ else {
118
+ console.error(`TEST OF MIGRATION FAILED! Check file migration.next.check.sql`);
119
+ if (!!((_b = test === null || test === void 0 ? void 0 : test.messages) === null || _b === void 0 ? void 0 : _b.length)) {
120
+ console.log("TESTE MESSAGES>>>>>>>>>>");
121
+ test.messages.forEach(value => {
122
+ console.log(value);
123
+ });
124
+ }
125
+ if (!!(test === null || test === void 0 ? void 0 : test.error)) {
126
+ console.log("TESTE ERROR>>>>>>>>>>");
127
+ console.error(test === null || test === void 0 ? void 0 : test.error);
128
+ }
129
+ }
130
+ write(JSON5.stringify({
131
+ migration: migration,
132
+ driver: options.generator.config.driver,
133
+ test: {
134
+ check: !!test ? "checked" : "skipped",
135
+ success: test === null || test === void 0 ? void 0 : test.success,
136
+ messages: test === null || test === void 0 ? void 0 : test.messages
137
+ }
138
+ }, null, 2), next, "migration.json5");
139
+ }
140
+ catch (e) {
141
+ console.error("console.error", e);
142
+ throw e;
143
+ }
144
+ });
145
+ },
146
+ });
147
+ // const raw = `
148
+ // @psm.view
149
+ // @psm.backup.skip
150
+ // @psm.backup.clean
151
+ // @psm.backup.lists.list1 += 8383
152
+ // @psm.backup.lists.list1 += 8383
153
+ // @psm.backup.lists.list1 += 8383
154
+ // @psm.type = view
155
+ // @psm.view
156
+ // @psm.view2 = true
157
+ // @psm.view3 = false
158
+ // @psm.description = <<<EOF
159
+ // Texto descritivo
160
+ // que ocupa várias linhas
161
+ // e pode ter qualquer coisa dentro.
162
+ // EOF
163
+ // @psm.multline_docs = Line1
164
+ // @psm.multline_docs = Line2
165
+ // @psm.multline_docs = Line3
166
+ // @psm.array += Line1
167
+ // @psm.array += Line2
168
+ // @psm.array += Line3
169
+ // @psm.array += ["Line4"]
170
+ // @psm.array += {i:"line5"}
171
+ // @psm.array_idx[2] = {i:"Array index 2"}
172
+ // @psm.childObject = {type:"Type", usr:"User"}
173
+ // @psm.childObject2 = { "type":"Type", name:"Object2"}
174
+ // `
175
+ // console.log( JSON.stringify( parsePsmDoc(raw), null, 2) );
176
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
package/index.ts ADDED
@@ -0,0 +1,172 @@
1
+ import { GeneratorOptions } from '@prisma/generator-helper'
2
+ import { generatorHandler, GeneratorManifest } from '@prisma/generator-helper'
3
+
4
+ import * as fs from 'fs'
5
+ import {extractModels} from "./extractor";
6
+ import * as Path from "node:path";
7
+ import {customRandom, random} from "nanoid";
8
+ import {
9
+ PSMDriver,
10
+ ModelOptions,
11
+ PSMField,
12
+ PSMModel,
13
+ PSMParserOptions,
14
+ DriverConfigs,
15
+ PSMMigrationResult
16
+ } from "./driver";
17
+ import {parsePsmDoc} from "./docs";
18
+ import * as JSON5 from "json5";
19
+ import * as process from "node:process";
20
+ export * from "./driver"
21
+
22
+ function write( sql:string, dirname:string, file:string){
23
+ fs.writeFileSync( Path.join( dirname, file ), sql );
24
+ }
25
+
26
+ generatorHandler({
27
+ onManifest(): GeneratorManifest {
28
+ return {
29
+ version: '1.0.0',
30
+ defaultOutput: './psm',
31
+ prettyName: 'PSM - Prisma Safe Migration',
32
+ }
33
+ },
34
+
35
+ async onGenerate(options: GeneratorOptions) {
36
+ try{
37
+
38
+ const home = options.generator.output?.value || "./psm";
39
+ const definition = Path.join( home, "definitions");
40
+ const revisions = Path.join( home, "revisions");
41
+ const next = Path.join( home, "next");
42
+
43
+ fs.mkdirSync( definition, { recursive: true });
44
+ fs.mkdirSync( revisions, { recursive: true });
45
+ fs.mkdirSync( next, { recursive: true });
46
+ const { datamodels, models, enums, schema } = extractModels( options, definition );
47
+
48
+
49
+ let rand = customRandom( "abcdefghijklmnopqrstuvwxyz0123456789",8, random);
50
+ const migration = rand();
51
+ const configs:DriverConfigs = options.generator.config as any;
52
+ const url = process.env[configs.url] as string;
53
+
54
+ const driver = await import( configs.driver ) as PSMDriver;
55
+
56
+
57
+ let usePrepare= ( model:ModelOptions )=>{
58
+ return Promise.resolve( driver.prepare( model ) )
59
+ }
60
+
61
+ for (let i = 0; i < models.length; i++) {
62
+ const model = models[i] as any as ModelOptions;
63
+ model.model = model.name;
64
+ model.name = model.dbName||model.model;
65
+
66
+ if( !!model.documentation ){
67
+ model.psm = parsePsmDoc<PSMModel>( model.documentation );
68
+ }
69
+ model.fields.forEach( field => {
70
+ if( !!field.documentation ) field.psm = parsePsmDoc<PSMField>( field.documentation );
71
+ });
72
+ await usePrepare(model);
73
+ }
74
+
75
+
76
+
77
+ const opts: PSMParserOptions = {
78
+ models: models as any,
79
+ indexes: datamodels.indexes,
80
+ migration: migration,
81
+ shadow: `psm_shadow_${rand()}`,
82
+ backup: "backup",
83
+ sys: "sys",
84
+ };
85
+
86
+ const generator = driver.generator(opts);
87
+
88
+ const check = generator.check();
89
+ const migrate = generator.migrate();
90
+
91
+ write( check, next, "migration.next.check.sql" );
92
+
93
+
94
+ let test:PSMMigrationResult|undefined;
95
+
96
+ if( !!url ) {
97
+ test = await driver.migrator({
98
+ migrate: migrate,
99
+ check: check,
100
+ url: url as string
101
+ }).test();
102
+ }
103
+
104
+ if( !configs.url ){
105
+ write( migrate, next, "migration.next.sql" );
106
+ } else if( !!test && test.success ) {
107
+ write( migrate, next, "migration.next.sql" );
108
+ } else {
109
+ console.error( `TEST OF MIGRATION FAILED! Check file migration.next.check.sql` );
110
+ if( !!test?.messages?.length ){
111
+ console.log("TESTE MESSAGES>>>>>>>>>>");
112
+ test.messages.forEach(value => {
113
+ console.log( value)
114
+ });
115
+ }
116
+
117
+ if( !!test?.error ){
118
+ console.log("TESTE ERROR>>>>>>>>>>");
119
+ console.error( test?.error );
120
+ }
121
+ }
122
+
123
+ write( JSON5.stringify({
124
+ migration: migration,
125
+ driver: options.generator.config.driver,
126
+ test: {
127
+ check: !!test? "checked": "skipped",
128
+ success: test?.success,
129
+ messages: test?.messages
130
+ }
131
+ }, null, 2), next, "migration.json5" )
132
+ } catch (e){
133
+ console.error( "console.error", e );
134
+ throw e
135
+ }
136
+ },
137
+ })
138
+
139
+
140
+
141
+
142
+ // const raw = `
143
+ // @psm.view
144
+ // @psm.backup.skip
145
+ // @psm.backup.clean
146
+ // @psm.backup.lists.list1 += 8383
147
+ // @psm.backup.lists.list1 += 8383
148
+ // @psm.backup.lists.list1 += 8383
149
+ // @psm.type = view
150
+ // @psm.view
151
+ // @psm.view2 = true
152
+ // @psm.view3 = false
153
+ // @psm.description = <<<EOF
154
+ // Texto descritivo
155
+ // que ocupa várias linhas
156
+ // e pode ter qualquer coisa dentro.
157
+ // EOF
158
+ // @psm.multline_docs = Line1
159
+ // @psm.multline_docs = Line2
160
+ // @psm.multline_docs = Line3
161
+ // @psm.array += Line1
162
+ // @psm.array += Line2
163
+ // @psm.array += Line3
164
+ // @psm.array += ["Line4"]
165
+ // @psm.array += {i:"line5"}
166
+ // @psm.array_idx[2] = {i:"Array index 2"}
167
+ // @psm.childObject = {type:"Type", usr:"User"}
168
+ // @psm.childObject2 = { "type":"Type", name:"Object2"}
169
+ // `
170
+ // console.log( JSON.stringify( parsePsmDoc(raw), null, 2) );
171
+
172
+
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@prisma-psm/core",
3
+ "version": "1.0.0",
4
+ "description": "PSM - Prisma SAFE MIGRATE",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "",
10
+ "license": "ISC",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "dependencies": {
15
+ "@prisma/generator-helper": "^6.13.0",
16
+ "json5": "^2.2.3",
17
+ "nanoid": "^5.1.5"
18
+ }
19
+ }