@pikku/cli 0.10.1 → 0.11.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.
- package/.pikku/channel/pikku-channel-types.gen.ts +4 -3
- package/.pikku/channel/pikku-channels-map.gen.d.ts +5 -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 +8 -116
- 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 +265 -138
- package/.pikku/function/pikku-functions-meta.min.gen.ts +62 -32
- package/.pikku/function/pikku-functions.gen.ts +9 -1
- package/.pikku/http/pikku-http-types.gen.ts +1 -1
- package/.pikku/http/pikku-http-wirings-map.gen.d.ts +5 -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 +4 -1
- package/.pikku/pikku-services.gen.ts +21 -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 +5 -2
- package/.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts +7 -2
- package/.pikku/queue/pikku-queue-workers-wirings.gen.ts +1 -1
- package/.pikku/rpc/pikku-remote-rpc-workers.gen.ts +27 -0
- package/.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts +13 -3
- package/.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +26 -10
- package/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts +15 -9
- 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 +17 -5
- package/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
- package/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
- package/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
- package/.pikku/workflow/pikku-workflow-map.gen.d.ts +62 -0
- package/.pikku/workflow/pikku-workflow-types.gen.ts +92 -0
- package/.pikku/workflow/pikku-workflow-wirings-meta.gen.ts +5 -0
- package/.pikku/workflow/pikku-workflow-wirings.gen.ts +4 -0
- package/CHANGELOG.md +57 -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 +8 -116
- 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 +265 -138
- package/dist/.pikku/function/pikku-functions-meta.min.gen.js +62 -32
- package/dist/.pikku/function/pikku-functions.gen.js +9 -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 +4 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +4 -1
- package/dist/.pikku/pikku-services.gen.d.ts +15 -6
- package/dist/.pikku/pikku-services.gen.js +14 -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 +7 -2
- 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-remote-rpc-workers.gen.d.ts +17 -0
- package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +22 -0
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +15 -9
- 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 +9 -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/PikkuPublicRPCOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuRemoteInternalRPCInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +58 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +28 -0
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +5 -0
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +4 -0
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +5 -0
- package/dist/bin/pikku.js +24 -19
- package/dist/src/cli.wiring.js +107 -99
- package/dist/src/functions/commands/all.js +51 -2
- package/dist/src/functions/commands/bootstrap.d.ts +1 -0
- package/dist/src/functions/commands/bootstrap.js +24 -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 +20 -7
- 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/functions/wirings/queue/pikku-queue.js +9 -1
- package/dist/src/functions/wirings/queue/serialize-queue-map.d.ts +2 -2
- package/dist/src/functions/wirings/queue/serialize-queue-meta.d.ts +2 -2
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +23 -0
- package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.js +23 -0
- package/dist/src/functions/wirings/rpc/serialize-public-rpc.d.ts +4 -0
- package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +30 -0
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.d.ts +4 -0
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +30 -0
- package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +2 -2
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +27 -3
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.d.ts +1 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.js +12 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.d.ts +1 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.js +11 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +55 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +79 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.d.ts +2 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +10 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +95 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-workers.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-workers.js +60 -0
- 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-forwarder.service.js +1 -1
- package/dist/src/services/cli-logger.service.d.ts +7 -2
- package/dist/src/services/cli-logger.service.js +17 -5
- package/dist/src/services.js +77 -12
- package/dist/src/utils/command-summary.d.ts +44 -0
- package/dist/src/utils/command-summary.js +74 -0
- package/dist/src/utils/file-writer.js +2 -2
- package/dist/src/utils/pikku-cli-config.js +48 -0
- package/dist/src/utils/schema-generator.d.ts +2 -2
- package/dist/src/utils/schema-generator.js +31 -10
- 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 +66 -2
- package/src/functions/commands/bootstrap.ts +28 -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 +20 -7
- 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/functions/wirings/queue/pikku-queue.ts +10 -1
- package/src/functions/wirings/queue/serialize-queue-map.ts +3 -3
- package/src/functions/wirings/queue/serialize-queue-meta.ts +2 -2
- package/src/functions/wirings/rpc/pikku-command-public-rpc.ts +32 -0
- package/src/functions/wirings/rpc/pikku-command-remote-rpc.ts +35 -0
- package/src/functions/wirings/rpc/serialize-public-rpc.ts +30 -0
- package/src/functions/wirings/rpc/serialize-remote-rpc.ts +30 -0
- package/src/functions/wirings/rpc/serialize-rpc-wrapper.ts +2 -2
- package/src/functions/wirings/rpc/serialize-typed-rpc-map.ts +26 -3
- package/src/functions/wirings/workflow/pikku-command-workflow-map.ts +24 -0
- package/src/functions/wirings/workflow/pikku-command-workflow-types.ts +22 -0
- package/src/functions/wirings/workflow/pikku-command-workflow.ts +123 -0
- package/src/functions/wirings/workflow/serialize-workflow-map.ts +123 -0
- package/src/functions/wirings/workflow/serialize-workflow-meta.ts +16 -0
- package/src/functions/wirings/workflow/serialize-workflow-types.ts +95 -0
- package/src/functions/wirings/workflow/serialize-workflow-workers.ts +60 -0
- package/src/middleware/log-command-info-and-time.ts +8 -5
- package/src/services/cli-logger-forwarder.service.ts +1 -1
- package/src/services/cli-logger.service.ts +21 -6
- package/src/services.ts +86 -11
- package/src/utils/command-summary.ts +103 -0
- package/src/utils/file-writer.ts +2 -2
- package/src/utils/pikku-cli-config.ts +68 -0
- package/src/utils/schema-generator.ts +30 -11
- package/types/application-types.d.ts +5 -1
- package/types/config.d.ts +61 -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.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/dist/.pikku/{cli/pikku-cli-channel.gen.d.ts → workflow/pikku-workflow-wirings-meta.gen.d.ts} +0 -0
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export const serializeNextJsBackendWrapper = (bootstrapPath, routesMapPath, configImport, singleServicesFactoryImport, sessionServicesImport) => {
|
|
2
2
|
return `'server-only'
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
/**
|
|
5
5
|
* This file provides a wrapper around the PikkuNextJS class to allow for methods to be type checked against your routes.
|
|
6
6
|
* It ensures type safety for route handling methods when integrating with the @pikku/core framework.
|
|
7
7
|
*/
|
|
8
8
|
import { PikkuNextJS } from '@pikku/next'
|
|
9
|
+
import { NextRequest } from 'next/server.js'
|
|
9
10
|
import type { HTTPWiringsMap, HTTPWiringHandlerOf, HTTPWiringsWithMethod } from '${routesMapPath}'
|
|
10
11
|
|
|
12
|
+
type RouteContext = { params: Promise<Record<string, string | string[]>> }
|
|
13
|
+
|
|
11
14
|
${configImport}
|
|
12
15
|
${singleServicesFactoryImport}
|
|
13
16
|
${sessionServicesImport}
|
|
@@ -15,6 +18,11 @@ ${sessionServicesImport}
|
|
|
15
18
|
import '${bootstrapPath}'
|
|
16
19
|
|
|
17
20
|
let _pikku: PikkuNextJS | undefined
|
|
21
|
+
let _removeAPIPrefix = true
|
|
22
|
+
|
|
23
|
+
export const removeAPIPrefix = (enable: boolean) => {
|
|
24
|
+
_removeAPIPrefix = enable
|
|
25
|
+
}
|
|
18
26
|
|
|
19
27
|
/**
|
|
20
28
|
* Initializes and returns an instance of PikkuNextJS with helper methods for handling route requests.
|
|
@@ -172,8 +180,44 @@ export const pikku = (_options?: any) => {
|
|
|
172
180
|
patch: dynamicPatch,
|
|
173
181
|
del: dynamicDel,
|
|
174
182
|
staticGet,
|
|
175
|
-
staticPost
|
|
183
|
+
staticPost,
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Pre-bound API request handler for Next.js App Router route handlers.
|
|
189
|
+
* Use this to directly export route handlers without losing context.
|
|
190
|
+
*
|
|
191
|
+
* @param req - The Next.js request object.
|
|
192
|
+
* @param context - Next.js route context (unused by Pikku, but required by Next.js signature).
|
|
193
|
+
* @returns A promise that resolves to a Next.js Response object.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* export const GET = pikkuAPIRequest
|
|
197
|
+
* export const POST = pikkuAPIRequest
|
|
198
|
+
*/
|
|
199
|
+
export const pikkuAPIRequest = (
|
|
200
|
+
req: NextRequest,
|
|
201
|
+
context: RouteContext
|
|
202
|
+
): Promise<Response> => {
|
|
203
|
+
if (!_pikku) {
|
|
204
|
+
_pikku = new PikkuNextJS(
|
|
205
|
+
createConfig as any,
|
|
206
|
+
createSingletonServices as any,
|
|
207
|
+
createSessionServices
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
if (_removeAPIPrefix) {
|
|
211
|
+
const url = new URL(req.url)
|
|
212
|
+
url.pathname = url.pathname.replace(/^\\/api/, '') || '/'
|
|
213
|
+
req = new NextRequest(url.toString(), {
|
|
214
|
+
method: req.method,
|
|
215
|
+
headers: req.headers,
|
|
216
|
+
body: req.body,
|
|
217
|
+
duplex: 'half',
|
|
218
|
+
} as any)
|
|
176
219
|
}
|
|
220
|
+
return _pikku.apiRequest(req)
|
|
177
221
|
}
|
|
178
222
|
`;
|
|
179
223
|
};
|
|
@@ -10,11 +10,12 @@ export const serializeChannelTypes = (functionTypesImportPath) => {
|
|
|
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.
|
|
@@ -35,8 +35,8 @@ export const pikkuCLIEntry = pikkuSessionlessFunc({
|
|
|
35
35
|
for (const entrypointConfig of configs) {
|
|
36
36
|
// Normalize entrypoint config to get type
|
|
37
37
|
const entrypointType = typeof entrypointConfig === 'string'
|
|
38
|
-
? '
|
|
39
|
-
: entrypointConfig.type || '
|
|
38
|
+
? 'local'
|
|
39
|
+
: entrypointConfig.type || 'local';
|
|
40
40
|
// Handle channel type entrypoint
|
|
41
41
|
if (entrypointType === 'channel') {
|
|
42
42
|
if (typeof entrypointConfig === 'string' ||
|
|
@@ -85,10 +85,10 @@ export const pikkuCLIEntry = pikkuSessionlessFunc({
|
|
|
85
85
|
}
|
|
86
86
|
continue;
|
|
87
87
|
}
|
|
88
|
-
// Handle CLI type entrypoint (default)
|
|
88
|
+
// Handle local CLI type entrypoint (default)
|
|
89
89
|
const entrypointPath = typeof entrypointConfig === 'string'
|
|
90
90
|
? entrypointConfig
|
|
91
|
-
: entrypointConfig.type === '
|
|
91
|
+
: entrypointConfig.type === 'local'
|
|
92
92
|
? entrypointConfig.path
|
|
93
93
|
: undefined;
|
|
94
94
|
if (!entrypointPath) {
|
|
@@ -99,11 +99,11 @@ ${rendererImports}
|
|
|
99
99
|
* Executes CLI commands over a WebSocket connection
|
|
100
100
|
*/
|
|
101
101
|
export async function ${capitalizedName}CLIClient(
|
|
102
|
-
|
|
102
|
+
ws: WebSocket,
|
|
103
103
|
args?: string[]
|
|
104
104
|
): Promise<void> {
|
|
105
|
-
// Create WebSocket
|
|
106
|
-
const pikkuWS = new CorePikkuWebsocket(
|
|
105
|
+
// Create Pikku WebSocket wrapper
|
|
106
|
+
const pikkuWS = new CorePikkuWebsocket(ws)
|
|
107
107
|
|
|
108
108
|
// Register renderers for CLI commands
|
|
109
109
|
const renderers = ${renderersMap}
|
|
@@ -121,10 +121,23 @@ export default ${capitalizedName}CLIClient
|
|
|
121
121
|
|
|
122
122
|
// For direct execution (if this file is run directly)
|
|
123
123
|
if (import.meta.url === \`file://\${process.argv[1]}\`) {
|
|
124
|
-
const url = process.env.PIKKU_WS_URL || 'ws://localhost:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
const url = process.env.PIKKU_WS_URL || 'ws://localhost:4002${finalChannelRoute}'
|
|
125
|
+
|
|
126
|
+
// Create WebSocket instance
|
|
127
|
+
let WebSocketImpl: any
|
|
128
|
+
if (typeof WebSocket !== 'undefined') {
|
|
129
|
+
WebSocketImpl = WebSocket
|
|
130
|
+
} else {
|
|
131
|
+
// Node.js environment - dynamically import 'ws'
|
|
132
|
+
const wsModule = await import('ws')
|
|
133
|
+
WebSocketImpl = wsModule.default
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const ws = new WebSocketImpl(url) as WebSocket
|
|
137
|
+
${capitalizedName}CLIClient(ws, process.argv.slice(2)).catch(error => {
|
|
138
|
+
console.error('Fatal channel CLI error:', error)
|
|
139
|
+
// TODO: We get an error code even when it exists cleanly, investigate
|
|
140
|
+
// process.exit(1)
|
|
128
141
|
})
|
|
129
142
|
}
|
|
130
143
|
`;
|
|
@@ -24,12 +24,6 @@ export function serializeChannelCLI(programName, programMeta, channelFile, funct
|
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
collectCommands(programMeta.commands);
|
|
27
|
-
// Generate the wireChannel call
|
|
28
|
-
const commandEntries = Object.entries(commandMap)
|
|
29
|
-
.map(([commandKey, { pikkuFuncName }]) => {
|
|
30
|
-
return ` '${commandKey}': ${pikkuFuncName}`;
|
|
31
|
-
})
|
|
32
|
-
.join(',\n');
|
|
33
27
|
// Generate imports from function file locations
|
|
34
28
|
const funcNames = [
|
|
35
29
|
...new Set(Object.values(commandMap).map((v) => v.pikkuFuncName)),
|
|
@@ -46,19 +40,50 @@ export function serializeChannelCLI(programName, programMeta, channelFile, funct
|
|
|
46
40
|
.join('\n');
|
|
47
41
|
// Get relative path to channel types file
|
|
48
42
|
const channelTypesPath = getFileImportRelativePath(channelFile, channelTypesFile, packageMappings);
|
|
43
|
+
// Get relative path to function types file
|
|
44
|
+
const functionTypesPath = getFileImportRelativePath(channelFile, functionTypesFile, packageMappings);
|
|
49
45
|
return `/**
|
|
50
46
|
* WebSocket channel backend for '${programName}' CLI commands
|
|
51
47
|
*/
|
|
52
48
|
import { wireChannel } from '${channelTypesPath}'
|
|
49
|
+
import { pikkuMiddleware } from '${functionTypesPath}'
|
|
53
50
|
${imports}
|
|
54
51
|
|
|
52
|
+
// Middleware to close the channel after CLI command completes
|
|
53
|
+
const cliCloseOnComplete = pikkuMiddleware(async (services, { channel }, next) => {
|
|
54
|
+
const closeChannel = () => {
|
|
55
|
+
setTimeout(async () => {
|
|
56
|
+
try {
|
|
57
|
+
// This gives time for the response to be sent before closing
|
|
58
|
+
await channel?.close()
|
|
59
|
+
} catch (err) {
|
|
60
|
+
// Ignore errors on close
|
|
61
|
+
}
|
|
62
|
+
}, 200)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const result = await next()
|
|
67
|
+
closeChannel()
|
|
68
|
+
return result
|
|
69
|
+
} catch (error) {
|
|
70
|
+
closeChannel()
|
|
71
|
+
throw error
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
55
75
|
wireChannel({
|
|
56
76
|
name: '${finalChannelName}',
|
|
57
77
|
route: '${finalChannelRoute}',
|
|
58
78
|
auth: false,
|
|
59
79
|
onMessageWiring: {
|
|
60
80
|
command: {
|
|
61
|
-
${
|
|
81
|
+
${Object.entries(commandMap)
|
|
82
|
+
.map(([commandKey, { pikkuFuncName }]) => ` '${commandKey}': {
|
|
83
|
+
func: ${pikkuFuncName},
|
|
84
|
+
middleware: [cliCloseOnComplete],
|
|
85
|
+
}`)
|
|
86
|
+
.join(',\n')}
|
|
62
87
|
}
|
|
63
88
|
},
|
|
64
89
|
tags: ['cli', '${programName}']
|
|
@@ -24,6 +24,28 @@ ${userSessionTypeName !== 'Session' ? `type Session = ${userSessionTypeName}` :
|
|
|
24
24
|
*/
|
|
25
25
|
type PikkuCLIRender<Data, RequiredServices extends SingletonServices = SingletonServices> = CorePikkuCLIRender<Data, RequiredServices, Session>
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Creates a type-safe CLI renderer with access to your application's singleton services.
|
|
29
|
+
* The renderer receives the full singleton services and output data to format and display results.
|
|
30
|
+
*
|
|
31
|
+
* @template Data - The output data type from the CLI command
|
|
32
|
+
* @template RequiredServices - The minimum services required for type checking (defaults to SingletonServices)
|
|
33
|
+
* @param render - Function that receives singleton services and data to render output
|
|
34
|
+
* @returns A CLI renderer configuration
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* \`\`\`typescript
|
|
38
|
+
* const myRenderer = pikkuCLIRender<MyData>(({ logger }, data) => {
|
|
39
|
+
* logger.info(data.message)
|
|
40
|
+
* })
|
|
41
|
+
* \`\`\`
|
|
42
|
+
*/
|
|
43
|
+
export const pikkuCLIRender = <Data, RequiredServices extends SingletonServices = SingletonServices>(
|
|
44
|
+
render: (services: SingletonServices, data: Data) => void | Promise<void>
|
|
45
|
+
): PikkuCLIRender<Data, RequiredServices> => {
|
|
46
|
+
return render as any
|
|
47
|
+
}
|
|
48
|
+
|
|
27
49
|
/**
|
|
28
50
|
* CLI command configuration with project-specific types.
|
|
29
51
|
* Uses CoreCLICommandConfig from @pikku/core with local middleware and render types.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const serializeServicesMap: (requiredServices: Set<string>, forceRequiredServices: string[] | undefined, servicesImport: string, sessionServicesImport: string) => string;
|
|
1
|
+
export declare const serializeServicesMap: (allSingletonServices: string[], allSessionServices: string[], requiredServices: Set<string>, forceRequiredServices: string[] | undefined, servicesImport: string, sessionServicesImport: string) => string;
|
|
2
2
|
export declare const pikkuServices: any;
|
|
@@ -3,7 +3,7 @@ import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
|
3
3
|
import { checkRequiredTypes } from '../../../utils/check-required-types.js';
|
|
4
4
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
5
5
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
6
|
-
export const serializeServicesMap = (requiredServices, forceRequiredServices = [], servicesImport, sessionServicesImport) => {
|
|
6
|
+
export const serializeServicesMap = (allSingletonServices, allSessionServices, requiredServices, forceRequiredServices = [], servicesImport, sessionServicesImport) => {
|
|
7
7
|
// Use pre-aggregated services from inspector state
|
|
8
8
|
// This includes services from:
|
|
9
9
|
// - Wired functions (HTTP, channels, queues, schedulers, MCP, CLI, RPC)
|
|
@@ -11,45 +11,73 @@ export const serializeServicesMap = (requiredServices, forceRequiredServices = [
|
|
|
11
11
|
// - Permissions used by wired functions
|
|
12
12
|
// - Session factories
|
|
13
13
|
const usedServices = new Set(requiredServices);
|
|
14
|
-
// Internal services that are created internally
|
|
15
|
-
|
|
14
|
+
// Internal services that are created internally by the framework (PikkuInteraction)
|
|
15
|
+
// These should not appear in the services maps
|
|
16
|
+
const internalServices = new Set([
|
|
17
|
+
'rpc',
|
|
18
|
+
'mcp',
|
|
19
|
+
'channel',
|
|
20
|
+
'userSession',
|
|
21
|
+
'cli',
|
|
22
|
+
'http',
|
|
23
|
+
'queue',
|
|
24
|
+
'scheduledTask',
|
|
25
|
+
]);
|
|
16
26
|
// Add force-required services that might not be detected from function inspection
|
|
17
27
|
forceRequiredServices.forEach((service) => {
|
|
18
28
|
if (!internalServices.has(service)) {
|
|
19
29
|
usedServices.add(service);
|
|
20
30
|
}
|
|
21
31
|
});
|
|
22
|
-
// Create a map of services with true for all needed services
|
|
23
|
-
const servicesMap = Object.fromEntries(Array.from(usedServices)
|
|
24
|
-
.sort()
|
|
25
|
-
.map((service) => [service, true]));
|
|
26
|
-
// Generate the TypeScript code
|
|
27
|
-
const serviceKeys = Object.keys(servicesMap).sort();
|
|
28
32
|
// Services that are always required internally by the framework
|
|
29
33
|
const defaultServices = ['config', 'logger', 'variables', 'schema'];
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
//
|
|
34
|
+
defaultServices.forEach((service) => usedServices.add(service));
|
|
35
|
+
// Create singleton services map: all singleton services with true/false based on usage
|
|
36
|
+
const singletonServicesMap = {};
|
|
37
|
+
allSingletonServices.forEach((service) => {
|
|
38
|
+
singletonServicesMap[service] = usedServices.has(service);
|
|
39
|
+
});
|
|
40
|
+
// Create session services map: all session services with true/false based on usage
|
|
41
|
+
// Exclude internal framework services (PikkuInteraction)
|
|
42
|
+
const sessionServicesMap = {};
|
|
43
|
+
allSessionServices.forEach((service) => {
|
|
44
|
+
if (!internalServices.has(service)) {
|
|
45
|
+
sessionServicesMap[service] = usedServices.has(service);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// Get all required service names (those marked as true)
|
|
49
|
+
const requiredSingletonServiceNames = Object.keys(singletonServicesMap)
|
|
50
|
+
.filter((key) => singletonServicesMap[key])
|
|
51
|
+
.sort();
|
|
52
|
+
const requiredSessionServiceNames = Object.keys(sessionServicesMap)
|
|
53
|
+
.filter((key) => sessionServicesMap[key])
|
|
54
|
+
.sort();
|
|
37
55
|
const code = [
|
|
38
56
|
servicesImport,
|
|
39
57
|
sessionServicesImport,
|
|
40
|
-
"import type { PikkuInteraction } from '@pikku/core'",
|
|
41
58
|
'',
|
|
42
|
-
'
|
|
43
|
-
|
|
59
|
+
'// Singleton services map: true if required, false if available but unused',
|
|
60
|
+
'export const requiredSingletonServices = {',
|
|
61
|
+
...Object.keys(singletonServicesMap)
|
|
62
|
+
.sort()
|
|
63
|
+
.map((service) => ` '${service}': ${singletonServicesMap[service]},`),
|
|
64
|
+
'} as const',
|
|
65
|
+
'',
|
|
66
|
+
'// Session services map: true if required, false if available but unused',
|
|
67
|
+
'export const requiredSessionServices = {',
|
|
68
|
+
...Object.keys(sessionServicesMap)
|
|
69
|
+
.sort()
|
|
70
|
+
.map((service) => ` '${service}': ${sessionServicesMap[service]},`),
|
|
44
71
|
'} as const',
|
|
45
72
|
'',
|
|
46
|
-
'//
|
|
47
|
-
|
|
48
|
-
|
|
73
|
+
'// Type exports',
|
|
74
|
+
requiredSingletonServiceNames.length > 0
|
|
75
|
+
? `export type RequiredSingletonServices = Pick<SingletonServices, ${requiredSingletonServiceNames.map((key) => `'${key}'`).join(' | ')}> & Partial<Omit<SingletonServices, ${requiredSingletonServiceNames.map((key) => `'${key}'`).join(' | ')}>>`
|
|
76
|
+
: 'export type RequiredSingletonServices = Partial<SingletonServices>',
|
|
49
77
|
'',
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
78
|
+
requiredSessionServiceNames.length > 0
|
|
79
|
+
? `export type RequiredSessionServices = Pick<Services, ${requiredSessionServiceNames.map((key) => `'${key}'`).join(' | ')}> & Partial<Omit<Services, ${requiredSessionServiceNames.map((key) => `'${key}'`).join(' | ')}>>`
|
|
80
|
+
: 'export type RequiredSessionServices = Partial<Services>',
|
|
53
81
|
'',
|
|
54
82
|
].join('\n');
|
|
55
83
|
return code;
|
|
@@ -68,7 +96,7 @@ export const pikkuServices = pikkuSessionlessFunc({
|
|
|
68
96
|
}
|
|
69
97
|
const servicesImport = `import type { ${singletonServicesType.type} } from '${getFileImportRelativePath(config.typesDeclarationFile, singletonServicesType.typePath, config.packageMappings)}'`;
|
|
70
98
|
const sessionServicesImport = `import type { ${sessionServicesType.type} } from '${getFileImportRelativePath(config.typesDeclarationFile, sessionServicesType.typePath, config.packageMappings)}'`;
|
|
71
|
-
const servicesCode = serializeServicesMap(visitState.serviceAggregation.requiredServices, config.forceRequiredServices, servicesImport, sessionServicesImport);
|
|
99
|
+
const servicesCode = serializeServicesMap(visitState.serviceAggregation.allSingletonServices, visitState.serviceAggregation.allSessionServices, visitState.serviceAggregation.requiredServices, config.forceRequiredServices, servicesImport, sessionServicesImport);
|
|
72
100
|
await writeFileInDir(logger, config.servicesFile, servicesCode);
|
|
73
101
|
},
|
|
74
102
|
middleware: [
|
|
@@ -7,8 +7,8 @@ import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-
|
|
|
7
7
|
export const pikkuSchemas = pikkuSessionlessFunc({
|
|
8
8
|
func: async ({ logger, config, getInspectorState }) => {
|
|
9
9
|
const visitState = await getInspectorState();
|
|
10
|
-
const schemas = await generateSchemas(logger, config.tsconfig, visitState.functions.typesMap, visitState.functions.meta, visitState.http.meta, config.schemasFromTypes);
|
|
11
|
-
await saveSchemas(logger, config.schemaDirectory, schemas, visitState.functions.typesMap, visitState.functions.meta, config.
|
|
10
|
+
const schemas = await generateSchemas(logger, config.tsconfig, visitState.functions.typesMap, visitState.functions.meta, visitState.http.meta, config.schemasFromTypes, config.schema?.additionalProperties);
|
|
11
|
+
await saveSchemas(logger, config.schemaDirectory, schemas, visitState.functions.typesMap, visitState.functions.meta, config.schemasFromTypes, config.schema?.supportsImportAttributes);
|
|
12
12
|
return true;
|
|
13
13
|
},
|
|
14
14
|
middleware: [
|
|
@@ -16,7 +16,7 @@ export const pikkuOpenAPI = pikkuSessionlessFunc({
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
const { http, functions } = await getInspectorState();
|
|
19
|
-
const schemas = await generateSchemas(logger, tsconfig, functions.typesMap, functions.meta, http.meta, schemasFromTypes);
|
|
19
|
+
const schemas = await generateSchemas(logger, tsconfig, functions.typesMap, functions.meta, http.meta, schemasFromTypes, config.schema?.additionalProperties);
|
|
20
20
|
const openAPISpec = await generateOpenAPISpec(logger, functions.meta, http.meta, schemas, openAPI.additionalInfo);
|
|
21
21
|
if (openAPI.outputFile.endsWith('.json')) {
|
|
22
22
|
await writeFileInDir(logger, openAPI.outputFile, JSON.stringify(openAPISpec, null, 2), { ignoreModifyComment: true });
|
|
@@ -9,20 +9,13 @@ export const pikkuMiddleware = pikkuSessionlessFunc({
|
|
|
9
9
|
const { middleware } = state;
|
|
10
10
|
const { middlewareFile, packageMappings } = config;
|
|
11
11
|
let filesGenerated = false;
|
|
12
|
-
// Check if there are any middleware
|
|
13
|
-
const hasHTTPFactories = Array.from(state.http.routeMiddleware.values()).some((meta) => meta.exportName && meta.isFactory);
|
|
14
|
-
const hasTagFactories = Array.from(state.middleware.tagMiddleware.values()).some((meta) => meta.exportName && meta.isFactory);
|
|
15
|
-
const hasFactories = hasHTTPFactories || hasTagFactories;
|
|
16
|
-
// Generate middleware imports file if there are factories
|
|
17
|
-
if (hasFactories) {
|
|
18
|
-
await writeFileInDir(logger, middlewareFile, serializeMiddlewareImports(middlewareFile, middleware, state.http, packageMappings));
|
|
19
|
-
filesGenerated = true;
|
|
20
|
-
}
|
|
21
|
-
// Generate middleware groups metadata file
|
|
12
|
+
// Check if there are any middleware groups
|
|
22
13
|
const hasHTTPGroups = state.http.routeMiddleware.size > 0;
|
|
23
14
|
const hasTagGroups = state.middleware.tagMiddleware.size > 0;
|
|
24
15
|
if (hasHTTPGroups || hasTagGroups) {
|
|
25
16
|
await writeFileInDir(logger, config.middlewareGroupsMetaFile, serializeMiddlewareGroupsMeta(state));
|
|
17
|
+
// Always generate middleware imports file when groups exist (even if empty)
|
|
18
|
+
await writeFileInDir(logger, middlewareFile, serializeMiddlewareImports(middlewareFile, middleware, state.http, packageMappings));
|
|
26
19
|
filesGenerated = true;
|
|
27
20
|
}
|
|
28
21
|
return filesGenerated;
|
|
@@ -8,7 +8,15 @@ export const pikkuQueue = pikkuSessionlessFunc({
|
|
|
8
8
|
const visitState = await getInspectorState();
|
|
9
9
|
const { queueWorkersWiringFile, queueWorkersWiringMetaFile, packageMappings, } = config;
|
|
10
10
|
const { queueWorkers } = visitState;
|
|
11
|
-
|
|
11
|
+
// Add remote RPC worker to queue metadata if it exists
|
|
12
|
+
const queueMeta = { ...queueWorkers.meta };
|
|
13
|
+
if (config.rpc?.remoteRpcWorkersPath) {
|
|
14
|
+
queueMeta['pikku-remote-internal-rpc'] = {
|
|
15
|
+
pikkuFuncName: 'pikkuRemoteInternalRPC',
|
|
16
|
+
queueName: 'pikku-remote-internal-rpc',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
await writeFileInDir(logger, queueWorkersWiringMetaFile, serializeQueueMeta(queueMeta));
|
|
12
20
|
await writeFileInDir(logger, queueWorkersWiringFile, serializeFileImports('addQueueWorkers', queueWorkersWiringFile, queueWorkers.files, packageMappings));
|
|
13
21
|
return true;
|
|
14
22
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { QueueWorkersMeta } from '@pikku/core/queue';
|
|
2
2
|
import { TypesMap } from '@pikku/inspector';
|
|
3
3
|
import { FunctionsMeta } from '@pikku/core';
|
|
4
|
-
export declare const serializeQueueMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, queueWorkersMeta:
|
|
4
|
+
export declare const serializeQueueMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, queueWorkersMeta: QueueWorkersMeta) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const serializeQueueMeta: (queueWorkersMeta:
|
|
1
|
+
import { QueueWorkersMeta } from '@pikku/core/queue';
|
|
2
|
+
export declare const serializeQueueMeta: (queueWorkersMeta: QueueWorkersMeta) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuPublicRPC: any;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { pikkuSessionlessFunc } from '../../../../.pikku/pikku-types.gen.js';
|
|
2
|
+
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
|
+
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
|
+
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { serializePublicRPC } from './serialize-public-rpc.js';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
export const pikkuPublicRPC = pikkuSessionlessFunc({
|
|
8
|
+
func: async ({ logger, config }) => {
|
|
9
|
+
if (config.rpc?.publicRpcPath) {
|
|
10
|
+
const publicRpcPath = join(config.rootDir, config.rpc.publicRpcPath);
|
|
11
|
+
const pathToPikkuTypes = getFileImportRelativePath(publicRpcPath, config.typesDeclarationFile, config.packageMappings);
|
|
12
|
+
await writeFileInDir(logger, publicRpcPath, serializePublicRPC(pathToPikkuTypes));
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
},
|
|
17
|
+
middleware: [
|
|
18
|
+
logCommandInfoAndTime({
|
|
19
|
+
commandStart: 'Generating Public RPC Endpoint',
|
|
20
|
+
commandEnd: 'Generated Public RPC Endpoint',
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
23
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuRemoteRPC: any;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { pikkuSessionlessFunc } from '../../../../.pikku/pikku-types.gen.js';
|
|
2
|
+
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
3
|
+
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
|
+
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
|
+
import { serializeRemoteRPC } from './serialize-remote-rpc.js';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
export const pikkuRemoteRPC = pikkuSessionlessFunc({
|
|
8
|
+
func: async ({ logger, config }) => {
|
|
9
|
+
if (config.rpc?.remoteRpcWorkersPath) {
|
|
10
|
+
const remoteRpcPath = join(config.rootDir, config.rpc.remoteRpcWorkersPath);
|
|
11
|
+
const pathToPikkuTypes = getFileImportRelativePath(remoteRpcPath, config.typesDeclarationFile, config.packageMappings);
|
|
12
|
+
await writeFileInDir(logger, remoteRpcPath, serializeRemoteRPC(pathToPikkuTypes));
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
},
|
|
17
|
+
middleware: [
|
|
18
|
+
logCommandInfoAndTime({
|
|
19
|
+
commandStart: 'Generating Remote RPC Workers',
|
|
20
|
+
commandEnd: 'Generated Remote RPC Workers',
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
23
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate public RPC HTTP endpoint
|
|
3
|
+
*/
|
|
4
|
+
export const serializePublicRPC = (pathToPikkuTypes) => {
|
|
5
|
+
return `/**
|
|
6
|
+
* Auto-generated public RPC HTTP endpoint
|
|
7
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
8
|
+
*/
|
|
9
|
+
import { pikkuSessionlessFunc, wireHTTP } from '${pathToPikkuTypes}'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Public RPC endpoint that invokes any exposed RPC by name
|
|
13
|
+
* This is used for public HTTP access to exposed server functions
|
|
14
|
+
*/
|
|
15
|
+
export const rpcCaller = pikkuSessionlessFunc<
|
|
16
|
+
{ name: string, data?: any },
|
|
17
|
+
any
|
|
18
|
+
>({
|
|
19
|
+
func: async ({ rpc }, { name, data }) => {
|
|
20
|
+
return await (rpc.invokeExposed as any)(name, data)
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
wireHTTP({
|
|
25
|
+
route: '/rpc',
|
|
26
|
+
method: 'post',
|
|
27
|
+
func: rpcCaller,
|
|
28
|
+
})
|
|
29
|
+
`;
|
|
30
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate remote internal RPC queue worker and HTTP endpoint
|
|
3
|
+
*/
|
|
4
|
+
export const serializeRemoteRPC = (pathToPikkuTypes) => {
|
|
5
|
+
return `/**
|
|
6
|
+
* Auto-generated remote internal RPC queue worker and HTTP endpoint
|
|
7
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
8
|
+
*/
|
|
9
|
+
import { pikkuSessionlessFunc, wireQueueWorker } from '${pathToPikkuTypes}'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Generic remote RPC worker that invokes any internal RPC by name
|
|
13
|
+
* This is used for executing internal RPCs via a queue or HTTP (e.g., scheduled tasks, background jobs, internal services)
|
|
14
|
+
*/
|
|
15
|
+
export const pikkuRemoteInternalRPC = pikkuSessionlessFunc<
|
|
16
|
+
{ rpcName: string, data?: any },
|
|
17
|
+
any
|
|
18
|
+
>({
|
|
19
|
+
func: async ({ rpc }, { rpcName, data }) => {
|
|
20
|
+
return await (rpc.invoke as any)(rpcName, data)
|
|
21
|
+
},
|
|
22
|
+
internal: true,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
wireQueueWorker({
|
|
26
|
+
queueName: 'pikku-remote-internal-rpc',
|
|
27
|
+
func: pikkuRemoteInternalRPC,
|
|
28
|
+
})
|
|
29
|
+
`;
|
|
30
|
+
};
|
|
@@ -53,13 +53,13 @@ export class PikkuRPC {
|
|
|
53
53
|
* Invokes a remote procedure call on the server.
|
|
54
54
|
* This is a generic method that routes to the appropriate server function
|
|
55
55
|
* based on the function name and passes the provided data.
|
|
56
|
-
*
|
|
56
|
+
*
|
|
57
57
|
* @param name - The name of the server function to invoke
|
|
58
58
|
* @param data - The data to pass to the server function
|
|
59
59
|
* @returns A promise that resolves with the function's return value
|
|
60
60
|
*/
|
|
61
61
|
invoke: RPCInvoke = async (name, data) => {
|
|
62
|
-
return await this.pikkuFetch.post('/rpc', { name, data })
|
|
62
|
+
return await this.pikkuFetch.post('/rpc' as any, { name, data }) as any
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|