@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.
Files changed (214) hide show
  1. package/.pikku/channel/pikku-channel-types.gen.ts +4 -3
  2. package/.pikku/channel/pikku-channels-map.gen.d.ts +5 -2
  3. package/.pikku/channel/pikku-channels-meta.gen.ts +1 -1
  4. package/.pikku/channel/pikku-channels.gen.ts +1 -1
  5. package/.pikku/cli/pikku-cli-types.gen.ts +23 -1
  6. package/.pikku/cli/pikku-cli-wirings-meta.gen.ts +8 -116
  7. package/.pikku/cli/pikku-cli-wirings.gen.ts +2 -3
  8. package/.pikku/function/pikku-function-types.gen.ts +1 -1
  9. package/.pikku/function/pikku-functions-meta.gen.ts +265 -138
  10. package/.pikku/function/pikku-functions-meta.min.gen.ts +62 -32
  11. package/.pikku/function/pikku-functions.gen.ts +9 -1
  12. package/.pikku/http/pikku-http-types.gen.ts +1 -1
  13. package/.pikku/http/pikku-http-wirings-map.gen.d.ts +5 -2
  14. package/.pikku/http/pikku-http-wirings-meta.gen.ts +1 -1
  15. package/.pikku/http/pikku-http-wirings.gen.ts +1 -1
  16. package/.pikku/mcp/pikku-mcp-types.gen.ts +1 -1
  17. package/.pikku/mcp/pikku-mcp-wirings-meta.gen.ts +1 -1
  18. package/.pikku/mcp/pikku-mcp-wirings.gen.ts +1 -1
  19. package/.pikku/pikku-bootstrap.gen.ts +4 -1
  20. package/.pikku/pikku-services.gen.ts +21 -12
  21. package/.pikku/pikku-types.gen.ts +1 -1
  22. package/.pikku/pikku-websocket.gen.ts +15 -1
  23. package/.pikku/queue/pikku-queue-types.gen.ts +1 -1
  24. package/.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts +5 -2
  25. package/.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts +7 -2
  26. package/.pikku/queue/pikku-queue-workers-wirings.gen.ts +1 -1
  27. package/.pikku/rpc/pikku-remote-rpc-workers.gen.ts +27 -0
  28. package/.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts +13 -3
  29. package/.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +26 -10
  30. package/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts +15 -9
  31. package/.pikku/scheduler/pikku-scheduler-types.gen.ts +1 -1
  32. package/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.ts +1 -1
  33. package/.pikku/scheduler/pikku-schedulers-wirings.gen.ts +1 -1
  34. package/.pikku/schemas/register.gen.ts +17 -5
  35. package/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  36. package/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
  37. package/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
  38. package/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
  39. package/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
  40. package/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
  41. package/.pikku/workflow/pikku-workflow-map.gen.d.ts +62 -0
  42. package/.pikku/workflow/pikku-workflow-types.gen.ts +92 -0
  43. package/.pikku/workflow/pikku-workflow-wirings-meta.gen.ts +5 -0
  44. package/.pikku/workflow/pikku-workflow-wirings.gen.ts +4 -0
  45. package/CHANGELOG.md +57 -0
  46. package/bin/pikku.ts +30 -21
  47. package/cli.schema.json +1 -1
  48. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +4 -3
  49. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  50. package/dist/.pikku/channel/pikku-channels-meta.gen.js +1 -1
  51. package/dist/.pikku/channel/pikku-channels.gen.d.ts +1 -1
  52. package/dist/.pikku/channel/pikku-channels.gen.js +1 -1
  53. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +18 -1
  54. package/dist/.pikku/cli/pikku-cli-types.gen.js +20 -1
  55. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +8 -116
  56. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -2
  57. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -2
  58. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  59. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  60. package/dist/.pikku/function/pikku-functions-meta.gen.js +265 -138
  61. package/dist/.pikku/function/pikku-functions-meta.min.gen.js +62 -32
  62. package/dist/.pikku/function/pikku-functions.gen.js +9 -1
  63. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  64. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  65. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
  66. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  67. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  68. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  69. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  70. package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +1 -1
  71. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +1 -1
  72. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +1 -1
  73. package/dist/.pikku/pikku-bootstrap.gen.d.ts +4 -1
  74. package/dist/.pikku/pikku-bootstrap.gen.js +4 -1
  75. package/dist/.pikku/pikku-services.gen.d.ts +15 -6
  76. package/dist/.pikku/pikku-services.gen.js +14 -2
  77. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  78. package/dist/.pikku/pikku-types.gen.js +1 -1
  79. package/dist/.pikku/pikku-websocket.gen.d.ts +15 -1
  80. package/dist/.pikku/pikku-websocket.gen.js +15 -1
  81. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  82. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  83. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +7 -2
  84. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  85. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  86. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.d.ts +17 -0
  87. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +22 -0
  88. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +15 -9
  89. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  90. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  91. package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +1 -1
  92. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +1 -1
  93. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +1 -1
  94. package/dist/.pikku/schemas/register.gen.js +9 -3
  95. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  96. package/dist/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
  97. package/dist/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
  98. package/dist/.pikku/schemas/schemas/PikkuRemoteInternalRPCInput.schema.json +1 -0
  99. package/dist/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
  100. package/dist/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
  101. package/dist/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
  102. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +58 -0
  103. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +28 -0
  104. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +5 -0
  105. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +4 -0
  106. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +5 -0
  107. package/dist/bin/pikku.js +24 -19
  108. package/dist/src/cli.wiring.js +107 -99
  109. package/dist/src/functions/commands/all.js +51 -2
  110. package/dist/src/functions/commands/bootstrap.d.ts +1 -0
  111. package/dist/src/functions/commands/bootstrap.js +24 -0
  112. package/dist/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.js +46 -2
  113. package/dist/src/functions/wirings/channels/serialize-channel-types.js +3 -2
  114. package/dist/src/functions/wirings/channels/serialize-websocket-wrapper.js +14 -0
  115. package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +4 -4
  116. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +20 -7
  117. package/dist/src/functions/wirings/cli/serialize-channel-cli.js +32 -7
  118. package/dist/src/functions/wirings/cli/serialize-cli-types.js +22 -0
  119. package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
  120. package/dist/src/functions/wirings/functions/pikku-command-services.js +54 -26
  121. package/dist/src/functions/wirings/functions/schemas.js +2 -2
  122. package/dist/src/functions/wirings/http/pikku-command-openapi.js +1 -1
  123. package/dist/src/functions/wirings/middleware/pikku-command-middleware.js +3 -10
  124. package/dist/src/functions/wirings/queue/pikku-queue.js +9 -1
  125. package/dist/src/functions/wirings/queue/serialize-queue-map.d.ts +2 -2
  126. package/dist/src/functions/wirings/queue/serialize-queue-meta.d.ts +2 -2
  127. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -0
  128. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +23 -0
  129. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -0
  130. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.js +23 -0
  131. package/dist/src/functions/wirings/rpc/serialize-public-rpc.d.ts +4 -0
  132. package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +30 -0
  133. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.d.ts +4 -0
  134. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +30 -0
  135. package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +2 -2
  136. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +27 -3
  137. package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.d.ts +1 -0
  138. package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.js +12 -0
  139. package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.d.ts +1 -0
  140. package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.js +11 -0
  141. package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -0
  142. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +55 -0
  143. package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +4 -0
  144. package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +79 -0
  145. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.d.ts +2 -0
  146. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +10 -0
  147. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +4 -0
  148. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +95 -0
  149. package/dist/src/functions/wirings/workflow/serialize-workflow-workers.d.ts +4 -0
  150. package/dist/src/functions/wirings/workflow/serialize-workflow-workers.js +60 -0
  151. package/dist/src/middleware/log-command-info-and-time.d.ts +1 -1
  152. package/dist/src/middleware/log-command-info-and-time.js +8 -5
  153. package/dist/src/services/cli-logger-forwarder.service.js +1 -1
  154. package/dist/src/services/cli-logger.service.d.ts +7 -2
  155. package/dist/src/services/cli-logger.service.js +17 -5
  156. package/dist/src/services.js +77 -12
  157. package/dist/src/utils/command-summary.d.ts +44 -0
  158. package/dist/src/utils/command-summary.js +74 -0
  159. package/dist/src/utils/file-writer.js +2 -2
  160. package/dist/src/utils/pikku-cli-config.js +48 -0
  161. package/dist/src/utils/schema-generator.d.ts +2 -2
  162. package/dist/src/utils/schema-generator.js +31 -10
  163. package/dist/tsconfig.tsbuildinfo +1 -1
  164. package/package.json +3 -4
  165. package/pikku.config.json +5 -2
  166. package/src/cli.wiring.ts +106 -101
  167. package/src/functions/commands/all.ts +66 -2
  168. package/src/functions/commands/bootstrap.ts +28 -0
  169. package/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts +46 -2
  170. package/src/functions/wirings/channels/serialize-channel-types.ts +3 -2
  171. package/src/functions/wirings/channels/serialize-websocket-wrapper.ts +14 -0
  172. package/src/functions/wirings/cli/pikku-command-cli-entry.ts +4 -4
  173. package/src/functions/wirings/cli/serialize-channel-cli-client.ts +20 -7
  174. package/src/functions/wirings/cli/serialize-channel-cli.ts +40 -8
  175. package/src/functions/wirings/cli/serialize-cli-types.ts +22 -0
  176. package/src/functions/wirings/functions/pikku-command-services.ts +57 -28
  177. package/src/functions/wirings/functions/schemas.ts +4 -3
  178. package/src/functions/wirings/http/pikku-command-openapi.ts +2 -1
  179. package/src/functions/wirings/middleware/pikku-command-middleware.ts +11 -22
  180. package/src/functions/wirings/queue/pikku-queue.ts +10 -1
  181. package/src/functions/wirings/queue/serialize-queue-map.ts +3 -3
  182. package/src/functions/wirings/queue/serialize-queue-meta.ts +2 -2
  183. package/src/functions/wirings/rpc/pikku-command-public-rpc.ts +32 -0
  184. package/src/functions/wirings/rpc/pikku-command-remote-rpc.ts +35 -0
  185. package/src/functions/wirings/rpc/serialize-public-rpc.ts +30 -0
  186. package/src/functions/wirings/rpc/serialize-remote-rpc.ts +30 -0
  187. package/src/functions/wirings/rpc/serialize-rpc-wrapper.ts +2 -2
  188. package/src/functions/wirings/rpc/serialize-typed-rpc-map.ts +26 -3
  189. package/src/functions/wirings/workflow/pikku-command-workflow-map.ts +24 -0
  190. package/src/functions/wirings/workflow/pikku-command-workflow-types.ts +22 -0
  191. package/src/functions/wirings/workflow/pikku-command-workflow.ts +123 -0
  192. package/src/functions/wirings/workflow/serialize-workflow-map.ts +123 -0
  193. package/src/functions/wirings/workflow/serialize-workflow-meta.ts +16 -0
  194. package/src/functions/wirings/workflow/serialize-workflow-types.ts +95 -0
  195. package/src/functions/wirings/workflow/serialize-workflow-workers.ts +60 -0
  196. package/src/middleware/log-command-info-and-time.ts +8 -5
  197. package/src/services/cli-logger-forwarder.service.ts +1 -1
  198. package/src/services/cli-logger.service.ts +21 -6
  199. package/src/services.ts +86 -11
  200. package/src/utils/command-summary.ts +103 -0
  201. package/src/utils/file-writer.ts +2 -2
  202. package/src/utils/pikku-cli-config.ts +68 -0
  203. package/src/utils/schema-generator.ts +30 -11
  204. package/types/application-types.d.ts +5 -1
  205. package/types/config.d.ts +61 -6
  206. package/.pikku/cli/pikku-cli-channel.gen.ts +0 -34
  207. package/.pikku/cli/pikku-cli-client.gen.ts +0 -43
  208. package/.pikku/cli/pikku-cli.gen.ts +0 -41
  209. package/dist/.pikku/cli/pikku-cli-channel.gen.js +0 -33
  210. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +0 -10
  211. package/dist/.pikku/cli/pikku-cli-client.gen.js +0 -34
  212. package/dist/.pikku/cli/pikku-cli.gen.d.ts +0 -10
  213. package/dist/.pikku/cli/pikku-cli.gen.js +0 -38
  214. /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
