@platformatic/generators 2.74.3 → 3.0.0-alpha.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/index.d.ts CHANGED
@@ -1,5 +1,2 @@
1
- import { BaseGenerator } from './lib/base-generator'
2
- import { generatePlugins, generateTests } from './lib/create-plugin'
3
- import { FileGenerator } from './lib/file-generator'
4
-
5
- export { BaseGenerator, FileGenerator, generatePlugins, generateTests }
1
+ export * from './lib/base-generator'
2
+ export * from './lib/file-generator'
package/index.js CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  const { BaseGenerator } = require('./lib/base-generator')
4
4
  const { ImportGenerator } = require('./lib/import-generator')
5
- const { generateTests } = require('./lib/create-plugin')
6
5
  const utils = require('./lib/utils')
7
6
 
8
7
  module.exports = {
9
8
  BaseGenerator,
10
9
  ImportGenerator,
11
- generateTests,
12
10
  ...utils
13
11
  }
package/index.test-d.ts CHANGED
@@ -1,22 +1,16 @@
1
1
  import { expectAssignable } from 'tsd'
2
2
  import { BaseGenerator } from './lib/base-generator'
3
- import { generatePlugins, generateTests } from './index'
4
- import { FileGenerator } from './lib/file-generator'
5
3
 
6
4
  expectAssignable<BaseGenerator.ConfigFieldDefinition>({
7
5
  label: 'PLT_TESTING',
8
6
  var: 'testing',
9
7
  default: 'hello world',
10
8
  type: 'string',
11
- configValue: 'someConfigValue',
9
+ configValue: 'someConfigValue'
12
10
  })
13
11
 
14
12
  expectAssignable<BaseGenerator.ConfigField>({
15
13
  var: 'testing',
16
14
  configValue: 'someConfigValue',
17
- value: 'asd123',
15
+ value: 'asd123'
18
16
  })
19
-
20
- expectAssignable<FileGenerator.FileObject[]>(generatePlugins(true))
21
-
22
- expectAssignable<FileGenerator.FileObject[]>(generateTests(true, '@platformatic/service'))
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { generateDashedName } = require('@platformatic/utils')
3
+ const { generateDashedName } = require('@platformatic/foundation')
4
4
  const { readFile } = require('node:fs/promises')
