@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.
- package/CHANGELOG.md +445 -0
- package/README.md +3 -0
- package/bin/pikku-all.ts +110 -0
- package/bin/pikku-channels-map.ts +53 -0
- package/bin/pikku-channels.ts +57 -0
- package/bin/pikku-fetch.ts +54 -0
- package/bin/pikku-function-types.ts +76 -0
- package/bin/pikku-nextjs.test.ts +279 -0
- package/bin/pikku-nextjs.ts +113 -0
- package/bin/pikku-openapi.ts +71 -0
- package/bin/pikku-routes-map.ts +54 -0
- package/bin/pikku-routes.ts +55 -0
- package/bin/pikku-scheduler.ts +61 -0
- package/bin/pikku-schemas.ts +51 -0
- package/bin/pikku-websocket.ts +54 -0
- package/bin/pikku.ts +26 -0
- package/cli.schema.json +212 -0
- package/dist/bin/pikku-all.d.ts +4 -0
- package/dist/bin/pikku-all.js +71 -0
- package/dist/bin/pikku-channels-map.d.ts +5 -0
- package/dist/bin/pikku-channels-map.js +27 -0
- package/dist/bin/pikku-channels.d.ts +5 -0
- package/dist/bin/pikku-channels.js +32 -0
- package/dist/bin/pikku-fetch.d.ts +6 -0
- package/dist/bin/pikku-fetch.js +25 -0
- package/dist/bin/pikku-function-types.d.ts +6 -0
- package/dist/bin/pikku-function-types.js +32 -0
- package/dist/bin/pikku-nextjs.d.ts +7 -0
- package/dist/bin/pikku-nextjs.js +40 -0
- package/dist/bin/pikku-openapi.d.ts +5 -0
- package/dist/bin/pikku-openapi.js +41 -0
- package/dist/bin/pikku-routes-map.d.ts +5 -0
- package/dist/bin/pikku-routes-map.js +27 -0
- package/dist/bin/pikku-routes.d.ts +5 -0
- package/dist/bin/pikku-routes.js +33 -0
- package/dist/bin/pikku-scheduler.d.ts +5 -0
- package/dist/bin/pikku-scheduler.js +32 -0
- package/dist/bin/pikku-schemas.d.ts +5 -0
- package/dist/bin/pikku-schemas.js +27 -0
- package/dist/bin/pikku-websocket.d.ts +6 -0
- package/dist/bin/pikku-websocket.js +25 -0
- package/dist/bin/pikku.d.ts +2 -0
- package/dist/bin/pikku.js +23 -0
- package/dist/src/channels/serialize-channels.d.ts +3 -0
- package/dist/src/channels/serialize-channels.js +19 -0
- package/dist/src/channels/serialize-typed-channel-map.d.ts +3 -0
- package/dist/src/channels/serialize-typed-channel-map.js +87 -0
- package/dist/src/channels/serialize-websocket-wrapper.d.ts +1 -0
- package/dist/src/channels/serialize-websocket-wrapper.js +61 -0
- package/dist/src/core/serialize-import-map.d.ts +2 -0
- package/dist/src/core/serialize-import-map.js +23 -0
- package/dist/src/core/serialize-pikku-types.d.ts +4 -0
- package/dist/src/core/serialize-pikku-types.js +48 -0
- package/dist/src/http/serialize-fetch-wrapper.d.ts +1 -0
- package/dist/src/http/serialize-fetch-wrapper.js +57 -0
- package/dist/src/http/serialize-route-imports.d.ts +1 -0
- package/dist/src/http/serialize-route-imports.js +13 -0
- package/dist/src/http/serialize-route-meta.d.ts +2 -0
- package/dist/src/http/serialize-route-meta.js +6 -0
- package/dist/src/http/serialize-typed-route-map.d.ts +3 -0
- package/dist/src/http/serialize-typed-route-map.js +107 -0
- package/dist/src/inspector-glob.d.ts +2 -0
- package/dist/src/inspector-glob.js +12 -0
- package/dist/src/nextjs/serialize-nextjs-wrapper.d.ts +1 -0
- package/dist/src/nextjs/serialize-nextjs-wrapper.js +149 -0
- package/dist/src/openapi/openapi-spec-generator.d.ts +79 -0
- package/dist/src/openapi/openapi-spec-generator.js +135 -0
- package/dist/src/pikku-cli-config.d.ts +31 -0
- package/dist/src/pikku-cli-config.js +113 -0
- package/dist/src/scheduler/serialize-schedulers.d.ts +3 -0
- package/dist/src/scheduler/serialize-schedulers.js +22 -0
- package/dist/src/schema/schema-generator.d.ts +5 -0
- package/dist/src/schema/schema-generator.js +79 -0
- package/dist/src/utils.d.ts +34 -0
- package/dist/src/utils.js +109 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +42 -0
- package/run-tests.sh +53 -0
- package/src/channels/serialize-channels.ts +34 -0
- package/src/channels/serialize-typed-channel-map.ts +133 -0
- package/src/channels/serialize-websocket-wrapper.ts +61 -0
- package/src/core/serialize-import-map.ts +33 -0
- package/src/core/serialize-pikku-types.ts +53 -0
- package/src/http/serialize-fetch-wrapper.ts +57 -0
- package/src/http/serialize-route-imports.ts +24 -0
- package/src/http/serialize-route-meta.ts +10 -0
- package/src/http/serialize-typed-route-map.ts +147 -0
- package/src/inspector-glob.ts +27 -0
- package/src/nextjs/serialize-nextjs-wrapper.ts +156 -0
- package/src/openapi/openapi-spec-generator.ts +229 -0
- package/src/pikku-cli-config.ts +189 -0
- package/src/scheduler/serialize-schedulers.ts +43 -0
- package/src/schema/schema-generator.ts +117 -0
- package/src/utils.ts +219 -0
- 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
|
+
}
|