@pikku/cli 0.12.90 → 0.12.92

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 (264) hide show
  1. package/LICENSE +106 -0
  2. package/README.md +25 -2
  3. package/console-app/assets/{index-CSzCJzBb.css → index-D0HG8q0B.css} +1 -1
  4. package/console-app/assets/{index-C5Bd44e4.js → index-DDpIMCpy.js} +149 -149
  5. package/console-app/index.html +2 -2
  6. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  7. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  8. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
  10. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  11. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  12. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +15 -0
  15. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  16. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  17. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  18. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +43 -0
  19. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  20. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  21. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  22. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  23. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  24. package/dist/.pikku/function/pikku-function-types.gen.d.ts +4 -4
  25. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  26. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  27. package/dist/.pikku/function/pikku-functions-meta.gen.json +39 -44
  28. package/dist/.pikku/function/pikku-functions.gen.js +1 -3
  29. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  30. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  31. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  32. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  33. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +9 -0
  34. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +9 -0
  35. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  36. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  37. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  38. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  39. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  40. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  41. package/dist/.pikku/pikku-types.gen.js +1 -1
  42. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  43. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  44. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  45. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  46. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  47. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  48. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
  49. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.d.ts +1 -0
  50. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +10 -0
  51. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.json +1 -0
  52. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +4 -0
  53. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.js +1 -0
  54. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.d.ts +1 -0
  55. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +10 -0
  56. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +4 -0
  57. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.js +1 -0
  58. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +4 -0
  59. package/dist/.pikku/scenarios/schemas/register.gen.js +4 -0
  60. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  61. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  62. package/dist/.pikku/schemas/register.gen.js +5 -3
  63. package/dist/.pikku/schemas/schemas/FabricSecretsListOutput.schema.json +1 -1
  64. package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -0
  65. package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -0
  66. package/dist/.pikku/schemas/schemas/FabricSecretsSetOutput.schema.json +1 -1
  67. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  68. package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +1 -1
  69. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  70. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  71. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  72. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  73. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  74. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  75. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  76. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  77. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  78. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  79. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  80. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  81. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  82. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +2 -8
  83. package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +19 -0
  84. package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +17 -0
  85. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +152 -3
  86. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +39 -1
  87. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  88. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  89. package/dist/bin/pikku-bin.mjs +2 -2
  90. package/dist/src/cli.wiring.js +28 -0
  91. package/dist/src/deploy/analyzer/analyzer.js +22 -5
  92. package/dist/src/deploy/build-pipeline.js +5 -1
  93. package/dist/src/fabric/fabric-commands.d.ts +37 -9
  94. package/dist/src/fabric/fabric-commands.js +12 -0
  95. package/dist/src/fabric/functions/domains-add.function.d.ts +4 -4
  96. package/dist/src/fabric/functions/secrets-list.function.d.ts +16 -4
  97. package/dist/src/fabric/functions/secrets-list.function.js +12 -10
  98. package/dist/src/fabric/functions/secrets-rotate.function.d.ts +24 -0
  99. package/dist/src/fabric/functions/secrets-rotate.function.js +36 -0
  100. package/dist/src/fabric/functions/secrets-set.function.d.ts +8 -4
  101. package/dist/src/fabric/functions/secrets-set.function.js +18 -7
  102. package/dist/src/fabric/lib/http.d.ts +7 -1
  103. package/dist/src/fabric/lib/sealed-box.d.ts +16 -0
  104. package/dist/src/fabric/lib/sealed-box.js +72 -0
  105. package/dist/src/functions/commands/dev.js +11 -0
  106. package/dist/src/functions/commands/load-user-project.d.ts +7 -0
  107. package/dist/src/functions/commands/load-user-project.js +21 -0
  108. package/dist/src/functions/commands/pikku-command-bootstrap.js +13 -0
  109. package/dist/src/functions/commands/scenario-browser.d.ts +84 -0
  110. package/dist/src/functions/commands/scenario-browser.js +68 -0
  111. package/dist/src/functions/commands/scenario-environment.d.ts +32 -0
  112. package/dist/src/functions/commands/scenario-environment.js +61 -0
  113. package/dist/src/functions/commands/scenario-formatter.d.ts +81 -0
  114. package/dist/src/functions/commands/scenario-formatter.js +120 -0
  115. package/dist/src/functions/commands/scenario-ladder.d.ts +66 -0
  116. package/dist/src/functions/commands/scenario-ladder.js +132 -0
  117. package/dist/src/functions/commands/scenario-plan.d.ts +61 -0
  118. package/dist/src/functions/commands/scenario-plan.js +106 -0
  119. package/dist/src/functions/commands/scenario.d.ts +24 -0
  120. package/dist/src/functions/commands/scenario.js +322 -50
  121. package/dist/src/functions/commands/serve.js +2 -0
  122. package/dist/src/functions/commands/skills.js +27 -61
  123. package/dist/src/functions/db/db-codegen.d.ts +6 -0
  124. package/dist/src/functions/db/db-codegen.js +9 -0
  125. package/dist/src/functions/db/db-migrator.js +14 -0
  126. package/dist/src/functions/db/local-db.d.ts +8 -0
  127. package/dist/src/functions/db/local-db.js +24 -2
  128. package/dist/src/functions/db/migration-identifiers.d.ts +58 -0
  129. package/dist/src/functions/db/migration-identifiers.js +262 -0
  130. package/dist/src/functions/db/migration-provenance.d.ts +35 -0
  131. package/dist/src/functions/db/migration-provenance.js +80 -0
  132. package/dist/src/functions/db/schema-sql.d.ts +43 -0
  133. package/dist/src/functions/db/schema-sql.js +135 -0
  134. package/dist/src/functions/db/sqlite/sqlite-kysely.js +22 -2
  135. package/dist/src/functions/wirings/functions/pikku-command-functions.js +26 -8
  136. package/dist/src/functions/wirings/functions/schemas.js +13 -1
  137. package/dist/src/functions/wirings/functions/serialize-function-types.js +3 -3
  138. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +6 -1
  139. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +10 -0
  140. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +102 -0
  141. package/dist/src/functions/wirings/scenarios/scenario-partition.d.ts +42 -0
  142. package/dist/src/functions/wirings/scenarios/scenario-partition.js +71 -0
  143. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.d.ts +33 -0
  144. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.js +49 -0
  145. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.d.ts +14 -0
  146. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.js +29 -0
  147. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.d.ts +12 -0
  148. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +56 -0
  149. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.d.ts +7 -0
  150. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.js +40 -0
  151. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +43 -8
  152. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +1 -1
  153. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +13 -2
  154. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.d.ts +4 -0
  155. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +62 -0
  156. package/dist/src/functions/wirings/workflow/serialize-workflow-bootstrap-map.js +10 -3
  157. package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +10 -3
  158. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +4 -4
  159. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +1 -1
  160. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +232 -3
  161. package/dist/src/functions/workflows/all.workflow.js +2 -7
  162. package/dist/src/server/server-ready.d.ts +12 -0
  163. package/dist/src/server/server-ready.js +12 -0
  164. package/dist/src/server/spawn-dev-server.d.ts +50 -0
  165. package/dist/src/server/spawn-dev-server.js +112 -0
  166. package/dist/src/services.js +12 -1
  167. package/dist/src/utils/file-writer.js +14 -2
  168. package/dist/src/utils/meta-diff.js +5 -2
  169. package/dist/src/utils/pikku-cli-config.d.ts +14 -0
  170. package/dist/src/utils/pikku-cli-config.js +60 -0
  171. package/dist/src/utils/remove-legacy-scaffold-file.d.ts +14 -0
  172. package/dist/src/utils/remove-legacy-scaffold-file.js +23 -0
  173. package/dist/src/utils/resolve-scenario-actors.d.ts +23 -0
  174. package/dist/src/utils/resolve-scenario-actors.js +74 -0
  175. package/dist/src/utils/serialize-schemas.d.ts +3 -1
  176. package/dist/src/utils/serialize-schemas.js +39 -4
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/package.json +18 -8
  179. package/dist/.pikku/schemas/schemas/PikkuScenarioFunctionsOutput.schema.json +0 -1
  180. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.d.ts +0 -1
  181. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +0 -31
  182. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +0 -10
  183. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +0 -104
  184. package/skills/pikku-addon/SKILL.md +0 -243
  185. package/skills/pikku-addon/references/addon-package-manifest.md +0 -63
  186. package/skills/pikku-ai-agent/SKILL.md +0 -231
  187. package/skills/pikku-ai-vercel/SKILL.md +0 -82
  188. package/skills/pikku-ai-voice/SKILL.md +0 -88
  189. package/skills/pikku-audit/SKILL.md +0 -175
  190. package/skills/pikku-aws/SKILL.md +0 -111
  191. package/skills/pikku-backblaze/SKILL.md +0 -71
  192. package/skills/pikku-better-auth/SKILL.md +0 -298
  193. package/skills/pikku-cli/SKILL.md +0 -198
  194. package/skills/pikku-cli/references/complete-example.md +0 -82
  195. package/skills/pikku-concepts/SKILL.md +0 -250
  196. package/skills/pikku-concepts/references/concept-mapping.md +0 -556
  197. package/skills/pikku-concepts/references/packages.md +0 -29
  198. package/skills/pikku-config/SKILL.md +0 -212
  199. package/skills/pikku-cron/SKILL.md +0 -214
  200. package/skills/pikku-deploy-azure/SKILL.md +0 -71
  201. package/skills/pikku-deploy-cloudflare/SKILL.md +0 -82
  202. package/skills/pikku-deploy-express/SKILL.md +0 -86
  203. package/skills/pikku-deploy-fastify/SKILL.md +0 -73
  204. package/skills/pikku-deploy-lambda/SKILL.md +0 -110
  205. package/skills/pikku-deploy-nextjs/SKILL.md +0 -78
  206. package/skills/pikku-deploy-uws/SKILL.md +0 -88
  207. package/skills/pikku-deps/SKILL.md +0 -98
  208. package/skills/pikku-emails/SKILL.md +0 -163
  209. package/skills/pikku-fabric/SKILL.md +0 -318
  210. package/skills/pikku-fabric-debug/SKILL.md +0 -112
  211. package/skills/pikku-feature/SKILL.md +0 -258
  212. package/skills/pikku-gateway-slack/SKILL.md +0 -115
  213. package/skills/pikku-http/SKILL.md +0 -220
  214. package/skills/pikku-http/references/http-options.md +0 -55
  215. package/skills/pikku-i18n/SKILL.md +0 -137
  216. package/skills/pikku-info/SKILL.md +0 -100
  217. package/skills/pikku-jose/SKILL.md +0 -105
  218. package/skills/pikku-kysely/SKILL.md +0 -219
  219. package/skills/pikku-machine-auth/SKILL.md +0 -183
  220. package/skills/pikku-mcp/SKILL.md +0 -241
  221. package/skills/pikku-middleware/SKILL.md +0 -231
  222. package/skills/pikku-middleware/references/middleware-patterns.md +0 -61
  223. package/skills/pikku-mongodb/SKILL.md +0 -105
  224. package/skills/pikku-n8n-import/SKILL.md +0 -109
  225. package/skills/pikku-n8n-import/SPEC.md +0 -84
  226. package/skills/pikku-n8n-import/references/addon-mapping.md +0 -121
  227. package/skills/pikku-n8n-import/references/code-translation.md +0 -121
  228. package/skills/pikku-n8n-import/references/loops-and-control.md +0 -87
  229. package/skills/pikku-paraglide/SKILL.md +0 -117
  230. package/skills/pikku-permissions/SKILL.md +0 -192
  231. package/skills/pikku-pino/SKILL.md +0 -79
  232. package/skills/pikku-product-second-opinion/README.md +0 -43
  233. package/skills/pikku-product-second-opinion/SKILL.md +0 -158
  234. package/skills/pikku-product-second-opinion/example/sample-report.md +0 -90
  235. package/skills/pikku-product-second-opinion/references/report-template.md +0 -73
  236. package/skills/pikku-queue/SKILL.md +0 -240
  237. package/skills/pikku-react/SKILL.md +0 -212
  238. package/skills/pikku-react-query/SKILL.md +0 -242
  239. package/skills/pikku-realtime/SKILL.md +0 -236
  240. package/skills/pikku-realtime/references/other-routes.md +0 -23
  241. package/skills/pikku-redis/SKILL.md +0 -90
  242. package/skills/pikku-rpc/SKILL.md +0 -171
  243. package/skills/pikku-rtl/SKILL.md +0 -219
  244. package/skills/pikku-scenario/SKILL.md +0 -215
  245. package/skills/pikku-schedule/SKILL.md +0 -57
  246. package/skills/pikku-schema-ajv/SKILL.md +0 -62
  247. package/skills/pikku-schema-cfworker/SKILL.md +0 -63
  248. package/skills/pikku-security/SKILL.md +0 -108
  249. package/skills/pikku-services/SKILL.md +0 -248
  250. package/skills/pikku-services/references/audit-wire-service.md +0 -34
  251. package/skills/pikku-software-archaeology/README.md +0 -70
  252. package/skills/pikku-software-archaeology/SKILL.md +0 -186
  253. package/skills/pikku-software-archaeology/references/blueprint.schema.json +0 -625
  254. package/skills/pikku-software-archaeology/references/pikku-mapping.md +0 -49
  255. package/skills/pikku-software-archaeology/scripts/validate.mjs +0 -173
  256. package/skills/pikku-tag-middleware/SKILL.md +0 -13
  257. package/skills/pikku-template-clone/SKILL.md +0 -40
  258. package/skills/pikku-trigger/SKILL.md +0 -181
  259. package/skills/pikku-versioning/SKILL.md +0 -173
  260. package/skills/pikku-websocket/SKILL.md +0 -243
  261. package/skills/pikku-workflow/SKILL.md +0 -172
  262. package/skills/pikku-workflow/references/workflow-reference.md +0 -63
  263. package/skills/pikku-workflows-client/SKILL.md +0 -150
  264. package/skills/pikku-ws/SKILL.md +0 -47
