@pikku/cli 0.6.20 → 0.7.0

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 (111) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/cli.schema.json +2 -2
  3. package/dist/bin/pikku-all.js +34 -16
  4. package/dist/bin/pikku-channels-map.js +4 -4
  5. package/dist/bin/pikku-channels.js +6 -10
  6. package/dist/bin/pikku-fetch.d.ts +1 -1
  7. package/dist/bin/pikku-fetch.js +3 -3
  8. package/dist/bin/pikku-function-types.js +4 -4
  9. package/dist/bin/pikku-functions.d.ts +5 -0
  10. package/dist/bin/pikku-functions.js +24 -0
  11. package/dist/bin/pikku-http-map.d.ts +5 -0
  12. package/dist/bin/pikku-http-map.js +23 -0
  13. package/dist/bin/pikku-http-routes.d.ts +5 -0
  14. package/dist/bin/pikku-http-routes.js +24 -0
  15. package/dist/bin/pikku-http.js +3 -5
  16. package/dist/bin/pikku-nextjs.d.ts +1 -1
  17. package/dist/bin/pikku-nextjs.js +8 -8
  18. package/dist/bin/pikku-openapi.d.ts +1 -1
  19. package/dist/bin/pikku-openapi.js +6 -6
  20. package/dist/bin/pikku-routes-map.d.ts +1 -1
  21. package/dist/bin/pikku-routes-map.js +3 -3
  22. package/dist/bin/pikku-scheduler.js +7 -10
  23. package/dist/bin/pikku-schemas.d.ts +1 -1
  24. package/dist/bin/pikku-schemas.js +6 -6
  25. package/dist/bin/pikku-websocket.js +1 -1
  26. package/dist/bin/pikku.js +2 -2
  27. package/dist/src/channels/serialize-typed-channel-map.js +5 -2
  28. package/dist/src/core/serialize-import-map.js +1 -0
  29. package/dist/src/core/serialize-pikku-types.js +90 -6
  30. package/dist/src/events/channels/serialize-channels.d.ts +3 -0
  31. package/dist/src/events/channels/serialize-channels.js +19 -0
  32. package/dist/src/events/channels/serialize-typed-channel-map.d.ts +3 -0
  33. package/dist/src/events/channels/serialize-typed-channel-map.js +90 -0
  34. package/dist/src/events/channels/serialize-websocket-wrapper.d.ts +1 -0
  35. package/{src/channels/serialize-websocket-wrapper.ts → dist/src/events/channels/serialize-websocket-wrapper.js} +4 -4
  36. package/dist/src/events/http/serialize-fetch-wrapper.d.ts +1 -0
  37. package/{src/http/serialize-fetch-wrapper.ts → dist/src/events/http/serialize-fetch-wrapper.js} +4 -4
  38. package/dist/src/events/http/serialize-route-imports.d.ts +1 -0
  39. package/dist/src/events/http/serialize-route-imports.js +13 -0
  40. package/dist/src/events/http/serialize-route-meta.d.ts +2 -0
  41. package/dist/src/events/http/serialize-route-meta.js +6 -0
  42. package/dist/src/events/http/serialize-typed-route-map.d.ts +4 -0
  43. package/dist/src/events/http/serialize-typed-route-map.js +107 -0
  44. package/dist/src/events/scheduler/serialize-schedulers.d.ts +3 -0
  45. package/dist/src/events/scheduler/serialize-schedulers.js +23 -0
  46. package/dist/src/http/serialize-typed-route-map.js +1 -1
  47. package/dist/src/inspector-glob.d.ts +1 -1
  48. package/dist/src/inspector-glob.js +2 -2
  49. package/dist/src/openapi-spec-generator.d.ts +79 -0
  50. package/dist/src/openapi-spec-generator.js +136 -0
  51. package/dist/src/pikku-cli-config.d.ts +9 -4
  52. package/dist/src/pikku-cli-config.js +19 -4
  53. package/dist/src/scheduler/serialize-schedulers.js +3 -2
  54. package/dist/src/schema/schema-generator.d.ts +1 -1
  55. package/dist/src/schema/schema-generator.js +20 -7
  56. package/dist/src/schema-generator.d.ts +5 -0
  57. package/dist/src/schema-generator.js +98 -0
  58. package/dist/src/serialize-fetch-wrapper.d.ts +1 -0
  59. package/dist/src/serialize-fetch-wrapper.js +67 -0
  60. package/dist/src/serialize-import-map.d.ts +2 -0
  61. package/dist/src/serialize-import-map.js +24 -0
  62. package/dist/src/serialize-nextjs-backend-wrapper.d.ts +1 -0
  63. package/{src/nextjs/serialize-nextjs-backend-wrapper.ts → dist/src/serialize-nextjs-backend-wrapper.js} +4 -11
  64. package/dist/src/serialize-nextjs-http-wrapper.d.ts +1 -0
  65. package/{src/nextjs/serialize-nextjs-http-wrapper.ts → dist/src/serialize-nextjs-http-wrapper.js} +4 -7
  66. package/dist/src/serialize-pikku-types.d.ts +4 -0
  67. package/dist/src/serialize-pikku-types.js +136 -0
  68. package/dist/src/serialize-scheduler-meta.d.ts +2 -0
  69. package/dist/src/serialize-scheduler-meta.js +10 -0
  70. package/dist/src/serialize-typed-channel-map.d.ts +3 -0
  71. package/dist/src/serialize-typed-channel-map.js +93 -0
  72. package/dist/src/serialize-typed-function-map.d.ts +4 -0
  73. package/dist/src/serialize-typed-function-map.js +107 -0
  74. package/dist/src/serialize-typed-http-map.d.ts +4 -0
  75. package/dist/src/serialize-typed-http-map.js +107 -0
  76. package/dist/src/serialize-typed-route-map.d.ts +4 -0
  77. package/dist/src/serialize-typed-route-map.js +107 -0
  78. package/dist/src/serialize-websocket-wrapper.d.ts +1 -0
  79. package/dist/src/serialize-websocket-wrapper.js +61 -0
  80. package/dist/src/utils.d.ts +1 -0
  81. package/dist/src/utils.js +17 -5
  82. package/package.json +3 -3
  83. package/bin/pikku-all.ts +0 -180
  84. package/bin/pikku-channels-map.ts +0 -55
  85. package/bin/pikku-channels.ts +0 -58
  86. package/bin/pikku-fetch.ts +0 -55
  87. package/bin/pikku-function-types.ts +0 -84
  88. package/bin/pikku-http.ts +0 -56
  89. package/bin/pikku-nextjs.test.ts +0 -279
  90. package/bin/pikku-nextjs.ts +0 -152
  91. package/bin/pikku-openapi.ts +0 -70
  92. package/bin/pikku-routes-map.ts +0 -55
  93. package/bin/pikku-scheduler.ts +0 -62
  94. package/bin/pikku-schemas.ts +0 -52
  95. package/bin/pikku-websocket.ts +0 -58
  96. package/bin/pikku.ts +0 -26
  97. package/dist/tsconfig.tsbuildinfo +0 -1
  98. package/src/channels/serialize-channels.ts +0 -34
  99. package/src/channels/serialize-typed-channel-map.ts +0 -136
  100. package/src/core/serialize-import-map.ts +0 -33
  101. package/src/core/serialize-pikku-types.ts +0 -55
  102. package/src/http/serialize-route-imports.ts +0 -24
  103. package/src/http/serialize-route-meta.ts +0 -10
  104. package/src/http/serialize-typed-route-map.ts +0 -150
  105. package/src/inspector-glob.ts +0 -28
  106. package/src/openapi/openapi-spec-generator.ts +0 -227
  107. package/src/pikku-cli-config.ts +0 -204
  108. package/src/scheduler/serialize-schedulers.ts +0 -41
  109. package/src/schema/schema-generator.ts +0 -114
  110. package/src/utils.ts +0 -260
  111. package/tsconfig.json +0 -21
