@pikku/cli 0.6.19 → 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 +12 -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 -7
  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 -53
  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,58 +0,0 @@
1
- import { Command } from 'commander'
2
- import {
3
- getFileImportRelativePath,
4
- logCommandInfoAndTime,
5
- logPikkuLogo,
6
- PikkuCLIOptions,
7
- writeFileInDir,
8
- } from '../src/utils.js'
9
- import { getPikkuCLIConfig, PikkuCLIConfig } from '../src/pikku-cli-config.js'
10
- import { serializeWebsocketWrapper } from '../src/channels/serialize-websocket-wrapper.js'
11
-
12
- export const pikkuWebSocket = async ({
13
- websocketFile,
14
- channelsMapDeclarationFile,
15
- packageMappings,
16
- }: PikkuCLIConfig) => {
17
- await logCommandInfoAndTime(
18
- 'Generating websocket wrapper',
19
- 'Generated websocket wrapper',
20
- [
21
- websocketFile === undefined,
22
- "websocketFile isn't set in the pikku config",
23
- ],
24
- async () => {
25
- if (!websocketFile) {
26
- throw new Error("fetchFile is isn't set in the pikku config")
27
- }
28
-
29
- const channelsMapDeclarationPath = getFileImportRelativePath(
30
- websocketFile,
31
- channelsMapDeclarationFile,
32
- packageMappings
33
- )
34
-
35
- const content = [serializeWebsocketWrapper(channelsMapDeclarationPath)]
36
- await writeFileInDir(websocketFile, content.join('\n'))
37
- }
38
- )
39
- }
40
-
41
- export const action = async (options: PikkuCLIOptions): Promise<void> => {
42
- logPikkuLogo()
43
- const cliConfig = await getPikkuCLIConfig(
44
- options.config,
45
- ['rootDir', 'schemaDirectory', 'configDir', 'fetchFile'],
46
- options.tags,
47
- true
48
- )
49
- await pikkuWebSocket(cliConfig)
50
- }
51
-
52
- export const websocket = (program: Command): void => {
53
- program
54
- .command('websocket')
55
- .description('generate websocket wrapper')
56
- .option('-c | --config <string>', 'The path to pikku cli config file')
57
- .action(action)
58
- }
package/bin/pikku.ts DELETED
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from 'commander'
3
- import { schemas } from './pikku-schemas.js'
4
- import { routes } from './pikku-http.js'
5
- import { nextjs } from './pikku-nextjs.js'
6
- import { all } from './pikku-all.js'
7
- import { functionTypes } from './pikku-function-types.js'
8
- import { routesMap } from './pikku-routes-map.js'
9
- import { fetch } from './pikku-fetch.js'
10
- import { channels } from './pikku-channels.js'
11
- import { schedules } from './pikku-scheduler.js'
12
-
13
- const program = new Command('pikku')
14
- program.usage('[command]')
15
-
16
- all(program)
17
- routes(program)
18
- routesMap(program)
19
- functionTypes(program)
20
- schemas(program)
21
- nextjs(program)
22
- fetch(program)
23
- channels(program)
24
- schedules(program)
25
-
26
- program.parse(process.argv)
@@ -1 +0,0 @@
1
- {"root":["../bin/pikku-all.ts","../bin/pikku-channels-map.ts","../bin/pikku-channels.ts","../bin/pikku-fetch.ts","../bin/pikku-function-types.ts","../bin/pikku-http.ts","../bin/pikku-nextjs.ts","../bin/pikku-openapi.ts","../bin/pikku-routes-map.ts","../bin/pikku-scheduler.ts","../bin/pikku-schemas.ts","../bin/pikku-websocket.ts","../bin/pikku.ts","../src/inspector-glob.ts","../src/pikku-cli-config.ts","../src/utils.ts","../src/channels/serialize-channels.ts","../src/channels/serialize-typed-channel-map.ts","../src/channels/serialize-websocket-wrapper.ts","../src/core/serialize-import-map.ts","../src/core/serialize-pikku-types.ts","../src/http/serialize-fetch-wrapper.ts","../src/http/serialize-route-imports.ts","../src/http/serialize-route-meta.ts","../src/http/serialize-typed-route-map.ts","../src/nextjs/serialize-nextjs-backend-wrapper.ts","../src/nextjs/serialize-nextjs-http-wrapper.ts","../src/openapi/openapi-spec-generator.ts","../src/scheduler/serialize-schedulers.ts","../src/schema/schema-generator.ts"],"version":"5.7.3"}
@@ -1,34 +0,0 @@
1
- import { ChannelsMeta } from '@pikku/core/channel'
2
- import { getFileImportRelativePath } from '../utils.js'
3
-
4
- export const serializeChannels = (
5
- outputPath: string,
6
- filesWithChannels: Set<string>,
7
- packageMappings: Record<string, string> = {}
8
- ) => {
9
- const serializedOutput: string[] = [
10
- '/* The files with an addChannel function call */',
11
- ]
12
-
13
- Array.from(filesWithChannels)
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 serializeChannelMeta = (channelsMeta: ChannelsMeta) => {
28
- const serializedOutput: string[] = []
29
- serializedOutput.push("import { pikkuState } from '@pikku/core'")
30
- serializedOutput.push(
31
- `pikkuState('channel', 'meta', ${JSON.stringify(channelsMeta, null, 2)})`
32
- )
33
- return serializedOutput.join('\n')
34
- }
@@ -1,136 +0,0 @@
1
- import { ChannelsMeta } from '@pikku/core/channel'
2
- import { serializeImportMap } from '../core/serialize-import-map.js'
3
- import { TypesMap } from '@pikku/inspector'
4
- import { generateCustomTypes } from '../http/serialize-typed-route-map.js'
5
-
6
- export const serializeTypedChannelsMap = (
7
- relativeToPath: string,
8
- packageMappings: Record<string, string>,
9
- typesMap: TypesMap,
10
- channelsMeta: ChannelsMeta
11
- ): string => {
12
- const { channels, requiredTypes } = generateChannels(channelsMeta)
13
- typesMap.customTypes.forEach(({ references }) => {
14
- for (const reference of references) {
15
- requiredTypes.add(reference)
16
- }
17
- })
18
- const imports = serializeImportMap(
19
- relativeToPath,
20
- packageMappings,
21
- typesMap,
22
- requiredTypes
23
- )
24
- const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes)
25
- return `/**
26
- * This provides the structure needed for TypeScript to be aware of channels
27
- */
28
-
29
- ${imports}
30
- ${serializedCustomTypes}
31
-
32
- interface ChannelHandler<I, O> {
33
- input: I;
34
- output: O;
35
- }
36
-
37
- ${channels}
38
-
39
- export type ChannelDefaultHandlerOf<Channel extends keyof ChannelsMap> =
40
- ChannelsMap[Channel]['defaultMessage'] extends { input: infer I; output: infer O }
41
- ? ChannelHandler<I, O>
42
- : never;
43
-
44
- export type ChannelRouteHandlerOf<
45
- Channel extends keyof ChannelsMap,
46
- Route extends keyof ChannelsMap[Channel]['routes'],
47
- Method extends keyof ChannelsMap[Channel]['routes'][Route],
48
- > =
49
- ChannelsMap[Channel]['routes'][Route][Method] extends { input: infer I; output: infer O }
50
- ? ChannelHandler<I, O>
51
- : never;
52
- `
53
- }
54
-
55
- function generateChannels(channelsMeta: ChannelsMeta) {
56
- const requiredTypes = new Set<string>()
57
- const channelsObject: Record<
58
- string,
59
- {
60
- message: { inputs: string[] | null; outputs: string[] | null } | null
61
- routes: Record<
62
- string,
63
- Record<
64
- string,
65
- {
66
- inputTypes: string[] | null
67
- outputTypes: string[] | null
68
- }
69
- >
70
- >
71
- }
72
- > = {}
73
-
74
- for (const meta of channelsMeta) {
75
- const { name, messageRoutes, message } = meta
76
-
77
- if (!channelsObject[name]) {
78
- channelsObject[name] = { message, routes: {} }
79
- }
80
-
81
- for (const [key, route] of Object.entries(messageRoutes)) {
82
- if (!channelsObject[name].routes[key]) {
83
- channelsObject[name].routes[key] = {}
84
- }
85
- for (const [method, { inputs, outputs }] of Object.entries(route)) {
86
- const inputTypes = inputs || null
87
- const outputTypes = outputs || null
88
- channelsObject[name].routes[key][method] = {
89
- inputTypes,
90
- outputTypes,
91
- }
92
- inputTypes?.forEach((type) => requiredTypes.add(type))
93
- outputTypes?.forEach((type) => requiredTypes.add(type))
94
- }
95
- }
96
- }
97
-
98
- let routesStr = 'export type ChannelsMap = {\n'
99
-
100
- for (const [channelPath, { routes, message }] of Object.entries(
101
- channelsObject
102
- )) {
103
- routesStr += ` readonly '${channelPath}': {\n`
104
-
105
- // Add `routes` object
106
- routesStr += ` readonly routes: {\n`
107
- for (const [key, methods] of Object.entries(routes)) {
108
- routesStr += ` readonly ${key}: {\n`
109
- for (const [method, handler] of Object.entries(methods)) {
110
- routesStr += ` readonly ${method}: ChannelHandler<${formatTypeArray(
111
- handler.inputTypes
112
- )}, ${formatTypeArray(handler.outputTypes) || 'never'}>,\n`
113
- }
114
- routesStr += ' },\n'
115
- }
116
- routesStr += ' },\n'
117
-
118
- // Add `defaultMessage` outside `routes`
119
- if (message) {
120
- routesStr += ` readonly defaultMessage: ChannelHandler<${formatTypeArray(
121
- message.inputs
122
- )}, ${formatTypeArray(message.outputs)}>,\n`
123
- }
124
-
125
- routesStr += ' },\n'
126
- }
127
-
128
- routesStr += '};'
129
-
130
- return { channels: routesStr, requiredTypes }
131
- }
132
-
133
- // Utility to format type arrays
134
- function formatTypeArray(types: string[] | null): string {
135
- return types ? types.join(' | ') : 'null'
136
- }
@@ -1,33 +0,0 @@
1
- import { TypesMap } from '@pikku/inspector'
2
- import { getFileImportRelativePath } from '../utils.js'
3
-
4
- export const serializeImportMap = (
5
- relativeToPath: string,
6
- packageMappings: Record<string, string>,
7
- typesMap: TypesMap,
8
- requiredTypes: Set<string>
9
- ) => {
10
- const paths = new Map<string, string[]>()
11
- Array.from(requiredTypes).forEach((requiredType) => {
12
- const { originalName, uniqueName, path } =
13
- typesMap.getTypeMeta(requiredType)
14
- if (!path) {
15
- return
16
- }
17
- const variables = paths.get(path) || []
18
- if (originalName === uniqueName) {
19
- variables.push(originalName)
20
- } else {
21
- variables.push(`${originalName} as ${uniqueName}`)
22
- }
23
- paths.set(path, variables)
24
- })
25
-
26
- const imports: string[] = []
27
- for (const [path, variables] of paths.entries()) {
28
- imports.push(
29
- `import type { ${variables.join(', ')} } from '${getFileImportRelativePath(relativeToPath, path, packageMappings)}'`
30
- )
31
- }
32
- return imports.join('\n')
33
- }
@@ -1,55 +0,0 @@
1
- /**
2
- *
3
- */
4
- export const serializePikkuTypes = (
5
- userSessionTypeImport: string,
6
- userSessionTypeName: string,
7
- singletonServicesTypeImport: string,
8
- singletonServicesTypeName: string,
9
- sessionServicesTypeImport: string,
10
- servicesTypeName: string
11
- ) => {
12
- return `/**
13
- * This is used to provide the application types in the typescript project
14
- */
15
-
16
- import { CoreAPIFunction, CoreAPIFunctionSessionless, CoreAPIPermission, PikkuMiddleware, MakeRequired } from '@pikku/core'
17
- import { CoreHTTPFunctionRoute, AssertRouteParams, addRoute as addCoreHTTP } from '@pikku/core/http'
18
- import { CoreScheduledTask, addScheduledTask as addCoreScheduledTask } from '@pikku/core/scheduler'
19
- import { CoreAPIChannel, PikkuChannel, addChannel as addCoreChannel } from '@pikku/core/channel'
20
-
21
- ${userSessionTypeImport}
22
- ${singletonServicesTypeImport}
23
- ${sessionServicesTypeImport}
24
-
25
- export type APIPermission<In = unknown, RequiredServices extends ${singletonServicesTypeName} = ${singletonServicesTypeName}> = CoreAPIPermission<In, RequiredServices, ${userSessionTypeName}>
26
- export type APIMiddleware<RequiredServices extends ${singletonServicesTypeName} = ${singletonServicesTypeName}> = PikkuMiddleware<RequiredServices, ${userSessionTypeName}>
27
-
28
- export type APIFunctionSessionless<In = unknown, Out = never, RequiredServices extends ${servicesTypeName} = ${servicesTypeName}> = CoreAPIFunctionSessionless<In, Out, RequiredServices, ${userSessionTypeName}>
29
- export type APIFunction<In = unknown, Out = never, RequiredServices extends ${servicesTypeName} = ${servicesTypeName}> = CoreAPIFunction<In, Out, RequiredServices, ${userSessionTypeName}>
30
- type APIRoute<In, Out, Route extends string> = CoreHTTPFunctionRoute<In, Out, Route, APIFunction<In, Out>, APIFunctionSessionless<In, Out>, APIPermission<In>, APIMiddleware>
31
-
32
- export type ChannelConnection<Out = unknown, ChannelData = unknown, RequiredServices extends ${servicesTypeName} = ${servicesTypeName}> = (services: MakeRequired<RequiredServices, 'userSession'>, channel: PikkuChannel<ChannelData, Out>) => Promise<void>
33
- export type ChannelDisconnection<ChannelData = unknown, RequiredServices extends ${servicesTypeName} = ${servicesTypeName}> = (services: MakeRequired<RequiredServices, 'userSession'>, channel: PikkuChannel<ChannelData, never>) => Promise<void>
34
- export type ChannelMessage<In, Out = unknown, ChannelData = unknown, RequiredServices extends ${servicesTypeName} = ${servicesTypeName}> = (services: MakeRequired<RequiredServices, 'userSession'>, channel: PikkuChannel<ChannelData, Out>, data: In) => Promise<Out | void>
35
- type APIChannel<ChannelData, Channel extends string> = CoreAPIChannel<ChannelData, Channel, ChannelConnection, ChannelDisconnection, ChannelMessage<any, any, ChannelData>, ChannelMessage<any, any, ChannelData>, APIPermission>
36
-
37
- type ScheduledTask = CoreScheduledTask<APIFunctionSessionless<void, void>, ${userSessionTypeName}>
38
-
39
- export const addChannel = <ChannelData, Channel extends string>(
40
- channel: APIChannel<ChannelData, Channel> & AssertRouteParams<ChannelData, Channel>
41
- ) => {
42
- addCoreChannel(channel as any) // TODO
43
- }
44
-
45
- export const addRoute = <In, Out, Route extends string>(
46
- route: APIRoute<In, Out, Route> & AssertRouteParams<In, Route>
47
- ) => {
48
- addCoreHTTP(route)
49
- }
50
-
51
- export const addScheduledTask = (task: ScheduledTask) => {
52
- addCoreScheduledTask(task as any) // TODO
53
- }
54
- `
55
- }
@@ -1,24 +0,0 @@
1
- import { getFileImportRelativePath } from '../utils.js'
2
-
3
- export const serializeRoutes = (
4
- outputPath: string,
5
- filesWithRoutes: Set<string>,
6
- packageMappings: Record<string, string> = {}
7
- ) => {
8
- const serializedOutput: string[] = [
9
- '/* The files with an addRoute function call */',
10
- ]
11
-
12
- Array.from(filesWithRoutes)
13
- .sort()
14
- .forEach((path) => {
15
- const filePath = getFileImportRelativePath(
16
- outputPath,
17
- path,
18
- packageMappings
19
- )
20
- serializedOutput.push(`import '${filePath}'`)
21
- })
22
-
23
- return serializedOutput.join('\n')
24
- }
@@ -1,10 +0,0 @@
1
- import type { HTTPRoutesMeta } from '@pikku/core/http'
2
-
3
- export const serializeHTTPRoutesMeta = (routesMeta: HTTPRoutesMeta) => {
4
- const serializedOutput: string[] = []
5
- serializedOutput.push("import { pikkuState } from '@pikku/core'")
6
- serializedOutput.push(
7
- `pikkuState('http', 'meta', ${JSON.stringify(routesMeta, null, 2)})`
8
- )
9
- return serializedOutput.join('\n')
10
- }
@@ -1,150 +0,0 @@
1
- import { HTTPRoutesMeta } from '@pikku/core/http'
2
- import { serializeImportMap } from '../core/serialize-import-map.js'
3
- import { MetaInputTypes, TypesMap } from '@pikku/inspector'
4
-
5
- export const serializeTypedRoutesMap = (
6
- relativeToPath: string,
7
- packageMappings: Record<string, string>,
8
- typesMap: TypesMap,
9
- routesMeta: HTTPRoutesMeta,
10
- metaTypes: MetaInputTypes
11
- ) => {
12
- const requiredTypes = new Set<string>()
13
- const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes)
14
- const serializedMetaTypes = generateMetaTypes(metaTypes, typesMap)
15
- const serializedImportMap = serializeImportMap(
16
- relativeToPath,
17
- packageMappings,
18
- typesMap,
19
- requiredTypes
20
- )
21
- const serializedRoutes = generateRoutes(routesMeta, typesMap, requiredTypes)
22
-
23
- return `/**
24
- * This provides the structure needed for typescript to be aware of routes and their return types
25
- */
26
-
27
- ${serializedImportMap}
28
- ${serializedCustomTypes}
29
- ${serializedMetaTypes}
30
-
31
- interface RouteHandler<I, O> {
32
- input: I;
33
- output: O;
34
- }
35
-
36
- ${serializedRoutes}
37
-
38
- export type RouteHandlerOf<Route extends keyof RoutesMap, Method extends keyof RoutesMap[Route]> =
39
- RoutesMap[Route][Method] extends { input: infer I; output: infer O }
40
- ? RouteHandler<I, O>
41
- : never;
42
-
43
- export type RoutesWithMethod<Method extends string> = {
44
- [Route in keyof RoutesMap]: Method extends keyof RoutesMap[Route] ? Route : never;
45
- }[keyof RoutesMap];
46
- `
47
- }
48
-
49
- export function generateCustomTypes(
50
- typesMap: TypesMap,
51
- requiredTypes: Set<string>
52
- ) {
53
- return `
54
- // Custom types are those that are defined directly within generics
55
- // or are broken into simpler types
56
- ${Array.from(typesMap.customTypes.entries())
57
- .map(([name, { type, references }]) => {
58
- references.forEach((name) => {
59
- const originalName = typesMap.getTypeMeta(name).originalName
60
- requiredTypes.add(originalName)
61
- })
62
- return `export type ${name} = ${type}`
63
- })
64
- .join('\n')}`
65
- }
66
-
67
- function generateRoutes(
68
- routesMeta: HTTPRoutesMeta,
69
- typesMap: TypesMap,
70
- requiredTypes: Set<string>
71
- ) {
72
- // Initialize an object to collect routes
73
- const routesObj: Record<
74
- string,
75
- Record<string, { inputType: string; outputType: string }>
76
- > = {}
77
-
78
- for (const meta of routesMeta) {
79
- const { route, method, input, output } = meta
80
-
81
- // Initialize the route entry if it doesn't exist
82
- if (!routesObj[route]) {
83
- routesObj[route] = {}
84
- }
85
-
86
- // Store the input and output types separately for RouteHandler
87
- const inputType = input ? typesMap.getTypeMeta(input).uniqueName : 'null'
88
- const outputType = output ? typesMap.getTypeMeta(output).uniqueName : 'null'
89
-
90
- requiredTypes.add(inputType)
91
- requiredTypes.add(outputType)
92
-
93
- // Add method entry
94
- routesObj[route][method] = {
95
- inputType,
96
- outputType,
97
- }
98
- }
99
-
100
- // Build the routes object as a string
101
- let routesStr = 'export type RoutesMap = {\n'
102
-
103
- for (const [routePath, methods] of Object.entries(routesObj)) {
104
- routesStr += ` readonly '${routePath}': {\n`
105
- for (const [method, handler] of Object.entries(methods)) {
106
- routesStr += ` readonly ${method.toUpperCase()}: RouteHandler<${handler.inputType}, ${handler.outputType}>,\n`
107
- }
108
- routesStr += ' },\n'
109
- }
110
-
111
- routesStr += '};'
112
-
113
- return routesStr
114
- }
115
-
116
- const generateMetaTypes = (metaTypes: MetaInputTypes, typesMap: TypesMap) => {
117
- const nameToTypeMap = Array.from(metaTypes.entries()).reduce<
118
- Map<string, string>
119
- >((result, [_name, { query, body, params }]) => {
120
- const { uniqueName } = typesMap.getTypeMeta(_name)
121
- const queryType =
122
- query && query.length > 0
123
- ? `Pick<${uniqueName}, '${query?.join("' | '")}'>`
124
- : undefined
125
- if (queryType) {
126
- result.set(`${uniqueName}Query`, queryType)
127
- }
128
- const paramsType =
129
- params && params.length > 0
130
- ? `Pick<${uniqueName}, '${params.join("' | '")}'>`
131
- : undefined
132
- if (paramsType) {
133
- result.set(`${uniqueName}Params`, paramsType)
134
- }
135
- const bodyType =
136
- (body && body.length > 0) || (params && params.length > 0)
137
- ? `Omit<${uniqueName}, '${[...new Set([...(query || []), ...(params || [])])].join("' | '")}'>`
138
- : uniqueName!
139
- if (bodyType) {
140
- result.set(`${uniqueName}Body`, bodyType)
141
- }
142
- return result
143
- }, new Map())
144
-
145
- return `
146
- // The '& {}' is a workaround for not directly refering to a type since it confuses typescript
147
- ${Array.from(nameToTypeMap.entries())
148
- .map(([name, type]) => `export type ${name} = ${type} & {}`)
149
- .join('\n')}`
150
- }
@@ -1,28 +0,0 @@
1
- import * as path from 'path'
2
- import { glob } from 'tinyglobby'
3
- import { InspectorFilters, InspectorState, inspect } from '@pikku/inspector'
4
- import { logCommandInfoAndTime } from './utils.js'
5
-
6
- export const inspectorGlob = async (
7
- rootDir: string,
8
- routeDirectories: string[],
9
- filters: InspectorFilters
10
- ) => {
11
- let result: InspectorState
12
- await logCommandInfoAndTime(
13
- 'Inspecting codebase',
14
- 'Inspected codebase',
15
- [false],
16
- async () => {
17
- const routeFiles = (
18
- await Promise.all(
19
- routeDirectories.map((dir) =>
20
- glob(`${path.join(rootDir, dir)}/**/*.ts`)
21
- )
22
- )
23
- ).flat()
24
- result = await inspect(routeFiles, filters)
25
- }
26
- )
27
- return result!
28
- }