@platformatic/generators 1.13.0 → 1.13.2
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/base-generator.d.ts +14 -4
- package/lib/base-generator.js +58 -112
- package/lib/create-plugin.js +5 -5
- package/lib/errors.js +3 -2
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +33 -1
- package/package.json +1 -1
- package/test/base-generator.test.js +123 -103
- package/test/utils.test.js +64 -2
package/lib/base-generator.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseLogger } from 'pino'
|
|
2
2
|
import { FileGenerator } from './file-generator'
|
|
3
|
-
|
|
3
|
+
import { PackageConfiguration } from './utils'
|
|
4
4
|
export namespace BaseGenerator {
|
|
5
5
|
export type BaseGeneratorOptions = FileGenerator.FileGeneratorOptions & {
|
|
6
|
-
|
|
6
|
+
module: string
|
|
7
7
|
inquirer?: object
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -24,6 +24,11 @@ export namespace BaseGenerator {
|
|
|
24
24
|
type Dependency = {
|
|
25
25
|
[key: string]: string
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
type PackageDefinition = {
|
|
29
|
+
name: string,
|
|
30
|
+
options: PackageConfiguration
|
|
31
|
+
}
|
|
27
32
|
type BaseGeneratorConfig = Record<string, any> & {
|
|
28
33
|
port?: number
|
|
29
34
|
hostname?: string
|
|
@@ -37,7 +42,7 @@ export namespace BaseGenerator {
|
|
|
37
42
|
env?: KeyValue,
|
|
38
43
|
isRuntimeContext?: boolean,
|
|
39
44
|
serviceName?: string,
|
|
40
|
-
envPrefix?: string
|
|
45
|
+
envPrefix?: string
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
type WhereClause = {
|
|
@@ -71,6 +76,7 @@ export namespace BaseGenerator {
|
|
|
71
76
|
config: BaseGeneratorConfig
|
|
72
77
|
questions: Array<object>
|
|
73
78
|
|
|
79
|
+
packages: PackageConfiguration[]
|
|
74
80
|
constructor(opts?: BaseGeneratorOptions)
|
|
75
81
|
|
|
76
82
|
setConfig(config?: BaseGeneratorConfig): void
|
|
@@ -82,6 +88,8 @@ export namespace BaseGenerator {
|
|
|
82
88
|
getFastifyVersion(): Promise<string>
|
|
83
89
|
getPlatformaticVersion(): Promise<string>
|
|
84
90
|
|
|
91
|
+
addPackage(pkg: PackageDefinition): void
|
|
92
|
+
|
|
85
93
|
prepare(): Promise<GeneratorMetadata>
|
|
86
94
|
run(): Promise<GeneratorMetadata>
|
|
87
95
|
addQuestion(question: any, where?: WhereClause): Promise<void>
|
|
@@ -101,5 +109,7 @@ export namespace BaseGenerator {
|
|
|
101
109
|
_getConfigFileContents(): Promise<JSONValue>
|
|
102
110
|
_generateEnv(): Promise<void>
|
|
103
111
|
appendConfigEnv(): Promise<void>
|
|
112
|
+
|
|
113
|
+
postInstallActions(): Promise<void>
|
|
104
114
|
}
|
|
105
|
-
}
|
|
115
|
+
}
|
package/lib/base-generator.js
CHANGED
|
@@ -5,8 +5,8 @@ const { stripVersion, convertServiceNameToPrefix, addPrefixToEnv, extractEnvVari
|
|
|
5
5
|
const { join } = require('node:path')
|
|
6
6
|
const { FileGenerator } = require('./file-generator')
|
|
7
7
|
const { generateTests, generatePlugins } = require('./create-plugin')
|
|
8
|
+
const { PrepareError, MissingEnvVariable, ModuleNeeded } = require('./errors')
|
|
8
9
|
const { generateGitignore } = require('./create-gitignore')
|
|
9
|
-
const { NoQuestionsError, PrepareError, MissingEnvVariable } = require('./errors')
|
|
10
10
|
const generateName = require('boring-name-generator')
|
|
11
11
|
/* c8 ignore start */
|
|
12
12
|
const fakeLogger = {
|
|
@@ -21,14 +21,18 @@ const fakeLogger = {
|
|
|
21
21
|
class BaseGenerator extends FileGenerator {
|
|
22
22
|
constructor (opts = {}) {
|
|
23
23
|
super(opts)
|
|
24
|
-
this.type = opts.type
|
|
25
24
|
this.files = []
|
|
26
25
|
this.logger = opts.logger || fakeLogger
|
|
27
26
|
this.questions = []
|
|
28
27
|
this.pkgData = null
|
|
29
|
-
this.inquirer = null
|
|
28
|
+
this.inquirer = opts.inquirer || null
|
|
30
29
|
this.targetDirectory = opts.targetDirectory || null
|
|
31
30
|
this.config = this.getDefaultConfig()
|
|
31
|
+
this.packages = []
|
|
32
|
+
this.module = opts.module
|
|
33
|
+
if (!this.module) {
|
|
34
|
+
throw ModuleNeeded()
|
|
35
|
+
}
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
getDefaultConfig () {
|
|
@@ -114,11 +118,13 @@ class BaseGenerator extends FileGenerator {
|
|
|
114
118
|
|
|
115
119
|
/* c8 ignore start */
|
|
116
120
|
async ask () {
|
|
117
|
-
if (!this.questions.length) {
|
|
118
|
-
throw new NoQuestionsError()
|
|
119
|
-
}
|
|
120
121
|
if (this.inquirer) {
|
|
121
|
-
|
|
122
|
+
await this.prepareQuestions()
|
|
123
|
+
const newConfig = await this.inquirer.prompt(this.questions)
|
|
124
|
+
this.setConfig({
|
|
125
|
+
...this.config,
|
|
126
|
+
...newConfig
|
|
127
|
+
})
|
|
122
128
|
}
|
|
123
129
|
}
|
|
124
130
|
|
|
@@ -153,8 +159,6 @@ class BaseGenerator extends FileGenerator {
|
|
|
153
159
|
|
|
154
160
|
await this.generateConfigFile()
|
|
155
161
|
|
|
156
|
-
await this.prepareQuestions()
|
|
157
|
-
|
|
158
162
|
await this.generateEnv()
|
|
159
163
|
|
|
160
164
|
if (this.config.typescript) {
|
|
@@ -171,12 +175,16 @@ class BaseGenerator extends FileGenerator {
|
|
|
171
175
|
this.files.push(...generatePlugins(this.config.typescript))
|
|
172
176
|
if (this.config.tests) {
|
|
173
177
|
// create tests
|
|
174
|
-
this.files.push(...generateTests(this.config.typescript, this.
|
|
178
|
+
this.files.push(...generateTests(this.config.typescript, this.module))
|
|
175
179
|
}
|
|
176
180
|
}
|
|
181
|
+
|
|
177
182
|
this.files.push(generateGitignore())
|
|
183
|
+
|
|
178
184
|
await this._afterPrepare()
|
|
185
|
+
|
|
179
186
|
this.checkEnvVariablesInConfigFile()
|
|
187
|
+
|
|
180
188
|
return {
|
|
181
189
|
targetDirectory: this.targetDirectory,
|
|
182
190
|
env: this.config.env
|
|
@@ -186,12 +194,14 @@ class BaseGenerator extends FileGenerator {
|
|
|
186
194
|
// throw the same error
|
|
187
195
|
throw err
|
|
188
196
|
}
|
|
189
|
-
|
|
197
|
+
const _err = new PrepareError(err.message)
|
|
198
|
+
_err.cause = err
|
|
199
|
+
throw _err
|
|
190
200
|
}
|
|
191
201
|
}
|
|
192
202
|
|
|
193
203
|
checkEnvVariablesInConfigFile () {
|
|
194
|
-
const configFileName =
|
|
204
|
+
const configFileName = 'platformatic.json'
|
|
195
205
|
const fileOjbect = this.getFileObject(configFileName)
|
|
196
206
|
const envVars = extractEnvVariablesFromText(fileOjbect.contents)
|
|
197
207
|
const envKeys = Object.keys(this.config.env)
|
|
@@ -230,113 +240,36 @@ class BaseGenerator extends FileGenerator {
|
|
|
230
240
|
}
|
|
231
241
|
|
|
232
242
|
async prepareQuestions () {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
this.questions.push({
|
|
242
|
-
type: 'list',
|
|
243
|
-
name: 'typescript',
|
|
244
|
-
message: 'Do you want to use TypeScript?',
|
|
245
|
-
default: false,
|
|
246
|
-
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
// init git repository
|
|
250
|
-
this.questions.push({
|
|
251
|
-
type: 'list',
|
|
252
|
-
name: 'initGitRepository',
|
|
253
|
-
message: 'Do you want to init the git repository?',
|
|
254
|
-
default: false,
|
|
255
|
-
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
256
|
-
})
|
|
257
|
-
|
|
258
|
-
// port
|
|
259
|
-
this.questions.push({
|
|
260
|
-
type: 'input',
|
|
261
|
-
name: 'port',
|
|
262
|
-
message: 'What port do you want to use?'
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
// github actions
|
|
266
|
-
this.questions.push({
|
|
267
|
-
type: 'list',
|
|
268
|
-
name: 'staticWorkspaceGitHubAction',
|
|
269
|
-
message: 'Do you want to create the github action to deploy this application to Platformatic Cloud?',
|
|
270
|
-
default: true,
|
|
271
|
-
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
type: 'list',
|
|
275
|
-
name: 'dynamicWorkspaceGitHubAction',
|
|
276
|
-
message: 'Do you want to enable PR Previews in your application?',
|
|
277
|
-
default: true,
|
|
278
|
-
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
279
|
-
})
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
async addQuestion (question, where) {
|
|
283
|
-
if (where) {
|
|
284
|
-
if (where.before) {
|
|
285
|
-
const position = this.questions.reduce((acc, element, idx) => {
|
|
286
|
-
if (acc === null) {
|
|
287
|
-
if (element.name === where.before) {
|
|
288
|
-
acc = idx
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return acc
|
|
292
|
-
}, null)
|
|
293
|
-
|
|
294
|
-
if (position) {
|
|
295
|
-
this.questions.splice(position, 0, question)
|
|
296
|
-
}
|
|
297
|
-
} else if (where.after) {
|
|
298
|
-
const position = this.questions.reduce((acc, element, idx) => {
|
|
299
|
-
if (acc === null) {
|
|
300
|
-
if (element.name === where.after) {
|
|
301
|
-
acc = idx + 1
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return acc
|
|
305
|
-
}, null)
|
|
306
|
-
|
|
307
|
-
if (position) {
|
|
308
|
-
this.questions.splice(position, 0, question)
|
|
309
|
-
}
|
|
243
|
+
if (!this.config.isRuntimeContext) {
|
|
244
|
+
if (!this.config.targetDirectory) {
|
|
245
|
+
// directory
|
|
246
|
+
this.questions.push({
|
|
247
|
+
type: 'input',
|
|
248
|
+
name: 'targetDirectory',
|
|
249
|
+
message: 'Where would you like to create your project?'
|
|
250
|
+
})
|
|
310
251
|
}
|
|
311
|
-
} else {
|
|
312
|
-
this.questions.push(question)
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
252
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}, null)
|
|
325
|
-
if (position) {
|
|
326
|
-
this.questions.splice(position, 1)
|
|
327
|
-
}
|
|
328
|
-
}
|
|
253
|
+
// typescript
|
|
254
|
+
this.questions.push({
|
|
255
|
+
type: 'list',
|
|
256
|
+
name: 'typescript',
|
|
257
|
+
message: 'Do you want to use TypeScript?',
|
|
258
|
+
default: false,
|
|
259
|
+
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
260
|
+
})
|
|
329
261
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
262
|
+
// port
|
|
263
|
+
this.questions.push({
|
|
264
|
+
type: 'input',
|
|
265
|
+
name: 'port',
|
|
266
|
+
message: 'What port do you want to use?'
|
|
267
|
+
})
|
|
335
268
|
}
|
|
336
269
|
}
|
|
337
270
|
|
|
338
271
|
async generateConfigFile () {
|
|
339
|
-
const configFileName =
|
|
272
|
+
const configFileName = 'platformatic.json'
|
|
340
273
|
const contents = await this._getConfigFileContents()
|
|
341
274
|
this.addFile({
|
|
342
275
|
path: '',
|
|
@@ -406,6 +339,13 @@ class BaseGenerator extends FileGenerator {
|
|
|
406
339
|
})
|
|
407
340
|
await this._generateEnv()
|
|
408
341
|
this.appendConfigEnv()
|
|
342
|
+
|
|
343
|
+
const { contents } = this.getFileObject('.env')
|
|
344
|
+
this.addFile({
|
|
345
|
+
path: '',
|
|
346
|
+
file: '.env.sample',
|
|
347
|
+
contents
|
|
348
|
+
})
|
|
409
349
|
}
|
|
410
350
|
}
|
|
411
351
|
|
|
@@ -415,7 +355,13 @@ class BaseGenerator extends FileGenerator {
|
|
|
415
355
|
return metadata
|
|
416
356
|
}
|
|
417
357
|
|
|
358
|
+
addPackage (pkg) {
|
|
359
|
+
this.packages.push(pkg)
|
|
360
|
+
}
|
|
361
|
+
|
|
418
362
|
// implement in the subclass
|
|
363
|
+
/* c8 ignore next 1 */
|
|
364
|
+
async postInstallActions () {}
|
|
419
365
|
async _beforePrepare () {}
|
|
420
366
|
async _afterPrepare () {}
|
|
421
367
|
async _getConfigFileContents () { return {} }
|
package/lib/create-plugin.js
CHANGED
|
@@ -115,7 +115,7 @@ function testHelperTS (mod, customizations = { pre: '', post: '', config: '', re
|
|
|
115
115
|
return `\
|
|
116
116
|
import { join } from 'node:path'
|
|
117
117
|
import { readFile } from 'node:fs/promises'
|
|
118
|
-
import { buildServer } from '
|
|
118
|
+
import { buildServer } from '${mod}'
|
|
119
119
|
import { test } from 'node:test'
|
|
120
120
|
${customizations.requires}
|
|
121
121
|
|
|
@@ -125,7 +125,7 @@ type TestContext = Parameters<Exclude<testfn, undefined>>[0]
|
|
|
125
125
|
export async function getServer (t: TestContext) {
|
|
126
126
|
${customizations.pre}
|
|
127
127
|
// We go up two folder because this files executes in the dist folder
|
|
128
|
-
const config = JSON.parse(await readFile(join(__dirname, '..', '..', 'platformatic
|
|
128
|
+
const config = JSON.parse(await readFile(join(__dirname, '..', '..', 'platformatic'), 'utf8'))
|
|
129
129
|
// Add your config customizations here. For example you want to set
|
|
130
130
|
// all things that are set in the config file to read from an env variable
|
|
131
131
|
config.server.logger.level = 'warn'
|
|
@@ -199,13 +199,13 @@ function generateRouteWithTypesSupport (typescript) {
|
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
function generateTests (typescript,
|
|
202
|
+
function generateTests (typescript, mod, customizations) {
|
|
203
203
|
const output = []
|
|
204
204
|
if (typescript) {
|
|
205
205
|
output.push({
|
|
206
206
|
path: 'test',
|
|
207
207
|
file: 'helper.ts',
|
|
208
|
-
contents: testHelperTS(
|
|
208
|
+
contents: testHelperTS(mod, customizations)
|
|
209
209
|
})
|
|
210
210
|
output.push({
|
|
211
211
|
path: join('test', 'plugins'),
|
|
@@ -221,7 +221,7 @@ function generateTests (typescript, type, customizations) {
|
|
|
221
221
|
output.push({
|
|
222
222
|
path: 'test',
|
|
223
223
|
file: 'helper.js',
|
|
224
|
-
contents: testHelperJS(
|
|
224
|
+
contents: testHelperJS(mod, customizations)
|
|
225
225
|
})
|
|
226
226
|
output.push({
|
|
227
227
|
path: join('test', 'plugins'),
|
package/lib/errors.js
CHANGED
|
@@ -5,7 +5,8 @@ const createError = require('@fastify/error')
|
|
|
5
5
|
const ERROR_PREFIX = 'PLT_GEN'
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
|
-
|
|
8
|
+
ModuleNeeded: createError(`${ERROR_PREFIX}_PREPARE_ERROR`, 'The module which the package will be published to must be specified'),
|
|
9
9
|
PrepareError: createError(`${ERROR_PREFIX}_PREPARE_ERROR`, 'Error while generating the files: %s.'),
|
|
10
|
-
MissingEnvVariable: createError(`${ERROR_PREFIX}_MISSING_ENV_VAR`, 'Env variable %s is defined in config file %s, but not in config.env object.')
|
|
10
|
+
MissingEnvVariable: createError(`${ERROR_PREFIX}_MISSING_ENV_VAR`, 'Env variable %s is defined in config file %s, but not in config.env object.'),
|
|
11
|
+
WrongTypeError: createError(`${ERROR_PREFIX}_WRONG_TYPE`, 'Invalid value type. Accepted values are \'string\', \'number\' and \'boolean\', found \'%s\'.')
|
|
11
12
|
}
|
package/lib/utils.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ type Env = {
|
|
|
2
2
|
[key: string]: string
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
+
export type PackageConfiguration = {
|
|
6
|
+
type: 'number' | 'string' | 'boolean'
|
|
7
|
+
path: string
|
|
8
|
+
value: number | string | boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
export namespace GeneratorUtils {
|
|
6
12
|
export function safeMkdir(dir: string): Promise<void>
|
|
7
13
|
export function stripVersion(version: string): string
|
|
@@ -9,4 +15,5 @@ export namespace GeneratorUtils {
|
|
|
9
15
|
export function addPrefixToEnv(env: Env, prefix: string): Env
|
|
10
16
|
export function envObjectToString(env: Env): string
|
|
11
17
|
export function extractEnvVariablesFromText(text: string): string[]
|
|
18
|
+
export function getPackageConfigurationObject(config: PackageConfiguration[]): object
|
|
12
19
|
}
|
package/lib/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { mkdir } = require('node:fs/promises')
|
|
4
|
+
const { WrongTypeError } = require('./errors')
|
|
4
5
|
|
|
5
6
|
async function safeMkdir (dir) {
|
|
6
7
|
try {
|
|
@@ -58,10 +59,41 @@ function extractEnvVariablesFromText (text) {
|
|
|
58
59
|
}
|
|
59
60
|
return []
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
+
function getPackageConfigurationObject (config) {
|
|
63
|
+
const output = {}
|
|
64
|
+
let current = output
|
|
65
|
+
for (const param of config) {
|
|
66
|
+
const props = param.path.split('.')
|
|
67
|
+
props.forEach((prop, idx) => {
|
|
68
|
+
if (idx === props.length - 1) {
|
|
69
|
+
switch (param.type) {
|
|
70
|
+
case 'string' :
|
|
71
|
+
current[prop] = param.value.toString()
|
|
72
|
+
break
|
|
73
|
+
case 'number':
|
|
74
|
+
current[prop] = parseInt(param.value)
|
|
75
|
+
break
|
|
76
|
+
case 'boolean':
|
|
77
|
+
current[prop] = (param.value === 'true')
|
|
78
|
+
break
|
|
79
|
+
default:
|
|
80
|
+
throw new WrongTypeError(param.type)
|
|
81
|
+
}
|
|
82
|
+
current = output
|
|
83
|
+
} else {
|
|
84
|
+
if (!current[prop]) {
|
|
85
|
+
current[prop] = {}
|
|
86
|
+
}
|
|
87
|
+
current = current[prop]
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
return output
|
|
92
|
+
}
|
|
62
93
|
module.exports = {
|
|
63
94
|
addPrefixToEnv,
|
|
64
95
|
convertServiceNameToPrefix,
|
|
96
|
+
getPackageConfigurationObject,
|
|
65
97
|
envObjectToString,
|
|
66
98
|
extractEnvVariablesFromText,
|
|
67
99
|
safeMkdir,
|
package/package.json
CHANGED
|
@@ -20,7 +20,8 @@ afterEach(async () => {
|
|
|
20
20
|
test('should write file and dirs', async (t) => {
|
|
21
21
|
const dir = await getTempDir()
|
|
22
22
|
const gen = new BaseGenerator({
|
|
23
|
-
logger: fakeLogger
|
|
23
|
+
logger: fakeLogger,
|
|
24
|
+
module: '@platformatic/service'
|
|
24
25
|
})
|
|
25
26
|
|
|
26
27
|
gen.setConfig({
|
|
@@ -43,6 +44,13 @@ test('should write file and dirs', async (t) => {
|
|
|
43
44
|
|
|
44
45
|
test('extended class should generate config', async (t) => {
|
|
45
46
|
class ServiceClass extends BaseGenerator {
|
|
47
|
+
constructor (opts) {
|
|
48
|
+
super({
|
|
49
|
+
...opts,
|
|
50
|
+
module: '@platformatic/service'
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
async _getConfigFileContents () {
|
|
47
55
|
// Implement when extending this class
|
|
48
56
|
return {
|
|
@@ -52,7 +60,6 @@ test('extended class should generate config', async (t) => {
|
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
const svc = new ServiceClass({
|
|
55
|
-
type: 'service',
|
|
56
63
|
logger: fakeLogger
|
|
57
64
|
})
|
|
58
65
|
|
|
@@ -61,14 +68,14 @@ test('extended class should generate config', async (t) => {
|
|
|
61
68
|
const configFile = svc.files[1]
|
|
62
69
|
assert.deepEqual(configFile, {
|
|
63
70
|
path: '',
|
|
64
|
-
file: 'platformatic.
|
|
71
|
+
file: 'platformatic.json',
|
|
65
72
|
contents: JSON.stringify({ foo: 'bar' }, null, 2)
|
|
66
73
|
})
|
|
67
74
|
})
|
|
68
75
|
|
|
69
76
|
test('setConfig', async (t) => {
|
|
70
77
|
const bg = new BaseGenerator({
|
|
71
|
-
|
|
78
|
+
module: '@platformatic/service'
|
|
72
79
|
})
|
|
73
80
|
|
|
74
81
|
// should init the default config
|
|
@@ -140,7 +147,7 @@ test('setConfig', async (t) => {
|
|
|
140
147
|
|
|
141
148
|
test('should append env values', async (t) => {
|
|
142
149
|
const bg = new BaseGenerator({
|
|
143
|
-
|
|
150
|
+
module: '@platformatic/service'
|
|
144
151
|
})
|
|
145
152
|
// partial config with defaults
|
|
146
153
|
bg.setConfig({
|
|
@@ -152,11 +159,85 @@ test('should append env values', async (t) => {
|
|
|
152
159
|
await bg.prepare()
|
|
153
160
|
const dotEnvFile = bg.getFileObject('.env')
|
|
154
161
|
assert.equal(dotEnvFile.contents, 'FOO=bar\n')
|
|
162
|
+
|
|
163
|
+
const dotEnvSampleFile = bg.getFileObject('.env.sample')
|
|
164
|
+
assert.equal(dotEnvSampleFile.contents, 'FOO=bar\n')
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('should prepare the questions', async (t) => {
|
|
168
|
+
const bg = new BaseGenerator({
|
|
169
|
+
module: '@platformatic/service'
|
|
170
|
+
})
|
|
171
|
+
// partial config with defaults
|
|
172
|
+
bg.setConfig({
|
|
173
|
+
env: {
|
|
174
|
+
FOO: 'bar'
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
await bg.prepareQuestions()
|
|
179
|
+
assert.deepStrictEqual(bg.questions, [{
|
|
180
|
+
type: 'input',
|
|
181
|
+
name: 'targetDirectory',
|
|
182
|
+
message: 'Where would you like to create your project?'
|
|
183
|
+
}, {
|
|
184
|
+
type: 'list',
|
|
185
|
+
name: 'typescript',
|
|
186
|
+
message: 'Do you want to use TypeScript?',
|
|
187
|
+
default: false,
|
|
188
|
+
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
189
|
+
}, {
|
|
190
|
+
type: 'input',
|
|
191
|
+
name: 'port',
|
|
192
|
+
message: 'What port do you want to use?'
|
|
193
|
+
}])
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
test('should prepare the questions with a targetDirectory', async (t) => {
|
|
197
|
+
const bg = new BaseGenerator({
|
|
198
|
+
module: '@platformatic/service'
|
|
199
|
+
})
|
|
200
|
+
// partial config with defaults
|
|
201
|
+
bg.setConfig({
|
|
202
|
+
targetDirectory: './foo',
|
|
203
|
+
env: {
|
|
204
|
+
FOO: 'bar'
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
await bg.prepareQuestions()
|
|
209
|
+
assert.deepStrictEqual(bg.questions, [{
|
|
210
|
+
type: 'list',
|
|
211
|
+
name: 'typescript',
|
|
212
|
+
message: 'Do you want to use TypeScript?',
|
|
213
|
+
default: false,
|
|
214
|
+
choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
|
|
215
|
+
}, {
|
|
216
|
+
type: 'input',
|
|
217
|
+
name: 'port',
|
|
218
|
+
message: 'What port do you want to use?'
|
|
219
|
+
}])
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
test('should prepare the questions in runtime context', async (t) => {
|
|
223
|
+
const bg = new BaseGenerator({
|
|
224
|
+
module: '@platformatic/service'
|
|
225
|
+
})
|
|
226
|
+
// partial config with defaults
|
|
227
|
+
bg.setConfig({
|
|
228
|
+
isRuntimeContext: true,
|
|
229
|
+
env: {
|
|
230
|
+
FOO: 'bar'
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
await bg.prepareQuestions()
|
|
235
|
+
assert.deepStrictEqual(bg.questions, [])
|
|
155
236
|
})
|
|
156
237
|
|
|
157
238
|
test('should return service metadata', async (t) => {
|
|
158
239
|
const bg = new BaseGenerator({
|
|
159
|
-
|
|
240
|
+
module: '@platformatic/service'
|
|
160
241
|
})
|
|
161
242
|
// partial config with defaults
|
|
162
243
|
bg.setConfig({
|
|
@@ -177,7 +258,7 @@ test('should return service metadata', async (t) => {
|
|
|
177
258
|
|
|
178
259
|
test('should generate javascript plugin, routes and tests', async (t) => {
|
|
179
260
|
const bg = new BaseGenerator({
|
|
180
|
-
|
|
261
|
+
module: '@platformatic/service'
|
|
181
262
|
})
|
|
182
263
|
bg.setConfig({
|
|
183
264
|
plugin: true,
|
|
@@ -193,7 +274,7 @@ test('should generate javascript plugin, routes and tests', async (t) => {
|
|
|
193
274
|
|
|
194
275
|
test('should generate tsConfig file and typescript files', async (t) => {
|
|
195
276
|
const bg = new BaseGenerator({
|
|
196
|
-
|
|
277
|
+
module: '@platformatic/service'
|
|
197
278
|
})
|
|
198
279
|
bg.setConfig({
|
|
199
280
|
typescript: true,
|
|
@@ -231,98 +312,10 @@ test('should generate tsConfig file and typescript files', async (t) => {
|
|
|
231
312
|
assert.ok(bg.getFileObject('example.test.ts', 'test/plugins'))
|
|
232
313
|
})
|
|
233
314
|
|
|
234
|
-
test('should
|
|
235
|
-
const bg = new BaseGenerator()
|
|
236
|
-
await bg.prepare()
|
|
237
|
-
const configFileObject = bg.getFileObject('platformatic.json')
|
|
238
|
-
assert.ok(configFileObject)
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
test('should add questions in the correct position (before)', async (t) => {
|
|
242
|
-
const question = {
|
|
243
|
-
type: 'input',
|
|
244
|
-
name: 'serviceName',
|
|
245
|
-
message: 'What is the name of the service?'
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const bg = new BaseGenerator({
|
|
249
|
-
type: 'service'
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
await bg.prepare()
|
|
253
|
-
const originalQuestionsLength = bg.questions.length
|
|
254
|
-
bg.addQuestion(question, { before: 'typescript' }) // should add as second question
|
|
255
|
-
|
|
256
|
-
assert.equal(bg.questions.length, originalQuestionsLength + 1)
|
|
257
|
-
assert.deepEqual(bg.questions[1], {
|
|
258
|
-
type: 'input',
|
|
259
|
-
name: 'serviceName',
|
|
260
|
-
message: 'What is the name of the service?'
|
|
261
|
-
})
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
test('should add questions in the correct position (after)', async (t) => {
|
|
265
|
-
const question = {
|
|
266
|
-
type: 'input',
|
|
267
|
-
name: 'serviceName',
|
|
268
|
-
message: 'What is the name of the service?'
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const bg = new BaseGenerator({
|
|
272
|
-
type: 'service'
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
await bg.prepare()
|
|
276
|
-
const originalQuestionsLength = bg.questions.length
|
|
277
|
-
bg.addQuestion(question, { after: 'typescript' }) // should add as third question
|
|
278
|
-
|
|
279
|
-
assert.equal(bg.questions.length, originalQuestionsLength + 1)
|
|
280
|
-
assert.deepEqual(bg.questions[2], {
|
|
281
|
-
type: 'input',
|
|
282
|
-
name: 'serviceName',
|
|
283
|
-
message: 'What is the name of the service?'
|
|
284
|
-
})
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
test('should add questions at the end', async (t) => {
|
|
288
|
-
const question = {
|
|
289
|
-
type: 'input',
|
|
290
|
-
name: 'serviceName',
|
|
291
|
-
message: 'What is the name of the service?'
|
|
292
|
-
}
|
|
293
|
-
|
|
315
|
+
test('should throw if preapare fails', async (t) => {
|
|
294
316
|
const bg = new BaseGenerator({
|
|
295
|
-
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
await bg.prepare()
|
|
299
|
-
const originalQuestionsLength = bg.questions.length
|
|
300
|
-
bg.addQuestion(question)
|
|
301
|
-
|
|
302
|
-
assert.equal(bg.questions.length, originalQuestionsLength + 1)
|
|
303
|
-
assert.deepEqual(bg.questions[originalQuestionsLength], {
|
|
304
|
-
type: 'input',
|
|
305
|
-
name: 'serviceName',
|
|
306
|
-
message: 'What is the name of the service?'
|
|
317
|
+
module: '@platformatic/service'
|
|
307
318
|
})
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
test('should remove question', async (t) => {
|
|
311
|
-
const bg = new BaseGenerator()
|
|
312
|
-
|
|
313
|
-
await bg.prepare()
|
|
314
|
-
|
|
315
|
-
bg.removeQuestion('typescript')
|
|
316
|
-
|
|
317
|
-
bg.questions.forEach((question) => {
|
|
318
|
-
if (question.name === 'typescript') {
|
|
319
|
-
assert.fail()
|
|
320
|
-
}
|
|
321
|
-
})
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
test('should throw if preapare fails', async (t) => {
|
|
325
|
-
const bg = new BaseGenerator()
|
|
326
319
|
|
|
327
320
|
bg._beforePrepare = async () => {
|
|
328
321
|
throw new Error('beforePrepare error')
|
|
@@ -337,7 +330,9 @@ test('should throw if preapare fails', async (t) => {
|
|
|
337
330
|
})
|
|
338
331
|
|
|
339
332
|
test('should throw if there is a missing env variable', async () => {
|
|
340
|
-
const bg = new BaseGenerator(
|
|
333
|
+
const bg = new BaseGenerator({
|
|
334
|
+
module: '@platformatic/service'
|
|
335
|
+
})
|
|
341
336
|
|
|
342
337
|
bg._getConfigFileContents = async () => {
|
|
343
338
|
return {
|
|
@@ -361,9 +356,32 @@ test('should throw if there is a missing env variable', async () => {
|
|
|
361
356
|
}
|
|
362
357
|
})
|
|
363
358
|
|
|
359
|
+
test('should add package', async () => {
|
|
360
|
+
const bg = new BaseGenerator({
|
|
361
|
+
module: '@platformatic/service'
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
const packageDefinition = {
|
|
365
|
+
name: '@my/package',
|
|
366
|
+
options: [
|
|
367
|
+
{
|
|
368
|
+
path: 'foobar',
|
|
369
|
+
type: 'string',
|
|
370
|
+
value: 'foobar'
|
|
371
|
+
}
|
|
372
|
+
]
|
|
373
|
+
}
|
|
374
|
+
bg.addPackage(packageDefinition)
|
|
375
|
+
|
|
376
|
+
assert.equal(bg.packages.length, 1)
|
|
377
|
+
assert.deepEqual(bg.packages[0], packageDefinition)
|
|
378
|
+
})
|
|
379
|
+
|
|
364
380
|
describe('runtime context', () => {
|
|
365
381
|
test('should set config.envPrefix correctly', async (t) => {
|
|
366
|
-
const bg = new BaseGenerator(
|
|
382
|
+
const bg = new BaseGenerator({
|
|
383
|
+
module: '@platformatic/service'
|
|
384
|
+
})
|
|
367
385
|
|
|
368
386
|
bg.setConfig({
|
|
369
387
|
isRuntimeContext: true,
|
|
@@ -390,7 +408,9 @@ describe('runtime context', () => {
|
|
|
390
408
|
})
|
|
391
409
|
|
|
392
410
|
test('should generate correct env file from config.env', async (t) => {
|
|
393
|
-
const bg = new BaseGenerator(
|
|
411
|
+
const bg = new BaseGenerator({
|
|
412
|
+
module: '@platformatic/service'
|
|
413
|
+
})
|
|
394
414
|
|
|
395
415
|
bg.setConfig({
|
|
396
416
|
isRuntimeContext: true,
|
|
@@ -412,7 +432,7 @@ describe('runtime context', () => {
|
|
|
412
432
|
|
|
413
433
|
test('should return service metadata', async (t) => {
|
|
414
434
|
const bg = new BaseGenerator({
|
|
415
|
-
|
|
435
|
+
module: '@platformatic/service'
|
|
416
436
|
})
|
|
417
437
|
// partial config with defaults
|
|
418
438
|
bg.setConfig({
|
|
@@ -435,7 +455,7 @@ describe('runtime context', () => {
|
|
|
435
455
|
|
|
436
456
|
test('should generate service name if not provided', async () => {
|
|
437
457
|
const bg = new BaseGenerator({
|
|
438
|
-
|
|
458
|
+
module: '@platformatic/service'
|
|
439
459
|
})
|
|
440
460
|
bg.setConfig({
|
|
441
461
|
targetDirectory: '/foo/bar',
|
package/test/utils.test.js
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { test, describe } = require('node:test')
|
|
4
4
|
const assert = require('node:assert')
|
|
5
|
-
const { stripVersion, convertServiceNameToPrefix, addPrefixToEnv, envObjectToString } = require('../lib/utils')
|
|
6
|
-
const { extractEnvVariablesFromText } = require('../lib/utils')
|
|
5
|
+
const { stripVersion, convertServiceNameToPrefix, addPrefixToEnv, envObjectToString, extractEnvVariablesFromText, getPackageConfigurationObject } = require('../lib/utils')
|
|
7
6
|
|
|
8
7
|
describe('utils', () => {
|
|
9
8
|
describe('stripVersion', async () => {
|
|
@@ -86,4 +85,67 @@ describe('utils', () => {
|
|
|
86
85
|
assert.deepEqual(env, [])
|
|
87
86
|
})
|
|
88
87
|
})
|
|
88
|
+
|
|
89
|
+
describe('getPackageConfigurationObject', async () => {
|
|
90
|
+
const input = [
|
|
91
|
+
{
|
|
92
|
+
path: 'prefix',
|
|
93
|
+
value: '/foo',
|
|
94
|
+
type: 'string'
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
path: 'foo.fooOption1',
|
|
98
|
+
value: 'value1',
|
|
99
|
+
type: 'string'
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
path: 'foo.fooOption2',
|
|
103
|
+
value: 'value2',
|
|
104
|
+
type: 'string'
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
path: 'foobar',
|
|
108
|
+
value: '123',
|
|
109
|
+
type: 'number'
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
path: 'boolean.truthy',
|
|
113
|
+
value: 'true',
|
|
114
|
+
type: 'boolean'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
path: 'boolean.falsey',
|
|
118
|
+
value: 'false',
|
|
119
|
+
type: 'boolean'
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
const config = getPackageConfigurationObject(input)
|
|
123
|
+
assert.deepEqual(config, {
|
|
124
|
+
prefix: '/foo',
|
|
125
|
+
foo: {
|
|
126
|
+
fooOption1: 'value1',
|
|
127
|
+
fooOption2: 'value2'
|
|
128
|
+
},
|
|
129
|
+
foobar: 123,
|
|
130
|
+
boolean: {
|
|
131
|
+
truthy: true,
|
|
132
|
+
falsey: false
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// should throw
|
|
137
|
+
try {
|
|
138
|
+
getPackageConfigurationObject([
|
|
139
|
+
{
|
|
140
|
+
path: 'wrong',
|
|
141
|
+
type: 'object',
|
|
142
|
+
value: {}
|
|
143
|
+
}
|
|
144
|
+
])
|
|
145
|
+
assert.fail()
|
|
146
|
+
} catch (err) {
|
|
147
|
+
assert.equal(err.code, 'PLT_GEN_WRONG_TYPE')
|
|
148
|
+
assert.equal(err.message, 'Invalid value type. Accepted values are \'string\', \'number\' and \'boolean\', found \'object\'.')
|
|
149
|
+
}
|
|
150
|
+
})
|
|
89
151
|
})
|