@@ -1,227 +0,0 @@
1
- import { HTTPRoutesMeta, pikkuState } from '@pikku/core'
2
- import _convertSchema from '@openapi-contrib/json-schema-to-openapi-schema'
3
- const convertSchema =
4
- 'default' in _convertSchema ? (_convertSchema.default as any) : _convertSchema
5
-
6
- interface OpenAPISpec {
7
- openapi: string
8
- info: {
9
- title: string
10
- version: string
11
- description?: string
12
- termsOfService?: string
13
- contact?: {
14
- name?: string
15
- url?: string
16
- email?: string
17
- }
18
- license?: {
19
- name: string
20
- url?: string
21
- }
22
- }
23
- servers: { url: string; description?: string }[]
24
- paths: Record<string, any>
25
- components: {
26
- schemas: Record<string, any>
27
- responses?: Record<string, any>
28
- parameters?: Record<string, any>
29
- examples?: Record<string, any>
30
- requestBodies?: Record<string, any>
31
- headers?: Record<string, any>
32
- securitySchemes?: Record<string, any>
33
- }
34
- security?: { [key: string]: any[] }[]
35
- tags?: { name: string; description?: string }[]
36
- externalDocs?: {
37
- description?: string
38
- url: string
39
- }
40
- }
41
-
42
- export interface OpenAPISpecInfo {
43
- info: {
44
- title: string
45
- version: string
46
- description: string
47
- termsOfService?: string
48
- contact?: {
49
- name?: string
50
- url?: string
51
- email?: string
52
- }
53
- license?: {
54
- name: string
55
- url?: string
56
- }
57
- }
58
- servers: { url: string; description?: string }[]
59
- tags?: { name: string; description?: string }[]
60
- externalDocs?: {
61
- description?: string
62
- url: string
63
- }
64
- securitySchemes?: Record<string, any>
65
- security?: { [key: string]: any[] }[]
66
- }
67
-
68
- const getErrorResponseForConstructorName = (constructorName: string) => {
69
- const errors = Array.from(pikkuState('misc', 'errors').entries())
70
- const foundError = errors.find(([e]) => e.name === constructorName)
71
- if (foundError) {
72
- return foundError[1]
73
- }
74
- return undefined
75
- }
76
-
77
- const convertSchemasToBodyPayloads = async (
78
- routesMeta: HTTPRoutesMeta,
79
- schemas: Record<string, any>
80
- ) => {
81
- const requiredSchemas = new Set(
82
- routesMeta
83
- .map(({ inputTypes, output }) => [inputTypes?.body, output])
84
- .flat()
85
- .filter((schema) => !!schema)
86
- )
87
- const convertedEntries = await Promise.all(
88
- Object.entries(schemas).map(async ([key, schema]) => {
89
- if (requiredSchemas.has(key)) {
90
- const convertedSchema = await convertSchema(schema, {
91
- convertUnreferencedDefinitions: false,
92
- dereference: { circular: 'ignore' },
93
- })
94
- return [key, convertedSchema]
95
- }
96
- return
97
- })
98
- )
99
- return Object.fromEntries(convertedEntries.filter((s) => !!s))
100
- }
101
-
102
- export async function generateOpenAPISpec(
103
- routeMeta: HTTPRoutesMeta,
104
- schemas: Record<string, any>,
105
- additionalInfo: OpenAPISpecInfo
106
- ): Promise<OpenAPISpec> {
107
- const paths: Record<string, any> = {}
108
-
109
- routeMeta.forEach((meta) => {
110
- const { route, method, inputTypes, output, params, query, docs } = meta
111
- const path = route.replace(/:(\w+)/g, '{$1}') // Convert ":param" to "{param}"
112
-
113
- if (!paths[path]) {
114
- paths[path] = {}
115
- }
116
-
117
- const responses = {}
118
- docs?.errors?.forEach((error) => {
119
- const errorResponse = getErrorResponseForConstructorName(error)
120
- if (errorResponse) {
121
- responses[errorResponse.status] = {
122
- description: errorResponse.message,
123
- }
124
- }
125
- })
126
-
127
- const operation: any = {
128
- description:
129
- docs?.description ||
130
- `This endpoint handles the ${method.toUpperCase()} request for the route ${route}.`,
131
- tags: docs?.tags || [route.split('/')[1] || 'default'],
132
- parameters: [],
133
- responses: {
134
- ...responses,
135
- '200': {
136
- description: 'Successful response',
137
- content: output
138
- ? {
139
- 'application/json': {
140
- schema:
141
- typeof output === 'string' &&
142
- ['boolean', 'string', 'number'].includes(output)
143
- ? { type: output }
144
- : { $ref: `#/components/schemas/${output}` },
145
- },
146
- }
147
- : undefined,
148
- },
149
- },
150
- }
151
-
152
- const bodyType = inputTypes?.body
153
- if (bodyType) {
154
- operation.requestBody = {
155
- required: true,
156
- content: {
157
- 'application/json': {
158
- schema:
159
- typeof bodyType === 'string' &&
160
- ['boolean', 'string', 'number'].includes(bodyType)
161
- ? { type: bodyType }
162
- : { $ref: `#/components/schemas/${bodyType}` },
163
- },
164
- },
165
- }
166
- }
167
-
168
- if (params) {
169
- operation.parameters = params.map((param) => ({
170
- name: param,
171
- in: 'path',
172
- required: true,
173
- schema: { type: 'string' },
174
- }))
175
- }
176
-
177
- if (query) {
178
- operation.parameters.push(
179
- ...query.map((query) => ({
180
- name: query,
181
- in: 'query',
182
- required: false,
183
- schema: { type: 'string' },
184
- }))
185
- )
186
- }
187
-
188
- paths[path][method] = operation
189
- })
190
-
191
- return {
192
- openapi: '3.1.0',
193
- info: additionalInfo.info,
194
- servers: additionalInfo.servers,
195
- paths,
196
- components: {
197
- schemas: await convertSchemasToBodyPayloads(routeMeta, schemas),
198
- responses: {},
199
- parameters: {},
200
- examples: {},
201
- requestBodies: {},
202
- headers: {},
203
- securitySchemes: additionalInfo.securitySchemes || {
204
- ApiKeyAuth: {
205
- type: 'apiKey',
206
- in: 'header',
207
- name: 'x-api-key',
208
- },
209
- BearerAuth: {
210
- type: 'http',
211
- scheme: 'bearer',
212
- },
213
- },
214
- },
215
- security: additionalInfo.security || [
216
- {
217
- ApiKeyAuth: [],
218
- },
219
- {
220
- BearerAuth: [],
221
- },
222
- ],
223
- tags: additionalInfo.tags,
224
- externalDocs: additionalInfo.externalDocs,
225
- // definitions
226
- }
227
- }
@@ -1,204 +0,0 @@
1
- import { join, dirname, resolve, isAbsolute } from 'path'
2
- import { readdir, readFile } from 'fs/promises'
3
- import { OpenAPISpecInfo } from './openapi/openapi-spec-generator.js'
4
- import { InspectorFilters } from '@pikku/inspector'
5
-
6
- export interface PikkuCLICoreOutputFiles {
7
- outDir?: string
8
- routesFile: string
9
- channelsFile: string
10
- schedulersFile: string
11
- schemaDirectory: string
12
- typesDeclarationFile: string
13
- routesMapDeclarationFile: string
14
- channelsMapDeclarationFile: string
15
- bootstrapFile: string
16
- }
17
-
18
- export type PikkuCLIConfig = {
19
- $schema?: string
20
-
21
- extends?: string
22
-
23
- rootDir: string
24
- routeDirectories: string[]
25
- packageMappings: Record<string, string>
26
- supportsImportAttributes: boolean
27
-
28
- configDir: string
29
- tsconfig: string
30
-
31
- nextBackendFile?: string
32
- nextHTTPFile?: string
33
- fetchFile?: string
34
- websocketFile?: string
35
-
36
- openAPI?: {
37
- outputFile: string
38
- additionalInfo: OpenAPISpecInfo
39
- }
40
-
41
- filters: InspectorFilters
42
- } & PikkuCLICoreOutputFiles
43
-
44
- const CONFIG_DIR_FILES = [
45
- 'nextBackendFile',
46
- 'nextHTTPFile',
47
- 'fetchFile',
48
- 'websocketFile',
49
- ]
50
-
51
- export const getPikkuCLIConfig = async (
52
- configFile: string | undefined = undefined,
53
- requiredFields: Array<keyof PikkuCLIConfig>,
54
- tags: string[] = [],
55
- exitProcess: boolean = false
56
- ): Promise<PikkuCLIConfig> => {
57
- const config = await _getPikkuCLIConfig(
58
- configFile,
59
- requiredFields,
60
- tags,
61
- exitProcess
62
- )
63
- return config
64
- }
65
-
66
- const _getPikkuCLIConfig = async (
67
- configFile: string | undefined = undefined,
68
- requiredFields: Array<keyof PikkuCLIConfig>,
69
- tags: string[] = [],
70
- exitProcess: boolean = false
71
- ): Promise<PikkuCLIConfig> => {
72
- if (!configFile) {
73
- let execDirectory = process.cwd()
74
- const files = await readdir(execDirectory)
75
- const file = files.find((file) => /pikku\.config\.(ts|js|json)$/.test(file))
76
- if (!file) {
77
- const errorMessage =
78
- '\nConfig file pikku.config.json not found\nExiting...'
79
- if (exitProcess) {
80
- console.error(errorMessage)
81
- process.exit(1)
82
- }
83
- throw new Error(errorMessage)
84
- }
85
- configFile = join(execDirectory, file)
86
- }
87
-
88
- try {
89
- let result: PikkuCLIConfig
90
- const file = await readFile(configFile, 'utf-8')
91
- const configDir = dirname(configFile)
92
- const config: PikkuCLIConfig = JSON.parse(file)
93
- if (config.extends) {
94
- const extendedConfig = await getPikkuCLIConfig(
95
- resolve(configDir, config.extends),
96
- [],
97
- tags,
98
- exitProcess
99
- )
100
- result = {
101
- ...extendedConfig,
102
- ...config,
103
- configDir,
104
- packageMappings: {
105
- ...extendedConfig.packageMappings,
106
- ...config.packageMappings,
107
- },
108
- }
109
- } else {
110
- result = {
111
- ...config,
112
- configDir,
113
- packageMappings: config.packageMappings || {},
114
- rootDir: config.rootDir
115
- ? resolve(configDir, config.rootDir)
116
- : configDir,
117
- }
118
- }
119
-
120
- if (result.outDir) {
121
- if (!result.schemaDirectory) {
122
- result.schemaDirectory = join(result.outDir, 'pikku-schemas')
123
- }
124
- if (!result.routesFile) {
125
- result.routesFile = join(result.outDir, 'pikku-routes.gen.ts')
126
- }
127
- if (!result.schedulersFile) {
128
- result.schedulersFile = join(result.outDir, 'pikku-schedules.gen.ts')
129
- }
130
- if (!result.channelsFile) {
131
- result.channelsFile = join(result.outDir, 'pikku-channels.gen.ts')
132
- }
133
- if (!result.typesDeclarationFile) {
134
- result.typesDeclarationFile = join(result.outDir, 'pikku-types.gen.ts')
135
- }
136
- if (!result.routesMapDeclarationFile) {
137
- result.routesMapDeclarationFile = join(
138
- result.outDir,
139
- 'pikku-routes-map.gen.d.ts'
140
- )
141
- }
142
- if (!result.channelsMapDeclarationFile) {
143
- result.channelsMapDeclarationFile = join(
144
- result.outDir,
145
- 'pikku-channels-map.gen.d.ts'
146
- )
147
- }
148
- if (!result.bootstrapFile) {
149
- result.bootstrapFile = join(result.outDir, 'pikku-bootstrap.gen.ts')
150
- }
151
- }
152
-
153
- if (requiredFields.length > 0) {
154
- validateCLIConfig(result, requiredFields)
155
- }
156
-
157
- for (const objectKey of Object.keys(result)) {
158
- if (objectKey.endsWith('File') || objectKey.endsWith('Directory')) {
159
- const relativeTo = CONFIG_DIR_FILES.includes(objectKey)
160
- ? result.configDir
161
- : result.rootDir
162
- if (result[objectKey]) {
163
- if (!isAbsolute(result[objectKey])) {
164
- result[objectKey] = join(relativeTo, result[objectKey])
165
- }
166
- }
167
- }
168
- }
169
-
170
- result.filters = result.filters || {}
171
- if (tags.length > 0) {
172
- result.filters.tags = tags
173
- }
174
-
175
- if (!isAbsolute(result.tsconfig)) {
176
- result.tsconfig = join(result.rootDir, result.tsconfig)
177
- }
178
-
179
- return result
180
- } catch (e: any) {
181
- console.error(e)
182
- console.error(`Config file not found: ${configFile}`)
183
- process.exit(1)
184
- }
185
- }
186
-
187
- export const validateCLIConfig = (
188
- cliConfig: PikkuCLIConfig,
189
- required: Array<keyof PikkuCLIConfig>
190
- ) => {
191
- let errors: string[] = []
192
- for (const key of required) {
193
- if (!cliConfig[key]) {
194
- errors.push(key)
195
- }
196
- }
197
-
198
- if (errors.length > 0) {
199
- console.error(
200
- `${errors.join(', ')} ${errors.length === 1 ? 'is' : 'are'} required in pikku.config.json`
201
- )
202
- process.exit(1)
203
- }
204
- }
@@ -1,41 +0,0 @@
1
- import { ScheduledTasksMeta } from '@pikku/core/scheduler'
2
- import { getFileImportRelativePath } from '../utils.js'
3
-
4
- export const serializeSchedulers = (
5
- outputPath: string,
6
- filesWithScheduledTasks: Set<string>,
7
- packageMappings: Record<string, string> = {}
8
- ) => {
9
- const serializedOutput: string[] = [
10
- '/* The files with an addSerializedTasks function call */',
11
- ]
12
-
13
- Array.from(filesWithScheduledTasks)
14
- .sort()
15
- .forEach((path) => {
16
- const filePath = getFileImportRelativePath(
17
- outputPath,
18
- path,
19
- packageMappings
20
- )
21
- serializedOutput.push(`import '${filePath}'`)
22
- })
23
-
24
- return serializedOutput.join('\n')
25
- }
26
-
27
- export const serializeSchedulerMeta = (
28
- scheduledTasksMeta: ScheduledTasksMeta
29
- ) => {
30
- const serializedOutput: string[] = []
31
- serializedOutput.push("import { pikkuState } from '@pikku/core'")
32
- serializedOutput.push(
33
- `pikkuState('scheduler', 'meta', ${JSON.stringify(scheduledTasksMeta, null, 2)})`
34
- )
35
- if (scheduledTasksMeta.length > 0) {
36
- serializedOutput.push(
37
- `export type ScheduledTaskNames = '${scheduledTasksMeta.map((s) => s.name).join("' | '")}'`
38
- )
39
- }
40
- return serializedOutput.join('\n')
41
- }
@@ -1,114 +0,0 @@
1
- import { createGenerator, RootlessError } from 'ts-json-schema-generator'
2
- import { logInfo, writeFileInDir } from '../utils.js'
3
- import { mkdir, writeFile } from 'fs/promises'
4
- import { JSONValue } from '@pikku/core'
5
- import { HTTPRoutesMeta } from '@pikku/core/http'
6
- import { TypesMap } from '@pikku/inspector'
7
-
8
- export async function generateSchemas(
9
- tsconfig: string,
10
- typesMap: TypesMap,
11
- routesMeta: HTTPRoutesMeta
12
- ): Promise<Record<string, JSONValue>> {
13
- const schemasSet = new Set(typesMap.customTypes.keys())
14
- for (const { input, output, inputTypes } of routesMeta) {
15
- if (input) {
16
- schemasSet.add(typesMap.getTypeMeta(input).uniqueName)
17
- }
18
- if (output) {
19
- schemasSet.add(typesMap.getTypeMeta(output).uniqueName)
20
- }
21
- if (inputTypes?.body) {
22
- schemasSet.add(inputTypes.body)
23
- }
24
- if (inputTypes?.query) {
25
- schemasSet.add(inputTypes.query)
26
- }
27
- if (inputTypes?.params) {
28
- schemasSet.add(inputTypes.params)
29
- }
30
- }
31
-
32
- const generator = createGenerator({
33
- tsconfig,
34
- skipTypeCheck: true,
35
- topRef: false,
36
- discriminatorType: 'open-api',
37
- })
38
- const schemas: Record<string, JSONValue> = {}
39
- schemasSet.forEach((schema) => {
40
- try {
41
- schemas[schema] = generator.createSchema(schema) as JSONValue
42
- } catch (e) {
43
- // Ignore rootless errors
44
- if (e instanceof RootlessError) {
45
- console.error('Error generating schema since it has no root:', schema)
46
- return
47
- }
48
- throw e
49
- }
50
- })
51
-
52
- return schemas
53
- }
54
-
55
- export async function saveSchemas(
56
- schemaParentDir: string,
57
- schemas: Record<string, JSONValue>,
58
- typesMap: TypesMap,
59
- routesMeta: HTTPRoutesMeta,
60
- supportsImportAttributes: boolean
61
- ) {
62
- await writeFileInDir(
63
- `${schemaParentDir}/register.gen.ts`,
64
- 'export const empty = null;'
65
- )
66
-
67
- const desiredSchemas = new Set([
68
- ...routesMeta
69
- .map(({ input, output }) => [
70
- input ? typesMap.getUniqueName(input) : undefined,
71
- output ? typesMap.getUniqueName(output) : undefined,
72
- ])
73
- .flat()
74
- .filter(
75
- (s) =>
76
- !!s &&
77
- !['boolean', 'string', 'number', 'null', 'undefined'].includes(s)
78
- ),
79
- ...typesMap.customTypes.keys(),
80
- ])
81
-
82
- if (desiredSchemas.size === 0) {
83
- logInfo(`• Skipping schemas since none found.\x1b[0m`)
84
- return
85
- }
86
-
87
- await mkdir(`${schemaParentDir}/schemas`, { recursive: true })
88
- await Promise.all(
89
- Object.entries(schemas).map(async ([schemaName, schema]) => {
90
- if (desiredSchemas.has(schemaName)) {
91
- await writeFile(
92
- `${schemaParentDir}/schemas/${schemaName}.schema.json`,
93
- JSON.stringify(schema),
94
- 'utf-8'
95
- )
96
- }
97
- })
98
- )
99
-
100
- const schemaImports = Array.from(desiredSchemas)
101
- .map(
102
- (schema) => `
103
- import * as ${schema} from './schemas/${schema}.schema.json' ${supportsImportAttributes ? `with { type: 'json' }` : ''}
104
- addSchema('${schema}', ${schema})
105
- `
106
- )
107
- .join('\n')
108
-
109
- await writeFileInDir(
110
- `${schemaParentDir}/register.gen.ts`,
111
- `import { addSchema } from '@pikku/core/schema'
112
- ${schemaImports}`
113
- )
114
- }