- ? 'cli'
39
- : entrypointConfig.type || 'cli';
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 === 'cli'
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
- url: string,
102
+ ws: WebSocket,
103
103
  args?: string[]
104
104
  ): Promise<void> {
105
- // Create WebSocket connection
106
- const pikkuWS = new CorePikkuWebsocket(url)
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:3000${finalChannelRoute}'
125
- ${capitalizedName}CLIClient(url, process.argv.slice(2)).catch(error => {
126
- console.error('Fatal error:', error.message)
127
- process.exit(1)
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
- ${commandEntries}
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 and not via the create service script
15
- const internalServices = new Set(['rpc', 'mcp', 'channel', 'userSession']);
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
- // Combine default services with detected services
31
- const allRequiredServices = [
32
- ...new Set([...defaultServices, ...serviceKeys]),
33
- ].sort();
34
- // For RequiredSingletonServices, we need to pick from the actual SingletonServices interface
35
- // This will be resolved at compile time based on what's actually in the SingletonServices interface
36
- // We don't need to hardcode which services are singletons beyond the core framework ones
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
- 'export const singletonServices = {',
43
- ...Object.keys(servicesMap).map((service) => ` '${service}': true,`),
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
- '// Singleton services (created once at startup)',
47
- '// Only includes services that are both required and available in SingletonServices',
48
- `export type RequiredSingletonServices = Pick<SingletonServices, Extract<keyof SingletonServices, ${allRequiredServices.map((key) => `'${key}'`).join(' | ')}>> & Partial<Omit<SingletonServices, ${allRequiredServices.map((key) => `'${key}'`).join(' | ')}>>`,
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
- '// Session services (created per request, can access singleton services)',
51
- '// Omits singleton services and PikkuInteraction (mcp, rpc, http, channel)',
52
- `export type RequiredSessionServices = Omit<Services, keyof SingletonServices | keyof PikkuInteraction>`,
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.supportsImportAttributes, config.schemasFromTypes);
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 group factories
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
- await writeFileInDir(logger, queueWorkersWiringMetaFile, serializeQueueMeta(queueWorkers.meta));
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 { queueWorkersMeta } from '@pikku/core/queue';
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: queueWorkersMeta) => string;
4
+ export declare const serializeQueueMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, queueWorkersMeta: QueueWorkersMeta) => string;
@@ -1,2 +1,2 @@
1
- import { queueWorkersMeta } from '@pikku/core/queue';
2
- export declare const serializeQueueMeta: (queueWorkersMeta: queueWorkersMeta) => string;
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,4 @@
1
+ /**
2
+ * Generate public RPC HTTP endpoint
3
+ */
4
+ export declare const serializePublicRPC: (pathToPikkuTypes: string) => string;
@@ -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,4 @@
1
+ /**
2
+ * Generate remote internal RPC queue worker and HTTP endpoint
3
+ */
4
+ export declare const serializeRemoteRPC: (pathToPikkuTypes: string) => string;
@@ -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