@pikku/core 0.7.7 → 0.8.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 (151) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/errors/error-handler.d.ts +2 -0
  3. package/dist/errors/errors.js +2 -0
  4. package/dist/{channel → events/channel}/channel-handler.d.ts +1 -1
  5. package/dist/{channel → events/channel}/channel-handler.js +2 -2
  6. package/dist/{channel → events/channel}/channel-runner.d.ts +1 -1
  7. package/dist/{channel → events/channel}/channel-runner.js +8 -8
  8. package/dist/{channel → events/channel}/channel-store.d.ts +1 -1
  9. package/dist/{channel → events/channel}/channel.types.d.ts +5 -9
  10. package/dist/{channel → events/channel}/local/local-channel-runner.js +10 -10
  11. package/dist/{channel → events/channel}/log-channels.d.ts +1 -1
  12. package/dist/{channel → events/channel}/log-channels.js +1 -1
  13. package/dist/{channel → events/channel}/serverless/serverless-channel-runner.js +11 -11
  14. package/dist/{http → events/http}/http-runner.d.ts +2 -2
  15. package/dist/{http → events/http}/http-runner.js +30 -19
  16. package/dist/{http → events/http}/http.types.d.ts +4 -3
  17. package/dist/{http → events/http}/index.d.ts +0 -1
  18. package/dist/{http → events/http}/index.js +0 -1
  19. package/dist/{http → events/http}/log-http-routes.d.ts +1 -1
  20. package/dist/{http → events/http}/log-http-routes.js +1 -1
  21. package/dist/{http → events/http}/pikku-fetch-http-request.js +1 -1
  22. package/dist/events/mcp/index.d.ts +2 -0
  23. package/dist/events/mcp/index.js +2 -0
  24. package/dist/events/mcp/mcp-runner.d.ts +30 -0
  25. package/dist/events/mcp/mcp-runner.js +192 -0
  26. package/dist/events/mcp/mcp.types.d.ts +117 -0
  27. package/dist/events/queue/index.d.ts +6 -0
  28. package/dist/events/queue/index.js +6 -0
  29. package/dist/events/queue/queue-runner.d.ts +24 -0
  30. package/dist/events/queue/queue-runner.js +83 -0
  31. package/dist/events/queue/queue.types.d.ts +154 -0
  32. package/dist/events/queue/register-queue-helper.d.ts +17 -0
  33. package/dist/events/queue/register-queue-helper.js +34 -0
  34. package/dist/events/queue/validate-worker-config.d.ts +41 -0
  35. package/dist/events/queue/validate-worker-config.js +50 -0
  36. package/dist/events/rpc/index.d.ts +2 -0
  37. package/dist/events/rpc/rpc-runner.d.ts +28 -0
  38. package/dist/{rpc → events/rpc}/rpc-runner.js +2 -2
  39. package/dist/events/scheduler/index.d.ts +3 -0
  40. package/dist/events/scheduler/index.js +3 -0
  41. package/dist/{scheduler → events/scheduler}/log-schedulers.d.ts +1 -1
  42. package/dist/{scheduler → events/scheduler}/log-schedulers.js +1 -1
  43. package/dist/{scheduler → events/scheduler}/scheduler-runner.d.ts +4 -3
  44. package/dist/{scheduler → events/scheduler}/scheduler-runner.js +7 -4
  45. package/dist/{scheduler → events/scheduler}/scheduler.types.d.ts +3 -4
  46. package/dist/function/function-runner.js +8 -0
  47. package/dist/function/functions.types.d.ts +3 -2
  48. package/dist/handle-error.d.ts +2 -2
  49. package/dist/handle-error.js +1 -1
  50. package/dist/index.d.ts +10 -6
  51. package/dist/index.js +10 -6
  52. package/dist/middleware-runner.d.ts +4 -4
  53. package/dist/middleware-runner.js +4 -2
  54. package/dist/pikku-state.d.ts +18 -4
  55. package/dist/pikku-state.js +12 -0
  56. package/dist/services/user-session-service.d.ts +1 -1
  57. package/dist/types/core.types.d.ts +22 -4
  58. package/dist/types/core.types.js +9 -1
  59. package/lcov.info +3557 -3476
  60. package/package.json +8 -7
  61. package/src/errors/error-handler.ts +2 -1
  62. package/src/errors/errors.ts +2 -0
  63. package/src/{channel → events/channel}/channel-handler.ts +3 -3
  64. package/src/{channel → events/channel}/channel-runner.ts +9 -9
  65. package/src/{channel → events/channel}/channel-store.ts +1 -1
  66. package/src/{channel → events/channel}/channel.types.ts +5 -9
  67. package/src/{channel → events/channel}/local/local-channel-runner.test.ts +1 -1
  68. package/src/{channel → events/channel}/local/local-channel-runner.ts +11 -11
  69. package/src/{channel → events/channel}/local/local-eventhub-service.test.ts +1 -1
  70. package/src/{channel → events/channel}/log-channels.ts +2 -2
  71. package/src/{channel → events/channel}/serverless/serverless-channel-runner.ts +12 -12
  72. package/src/{http → events/http}/http-runner.test.ts +4 -4
  73. package/src/{http → events/http}/http-runner.ts +39 -20
  74. package/src/{http → events/http}/http.types.ts +4 -3
  75. package/src/{http → events/http}/index.ts +0 -1
  76. package/src/{http → events/http}/log-http-routes.ts +2 -2
  77. package/src/{http → events/http}/pikku-fetch-http-request.ts +1 -1
  78. package/src/events/mcp/index.ts +2 -0
  79. package/src/events/mcp/mcp-runner.ts +321 -0
  80. package/src/events/mcp/mcp.types.ts +150 -0
  81. package/src/events/queue/index.ts +18 -0
  82. package/src/events/queue/queue-runner.ts +125 -0
  83. package/src/events/queue/queue.types.ts +176 -0
  84. package/src/events/queue/register-queue-helper.ts +62 -0
  85. package/src/events/queue/validate-worker-config.ts +113 -0
  86. package/src/events/rpc/index.ts +2 -0
  87. package/src/{rpc → events/rpc}/rpc-runner.ts +3 -3
  88. package/src/events/scheduler/index.ts +9 -0
  89. package/src/{scheduler → events/scheduler}/log-schedulers.ts +2 -2
  90. package/src/{scheduler → events/scheduler}/scheduler-runner.ts +11 -10
  91. package/src/{scheduler → events/scheduler}/scheduler.types.ts +2 -4
  92. package/src/function/function-runner.ts +19 -1
  93. package/src/function/functions.types.ts +3 -1
  94. package/src/handle-error.ts +2 -2
  95. package/src/index.ts +23 -6
  96. package/src/middleware-runner.ts +14 -7
  97. package/src/pikku-state.ts +40 -4
  98. package/src/services/user-session-service.ts +1 -1
  99. package/src/types/core.types.ts +31 -4
  100. package/tsconfig.json +3 -2
  101. package/tsconfig.tsbuildinfo +1 -1
  102. package/dist/rpc/index.d.ts +0 -2
  103. package/dist/rpc/rpc-runner.d.ts +0 -27
  104. package/dist/scheduler/index.d.ts +0 -3
  105. package/dist/scheduler/index.js +0 -3
  106. package/src/http/incomingmessage-to-request-convertor.ts +0 -0
  107. package/src/rpc/index.ts +0 -2
  108. package/src/scheduler/index.ts +0 -5
  109. /package/dist/{channel → events/channel}/channel-store.js +0 -0
  110. /package/dist/{channel → events/channel}/channel.types.js +0 -0
  111. /package/dist/{channel → events/channel}/eventhub-service.d.ts +0 -0
  112. /package/dist/{channel → events/channel}/eventhub-service.js +0 -0
  113. /package/dist/{channel → events/channel}/eventhub-store.d.ts +0 -0
  114. /package/dist/{channel → events/channel}/eventhub-store.js +0 -0
  115. /package/dist/{channel → events/channel}/index.d.ts +0 -0
  116. /package/dist/{channel → events/channel}/index.js +0 -0
  117. /package/dist/{channel → events/channel}/local/index.d.ts +0 -0
  118. /package/dist/{channel → events/channel}/local/index.js +0 -0
  119. /package/dist/{channel → events/channel}/local/local-channel-handler.d.ts +0 -0
  120. /package/dist/{channel → events/channel}/local/local-channel-handler.js +0 -0
  121. /package/dist/{channel → events/channel}/local/local-channel-runner.d.ts +0 -0
  122. /package/dist/{channel → events/channel}/local/local-eventhub-service.d.ts +0 -0
  123. /package/dist/{channel → events/channel}/local/local-eventhub-service.js +0 -0
  124. /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.d.ts +0 -0
  125. /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.js +0 -0
  126. /package/dist/{channel → events/channel}/serverless/index.d.ts +0 -0
  127. /package/dist/{channel → events/channel}/serverless/index.js +0 -0
  128. /package/dist/{channel → events/channel}/serverless/serverless-channel-runner.d.ts +0 -0
  129. /package/dist/{http → events/http}/http.types.js +0 -0
  130. /package/dist/{http → events/http}/pikku-fetch-http-request.d.ts +0 -0
  131. /package/dist/{http → events/http}/pikku-fetch-http-response.d.ts +0 -0
  132. /package/dist/{http → events/http}/pikku-fetch-http-response.js +0 -0
  133. /package/dist/{http/incomingmessage-to-request-convertor.d.ts → events/mcp/mcp.types.js} +0 -0
  134. /package/dist/{http/incomingmessage-to-request-convertor.js → events/queue/queue.types.js} +0 -0
  135. /package/dist/{rpc → events/rpc}/index.js +0 -0
  136. /package/dist/{rpc → events/rpc}/rpc-types.d.ts +0 -0
  137. /package/dist/{rpc → events/rpc}/rpc-types.js +0 -0
  138. /package/dist/{scheduler → events/scheduler}/scheduler.types.js +0 -0
  139. /package/src/{channel → events/channel}/eventhub-service.ts +0 -0
  140. /package/src/{channel → events/channel}/eventhub-store.ts +0 -0
  141. /package/src/{channel → events/channel}/index.ts +0 -0
  142. /package/src/{channel → events/channel}/local/index.ts +0 -0
  143. /package/src/{channel → events/channel}/local/local-channel-handler.ts +0 -0
  144. /package/src/{channel → events/channel}/local/local-eventhub-service.ts +0 -0
  145. /package/src/{channel → events/channel}/pikku-abstract-channel-handler.test.ts +0 -0
  146. /package/src/{channel → events/channel}/pikku-abstract-channel-handler.ts +0 -0
  147. /package/src/{channel → events/channel}/serverless/index.ts +0 -0
  148. /package/src/{http → events/http}/pikku-fetch-http-request.test.ts +0 -0
  149. /package/src/{http → events/http}/pikku-fetch-http-response.test.ts +0 -0
  150. /package/src/{http → events/http}/pikku-fetch-http-response.ts +0 -0
  151. /package/src/{rpc → events/rpc}/rpc-types.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/core",
