@pikku/cli 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pikku/channel/pikku-channel-types.gen.ts +4 -3
- package/.pikku/channel/pikku-channels-map.gen.d.ts +2 -2
- package/.pikku/channel/pikku-channels-meta.gen.ts +1 -1
- package/.pikku/channel/pikku-channels.gen.ts +1 -1
- package/.pikku/cli/pikku-cli-types.gen.ts +23 -1
- package/.pikku/cli/pikku-cli-wirings-meta.gen.ts +4 -115
- package/.pikku/cli/pikku-cli-wirings.gen.ts +2 -3
- package/.pikku/function/pikku-function-types.gen.ts +1 -1
- package/.pikku/function/pikku-functions-meta.gen.ts +156 -138
- package/.pikku/function/pikku-functions-meta.min.gen.ts +37 -32
- package/.pikku/function/pikku-functions.gen.ts +1 -1
- package/.pikku/http/pikku-http-types.gen.ts +1 -1
- package/.pikku/http/pikku-http-wirings-map.gen.d.ts +2 -2
- package/.pikku/http/pikku-http-wirings-meta.gen.ts +1 -1
- package/.pikku/http/pikku-http-wirings.gen.ts +1 -1
- package/.pikku/mcp/pikku-mcp-types.gen.ts +1 -1
- package/.pikku/mcp/pikku-mcp-wirings-meta.gen.ts +1 -1
- package/.pikku/mcp/pikku-mcp-wirings.gen.ts +1 -1
- package/.pikku/pikku-bootstrap.gen.ts +1 -1
- package/.pikku/pikku-services.gen.ts +16 -12
- package/.pikku/pikku-types.gen.ts +1 -1
- package/.pikku/pikku-websocket.gen.ts +15 -1
- package/.pikku/queue/pikku-queue-types.gen.ts +1 -1
- package/.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts +2 -2
- package/.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts +1 -1
- package/.pikku/queue/pikku-queue-workers-wirings.gen.ts +1 -1
- package/.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts +2 -2
- package/.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +10 -9
- package/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts +9 -8
- package/.pikku/scheduler/pikku-scheduler-types.gen.ts +1 -1
- package/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.ts +1 -1
- package/.pikku/scheduler/pikku-schedulers-wirings.gen.ts +1 -1
- package/.pikku/schemas/register.gen.ts +5 -5
- package/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
- package/CHANGELOG.md +58 -0
- package/bin/pikku.ts +30 -21
- package/cli.schema.json +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +4 -3
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/channel/pikku-channels-meta.gen.js +1 -1
- package/dist/.pikku/channel/pikku-channels.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channels.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +18 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +20 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +4 -115
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -2
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -2
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +156 -138
- package/dist/.pikku/function/pikku-functions-meta.min.gen.js +37 -32
- package/dist/.pikku/function/pikku-functions.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +9 -6
- package/dist/.pikku/pikku-services.gen.js +8 -2
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/pikku-websocket.gen.d.ts +15 -1
- package/dist/.pikku/pikku-websocket.gen.js +15 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +9 -8
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +3 -3
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
- package/dist/bin/pikku.js +24 -19
- package/dist/src/cli.wiring.js +107 -99
- package/dist/src/functions/commands/all.js +31 -2
- package/dist/src/functions/commands/bootstrap.d.ts +1 -0
- package/dist/src/functions/commands/bootstrap.js +23 -0
- package/dist/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.js +46 -2
- package/dist/src/functions/wirings/channels/serialize-channel-types.js +3 -2
- package/dist/src/functions/wirings/channels/serialize-websocket-wrapper.js +14 -0
- package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +4 -4
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +24 -4
- package/dist/src/functions/wirings/cli/serialize-channel-cli.js +32 -7
- package/dist/src/functions/wirings/cli/serialize-cli-types.js +22 -0
- package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-services.js +54 -26
- package/dist/src/functions/wirings/functions/schemas.js +2 -2
- package/dist/src/functions/wirings/http/pikku-command-openapi.js +1 -1
- package/dist/src/functions/wirings/middleware/pikku-command-middleware.js +3 -10
- package/dist/src/middleware/log-command-info-and-time.d.ts +1 -1
- package/dist/src/middleware/log-command-info-and-time.js +8 -5
- package/dist/src/services/cli-logger.service.d.ts +7 -2
- package/dist/src/services/cli-logger.service.js +16 -4
- package/dist/src/services.js +77 -12
- package/dist/src/utils/check-required-types.js +11 -1
- package/dist/src/utils/command-summary.d.ts +43 -0
- package/dist/src/utils/command-summary.js +73 -0
- package/dist/src/utils/file-writer.js +2 -2
- package/dist/src/utils/pikku-cli-config.js +28 -0
- package/dist/src/utils/schema-generator.d.ts +2 -2
- package/dist/src/utils/schema-generator.js +3 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/pikku.config.json +5 -2
- package/src/cli.wiring.ts +106 -101
- package/src/functions/commands/all.ts +38 -2
- package/src/functions/commands/bootstrap.ts +27 -0
- package/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts +46 -2
- package/src/functions/wirings/channels/serialize-channel-types.ts +3 -2
- package/src/functions/wirings/channels/serialize-websocket-wrapper.ts +14 -0
- package/src/functions/wirings/cli/pikku-command-cli-entry.ts +4 -4
- package/src/functions/wirings/cli/serialize-channel-cli-client.ts +24 -4
- package/src/functions/wirings/cli/serialize-channel-cli.ts +40 -8
- package/src/functions/wirings/cli/serialize-cli-types.ts +22 -0
- package/src/functions/wirings/functions/pikku-command-services.ts +57 -28
- package/src/functions/wirings/functions/schemas.ts +4 -3
- package/src/functions/wirings/http/pikku-command-openapi.ts +2 -1
- package/src/functions/wirings/middleware/pikku-command-middleware.ts +11 -22
- package/src/middleware/log-command-info-and-time.ts +8 -5
- package/src/services/cli-logger.service.ts +20 -5
- package/src/services.ts +86 -11
- package/src/utils/check-required-types.ts +16 -1
- package/src/utils/command-summary.ts +101 -0
- package/src/utils/file-writer.ts +2 -2
- package/src/utils/pikku-cli-config.ts +28 -0
- package/src/utils/schema-generator.ts +5 -4
- package/types/application-types.d.ts +5 -1
- package/types/config.d.ts +16 -6
- package/.pikku/cli/pikku-cli-channel.gen.ts +0 -34
- package/.pikku/cli/pikku-cli-client.gen.ts +0 -43
- package/.pikku/cli/pikku-cli.gen.ts +0 -41
- package/dist/.pikku/cli/pikku-cli-channel.gen.d.ts +0 -1
- package/dist/.pikku/cli/pikku-cli-channel.gen.js +0 -33
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +0 -10
- package/dist/.pikku/cli/pikku-cli-client.gen.js +0 -34
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +0 -10
- package/dist/.pikku/cli/pikku-cli.gen.js +0 -38
package/src/cli.wiring.ts
CHANGED
|
@@ -1,102 +1,107 @@
|
|
|
1
|
-
import { pikkuSchemas } from './functions/wirings/functions/schemas.js'
|
|
2
|
-
import { pikkuFetch } from './functions/wirings/fetch/index.js'
|
|
3
|
-
import { pikkuWebSocketTyped } from './functions/wirings/channels/pikku-command-websocket-typed.js'
|
|
4
|
-
import { pikkuRPCClient } from './functions/wirings/rpc/pikku-command-rpc-client.js'
|
|
5
|
-
import { pikkuQueueService } from './functions/wirings/queue/pikku-command-queue-service.js'
|
|
6
|
-
import { pikkuOpenAPI } from './functions/wirings/http/pikku-command-openapi.js'
|
|
7
|
-
import { pikkuNext } from './functions/runtimes/nextjs/pikku-command-nextjs.js'
|
|
8
|
-
import { pikkuCLICommand, wireCLI } from '../.pikku/cli/pikku-cli-types.gen.js'
|
|
9
|
-
import { all } from './functions/commands/all.js'
|
|
10
|
-
import {
|
|
1
|
+
// import { pikkuSchemas } from './functions/wirings/functions/schemas.js'
|
|
2
|
+
// import { pikkuFetch } from './functions/wirings/fetch/index.js'
|
|
3
|
+
// import { pikkuWebSocketTyped } from './functions/wirings/channels/pikku-command-websocket-typed.js'
|
|
4
|
+
// import { pikkuRPCClient } from './functions/wirings/rpc/pikku-command-rpc-client.js'
|
|
5
|
+
// import { pikkuQueueService } from './functions/wirings/queue/pikku-command-queue-service.js'
|
|
6
|
+
// import { pikkuOpenAPI } from './functions/wirings/http/pikku-command-openapi.js'
|
|
7
|
+
// import { pikkuNext } from './functions/runtimes/nextjs/pikku-command-nextjs.js'
|
|
8
|
+
// import { pikkuCLICommand, wireCLI } from '../.pikku/cli/pikku-cli-types.gen.js'
|
|
9
|
+
// import { all } from './functions/commands/all.js'
|
|
10
|
+
// import { bootstrap } from './functions/commands/bootstrap.js'
|
|
11
|
+
// import { clientCLIRenderer } from './services.js'
|
|
11
12
|
|
|
12
|
-
wireCLI({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
13
|
+
// wireCLI({
|
|
14
|
+
// program: 'pikku',
|
|
15
|
+
// description:
|
|
16
|
+
// 'Pikku CLI - Code generation tool for type-safe backend development',
|
|
17
|
+
// render: clientCLIRenderer,
|
|
18
|
+
// options: {
|
|
19
|
+
// config: {
|
|
20
|
+
// description: 'Path to pikku.config.json file',
|
|
21
|
+
// short: 'c',
|
|
22
|
+
// },
|
|
23
|
+
// logLevel: {
|
|
24
|
+
// description: 'Set log level',
|
|
25
|
+
// default: 'info' as const,
|
|
26
|
+
// short: 'l',
|
|
27
|
+
// },
|
|
28
|
+
// userSessionType: {
|
|
29
|
+
// description:
|
|
30
|
+
// 'Specify which UserSession type to use (when multiple exist)',
|
|
31
|
+
// },
|
|
32
|
+
// singletonServicesFactoryType: {
|
|
33
|
+
// description: 'Specify which singleton services factory to use',
|
|
34
|
+
// },
|
|
35
|
+
// sessionServicesFactoryType: {
|
|
36
|
+
// description: 'Specify which session services factory to use',
|
|
37
|
+
// },
|
|
38
|
+
// stateOutput: {
|
|
39
|
+
// description: 'Save inspector state to JSON file for reuse',
|
|
40
|
+
// },
|
|
41
|
+
// stateInput: {
|
|
42
|
+
// description: 'Load inspector state from JSON file (skips inspection)',
|
|
43
|
+
// },
|
|
44
|
+
// },
|
|
45
|
+
// commands: {
|
|
46
|
+
// all: pikkuCLICommand({
|
|
47
|
+
// func: all,
|
|
48
|
+
// description: 'Generate all Pikku files (types, schemas, wirings, etc.)',
|
|
49
|
+
// isDefault: true,
|
|
50
|
+
// options: {
|
|
51
|
+
// tags: {
|
|
52
|
+
// description: 'Filter functions by tags (comma-separated)',
|
|
53
|
+
// short: 't',
|
|
54
|
+
// },
|
|
55
|
+
// types: {
|
|
56
|
+
// description: 'Filter functions by types (comma-separated)',
|
|
57
|
+
// },
|
|
58
|
+
// directories: {
|
|
59
|
+
// description: 'Filter functions by directories (comma-separated)',
|
|
60
|
+
// short: 'd',
|
|
61
|
+
// },
|
|
62
|
+
// httpMethods: {
|
|
63
|
+
// description: 'Filter HTTP routes by methods (comma-separated)',
|
|
64
|
+
// },
|
|
65
|
+
// httpRoutes: {
|
|
66
|
+
// description: 'Filter HTTP routes by route patterns (comma-separated)',
|
|
67
|
+
// },
|
|
68
|
+
// names: {
|
|
69
|
+
// description: 'Filter functions by name patterns (supports wildcards)',
|
|
70
|
+
// short: 'n',
|
|
71
|
+
// },
|
|
72
|
+
// },
|
|
73
|
+
// }),
|
|
74
|
+
// bootstrap: pikkuCLICommand({
|
|
75
|
+
// func: bootstrap,
|
|
76
|
+
// description: 'Generate only type files (setup phase only)',
|
|
77
|
+
// }),
|
|
78
|
+
// schemas: pikkuCLICommand({
|
|
79
|
+
// func: pikkuSchemas,
|
|
80
|
+
// description: 'Generate JSON schemas for function input/output types',
|
|
81
|
+
// }),
|
|
82
|
+
// fetch: pikkuCLICommand({
|
|
83
|
+
// func: pikkuFetch,
|
|
84
|
+
// description: 'Generate type-safe HTTP fetch client',
|
|
85
|
+
// }),
|
|
86
|
+
// websocket: pikkuCLICommand({
|
|
87
|
+
// func: pikkuWebSocketTyped,
|
|
88
|
+
// description: 'Generate type-safe WebSocket client',
|
|
89
|
+
// }),
|
|
90
|
+
// rpc: pikkuCLICommand({
|
|
91
|
+
// func: pikkuRPCClient,
|
|
92
|
+
// description: 'Generate RPC client wrappers',
|
|
93
|
+
// }),
|
|
94
|
+
// 'queue-service': pikkuCLICommand({
|
|
95
|
+
// func: pikkuQueueService,
|
|
96
|
+
// description: 'Generate queue service wrapper',
|
|
97
|
+
// }),
|
|
98
|
+
// openapi: pikkuCLICommand({
|
|
99
|
+
// func: pikkuOpenAPI,
|
|
100
|
+
// description: 'Generate OpenAPI specification from HTTP routes',
|
|
101
|
+
// }),
|
|
102
|
+
// nextjs: pikkuCLICommand({
|
|
103
|
+
// func: pikkuNext,
|
|
104
|
+
// description: 'Generate Next.js backend and HTTP wrappers',
|
|
105
|
+
// }),
|
|
106
|
+
// },
|
|
107
|
+
// })
|
|
@@ -2,9 +2,11 @@ import { existsSync } from 'fs'
|
|
|
2
2
|
import { pikkuVoidFunc } from '../../../.pikku/pikku-types.gen.js'
|
|
3
3
|
import { getFileImportRelativePath } from '../../utils/file-import-path.js'
|
|
4
4
|
import { writeFileInDir } from '../../utils/file-writer.js'
|
|
5
|
+
import { CommandSummary } from '../../utils/command-summary.js'
|
|
5
6
|
|
|
6
7
|
export const all: any = pikkuVoidFunc({
|
|
7
8
|
func: async ({ logger, config, rpc, getInspectorState }) => {
|
|
9
|
+
const summary = new CommandSummary('all')
|
|
8
10
|
const allImports: string[] = []
|
|
9
11
|
let typesDeclarationFileExists = true
|
|
10
12
|
|
|
@@ -16,7 +18,7 @@ export const all: any = pikkuVoidFunc({
|
|
|
16
18
|
|
|
17
19
|
// This is needed since the wireHTTP function will add the routes to the visitState
|
|
18
20
|
if (!typesDeclarationFileExists) {
|
|
19
|
-
logger.
|
|
21
|
+
logger.debug(`• Type file first created, inspecting again...`)
|
|
20
22
|
await getInspectorState(true)
|
|
21
23
|
}
|
|
22
24
|
|
|
@@ -125,7 +127,7 @@ export const all: any = pikkuVoidFunc({
|
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
if (config.openAPI) {
|
|
128
|
-
logger.
|
|
130
|
+
logger.debug(
|
|
129
131
|
`• OpenAPI requires a reinspection to pickup new generated types..`
|
|
130
132
|
)
|
|
131
133
|
await getInspectorState(true)
|
|
@@ -145,6 +147,40 @@ export const all: any = pikkuVoidFunc({
|
|
|
145
147
|
.join('\n')
|
|
146
148
|
)
|
|
147
149
|
|
|
150
|
+
// Get final inspector state and collect stats for summary
|
|
151
|
+
const state = await getInspectorState()
|
|
152
|
+
if (state.http?.meta)
|
|
153
|
+
summary.set('httpRoutes', Object.keys(state.http.meta).length)
|
|
154
|
+
if (state.channels?.meta)
|
|
155
|
+
summary.set('channels', Object.keys(state.channels.meta).length)
|
|
156
|
+
if (state.scheduledTasks?.meta)
|
|
157
|
+
summary.set(
|
|
158
|
+
'scheduledTasks',
|
|
159
|
+
Object.keys(state.scheduledTasks.meta).length
|
|
160
|
+
)
|
|
161
|
+
if (state.queueWorkers?.meta)
|
|
162
|
+
summary.set('queueWorkers', Object.keys(state.queueWorkers.meta).length)
|
|
163
|
+
if (state.mcpEndpoints) {
|
|
164
|
+
const mcpTotal =
|
|
165
|
+
Object.keys(state.mcpEndpoints.toolsMeta || {}).length +
|
|
166
|
+
Object.keys(state.mcpEndpoints.resourcesMeta || {}).length +
|
|
167
|
+
Object.keys(state.mcpEndpoints.promptsMeta || {}).length
|
|
168
|
+
if (mcpTotal > 0) summary.set('mcpEndpoints', mcpTotal)
|
|
169
|
+
}
|
|
170
|
+
if (state.cli?.meta) {
|
|
171
|
+
// Count total CLI commands across all programs
|
|
172
|
+
const totalCommands = Object.values(state.cli.meta).reduce(
|
|
173
|
+
(sum, program) => sum + (program.commands?.length || 0),
|
|
174
|
+
0
|
|
175
|
+
)
|
|
176
|
+
if (totalCommands > 0) summary.set('cliCommands', totalCommands)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Display summary (unless in silent mode)
|
|
180
|
+
if (!logger.isSilent()) {
|
|
181
|
+
console.log(summary.format())
|
|
182
|
+
}
|
|
183
|
+
|
|
148
184
|
// Check for critical errors and exit if any were logged
|
|
149
185
|
if (logger.hasCriticalErrors()) {
|
|
150
186
|
process.exit(1)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { pikkuVoidFunc } from '../../../.pikku/pikku-types.gen.js'
|
|
2
|
+
|
|
3
|
+
export const bootstrap: any = pikkuVoidFunc({
|
|
4
|
+
func: async ({ logger, config, rpc, getInspectorState }) => {
|
|
5
|
+
// Initialize inspector state in bootstrap mode with core types only
|
|
6
|
+
// This allows bootstrap to run immediately without inspecting the codebase
|
|
7
|
+
// All subsequent RPC commands will use this cached state
|
|
8
|
+
await getInspectorState(false, false, true)
|
|
9
|
+
|
|
10
|
+
await rpc.invoke('pikkuFunctionTypes', null)
|
|
11
|
+
|
|
12
|
+
// Generate wiring-specific type files for tree-shaking
|
|
13
|
+
// These use the bootstrap mode state with core types
|
|
14
|
+
await rpc.invoke('pikkuFunctionTypesSplit', null)
|
|
15
|
+
await rpc.invoke('pikkuHTTPTypes', null)
|
|
16
|
+
await rpc.invoke('pikkuChannelTypes', null)
|
|
17
|
+
await rpc.invoke('pikkuSchedulerTypes', null)
|
|
18
|
+
await rpc.invoke('pikkuQueueTypes', null)
|
|
19
|
+
await rpc.invoke('pikkuMCPTypes', null)
|
|
20
|
+
await rpc.invoke('pikkuCLITypes', null)
|
|
21
|
+
|
|
22
|
+
// Check for critical errors and exit if any were logged
|
|
23
|
+
if (logger.hasCriticalErrors()) {
|
|
24
|
+
process.exit(1)
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
})
|
|
@@ -6,14 +6,17 @@ export const serializeNextJsBackendWrapper = (
|
|
|
6
6
|
sessionServicesImport: string
|
|
7
7
|
) => {
|
|
8
8
|
return `'server-only'
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
/**
|
|
11
11
|
* This file provides a wrapper around the PikkuNextJS class to allow for methods to be type checked against your routes.
|
|
12
12
|
* It ensures type safety for route handling methods when integrating with the @pikku/core framework.
|
|
13
13
|
*/
|
|
14
14
|
import { PikkuNextJS } from '@pikku/next'
|
|
15
|
+
import { NextRequest } from 'next/server.js'
|
|
15
16
|
import type { HTTPWiringsMap, HTTPWiringHandlerOf, HTTPWiringsWithMethod } from '${routesMapPath}'
|
|
16
17
|
|
|
18
|
+
type RouteContext = { params: Promise<Record<string, string | string[]>> }
|
|
19
|
+
|
|
17
20
|
${configImport}
|
|
18
21
|
${singleServicesFactoryImport}
|
|
19
22
|
${sessionServicesImport}
|
|
@@ -21,6 +24,11 @@ ${sessionServicesImport}
|
|
|
21
24
|
import '${bootstrapPath}'
|
|
22
25
|
|
|
23
26
|
let _pikku: PikkuNextJS | undefined
|
|
27
|
+
let _removeAPIPrefix = true
|
|
28
|
+
|
|
29
|
+
export const removeAPIPrefix = (enable: boolean) => {
|
|
30
|
+
_removeAPIPrefix = enable
|
|
31
|
+
}
|
|
24
32
|
|
|
25
33
|
/**
|
|
26
34
|
* Initializes and returns an instance of PikkuNextJS with helper methods for handling route requests.
|
|
@@ -178,8 +186,44 @@ export const pikku = (_options?: any) => {
|
|
|
178
186
|
patch: dynamicPatch,
|
|
179
187
|
del: dynamicDel,
|
|
180
188
|
staticGet,
|
|
181
|
-
staticPost
|
|
189
|
+
staticPost,
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Pre-bound API request handler for Next.js App Router route handlers.
|
|
195
|
+
* Use this to directly export route handlers without losing context.
|
|
196
|
+
*
|
|
197
|
+
* @param req - The Next.js request object.
|
|
198
|
+
* @param context - Next.js route context (unused by Pikku, but required by Next.js signature).
|
|
199
|
+
* @returns A promise that resolves to a Next.js Response object.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* export const GET = pikkuAPIRequest
|
|
203
|
+
* export const POST = pikkuAPIRequest
|
|
204
|
+
*/
|
|
205
|
+
export const pikkuAPIRequest = (
|
|
206
|
+
req: NextRequest,
|
|
207
|
+
context: RouteContext
|
|
208
|
+
): Promise<Response> => {
|
|
209
|
+
if (!_pikku) {
|
|
210
|
+
_pikku = new PikkuNextJS(
|
|
211
|
+
createConfig as any,
|
|
212
|
+
createSingletonServices as any,
|
|
213
|
+
createSessionServices
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
if (_removeAPIPrefix) {
|
|
217
|
+
const url = new URL(req.url)
|
|
218
|
+
url.pathname = url.pathname.replace(/^\\/api/, '') || '/'
|
|
219
|
+
req = new NextRequest(url.toString(), {
|
|
220
|
+
method: req.method,
|
|
221
|
+
headers: req.headers,
|
|
222
|
+
body: req.body,
|
|
223
|
+
duplex: 'half',
|
|
224
|
+
} as any)
|
|
182
225
|
}
|
|
226
|
+
return _pikku.apiRequest(req)
|
|
183
227
|
}
|
|
184
228
|
`
|
|
185
229
|
}
|
|
@@ -10,11 +10,12 @@ export const serializeChannelTypes = (functionTypesImportPath: string) => {
|
|
|
10
10
|
import { CoreChannel, wireChannel as wireChannelCore } from '@pikku/core/channel'
|
|
11
11
|
import { CorePikkuFunctionConfig } from '@pikku/core'
|
|
12
12
|
import { AssertHTTPWiringParams } from '@pikku/core/http'
|
|
13
|
-
import type { PikkuFunctionSessionless, PikkuPermission, PikkuMiddleware } from '${functionTypesImportPath}'
|
|
13
|
+
import type { PikkuFunction, PikkuFunctionSessionless, PikkuPermission, PikkuMiddleware } from '${functionTypesImportPath}'
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Type definition for WebSocket channels with typed data exchange.
|
|
17
17
|
* Supports connection, disconnection, and message handling.
|
|
18
|
+
* Accepts both session-based (PikkuFunction) and sessionless (PikkuFunctionSessionless) functions.
|
|
18
19
|
*
|
|
19
20
|
* @template ChannelData - Type of data exchanged through the channel
|
|
20
21
|
* @template Channel - String literal type for the channel name
|
|
@@ -24,7 +25,7 @@ type ChannelWiring<ChannelData, Channel extends string> = CoreChannel<
|
|
|
24
25
|
Channel,
|
|
25
26
|
CorePikkuFunctionConfig<PikkuFunctionSessionless<void, any, ChannelData>, PikkuPermission<void>, PikkuMiddleware>,
|
|
26
27
|
CorePikkuFunctionConfig<PikkuFunctionSessionless<void, void, ChannelData>, PikkuPermission<void>, PikkuMiddleware>,
|
|
27
|
-
CorePikkuFunctionConfig<PikkuFunctionSessionless<any, any, ChannelData>, PikkuPermission<any>, PikkuMiddleware>,
|
|
28
|
+
CorePikkuFunctionConfig<PikkuFunctionSessionless<any, any, ChannelData> | PikkuFunction<any, any, ChannelData>, PikkuPermission<any>, PikkuMiddleware>,
|
|
28
29
|
PikkuPermission,
|
|
29
30
|
PikkuMiddleware
|
|
30
31
|
>
|
|
@@ -26,6 +26,20 @@ class PikkuWebSocketRoute<Channel extends keyof ChannelsMap, Route extends keyof
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Type-safe WebSocket wrapper for Pikku channels.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Browser usage
|
|
34
|
+
* const ws = new WebSocket('ws://localhost:3000')
|
|
35
|
+
* const pikkuWS = new PikkuWebSocket<'events'>(ws)
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Node.js usage
|
|
39
|
+
* import WebSocket from 'ws'
|
|
40
|
+
* const ws = new WebSocket('ws://localhost:3000')
|
|
41
|
+
* const pikkuWS = new PikkuWebSocket<'events'>(ws)
|
|
42
|
+
*/
|
|
29
43
|
export class PikkuWebSocket<Channel extends keyof ChannelsMap, EventHubTopics extends Record<string, any> = {}> extends CorePikkuWebsocket {
|
|
30
44
|
/**
|
|
31
45
|
* Send a message to a specific route and method.
|
|
@@ -52,8 +52,8 @@ export const pikkuCLIEntry: any = pikkuSessionlessFunc<void, void>({
|
|
|
52
52
|
// Normalize entrypoint config to get type
|
|
53
53
|
const entrypointType =
|
|
54
54
|
typeof entrypointConfig === 'string'
|
|
55
|
-
? '
|
|
56
|
-
: entrypointConfig.type || '
|
|
55
|
+
? 'local'
|
|
56
|
+
: entrypointConfig.type || 'local'
|
|
57
57
|
|
|
58
58
|
// Handle channel type entrypoint
|
|
59
59
|
if (entrypointType === 'channel') {
|
|
@@ -152,11 +152,11 @@ export const pikkuCLIEntry: any = pikkuSessionlessFunc<void, void>({
|
|
|
152
152
|
continue
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
// Handle CLI type entrypoint (default)
|
|
155
|
+
// Handle local CLI type entrypoint (default)
|
|
156
156
|
const entrypointPath =
|
|
157
157
|
typeof entrypointConfig === 'string'
|
|
158
158
|
? entrypointConfig
|
|
159
|
-
: entrypointConfig.type === '
|
|
159
|
+
: entrypointConfig.type === 'local'
|
|
160
160
|
? entrypointConfig.path
|
|
161
161
|
: undefined
|
|
162
162
|
|
|
@@ -142,8 +142,27 @@ export async function ${capitalizedName}CLIClient(
|
|
|
142
142
|
url: string,
|
|
143
143
|
args?: string[]
|
|
144
144
|
): Promise<void> {
|
|
145
|
+
// Get WebSocket implementation (browser or Node.js)
|
|
146
|
+
let WebSocketImpl: any
|
|
147
|
+
if (typeof WebSocket !== 'undefined') {
|
|
148
|
+
WebSocketImpl = WebSocket
|
|
149
|
+
} else {
|
|
150
|
+
// Node.js environment - dynamically import 'ws'
|
|
151
|
+
try {
|
|
152
|
+
const wsModule = await import('ws')
|
|
153
|
+
WebSocketImpl = wsModule.default
|
|
154
|
+
} catch (e) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
'No WebSocket implementation found. In Node.js environments, you need to:\\n' +
|
|
157
|
+
'1. Install the "ws" package: npm install ws\\n' +
|
|
158
|
+
'Learn more: https://www.npmjs.com/package/ws'
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
145
163
|
// Create WebSocket connection
|
|
146
|
-
const
|
|
164
|
+
const ws = new WebSocketImpl(url) as WebSocket
|
|
165
|
+
const pikkuWS = new CorePikkuWebsocket(ws)
|
|
147
166
|
|
|
148
167
|
// Register renderers for CLI commands
|
|
149
168
|
const renderers = ${renderersMap}
|
|
@@ -161,10 +180,11 @@ export default ${capitalizedName}CLIClient
|
|
|
161
180
|
|
|
162
181
|
// For direct execution (if this file is run directly)
|
|
163
182
|
if (import.meta.url === \`file://\${process.argv[1]}\`) {
|
|
164
|
-
const url = process.env.PIKKU_WS_URL || 'ws://localhost:
|
|
183
|
+
const url = process.env.PIKKU_WS_URL || 'ws://localhost:4002${finalChannelRoute}'
|
|
165
184
|
${capitalizedName}CLIClient(url, process.argv.slice(2)).catch(error => {
|
|
166
|
-
console.error('Fatal error:', error
|
|
167
|
-
|
|
185
|
+
console.error('Fatal channel CLI error:', error)
|
|
186
|
+
// TODO: We get an error code even when it exists cleanly, investigate
|
|
187
|
+
// process.exit(1)
|
|
168
188
|
})
|
|
169
189
|
}
|
|
170
190
|
`
|
|
@@ -47,13 +47,6 @@ export function serializeChannelCLI(
|
|
|
47
47
|
|
|
48
48
|
collectCommands(programMeta.commands)
|
|
49
49
|
|
|
50
|
-
// Generate the wireChannel call
|
|
51
|
-
const commandEntries = Object.entries(commandMap)
|
|
52
|
-
.map(([commandKey, { pikkuFuncName }]) => {
|
|
53
|
-
return ` '${commandKey}': ${pikkuFuncName}`
|
|
54
|
-
})
|
|
55
|
-
.join(',\n')
|
|
56
|
-
|
|
57
50
|
// Generate imports from function file locations
|
|
58
51
|
const funcNames = [
|
|
59
52
|
...new Set(Object.values(commandMap).map((v) => v.pikkuFuncName)),
|
|
@@ -81,19 +74,58 @@ export function serializeChannelCLI(
|
|
|
81
74
|
packageMappings
|
|
82
75
|
)
|
|
83
76
|
|
|
77
|
+
// Get relative path to function types file
|
|
78
|
+
const functionTypesPath = getFileImportRelativePath(
|
|
79
|
+
channelFile,
|
|
80
|
+
functionTypesFile,
|
|
81
|
+
packageMappings
|
|
82
|
+
)
|
|
83
|
+
|
|
84
84
|
return `/**
|
|
85
85
|
* WebSocket channel backend for '${programName}' CLI commands
|
|
86
86
|
*/
|
|
87
87
|
import { wireChannel } from '${channelTypesPath}'
|
|
88
|
+
import { pikkuMiddleware } from '${functionTypesPath}'
|
|
88
89
|
${imports}
|
|
89
90
|
|
|
91
|
+
// Middleware to close the channel after CLI command completes
|
|
92
|
+
const cliCloseOnComplete = pikkuMiddleware(async (services, { channel }, next) => {
|
|
93
|
+
const closeChannel = () => {
|
|
94
|
+
setTimeout(async () => {
|
|
95
|
+
try {
|
|
96
|
+
// This gives time for the response to be sent before closing
|
|
97
|
+
await channel?.close()
|
|
98
|
+
} catch (err) {
|
|
99
|
+
// Ignore errors on close
|
|
100
|
+
}
|
|
101
|
+
}, 200)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const result = await next()
|
|
106
|
+
closeChannel()
|
|
107
|
+
return result
|
|
108
|
+
} catch (error) {
|
|
109
|
+
closeChannel()
|
|
110
|
+
throw error
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
90
114
|
wireChannel({
|
|
91
115
|
name: '${finalChannelName}',
|
|
92
116
|
route: '${finalChannelRoute}',
|
|
93
117
|
auth: false,
|
|
94
118
|
onMessageWiring: {
|
|
95
119
|
command: {
|
|
96
|
-
${
|
|
120
|
+
${Object.entries(commandMap)
|
|
121
|
+
.map(
|
|
122
|
+
([commandKey, { pikkuFuncName }]) =>
|
|
123
|
+
` '${commandKey}': {
|
|
124
|
+
func: ${pikkuFuncName},
|
|
125
|
+
middleware: [cliCloseOnComplete],
|
|
126
|
+
}`
|
|
127
|
+
)
|
|
128
|
+
.join(',\n')}
|
|
97
129
|
}
|
|
98
130
|
},
|
|
99
131
|
tags: ['cli', '${programName}']
|
|
@@ -30,6 +30,28 @@ ${userSessionTypeName !== 'Session' ? `type Session = ${userSessionTypeName}` :
|
|
|
30
30
|
*/
|
|
31
31
|
type PikkuCLIRender<Data, RequiredServices extends SingletonServices = SingletonServices> = CorePikkuCLIRender<Data, RequiredServices, Session>
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Creates a type-safe CLI renderer with access to your application's singleton services.
|
|
35
|
+
* The renderer receives the full singleton services and output data to format and display results.
|
|
36
|
+
*
|
|
37
|
+
* @template Data - The output data type from the CLI command
|
|
38
|
+
* @template RequiredServices - The minimum services required for type checking (defaults to SingletonServices)
|
|
39
|
+
* @param render - Function that receives singleton services and data to render output
|
|
40
|
+
* @returns A CLI renderer configuration
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* \`\`\`typescript
|
|
44
|
+
* const myRenderer = pikkuCLIRender<MyData>(({ logger }, data) => {
|
|
45
|
+
* logger.info(data.message)
|
|
46
|
+
* })
|
|
47
|
+
* \`\`\`
|
|
48
|
+
*/
|
|
49
|
+
export const pikkuCLIRender = <Data, RequiredServices extends SingletonServices = SingletonServices>(
|
|
50
|
+
render: (services: SingletonServices, data: Data) => void | Promise<void>
|
|
51
|
+
): PikkuCLIRender<Data, RequiredServices> => {
|
|
52
|
+
return render as any
|
|
53
|
+
}
|
|
54
|
+
|
|
33
55
|
/**
|
|
34
56
|
* CLI command configuration with project-specific types.
|
|
35
57
|
* Uses CoreCLICommandConfig from @pikku/core with local middleware and render types.
|