@pikku/cli 0.6.6

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.
Files changed (95) hide show
  1. package/CHANGELOG.md +445 -0
  2. package/README.md +3 -0
  3. package/bin/pikku-all.ts +110 -0
  4. package/bin/pikku-channels-map.ts +53 -0
  5. package/bin/pikku-channels.ts +57 -0
  6. package/bin/pikku-fetch.ts +54 -0
  7. package/bin/pikku-function-types.ts +76 -0
  8. package/bin/pikku-nextjs.test.ts +279 -0
  9. package/bin/pikku-nextjs.ts +113 -0
  10. package/bin/pikku-openapi.ts +71 -0
  11. package/bin/pikku-routes-map.ts +54 -0
  12. package/bin/pikku-routes.ts +55 -0
  13. package/bin/pikku-scheduler.ts +61 -0
  14. package/bin/pikku-schemas.ts +51 -0
  15. package/bin/pikku-websocket.ts +54 -0
  16. package/bin/pikku.ts +26 -0
  17. package/cli.schema.json +212 -0
  18. package/dist/bin/pikku-all.d.ts +4 -0
  19. package/dist/bin/pikku-all.js +71 -0
  20. package/dist/bin/pikku-channels-map.d.ts +5 -0
  21. package/dist/bin/pikku-channels-map.js +27 -0
  22. package/dist/bin/pikku-channels.d.ts +5 -0
  23. package/dist/bin/pikku-channels.js +32 -0
  24. package/dist/bin/pikku-fetch.d.ts +6 -0
  25. package/dist/bin/pikku-fetch.js +25 -0
  26. package/dist/bin/pikku-function-types.d.ts +6 -0
  27. package/dist/bin/pikku-function-types.js +32 -0
  28. package/dist/bin/pikku-nextjs.d.ts +7 -0
  29. package/dist/bin/pikku-nextjs.js +40 -0
  30. package/dist/bin/pikku-openapi.d.ts +5 -0
  31. package/dist/bin/pikku-openapi.js +41 -0
  32. package/dist/bin/pikku-routes-map.d.ts +5 -0
  33. package/dist/bin/pikku-routes-map.js +27 -0
  34. package/dist/bin/pikku-routes.d.ts +5 -0
  35. package/dist/bin/pikku-routes.js +33 -0
  36. package/dist/bin/pikku-scheduler.d.ts +5 -0
  37. package/dist/bin/pikku-scheduler.js +32 -0
  38. package/dist/bin/pikku-schemas.d.ts +5 -0
  39. package/dist/bin/pikku-schemas.js +27 -0
  40. package/dist/bin/pikku-websocket.d.ts +6 -0
  41. package/dist/bin/pikku-websocket.js +25 -0
  42. package/dist/bin/pikku.d.ts +2 -0
  43. package/dist/bin/pikku.js +23 -0
  44. package/dist/src/channels/serialize-channels.d.ts +3 -0
  45. package/dist/src/channels/serialize-channels.js +19 -0
  46. package/dist/src/channels/serialize-typed-channel-map.d.ts +3 -0
  47. package/dist/src/channels/serialize-typed-channel-map.js +87 -0
  48. package/dist/src/channels/serialize-websocket-wrapper.d.ts +1 -0
  49. package/dist/src/channels/serialize-websocket-wrapper.js +61 -0
  50. package/dist/src/core/serialize-import-map.d.ts +2 -0
  51. package/dist/src/core/serialize-import-map.js +23 -0
  52. package/dist/src/core/serialize-pikku-types.d.ts +4 -0
  53. package/dist/src/core/serialize-pikku-types.js +48 -0
  54. package/dist/src/http/serialize-fetch-wrapper.d.ts +1 -0
  55. package/dist/src/http/serialize-fetch-wrapper.js +57 -0
  56. package/dist/src/http/serialize-route-imports.d.ts +1 -0
  57. package/dist/src/http/serialize-route-imports.js +13 -0
  58. package/dist/src/http/serialize-route-meta.d.ts +2 -0
  59. package/dist/src/http/serialize-route-meta.js +6 -0
  60. package/dist/src/http/serialize-typed-route-map.d.ts +3 -0
  61. package/dist/src/http/serialize-typed-route-map.js +107 -0
  62. package/dist/src/inspector-glob.d.ts +2 -0
  63. package/dist/src/inspector-glob.js +12 -0
  64. package/dist/src/nextjs/serialize-nextjs-wrapper.d.ts +1 -0
  65. package/dist/src/nextjs/serialize-nextjs-wrapper.js +149 -0
  66. package/dist/src/openapi/openapi-spec-generator.d.ts +79 -0
  67. package/dist/src/openapi/openapi-spec-generator.js +135 -0
  68. package/dist/src/pikku-cli-config.d.ts +31 -0
  69. package/dist/src/pikku-cli-config.js +113 -0
  70. package/dist/src/scheduler/serialize-schedulers.d.ts +3 -0
  71. package/dist/src/scheduler/serialize-schedulers.js +22 -0
  72. package/dist/src/schema/schema-generator.d.ts +5 -0
  73. package/dist/src/schema/schema-generator.js +79 -0
  74. package/dist/src/utils.d.ts +34 -0
  75. package/dist/src/utils.js +109 -0
  76. package/dist/tsconfig.tsbuildinfo +1 -0
  77. package/package.json +42 -0
  78. package/run-tests.sh +53 -0
  79. package/src/channels/serialize-channels.ts +34 -0
  80. package/src/channels/serialize-typed-channel-map.ts +133 -0
  81. package/src/channels/serialize-websocket-wrapper.ts +61 -0
  82. package/src/core/serialize-import-map.ts +33 -0
  83. package/src/core/serialize-pikku-types.ts +53 -0
  84. package/src/http/serialize-fetch-wrapper.ts +57 -0
  85. package/src/http/serialize-route-imports.ts +24 -0
  86. package/src/http/serialize-route-meta.ts +10 -0
  87. package/src/http/serialize-typed-route-map.ts +147 -0
  88. package/src/inspector-glob.ts +27 -0
  89. package/src/nextjs/serialize-nextjs-wrapper.ts +156 -0
  90. package/src/openapi/openapi-spec-generator.ts +229 -0
  91. package/src/pikku-cli-config.ts +189 -0
  92. package/src/scheduler/serialize-schedulers.ts +43 -0
  93. package/src/schema/schema-generator.ts +117 -0
  94. package/src/utils.ts +219 -0
  95. package/tsconfig.json +21 -0