3
- "version": "0.7.7",
3
+ "version": "0.8.0",
4
4
  "author": "yasser.fadl@gmail.com",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",
@@ -20,13 +20,14 @@
20
20
  ".": "./dist/index.js",
21
21
  "./middleware": "./dist/middleware/index.js",
22
22
  "./function": "./dist/function/index.js",
23
- "./channel": "./dist/channel/index.js",
24
- "./channel/local": "./dist/channel/local/index.js",
25
- "./channel/serverless": "./dist/channel/serverless/index.js",
26
- "./http": "./dist/http/index.js",
27
- "./rpc": "./dist/rpc/index.js",
23
+ "./channel": "./dist/events/channel/index.js",
24
+ "./channel/local": "./dist/events/channel/local/index.js",
25
+ "./channel/serverless": "./dist/events/channel/serverless/index.js",
26
+ "./http": "./dist/events/http/index.js",
27
+ "./queue": "./dist/events/queue/index.js",
28
+ "./scheduler": "./dist/events/scheduler/index.js",
29
+ "./rpc": "./dist/events/rpc/index.js",
28
30
  "./errors": "./dist/errors/index.js",
29
- "./scheduler": "./dist/scheduler/index.js",
30
31
  "./services": "./dist/services/index.js",
31
32
  "./schema": "./dist/schema.js",
