@pikku/core 0.12.4 → 0.12.5

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 (229) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/dist/dev/hot-reload.d.ts +10 -0
  3. package/dist/dev/hot-reload.js +158 -0
  4. package/dist/middleware-runner.d.ts +1 -0
  5. package/dist/middleware-runner.js +5 -0
  6. package/dist/permissions.d.ts +1 -0
  7. package/dist/permissions.js +5 -0
  8. package/dist/services/in-memory-workflow-service.js +7 -11
  9. package/dist/wirings/ai-agent/ai-agent-prepare.js +16 -1
  10. package/dist/wirings/channel/channel-middleware-runner.d.ts +1 -0
  11. package/dist/wirings/channel/channel-middleware-runner.js +5 -0
  12. package/dist/wirings/workflow/pikku-workflow-service.js +7 -8
  13. package/package.json +3 -2
  14. package/src/crypto-utils.test.ts +214 -0
  15. package/src/crypto-utils.ts +213 -0
  16. package/src/dev/hot-reload.test.ts +484 -0
  17. package/src/dev/hot-reload.ts +212 -0
  18. package/src/errors/error-handler.ts +62 -0
  19. package/src/errors/error.test.ts +195 -0
  20. package/src/errors/errors.ts +374 -0
  21. package/src/errors/index.ts +2 -0
  22. package/src/factory-functions.test.ts +109 -0
  23. package/src/function/function-runner.test.ts +536 -0
  24. package/src/function/function-runner.ts +365 -0
  25. package/src/function/functions.types.ts +304 -0
  26. package/src/function/index.ts +5 -0
  27. package/src/handle-error.test.ts +424 -0
  28. package/src/handle-error.ts +69 -0
  29. package/src/index.ts +118 -0
  30. package/src/internal.ts +6 -0
  31. package/src/middleware/auth-apikey.test.ts +363 -0
  32. package/src/middleware/auth-apikey.ts +47 -0
  33. package/src/middleware/auth-bearer.test.ts +450 -0
  34. package/src/middleware/auth-bearer.ts +72 -0
  35. package/src/middleware/auth-cookie.test.ts +528 -0
  36. package/src/middleware/auth-cookie.ts +80 -0
  37. package/src/middleware/cors.test.ts +424 -0
  38. package/src/middleware/cors.ts +104 -0
  39. package/src/middleware/index.ts +5 -0
  40. package/src/middleware/remote-auth.test.ts +488 -0
  41. package/src/middleware/remote-auth.ts +68 -0
  42. package/src/middleware/timeout.ts +15 -0
  43. package/src/middleware-runner.test.ts +418 -0
  44. package/src/middleware-runner.ts +240 -0
  45. package/src/permissions.test.ts +434 -0
  46. package/src/permissions.ts +327 -0
  47. package/src/pikku-request.ts +23 -0
  48. package/src/pikku-response.ts +5 -0
  49. package/src/pikku-state.test.ts +224 -0
  50. package/src/pikku-state.ts +216 -0
  51. package/src/run-tests-script.test.ts +49 -0
  52. package/src/schema.test.ts +249 -0
  53. package/src/schema.ts +151 -0
  54. package/src/services/ai-agent-runner-service.ts +41 -0
  55. package/src/services/ai-run-state-service.ts +20 -0
  56. package/src/services/ai-storage-service.ts +39 -0
  57. package/src/services/content-service.ts +76 -0
  58. package/src/services/deployment-service.ts +22 -0
  59. package/src/services/gateway-service.ts +20 -0
  60. package/src/services/gopass-secrets.ts +98 -0
  61. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  62. package/src/services/in-memory-trigger-service.ts +64 -0
  63. package/src/services/in-memory-workflow-service.test.ts +351 -0
  64. package/src/services/in-memory-workflow-service.ts +502 -0
  65. package/src/services/index.ts +56 -0
  66. package/src/services/jwt-service.ts +30 -0
  67. package/src/services/local-content.ts +120 -0
  68. package/src/services/local-gateway-service.ts +62 -0
  69. package/src/services/local-secrets.test.ts +80 -0
  70. package/src/services/local-secrets.ts +94 -0
  71. package/src/services/local-variables.test.ts +61 -0
  72. package/src/services/local-variables.ts +39 -0
  73. package/src/services/logger-console.test.ts +118 -0
  74. package/src/services/logger-console.ts +98 -0
  75. package/src/services/logger.ts +57 -0
  76. package/src/services/scheduler-service.ts +86 -0
  77. package/src/services/schema-service.ts +33 -0
  78. package/src/services/scoped-secret-service.test.ts +74 -0
  79. package/src/services/scoped-secret-service.ts +41 -0
  80. package/src/services/secret-service.ts +38 -0
  81. package/src/services/trigger-service.ts +17 -0
  82. package/src/services/typed-secret-service.test.ts +93 -0
  83. package/src/services/typed-secret-service.ts +70 -0
  84. package/src/services/typed-variables-service.test.ts +73 -0
  85. package/src/services/typed-variables-service.ts +81 -0
  86. package/src/services/user-session-service.test.ts +113 -0
  87. package/src/services/user-session-service.ts +86 -0
  88. package/src/services/variables-service.ts +11 -0
  89. package/src/services/workflow-service.ts +95 -0
  90. package/src/testing/index.ts +2 -0
  91. package/src/testing/service-tests.ts +873 -0
  92. package/src/time-utils.test.ts +56 -0
  93. package/src/time-utils.ts +107 -0
  94. package/src/types/core.types.ts +478 -0
  95. package/src/types/state.types.ts +188 -0
  96. package/src/utils/hash.test.ts +68 -0
  97. package/src/utils/hash.ts +26 -0
  98. package/src/utils.test.ts +350 -0
  99. package/src/utils.ts +129 -0
  100. package/src/version.test.ts +80 -0
  101. package/src/version.ts +25 -0
  102. package/src/wirings/ai-agent/agent-dynamic-workflow.ts +469 -0
  103. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  104. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  105. package/src/wirings/ai-agent/ai-agent-memory.ts +310 -0
  106. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  107. package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
  108. package/src/wirings/ai-agent/ai-agent-prepare.ts +659 -0
  109. package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
  110. package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
  111. package/src/wirings/ai-agent/ai-agent-runner.test.ts +319 -0
  112. package/src/wirings/ai-agent/ai-agent-runner.ts +773 -0
  113. package/src/wirings/ai-agent/ai-agent-stream.test.ts +859 -0
  114. package/src/wirings/ai-agent/ai-agent-stream.ts +1153 -0
  115. package/src/wirings/ai-agent/ai-agent.types.ts +382 -0
  116. package/src/wirings/ai-agent/index.ts +37 -0
  117. package/src/wirings/channel/channel-common.ts +90 -0
  118. package/src/wirings/channel/channel-handler.ts +250 -0
  119. package/src/wirings/channel/channel-middleware-runner.ts +126 -0
  120. package/src/wirings/channel/channel-runner.ts +166 -0
  121. package/src/wirings/channel/channel-store.ts +29 -0
  122. package/src/wirings/channel/channel.types.ts +172 -0
  123. package/src/wirings/channel/define-channel-routes.ts +25 -0
  124. package/src/wirings/channel/eventhub-service.ts +34 -0
  125. package/src/wirings/channel/eventhub-store.ts +13 -0
  126. package/src/wirings/channel/index.ts +24 -0
  127. package/src/wirings/channel/local/index.ts +3 -0
  128. package/src/wirings/channel/local/local-channel-handler.ts +81 -0
  129. package/src/wirings/channel/local/local-channel-runner.test.ts +215 -0
  130. package/src/wirings/channel/local/local-channel-runner.ts +210 -0
  131. package/src/wirings/channel/local/local-eventhub-service.test.ts +95 -0
  132. package/src/wirings/channel/local/local-eventhub-service.ts +101 -0
  133. package/src/wirings/channel/log-channels.ts +20 -0
  134. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +54 -0
  135. package/src/wirings/channel/pikku-abstract-channel-handler.ts +45 -0
  136. package/src/wirings/channel/serverless/index.ts +5 -0
  137. package/src/wirings/channel/serverless/serverless-channel-runner.ts +289 -0
  138. package/src/wirings/cli/channel/cli-channel-runner.ts +136 -0
  139. package/src/wirings/cli/channel/index.ts +1 -0
  140. package/src/wirings/cli/cli-runner.test.ts +403 -0
  141. package/src/wirings/cli/cli-runner.ts +529 -0
  142. package/src/wirings/cli/cli.types.ts +358 -0
  143. package/src/wirings/cli/command-parser.test.ts +445 -0
  144. package/src/wirings/cli/command-parser.ts +504 -0
  145. package/src/wirings/cli/define-cli-commands.ts +24 -0
  146. package/src/wirings/cli/index.ts +19 -0
  147. package/src/wirings/gateway/gateway-runner.test.ts +474 -0
  148. package/src/wirings/gateway/gateway-runner.ts +411 -0
  149. package/src/wirings/gateway/gateway.types.ts +149 -0
  150. package/src/wirings/gateway/index.ts +13 -0
  151. package/src/wirings/http/http-routes.test.ts +322 -0
  152. package/src/wirings/http/http-routes.ts +197 -0
  153. package/src/wirings/http/http-runner.test.ts +144 -0
  154. package/src/wirings/http/http-runner.ts +588 -0
  155. package/src/wirings/http/http.types.ts +369 -0
  156. package/src/wirings/http/index.ts +28 -0
  157. package/src/wirings/http/log-http-routes.ts +22 -0
  158. package/src/wirings/http/pikku-fetch-http-request.test.ts +237 -0
  159. package/src/wirings/http/pikku-fetch-http-request.ts +170 -0
  160. package/src/wirings/http/pikku-fetch-http-response.test.ts +82 -0
  161. package/src/wirings/http/pikku-fetch-http-response.ts +147 -0
  162. package/src/wirings/http/routers/http-router.ts +13 -0
  163. package/src/wirings/http/routers/path-to-regex.test.ts +319 -0
  164. package/src/wirings/http/routers/path-to-regex.ts +126 -0
  165. package/src/wirings/http/web-request.test.ts +236 -0
  166. package/src/wirings/http/web-request.ts +104 -0
  167. package/src/wirings/mcp/index.ts +27 -0
  168. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +389 -0
  169. package/src/wirings/mcp/mcp-endpoint-registry.ts +159 -0
  170. package/src/wirings/mcp/mcp-runner.ts +323 -0
  171. package/src/wirings/mcp/mcp.types.ts +216 -0
  172. package/src/wirings/node/index.ts +2 -0
  173. package/src/wirings/node/node.types.ts +23 -0
  174. package/src/wirings/oauth2/index.ts +3 -0
  175. package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
  176. package/src/wirings/oauth2/oauth2-client.ts +335 -0
  177. package/src/wirings/oauth2/oauth2.types.ts +69 -0
  178. package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
  179. package/src/wirings/queue/index.ts +31 -0
  180. package/src/wirings/queue/queue-runner.test.ts +710 -0
  181. package/src/wirings/queue/queue-runner.ts +192 -0
  182. package/src/wirings/queue/queue.types.ts +189 -0
  183. package/src/wirings/queue/register-queue-helper.ts +60 -0
  184. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  185. package/src/wirings/queue/validate-worker-config.ts +116 -0
  186. package/src/wirings/rpc/index.ts +4 -0
  187. package/src/wirings/rpc/rpc-runner.ts +460 -0
  188. package/src/wirings/rpc/rpc-types.ts +56 -0
  189. package/src/wirings/rpc/wire-addon.ts +21 -0
  190. package/src/wirings/scheduler/index.ts +11 -0
  191. package/src/wirings/scheduler/log-schedulers.ts +20 -0
  192. package/src/wirings/scheduler/scheduler-runner.test.ts +660 -0
  193. package/src/wirings/scheduler/scheduler-runner.ts +133 -0
  194. package/src/wirings/scheduler/scheduler.types.ts +53 -0
  195. package/src/wirings/secret/index.ts +9 -0
  196. package/src/wirings/secret/secret.types.ts +32 -0
  197. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  198. package/src/wirings/secret/validate-secret-definitions.ts +82 -0
  199. package/src/wirings/trigger/index.ts +10 -0
  200. package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
  201. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  202. package/src/wirings/trigger/trigger-runner.ts +135 -0
  203. package/src/wirings/trigger/trigger.types.ts +178 -0
  204. package/src/wirings/variable/index.ts +8 -0
  205. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  206. package/src/wirings/variable/validate-variable-definitions.ts +69 -0
  207. package/src/wirings/variable/variable.types.ts +22 -0
  208. package/src/wirings/workflow/dsl/index.ts +31 -0
  209. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +320 -0
  210. package/src/wirings/workflow/dsl/workflow-runner.ts +28 -0
  211. package/src/wirings/workflow/graph/graph-node.ts +222 -0
  212. package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
  213. package/src/wirings/workflow/graph/graph-runner.ts +816 -0
  214. package/src/wirings/workflow/graph/graph-validation.test.ts +170 -0
  215. package/src/wirings/workflow/graph/graph-validation.ts +237 -0
  216. package/src/wirings/workflow/graph/index.ts +19 -0
  217. package/src/wirings/workflow/graph/template.test.ts +49 -0
  218. package/src/wirings/workflow/graph/template.ts +42 -0
  219. package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
  220. package/src/wirings/workflow/graph/workflow-graph.types.ts +104 -0
  221. package/src/wirings/workflow/index.ts +82 -0
  222. package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
  223. package/src/wirings/workflow/pikku-workflow-service.ts +1179 -0
  224. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  225. package/src/wirings/workflow/workflow-helpers.ts +79 -0
  226. package/src/wirings/workflow/workflow.types.ts +274 -0
  227. package/tsconfig.json +14 -0
  228. package/tsconfig.tsbuildinfo +1 -0
  229. package/lcov.info +0 -18891