5
5
  const {
6
6
  convertServiceNameToPrefix,
@@ -12,7 +12,6 @@ const {
12
12
  } = require('./utils')
13
13
  const { join } = require('node:path')
14
14
  const { FileGenerator } = require('./file-generator')
15
- const { generateTests, generatePlugins } = require('./create-plugin')
16
15
  const { PrepareError, MissingEnvVariable, ModuleNeeded } = require('./errors')
17
16
  const { generateGitignore } = require('./create-gitignore')
18
17
  const { getServiceTemplateFromSchemaUrl } = require('./utils')
@@ -28,6 +27,8 @@ const fakeLogger = {
28
27
  }
29
28
  /* c8 ignore start */
30
29
 
30
+ const DEFAULT_SERVICES_PATH = 'services'
31
+
31
32
  class BaseGenerator extends FileGenerator {
32
33
  constructor (opts = {}) {
33
34
  super(opts)
@@ -40,12 +41,17 @@ class BaseGenerator extends FileGenerator {
40
41
  this.config = this.getDefaultConfig()
41
42
  this.packages = []
42
43
  this.module = opts.module
44
+ this.runtime = null
43
45
  this.runtimeConfig = opts.runtimeConfig ?? 'platformatic.json'
44
46
  if (!this.module) {
45
47
  throw ModuleNeeded()
46
48
  }
47
49
  }
48
50
 
51
+ setRuntime (runtime) {
52
+ this.runtime = runtime
53
+ }
54
+
49
55
  getDefaultConfig () {
50
56
  return {
51
57
  port: 3042,
@@ -213,24 +219,6 @@ class BaseGenerator extends FileGenerator {
213
219
 
214
220
  await this.generateEnv()
215
221
 
216
- if (this.config.typescript) {
217
- // create tsconfig.json
218
- this.addFile({
219
- path: '',
220
- file: 'tsconfig.json',
221
- contents: JSON.stringify(this.getTsConfig(), null, 2)
222
- })
223
- }
224
-
225
- if (this.config.plugin) {
226
- // create plugin
227
- this.files.push(...generatePlugins(this.config.typescript))
228
- if (this.config.tests) {
229
- // create tests
230
- this.files.push(...generateTests(this.config.typescript, this.module))
231
- }
232
- }
233
-
234
222
  this.files.push(generateGitignore())
235
223
 
236
224
  await this._afterPrepare()
@@ -272,30 +260,6 @@ class BaseGenerator extends FileGenerator {
272
260
  return true
273
261
  }
274
262
 
275
- getTsConfig () {
276
- return {
277
- compilerOptions: {
278
- module: 'commonjs',
279
- esModuleInterop: true,
280
- target: 'es2020',
281
- sourceMap: true,
282
- pretty: true,
283
- noEmitOnError: true,
284
- incremental: true,
285
- strict: true,
286
- outDir: 'dist',
287
- skipLibCheck: true
288
- },
289
- watchOptions: {
290
- watchFile: 'fixedPollingInterval',
291
- watchDirectory: 'fixedPollingInterval',
292
- fallbackPolling: 'dynamicPriority',
293
- synchronousWatchDirectory: true,
294
- excludeDirectories: ['**/node_modules', 'dist']
295
- }
296
- }
297
- }
298
-
299
263
  async prepareQuestions () {
300
264
  if (!this.config.isRuntimeContext) {
301
265
  if (!this.config.targetDirectory) {
@@ -307,19 +271,6 @@ class BaseGenerator extends FileGenerator {
307
271
  })
308
272
  }
309
273
 
310
- if (!this.config.skipTypescript) {
311
- this.questions.push({
312
- type: 'list',
313
- name: 'typescript',
314
- message: 'Do you want to use TypeScript?',
315
- default: false,
316
- choices: [
317
- { name: 'yes', value: true },
318
- { name: 'no', value: false }
319
- ]
320
- })
321
- }
322
-
323
274
  // port
324
275
  if (!this.config.skipPort) {
325
276
  this.questions.push({
@@ -403,15 +354,13 @@ class BaseGenerator extends FileGenerator {
403
354
  ...this.config.dependencies
404
355
  },
405
356
  engines: {
406
- node: '^22.14.0 || ^20.6.0'
357
+ node: '>=22.18.0'
407
358
  }
408
359
  }
409
360
 
410
361
  if (this.config.typescript) {
411
362
  const typescriptVersion = JSON.parse(await readFile(join(__dirname, '..', 'package.json'), 'utf-8'))
412
363
  .devDependencies.typescript
413
- template.scripts.clean = 'rm -fr ./dist'
414
- template.scripts.build = 'platformatic compile'
415
364
  template.devDependencies.typescript = typescriptVersion
416
365
  }
417
366
  return template
@@ -470,7 +419,7 @@ class BaseGenerator extends FileGenerator {
470
419
 
471
420
  async loadFromDir (serviceName, runtimeRootPath) {
472
421
  const runtimePkgConfigFileData = JSON.parse(await readFile(join(runtimeRootPath, this.runtimeConfig), 'utf-8'))
473
- const servicesPath = runtimePkgConfigFileData.autoload.path
422
+ const servicesPath = runtimePkgConfigFileData.autoload?.path ?? DEFAULT_SERVICES_PATH
474
423
  const servicePkgJsonFileData = JSON.parse(
475
424
  await readFile(join(runtimeRootPath, servicesPath, serviceName, 'platformatic.json'), 'utf-8')
476
425
  )
@@ -1,5 +1,5 @@
1
1
  'use strict'
2
- const { createDirectory } = require('@platformatic/utils')
2
+ const { createDirectory } = require('@platformatic/foundation')
3
3
  const { dirname, join, isAbsolute } = require('node:path')
4
4
  const { writeFile, readFile } = require('node:fs/promises')
5
5
 
@@ -1,12 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const { findConfigurationFile } = require('@platformatic/config')
4
- const { safeRemove } = require('@platformatic/utils')
5
- const { glob } = require('glob')
3
+ const { safeRemove, findConfigurationFileRecursive } = require('@platformatic/foundation')
6
4
  const { BaseGenerator } = require('./base-generator')
7
5
  const { spawnSync } = require('node:child_process')
8
- const { stat, readFile } = require('node:fs/promises')
9
- const { join, dirname } = require('node:path')
6
+ const { stat, readFile, readdir } = require('node:fs/promises')
7
+ const { join, dirname, resolve, relative } = require('node:path')
10
8
 
11
9
  class ImportGenerator extends BaseGenerator {
12
10
  constructor (options = {}) {
@@ -120,7 +118,7 @@ class ImportGenerator extends BaseGenerator {
120
118
  async #generateConfigFile (originalPath, updatedPath) {
121
119
  // Determine if there is a watt.json file in the application path - If it's missing, insert one
122
120
  // For import it means we don't update the file, for copy it means it was already copied in #copy.
123
- const existingConfig = await findConfigurationFile(originalPath)
121
+ const existingConfig = await findConfigurationFileRecursive(originalPath)
124
122
 
125
123
  if (existingConfig) {
126
124
  return
@@ -203,30 +201,29 @@ class ImportGenerator extends BaseGenerator {
203
201
  }
204
202
 
205
203
  async #copy (root) {
206
- const files = await glob('**/*', {
207
- cwd: root,
208
- dot: true,
209
- ignore: ['node_modules/**', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'],
210
- withFileTypes: true
211
- })
204
+ const files = await readdir(root, { withFileTypes: true, recursive: true })
205
+
206
+ for await (const file of files) {
207
+ const absolutePath = resolve(file.parentPath, file.name)
208
+ let path = relative(root, dirname(absolutePath))
212
209
 
213
- for (const file of files) {
214
- if (file.isDirectory()) {
210
+ if (
211
+ file.isDirectory() ||
212
+ ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'].includes(file.name) ||
213
+ path.includes('node_modules')
214
+ ) {
215
215
  continue
216
216
  }
217
217
 
218
218
  /* c8 ignore next 6 */
219
- let path = dirname(file.relative())
220
219
  if (path === '.') {
221
220
  path = ''
222
- } else if (path.startsWith('./')) {
223
- path = path.substring(2)
224
221
  }
225
222
 
226
223
  this.addFile({
227
224
  path,
228
225
  file: file.name,
229
- contents: await readFile(file.fullpath())
226
+ contents: await readFile(resolve(file.parentPath, file.name))
230
227
  })
231
228
  }
232
229
  }
package/lib/utils.js CHANGED
@@ -6,7 +6,7 @@ const { request } = require('undici')
6
6
  const { setTimeout } = require('timers/promises')
7
7
  const PLT_ROOT = 'PLT_ROOT'
8
8
  const { EOL } = require('node:os')
9
- const { createDirectory } = require('@platformatic/utils')
9
+ const { createDirectory } = require('@platformatic/foundation')
10
10
 
11
11
  /**
12
12
  * Strip all extra characters from a simple semver version string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/generators",
3
- "version": "2.74.3",
3
+ "version": "3.0.0-alpha.2",
4
4
  "description": "Main classes and utils for generators.",
5
5
  "main": "index.js",
6
6
  "keywords": [],
@@ -11,11 +11,9 @@
11
11
  "change-case-all": "^2.1.0",
12
12
  "execa": "^9.6.0",
13
13
  "fastify": "^5.0.0",
14
- "glob": "^11.0.2",
15
- "pino": "^9.0.0",
14
+ "pino": "^9.9.0",
16
15
  "undici": "^7.0.0",
17
- "@platformatic/config": "2.74.3",
18
- "@platformatic/utils": "2.74.3"
16
+ "@platformatic/foundation": "3.0.0-alpha.2"
19
17
  },
20
18
  "devDependencies": {
21
19
  "@types/inquirer": "^9.0.7",
@@ -26,6 +24,9 @@
26
24
  "tsd": "^0.32.0",
27
25
  "typescript": "^5.5.4"
28
26
  },
27
+ "engines": {
28
+ "node": ">=22.18.0"
29
+ },
29
30
  "scripts": {
30
31
  "lint": "eslint",
31
32
  "test": "pnpm run lint && borp --timeout=1200000 -C -X fixtures -X test --concurrency=1 && tsd"
@@ -1,13 +0,0 @@
1
- import { FileGenerator } from './file-generator'
2
-
3
- type HelperCustomization = {
4
- pre: string
5
- post: string
6
- config: string
7
- requires: string
8
- }
9
-
10
- export function generatePluginWithTypesSupport (typescript: boolean): FileGenerator.FileObject
11
- export function generateRouteWithTypesSupport (typescript: boolean): FileGenerator.FileObject
12
- export function generateTests (typescript: boolean, type: string, customization?: HelperCustomization): Array<FileGenerator.FileObject>
13
- export function generatePlugins (typescript: boolean): Array<FileGenerator.FileObject>
@@ -1,255 +0,0 @@
1
- 'use strict'
2
-
3
- const { join } = require('path')
4
-
5
- const JS_PLUGIN_WITH_TYPES_SUPPORT = `\
6
- /// <reference path="../global.d.ts" />
7
- 'use strict'
8
- /** @param {import('fastify').FastifyInstance} fastify */
9
- module.exports = async function (fastify, opts) {
10
- fastify.decorate('example', 'foobar')
11
- }
12
- `
13
-
14
- const TS_PLUGIN_WITH_TYPES_SUPPORT = `\
15
- /// <reference path="../global.d.ts" />
16
- import { FastifyInstance, FastifyPluginOptions } from 'fastify'
17
-
18
- export default async function (fastify: FastifyInstance, opts: FastifyPluginOptions) {
19
- fastify.decorate('example', 'foobar')
20
- }
21
- `
22
-
23
- const JS_ROUTES_WITH_TYPES_SUPPORT = `\
24
- /// <reference path="../global.d.ts" />
25
- 'use strict'
26
- /** @param {import('fastify').FastifyInstance} fastify */
27
- module.exports = async function (fastify, opts) {
28
- fastify.get('/example', async (request, reply) => {
29
- return { hello: fastify.example }
30
- })
31
- }
32
- `
33
-
34
- const TS_ROUTES_WITH_TYPES_SUPPORT = `\
35
- /// <reference path="../global.d.ts" />
36
- import { FastifyInstance, FastifyPluginOptions } from 'fastify'
37
-
38
- declare module 'fastify' {
39
- interface FastifyInstance {
40
- example: string
41
- }
42
- }
43
-
44
- export default async function (fastify: FastifyInstance, opts: FastifyPluginOptions) {
45
- fastify.get('/example', async (request, reply) => {
46
- return { hello: fastify.example }
47
- })
48
- }
49
- `
50
-
51
- function testHelperJS (mod, customization = { pre: '', post: '', config: '' }) {
52
- return `\
53
- 'use strict'
54
-
55
- const { join } = require('node:path')
56
- const { readFile } = require('node:fs/promises')
57
- const { buildServer } = require('${mod}')
58
- ${customization.requires || ''}
59
-
60
- async function getServer (t) {
61
- ${customization.pre || ''}
62
- const config = JSON.parse(await readFile(join(__dirname, '..', 'watt.json'), 'utf8'))
63
- // Add your config customizations here. For example you want to set
64
- // all things that are set in the config file to read from an env variable
65
- config.server ||= {}
66
- config.server.logger ||= {}
67
- config.watch = false
68
- ${customization.config || ''}
69
- // Add your config customizations here
70
- const server = await buildServer(config)
71
- t.after(() => server.close())
72
- ${customization.post || ''}
73
- return server
74
- }
75
-
76
- module.exports.getServer = getServer
77
- `
78
- }
79
-
80
- const TEST_ROUTES_JS = `\
81
- 'use strict'
82
-
83
- const test = require('node:test')
84
- const assert = require('node:assert')
85
- const { getServer } = require('../helper')
86
-
87
- test('example', async (t) => {
88
- const server = await getServer(t)
89
- const res = await server.inject({
90
- method: 'GET',
91
- url: '/example'
92
- })
93
-
94
- assert.strictEqual(res.statusCode, 200)
95
- assert.deepStrictEqual(res.json(), {
96
- hello: 'foobar'
97
- })
98
- })
99
- `
100
-
101
- const TEST_PLUGIN_JS = `\
102
- 'use strict'
103
-
104
- const test = require('node:test')
105
- const assert = require('node:assert')
106
- const { getServer } = require('../helper')
107
-
108
- test('example decorator', async (t) => {
109
- const server = await getServer(t)
110
-
111
- assert.strictEqual(server.example, 'foobar')
112
- })
113
- `
114
-
115
- function testHelperTS (mod, customizations = { pre: '', post: '', config: '', requires: '' }) {
116
- return `\
117
- import { join } from 'node:path'
118
- import { readFile } from 'node:fs/promises'
119
- import { buildServer } from '${mod}'
120
- import { test } from 'node:test'
121
- ${customizations.requires}
122
-
123
- type testfn = Parameters<typeof test>[0]
124
- type TestContext = Parameters<Exclude<testfn, undefined>>[0]
125
-
126
- export async function getServer (t: TestContext) {
127
- ${customizations.pre}
128
- // We go up two folder because this files executes in the dist folder
129
- const config = JSON.parse(await readFile(join(__dirname, '..', '..', 'watt.json'), 'utf8'))
130
- // Add your config customizations here. For example you want to set
131
- // all things that are set in the config file to read from an env variable
132
- config.server ||= {}
133
- config.server.logger ||= {}
134
- config.server.logger.level = 'warn'
135
- config.watch = false
136
- ${customizations.config}
137
- // Add your config customizations here
138
- const server = await buildServer(config)
139
- t.after(() => server.close())
140
- ${customizations.post}
141
- return server
142
- }
143
- `
144
- }
145
-
146
- const TEST_ROUTES_TS = `\
147
- import test from 'node:test'
148
- import assert from 'node:assert'
149
- import { getServer } from '../helper'
150
-
151
- test('root', async (t) => {
152
- const server = await getServer(t)
153
- const res = await server.inject({
154
- method: 'GET',
155
- url: '/example'
156
- })
157
-
158
- assert.strictEqual(res.statusCode, 200)
159
- assert.deepStrictEqual(res.json(), {
160
- hello: 'foobar'
161
- })
162
- })
163
- `
164
-
165
- const TEST_PLUGIN_TS = `\
166
- import test from 'node:test'
167
- import assert from 'node:assert'
168
- import { getServer } from '../helper'
169
-
170
- test('example decorator', async (t) => {
171
- const server = await getServer(t)
172
-
173
- assert.strictEqual(server.example, 'foobar')
174
- })
175
- `
176
-
177
- function generatePluginWithTypesSupport (typescript) {
178
- const pluginTemplate = typescript
179
- ? TS_PLUGIN_WITH_TYPES_SUPPORT
180
- : JS_PLUGIN_WITH_TYPES_SUPPORT
181
- const pluginName = typescript
182
- ? 'example.ts'
183
- : 'example.js'
184
- return {
185
- path: 'plugins',
186
- file: pluginName,
187
- contents: pluginTemplate,
188
- }
189
- }
190
-
191
- function generateRouteWithTypesSupport (typescript) {
192
- const routesTemplate = typescript
193
- ? TS_ROUTES_WITH_TYPES_SUPPORT
194
- : JS_ROUTES_WITH_TYPES_SUPPORT
195
- const routesName = typescript
196
- ? 'root.ts'
197
- : 'root.js'
198
- return {
199
- path: 'routes',
200
- file: routesName,
201
- contents: routesTemplate,
202
- }
203
- }
204
-
205
- function generateTests (typescript, mod, customizations) {
206
- const output = []
207
- if (typescript) {
208
- output.push({
209
- path: 'test',
210
- file: 'helper.ts',
211
- contents: testHelperTS(mod, customizations),
212
- })
213
- output.push({
214
- path: join('test', 'plugins'),
215
- file: 'example.test.ts',
216
- contents: TEST_PLUGIN_TS,
217
- })
218
- output.push({
219
- path: join('test', 'routes'),
220
- file: 'root.test.ts',
221
- contents: TEST_ROUTES_TS,
222
- })
223
- } else {
224
- output.push({
225
- path: 'test',
226
- file: 'helper.js',
227
- contents: testHelperJS(mod, customizations),
228
- })
229
- output.push({
230
- path: join('test', 'plugins'),
231
- file: 'example.test.js',
232
- contents: TEST_PLUGIN_JS,
233
- })
234
- output.push({
235
- path: join('test', 'routes'),
236
- file: 'root.test.js',
237
- contents: TEST_ROUTES_JS,
238
- })
239
- }
240
- return output
241
- }
242
-
243
- function generatePlugins (typescript) {
244
- const files = []
245
- files.push(generatePluginWithTypesSupport(typescript))
246
- files.push(generateRouteWithTypesSupport(typescript))
247
- return files
248
- }
249
-
250
- module.exports = {
251
- generatePluginWithTypesSupport,
252
- generateRouteWithTypesSupport,
253
- generatePlugins,
254
- generateTests,
255
- }