@@ -1,556 +0,0 @@
1
- # Concept Mapping: Generic Backend → Pikku
2
-
3
- Authoritative mapping table plus side-by-side code examples showing how common backend patterns translate to Pikku.
4
-
5
- ## Quick Reference Table
6
-
7
- | Generic Backend Concept | Pikku Equivalent | Skill |
8
- | --------------------------------------- | --------------------------------------------------------------- | ----------------- |
9
- | **Controller / Route Handler** | `pikkuFunc` / `pikkuSessionlessFunc` | `pikku-concepts` |
10
- | **Route definition** (`GET /users/:id`) | `wireHTTP({ route, method, func })` | `pikku-http` |
11
- | **Middleware** (Express/Koa-style) | `pikkuMiddleware` | `pikku-security` |
12
- | **Auth Guard / Auth Middleware** | `authBearer()` / `authCookie()` / `authApiKey()` | `pikku-security` |
13
- | **Authorization / Permissions** | `pikkuPermission` / `pikkuAuth` | `pikku-security` |
14
- | **DTO / Request Validation** | Standard Schema (Zod, Valibot, ArkType) | `pikku-concepts` |
15
- | **Dependency Injection** | `pikkuServices` (singleton) + `pikkuWireServices` (per-request) | `pikku-services` |
16
- | **WebSocket handlers** | `wireChannel` | `pikku-websocket` |
17
- | **Job Queue workers** | `wireQueueWorker` | `pikku-queue` |
18
- | **Cron / Scheduled tasks** | `wireScheduler` | `pikku-cron` |
19
- | **Module / Feature grouping** | Tags + wiring files | `pikku-concepts` |
20
- | **Error handling** | Throw typed errors (`NotFoundError`, `ForbiddenError`) | `pikku-concepts` |
21
- | **Type-safe API client** | `npx pikku all` generates clients | `pikku-concepts` |
22
- | **Secrets / Config** | `wireSecret`, `wireVariable`, `services.variables` | `pikku-config` |
23
-
24
- ## Route Handler / Controller → pikkuFunc
25
-
26
- **Traditional (generic):**
27
-
28
- ```typescript
29
- // A controller method tied to HTTP
30
- class TodoController {
31
- async create(req: Request, res: Response) {
32
- const { title, priority } = req.body
33
- const todo = await this.todoService.create(title, priority)
34
- res.json({ todo })
35
- }
36
- }
37
- // Route: router.post('/todos', controller.create)
38
- ```
39
-
40
- **Pikku:**
41
-
42
- ```typescript
43
- // Function knows nothing about HTTP.
44
- // input/output are Zod schemas; the data + return types are inferred from them.
45
- const createTodo = pikkuSessionlessFunc({
46
- input: CreateTodoInput,
47
- output: TodoOutput,
48
- func: async ({ todoStore, logger }, { title, priority }) => {
49
- const todo = todoStore.createTodo(title, priority)
50
- logger.info(`Created todo: ${todo.id}`)
51
- return { todo }
52
- },
53
- })
54
-
55
- // Wiring (separate file) - grouped with defineHTTPRoutes
56
- export const todoRoutes = defineHTTPRoutes({
57
- basePath: '/todos',
58
- tags: ['todos'],
59
- auth: false,
60
- routes: {
61
- create: { method: 'post', route: '', func: createTodo },
62
- list: { method: 'get', route: '', func: listTodos },
63
- },
64
- })
65
-
66
- // Compose into top-level API
67
- wireHTTPRoutes({
68
- basePath: '/api',
69
- routes: { todos: todoRoutes },
70
- })
71
- ```
72
-
73
- **Key difference:** The function receives `{ title, priority }` as typed data - it doesn't know if it came from HTTP body, WebSocket message, or CLI args. Routes are grouped with `defineHTTPRoutes` (like a controller) and composed with `wireHTTPRoutes`.
74
-
75
- ---
76
-
77
- ## Route Parameters → Merged into Data
78
-
79
- **Traditional:**
80
-
81
- ```typescript
82
- // Must extract from req.params, req.query, req.body separately
83
- async getUser(req: Request, res: Response) {
84
- const id = req.params.id // from URL
85
- const fields = req.query.fields // from query string
86
- const updates = req.body // from body
87
- }
88
- ```
89
-
90
- **Pikku:**
91
-
92
- ```typescript
93
- // All sources merged into a single typed `data` object.
94
- // input/output are Zod schemas; the data + return types are inferred from them.
95
- const getUser = pikkuSessionlessFunc({
96
- input: z.object({ id: z.string(), fields: z.string().optional() }),
97
- output: UserOutput,
98
- func: async (services, { id, fields }) => {
99
- // id comes from route param, fields from query - function doesn't care
100
- return { user: await services.db.getUser(id, fields) }
101
- },
102
- })
103
-
104
- wireHTTP({ method: 'get', route: '/users/:id', func: getUser, auth: false })
105
- ```
106
-
107
- Pikku merges route params + query string + body + headers into a single typed input.
108
-
109
- ---
110
-
111
- ## Middleware → pikkuMiddleware
112
-
113
- **Traditional:**
114
-
115
- ```typescript
116
- // Express-style middleware
117
- function logRequest(req: Request, res: Response, next: NextFunction) {
118
- console.log(`${req.method} ${req.url}`)
119
- next()
120
- console.log(`Response: ${res.statusCode}`)
121
- }
122
- app.use(logRequest)
123
- ```
124
-
125
- **Pikku:**
126
-
127
- ```typescript
128
- const logRequest = pikkuMiddleware(async ({ logger }, wire, next) => {
129
- logger.info('Request started')
130
- await next()
131
- logger.info('Request completed')
132
- })
133
-
134
- // Apply globally
135
- addHTTPMiddleware('*', [logRequest])
136
-
137
- // Apply by route pattern
138
- addHTTPMiddleware('/api/*', [logRequest])
139
- ```
140
-
141
- **Key difference:** Pikku middleware receives services (injected), not raw req/res.
142
-
143
- ---
144
-
145
- ## Auth Guard → Built-in Auth Middleware
146
-
147
- **Traditional:**
148
-
149
- ```typescript
150
- // Custom auth middleware
151
- function authMiddleware(req, res, next) {
152
- const token = req.headers.authorization?.replace('Bearer ', '')
153
- if (!token) return res.status(401).json({ error: 'Unauthorized' })
154
- try {
155
- req.user = jwt.verify(token)
156
- next()
157
- } catch {
158
- res.status(401).json({ error: 'Invalid token' })
159
- }
160
- }
161
- ```
162
-
163
- **Pikku:**
164
-
165
- ```typescript
166
- import { authBearer } from '@pikku/core/middleware'
167
-
168
- // One line - handles token extraction, JWT verification, session population
169
- addHTTPMiddleware('*', [authBearer({})])
170
- ```
171
-
172
- Other built-in options: `authCookie({ cookieName })`, `authApiKey({ header })`.
173
-
174
- ---
175
-
176
- ## Authorization / Role Checks → pikkuPermission
177
-
178
- **Traditional:**
179
-
180
- ```typescript
181
- // Guard or middleware that checks roles
182
- function requireRole(role: string) {
183
- return (req, res, next) => {
184
- if (req.user.role !== role)
185
- return res.status(403).json({ error: 'Forbidden' })
186
- next()
187
- }
188
- }
189
- router.delete('/users/:id', requireRole('admin'), deleteUser)
190
- ```
191
-
192
- **Pikku:**
193
-
194
- ```typescript
195
- const isOwner = pikkuPermission(async ({ db }, { userId }, wire) => {
196
- const { session } = wire
197
- return session?.userId === userId
198
- })
199
-
200
- // Declare on the function definition (the only place permissions live).
201
- // A capability like "may delete users" is a scope, not a permission.
202
- export const deleteUser = pikkuFunc({
203
- func: async (services, data) => {
204
- /* ... */
205
- },
206
- scopes: ['admin:users:delete'],
207
- permissions: { owner: [isOwner] },
208
- })
209
-
210
- // App-wide baseline every function must also pass (AND gate, narrow-only)
211
- addGlobalPermission([signedInUser])
212
- ```
213
-
214
- **Permission groups:** `{ groupA: [perm1, perm2], groupB: [perm3] }` means `(perm1 AND perm2) OR perm3`.
215
-
216
- > Route-pattern (`addHTTPPermission`) and wire-level `permissions` were removed in #972 — permissions live on the function, plus the optional global gate.
217
-
218
- ---
219
-
220
- ## DTO / Request Validation → Standard Schema
221
-
222
- **Traditional (class-validator):**
223
-
224
- ```typescript
225
- class CreateTodoDTO {
226
- @IsString()
227
- @IsNotEmpty()
228
- @MaxLength(200)
229
- title: string
230
-
231
- @IsOptional()
232
- @IsIn(['low', 'medium', 'high'])
233
- priority?: string
234
- }
235
- ```
236
-
237
- **Pikku (Zod):**
238
-
239
- ```typescript
240
- const CreateTodoInputSchema = z.object({
241
- title: z.string().min(1).max(200),
242
- priority: z.enum(['low', 'medium', 'high']).optional(),
243
- })
244
-
245
- // Schema declared on function - auto-validated before function runs
246
- const createTodo = pikkuSessionlessFunc({
247
- input: CreateTodoInputSchema,
248
- output: TodoOutputSchema,
249
- func: async (services, data) => { ... },
250
- })
251
- ```
252
-
253
- Also supports Valibot, ArkType, or any Standard Schema-compatible library.
254
-
255
- ---
256
-
257
- ## Dependency Injection → Service Factories
258
-
259
- **Traditional (class-based DI):**
260
-
261
- ```typescript
262
- @Injectable()
263
- class TodoService {
264
- constructor(
265
- @Inject('DATABASE') private db: Database,
266
- private logger: Logger
267
- ) {}
268
-
269
- async create(title: string) {
270
- this.logger.info('Creating todo')
271
- return this.db.insert('todos', { title })
272
- }
273
- }
274
- ```
275
-
276
- **Pikku:**
277
-
278
- ```typescript
279
- // Define services once at startup
280
- const createSingletonServices = pikkuServices(async (config) => ({
281
- logger: new ConsoleLogger(),
282
- db: new KyselyService(config.database),
283
- todoStore: new TodoStore(),
284
- }))
285
-
286
- // Functions destructure what they need
287
- const createTodo = pikkuSessionlessFunc(
288
- async ({ logger, todoStore }, { title }) => {
289
- logger.info('Creating todo')
290
- return { todo: todoStore.createTodo(title) }
291
- }
292
- )
293
- ```
294
-
295
- **Key difference:** No container, no decorators, no class hierarchy. Just a factory function returning an object.
296
-
297
- Per-request services (like scoped loggers) use `pikkuWireServices`:
298
-
299
- ```typescript
300
- const createWireServices = pikkuWireServices(
301
- async (singletonServices, wire) => ({
302
- scopedLogger: new ScopedLogger(wire.session?.initial?.userId),
303
- })
304
- )
305
- ```
306
-
307
- ---
308
-
309
- ## WebSocket Handlers → wireChannel
310
-
311
- **Traditional:**
312
-
313
- ```typescript
314
- wss.on('connection', (ws) => {
315
- ws.on('message', (raw) => {
316
- const { type, payload } = JSON.parse(raw)
317
- switch (type) {
318
- case 'subscribe':
319
- handleSubscribe(ws, payload)
320
- break
321
- case 'create':
322
- handleCreate(ws, payload)
323
- break
324
- }
325
- })
326
- ws.on('close', () => handleDisconnect(ws))
327
- })
328
- ```
329
-
330
- **Pikku:**
331
-
332
- ```typescript
333
- wireChannel({
334
- name: 'todos-live',
335
- route: '/',
336
- onConnect, // pikkuVoidFunc
337
- onDisconnect, // pikkuVoidFunc
338
- onMessageWiring: {
339
- action: {
340
- // First level of message routing
341
- subscribe: { func: subscribe },
342
- create: { func: createTodo },
343
- auth: { func: login, auth: false },
344
- },
345
- },
346
- })
347
- ```
348
-
349
- Functions send data back via `wire.channel.send(data)`. Structured message routing replaces manual switch/case parsing.
350
-
351
- ---
352
-
353
- ## Job Queue Workers → wireQueueWorker
354
-
355
- **Traditional (Bull/BullMQ):**
356
-
357
- ```typescript
358
- const queue = new Queue('reminders')
359
-
360
- // Producer
361
- await queue.add('send-reminder', { todoId: '123', userId: 'user1' })
362
-
363
- // Consumer
364
- const worker = new Worker('reminders', async (job) => {
365
- const { todoId, userId } = job.data
366
- await sendReminder(todoId, userId)
367
- })
368
- ```
369
-
370
- **Pikku:**
371
-
372
- ```typescript
373
- // Same pikkuFunc shape - knows nothing about queues
374
- const processReminder = pikkuSessionlessFunc(
375
- async ({ todoStore, logger }, { todoId, userId }) => {
376
- const todo = todoStore.getTodo(todoId)
377
- if (todo && !todo.completed) {
378
- logger.info(`Sending reminder for: ${todo.title}`)
379
- }
380
- return { processed: true }
381
- }
382
- )
383
-
384
- // Wire it to a queue
385
- wireQueueWorker({ name: 'todo-reminders', func: processReminder })
386
-
387
- // Enqueue from other functions via queue service
388
- await services.queueService.addJob('todo-reminders', {
389
- todoId: '123',
390
- userId: 'user1',
391
- })
392
- ```
393
-
394
- ---
395
-
396
- ## Cron / Scheduled Tasks → wireScheduler
397
-
398
- **Traditional:**
399
-
400
- ```typescript
401
- import cron from 'node-cron'
402
- cron.schedule('0 9 * * *', async () => {
403
- const stats = await todoService.getStats()
404
- console.log(`Daily: ${stats.completed}/${stats.total}`)
405
- })
406
- ```
407
-
408
- **Pikku:**
409
-
410
- ```typescript
411
- const dailySummary = pikkuVoidFunc(async ({ logger, todoStore }) => {
412
- const stats = todoStore.getStats('user1')
413
- logger.info(`Daily: ${stats.completed}/${stats.total}`)
414
- })
415
-
416
- wireScheduler({
417
- name: 'dailySummary',
418
- schedule: '0 9 * * *',
419
- func: dailySummary,
420
- })
421
- ```
422
-
423
- ---
424
-
425
- ## Module / Feature Grouping → Tags + File Organization
426
-
427
- **Traditional (NestJS):**
428
-
429
- ```typescript
430
- @Module({
431
- imports: [DatabaseModule],
432
- controllers: [TodoController],
433
- providers: [TodoService],
434
- exports: [TodoService],
435
- })
436
- export class TodoModule {}
437
- ```
438
-
439
- **Pikku:**
440
-
441
- ```text
442
- // No module system. Organize by convention:
443
- src/
444
- ├── functions/
445
- │ └── todos.functions.ts # All todo business logic
446
- ├── wirings/
447
- │ └── todos.http.ts # All todo HTTP routes
448
- └── schemas.ts # Shared schemas
449
-
450
- // Use tags for cross-cutting concerns:
451
- wireHTTP({ route: '/todos', func: listTodos, tags: ['todos', 'public'] })
452
- addMiddleware('todos', [loggingMiddleware]) // Applies to all 'todos'-tagged functions
453
- ```
454
-
455
- ---
456
-
457
- ## Error Handling → Typed Errors
458
-
459
- **Traditional:**
460
-
461
- ```typescript
462
- if (!todo) {
463
- res.status(404).json({ error: 'Todo not found' })
464
- return
465
- }
466
- if (!canEdit(user, todo)) {
467
- res.status(403).json({ error: 'Forbidden' })
468
- return
469
- }
470
- ```
471
-
472
- **Pikku:**
473
-
474
- ```typescript
475
- import { NotFoundError, ForbiddenError } from '@pikku/core/errors'
476
-
477
- const updateTodo = pikkuFunc(async (services, { id, title }, wire) => {
478
- const todo = services.todoStore.getTodo(id)
479
- if (!todo) throw new NotFoundError('Todo not found')
480
-
481
- const { session } = wire
482
- if (todo.userId !== session.userId) throw new ForbiddenError()
483
-
484
- return { todo: services.todoStore.update(id, { title }) }
485
- })
486
- ```
487
-
488
- Pikku catches these errors and maps them to appropriate HTTP status codes automatically.
489
-
490
- ---
491
-
492
- ## Session Management
493
-
494
- **Traditional:**
495
-
496
- ```typescript
497
- // Express session
498
- app.use(session({ store: new RedisStore({ client: redis }), secret: 'key' }))
499
-
500
- // In handler
501
- req.session.userId = user.id // Set
502
- const userId = req.session.userId // Get
503
- req.session.destroy() // Clear
504
- ```
505
-
506
- **Pikku:**
507
-
508
- ```typescript
509
- // Session is on the wire context, managed by auth middleware
510
- const login = pikkuSessionlessFunc(
511
- async ({ jwt }, { username, password }, wire) => {
512
- const user = authenticate(username, password)
513
- const token = await jwt.sign({ userId: user.id })
514
- await wire.setSession({ userId: user.id, user }) // Set
515
- return { token, user }
516
- }
517
- )
518
-
519
- const getMe = pikkuFunc(async (services, data, wire) => {
520
- const { session } = wire // Get
521
- return { user: session.user }
522
- })
523
-
524
- const logout = pikkuFunc(async (services, data, wire) => {
525
- await wire.clearSession() // Clear
526
- return { success: true }
527
- })
528
- ```
529
-
530
- ---
531
-
532
- ## API Client Generation
533
-
534
- **Traditional:**
535
-
536
- ```typescript
537
- // Manually written or generated via OpenAPI
538
- const response = await fetch('/api/todos', {
539
- method: 'POST',
540
- headers: { 'Content-Type': 'application/json' },
541
- body: JSON.stringify({ title: 'New todo' }),
542
- })
543
- const data: unknown = await response.json()
544
- ```
545
-
546
- **Pikku (auto-generated, fully typed):**
547
-
548
- ```typescript
549
- import { createPikkuFetchClient } from './.pikku/pikku-fetch.gen.js'
550
-
551
- const client = createPikkuFetchClient({ baseUrl: 'http://localhost:4002' })
552
- const result = await client.post('/todos', { title: 'New todo' })
553
- // result is fully typed as TodoOutput - no manual type casting
554
- ```
555
-
556
- Generated by running `npx pikku all`. Both HTTP and WebSocket clients available.
@@ -1,29 +0,0 @@
1
- # Available Pikku Packages
2
-
3
- ## Runtime Adapters
4
-
5
- | Package | Use Case |
6
- | ----------------------------- | ------------------------------------- |
7
- | `@pikku/express-server` | Express standalone server |
8
- | `@pikku/express-middleware` | Express as middleware in existing app |
9
- | `@pikku/fastify-server` | Fastify standalone |
10
- | `@pikku/fastify-plugin` | Fastify plugin |
11
- | `@pikku/next` | Next.js API routes |
12
- | `@pikku/aws-lambda` | AWS Lambda handlers |
13
- | `@pikku/cloudflare` | Cloudflare Workers |
14
- | `@pikku/uws-server` | uWebSockets.js (high perf) |
15
- | `@pikku/modelcontextprotocol` | MCP server |
16
-
17
- ## Service Packages
18
-
19
- | Package | Provides |
20
- | ------------------------ | ---------------------------------------------------- |
21
- | `@pikku/jose` | JWT (sign/verify) via jose library |
22
- | `@pikku/schema-ajv` | Schema validation via AJV |
23
- | `@pikku/schema-cfworker` | Schema validation for Cloudflare |
24
- | `@pikku/pino` | Structured logging via Pino |
25
- | `@pikku/kysely` | Type-safe SQL via Kysely (PostgreSQL, SQLite, MySQL) |
26
- | `@pikku/redis` | Redis client |
27
- | `@pikku/queue-bullmq` | Job queues via BullMQ |
28
- | `@pikku/queue-pg-boss` | Job queues via PgBoss |
29
- | `@pikku/aws-services` | AWS SDK (SQS, DynamoDB, etc.) |