@@ -0,0 +1,56 @@
1
+ import { describe, test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import type { RelativeTimeInput } from './time-utils'
5
+ import {
6
+ getRelativeTimeOffset,
7
+ getRelativeTimeOffsetFromNow,
8
+ } from './time-utils'
9
+
10
+ const approxEqual = (a: number, b: number, delta: number = 10): boolean =>
11
+ Math.abs(a - b) <= delta
12
+
13
+ describe('Time Utils', () => {
14
+ const offsetCases: Array<{ input: RelativeTimeInput; expected: number }> = [
15
+ { input: { value: 1, unit: 'second' }, expected: 1000 },
16
+ { input: { value: 2, unit: 'minute' }, expected: 120000 },
17
+ { input: { value: 1.5, unit: 'hour' }, expected: 5400000 },
18
+ { input: { value: -1, unit: 'day' }, expected: -86400000 },
19
+ { input: { value: 1, unit: 'week' }, expected: 604800000 },
20
+ {
21
+ input: { value: 2, unit: 'year' },
22
+ expected: Math.round(2 * 365.25 * 86400 * 1000),
23
+ },
24
+ ]
25
+
26
+ describe('getRelativeTimeOffset', () => {
27
+ for (const { input, expected } of offsetCases) {
28
+ test(`returns ${expected} ms for ${input.value} ${input.unit}`, () => {
29
+ const actual = getRelativeTimeOffset(input)
30
+ assert.strictEqual(actual, expected)
31
+ })
32
+ }
33
+ })
34
+
35
+ describe('getRelativeTimeOffsetFromNow', () => {
36
+ test('returns a Date ~1 minute in the future', () => {
37
+ const now = Date.now()
38
+ const result = getRelativeTimeOffsetFromNow({ value: 1, unit: 'minute' })
39
+ const delta = result.getTime() - now
40
+ assert.ok(
41
+ approxEqual(delta, 60000),
42
+ `Expected ~60000ms ahead, got ${delta}ms`
43
+ )
44
+ })
45
+
46
+ test('returns a Date ~2 hours in the past', () => {
47
+ const now = Date.now()
48
+ const result = getRelativeTimeOffsetFromNow({ value: -2, unit: 'hour' })
49
+ const delta = now - result.getTime()
50
+ assert.ok(
51
+ approxEqual(delta, 7200000),
52
+ `Expected ~7200000ms ago, got ${delta}ms`
53
+ )
54
+ })
55
+ })
56
+ })
@@ -0,0 +1,107 @@
1
+ type TimeUnit = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'year'
2
+
3
+ export interface RelativeTimeInput {
4
+ value: number // negative = in the past
5
+ unit: TimeUnit
6
+ }
7
+
8
+ const multipliers: Record<TimeUnit, number> = {
9
+ second: 1,
10
+ minute: 60,
11
+ hour: 60 * 60,
12
+ day: 60 * 60 * 24,
13
+ week: 60 * 60 * 24 * 7,
14
+ year: Math.round(365.25 * 60 * 60 * 24),
15
+ }
16
+
17
+ export const getRelativeTimeOffset = ({
18
+ value,
19
+ unit,
20
+ }: RelativeTimeInput): number => {
21
+ return Math.round(value * multipliers[unit]) * 1000 // convert to milliseconds
22
+ }
23
+
24
+ /**
25
+ * Returns a Unix timestamp (in seconds) offset from now by the given duration.
26
+ * e.g. value = -1 and unit = 'day' => 1 day ago => now - 86400 seconds
27
+ */
28
+ export const getRelativeTimeOffsetFromNow = (
29
+ relativeTime: RelativeTimeInput
30
+ ): Date => {
31
+ return new Date(Date.now() + getRelativeTimeOffset(relativeTime))
32
+ }
33
+
34
+ /**
35
+ * Get duration in milliseconds from a string or number
36
+ * @param duration
37
+ * @returns
38
+ */
39
+ export const getDurationInMilliseconds = (
40
+ duration: string | number
41
+ ): number => {
42
+ if (typeof duration === 'number') {
43
+ return duration
44
+ }
45
+ return parseDurationString(duration)
46
+ }
47
+
48
+ /**
49
+ * Parse a duration string to milliseconds
50
+ * Supports formats like: '2s', '5s', '5sec', '5seconds', '5m', '5min', '5minutes', '1h', '1hour', '2d', '2day', '1w', '1week'
51
+ *
52
+ * @param duration - Duration string (e.g., '2s', '5min', '2hours', '1day')
53
+ * @returns Duration in milliseconds
54
+ */
55
+ export const parseDurationString = (duration: string): number => {
56
+ const match = duration.match(
57
+ /^(\d+)(ms|milliseconds?|s|sec|seconds?|m|min|minutes?|h|hour|hours?|d|day|days?|w|week|weeks?|y|year|years?)$/
58
+ )
59
+
60
+ if (!match) {
61
+ throw new Error(
62
+ `Invalid duration format: ${duration}. Use formats like '2s', '5s', '5min', '1hour', '2days', '1week'`
63
+ )
64
+ }
65
+
66
+ const value = parseInt(match[1], 10)
67
+ const unitStr = match[2]
68
+
69
+ // Handle milliseconds specially
70
+ if (
71
+ unitStr === 'ms' ||
72
+ unitStr === 'millisecond' ||
73
+ unitStr === 'milliseconds'
74
+ ) {
75
+ return value
76
+ }
77
+
78
+ // Map string variations to TimeUnit
79
+ let unit: TimeUnit
80
+ if (
81
+ unitStr === 's' ||
82
+ unitStr === 'sec' ||
83
+ unitStr === 'second' ||
84
+ unitStr === 'seconds'
85
+ ) {
86
+ unit = 'second'
87
+ } else if (
88
+ unitStr === 'm' ||
89
+ unitStr === 'min' ||
90
+ unitStr === 'minute' ||
91
+ unitStr === 'minutes'
92
+ ) {
93
+ unit = 'minute'
94
+ } else if (unitStr === 'h' || unitStr === 'hour' || unitStr === 'hours') {
95
+ unit = 'hour'
96
+ } else if (unitStr === 'd' || unitStr === 'day' || unitStr === 'days') {
97
+ unit = 'day'
98
+ } else if (unitStr === 'w' || unitStr === 'week' || unitStr === 'weeks') {
99
+ unit = 'week'
100
+ } else if (unitStr === 'y' || unitStr === 'year' || unitStr === 'years') {
101
+ unit = 'year'
102
+ } else {
103
+ throw new Error(`Unknown time unit: ${unitStr}`)
104
+ }
105
+
106
+ return getRelativeTimeOffset({ value, unit })
107
+ }
@@ -0,0 +1,478 @@
1
+ import type { Logger, LogLevel } from '../services/logger.js'
2
+ import type { VariablesService } from '../services/variables-service.js'
3
+ import type { SecretService } from '../services/secret-service.js'
4
+ import type { SchemaService } from '../services/schema-service.js'
5
+ import type { JWTService } from '../services/jwt-service.js'
6
+ import type { PikkuHTTP } from '../wirings/http/http.types.js'
7
+ import type {
8
+ PikkuChannel,
9
+ CorePikkuChannelMiddleware,
10
+ CorePikkuChannelMiddlewareFactory,
11
+ } from '../wirings/channel/channel.types.js'
12
+ import type { PikkuRPC } from '../wirings/rpc/rpc-types.js'
13
+ import type { PikkuMCP } from '../wirings/mcp/mcp.types.js'
14
+ import type { PikkuScheduledTask } from '../wirings/scheduler/scheduler.types.js'
15
+ import type { PikkuQueue, QueueService } from '../wirings/queue/queue.types.js'
16
+ import type { PikkuCLI } from '../wirings/cli/cli.types.js'
17
+ import type {
18
+ PikkuWorkflowWire,
19
+ WorkflowService,
20
+ WorkflowServiceConfig,
21
+ WorkflowStepWire,
22
+ } from '../wirings/workflow/workflow.types.js'
23
+ import type { PikkuGraphWire } from '../wirings/workflow/graph/workflow-graph.types.js'
24
+ import type { PikkuTrigger } from '../wirings/trigger/trigger.types.js'
25
+ import type { PikkuGateway } from '../wirings/gateway/gateway.types.js'
26
+ import type { SchedulerService } from '../services/scheduler-service.js'
27
+ import type { DeploymentService } from '../services/deployment-service.js'
28
+ import type { AIStorageService } from '../services/ai-storage-service.js'
29
+
30
+ import type { ContentService } from '../services/content-service.js'
31
+ import type { AIAgentRunnerService } from '../services/ai-agent-runner-service.js'
32
+ import type { AIRunStateService } from '../services/ai-run-state-service.js'
33
+ import type { AgentRunService } from '../wirings/ai-agent/ai-agent.types.js'
34
+ import type { PikkuAIMiddlewareHooks } from '../wirings/ai-agent/ai-agent.types.js'
35
+ import type { WorkflowRunService } from '../wirings/workflow/workflow.types.js'
36
+
37
+ export type PikkuWiringTypes =
38
+ | 'http'
39
+ | 'scheduler'
40
+ | 'trigger'
41
+ | 'channel'
42
+ | 'rpc'
43
+ | 'queue'
44
+ | 'mcp'
45
+ | 'cli'
46
+ | 'workflow'
47
+ | 'agent'
48
+ | 'gateway'
49
+
50
+ export interface FunctionServicesMeta {
51
+ optimized: boolean
52
+ services: string[]
53
+ }
54
+
55
+ export interface FunctionWiresMeta {
56
+ optimized: boolean
57
+ wires: string[]
58
+ }
59
+
60
+ /**
61
+ * Metadata for middleware at any level
62
+ * - type: 'http' = HTTP route middleware group (references httpGroup in pikkuState)
63
+ * - type: 'tag' = Tag-based middleware group (references tagGroup in pikkuState)
64
+ * - type: 'wire' = Wire-level individual middleware
65
+ */
66
+ export type MiddlewareMetadata =
67
+ | {
68
+ type: 'http'
69
+ route: string // Route pattern (e.g., '*' for all, '/api/*' for specific)
70
+ }
71
+ | {
72
+ type: 'tag'
73
+ tag: string // Tag name
74
+ }
75
+ | {
76
+ type: 'wire'
77
+ name: string
78
+ inline?: boolean // true if inline middleware
79
+ }
80
+
81
+ /**
82
+ * Metadata for permissions at any level
83
+ * - type: 'http' = HTTP route permission group (references httpGroup in pikkuState)
84
+ * - type: 'tag' = Tag-based permission group (references tagGroup in pikkuState)
85
+ * - type: 'wire' = Wire-level individual permission
86
+ */
87
+ export type PermissionMetadata =
88
+ | {
89
+ type: 'http'
90
+ route: string // Route pattern (e.g., '*' for all, '/api/*' for specific)
91
+ }
92
+ | {
93
+ type: 'tag'
94
+ tag: string // Tag name
95
+ }
96
+ | {
97
+ type: 'wire'
98
+ name: string
99
+ inline?: boolean // true if inline permission
100
+ }
101
+
102
+ export type FunctionRuntimeMeta = {
103
+ pikkuFuncId: string
104
+ inputSchemaName: string | null
105
+ outputSchemaName: string | null
106
+ expose?: boolean
107
+ remote?: boolean
108
+ mcp?: boolean
109
+ readonly?: boolean
110
+ sessionless?: boolean
111
+ version?: number
112
+ approvalRequired?: boolean
113
+ approvalDescription?: string
114
+ contractHash?: string
115
+ inputHash?: string
116
+ outputHash?: string
117
+ }
118
+
119
+ export type FunctionMeta = FunctionRuntimeMeta &
120
+ Partial<
121
+ {
122
+ name: string
123
+ functionType: 'user' | 'inline' | 'helper'
124
+ funcWrapper: string
125
+ services: FunctionServicesMeta
126
+ wires: FunctionWiresMeta
127
+ inputs: string[] | null
128
+ outputs: string[] | null
129
+ middleware: MiddlewareMetadata[]
130
+ permissions: PermissionMetadata[]
131
+ isDirectFunction: boolean
132
+ } & CommonWireMeta
133
+ >
134
+
135
+ export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>
136
+ export type FunctionsMeta = Record<string, FunctionMeta>
137
+
138
+ // Optimized runtime metadata with only essential fields
139
+
140
+ export type MakeRequired<T, K extends keyof T> = Omit<T, K> &
141
+ Required<Pick<T, K>>
142
+
143
+ /**
144
+ * Represents a JSON primitive type which can be a string, number, boolean, null, or undefined.
145
+ */
146
+ export type JSONPrimitive = string | number | boolean | null | undefined
147
+
148
+ /**
149
+ * Represents a JSON value which can be a primitive, an array, or an object.
150
+ */
151
+ export type JSONValue =
152
+ | JSONPrimitive
153
+ | JSONValue[]
154
+ | {
155
+ [key: string]: JSONValue
156
+ }
157
+
158
+ /**
159
+ * Utility type for making certain keys required and leaving the rest as optional.
160
+ */
161
+ export type PickRequired<T, K extends keyof T> = Required<Pick<T, K>> &
162
+ Partial<T>
163
+
164
+ /**
165
+ * Utility type for making certain keys optional while keeping the rest required.
166
+ */
167
+ export type PickOptional<T, K extends keyof T> = Partial<T> & Pick<T, K>
168
+
169
+ /**
170
+ * Utility type that ensures at least one key in the given type `T` is required.
171
+ */
172
+ export type RequireAtLeastOne<T> = {
173
+ [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>
174
+ }[keyof T]
175
+
176
+ /**
177
+ * Interface for the core configuration settings of Pikku.
178
+ */
179
+ export type CoreConfig<Config extends Record<string, unknown> = {}> = {
180
+ /** The log level for the application. */
181
+ logLevel?: LogLevel
182
+ /** Secrets used by the application (optional). */
183
+ secrets?: {}
184
+
185
+ workflow?: WorkflowServiceConfig
186
+ } & Config
187
+
188
+ /**
189
+ * Represents a core user session, which can be extended for more specific session information.
190
+ */
191
+ export interface CoreUserSession {}
192
+
193
+ /**
194
+ * Interface for core singleton services provided by Pikku.
195
+ */
196
+ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
197
+ /** The schema library used to validate data */
198
+ schema?: SchemaService
199
+ /** The JWT service used to encode and decode tokens */
200
+ jwt?: JWTService
201
+ /** The core configuration for the application. */
202
+ config: Config
203
+ /** The logger used by the application. */
204
+ logger: Logger
205
+ /** The variable service to be used */
206
+ variables: VariablesService
207
+ /** The secrets service to retrieve secrets */
208
+ secrets: SecretService
209
+ /** The workflow orchestrator service */
210
+ workflowService?: WorkflowService
211
+ /** The queue service */
212
+ queueService?: QueueService
213
+ /** The scheduler service */
214
+ schedulerService?: SchedulerService
215
+ /** The deployment service for service discovery */
216
+ deploymentService?: DeploymentService
217
+ /** AI agent storage service (threads, messages, working memory) */
218
+ aiStorage?: AIStorageService
219
+
220
+ /** Content service for file storage and retrieval */
221
+ content?: ContentService
222
+ /** AI agent runner service (model calls + tool loop) */
223
+ aiAgentRunner?: AIAgentRunnerService
224
+ /** AI run state service (run lifecycle + approval persistence) */
225
+ aiRunState?: AIRunStateService
226
+ /** Agent run service (listing threads, runs, steps) */
227
+ agentRunService?: AgentRunService
228
+ /** Workflow run service (listing workflow runs) */
229
+ workflowRunService?: WorkflowRunService
230
+ }
231
+
232
+ /**
233
+ * Represents different forms of wire within Pikku and the outside world.
234
+ */
235
+ export type PikkuWire<
236
+ In = unknown,
237
+ Out = unknown,
238
+ HasInitialSession extends boolean = false,
239
+ UserSession extends CoreUserSession = CoreUserSession,
240
+ TypedRPC extends PikkuRPC = PikkuRPC,
241
+ IsChannel extends true | null = null,
242
+ MCPTools extends string | never = never,
243
+ TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire,
244
+ TriggerOutput = unknown,
245
+ > = Partial<{
246
+ wireType: PikkuWiringTypes
247
+ wireId: string
248
+ http: PikkuHTTP<In>
249
+ mcp: PikkuMCP<MCPTools>
250
+ rpc: TypedRPC
251
+ channel: [IsChannel] extends [null]
252
+ ? PikkuChannel<unknown, Out>
253
+ : PikkuChannel<unknown, Out> | undefined
254
+ scheduledTask: PikkuScheduledTask
255
+ queue: PikkuQueue
256
+ cli: PikkuCLI
257
+ workflow: TypedWorkflow
258
+ workflowStep: WorkflowStepWire
259
+ graph: PikkuGraphWire
260
+ trigger: PikkuTrigger<TriggerOutput>
261
+ gateway: PikkuGateway
262
+ session: HasInitialSession extends true
263
+ ? UserSession
264
+ : UserSession | undefined
265
+ /** Update and persist the current session */
266
+ setSession: (session: CoreUserSession) => Promise<void> | void
267
+ /** Clear and persist the current session */
268
+ clearSession: () => Promise<void> | void
269
+ /** Fetch the latest session (may read from backing store) */
270
+ getSession: () => Promise<UserSession> | UserSession | undefined
271
+ /** Whether the session was modified during this run */
272
+ hasSessionChanged: () => boolean
273
+ }>
274
+
275
+ /**
276
+ * A function that can wrap an wire and be called before or after
277
+ */
278
+ export type CorePikkuMiddleware<
279
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
280
+ UserSession extends CoreUserSession = CoreUserSession,
281
+ > = (
282
+ services: SingletonServices,
283
+ wires: PikkuWire<unknown, unknown, false, UserSession>,
284
+ next: () => Promise<void>
285
+ ) => Promise<void>
286
+
287
+ /**
288
+ * Configuration object for creating middleware with metadata
289
+ *
290
+ * @template SingletonServices - The singleton services type
291
+ * @template UserSession - The user session type
292
+ */
293
+ export type CorePikkuMiddlewareConfig<
294
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
295
+ UserSession extends CoreUserSession = CoreUserSession,
296
+ > = {
297
+ /** The middleware function */
298
+ func: CorePikkuMiddleware<SingletonServices, UserSession>
299
+ /** Optional human-readable name for the middleware */
300
+ name?: string
301
+ /** Optional description of what the middleware does */
302
+ description?: string
303
+ }
304
+
305
+ /**
306
+ * A factory function that takes input and returns middleware
307
+ * Used when middleware needs configuration/input parameters
308
+ */
309
+ export type CorePikkuMiddlewareFactory<
310
+ In = any,
311
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
312
+ UserSession extends CoreUserSession = CoreUserSession,
313
+ > = (input: In) => CorePikkuMiddleware<SingletonServices, UserSession>
314
+
315
+ /**
316
+ * A group of middleware (combination of regular middleware and factories)
317
+ * Used with addMiddleware() and addHTTPMiddleware() to group related middleware together
318
+ */
319
+ export type CorePikkuMiddlewareGroup<
320
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
321
+ UserSession extends CoreUserSession = CoreUserSession,
322
+ > = Array<
323
+ | CorePikkuMiddleware<SingletonServices, UserSession>
324
+ | CorePikkuMiddlewareFactory<any, SingletonServices, UserSession>
325
+ >
326
+
327
+ /**
328
+ * Factory function for creating middleware with tree-shaking support
329
+ * Supports both direct function and configuration object syntax
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * // Direct function syntax
334
+ * export const logMiddleware = pikkuMiddleware(
335
+ * async ({ logger }, next) => {
336
+ * logger.info('Request started')
337
+ * await next()
338
+ * }
339
+ * )
340
+ *
341
+ * // Configuration object syntax with metadata
342
+ * export const logMiddleware = pikkuMiddleware({
343
+ * name: 'Request Logger',
344
+ * description: 'Logs request information',
345
+ * func: async ({ logger }, next) => {
346
+ * logger.info('Request started')
347
+ * await next()
348
+ * }
349
+ * })
350
+ * ```
351
+ */
352
+ export const pikkuMiddleware = <
353
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
354
+ UserSession extends CoreUserSession = CoreUserSession,
355
+ >(
356
+ middleware:
357
+ | CorePikkuMiddleware<SingletonServices, UserSession>
358
+ | CorePikkuMiddlewareConfig<SingletonServices, UserSession>
359
+ ): CorePikkuMiddleware<SingletonServices, UserSession> => {
360
+ return typeof middleware === 'function' ? middleware : middleware.func
361
+ }
362
+
363
+ /**
364
+ * Factory function for creating middleware factories
365
+ * Use this when your middleware needs configuration/input parameters
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * export const logMiddleware = pikkuMiddlewareFactory<LogOptions>(({
370
+ * message,
371
+ * level = 'info'
372
+ * }) => {
373
+ * return pikkuMiddleware(async ({ logger }, next) => {
374
+ * logger[level](message)
375
+ * await next()
376
+ * })
377
+ * })
378
+ * ```
379
+ */
380
+ export const pikkuMiddlewareFactory = <In = any>(
381
+ factory: CorePikkuMiddlewareFactory<In>
382
+ ): CorePikkuMiddlewareFactory<In> => {
383
+ return factory
384
+ }
385
+
386
+ export const pikkuChannelMiddleware = <
387
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
388
+ Event = unknown,
389
+ >(
390
+ middleware: CorePikkuChannelMiddleware<SingletonServices, Event>
391
+ ): CorePikkuChannelMiddleware<SingletonServices, Event> => {
392
+ return middleware
393
+ }
394
+
395
+ export const pikkuChannelMiddlewareFactory = <In = any>(
396
+ factory: CorePikkuChannelMiddlewareFactory<In>
397
+ ): CorePikkuChannelMiddlewareFactory<In> => {
398
+ return factory
399
+ }
400
+
401
+ export type { PikkuAIMiddlewareHooks } from '../wirings/ai-agent/ai-agent.types.js'
402
+
403
+ export const pikkuAIMiddleware = <
404
+ State extends Record<string, unknown> = Record<string, unknown>,
405
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
406
+ >(
407
+ hooks: PikkuAIMiddlewareHooks<State, SingletonServices>
408
+ ): PikkuAIMiddlewareHooks<State, SingletonServices> => hooks
409
+
410
+ /**
411
+ * Represents the core services used by Pikku, including singleton services.
412
+ */
413
+ export type CoreServices<SingletonServices = CoreSingletonServices> =
414
+ SingletonServices
415
+
416
+ export type WireServices<
417
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
418
+ Services = CoreServices<SingletonServices>,
419
+ > = Omit<Services, keyof SingletonServices | 'session'>
420
+
421
+ /**
422
+ * Defines a function type for creating singleton services from the given configuration.
423
+ */
424
+ export type CreateSingletonServices<
425
+ Config extends CoreConfig,
426
+ SingletonServices extends CoreSingletonServices,
427
+ > = (
428
+ config: Config,
429
+ existingServices?: Partial<SingletonServices>
430
+ ) => Promise<SingletonServices>
431
+
432
+ /**
433
+ * Defines a function type for creating session-specific services.
434
+ */
435
+ export type CreateWireServices<
436
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
437
+ Services extends
438
+ CoreServices<SingletonServices> = CoreServices<SingletonServices>,
439
+ UserSession extends CoreUserSession = CoreUserSession,
440
+ > = (
441
+ services: SingletonServices,
442
+ wire: PikkuWire<unknown, unknown, false, UserSession>
443
+ ) => Promise<WireServices<Services, SingletonServices>>
444
+
445
+ /**
446
+ * Defines a function type for creating config.
447
+ */
448
+ export type CreateConfig<
449
+ Config extends CoreConfig,
450
+ RemainingArgs extends any[] = unknown[],
451
+ > = (variables?: VariablesService, ...args: RemainingArgs) => Promise<Config>
452
+
453
+ /**
454
+ * Represents the documentation for a route, including summary, description, tags, and errors.
455
+ */
456
+ export type CommonWireMeta = {
457
+ pikkuFuncId: string
458
+ packageName?: string
459
+
460
+ title?: string
461
+ tags?: string[]
462
+ summary?: string
463
+ description?: string
464
+ errors?: string[]
465
+
466
+ middleware?: MiddlewareMetadata[]
467
+ permissions?: PermissionMetadata[]
468
+ }
469
+
470
+ /**
471
+ * Serialized error for storage
472
+ */
473
+ export interface SerializedError {
474
+ message: string
475
+ stack?: string
476
+ code?: string
477
+ [key: string]: any
478
+ }