@@ -0,0 +1,76 @@
1
+ import { Command } from 'commander'
2
+ import { getPikkuCLIConfig, PikkuCLIConfig } from '../src/pikku-cli-config.js'
3
+ import { InspectorState } from '@pikku/inspector'
4
+ import {
5
+ getFileImportRelativePath,
6
+ getPikkuFilesAndMethods,
7
+ logCommandInfoAndTime,
8
+ logPikkuLogo,
9
+ PikkuCLIOptions,
10
+ writeFileInDir,
11
+ } from '../src/utils.js'
12
+ import { pikkuRoutes } from './pikku-routes.js'
13
+ import { inspectorGlob } from '../src/inspector-glob.js'
14
+ import { serializePikkuTypes } from '../src/core/serialize-pikku-types.js'
15
+
16
+ export const pikkuFunctionTypes = async (
17
+ { typesDeclarationFile: typesFile, packageMappings }: PikkuCLIConfig,
18
+ options: PikkuCLIOptions,
19
+ visitState: InspectorState
20
+ ) => {
21
+ await logCommandInfoAndTime(
22
+ 'Creating api types',
23
+ 'Created api types',
24
+ [false],
25
+ async () => {
26
+ const { userSessionType, sessionServicesType } =
27
+ await getPikkuFilesAndMethods(
28
+ visitState,
29
+ packageMappings,
30
+ typesFile,
31
+ options,
32
+ { userSessionType: true, sessionServiceType: true }
33
+ )
34
+ const content = serializePikkuTypes(
35
+ `import type { ${userSessionType.type} } from '${getFileImportRelativePath(typesFile, userSessionType.typePath, packageMappings)}'`,
36
+ userSessionType.type,
37
+ `import type { ${sessionServicesType.type} } from '${getFileImportRelativePath(typesFile, sessionServicesType.typePath, packageMappings)}'`,
38
+ sessionServicesType.type
39
+ )
40
+ await writeFileInDir(typesFile, content)
41
+ }
42
+ )
43
+ }
44
+
45
+ async function action(cliOptions: PikkuCLIOptions): Promise<void> {
46
+ logPikkuLogo()
47
+
48
+ const cliConfig = await getPikkuCLIConfig(cliOptions.config, [
49
+ 'rootDir',
50
+ 'routeDirectories',
51
+ 'typesDeclarationFile',
52
+ ])
53
+
54
+ const visitState = await inspectorGlob(
55
+ cliConfig.rootDir,
56
+ cliConfig.routeDirectories
57
+ )
58
+ await pikkuRoutes(cliConfig, visitState)
59
+ }
60
+
61
+ export const functionTypes = (program: Command): void => {
62
+ program
63
+ .command('types')
64
+ .description('Generate the core API')
65
+ .option('-ct | --pikku-config-type', 'The type of your pikku config object')
66
+ .option(
67
+ '-ss | --singleton-services-factory-type',
68
+ 'The type of your singleton services factory'
69
+ )
70
+ .option(
71
+ '-se | --session-services-factory-type',
72
+ 'The type of your session services factory'
73
+ )
74
+ .option('-c | --config <string>', 'The path to pikku cli config file')
75
+ .action(action)
76
+ }
@@ -0,0 +1,279 @@
1
+ // import * as path from 'path'
2
+ // import { assert } from 'chai'
3
+ // import * as sinon from 'sinon'
4
+
5
+ // import { action } from './pikku-nextjs.js'
6
+
7
+ // // Mocking external dependencies
8
+ // import * as fsPromises from 'fs/promises'
9
+ // import * as extractPikkuInformation from '../src/extract-pikku-information.js'
10
+ // import * as getFileImportRelativePath from '../src/utils.js'
11
+ // import * as nextjsWrapperGenerator from '../src/nextjs-wrapper-generator.js'
12
+
13
+ // import * as getPikkuConfig from '@pikku/core/pikku-config'
14
+
15
+ // describe('action function - generateNextJsWrapper arguments', () => {
16
+ // let sandbox: sinon.SinonSandbox
17
+ // let getPikkuConfigStub: sinon.SinonStub
18
+ // let extractPikkuInformationStub: sinon.SinonStub
19
+ // let getFileImportRelativePathStub: sinon.SinonStub
20
+ // let generateNextJsWrapperStub: sinon.SinonStub
21
+ // let processExitStub: sinon.SinonStub
22
+ // let consoleErrorStub: sinon.SinonStub
23
+
24
+ // beforeEach(() => {
25
+ // sandbox = sinon.createSandbox()
26
+
27
+ // // Stub external dependencies
28
+ // getPikkuConfigStub = sandbox.stub(
29
+ // getPikkuConfig,
30
+ // 'getPikkuConfig'
31
+ // )
32
+ // extractPikkuInformationStub = sandbox.stub(
33
+ // extractPikkuInformation,
34
+ // 'extractPikkuInformation'
35
+ // )
36
+ // getFileImportRelativePathStub = sandbox.stub(
37
+ // getFileImportRelativePath,
38
+ // 'getFileImportRelativePath'
39
+ // )
40
+ // generateNextJsWrapperStub = sandbox.stub(
41
+ // nextjsWrapperGenerator,
42
+ // 'generateNextJsWrapper'
43
+ // )
44
+
45
+ // // Stub fs.promises methods to prevent actual file system operations
46
+ // sandbox.stub(fsPromises, 'mkdir').resolves()
47
+ // sandbox.stub(fsPromises, 'writeFile').resolves()
48
+
49
+ // // Stub process.exit and console.error to prevent test from exiting and to capture errors
50
+ // processExitStub = sandbox.stub(process, 'exit')
51
+ // sandbox.stub(console, 'log')
52
+ // consoleErrorStub = sandbox.stub(console, 'error')
53
+
54
+ // // Default stubs for external functions
55
+ // getPikkuConfigStub.resolves({
56
+ // pikkuNextFile: 'nextFile.ts',
57
+ // rootDir: 'rootDir',
58
+ // routesFile: 'routes.ts',
59
+ // configDir: 'configDir',
60
+ // packageMappings: {},
61
+ // schemaDirectory: 'schemas',
62
+ // })
63
+
64
+ // extractPikkuInformationStub.resolves({
65
+ // pikkuConfigs: { 'configFile.ts': ['pikkuConfigVariable'] },
66
+ // sessionServicesFactories: {
67
+ // 'sessionFactoryFile.ts': ['sessionFactoryVariable'],
68
+ // },
69
+ // singletonServicesFactories: {
70
+ // 'singletonFactoryFile.ts': ['singletonFactoryVariable'],
71
+ // },
72
+ // })
73
+
74
+ // // Mock getFileImportRelativePath to return predictable paths
75
+ // getFileImportRelativePathStub.callsFake(
76
+ // (from: string, to: string, packageMappings: any) => {
77
+ // return `./${to}`
78
+ // }
79
+ // )
80
+ // })
81
+
82
+ // afterEach(() => {
83
+ // sandbox.restore()
84
+ // })
85
+
86
+ // it('should pass correct imports to generateNextJsWrapper', async () => {
87
+ // await action({})
88
+
89
+ // // Capture the arguments passed to generateNextJsWrapper
90
+ // assert(
91
+ // generateNextJsWrapperStub.calledOnce,
92
+ // 'generateNextJsWrapper should be called once'
93
+ // )
94
+
95
+ // const [
96
+ // ,
97
+ // ,
98
+ // pikkuConfigImport,
99
+ // singletonServicesImport,
100
+ // sessionServicesImport,
101
+ // ] = generateNextJsWrapperStub.firstCall.args
102
+
103
+ // const expectedPikkuConfigImport = `import { pikkuConfigVariable } from './configFile.ts'`
104
+ // const expectedSingletonServicesImport = `import { singletonFactoryVariable } from './singletonFactoryFile.ts'`
105
+ // const expectedSessionServicesImport = `import { sessionFactoryVariable } from './sessionFactoryFile.ts'`
106
+
107
+ // assert.strictEqual(
108
+ // pikkuConfigImport,
109
+ // expectedPikkuConfigImport,
110
+ // 'pikkuConfigImport should match expected import'
111
+ // )
112
+ // assert.strictEqual(
113
+ // singletonServicesImport,
114
+ // expectedSingletonServicesImport,
115
+ // 'singletonServicesImport should match expected import'
116
+ // )
117
+ // assert.strictEqual(
118
+ // sessionServicesImport,
119
+ // expectedSessionServicesImport,
120
+ // 'sessionServicesImport should match expected import'
121
+ // )
122
+ // })
123
+
124
+ // it('should use provided pikkuConfigFile and pikkuConfigVariable', async () => {
125
+ // const options = {
126
+ // pikkuConfigFile: 'customConfigFile.ts',
127
+ // pikkuConfigVariable: 'customPikkuConfigVariable',
128
+ // }
129
+
130
+ // await action(options)
131
+
132
+ // assert(
133
+ // generateNextJsWrapperStub.calledOnce,
134
+ // 'generateNextJsWrapper should be called once'
135
+ // )
136
+
137
+ // const [, , pikkuConfigImport] = generateNextJsWrapperStub.firstCall.args
138
+
139
+ // const expectedImport = `import { customPikkuConfigVariable } from './customConfigFile.ts'`
140
+ // assert.strictEqual(
141
+ // pikkuConfigImport,
142
+ // expectedImport,
143
+ // 'pikkuConfigImport should use provided file and variable'
144
+ // )
145
+ // })
146
+
147
+ // it('should handle missing pikkuConfigs and exit', async () => {
148
+ // // Modify the stub to simulate missing pikkuConfigs
149
+ // extractPikkuInformationStub.resolves({
150
+ // pikkuConfigs: {},
151
+ // sessionServicesFactories: {
152
+ // 'sessionFactoryFile.ts': ['sessionFactoryVariable'],
153
+ // },
154
+ // singletonServicesFactories: {
155
+ // 'singletonFactoryFile.ts': ['singletonFactoryVariable'],
156
+ // },
157
+ // })
158
+
159
+ // await action({})
160
+
161
+ // assert(consoleErrorStub.calledWithMatch('Found errors:'))
162
+ // assert(consoleErrorStub.calledWithMatch('No PikkuConfig object found'))
163
+ // assert(
164
+ // processExitStub.calledWith(1),
165
+ // 'process.exit should be called with 1'
166
+ // )
167
+ // assert.isFalse(
168
+ // generateNextJsWrapperStub.called,
169
+ // 'generateNextJsWrapper should not be called when there is an error'
170
+ // )
171
+ // })
172
+
173
+ // it('should generate correct import paths with packageMappings', async () => {
174
+ // // Provide packageMappings in the pikkuConfig
175
+ // getPikkuConfigStub.resolves({
176
+ // pikkuNextFile: 'nextFile.ts',
177
+ // rootDir: 'rootDir',
178
+ // routesFile: 'routes.ts',
179
+ // configDir: 'configDir',
180
+ // packageMappings: {
181
+ // 'configFile.ts': '@configs/configFile',
182
+ // 'singletonFactoryFile.ts': '@factories/singletonFactory',
183
+ // 'sessionFactoryFile.ts': '@factories/sessionFactory',
184
+ // },
185
+ // schemaDirectory: 'schemas',
186
+ // })
187
+
188
+ // // Modify getFileImportRelativePath to consider packageMappings
189
+ // getFileImportRelativePathStub.callsFake(
190
+ // (from: string, to: string, packageMappings: any) => {
191
+ // const mappedPackage = packageMappings[to]
192
+ // return mappedPackage || `./${path.relative(path.dirname(from), to)}`
193
+ // }
194
+ // )
195
+
196
+ // await action({})
197
+
198
+ // assert(
199
+ // generateNextJsWrapperStub.calledOnce,
200
+ // 'generateNextJsWrapper should be called once'
201
+ // )
202
+
203
+ // const [
204
+ // ,
205
+ // ,
206
+ // pikkuConfigImport,
207
+ // singletonServicesImport,
208
+ // sessionServicesImport,
209
+ // ] = generateNextJsWrapperStub.firstCall.args
210
+
211
+ // const expectedPikkuConfigImport = `import { pikkuConfigVariable } from '@configs/configFile'`
212
+ // const expectedSingletonServicesImport = `import { singletonFactoryVariable } from '@factories/singletonFactory'`
213
+ // const expectedSessionServicesImport = `import { sessionFactoryVariable } from '@factories/sessionFactory'`
214
+
215
+ // assert.strictEqual(
216
+ // pikkuConfigImport,
217
+ // expectedPikkuConfigImport,
218
+ // 'pikkuConfigImport should use package mapping'
219
+ // )
220
+ // assert.strictEqual(
221
+ // singletonServicesImport,
222
+ // expectedSingletonServicesImport,
223
+ // 'singletonServicesImport should use package mapping'
224
+ // )
225
+ // assert.strictEqual(
226
+ // sessionServicesImport,
227
+ // expectedSessionServicesImport,
228
+ // 'sessionServicesImport should use package mapping'
229
+ // )
230
+ // })
231
+
232
+ // it('should use provided singletonServicesFactoryFile and singletonServicesFactoryVariable', async () => {
233
+ // const options = {
234
+ // singletonServicesFactoryFile: 'customSingletonFactoryFile.ts',
235
+ // singletonServicesFactoryVariable: 'customSingletonFactoryVariable',
236
+ // }
237
+
238
+ // await action(options)
239
+
240
+ // assert(
241
+ // generateNextJsWrapperStub.calledOnce,
242
+ // 'generateNextJsWrapper should be called once'
243
+ // )
244
+
245
+ // const [, , , singletonServicesImport] =
246
+ // generateNextJsWrapperStub.firstCall.args
247
+
248
+ // const expectedImport = `import { customSingletonFactoryVariable } from './customSingletonFactoryFile.ts'`
249
+ // assert.strictEqual(
250
+ // singletonServicesImport,
251
+ // expectedImport,
252
+ // 'singletonServicesImport should use provided file and variable'
253
+ // )
254
+ // })
255
+
256
+ // it('should use provided sessionServicesFactoryFile and sessionServicesFactoryVariable', async () => {
257
+ // const options = {
258
+ // sessionServicesFactoryFile: 'customSessionFactoryFile.ts',
259
+ // sessionServicesFactoryVariable: 'customSessionFactoryVariable',
260
+ // }
261
+
262
+ // await action(options)
263
+
264
+ // assert(
265
+ // generateNextJsWrapperStub.calledOnce,
266
+ // 'generateNextJsWrapper should be called once'
267
+ // )
268
+
269
+ // const [, , , , sessionServicesImport] =
270
+ // generateNextJsWrapperStub.firstCall.args
271
+
272
+ // const expectedImport = `import { customSessionFactoryVariable } from './customSessionFactoryFile.ts'`
273
+ // assert.strictEqual(
274
+ // sessionServicesImport,
275
+ // expectedImport,
276
+ // 'sessionServicesImport should use provided file and variable'
277
+ // )
278
+ // })
279
+ // })
@@ -0,0 +1,113 @@
1
+ import { Command } from 'commander'
2
+ import { serializeNextJsWrapper } from '../src/nextjs/serialize-nextjs-wrapper.js'
3
+ import {
4
+ getFileImportRelativePath,
5
+ getPikkuFilesAndMethods,
6
+ logCommandInfoAndTime,
7
+ logPikkuLogo,
8
+ PikkuCLIOptions,
9
+ writeFileInDir,
10
+ } from '../src/utils.js'
11
+ import { getPikkuCLIConfig, PikkuCLIConfig } from '../src/pikku-cli-config.js'
12
+ import { InspectorState } from '@pikku/inspector'
13
+ import { inspectorGlob } from '../src/inspector-glob.js'
14
+
15
+ export const pikkuNext = async (
16
+ {
17
+ nextJSfile,
18
+ routesFile,
19
+ routesMapDeclarationFile,
20
+ schemaDirectory,
21
+ packageMappings,
22
+ }: PikkuCLIConfig,
23
+ visitState: InspectorState,
24
+ options: PikkuCLIOptions
25
+ ) => {
26
+ return await logCommandInfoAndTime(
27
+ 'Generating nextjs wrapper',
28
+ 'Generated nextjs wrapper',
29
+ [nextJSfile === undefined, 'nextjs outfile is not defined'],
30
+ async () => {
31
+ if (!nextJSfile) {
32
+ throw new Error('nextJSfile is required in pikku config')
33
+ }
34
+
35
+ const {
36
+ pikkuConfigFactory,
37
+ singletonServicesFactory,
38
+ sessionServicesFactory,
39
+ } = await getPikkuFilesAndMethods(
40
+ visitState,
41
+ packageMappings,
42
+ nextJSfile,
43
+ options,
44
+ {
45
+ config: true,
46
+ singletonServicesFactory: true,
47
+ sessionServicesFactory: true,
48
+ }
49
+ )
50
+
51
+ const pikkuConfigImport = `import { ${pikkuConfigFactory.variable} as createConfig } from '${getFileImportRelativePath(nextJSfile, pikkuConfigFactory.file, packageMappings)}'`
52
+ const singletonServicesImport = `import { ${singletonServicesFactory.variable} as createSingletonServices } from '${getFileImportRelativePath(nextJSfile, singletonServicesFactory.file, packageMappings)}'`
53
+ const sessionServicesImport = `import { ${sessionServicesFactory.variable} as createSessionServices } from '${getFileImportRelativePath(nextJSfile, sessionServicesFactory.file, packageMappings)}'`
54
+
55
+ const routesPath = getFileImportRelativePath(
56
+ nextJSfile,
57
+ routesFile,
58
+ packageMappings
59
+ )
60
+ const routesMapDeclarationPath = getFileImportRelativePath(
61
+ nextJSfile,
62
+ routesMapDeclarationFile,
63
+ packageMappings
64
+ )
65
+ const schemasPath = getFileImportRelativePath(
66
+ nextJSfile,
67
+ `${schemaDirectory}/register.gen.ts`,
68
+ packageMappings
69
+ )
70
+
71
+ const content = serializeNextJsWrapper(
72
+ routesPath,
73
+ routesMapDeclarationPath,
74
+ schemasPath,
75
+ pikkuConfigImport,
76
+ singletonServicesImport,
77
+ sessionServicesImport
78
+ )
79
+ await writeFileInDir(nextJSfile, content)
80
+ }
81
+ )
82
+ }
83
+
84
+ export const action = async (options: PikkuCLIOptions): Promise<void> => {
85
+ logPikkuLogo()
86
+ const cliConfig = await getPikkuCLIConfig(
87
+ options.config,
88
+ ['rootDir', 'schemaDirectory', 'configDir', 'nextJSfile'],
89
+ true
90
+ )
91
+ const visitState = await inspectorGlob(
92
+ cliConfig.rootDir,
93
+ cliConfig.routeDirectories
94
+ )
95
+ await pikkuNext(cliConfig, visitState, options)
96
+ }
97
+
98
+ export const nextjs = (program: Command): void => {
99
+ program
100
+ .command('nextjs')
101
+ .description('generate nextjs wrapper')
102
+ .option('-ct | --pikku-config-type', 'The type of your pikku config object')
103
+ .option(
104
+ '-ss | --singleton-services-factory-type',
105
+ 'The type of your singleton services factory'
106
+ )
107
+ .option(
108
+ '-se | --session-services-factory-type',
109
+ 'The type of your session services factory'
110
+ )
111
+ .option('-c | --config <string>', 'The path to pikku cli config file')
112
+ .action(action)
113
+ }
@@ -0,0 +1,71 @@
1
+ import { Command } from 'commander'
2
+ import {
3
+ logCommandInfoAndTime,
4
+ logPikkuLogo,
5
+ PikkuCLIOptions,
6
+ writeFileInDir,
7
+ } from '../src/utils.js'
8
+ import { generateSchemas } from '../src/schema/schema-generator.js'
9
+ import { generateOpenAPISpec } from '../src/openapi/openapi-spec-generator.js'
10
+ import { getPikkuCLIConfig, PikkuCLIConfig } from '../src/pikku-cli-config.js'
11
+ import { InspectorState } from '@pikku/inspector'
12
+ import { stringify } from 'yaml'
13
+ import { inspectorGlob } from '../src/inspector-glob.js'
14
+
15
+ export const pikkuOpenAPI = async (
16
+ { tsconfig, openAPI }: PikkuCLIConfig,
17
+ { http }: InspectorState
18
+ ) => {
19
+ await logCommandInfoAndTime(
20
+ 'Creating OpenAPI spec',
21
+ 'Created OpenAPI spec',
22
+ [openAPI?.outputFile === undefined, 'openAPI outfile is not defined'],
23
+ async () => {
24
+ if (!openAPI?.outputFile) {
25
+ throw new Error('openAPI is required')
26
+ }
27
+ const schemas = await generateSchemas(tsconfig, http.typesMap, http.meta)
28
+ const openAPISpec = await generateOpenAPISpec(
29
+ http.meta,
30
+ schemas,
31
+ openAPI.additionalInfo
32
+ )
33
+ if (openAPI.outputFile.endsWith('.json')) {
34
+ await writeFileInDir(
35
+ openAPI.outputFile,
36
+ JSON.stringify(openAPISpec, null, 2),
37
+ true
38
+ )
39
+ } else if (
40
+ openAPI.outputFile.endsWith('.yaml') ||
41
+ openAPI.outputFile.endsWith('.yml')
42
+ ) {
43
+ await writeFileInDir(openAPI.outputFile, stringify(openAPISpec), true)
44
+ }
45
+ }
46
+ )
47
+ }
48
+
49
+ async function action({ config }: PikkuCLIOptions): Promise<void> {
50
+ logPikkuLogo()
51
+ const cliConfig = await getPikkuCLIConfig(config, [
52
+ 'rootDir',
53
+ 'routesFile',
54
+ 'openAPI',
55
+ 'schemaDirectory',
56
+ 'tsconfig',
57
+ ])
58
+ const visitState = await inspectorGlob(
59
+ cliConfig.rootDir,
60
+ cliConfig.routeDirectories
61
+ )
62
+ await pikkuOpenAPI(cliConfig, visitState)
63
+ }
64
+
65
+ export const openapi = (program: Command): void => {
66
+ program
67
+ .command('openapi')
68
+ .description('Generate an openapi spec')
69
+ .option('-c | --config <string>', 'The path to pikku cli config file')
70
+ .action(action)
71
+ }
@@ -0,0 +1,54 @@
1
+ import { Command } from 'commander'
2
+ import { getPikkuCLIConfig, PikkuCLIConfig } from '../src/pikku-cli-config.js'
3
+ import { InspectorState } from '@pikku/inspector'
4
+ import {
5
+ logCommandInfoAndTime,
6
+ logPikkuLogo,
7
+ PikkuCLIOptions,
8
+ writeFileInDir,
9
+ } from '../src/utils.js'
10
+ import { serializeTypedRoutesMap } from '../src/http/serialize-typed-route-map.js'
11
+ import { inspectorGlob } from '../src/inspector-glob.js'
12
+
13
+ export const pikkuHTTPMap = async (
14
+ { routesMapDeclarationFile, packageMappings }: PikkuCLIConfig,
15
+ { http }: InspectorState
16
+ ) => {
17
+ return await logCommandInfoAndTime(
18
+ 'Creating routes map',
19
+ 'Created routes map',
20
+ [http.files.size === 0],
21
+ async () => {
22
+ const content = serializeTypedRoutesMap(
23
+ routesMapDeclarationFile,
24
+ packageMappings,
25
+ http.typesMap,
26
+ http.meta,
27
+ http.metaInputTypes
28
+ )
29
+ await writeFileInDir(routesMapDeclarationFile, content)
30
+ }
31
+ )
32
+ }
33
+
34
+ async function action(cliOptions: PikkuCLIOptions): Promise<void> {
35
+ logPikkuLogo()
36
+ const cliConfig = await getPikkuCLIConfig(cliOptions.config, [
37
+ 'rootDir',
38
+ 'routeDirectories',
39
+ 'routesFile',
40
+ ])
41
+ const visitState = await inspectorGlob(
42
+ cliConfig.rootDir,
43
+ cliConfig.routeDirectories
44
+ )
45
+ await pikkuHTTPMap(cliConfig, visitState)
46
+ }
47
+
48
+ export const routesMap = (program: Command): void => {
49
+ program
50
+ .command('map')
51
+ .description('Generate a map of all routes to aid in type checking')
52
+ .option('-c | --config <string>', 'The path to pikku cli config file')
53
+ .action(action)
54
+ }
@@ -0,0 +1,55 @@
1
+ import { Command } from 'commander'
2
+ import { getPikkuCLIConfig, PikkuCLIConfig } from '../src/pikku-cli-config.js'
3
+ import { serializeHTTPRoutesMeta } from '../src/http/serialize-route-meta.js'
4
+ import { InspectorState } from '@pikku/inspector'
5
+ import {
6
+ logCommandInfoAndTime,
7
+ logPikkuLogo,
8
+ PikkuCLIOptions,
9
+ writeFileInDir,
10
+ } from '../src/utils.js'
11
+ import { serializeRoutes } from '../src/http/serialize-route-imports.js'
12
+ import { inspectorGlob } from '../src/inspector-glob.js'
13
+
14
+ export const pikkuRoutes = async (
15
+ cliConfig: PikkuCLIConfig,
16
+ visitState: InspectorState
17
+ ) => {
18
+ return await logCommandInfoAndTime(
19
+ 'Finding routes',
20
+ 'Found routes',
21
+ [visitState.http.files.size === 0],
22
+ async () => {
23
+ const { routesFile, packageMappings } = cliConfig
24
+ const { http } = visitState
25
+ const content = [
26
+ serializeRoutes(routesFile, http.files, packageMappings),
27
+ serializeHTTPRoutesMeta(http.meta),
28
+ ]
29
+ await writeFileInDir(routesFile, content.join('\n\n'))
30
+ }
31
+ )
32
+ }
33
+
34
+ async function action(cliOptions: PikkuCLIOptions): Promise<void> {
35
+ logPikkuLogo()
36
+
37
+ const cliConfig = await getPikkuCLIConfig(cliOptions.config, [
38
+ 'rootDir',
39
+ 'routeDirectories',
40
+ 'routesFile',
41
+ ])
42
+ const visitState = await inspectorGlob(
43
+ cliConfig.rootDir,
44
+ cliConfig.routeDirectories
45
+ )
46
+ await pikkuRoutes(cliConfig, visitState)
47
+ }
48
+
49
+ export const routes = (program: Command): void => {
50
+ program
51
+ .command('routes')
52
+ .description('Find all routes to import')
53
+ .option('-c | --config <string>', 'The path to pikku cli config file')
54
+ .action(action)
55
+ }