create-platformatic 0.45.1 → 0.46.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-platformatic",
3
- "version": "0.45.1",
3
+ "version": "0.46.2",
4
4
  "description": "Create platformatic-db interactive tool",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "semver": "^7.5.1",
35
35
  "undici": "^5.22.1",
36
36
  "which": "^3.0.1",
37
- "@platformatic/config": "0.45.1"
37
+ "@platformatic/config": "0.46.2"
38
38
  },
39
39
  "devDependencies": {
40
40
  "ajv": "^8.12.0",
@@ -47,8 +47,8 @@
47
47
  "tap": "^16.3.6",
48
48
  "typescript": "~5.2.0",
49
49
  "yaml": "^2.3.1",
50
- "@platformatic/db": "0.45.1",
51
- "@platformatic/service": "0.45.1"
50
+ "@platformatic/db": "0.46.2",
51
+ "@platformatic/service": "0.46.2"
52
52
  },
53
53
  "scripts": {
54
54
  "test": "standard | snazzy && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" c8 tap --no-coverage test/*test.mjs test/*/*test.mjs",
@@ -93,8 +93,8 @@ const createPlatformaticComposer = async (_args, opts) => {
93
93
  }
94
94
 
95
95
  if (!opts.skipGitHubActions) {
96
- await askDynamicWorkspaceCreateGHAction(logger, env, 'composer', false, projectDir)
97
96
  await askStaticWorkspaceGHAction(logger, env, 'composer', false, projectDir)
97
+ await askDynamicWorkspaceCreateGHAction(logger, env, 'composer', false, projectDir)
98
98
  }
99
99
  }
100
100
 
