db-migrate 1.0.0-beta.16
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/CHANGELOG.md +487 -0
- package/LICENSE +22 -0
- package/README.md +100 -0
- package/api.js +463 -0
- package/bin/db-migrate +39 -0
- package/connect.js +198 -0
- package/get.js +67 -0
- package/index.js +85 -0
- package/lib/chain.js +157 -0
- package/lib/class.js +75 -0
- package/lib/commands/check.js +52 -0
- package/lib/commands/create-migration.js +252 -0
- package/lib/commands/db.js +63 -0
- package/lib/commands/down.js +45 -0
- package/lib/commands/dump.js +22 -0
- package/lib/commands/fn/plugin.js +45 -0
- package/lib/commands/generated.js +32 -0
- package/lib/commands/helper/assert.js +15 -0
- package/lib/commands/helper/load-config.js +26 -0
- package/lib/commands/helper/migration-hook.js +4 -0
- package/lib/commands/helper/register-events.js +19 -0
- package/lib/commands/index.js +9 -0
- package/lib/commands/on-complete.js +28 -0
- package/lib/commands/run.js +122 -0
- package/lib/commands/seed.js +48 -0
- package/lib/commands/set-default-argv.js +169 -0
- package/lib/commands/sync.js +52 -0
- package/lib/commands/undo-seed.js +54 -0
- package/lib/commands/up.js +52 -0
- package/lib/config.js +207 -0
- package/lib/driver/index.js +156 -0
- package/lib/driver/shadow.js +74 -0
- package/lib/executors/versioned/v1.js +48 -0
- package/lib/executors/versioned/v2.js +78 -0
- package/lib/file.js +190 -0
- package/lib/interface/migratorInterface.js +127 -0
- package/lib/interface/seederInterface.js +145 -0
- package/lib/learn.js +369 -0
- package/lib/methods/v2/conventions.js +47 -0
- package/lib/methods/v2/migrate.js +5 -0
- package/lib/methods/v2/statetravel.js +86 -0
- package/lib/methods/v2/translatestate.js +117 -0
- package/lib/relation.js +37 -0
- package/lib/state.js +154 -0
- package/lib/template.js +312 -0
- package/lib/templates/v2.js +12 -0
- package/lib/temputils.js +62 -0
- package/lib/walker.js +266 -0
- package/package.json +87 -0
- package/pnpm-lock.yaml +2574 -0
- package/te.js +70 -0
package/lib/state.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
const MSTATE = '__dbmigrate_state__';
|
|
2
|
+
const SSTATE = '__dbmigrate_schema__';
|
|
3
|
+
const log = require('db-migrate-shared').log;
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
lockState: async function (driver, state, internals) {
|
|
7
|
+
if (!state) {
|
|
8
|
+
return driver._insertKV(
|
|
9
|
+
internals.migrationState,
|
|
10
|
+
MSTATE,
|
|
11
|
+
JSON.stringify({
|
|
12
|
+
s: {
|
|
13
|
+
step: 0,
|
|
14
|
+
fin: 0,
|
|
15
|
+
date: new Date()
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
} else {
|
|
20
|
+
state = state.value;
|
|
21
|
+
state = JSON.parse(state);
|
|
22
|
+
state.s.date = new Date();
|
|
23
|
+
return driver._updateKV(
|
|
24
|
+
internals.migrationState,
|
|
25
|
+
MSTATE,
|
|
26
|
+
|
|
27
|
+
JSON.stringify(state)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
init: async function (driver, internals) {
|
|
33
|
+
await driver._createKV(internals.migrationState);
|
|
34
|
+
const schema = await driver._getKV(internals.migrationState, SSTATE);
|
|
35
|
+
if (schema) {
|
|
36
|
+
internals.schema = JSON.parse(schema.value);
|
|
37
|
+
} else {
|
|
38
|
+
await driver._insertKV(internals.migrationState, SSTATE, '{}');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!internals.dryRun) {
|
|
42
|
+
const state = await driver._getKV(internals.migrationState, MSTATE);
|
|
43
|
+
return module.exports.lockState(driver, state, internals);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return Promise.resolve();
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
startMigration: async function (driver, file, internals) {
|
|
50
|
+
const state = await driver._getKV(internals.migrationState, MSTATE);
|
|
51
|
+
const mig = await driver._getKV(internals.migrationState, file.name);
|
|
52
|
+
|
|
53
|
+
if (mig && mig.value !== '{}') {
|
|
54
|
+
internals.modSchema = JSON.parse(mig.value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (internals.dryRun) {
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await module.exports.lockState(driver, state, internals);
|
|
62
|
+
|
|
63
|
+
if (!mig) {
|
|
64
|
+
return driver._insertKV(
|
|
65
|
+
internals.migrationState,
|
|
66
|
+
file.name,
|
|
67
|
+
JSON.stringify({})
|
|
68
|
+
);
|
|
69
|
+
} else {
|
|
70
|
+
return Promise.resolve();
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
update: async function (driver, file, state, internals) {
|
|
75
|
+
log.verbose(`[state] update state`);
|
|
76
|
+
if (internals.dryRun) {
|
|
77
|
+
return Promise.resolve();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await driver._updateKV(internals.migrationState, SSTATE, internals.schema);
|
|
81
|
+
|
|
82
|
+
return driver._updateKV(
|
|
83
|
+
internals.migrationState,
|
|
84
|
+
file.name,
|
|
85
|
+
JSON.stringify(state)
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
get: function (driver, file, internals) {
|
|
90
|
+
return driver._getKV(internals.migrationState, file.name);
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
tick: async function (driver, internals) {
|
|
94
|
+
if (internals.dryRun) {
|
|
95
|
+
return Promise.resolve();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let { value: state } = await driver._getKV(
|
|
99
|
+
internals.migrationState,
|
|
100
|
+
MSTATE
|
|
101
|
+
);
|
|
102
|
+
state = JSON.parse(state);
|
|
103
|
+
state.s.date = new Date();
|
|
104
|
+
return driver._updateKV(
|
|
105
|
+
internals.migrationState,
|
|
106
|
+
MSTATE,
|
|
107
|
+
JSON.stringify(state)
|
|
108
|
+
);
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
step: async function (driver, step, internals) {
|
|
112
|
+
log.verbose(`[state] proceeded to step ${step}`);
|
|
113
|
+
if (internals.dryRun) {
|
|
114
|
+
return Promise.resolve();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let { value: state } = await driver._getKV(
|
|
118
|
+
internals.migrationState,
|
|
119
|
+
MSTATE
|
|
120
|
+
);
|
|
121
|
+
state = JSON.parse(state);
|
|
122
|
+
state.s.date = new Date();
|
|
123
|
+
state.s.step = step;
|
|
124
|
+
return driver._updateKV(
|
|
125
|
+
internals.migrationState,
|
|
126
|
+
MSTATE,
|
|
127
|
+
JSON.stringify(state)
|
|
128
|
+
);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
deleteState: function (driver, file, internals) {
|
|
132
|
+
return driver._deleteKV(internals.migrationState, file.name);
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
endMigration: async function (driver, file, internals) {
|
|
136
|
+
if (internals.dryRun) {
|
|
137
|
+
return Promise.resolve();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let { value: state } = await driver._getKV(
|
|
141
|
+
internals.migrationState,
|
|
142
|
+
MSTATE
|
|
143
|
+
);
|
|
144
|
+
state = JSON.parse(state);
|
|
145
|
+
state.s.date = new Date();
|
|
146
|
+
state.s.fin = 1;
|
|
147
|
+
|
|
148
|
+
return driver._updateKV(
|
|
149
|
+
internals.migrationState,
|
|
150
|
+
MSTATE,
|
|
151
|
+
JSON.stringify(state)
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
};
|
package/lib/template.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const File = require('./file.js');
|
|
4
|
+
const { util: dbmUtil, log } = require('db-migrate-shared');
|
|
5
|
+
|
|
6
|
+
const Template = function () {
|
|
7
|
+
if (arguments[4] && typeof arguments[4].overwrite === 'function') {
|
|
8
|
+
this.plugins = arguments[4];
|
|
9
|
+
arguments[4] = undefined;
|
|
10
|
+
arguments.length--;
|
|
11
|
+
}
|
|
12
|
+
this.templateType = arguments[3];
|
|
13
|
+
// this is a tweak for node 4 this can be translated
|
|
14
|
+
// to ...arguments instead in upcoming node versions
|
|
15
|
+
const Comp = File.bind.apply(File, [null].concat(dbmUtil.toArray(arguments)));
|
|
16
|
+
this.file = new Comp();
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Template.prototype.defaultCoffeeTemplate = function () {
|
|
20
|
+
return [
|
|
21
|
+
"'use strict';",
|
|
22
|
+
'',
|
|
23
|
+
'dbm = undefined',
|
|
24
|
+
'type = undefined',
|
|
25
|
+
'seed = undefined',
|
|
26
|
+
'',
|
|
27
|
+
'exports.setup = (options, seedLink) ->',
|
|
28
|
+
' dbm = options.dbmigrate',
|
|
29
|
+
' type = dbm.dataType',
|
|
30
|
+
' seed = seedLink',
|
|
31
|
+
'',
|
|
32
|
+
'exports.up = (db) ->',
|
|
33
|
+
' null',
|
|
34
|
+
'',
|
|
35
|
+
'exports.down = (db) ->',
|
|
36
|
+
' null',
|
|
37
|
+
'',
|
|
38
|
+
''
|
|
39
|
+
].join('\n');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
Template.prototype.defaultJsTemplate = function () {
|
|
43
|
+
return [
|
|
44
|
+
"'use strict';",
|
|
45
|
+
'',
|
|
46
|
+
'var dbm;',
|
|
47
|
+
'var type;',
|
|
48
|
+
'var seed;',
|
|
49
|
+
'',
|
|
50
|
+
'/**',
|
|
51
|
+
' * We receive the dbmigrate dependency from dbmigrate initially.',
|
|
52
|
+
' * This enables us to not have to rely on NODE_PATH.',
|
|
53
|
+
' */',
|
|
54
|
+
'exports.setup = function(options, seedLink) {',
|
|
55
|
+
' dbm = options.dbmigrate;',
|
|
56
|
+
' type = dbm.dataType;',
|
|
57
|
+
' seed = seedLink;',
|
|
58
|
+
'};',
|
|
59
|
+
'',
|
|
60
|
+
'exports.up = function(db) {',
|
|
61
|
+
' return null;',
|
|
62
|
+
'};',
|
|
63
|
+
'',
|
|
64
|
+
'exports.down = function(db) {',
|
|
65
|
+
' return null;',
|
|
66
|
+
'};',
|
|
67
|
+
'',
|
|
68
|
+
'exports._meta = {',
|
|
69
|
+
' "version": 1',
|
|
70
|
+
'};',
|
|
71
|
+
''
|
|
72
|
+
].join('\n');
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
Template.prototype.defaultSqlTemplate = function () {
|
|
76
|
+
return '/* Replace with your SQL commands */';
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
Template.prototype.sqlFileLoaderTemplate = function () {
|
|
80
|
+
return [
|
|
81
|
+
"'use strict';",
|
|
82
|
+
'',
|
|
83
|
+
'var dbm;',
|
|
84
|
+
'var type;',
|
|
85
|
+
'var seed;',
|
|
86
|
+
"var fs = require('fs');",
|
|
87
|
+
"var path = require('path');",
|
|
88
|
+
'var Promise;',
|
|
89
|
+
'',
|
|
90
|
+
'/**',
|
|
91
|
+
' * We receive the dbmigrate dependency from dbmigrate initially.',
|
|
92
|
+
' * This enables us to not have to rely on NODE_PATH.',
|
|
93
|
+
' */',
|
|
94
|
+
'exports.setup = function(options, seedLink) {',
|
|
95
|
+
' dbm = options.dbmigrate;',
|
|
96
|
+
' type = dbm.dataType;',
|
|
97
|
+
' seed = seedLink;',
|
|
98
|
+
' Promise = options.Promise;',
|
|
99
|
+
'};',
|
|
100
|
+
'',
|
|
101
|
+
'exports.up = function(db) {',
|
|
102
|
+
" var filePath = path.join(__dirname, 'sqls', '" +
|
|
103
|
+
this.file.name.replace('.js', '') +
|
|
104
|
+
"-up.sql');",
|
|
105
|
+
' return new Promise( function( resolve, reject ) {',
|
|
106
|
+
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){",
|
|
107
|
+
' if (err) return reject(err);',
|
|
108
|
+
" console.log('received data: ' + data);",
|
|
109
|
+
'',
|
|
110
|
+
' resolve(data);',
|
|
111
|
+
' });',
|
|
112
|
+
' })',
|
|
113
|
+
' .then(function(data) {',
|
|
114
|
+
' return db.runSql(data);',
|
|
115
|
+
' });',
|
|
116
|
+
'};',
|
|
117
|
+
'',
|
|
118
|
+
'exports.down = function(db) {',
|
|
119
|
+
" var filePath = path.join(__dirname, 'sqls', '" +
|
|
120
|
+
this.file.name.replace('.js', '') +
|
|
121
|
+
"-down.sql');",
|
|
122
|
+
' return new Promise( function( resolve, reject ) {',
|
|
123
|
+
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){",
|
|
124
|
+
' if (err) return reject(err);',
|
|
125
|
+
" console.log('received data: ' + data);",
|
|
126
|
+
'',
|
|
127
|
+
' resolve(data);',
|
|
128
|
+
' });',
|
|
129
|
+
' })',
|
|
130
|
+
' .then(function(data) {',
|
|
131
|
+
' return db.runSql(data);',
|
|
132
|
+
' });',
|
|
133
|
+
'};',
|
|
134
|
+
'',
|
|
135
|
+
'exports._meta = {',
|
|
136
|
+
' "version": 1',
|
|
137
|
+
'};',
|
|
138
|
+
''
|
|
139
|
+
].join('\n');
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
Template.prototype.sqlFileLoaderIgnoreOnInitTemplate = function () {
|
|
143
|
+
return [
|
|
144
|
+
"'use strict';",
|
|
145
|
+
'',
|
|
146
|
+
'var dbm;',
|
|
147
|
+
'var type;',
|
|
148
|
+
'var seed;',
|
|
149
|
+
"var fs = require('fs');",
|
|
150
|
+
"var path = require('path');",
|
|
151
|
+
'var ignoreOnInit = false;',
|
|
152
|
+
'var Promise;',
|
|
153
|
+
'',
|
|
154
|
+
'/**',
|
|
155
|
+
' * We receive the dbmigrate dependency from dbmigrate initially.',
|
|
156
|
+
' * This enables us to not have to rely on NODE_PATH.',
|
|
157
|
+
' */',
|
|
158
|
+
'exports.setup = function(options, seedLink) {',
|
|
159
|
+
' dbm = options.dbmigrate;',
|
|
160
|
+
' ignoreOnInit = options.ignoreOnInit;',
|
|
161
|
+
' type = dbm.dataType;',
|
|
162
|
+
' seed = seedLink;',
|
|
163
|
+
' Promise = options.Promise;',
|
|
164
|
+
'};',
|
|
165
|
+
'',
|
|
166
|
+
'exports.up = function(db, callback) {',
|
|
167
|
+
" var filePath = path.join(__dirname + '/sqls/" +
|
|
168
|
+
this.file.name.replace('.js', '') +
|
|
169
|
+
"-up.sql');",
|
|
170
|
+
' if (!ignoreOnInit) {',
|
|
171
|
+
' return new Promise( function( resolve, reject ) {',
|
|
172
|
+
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){",
|
|
173
|
+
' if (err) return reject(err);',
|
|
174
|
+
" console.log('received data: ' + data);",
|
|
175
|
+
'',
|
|
176
|
+
' resolve(data);',
|
|
177
|
+
' });',
|
|
178
|
+
' })',
|
|
179
|
+
' .then(function(data) {',
|
|
180
|
+
' return db.runSql(data);',
|
|
181
|
+
' });',
|
|
182
|
+
' }',
|
|
183
|
+
' else {',
|
|
184
|
+
" console.log('ignoring on init: ' + filePath)",
|
|
185
|
+
' return null;',
|
|
186
|
+
' }',
|
|
187
|
+
'};',
|
|
188
|
+
'',
|
|
189
|
+
'exports.down = function(db, callback) {',
|
|
190
|
+
" var filePath = path.join(__dirname + '/sqls/" +
|
|
191
|
+
this.file.name.replace('.js', '') +
|
|
192
|
+
"-down.sql');",
|
|
193
|
+
' return new Promise( function( resolve, reject ) {',
|
|
194
|
+
" fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){",
|
|
195
|
+
' if (err) return reject(err);',
|
|
196
|
+
" console.log('received data: ' + data);",
|
|
197
|
+
'',
|
|
198
|
+
' resolve(data);',
|
|
199
|
+
' });',
|
|
200
|
+
' })',
|
|
201
|
+
' .then(function(data) {',
|
|
202
|
+
' return db.runSql(data);',
|
|
203
|
+
' });',
|
|
204
|
+
'};',
|
|
205
|
+
'',
|
|
206
|
+
'exports._meta = {',
|
|
207
|
+
' "version": 1',
|
|
208
|
+
'};',
|
|
209
|
+
''
|
|
210
|
+
].join('\n');
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
Template.prototype.coffeeSqlFileLoaderTemplate = function () {
|
|
214
|
+
return [
|
|
215
|
+
"'use strict';",
|
|
216
|
+
'',
|
|
217
|
+
'dbm = undefined',
|
|
218
|
+
'type = undefined',
|
|
219
|
+
'seed = undefined',
|
|
220
|
+
"fs = require 'fs'",
|
|
221
|
+
"path = require 'path'",
|
|
222
|
+
'',
|
|
223
|
+
'#',
|
|
224
|
+
'# We receive the dbmigrate dependency from dbmigrate initially.',
|
|
225
|
+
'# This enables us to not have to rely on NODE_PATH.',
|
|
226
|
+
'#',
|
|
227
|
+
'exports.setup = (options, seedLink) ->',
|
|
228
|
+
' dbm = options.dbmigrate',
|
|
229
|
+
' type = dbm.dataType',
|
|
230
|
+
' seed = seedLink',
|
|
231
|
+
'',
|
|
232
|
+
'',
|
|
233
|
+
'exports.up = (db, callback) ->',
|
|
234
|
+
' filePath = path.join "#{__dirname}/sqls/' +
|
|
235
|
+
this.file.name.replace('.coffee', '') +
|
|
236
|
+
'-up.sql"',
|
|
237
|
+
" fs.readFile filePath, {encoding: 'utf-8'}, (err,data) ->",
|
|
238
|
+
' return callback err if err',
|
|
239
|
+
'',
|
|
240
|
+
' db.runSql data, callback',
|
|
241
|
+
'',
|
|
242
|
+
'exports.down = (db, callback) ->',
|
|
243
|
+
' filePath = path.join "#{__dirname}/sqls/' +
|
|
244
|
+
this.file.name.replace('.coffee', '') +
|
|
245
|
+
'-down.sql"',
|
|
246
|
+
|
|
247
|
+
" fs.readFile filePath, {encoding: 'utf-8'}, (err,data) ->",
|
|
248
|
+
' return callback err if err',
|
|
249
|
+
'',
|
|
250
|
+
' db.runSql data, callback',
|
|
251
|
+
''
|
|
252
|
+
].join('\n');
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
Template.TemplateType = {
|
|
256
|
+
DEFAULT_JS: 0,
|
|
257
|
+
DEFAULT_SQL: 1,
|
|
258
|
+
SQL_FILE_LOADER: 2,
|
|
259
|
+
DEFAULT_COFFEE: 3,
|
|
260
|
+
COFFEE_SQL_FILE_LOADER: 4,
|
|
261
|
+
SQL_FILE_LOADER_IGNORE_ON_INIT: 5,
|
|
262
|
+
V2_DEFAULT: 6
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
Template.prototype.getTemplate = function () {
|
|
266
|
+
let plugin = false;
|
|
267
|
+
|
|
268
|
+
switch (this.templateType) {
|
|
269
|
+
case Template.TemplateType.DEFAULT_SQL:
|
|
270
|
+
return this.defaultSqlTemplate();
|
|
271
|
+
case Template.TemplateType.SQL_FILE_LOADER:
|
|
272
|
+
return this.sqlFileLoaderTemplate();
|
|
273
|
+
case Template.TemplateType.DEFAULT_COFFEE:
|
|
274
|
+
return this.defaultCoffeeTemplate();
|
|
275
|
+
case Template.TemplateType.COFFEE_SQL_FILE_LOADER:
|
|
276
|
+
return this.coffeeSqlFileLoaderTemplate();
|
|
277
|
+
case Template.TemplateType.SQL_FILE_LOADER_IGNORE_ON_INIT:
|
|
278
|
+
return this.sqlFileLoaderIgnoreOnInitTemplate();
|
|
279
|
+
case Template.TemplateType.DEFAULT_JS:
|
|
280
|
+
return this.defaultJsTemplate();
|
|
281
|
+
case Template.TemplateType.V2_DEFAULT:
|
|
282
|
+
return require('./templates/v2.js')();
|
|
283
|
+
default:
|
|
284
|
+
if (this.plugins) {
|
|
285
|
+
plugin = this.plugins.overwrite(
|
|
286
|
+
`template:overwrite:provider:${this.templateType}`
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (plugin !== false) {
|
|
291
|
+
try {
|
|
292
|
+
return plugin[`template:overwrite:provider:${this.templateType}`]({
|
|
293
|
+
file: {
|
|
294
|
+
name: this.file.name
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
} catch (ex) {
|
|
298
|
+
log.error('Plugin failure "' + plugin.name + '", arborting!');
|
|
299
|
+
|
|
300
|
+
throw ex;
|
|
301
|
+
}
|
|
302
|
+
} else {
|
|
303
|
+
return this.defaultJsTemplate();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
Template.prototype.write = function (callback) {
|
|
309
|
+
return this.file.write(this.getTemplate()).nodeify(callback);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
module.exports = Template;
|
package/lib/temputils.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function isPromise (probe) {
|
|
4
|
+
return (
|
|
5
|
+
probe instanceof Promise ||
|
|
6
|
+
(probe &&
|
|
7
|
+
probe.then &&
|
|
8
|
+
probe.constructor &&
|
|
9
|
+
probe.constructor.name === 'Promise')
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Backwards compatibility function.
|
|
15
|
+
*
|
|
16
|
+
* This ensures old migrations can still be executed by allowing them
|
|
17
|
+
* to still use callbacks or promises. This function ensures that every
|
|
18
|
+
* execution context may be returned only once (since callbacks can be called
|
|
19
|
+
* multiple times) and is basically FI(-only-)FO function.
|
|
20
|
+
*/
|
|
21
|
+
function maybePromised (context, action, params) {
|
|
22
|
+
let cbExecuted = false;
|
|
23
|
+
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const r = err => {
|
|
26
|
+
if (cbExecuted === false) {
|
|
27
|
+
cbExecuted = true;
|
|
28
|
+
|
|
29
|
+
if (err) {
|
|
30
|
+
reject(err);
|
|
31
|
+
} else {
|
|
32
|
+
resolve();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
params[params.length++] = r;
|
|
38
|
+
|
|
39
|
+
if (typeof action === 'function') action = action.apply(context, params);
|
|
40
|
+
if (action === null) action = Promise.resolve();
|
|
41
|
+
|
|
42
|
+
if (isPromise(action)) {
|
|
43
|
+
action
|
|
44
|
+
.then(() => {
|
|
45
|
+
if (cbExecuted === false) {
|
|
46
|
+
cbExecuted = true;
|
|
47
|
+
resolve();
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
.catch(err => {
|
|
51
|
+
if (cbExecuted === false) {
|
|
52
|
+
cbExecuted = true;
|
|
53
|
+
reject(err);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
maybePromised: maybePromised
|
|
62
|
+
};
|