32
33
  "./types": "./dist/types/index.d.ts"
@@ -21,6 +21,7 @@ export class PikkuError extends Error {
21
21
  export interface ErrorDetails {
22
22
  status: number
23
23
  message: string
24
+ mcpCode?: number
24
25
  }
25
26
 
26
27
  /**
@@ -51,7 +52,7 @@ export const addErrors = (
51
52
  */
52
53
  export const getErrorResponse = (
53
54
  error: Error
54
- ): { status: number; message: string } | undefined => {
55
+ ): { status: number; message: string; mcpCode?: number } | undefined => {
55
56
  const errors = Array.from(pikkuState('misc', 'errors').entries())
56
57
  const foundError = errors.find(([e]) => e.name === error.constructor.name)
57
58
  if (foundError) {
@@ -10,6 +10,7 @@ import { addError, PikkuError } from './error-handler.js'
10
10
  export class BadRequestError extends PikkuError {}
11
11
  addError(BadRequestError, {
12
12
  status: 400,
13
+ mcpCode: -32600,
13
14
  message:
14
15
  'The server cannot or will not process the request due to client error (e.g., malformed request syntax).',
15
16
  })
@@ -85,6 +86,7 @@ export class NotFoundError extends PikkuError {}
85
86
  */
86
87
  addError(NotFoundError, {
87
88
  status: 404,
89
+ mcpCode: -32601,
88
90
  message: 'The server cannot find the requested resource.',
89
91
  })
90
92
 
@@ -2,14 +2,14 @@ import {
2
2
  CoreServices,
3
3
  JSONValue,
4
4
  CoreUserSession,
5
- } from '../types/core.types.js'
5
+ } from '../../types/core.types.js'
6
6
  import {
7
7
  ChannelMessageMeta,
8
8
  CoreAPIChannel,
9
9
  PikkuChannelHandler,
10
10
  } from './channel.types.js'
11
- import { pikkuState } from '../pikku-state.js'
12
- import { runPikkuFunc } from '../function/function-runner.js'
11
+ import { pikkuState } from '../../pikku-state.js'
12
+ import { runPikkuFunc } from '../../function/function-runner.js'
13
13
 
14
14
  const getRouteMeta = (
15
15
  channelName: string,
@@ -1,8 +1,8 @@
1
- import { NotFoundError } from '../errors/errors.js'
2
- import { addFunction } from '../function/function-runner.js'
3
- import { pikkuState } from '../pikku-state.js'
4
- import { coerceTopLevelDataFromSchema, validateSchema } from '../schema.js'
5
- import { UserSessionService } from '../services/user-session-service.js'
1
+ import { NotFoundError } from '../../errors/errors.js'
2
+ import { addFunction } from '../../function/function-runner.js'
3
+ import { pikkuState } from '../../pikku-state.js'
4
+ import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js'
5
+ import { UserSessionService } from '../../services/user-session-service.js'
6
6
  import {
7
7
  ChannelMeta,
8
8
  CoreAPIChannel,
@@ -34,15 +34,15 @@ export const addChannel = <
34
34
  pikkuState('channel', 'channels').set(channel.name, channel as any)
35
35
 
36
36
  // Register onConnect function if provided
37
- if (channel.onConnect && channelMeta.connectPikkuFuncName) {
38
- addFunction(channelMeta.connectPikkuFuncName, {
37
+ if (channel.onConnect && channelMeta.connect) {
38
+ addFunction(channelMeta.connect.pikkuFuncName, {
39
39
  func: channel.onConnect as any,
40
40
  })
41
41
  }
42
42
 
43
43
  // Register onDisconnect function if provided
44
- if (channel.onDisconnect && channelMeta.disconnectPikkuFuncName) {
45
- addFunction(channelMeta.disconnectPikkuFuncName, {
44
+ if (channel.onDisconnect && channelMeta.disconnect) {
45
+ addFunction(channelMeta.disconnect.pikkuFuncName, {
46
46
  func: channel.onDisconnect,
47
47
  })
48
48
  }
@@ -1,4 +1,4 @@
1
- import { CoreUserSession } from '../types/core.types.js'
1
+ import { CoreUserSession } from '../../types/core.types.js'
2
2
 
3
3
  export type Channel<ChannelType = unknown, OpeningData = unknown> = {
4
4
  channelId: string
@@ -1,4 +1,4 @@
1
- import { PikkuError } from '../errors/error-handler.js'
1
+ import { PikkuError } from '../../errors/error-handler.js'
2
2
  import {
3
3
  HTTPFunctionMetaInputTypes,
4
4
  PikkuHTTPRequest,
@@ -9,12 +9,12 @@ import {
9
9
  CoreSingletonServices,
10
10
  CreateSessionServices,
11
11
  PikkuMiddleware,
12
- } from '../types/core.types.js'
12
+ } from '../../types/core.types.js'
13
13
  import {
14
14
  CoreAPIFunction,
15
15
  CoreAPIFunctionSessionless,
16
16
  CoreAPIPermission,
17
- } from '../function/functions.types.js'
17
+ } from '../../function/functions.types.js'
18
18
 
19
19
  export type RunChannelOptions = Partial<{
20
20
  skipUserSession: boolean
@@ -34,8 +34,6 @@ export type RunChannelParams<ChannelData> = {
34
34
 
35
35
  export interface ChannelMessageMeta {
36
36
  pikkuFuncName: string
37
- inputs: string[] | null
38
- outputs: string[] | null
39
37
  docs?: APIDocs
40
38
  }
41
39
 
@@ -46,10 +44,8 @@ export interface ChannelMeta {
46
44
  query?: string[]
47
45
  input: string | null
48
46
  inputTypes?: HTTPFunctionMetaInputTypes
49
- connect: boolean
50
- connectPikkuFuncName: string | null
51
- disconnect: boolean
52
- disconnectPikkuFuncName: string | null
47
+ connect: ChannelMessageMeta | null
48
+ disconnect: ChannelMessageMeta | null
53
49
  message: ChannelMessageMeta | null
54
50
  messageRoutes: Record<string, Record<string, ChannelMessageMeta>>
55
51
  docs?: APIDocs
@@ -1,7 +1,7 @@
1
1
  import { test, beforeEach, afterEach } from 'node:test'
2
2
  import * as assert from 'node:assert/strict'
3
3
  import { runLocalChannel } from './local-channel-runner.js'
4
- import { pikkuState, resetPikkuState } from '../../pikku-state.js'
4
+ import { pikkuState, resetPikkuState } from '../../../pikku-state.js'
5
5
  import { addChannel } from '../channel-runner.js'
6
6
  import {
7
7
  HTTPMethod,
@@ -1,6 +1,6 @@
1
1
  import { openChannel } from '../channel-runner.js'
2
2
  import { createHTTPInteraction } from '../../http/http-runner.js'
3
- import { closeSessionServices } from '../../utils.js'
3
+ import { closeSessionServices } from '../../../utils.js'
4
4
  import { processMessageHandlers } from '../channel-handler.js'
5
5
  import {
6
6
  CoreAPIChannel,
@@ -8,12 +8,12 @@ import {
8
8
  RunChannelParams,
9
9
  } from '../channel.types.js'
10
10
  import { PikkuLocalChannelHandler } from './local-channel-handler.js'
11
- import { SessionServices } from '../../types/core.types.js'
12
- import { handleError } from '../../handle-error.js'
13
- import { runMiddleware } from '../../middleware-runner.js'
14
- import { PikkuUserSessionService } from '../../services/user-session-service.js'
11
+ import { SessionServices } from '../../../types/core.types.js'
12
+ import { handleHTTPError } from '../../../handle-error.js'
13
+ import { runMiddleware } from '../../../middleware-runner.js'
14
+ import { PikkuUserSessionService } from '../../../services/user-session-service.js'
15
15
  import { PikkuHTTP } from '../../http/http.types.js'
16
- import { runPikkuFuncDirectly } from '../../function/function-runner.js'
16
+ import { runPikkuFuncDirectly } from '../../../function/function-runner.js'
17
17
  import { rpcService } from '../../rpc/rpc-runner.js'
18
18
 
19
19
  export const runLocalChannel = async ({
@@ -79,9 +79,9 @@ export const runLocalChannel = async ({
79
79
  })
80
80
 
81
81
  channelHandler.registerOnOpen(() => {
82
- if (channelConfig.onConnect && meta.connectPikkuFuncName) {
82
+ if (channelConfig.onConnect && meta.connect) {
83
83
  runPikkuFuncDirectly(
84
- meta.connectPikkuFuncName,
84
+ meta.connect.pikkuFuncName,
85
85
  { ...allServices, channel },
86
86
  openingData
87
87
  )
@@ -89,9 +89,9 @@ export const runLocalChannel = async ({
89
89
  })
90
90
 
91
91
  channelHandler.registerOnClose(async () => {
92
- if (channelConfig.onDisconnect && meta.disconnectPikkuFuncName) {
92
+ if (channelConfig.onDisconnect && meta.disconnect) {
93
93
  runPikkuFuncDirectly(
94
- meta.disconnectPikkuFuncName,
94
+ meta.disconnect.pikkuFuncName,
95
95
  { ...allServices, channel },
96
96
  openingData
97
97
  )
@@ -110,7 +110,7 @@ export const runLocalChannel = async ({
110
110
  )
111
111
  )
112
112
  } catch (e: any) {
113
- handleError(
113
+ handleHTTPError(
114
114
  e,
115
115
  http,
116
116
  channelId,
@@ -1,7 +1,7 @@
1
1
  import * as assert from 'assert'
2
2
  import { test } from 'node:test'
3
3
  import { PikkuChannelHandler } from '../channel.types.js'
4
- import { CoreUserSession } from '../../types/core.types.js'
4
+ import { CoreUserSession } from '../../../types/core.types.js'
5
5
  import { LocalEventHubService } from './local-eventhub-service.js'
6
6
 
7
7
  class MockChannelHandler implements PikkuChannelHandler {
@@ -1,5 +1,5 @@
1
- import { pikkuState } from '../pikku-state.js'
2
- import { Logger } from '../services/index.js'
1
+ import { pikkuState } from '../../pikku-state.js'
2
+ import { Logger } from '../../services/index.js'
3
3
 
4
4
  /**
5
5
  * Logs all the loaded channels.
@@ -1,5 +1,5 @@
1
- import { SessionServices } from '../../types/core.types.js'
2
- import { closeSessionServices } from '../../utils.js'
1
+ import { SessionServices } from '../../../types/core.types.js'
2
+ import { closeSessionServices } from '../../../utils.js'
3
3
  import { processMessageHandlers } from '../channel-handler.js'
4
4
  import { openChannel } from '../channel-runner.js'
5
5
  import type {
@@ -10,13 +10,13 @@ import type {
10
10
  } from '../channel.types.js'
11
11
  import { createHTTPInteraction } from '../../http/http-runner.js'
12
12
  import { ChannelStore } from '../channel-store.js'
13
- import { handleError } from '../../handle-error.js'
14
- import { PikkuUserSessionService } from '../../services/user-session-service.js'
15
- import { runMiddleware } from '../../middleware-runner.js'
16
- import { pikkuState } from '../../pikku-state.js'
13
+ import { handleHTTPError } from '../../../handle-error.js'
14
+ import { PikkuUserSessionService } from '../../../services/user-session-service.js'
15
+ import { runMiddleware } from '../../../middleware-runner.js'
16
+ import { pikkuState } from '../../../pikku-state.js'
17
17
  import { PikkuFetchHTTPRequest } from '../../http/pikku-fetch-http-request.js'
18
18
  import { PikkuHTTP } from '../../http/http.types.js'
19
- import { runPikkuFuncDirectly } from '../../function/function-runner.js'
19
+ import { runPikkuFuncDirectly } from '../../../function/function-runner.js'
20
20
 
21
21
  export interface RunServerlessChannelParams<ChannelData>
22
22
  extends RunChannelParams<ChannelData> {
@@ -115,16 +115,16 @@ export const runChannelConnect = async ({
115
115
  await userSession.get()
116
116
  )
117
117
  }
118
- if (channelConfig.onConnect && meta.connectPikkuFuncName) {
118
+ if (channelConfig.onConnect && meta.connect) {
119
119
  await runPikkuFuncDirectly(
120
- meta.connectPikkuFuncName,
120
+ meta.connect.pikkuFuncName,
121
121
  { ...singletonServices, ...sessionServices, channel },
122
122
  openingData
123
123
  )
124
124
  }
125
125
  http?.response?.status(101)
126
126
  } catch (e: any) {
127
- handleError(
127
+ handleHTTPError(
128
128
  e,
129
129
  http,
130
130
  channelId,
@@ -170,9 +170,9 @@ export const runChannelDisconnect = async ({
170
170
  session
171
171
  )
172
172
  }
173
- if (channelConfig.onDisconnect && meta.disconnectPikkuFuncName) {
173
+ if (channelConfig.onDisconnect && meta.disconnect) {
174
174
  await runPikkuFuncDirectly(
175
- meta.disconnectPikkuFuncName,
175
+ meta.disconnect.pikkuFuncName,
176
176
  { ...singletonServices, ...sessionServices, channel },
177
177
  undefined
178
178
  )
@@ -1,14 +1,14 @@
1
1
  import { test, describe, beforeEach, afterEach } from 'node:test'
2
2
  import * as assert from 'assert'
3
- import { NotFoundError } from '../errors/errors.js'
4
- import { JSONValue, PikkuMiddleware } from '../types/core.types.js'
3
+ import { NotFoundError } from '../../errors/errors.js'
4
+ import { JSONValue, PikkuMiddleware } from '../../types/core.types.js'
5
5
  import { fetch, addHTTPRoute } from './http-runner.js'
6
- import { pikkuState, resetPikkuState } from '../pikku-state.js'
6
+ import { pikkuState, resetPikkuState } from '../../pikku-state.js'
7
7
  import {
8
8
  PikkuMockRequest,
9
9
  PikkuMockResponse,
10
10
  } from '../channel/local/local-channel-runner.test.js'
11
- import { addFunction } from '../function/function-runner.js'
11
+ import { addFunction } from '../../function/function-runner.js'
12
12
 
13
13
  const sessionMiddleware: PikkuMiddleware = async (services, _, next) => {
14
14
  services.userSession.set({ userId: 'test' } as any)
@@ -12,25 +12,25 @@ import {
12
12
  CoreUserSession,
13
13
  PikkuMiddleware,
14
14
  SessionServices,
15
- } from '../types/core.types.js'
15
+ } from '../../types/core.types.js'
16
16
  import { match } from 'path-to-regexp'
17
- import { MissingSessionError, NotFoundError } from '../errors/errors.js'
17
+ import { MissingSessionError, NotFoundError } from '../../errors/errors.js'
18
18
  import {
19
19
  closeSessionServices,
20
20
  createWeakUID,
21
21
  isSerializable,
22
- } from '../utils.js'
22
+ } from '../../utils.js'
23
23
  import {
24
24
  PikkuUserSessionService,
25
25
  UserSessionService,
26
- } from '../services/user-session-service.js'
27
- import { runMiddleware } from '../middleware-runner.js'
28
- import { handleError } from '../handle-error.js'
29
- import { pikkuState } from '../pikku-state.js'
26
+ } from '../../services/user-session-service.js'
27
+ import { runMiddleware } from '../../middleware-runner.js'
28
+ import { handleHTTPError } from '../../handle-error.js'
29
+ import { pikkuState } from '../../pikku-state.js'
30
30
  import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js'
31
31
  import { PikkuFetchHTTPRequest } from './pikku-fetch-http-request.js'
32
32
  import { PikkuChannel } from '../channel/channel.types.js'
33
- import { addFunction, runPikkuFunc } from '../function/function-runner.js'
33
+ import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
34
34
  import { rpcService } from '../rpc/rpc-runner.js'
35
35
 
36
36
  /**
@@ -48,13 +48,30 @@ export const addMiddleware = <APIMiddleware extends PikkuMiddleware>(
48
48
  routeOrMiddleware: APIMiddleware[] | string,
49
49
  middleware?: APIMiddleware[]
50
50
  ) => {
51
+ const middlewareStore = pikkuState('http', 'middleware')
52
+
51
53
  if (typeof routeOrMiddleware === 'string' && middleware) {
52
- pikkuState('http', 'middleware').push({
53
- route: routeOrMiddleware,
54
- middleware,
55
- })
54
+ const route = routeOrMiddleware
55
+
56
+ // Remove existing entry for this route if it exists
57
+ const existingIndex = middlewareStore.findIndex(
58
+ (item) => item.route === route
59
+ )
60
+ if (existingIndex !== -1) {
61
+ middlewareStore.splice(existingIndex, 1)
62
+ }
63
+
64
+ middlewareStore.push({ route, middleware })
56
65
  } else {
57
- pikkuState('http', 'middleware').push({
66
+ // Handle global middleware
67
+ const existingIndex = middlewareStore.findIndex(
68
+ (item) => item.route === '*'
69
+ )
70
+ if (existingIndex !== -1) {
71
+ middlewareStore.splice(existingIndex, 1)
72
+ }
73
+
74
+ middlewareStore.push({
58
75
  route: '*',
59
76
  middleware: routeOrMiddleware as any,
60
77
  })
@@ -104,8 +121,6 @@ export const addHTTPRoute = <
104
121
  }
105
122
  addFunction(routeMeta.pikkuFuncName, {
106
123
  func: httpRoute.func,
107
- auth: httpRoute.auth,
108
- permissions: httpRoute.permissions,
109
124
  })
110
125
  const routes = pikkuState('http', 'routes')
111
126
  if (!routes.has(httpRoute.method)) {
@@ -324,7 +339,7 @@ const executeRouteWithMiddleware = async (
324
339
  })
325
340
  }
326
341
 
327
- const result = await runPikkuFunc(meta.pikkuFuncName, {
342
+ result = await runPikkuFunc(meta.pikkuFuncName, {
328
343
  getAllServices,
329
344
  session,
330
345
  data,
@@ -342,8 +357,6 @@ const executeRouteWithMiddleware = async (
342
357
  http?.response?.status(200)
343
358
  // TODO: Evaluate if the response stream should be explicitly ended.
344
359
  // http?.response?.end()
345
-
346
- return result
347
360
  }
348
361
 
349
362
  // Execute middleware, then run the main logic
@@ -432,6 +445,7 @@ export const fetchData = async <In, Out>(
432
445
  coerceDataFromSchema = true,
433
446
  bubbleErrors = false,
434
447
  generateRequestId,
448
+ ignoreMiddleware = false,
435
449
  }: RunRouteOptions & RunRouteParams
436
450
  ): Promise<Out | void> => {
437
451
  const requestId =
@@ -472,7 +486,12 @@ export const fetchData = async <In, Out>(
472
486
  skipUserSession,
473
487
  requestId,
474
488
  },
475
- matchedRoute,
489
+ ignoreMiddleware
490
+ ? {
491
+ ...matchedRoute,
492
+ middleware: [],
493
+ }
494
+ : matchedRoute,
476
495
  http!,
477
496
  { coerceDataFromSchema }
478
497
  ))
@@ -480,7 +499,7 @@ export const fetchData = async <In, Out>(
480
499
  return result
481
500
  } catch (e: any) {
482
501
  // Handle errors and, depending on configuration, bubble them up or respond with an error
483
- handleError(
502
+ handleHTTPError(
484
503
  e,
485
504
  http,
486
505
  requestId,
@@ -1,5 +1,5 @@
1
1
  import type { SerializeOptions } from 'cookie'
2
- import type { PikkuError } from '../errors/error-handler.js'
2
+ import type { PikkuError } from '../../errors/error-handler.js'
3
3
  import type {
4
4
  APIDocs,
5
5
  CoreServices,
@@ -7,13 +7,13 @@ import type {
7
7
  CoreUserSession,
8
8
  CreateSessionServices,
9
9
  PikkuMiddleware,
10
- } from '../types/core.types.js'
10
+ } from '../../types/core.types.js'
11
11
  import type {
12
12
  CoreAPIFunction,
13
13
  CoreAPIFunctionSessionless,
14
14
  CoreAPIPermission,
15
15
  CorePermissionGroup,
16
- } from '../function/functions.types.js'
16
+ } from '../../function/functions.types.js'
17
17
 
18
18
  type ExtractRouteParams<S extends string> =
19
19
  S extends `${string}:${infer Param}/${infer Rest}`
@@ -34,6 +34,7 @@ export type RunRouteOptions = Partial<{
34
34
  coerceDataFromSchema: boolean
35
35
  bubbleErrors: boolean
36
36
  generateRequestId: () => string
37
+ ignoreMiddleware: boolean
37
38
  }>
38
39
 
39
40
  export type RunRouteParams = {
@@ -1,6 +1,5 @@
1
1
  export * from './pikku-fetch-http-request.js'
2
2
  export * from './pikku-fetch-http-response.js'
3
- export * from './incomingmessage-to-request-convertor.js'
4
3
  export * from './log-http-routes.js'
5
4
 
6
5
  export { fetch, fetchData, addHTTPRoute } from './http-runner.js'
@@ -1,5 +1,5 @@
1
- import { pikkuState } from '../pikku-state.js'
2
- import { Logger } from '../services/index.js'
1
+ import { pikkuState } from '../../pikku-state.js'
2
+ import { Logger } from '../../services/index.js'
3
3
 
4
4
  /**
5
5
  * Logs all the loaded routes.
@@ -1,7 +1,7 @@
1
1
  import { parse as parseQuery } from 'picoquery'
2
2
  import { parse as parseCookie } from 'cookie'
3
3
  import { HTTPMethod, PikkuHTTPRequest, PikkuQuery } from './http.types.js'
4
- import { UnprocessableContentError } from '../errors/errors.js'
4
+ import { UnprocessableContentError } from '../../errors/errors.js'
5
5
 
6
6
  /**
7
7
  * Abstract class representing a pikku request.
@@ -0,0 +1,2 @@
1
+ export * from './mcp.types.js'
2
+ export * from './mcp-runner.js'