@@ -0,0 +1,232 @@
1
+ import { join } from 'path'
2
+ import { writeFile, mkdir } from 'fs/promises'
3
+ import { isFileAccessible } from './utils.mjs'
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('@platformatic/${mod}')
58
+ ${customization.requires || ''}
59
+
60
+ async function getServer (t) {
61
+ ${customization.pre || ''}
62
+ const config = JSON.parse(await readFile(join(__dirname, '..', 'platformatic.${mod}.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.logger.level = 'warn'
66
+ config.watch = false
67
+ ${customization.config || ''}
68
+ // Add your config customizations here
69
+ const server = await buildServer(config)
70
+ t.after(() => server.close())
71
+ ${customization.post || ''}
72
+ return server
73
+ }
74
+
75
+ module.exports.getServer = getServer
76
+ `
77
+ }
78
+
79
+ const TEST_ROUTES_JS = `\
80
+ 'use strict'
81
+
82
+ const test = require('node:test')
83
+ const assert = require('node:assert')
84
+ const { getServer } = require('../helper')
85
+
86
+ test('example', async (t) => {
87
+ const server = await getServer(t)
88
+ const res = await server.inject({
89
+ method: 'GET',
90
+ url: '/example'
91
+ })
92
+
93
+ assert.strictEqual(res.statusCode, 200)
94
+ assert.deepStrictEqual(res.json(), {
95
+ hello: 'foobar'
96
+ })
97
+ })
98
+ `
99
+
100
+ const TEST_PLUGIN_JS = `\
101
+ 'use strict'
102
+
103
+ const test = require('node:test')
104
+ const assert = require('node:assert')
105
+ const { getServer } = require('../helper')
106
+
107
+ test('example decorator', async (t) => {
108
+ const server = await getServer(t)
109
+
110
+ assert.strictEqual(server.example, 'foobar')
111
+ })
112
+ `
113
+
114
+ function testHelperTS (mod, customizations = { pre: '', post: '', config: '', requires: '' }) {
115
+ return `\
116
+ import { join } from 'node:path'
117
+ import { readFile } from 'node:fs/promises'
118
+ import { buildServer } from '@platformatic/${mod}'
119
+ ${customizations.requires}
120
+
121
+ export async function getServer (t) {
122
+ ${customizations.pre}
123
+ // We go up two folder because this files executes in the dist folder
124
+ const config = JSON.parse(await readFile(join(__dirname, '..', '..', 'platformatic.${mod}.json'), 'utf8'))
125
+ // Add your config customizations here. For example you want to set
126
+ // all things that are set in the config file to read from an env variable
127
+ config.server.logger.level = 'warn'
128
+ config.watch = false
129
+ ${customizations.config}
130
+ // Add your config customizations here
131
+ const server = await buildServer(config)
132
+ t.after(() => server.close())
133
+ ${customizations.post}
134
+ return server
135
+ }
136
+ `
137
+ }
138
+
139
+ const TEST_ROUTES_TS = `\
140
+ import test from 'node:test'
141
+ import assert from 'node:assert'
142
+ import { getServer } from '../helper'
143
+
144
+ test('root', async (t) => {
145
+ const server = await getServer(t)
146
+ const res = await server.inject({
147
+ method: 'GET',
148
+ url: '/example'
149
+ })
150
+
151
+ assert.strictEqual(res.statusCode, 200)
152
+ assert.deepStrictEqual(res.json(), {
153
+ hello: 'foobar'
154
+ })
155
+ })
156
+ `
157
+
158
+ const TEST_PLUGIN_TS = `\
159
+ import test from 'node:test'
160
+ import assert from 'node:assert'
161
+ import { getServer } from '../helper'
162
+
163
+ test('example decorator', async (t) => {
164
+ const server = await getServer(t)
165
+
166
+ assert.strictEqual(server.example, 'foobar')
167
+ })
168
+ `
169
+
170
+ export async function generatePluginWithTypesSupport (logger, currentDir, isTypescript) {
171
+ const accessible = await isFileAccessible('plugins', currentDir)
172
+ if (accessible) {
173
+ logger.info('Plugins folder "plugins" found, skipping creation of plugins folder.')
174
+ return
175
+ }
176
+ await mkdir(join(currentDir, 'plugins'))
177
+ const pluginTemplate = isTypescript
178
+ ? TS_PLUGIN_WITH_TYPES_SUPPORT
179
+ : JS_PLUGIN_WITH_TYPES_SUPPORT
180
+ const pluginName = isTypescript
181
+ ? 'example.ts'
182
+ : 'example.js'
183
+ await writeFile(join(currentDir, 'plugins', pluginName), pluginTemplate)
184
+ logger.info('Plugins folder "plugins" successfully created.')
185
+ }
186
+
187
+ export async function generateRouteWithTypesSupport (logger, currentDir, isTypescript) {
188
+ const accessible = await isFileAccessible('routes', currentDir)
189
+ if (accessible) {
190
+ logger.info('Routes folder "routes" found, skipping creation of routes folder.')
191
+ return
192
+ }
193
+ await mkdir(join(currentDir, 'routes'))
194
+ const routesTemplate = isTypescript
195
+ ? TS_ROUTES_WITH_TYPES_SUPPORT
196
+ : JS_ROUTES_WITH_TYPES_SUPPORT
197
+ const routesName = isTypescript
198
+ ? 'root.ts'
199
+ : 'root.js'
200
+ await writeFile(join(currentDir, 'routes', routesName), routesTemplate)
201
+ logger.info('Routes folder "routes" successfully created.')
202
+ }
203
+
204
+ export async function generateTests (logger, currentDir, isTypescript, mod, customizations) {
205
+ const accessible = await isFileAccessible('tests', currentDir)
206
+ if (accessible) {
207
+ logger.info('Test folder found, skipping creation of tests.')
208
+ return
209
+ }
210
+
211
+ await mkdir(join(currentDir, 'test'))
212
+ await mkdir(join(currentDir, 'test', 'plugins'))
213
+ await mkdir(join(currentDir, 'test', 'routes'))
214
+
215
+ if (isTypescript) {
216
+ await writeFile(join(currentDir, 'test', 'helper.ts'), testHelperTS(mod, customizations))
217
+ await writeFile(join(currentDir, 'test', 'plugins', 'example.test.ts'), TEST_PLUGIN_TS)
218
+ await writeFile(join(currentDir, 'test', 'routes', 'root.test.ts'), TEST_ROUTES_TS)
219
+ } else {
220
+ await writeFile(join(currentDir, 'test', 'helper.js'), testHelperJS(mod, customizations))
221
+ await writeFile(join(currentDir, 'test', 'plugins', 'example.test.js'), TEST_PLUGIN_JS)
222
+ await writeFile(join(currentDir, 'test', 'routes', 'root.test.js'), TEST_ROUTES_JS)
223
+ }
224
+
225
+ logger.info('Test folder "tests" successfully created.')
226
+ }
227
+
228
+ export async function generatePlugins (logger, currentDir, isTypescript, mod, helperCustomization) {
229
+ await generatePluginWithTypesSupport(logger, currentDir, isTypescript)
230
+ await generateRouteWithTypesSupport(logger, currentDir, isTypescript)
231
+ await generateTests(logger, currentDir, isTypescript, mod, helperCustomization)
232
+ }
@@ -166,7 +166,8 @@ const createPlatformaticDB = async (_args, opts) => {
166
166
  const fastifyVersion = await getDependencyVersion('fastify')
167
167
 
168
168
  const scripts = {
169
- migrate: 'platformatic db migrations apply'
169
+ migrate: 'platformatic db migrations apply',
170
+ test: useTypescript ? 'tsc && node --test dist/test/*/*.test.js' : 'node --test test/*/*.test.js'
170
171
  }
171
172
 
172
173
  const dependencies = {
@@ -245,8 +246,8 @@ const createPlatformaticDB = async (_args, opts) => {
245
246
  }
246
247
 
247
248
  if (!opts.skipGitHubActions) {
248
- await askDynamicWorkspaceCreateGHAction(logger, env, 'db', useTypescript, projectDir)
249
249
  await askStaticWorkspaceGHAction(logger, env, 'db', useTypescript, projectDir)
250
+ await askDynamicWorkspaceCreateGHAction(logger, env, 'db', useTypescript, projectDir)
250
251
  }
251
252
  }
252
253
 
@@ -1,7 +1,8 @@
1
1
  import { writeFile, mkdir, appendFile } from 'fs/promises'
2
- import { join, relative, resolve } from 'path'
2
+ import { join } from 'path'
3
3
  import { findDBConfigFile, isFileAccessible } from '../utils.mjs'
4
4
  import { getTsConfig } from '../get-tsconfig.mjs'
5
+ import { generatePlugins } from '../create-plugins.mjs'
5
6
 
6
7
  const connectionStrings = {
7
8
  postgres: 'postgres://postgres:postgres@127.0.0.1:5432/postgres',
@@ -32,9 +33,222 @@ const moviesMigrationUndo = `
32
33
  DROP TABLE movies;
33
34
  `
34
35
 
35
- const getPluginName = (isTypescript) => isTypescript === true ? 'plugin.ts' : 'plugin.js'
36
36
  const TS_OUT_DIR = 'dist'
37
37
 
38
+ const jsHelperSqlite = {
39
+ requires: `
40
+ const os = require('node:os')
41
+ const path = require('node:path')
42
+ const fs = require('node:fs/promises')
43
+
44
+ let counter = 0
45
+ `,
46
+ pre: `
47
+ const dbPath = join(os.tmpdir(), 'db-' + process.pid + '-' + counter++ + '.sqlite')
48
+ const connectionString = 'sqlite://' + dbPath
49
+ `,
50
+ config: `
51
+ config.migrations.autoApply = true
52
+ config.types.autogenerate = false
53
+ config.db.connectionString = connectionString
54
+ `,
55
+ post: `
56
+ t.after(async () => {
57
+ await fs.unlink(dbPath)
58
+ })
59
+ `
60
+ }
61
+
62
+ function jsHelperPostgres (connectionString) {
63
+ return {
64
+ // TODO(mcollina): replace sql-mapper
65
+ requires: `
66
+ const { createConnectionPool } = require('@platformatic/sql-mapper')
67
+ const connectionString = '${connectionString}'
68
+ let counter = 0
69
+ `,
70
+ pre: `
71
+ const { db, sql } = await createConnectionPool({
72
+ log: {
73
+ debug: () => {},
74
+ info: () => {},
75
+ trace: () => {}
76
+ },
77
+ connectionString,
78
+ poolSize: 1
79
+ })
80
+
81
+ const newDB = \`t-\${process.pid}-\${counter++}\`
82
+ t.diagnostic('Creating database ' + newDB)
83
+
84
+ await db.query(sql\`
85
+ CREATE DATABASE \${sql.ident(newDB)}
86
+ \`)
87
+ `,
88
+ config: `
89
+ config.migrations.autoApply = true
90
+ config.types.autogenerate = false
91
+ config.db.connectionString = connectionString.replace(/\\/[a-zA-Z0-9\\-_]+$/, '/' + newDB)
92
+ config.db.schemalock = false
93
+ `,
94
+ post: `
95
+ t.after(async () => {
96
+ t.diagnostic('Disposing test database ' + newDB)
97
+ await db.query(sql\`
98
+ DROP DATABASE \${sql.ident(newDB)}
99
+ \`)
100
+ await db.dispose()
101
+ })
102
+ `
103
+ }
104
+ }
105
+
106
+ function jsHelperMySQL (connectionString) {
107
+ return {
108
+ // TODO(mcollina): replace sql-mapper
109
+ requires: `
110
+ const { createConnectionPool } = require('@platformatic/sql-mapper')
111
+ const connectionString = '${connectionString}'
112
+ let counter = 0
113
+ `,
114
+ pre: `
115
+ const { db, sql } = await createConnectionPool({
116
+ log: {
117
+ debug: () => {},
118
+ info: () => {},
119
+ trace: () => {}
120
+ },
121
+ connectionString,
122
+ poolSize: 1
123
+ })
124
+
125
+ const newDB = \`t-\${process.pid}-\${counter++}\`
126
+ t.diagnostic('Creating database ' + newDB)
127
+
128
+ await db.query(sql\`
129
+ CREATE DATABASE \${sql.ident(newDB)}
130
+ \`)
131
+ `,
132
+ config: `
133
+ config.migrations.autoApply = true
134
+ config.types.autogenerate = false
135
+ config.db.connectionString = connectionString.replace(/\\/[a-zA-Z0-9\\-_]+$/, '/' + newDB)
136
+ config.db.schemalock = false
137
+ `,
138
+ post: `
139
+ t.after(async () => {
140
+ t.diagnostic('Disposing test database ' + newDB)
141
+ await db.query(sql\`
142
+ DROP DATABASE \${sql.ident(newDB)}
143
+ \`)
144
+ await db.dispose()
145
+ })
146
+ `
147
+ }
148
+ }
149
+
150
+ const moviesTestJS = `\
151
+ 'use strict'
152
+
153
+ const test = require('node:test')
154
+ const assert = require('node:assert')
155
+ const { getServer } = require('../helper')
156
+
157
+ test('movies', async (t) => {
158
+ const server = await getServer(t)
159
+
160
+ {
161
+ const res = await server.inject({
162
+ method: 'GET',
163
+ url: '/movies'
164
+ })
165
+
166
+ assert.strictEqual(res.statusCode, 200)
167
+ assert.deepStrictEqual(res.json(), [])
168
+ }
169
+
170
+ let id
171
+ {
172
+ const res = await server.inject({
173
+ method: 'POST',
174
+ url: '/movies',
175
+ body: {
176
+ title: 'The Matrix'
177
+ }
178
+ })
179
+
180
+ assert.strictEqual(res.statusCode, 200)
181
+ const body = res.json()
182
+ assert.strictEqual(body.title, 'The Matrix')
183
+ assert.strictEqual(body.id !== undefined, true)
184
+ id = body.id
185
+ }
186
+
187
+ {
188
+ const res = await server.inject({
189
+ method: 'GET',
190
+ url: '/movies'
191
+ })
192
+
193
+ assert.strictEqual(res.statusCode, 200)
194
+ assert.deepStrictEqual(res.json(), [{
195
+ id,
196
+ title: 'The Matrix'
197
+ }])
198
+ }
199
+ })
200
+ `
201
+
202
+ const moviesTestTS = `\
203
+ import test from 'node:test'
204
+ import assert from 'node:assert'
205
+ import { getServer } from '../helper'
206
+
207
+ test('movies', async (t) => {
208
+ const server = await getServer(t)
209
+
210
+ {
211
+ const res = await server.inject({
212
+ method: 'GET',
213
+ url: '/movies'
214
+ })
215
+
216
+ assert.strictEqual(res.statusCode, 200)
217
+ assert.deepStrictEqual(res.json(), [])
218
+ }
219
+
220
+ let id : Number
221
+ {
222
+ const res = await server.inject({
223
+ method: 'POST',
224
+ url: '/movies',
225
+ body: {
226
+ title: 'The Matrix'
227
+ }
228
+ })
229
+
230
+ assert.strictEqual(res.statusCode, 200)
231
+ const body = res.json()
232
+ assert.strictEqual(body.title, 'The Matrix')
233
+ assert.strictEqual(body.id !== undefined, true)
234
+ id = body.id as Number
235
+ }
236
+
237
+ {
238
+ const res = await server.inject({
239
+ method: 'GET',
240
+ url: '/movies'
241
+ })
242
+
243
+ assert.strictEqual(res.statusCode, 200)
244
+ assert.deepStrictEqual(res.json(), [{
245
+ id,
246
+ title: 'The Matrix'
247
+ }])
248
+ }
249
+ })
250
+ `
251
+
38
252
  function generateConfig (migrations, plugin, types, typescript, version) {
39
253
  const config = {
40
254
  $schema: `https://platformatic.dev/schemas/v${version}/db`,
@@ -64,7 +278,12 @@ function generateConfig (migrations, plugin, types, typescript, version) {
64
278
 
65
279
  if (plugin === true) {
66
280
  config.plugins = {
67
- paths: [getPluginName(typescript)]
281
+ paths: [{
282
+ path: './plugins',
283
+ encapsulate: false
284
+ }, {
285
+ path: './routes'
286
+ }]
68
287
  }
69
288
  }
70
289
 
@@ -101,38 +320,6 @@ PLT_TYPESCRIPT=true
101
320
  return env
102
321
  }
103
322
 
104
- const JS_PLUGIN_WITH_TYPES_SUPPORT = `\
105
- /// <reference path="./global.d.ts" />
106
- 'use strict'
107
-
108
- /** @param {import('fastify').FastifyInstance} app */
109
- module.exports = async function (app) {}
110
- `
111
-
112
- const TS_PLUGIN_WITH_TYPES_SUPPORT = `\
113
- /// <reference path="./global.d.ts" />
114
- import { FastifyInstance } from 'fastify'
115
-
116
- export default async function (app: FastifyInstance) {}
117
- `
118
-
119
- async function generatePluginWithTypesSupport (logger, currentDir, isTypescript) {
120
- const pluginPath = resolve(currentDir, getPluginName(isTypescript))
121
-
122
- const isPluginExists = await isFileAccessible(pluginPath)
123
- if (isPluginExists) {
124
- logger.info(`Plugin file ${pluginPath} found, skipping creation of plugin file.`)
125
- return
126
- }
127
-
128
- const pluginTemplate = isTypescript
129
- ? TS_PLUGIN_WITH_TYPES_SUPPORT
130
- : JS_PLUGIN_WITH_TYPES_SUPPORT
131
-
132
- await writeFile(pluginPath, pluginTemplate)
133
- logger.info(`Plugin file created at ${relative(currentDir, pluginPath)}`)
134
- }
135
-
136
323
  export function getConnectionString (database) {
137
324
  return connectionStrings[database]
138
325
  }
@@ -201,7 +388,30 @@ export async function createDB ({ hostname, database = 'sqlite', port, migration
201
388
  }
202
389
 
203
390
  if (plugin) {
204
- await generatePluginWithTypesSupport(logger, currentDir, typescript)
391
+ let jsHelper = { pre: '', config: '', post: '' }
392
+ switch (database) {
393
+ case 'sqlite':
394
+ jsHelper = jsHelperSqlite
395
+ break
396
+ case 'mysql':
397
+ jsHelper = jsHelperMySQL(connectionString)
398
+ break
399
+ case 'postgres':
400
+ jsHelper = jsHelperPostgres(connectionString)
401
+ break
402
+ case 'mariadb':
403
+ jsHelper = jsHelperMySQL(connectionString)
404
+ break
405
+ }
406
+ await generatePlugins(logger, currentDir, typescript, 'db', jsHelper)
407
+
408
+ if (createMigrations) {
409
+ if (typescript) {
410
+ await writeFile(join(currentDir, 'test', 'routes', 'movies.test.ts'), moviesTestTS)
411
+ } else {
412
+ await writeFile(join(currentDir, 'test', 'routes', 'movies.test.js'), moviesTestJS)
413
+ }
414
+ }
205
415
  }
206
416
 
207
417
  const output = {
package/src/ghaction.mjs CHANGED
@@ -176,7 +176,7 @@ export const askStaticWorkspaceGHAction = async (logger, env, type, buildTS, pro
176
176
  {
177
177
  type: 'list',
178
178
  name: 'githubAction',
179
- message: 'Do you want to create the github action to deploy this application to Platformatic Cloud static workspace?',
179
+ message: 'Do you want to create the github action to deploy this application to Platformatic Cloud?',
180
180
  default: true,
181
181
  choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
182
182
  }
@@ -114,8 +114,8 @@ export async function createPlatformaticRuntime (_args) {
114
114
 
115
115
  const env = await createRuntime(logger, projectDir, version, servicesDir, entrypoint)
116
116
 
117
- await askDynamicWorkspaceCreateGHAction(logger, env, 'service', false, projectDir)
118
117
  await askStaticWorkspaceGHAction(logger, env, 'service', false, projectDir)
118
+ await askDynamicWorkspaceCreateGHAction(logger, env, 'service', false, projectDir)
119
119
  }
120
120
 
121
121
  export async function createRuntimeService ({ servicesDir, names, logger }) {
@@ -78,8 +78,11 @@ const createPlatformaticService = async (_args, opts = {}) => {
78
78
  const fastifyVersion = await getDependencyVersion('fastify')
79
79
 
80
80
  if (!opts.skipPackageJson) {
81
- await createPackageJson(version, fastifyVersion, logger, projectDir, useTypescript, {}, {
82
- '@platformatic/service': '^' + version
81
+ const test = useTypescript ? 'tsc && node --test dist/test/*/*.test.js' : 'node --test test/*/*.test.js'
82
+ await createPackageJson(version, fastifyVersion, logger, projectDir, useTypescript, {
83
+ test
84
+ }, {
85
+ '@platformatic/service': `^${version}`
83
86
  })
84
87
  }
85
88
  if (!opts.skipGitignore) {
@@ -103,8 +106,8 @@ const createPlatformaticService = async (_args, opts = {}) => {
103
106
  }
104
107
 
105
108
  if (!opts.skipGitHubActions) {
106
- await askDynamicWorkspaceCreateGHAction(logger, env, 'service', useTypescript, projectDir)
107
109
  await askStaticWorkspaceGHAction(logger, env, 'service', useTypescript, projectDir)
110
+ await askDynamicWorkspaceCreateGHAction(logger, env, 'service', useTypescript, projectDir)
108
111
  }
109
112
  }
110
113