nesoi 3.0.9 → 3.0.10
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/lib/compiler/apps/monolyth/monolyth_compiler.d.ts +1 -1
- package/lib/compiler/apps/monolyth/monolyth_compiler.js +7 -7
- package/lib/elements/blocks/machine/machine.builder.js +12 -1
- package/lib/elements/blocks/machine/machine.schema.d.ts +2 -1
- package/lib/elements/blocks/machine/machine.schema.js +2 -1
- package/lib/elements/edge/controller/adapters/controller_adapter.d.ts +3 -1
- package/lib/elements/edge/controller/adapters/controller_adapter.js +2 -1
- package/lib/elements/edge/controller/controller.config.d.ts +3 -2
- package/lib/elements/edge/controller/controller.d.ts +3 -3
- package/lib/elements/edge/controller/controller.js +3 -3
- package/lib/elements/entities/bucket/adapters/bucket_adapter.d.ts +2 -1
- package/lib/elements/entities/bucket/bucket.config.d.ts +3 -3
- package/lib/elements/entities/bucket/bucket.d.ts +3 -2
- package/lib/elements/entities/bucket/bucket.js +4 -4
- package/lib/engine/apps/app.config.d.ts +12 -11
- package/lib/engine/apps/app.d.ts +11 -22
- package/lib/engine/apps/app.js +9 -9
- package/lib/engine/apps/inline.app.d.ts +9 -8
- package/lib/engine/apps/inline.app.js +24 -24
- package/lib/engine/apps/monolyth/monolyth.app.d.ts +5 -5
- package/lib/engine/apps/monolyth/monolyth.app.js +6 -6
- package/lib/engine/apps/service.d.ts +30 -0
- package/lib/engine/apps/service.js +15 -0
- package/lib/engine/auth/authn.d.ts +10 -1
- package/lib/engine/auth/zero.authn_provider.d.ts +7 -3
- package/lib/engine/auth/zero.authn_provider.js +9 -2
- package/lib/engine/cli/cli.d.ts +2 -2
- package/lib/engine/cli/cli.js +1 -1
- package/lib/engine/cli/ui.js +1 -1
- package/lib/engine/daemon.d.ts +11 -11
- package/lib/engine/daemon.js +18 -18
- package/lib/engine/dependency.d.ts +2 -1
- package/lib/engine/dependency.js +18 -0
- package/lib/engine/module.d.ts +6 -4
- package/lib/engine/module.js +25 -10
- package/lib/engine/transaction/nodes/bucket.trx_node.js +1 -2
- package/lib/engine/transaction/nodes/bucket_query.trx_node.js +5 -10
- package/lib/engine/transaction/nodes/job.trx_node.js +2 -4
- package/lib/engine/transaction/nodes/machine.trx_node.js +2 -4
- package/lib/engine/transaction/nodes/queue.trx_node.js +1 -2
- package/lib/engine/transaction/nodes/resource.trx_node.js +2 -4
- package/lib/engine/transaction/trx.d.ts +6 -4
- package/lib/engine/transaction/trx.js +2 -1
- package/lib/engine/transaction/trx_engine.config.d.ts +2 -2
- package/lib/engine/transaction/trx_engine.d.ts +4 -3
- package/lib/engine/transaction/trx_engine.js +20 -17
- package/lib/engine/transaction/trx_node.d.ts +4 -2
- package/lib/engine/transaction/trx_node.js +13 -1
- package/lib/engine/tree.js +6 -17
- package/lib/schema.d.ts +1 -1
- package/package.json +2 -3
- package/tools/joaquin/job.js +2 -2
- package/tools/joaquin/message.js +2 -2
- package/tools/joaquin/mock.d.ts +6 -6
- package/tsconfig.build.tsbuildinfo +1 -1
- package/lib/adapters/postgres/src/migrator/csv.d.ts +0 -7
- package/lib/adapters/postgres/src/migrator/csv.js +0 -72
- package/lib/adapters/postgres/src/migrator/database.d.ts +0 -34
- package/lib/adapters/postgres/src/migrator/database.js +0 -88
- package/lib/adapters/postgres/src/migrator/generator/generator.d.ts +0 -22
- package/lib/adapters/postgres/src/migrator/generator/generator.js +0 -326
- package/lib/adapters/postgres/src/migrator/generator/migration.d.ts +0 -66
- package/lib/adapters/postgres/src/migrator/generator/migration.js +0 -249
- package/lib/adapters/postgres/src/migrator/generator/provider.d.ts +0 -19
- package/lib/adapters/postgres/src/migrator/generator/provider.js +0 -74
- package/lib/adapters/postgres/src/migrator/index.d.ts +0 -47
- package/lib/adapters/postgres/src/migrator/index.js +0 -22
- package/lib/adapters/postgres/src/migrator/runner/runner.d.ts +0 -17
- package/lib/adapters/postgres/src/migrator/runner/runner.js +0 -249
- package/lib/adapters/postgres/src/migrator/runner/status.d.ts +0 -17
- package/lib/adapters/postgres/src/migrator/runner/status.js +0 -55
- package/lib/adapters/postgres/src/postgres.bucket_adapter.d.ts +0 -42
- package/lib/adapters/postgres/src/postgres.bucket_adapter.js +0 -294
- package/lib/adapters/postgres/src/postgres.cli.d.ts +0 -76
- package/lib/adapters/postgres/src/postgres.cli.js +0 -207
- package/lib/adapters/postgres/src/postgres.config.d.ts +0 -5
- package/lib/adapters/postgres/src/postgres.config.js +0 -2
- package/lib/adapters/postgres/src/postgres.nql.d.ts +0 -16
- package/lib/adapters/postgres/src/postgres.nql.js +0 -123
- package/lib/adapters/postgres/src/postgres.provider.d.ts +0 -18
- package/lib/adapters/postgres/src/postgres.provider.js +0 -77
- package/lib/adapters/postgres/test/postgres.bucket_adapter.test.d.ts +0 -1
- package/lib/adapters/postgres/test/postgres.bucket_adapter.test.js +0 -210
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { $Bucket, $Space } from "../../../../../elements";
|
|
2
|
-
import postgres from 'postgres';
|
|
3
|
-
import { AnyDaemon } from "../../../../../engine/daemon";
|
|
4
|
-
import { BucketAdapterConfig } from "../../../../../elements/entities/bucket/adapters/bucket_adapter";
|
|
5
|
-
import { $Migration } from './migration';
|
|
6
|
-
export declare class MigrationGenerator<S extends $Space, D extends AnyDaemon, ModuleName extends NoInfer<keyof S['modules']>> {
|
|
7
|
-
private sql;
|
|
8
|
-
private module;
|
|
9
|
-
private tableName;
|
|
10
|
-
protected schema: $Bucket;
|
|
11
|
-
protected config?: BucketAdapterConfig;
|
|
12
|
-
constructor(daemon: D, sql: postgres.Sql<any>, module: ModuleName, bucketName: NoInfer<keyof S['modules'][ModuleName]['buckets']>, tableName: string);
|
|
13
|
-
generate(): Promise<$Migration | undefined>;
|
|
14
|
-
private getCurrentSchema;
|
|
15
|
-
private generateDrops;
|
|
16
|
-
private generateSteps;
|
|
17
|
-
private generateFieldSteps;
|
|
18
|
-
private fieldUdt;
|
|
19
|
-
private fieldTypeFromUdt;
|
|
20
|
-
private fieldType;
|
|
21
|
-
private manualReview;
|
|
22
|
-
}
|
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MigrationGenerator = void 0;
|
|
7
|
-
const daemon_1 = require("../../../../../engine/daemon");
|
|
8
|
-
const migration_1 = require("./migration");
|
|
9
|
-
const string_1 = require("../../../../../engine/util/string");
|
|
10
|
-
const ui_1 = __importDefault(require("../../../../../engine/cli/ui"));
|
|
11
|
-
const log_1 = require("../../../../../engine/util/log");
|
|
12
|
-
class MigrationOption {
|
|
13
|
-
constructor(schema) {
|
|
14
|
-
this.schema = schema;
|
|
15
|
-
this.selected = false;
|
|
16
|
-
this.excluded_by = [];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
class MigrationGenerator {
|
|
20
|
-
constructor(daemon, sql, module, bucketName, tableName) {
|
|
21
|
-
this.sql = sql;
|
|
22
|
-
this.module = module;
|
|
23
|
-
this.tableName = tableName;
|
|
24
|
-
const bucket = daemon_1.Daemon.getModule(daemon, module).buckets[bucketName];
|
|
25
|
-
this.schema = bucket.schema;
|
|
26
|
-
this.config = bucket.adapter.config;
|
|
27
|
-
}
|
|
28
|
-
async generate() {
|
|
29
|
-
const current = await this.getCurrentSchema();
|
|
30
|
-
const drops = current ? this.generateDrops(current.columns) : {};
|
|
31
|
-
const steps = this.generateSteps(current?.mapped, drops);
|
|
32
|
-
steps.push(...Object.values(drops).map(d => ({
|
|
33
|
-
options: [d]
|
|
34
|
-
})));
|
|
35
|
-
if (!steps.length) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const type = current ? 'alter' : 'create';
|
|
39
|
-
const migration = await this.manualReview(type, steps);
|
|
40
|
-
return migration;
|
|
41
|
-
}
|
|
42
|
-
async getCurrentSchema() {
|
|
43
|
-
const rawColumns = await this.sql `
|
|
44
|
-
SELECT column_name, udt_name, is_nullable, numeric_precision, numeric_scale
|
|
45
|
-
FROM information_schema.columns
|
|
46
|
-
WHERE table_name = ${this.tableName}`;
|
|
47
|
-
if (!rawColumns.length) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const columns = rawColumns.map(col => ({
|
|
51
|
-
column_name: col.column_name,
|
|
52
|
-
udt_name: col.udt_name,
|
|
53
|
-
data_type: this.fieldTypeFromUdt(col.udt_name, {
|
|
54
|
-
n0: col.numeric_precision,
|
|
55
|
-
n1: col.numeric_scale,
|
|
56
|
-
}),
|
|
57
|
-
nullable: col.is_nullable === 'YES',
|
|
58
|
-
field_exists: false
|
|
59
|
-
}));
|
|
60
|
-
// Map current columns by name, and flag if they already exist
|
|
61
|
-
const mapped = {};
|
|
62
|
-
columns.forEach(col => {
|
|
63
|
-
mapped[col.column_name] = col;
|
|
64
|
-
const created_by = this.config?.meta.created_by || 'created_by';
|
|
65
|
-
const created_at = this.config?.meta.created_at || 'created_at';
|
|
66
|
-
const updated_by = this.config?.meta.updated_by || 'updated_by';
|
|
67
|
-
const updated_at = this.config?.meta.updated_at || 'updated_at';
|
|
68
|
-
if (col.column_name === created_by
|
|
69
|
-
|| col.column_name === created_at
|
|
70
|
-
|| col.column_name === updated_by
|
|
71
|
-
|| col.column_name === updated_at) {
|
|
72
|
-
mapped[col.column_name].field_exists = true;
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
Object.keys(this.schema.model.fields)
|
|
76
|
-
.forEach(name => {
|
|
77
|
-
if (mapped[name]) {
|
|
78
|
-
mapped[name].field_exists = true;
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
return { columns, mapped };
|
|
82
|
-
}
|
|
83
|
-
generateDrops(columns) {
|
|
84
|
-
const drops = {};
|
|
85
|
-
for (const col of columns) {
|
|
86
|
-
if (col.field_exists)
|
|
87
|
-
continue;
|
|
88
|
-
drops[col.column_name] = new MigrationOption(new migration_1.$MigrationField(col.column_name, {
|
|
89
|
-
drop: {
|
|
90
|
-
type: col.data_type,
|
|
91
|
-
nullable: col.nullable
|
|
92
|
-
}
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
|
-
return drops;
|
|
96
|
-
}
|
|
97
|
-
generateSteps(current, drops = {}) {
|
|
98
|
-
const steps = [];
|
|
99
|
-
// Generate migration step for each field
|
|
100
|
-
Object.values(this.schema.model.fields)
|
|
101
|
-
.forEach(field => {
|
|
102
|
-
const fieldSteps = this.generateFieldSteps(field, current, drops);
|
|
103
|
-
if (fieldSteps.length) {
|
|
104
|
-
steps.push(...fieldSteps);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
// Add meta fields when creating table
|
|
108
|
-
if (!current) {
|
|
109
|
-
const created_by = this.config?.meta.created_by || 'created_by';
|
|
110
|
-
const created_at = this.config?.meta.created_at || 'created_at';
|
|
111
|
-
const updated_by = this.config?.meta.updated_by || 'updated_by';
|
|
112
|
-
const updated_at = this.config?.meta.updated_at || 'updated_at';
|
|
113
|
-
steps.push({ options: [new MigrationOption(new migration_1.$MigrationField(created_by, {
|
|
114
|
-
create: { type: 'character(64)', nullable: true }
|
|
115
|
-
}))] });
|
|
116
|
-
steps.push({ options: [new MigrationOption(new migration_1.$MigrationField(created_at, {
|
|
117
|
-
create: { type: 'timestamp without time zone' }
|
|
118
|
-
}))] });
|
|
119
|
-
steps.push({ options: [new MigrationOption(new migration_1.$MigrationField(updated_by, {
|
|
120
|
-
create: { type: 'character(64)', nullable: true }
|
|
121
|
-
}))] });
|
|
122
|
-
steps.push({ options: [new MigrationOption(new migration_1.$MigrationField(updated_at, {
|
|
123
|
-
create: { type: 'timestamp without time zone' }
|
|
124
|
-
}))] });
|
|
125
|
-
}
|
|
126
|
-
return steps;
|
|
127
|
-
}
|
|
128
|
-
generateFieldSteps($, current, drops = {}) {
|
|
129
|
-
const type = this.fieldType($);
|
|
130
|
-
const pk = $.name === 'id';
|
|
131
|
-
const nullable = !$.required;
|
|
132
|
-
// Table doesn't exist yet, only option is to create the field
|
|
133
|
-
if (!current) {
|
|
134
|
-
const options = [
|
|
135
|
-
new MigrationOption(new migration_1.$MigrationField($.name, {
|
|
136
|
-
create: { type, pk, nullable }
|
|
137
|
-
}))
|
|
138
|
-
];
|
|
139
|
-
return [{ options }];
|
|
140
|
-
}
|
|
141
|
-
// Table exists, evaluate options
|
|
142
|
-
else {
|
|
143
|
-
const col = current[$.name];
|
|
144
|
-
// Field exists in columns, alter only what changed
|
|
145
|
-
if (col) {
|
|
146
|
-
if ($.name === 'id') {
|
|
147
|
-
// Id can't be modified for now.
|
|
148
|
-
return [];
|
|
149
|
-
}
|
|
150
|
-
// TODO: check details such as
|
|
151
|
-
// - changes in decimal precision
|
|
152
|
-
// - changes in maxLength
|
|
153
|
-
const typeChanged = !type.startsWith(col.data_type);
|
|
154
|
-
const nullableChanged = col.nullable !== nullable;
|
|
155
|
-
const steps = [];
|
|
156
|
-
if (typeChanged) {
|
|
157
|
-
const options = [
|
|
158
|
-
new MigrationOption(new migration_1.$MigrationField($.name, {
|
|
159
|
-
alter_type: { from: col.data_type, to: type, using: {} }
|
|
160
|
-
}))
|
|
161
|
-
];
|
|
162
|
-
steps.push({ options });
|
|
163
|
-
}
|
|
164
|
-
if (nullableChanged) {
|
|
165
|
-
const options = [
|
|
166
|
-
new MigrationOption(new migration_1.$MigrationField($.name, {
|
|
167
|
-
alter_null: { from: col.nullable, to: nullable }
|
|
168
|
-
}))
|
|
169
|
-
];
|
|
170
|
-
steps.push({ options });
|
|
171
|
-
}
|
|
172
|
-
return steps;
|
|
173
|
-
}
|
|
174
|
-
// Field doesn't exists in columns, it might:
|
|
175
|
-
// - 1: be a new field
|
|
176
|
-
// - 2: be a field of the same type being renamed
|
|
177
|
-
else {
|
|
178
|
-
const options = [];
|
|
179
|
-
// Option 1
|
|
180
|
-
const createOption = new MigrationOption(new migration_1.$MigrationField($.name, {
|
|
181
|
-
create: { type, pk, nullable }
|
|
182
|
-
}));
|
|
183
|
-
options.push(createOption);
|
|
184
|
-
const deletedColumnsOfSameType = Object.values(current)
|
|
185
|
-
.filter(col => !col.field_exists)
|
|
186
|
-
.filter(col => type.startsWith(col.data_type));
|
|
187
|
-
if (deletedColumnsOfSameType.length) {
|
|
188
|
-
// TODO: check details such as
|
|
189
|
-
// - changes in decimal precision
|
|
190
|
-
// - changes in maxLength
|
|
191
|
-
deletedColumnsOfSameType.forEach(col => {
|
|
192
|
-
// Option 2
|
|
193
|
-
const renameOption = new MigrationOption(new migration_1.$MigrationField(col.column_name, {
|
|
194
|
-
rename: { name: $.name }
|
|
195
|
-
}));
|
|
196
|
-
options.push(renameOption);
|
|
197
|
-
// If this option is picked, the drop option for this column is no longer valid
|
|
198
|
-
drops[col.column_name].excluded_by.push(renameOption);
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
return [{ options }];
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
fieldUdt($) {
|
|
206
|
-
if ($.name === 'id') {
|
|
207
|
-
if ($.type === 'string') {
|
|
208
|
-
return 'bpchar';
|
|
209
|
-
}
|
|
210
|
-
return 'int4';
|
|
211
|
-
}
|
|
212
|
-
let type = {
|
|
213
|
-
'boolean': () => 'bool',
|
|
214
|
-
'date': () => 'date',
|
|
215
|
-
'datetime': () => 'timestamp',
|
|
216
|
-
'decimal': () => 'numeric',
|
|
217
|
-
'dict': () => 'jsonb',
|
|
218
|
-
'enum': () => 'bpchar', // TODO: read from schema maxLength
|
|
219
|
-
'file': () => 'jsonb',
|
|
220
|
-
'float': () => 'float8',
|
|
221
|
-
'int': () => 'int4',
|
|
222
|
-
'obj': () => 'jsonb',
|
|
223
|
-
'string': () => 'varchar', // TODO: char() if maxLength
|
|
224
|
-
'unknown': () => { throw new Error('An unknown field shouldn\'t be stored on SQL'); },
|
|
225
|
-
}[$.type]();
|
|
226
|
-
if ($.array) {
|
|
227
|
-
type = '_' + type;
|
|
228
|
-
}
|
|
229
|
-
return type;
|
|
230
|
-
}
|
|
231
|
-
fieldTypeFromUdt(udt, extra) {
|
|
232
|
-
const array = udt.startsWith('_');
|
|
233
|
-
if (array)
|
|
234
|
-
udt = udt.slice(1);
|
|
235
|
-
let type = {
|
|
236
|
-
'bool': () => 'boolean',
|
|
237
|
-
'date': () => 'date',
|
|
238
|
-
'timestamp': () => 'timestamp',
|
|
239
|
-
'numeric': () => `numeric(${extra.n0},${extra.n1})`,
|
|
240
|
-
'jsonb': () => 'jsonb',
|
|
241
|
-
'bpchar': () => 'character(64)', // TODO: read from schema maxLength
|
|
242
|
-
'float8': () => 'double precision',
|
|
243
|
-
'int4': () => 'integer',
|
|
244
|
-
'varchar': () => 'character varying', // TODO: char() if maxLength
|
|
245
|
-
'unknown': () => { throw new Error('An unknown field shouldn\'t be stored on SQL'); },
|
|
246
|
-
}[udt]();
|
|
247
|
-
if (array)
|
|
248
|
-
type += '[]';
|
|
249
|
-
return type;
|
|
250
|
-
}
|
|
251
|
-
fieldType($) {
|
|
252
|
-
const udt = this.fieldUdt($);
|
|
253
|
-
return this.fieldTypeFromUdt(udt, {
|
|
254
|
-
n0: ($.meta?.decimal?.left || 9) + ($.meta?.decimal?.right || 9),
|
|
255
|
-
n1: $.meta?.decimal?.right || 9
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
async manualReview(type, steps) {
|
|
259
|
-
let header_shown = false;
|
|
260
|
-
const header = () => {
|
|
261
|
-
if (header_shown)
|
|
262
|
-
return;
|
|
263
|
-
let str = '';
|
|
264
|
-
str += '┌\n';
|
|
265
|
-
str += `│ module: ${(0, string_1.colored)(this.module, 'cyan')}\n`;
|
|
266
|
-
str += `│ table: ${(0, string_1.colored)(this.tableName, 'lightcyan')}\n`;
|
|
267
|
-
str += `│ ${(0, string_1.colored)('⚠ Requires manual review.', 'red')}\n`;
|
|
268
|
-
str += '└\n\n';
|
|
269
|
-
console.clear();
|
|
270
|
-
console.log(str);
|
|
271
|
-
header_shown = true;
|
|
272
|
-
};
|
|
273
|
-
const fields = [];
|
|
274
|
-
for (const step of steps) {
|
|
275
|
-
const stepFields = step.options.filter(field => {
|
|
276
|
-
if (field.excluded_by.length === 0)
|
|
277
|
-
return true;
|
|
278
|
-
return !field.excluded_by.some(field => field.selected);
|
|
279
|
-
});
|
|
280
|
-
let schema;
|
|
281
|
-
if (stepFields.length === 0) {
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
else if (stepFields.length === 1) {
|
|
285
|
-
schema = stepFields[0].schema;
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
header();
|
|
289
|
-
const opt = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
290
|
-
const selected = await ui_1.default.select('Pick one of the options below:\n', stepFields.map((s, i) => `${(0, string_1.colored)(opt[i], 'lightcyan')} ${stepFields[i].schema.describe()}`));
|
|
291
|
-
console.log();
|
|
292
|
-
stepFields[selected.i].selected = true;
|
|
293
|
-
schema = stepFields[selected.i].schema;
|
|
294
|
-
}
|
|
295
|
-
if ('drop' in schema.operation && !schema.operation.drop.nullable) {
|
|
296
|
-
header();
|
|
297
|
-
const defaul = await ui_1.default.question(`Column '${schema.column}' is NOT NULL and is being deleted. What should be the default value on rollback?\n`);
|
|
298
|
-
schema.operation.drop.default = defaul;
|
|
299
|
-
}
|
|
300
|
-
if ('alter_type' in schema.operation) {
|
|
301
|
-
header();
|
|
302
|
-
const from = (0, string_1.colored)(schema.operation.alter_type.from, 'lightcyan');
|
|
303
|
-
const to = (0, string_1.colored)(schema.operation.alter_type.to, 'lightcyan');
|
|
304
|
-
const up = (0, string_1.colored)('▲ UP', 'lightgreen');
|
|
305
|
-
const down = (0, string_1.colored)('▼ DOWN', 'yellow');
|
|
306
|
-
const defaultUp = `${schema.column}::${schema.operation.alter_type.to}`;
|
|
307
|
-
const defaultDown = `${schema.column}::${schema.operation.alter_type.from}`;
|
|
308
|
-
const usingUp = await ui_1.default.question(`Column '${schema.column}' is changing from ${from} to ${to}. Write a cast expression for the ${up} migration.\n`, defaultUp);
|
|
309
|
-
const usingDown = await ui_1.default.question(`Column '${schema.column}' is changing from ${from} to ${to}. Write a cast expression for the ${down} migration.\n`, defaultDown);
|
|
310
|
-
schema.operation.alter_type.using.up = usingUp;
|
|
311
|
-
schema.operation.alter_type.using.down = usingDown;
|
|
312
|
-
}
|
|
313
|
-
fields.push(schema);
|
|
314
|
-
}
|
|
315
|
-
const migration = new migration_1.$Migration(this.module, type, this.tableName, fields);
|
|
316
|
-
console.clear();
|
|
317
|
-
console.log(migration.describe());
|
|
318
|
-
const proceed = await ui_1.default.yesOrNo('Is everything OK with the migration above?');
|
|
319
|
-
if (!proceed) {
|
|
320
|
-
log_1.Log.warn('migrator', 'generator', 'Migration rejected by manual review.');
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
return migration;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
exports.MigrationGenerator = MigrationGenerator;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export type $MigrationFieldOperation = {
|
|
2
|
-
create: {
|
|
3
|
-
type: string;
|
|
4
|
-
nullable?: boolean;
|
|
5
|
-
pk?: boolean;
|
|
6
|
-
};
|
|
7
|
-
} | {
|
|
8
|
-
rename: {
|
|
9
|
-
name: string;
|
|
10
|
-
};
|
|
11
|
-
} | {
|
|
12
|
-
alter_type: {
|
|
13
|
-
from: string;
|
|
14
|
-
to: string;
|
|
15
|
-
using: {
|
|
16
|
-
up: string;
|
|
17
|
-
down: string;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
} | {
|
|
21
|
-
alter_null: {
|
|
22
|
-
from: boolean;
|
|
23
|
-
to: boolean;
|
|
24
|
-
};
|
|
25
|
-
} | {
|
|
26
|
-
drop: {
|
|
27
|
-
type: string;
|
|
28
|
-
nullable: boolean;
|
|
29
|
-
default?: string;
|
|
30
|
-
};
|
|
31
|
-
} | {
|
|
32
|
-
create_fk: {
|
|
33
|
-
table: string;
|
|
34
|
-
field: string;
|
|
35
|
-
};
|
|
36
|
-
} | {
|
|
37
|
-
drop_fk: {
|
|
38
|
-
table: string;
|
|
39
|
-
field: string;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
export declare class $MigrationField {
|
|
43
|
-
column: string;
|
|
44
|
-
operation: $MigrationFieldOperation;
|
|
45
|
-
constructor(column: string, operation: $MigrationFieldOperation);
|
|
46
|
-
describe(): string;
|
|
47
|
-
sqlUp(table_op: 'create' | 'alter'): string;
|
|
48
|
-
sqlDown(): string;
|
|
49
|
-
}
|
|
50
|
-
export declare class $Migration {
|
|
51
|
-
module: string;
|
|
52
|
-
private type;
|
|
53
|
-
private tableName;
|
|
54
|
-
private fields;
|
|
55
|
-
description?: string | undefined;
|
|
56
|
-
name: string;
|
|
57
|
-
constructor(module: string, type: 'create' | 'alter' | 'custom', tableName: string, fields: $MigrationField[], description?: string | undefined);
|
|
58
|
-
describe(): string;
|
|
59
|
-
sqlUp(): string[];
|
|
60
|
-
sqlDown(): string[];
|
|
61
|
-
save(dirpath?: string): string;
|
|
62
|
-
private fnUp;
|
|
63
|
-
private fnDown;
|
|
64
|
-
hash(): string;
|
|
65
|
-
static empty(module: string, name: string): $Migration;
|
|
66
|
-
}
|
|
@@ -1,249 +0,0 @@
|
|
|
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 () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.$Migration = exports.$MigrationField = void 0;
|
|
37
|
-
const string_1 = require("../../../../../engine/util/string");
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
|
-
const fs = __importStar(require("fs"));
|
|
40
|
-
const datetime_1 = require("../../../../../engine/data/datetime");
|
|
41
|
-
const crypto_1 = require("crypto");
|
|
42
|
-
class $MigrationField {
|
|
43
|
-
constructor(column, operation) {
|
|
44
|
-
this.column = column;
|
|
45
|
-
this.operation = operation;
|
|
46
|
-
}
|
|
47
|
-
describe() {
|
|
48
|
-
const col_str = (0, string_1.colored)(this.column, 'lightblue');
|
|
49
|
-
if ('create' in this.operation) {
|
|
50
|
-
const type_str = (0, string_1.colored)(this.operation.create.type, 'purple');
|
|
51
|
-
return `Create column ${col_str} as ${type_str}`;
|
|
52
|
-
}
|
|
53
|
-
else if ('rename' in this.operation) {
|
|
54
|
-
const op = this.operation.rename;
|
|
55
|
-
const name_str = op.name ? (0, string_1.colored)(op.name, 'lightcyan') : undefined;
|
|
56
|
-
return `Rename column ${col_str} to ${name_str}`;
|
|
57
|
-
}
|
|
58
|
-
else if ('alter_type' in this.operation) {
|
|
59
|
-
const op = this.operation.alter_type;
|
|
60
|
-
const from_str = op.from ? (0, string_1.colored)(op.from, 'purple') : undefined;
|
|
61
|
-
const to_str = op.to ? (0, string_1.colored)(op.to, 'purple') : undefined;
|
|
62
|
-
return `Alter column ${col_str} type from ${from_str} to ${to_str};`;
|
|
63
|
-
}
|
|
64
|
-
else if ('alter_null' in this.operation) {
|
|
65
|
-
const op = this.operation.alter_null;
|
|
66
|
-
const from_str = (0, string_1.colored)(op.from ? 'NULL' : 'NOT NULL', 'purple');
|
|
67
|
-
const to_str = (0, string_1.colored)(op.to ? 'NULL' : 'NOT NULL', 'purple');
|
|
68
|
-
return `Alter column ${col_str} from ${from_str} to ${to_str};`;
|
|
69
|
-
}
|
|
70
|
-
else if ('drop' in this.operation) {
|
|
71
|
-
return `Drop column ${col_str}`;
|
|
72
|
-
}
|
|
73
|
-
else if ('create_fk' in this.operation) {
|
|
74
|
-
const op = this.operation.create_fk;
|
|
75
|
-
const table_str = (0, string_1.colored)(op.table, 'lightcyan');
|
|
76
|
-
const field_str = (0, string_1.colored)(op.field, 'purple');
|
|
77
|
-
return `Create foreign key from ${col_str} to ${table_str}.${field_str}`;
|
|
78
|
-
}
|
|
79
|
-
else if ('drop_fk' in this.operation) {
|
|
80
|
-
const op = this.operation.drop_fk;
|
|
81
|
-
const table_str = (0, string_1.colored)(op.table, 'lightcyan');
|
|
82
|
-
const field_str = (0, string_1.colored)(op.field, 'purple');
|
|
83
|
-
return `Drop foreign key from ${col_str} to ${table_str}.${field_str}`;
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
return (0, string_1.colored)(`Unknown: ${this.operation}`, 'lightred');
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
sqlUp(table_op) {
|
|
90
|
-
if ('create' in this.operation) {
|
|
91
|
-
const notNull = this.operation.create.nullable ? '' : ' NOT NULL';
|
|
92
|
-
if (table_op === 'create') {
|
|
93
|
-
return `"${this.column}" ${this.operation.create.type} ${notNull}`;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
return `ADD "${this.column}" ${this.operation.create.type} ${notNull}`;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else if ('rename' in this.operation) {
|
|
100
|
-
return `RENAME COLUMN "${this.column}" TO "${this.operation.rename.name}"`;
|
|
101
|
-
}
|
|
102
|
-
else if ('alter_type' in this.operation) {
|
|
103
|
-
return `ALTER COLUMN "${this.column}" TYPE ${this.operation.alter_type.to} USING ${this.operation.alter_type.using.up}`;
|
|
104
|
-
}
|
|
105
|
-
else if ('alter_null' in this.operation) {
|
|
106
|
-
return `ALTER COLUMN "${this.column}" ${this.operation.alter_null.to ? 'DROP' : 'SET'} NOT NULL`;
|
|
107
|
-
}
|
|
108
|
-
else if ('drop' in this.operation) {
|
|
109
|
-
return `DROP COLUMN "${this.column}"`;
|
|
110
|
-
}
|
|
111
|
-
return '';
|
|
112
|
-
}
|
|
113
|
-
sqlDown() {
|
|
114
|
-
if ('create' in this.operation) {
|
|
115
|
-
return `DROP COLUMN "${this.column}"`;
|
|
116
|
-
}
|
|
117
|
-
else if ('rename' in this.operation) {
|
|
118
|
-
return `RENAME COLUMN "${this.operation.rename.name}" TO "${this.column}"`;
|
|
119
|
-
}
|
|
120
|
-
else if ('alter_type' in this.operation) {
|
|
121
|
-
return `ALTER COLUMN "${this.column}" TYPE ${this.operation.alter_type.from} USING ${this.operation.alter_type.using.down}`;
|
|
122
|
-
}
|
|
123
|
-
else if ('alter_null' in this.operation) {
|
|
124
|
-
return `ALTER COLUMN "${this.column}" ${this.operation.alter_null.from ? 'DROP' : 'SET'} NOT NULL`;
|
|
125
|
-
}
|
|
126
|
-
else if ('drop' in this.operation) {
|
|
127
|
-
const notNull = this.operation.drop.nullable ? '' : ' NOT NULL';
|
|
128
|
-
const defaul = this.operation.drop.default;
|
|
129
|
-
return `ADD COLUMN "${this.column}" ${this.operation.drop.type}${notNull}${defaul ? (' DEFAULT ' + defaul) : ''}`;
|
|
130
|
-
}
|
|
131
|
-
return '';
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
exports.$MigrationField = $MigrationField;
|
|
135
|
-
class $Migration {
|
|
136
|
-
constructor(module, type, tableName, fields, description) {
|
|
137
|
-
this.module = module;
|
|
138
|
-
this.type = type;
|
|
139
|
-
this.tableName = tableName;
|
|
140
|
-
this.fields = fields;
|
|
141
|
-
this.description = description;
|
|
142
|
-
this.name = `${datetime_1.NesoiDatetime.now().epoch}_${this.tableName}`;
|
|
143
|
-
}
|
|
144
|
-
describe() {
|
|
145
|
-
let str = '';
|
|
146
|
-
str += '┌\n';
|
|
147
|
-
str += `│ ${(0, string_1.colored)('module: ' + this.module, 'darkgray')}\n`;
|
|
148
|
-
str += `│ ${(0, string_1.colored)(this.name, 'lightcyan')}\n`;
|
|
149
|
-
str += '└\n\n';
|
|
150
|
-
if (this.type === 'create') {
|
|
151
|
-
str += `◆ Create table ${(0, string_1.colored)(this.tableName, 'lightblue')}\n`;
|
|
152
|
-
}
|
|
153
|
-
else if (this.type === 'alter') {
|
|
154
|
-
str += `◆ Alter table '${this.tableName}'\n`;
|
|
155
|
-
}
|
|
156
|
-
this.fields.forEach(field => {
|
|
157
|
-
str += `└ ${field.describe()}\n`;
|
|
158
|
-
});
|
|
159
|
-
str += '\n';
|
|
160
|
-
str += `${(0, string_1.colored)('▲ UP', 'lightgreen')}:\n`;
|
|
161
|
-
str += this.sqlUp().join('\n');
|
|
162
|
-
str += '\n';
|
|
163
|
-
str += `${(0, string_1.colored)('▼ DOWN', 'yellow')}:\n`;
|
|
164
|
-
str += this.sqlDown().join('\n');
|
|
165
|
-
return str;
|
|
166
|
-
}
|
|
167
|
-
sqlUp() {
|
|
168
|
-
if (this.type === 'create') {
|
|
169
|
-
return [`CREATE TABLE ${this.tableName} (\n` +
|
|
170
|
-
this.fields.map(field => '\t' + field.sqlUp('create')).join(',\n')
|
|
171
|
-
+ '\n)'];
|
|
172
|
-
}
|
|
173
|
-
else if (this.type === 'alter') {
|
|
174
|
-
return this.fields.map(field => `ALTER TABLE ${this.tableName} ` + field.sqlUp('alter'));
|
|
175
|
-
}
|
|
176
|
-
return [];
|
|
177
|
-
}
|
|
178
|
-
sqlDown() {
|
|
179
|
-
if (this.type === 'create') {
|
|
180
|
-
return [`DROP TABLE ${this.tableName}`];
|
|
181
|
-
}
|
|
182
|
-
else if (this.type === 'alter') {
|
|
183
|
-
return this.fields.map(field => `ALTER TABLE ${this.tableName} ` + field.sqlDown());
|
|
184
|
-
}
|
|
185
|
-
return [];
|
|
186
|
-
}
|
|
187
|
-
save(dirpath = './migrations') {
|
|
188
|
-
const filedir = path.join('modules', this.module, dirpath);
|
|
189
|
-
fs.mkdirSync(filedir, { recursive: true });
|
|
190
|
-
const filepath = path.join(filedir, this.name + '.ts');
|
|
191
|
-
let str = '';
|
|
192
|
-
str += 'import { migration } from \'nesoi/lib/adapters/postgres/src/migrator\';\n';
|
|
193
|
-
str += '\n';
|
|
194
|
-
str += '/**\n';
|
|
195
|
-
str += ` * $migration[${this.name}]\n`;
|
|
196
|
-
str += ' *\n';
|
|
197
|
-
str += ` * $type[${this.type}]\n`;
|
|
198
|
-
if (this.type !== 'custom') {
|
|
199
|
-
str += ` * $table[${this.tableName}]\n`;
|
|
200
|
-
str += ' *\n';
|
|
201
|
-
str += ' * Migration auto-generated by @nesoi/postgres. Don\'t modify it manually.\n';
|
|
202
|
-
}
|
|
203
|
-
str += ' */\n';
|
|
204
|
-
str += '\n';
|
|
205
|
-
str += 'export default migration({\n';
|
|
206
|
-
if (this.type !== 'custom')
|
|
207
|
-
str += `\thash: '${this.hash()}',\n`;
|
|
208
|
-
str += `\tdescription: '${this.description || ''}',\n`;
|
|
209
|
-
str += '\tup: ' + this.fnUp().replace(/\n/g, '\n\t') + ',\n';
|
|
210
|
-
str += '\tdown: ' + this.fnDown().replace(/\n/g, '\n\t') + '\n';
|
|
211
|
-
str += '})';
|
|
212
|
-
fs.writeFileSync(filepath, str);
|
|
213
|
-
return filepath;
|
|
214
|
-
}
|
|
215
|
-
fnUp() {
|
|
216
|
-
let str = '';
|
|
217
|
-
str += 'async ({ sql }) => {\n';
|
|
218
|
-
this.sqlUp().forEach(sql => {
|
|
219
|
-
str += '\tawait sql`\n';
|
|
220
|
-
str += '\t\t' + sql.replace(/\n/g, '\n\t\t') + '\n';
|
|
221
|
-
str += '\t`\n';
|
|
222
|
-
});
|
|
223
|
-
str += '}';
|
|
224
|
-
return str;
|
|
225
|
-
}
|
|
226
|
-
fnDown() {
|
|
227
|
-
let str = '';
|
|
228
|
-
str += 'async ({ sql }) => {\n';
|
|
229
|
-
this.sqlDown().forEach(sql => {
|
|
230
|
-
str += '\tawait sql`\n';
|
|
231
|
-
str += '\t\t' + sql.replace(/\n/g, '\n\t\t') + '\n';
|
|
232
|
-
str += '\t`\n';
|
|
233
|
-
});
|
|
234
|
-
str += '}';
|
|
235
|
-
return str;
|
|
236
|
-
}
|
|
237
|
-
hash() {
|
|
238
|
-
const hash = (0, crypto_1.createHash)('md5');
|
|
239
|
-
const up = this.fnUp().replace(/\s*/g, '');
|
|
240
|
-
hash.update(up);
|
|
241
|
-
const down = this.fnDown().replace(/\s*/g, '');
|
|
242
|
-
hash.update(down);
|
|
243
|
-
return hash.digest('hex');
|
|
244
|
-
}
|
|
245
|
-
static empty(module, name) {
|
|
246
|
-
return new $Migration(module, 'custom', name, []);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
exports.$Migration = $Migration;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import postgres from 'postgres';
|
|
2
|
-
import { $Space } from "../../../../../elements";
|
|
3
|
-
import { AnyDaemon } from "../../../../../engine/daemon";
|
|
4
|
-
import { MigrationRunnerStatus } from '../runner/status';
|
|
5
|
-
import { $Migration } from './migration';
|
|
6
|
-
export type MigratorConfig = {
|
|
7
|
-
dirpath?: string;
|
|
8
|
-
postgres?: postgres.Options<any>;
|
|
9
|
-
};
|
|
10
|
-
export declare class MigrationProvider<S extends $Space> {
|
|
11
|
-
protected daemon: AnyDaemon;
|
|
12
|
-
private sql;
|
|
13
|
-
dirpath: string;
|
|
14
|
-
status: MigrationRunnerStatus;
|
|
15
|
-
private constructor();
|
|
16
|
-
static create(daemon: AnyDaemon, sql: postgres.Sql<any>): Promise<MigrationProvider<$Space>>;
|
|
17
|
-
generate(): Promise<$Migration[]>;
|
|
18
|
-
generateForBucket<ModuleName extends keyof S['modules']>(module: ModuleName, bucket: keyof S['modules'][ModuleName]['buckets'], tableName: string): Promise<$Migration | undefined>;
|
|
19
|
-
}
|