@pikku/core 0.11.0 → 0.11.1

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 (105) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/dist/errors/errors.d.ts +1 -1
  3. package/dist/errors/errors.js +3 -3
  4. package/dist/function/function-runner.d.ts +6 -7
  5. package/dist/function/function-runner.js +35 -16
  6. package/dist/function/functions.types.d.ts +22 -30
  7. package/dist/function/functions.types.js +9 -6
  8. package/dist/handle-error.d.ts +1 -1
  9. package/dist/handle-error.js +1 -1
  10. package/dist/middleware/auth-apikey.js +3 -3
  11. package/dist/middleware/auth-bearer.js +3 -3
  12. package/dist/middleware/auth-cookie.js +5 -5
  13. package/dist/middleware/timeout.js +3 -2
  14. package/dist/middleware-runner.d.ts +3 -6
  15. package/dist/middleware-runner.js +11 -12
  16. package/dist/permissions.d.ts +6 -6
  17. package/dist/permissions.js +15 -16
  18. package/dist/services/user-session-service.d.ts +7 -3
  19. package/dist/services/user-session-service.js +8 -1
  20. package/dist/types/core.types.d.ts +29 -38
  21. package/dist/types/core.types.js +3 -14
  22. package/dist/utils.d.ts +1 -1
  23. package/dist/utils.js +3 -3
  24. package/dist/wirings/channel/channel-common.js +2 -3
  25. package/dist/wirings/channel/channel-handler.d.ts +3 -2
  26. package/dist/wirings/channel/channel-handler.js +6 -9
  27. package/dist/wirings/channel/channel-runner.d.ts +2 -2
  28. package/dist/wirings/channel/channel.types.d.ts +10 -5
  29. package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
  30. package/dist/wirings/channel/local/local-channel-runner.js +19 -26
  31. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
  32. package/dist/wirings/channel/serverless/serverless-channel-runner.js +41 -46
  33. package/dist/wirings/cli/cli-runner.d.ts +5 -5
  34. package/dist/wirings/cli/cli-runner.js +10 -28
  35. package/dist/wirings/cli/cli.types.d.ts +15 -11
  36. package/dist/wirings/http/http-runner.d.ts +6 -6
  37. package/dist/wirings/http/http-runner.js +25 -39
  38. package/dist/wirings/http/http.types.d.ts +5 -10
  39. package/dist/wirings/mcp/mcp-runner.d.ts +2 -2
  40. package/dist/wirings/mcp/mcp-runner.js +12 -19
  41. package/dist/wirings/mcp/mcp.types.d.ts +6 -0
  42. package/dist/wirings/queue/queue-runner.d.ts +3 -3
  43. package/dist/wirings/queue/queue-runner.js +7 -17
  44. package/dist/wirings/queue/queue.types.d.ts +4 -11
  45. package/dist/wirings/rpc/rpc-runner.d.ts +10 -8
  46. package/dist/wirings/rpc/rpc-runner.js +36 -47
  47. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -3
  48. package/dist/wirings/scheduler/scheduler-runner.js +13 -24
  49. package/dist/wirings/scheduler/scheduler.types.d.ts +3 -8
  50. package/dist/wirings/workflow/index.d.ts +11 -2
  51. package/dist/wirings/workflow/index.js +10 -2
  52. package/dist/wirings/workflow/pikku-workflow-service.d.ts +12 -4
  53. package/dist/wirings/workflow/pikku-workflow-service.js +61 -79
  54. package/dist/wirings/workflow/workflow-runner.d.ts +3 -4
  55. package/dist/wirings/workflow/workflow-runner.js +11 -14
  56. package/dist/wirings/workflow/workflow.types.d.ts +114 -29
  57. package/package.json +2 -2
  58. package/src/errors/errors.ts +3 -3
  59. package/src/factory-functions.test.ts +9 -36
  60. package/src/function/function-runner.test.ts +57 -68
  61. package/src/function/function-runner.ts +51 -28
  62. package/src/function/function-runner.ts.bak +188 -0
  63. package/src/function/functions.types.ts +68 -51
  64. package/src/handle-error.ts +1 -1
  65. package/src/middleware/auth-apikey.test.ts +360 -0
  66. package/src/middleware/auth-apikey.ts +3 -7
  67. package/src/middleware/auth-bearer.test.ts +447 -0
  68. package/src/middleware/auth-bearer.ts +27 -33
  69. package/src/middleware/auth-cookie.test.ts +525 -0
  70. package/src/middleware/auth-cookie.ts +6 -6
  71. package/src/middleware/timeout.ts +4 -2
  72. package/src/middleware-runner.test.ts +58 -127
  73. package/src/middleware-runner.ts +13 -16
  74. package/src/permissions.test.ts +41 -45
  75. package/src/permissions.ts +21 -21
  76. package/src/services/user-session-service.ts +14 -4
  77. package/src/types/core.types.ts +67 -55
  78. package/src/utils.ts +4 -4
  79. package/src/wirings/channel/channel-common.ts +4 -7
  80. package/src/wirings/channel/channel-handler.ts +16 -22
  81. package/src/wirings/channel/channel-runner.ts +2 -2
  82. package/src/wirings/channel/channel.types.ts +14 -11
  83. package/src/wirings/channel/local/local-channel-runner.test.ts +5 -3
  84. package/src/wirings/channel/local/local-channel-runner.ts +23 -38
  85. package/src/wirings/channel/serverless/serverless-channel-runner.ts +51 -77
  86. package/src/wirings/cli/cli-runner.test.ts +7 -7
  87. package/src/wirings/cli/cli-runner.ts +24 -62
  88. package/src/wirings/cli/cli.types.ts +22 -16
  89. package/src/wirings/http/http-runner.test.ts +8 -8
  90. package/src/wirings/http/http-runner.ts +29 -56
  91. package/src/wirings/http/http.types.ts +5 -14
  92. package/src/wirings/mcp/mcp-runner.ts +23 -48
  93. package/src/wirings/mcp/mcp.types.ts +6 -0
  94. package/src/wirings/queue/queue-runner.test.ts +641 -0
  95. package/src/wirings/queue/queue-runner.ts +10 -32
  96. package/src/wirings/queue/queue.types.ts +4 -11
  97. package/src/wirings/rpc/rpc-runner.ts +41 -55
  98. package/src/wirings/scheduler/scheduler-runner.test.ts +627 -0
  99. package/src/wirings/scheduler/scheduler-runner.ts +24 -50
  100. package/src/wirings/scheduler/scheduler.types.ts +3 -9
  101. package/src/wirings/workflow/index.ts +24 -3
  102. package/src/wirings/workflow/pikku-workflow-service.ts +83 -93
  103. package/src/wirings/workflow/workflow-runner.ts +12 -25
  104. package/src/wirings/workflow/workflow.types.ts +144 -54
  105. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -1,12 +1,22 @@
1
1
  ## 0.11.0
2
2
 
3
+ ## 0.11.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 4b811db: chore: updating all dependencies
8
+ - e12a00c: feat: adding initialSession to PikkuWire which is correctly typed (undefined / not depending on function type)
9
+ - 4579434: breaking: changing the signature of functions
10
+ - 28aeb7f: breaking: extract docs in the wiring meta
11
+ - ce902b1: feat: adding in pikkuSimpleWorkflowFunc
12
+ - 06e1a31: breaking: change session services to wire services
13
+
3
14
  ### Minor Changes
4
15
 
5
16
  - Add workflow orchestration engine with step execution and retries
6
17
  - Add scheduler service abstraction
7
18
  - Remove file-based channel and eventhub stores
8
19
 
9
-
10
20
  # @pikku/core
11
21
 
12
22
  ## 0.10.2
@@ -2,7 +2,7 @@
2
2
  * The server cannot or will not process the request due to client error (e.g., malformed request syntax).
3
3
  */
4
4
  import { PikkuError } from './error-handler.js';
5
- export declare class InvalidMiddlewareInteractionError extends PikkuError {
5
+ export declare class InvalidMiddlewareWireError extends PikkuError {
6
6
  }
7
7
  /**
8
8
  * The server cannot or will not process the request due to client error (e.g., malformed request syntax).
@@ -2,11 +2,11 @@
2
2
  * The server cannot or will not process the request due to client error (e.g., malformed request syntax).
3
3
  */
4
4
  import { addError, PikkuError } from './error-handler.js';
5
- export class InvalidMiddlewareInteractionError extends PikkuError {
5
+ export class InvalidMiddlewareWireError extends PikkuError {
6
6
  }
7
- addError(InvalidMiddlewareInteractionError, {
7
+ addError(InvalidMiddlewareWireError, {
8
8
  status: 500,
9
- message: 'The middleware interaction is invalid for the current wiring type.',
9
+ message: 'The middleware wire is invalid for the current wiring type.',
10
10
  });
11
11
  /**
12
12
  * The server cannot or will not process the request due to client error (e.g., malformed request syntax).
@@ -1,12 +1,11 @@
1
- import { CoreServices, CoreUserSession, CorePikkuMiddleware, PikkuWiringTypes, CoreSingletonServices, PikkuInteraction, MiddlewareMetadata, PermissionMetadata } from '../types/core.types.js';
1
+ import { CoreServices, CoreUserSession, CorePikkuMiddleware, PikkuWiringTypes, PikkuWire, MiddlewareMetadata, PermissionMetadata, CoreSingletonServices, CreateWireServices } from '../types/core.types.js';
2
2
  import { CorePermissionGroup, CorePikkuFunctionConfig, CorePikkuPermission } from './functions.types.js';
3
- import { UserSessionService } from '../services/user-session-service.js';
3
+ import { SessionService } from '../services/user-session-service.js';
4
4
  export declare const addFunction: (funcName: string, funcConfig: CorePikkuFunctionConfig<any, any>) => void;
5
- export declare const runPikkuFuncDirectly: <In, Out>(funcName: string, allServices: CoreServices, data: In, session?: CoreUserSession) => Promise<Out>;
6
- export declare const runPikkuFunc: <In = any, Out = any>(wireType: PikkuWiringTypes, wireId: string, funcName: string, { getAllServices, singletonServices, data, userSession, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags, interaction, }: {
5
+ export declare const runPikkuFuncDirectly: <In, Out>(funcName: string, allServices: CoreServices, wire: PikkuWire, data: In, userSession?: SessionService<CoreUserSession>) => Promise<Out>;
6
+ export declare const runPikkuFunc: <In = any, Out = any>(wireType: PikkuWiringTypes, wireId: string, funcName: string, { singletonServices, createWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags, wire, }: {
7
7
  singletonServices: CoreSingletonServices;
8
- getAllServices: (session?: CoreUserSession) => Promise<CoreServices> | CoreServices;
9
- userSession?: UserSessionService<CoreUserSession>;
8
+ createWireServices?: CreateWireServices;
10
9
  data: () => Promise<In> | In;
11
10
  auth?: boolean;
12
11
  inheritedMiddleware?: MiddlewareMetadata[];
@@ -15,5 +14,5 @@ export declare const runPikkuFunc: <In = any, Out = any>(wireType: PikkuWiringTy
15
14
  wirePermissions?: CorePermissionGroup | CorePikkuPermission[];
16
15
  coerceDataFromSchema?: boolean;
17
16
  tags?: string[];
18
- interaction: PikkuInteraction;
17
+ wire: PikkuWire;
19
18
  }) => Promise<Out>;
@@ -3,17 +3,24 @@ import { runPermissions } from '../permissions.js';
3
3
  import { pikkuState } from '../pikku-state.js';
4
4
  import { coerceTopLevelDataFromSchema, validateSchema } from '../schema.js';
5
5
  import { ForbiddenError } from '../errors/errors.js';
6
+ import { rpcService } from '../wirings/rpc/rpc-runner.js';
7
+ import { closeWireServices } from '../utils.js';
6
8
  export const addFunction = (funcName, funcConfig) => {
7
9
  pikkuState('function', 'functions').set(funcName, funcConfig);
8
10
  };
9
- export const runPikkuFuncDirectly = async (funcName, allServices, data, session) => {
11
+ export const runPikkuFuncDirectly = async (funcName, allServices, wire, data, userSession) => {
10
12
  const funcConfig = pikkuState('function', 'functions').get(funcName);
11
13
  if (!funcConfig) {
12
14
  throw new Error(`Function not found: ${funcName}`);
13
15
  }
14
- return (await funcConfig.func(allServices, data, session));
16
+ // Inject session into wire
17
+ const wireWithSession = {
18
+ ...wire,
19
+ session: userSession,
20
+ };
21
+ return (await funcConfig.func(allServices, data, wireWithSession));
15
22
  };
16
- export const runPikkuFunc = async (wireType, wireId, funcName, { getAllServices, singletonServices, data, userSession, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags = [], interaction, }) => {
23
+ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServices, createWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedPermissions, wirePermissions, coerceDataFromSchema, tags = [], wire, }) => {
17
24
  const funcConfig = pikkuState('function', 'functions').get(funcName);
18
25
  if (!funcConfig) {
19
26
  throw new Error(`Function not found: ${funcName}`);
@@ -29,16 +36,21 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { getAllServices,
29
36
  ];
30
37
  // Helper function to run permissions and execute the function
31
38
  const executeFunction = async () => {
32
- const session = await userSession?.get();
39
+ const initialSession = wire.session?.freezeInitial();
40
+ const wireWithInitialSession = {
41
+ ...wire,
42
+ initialSession,
43
+ };
33
44
  if (wiringAuth === true || funcConfig.auth === true) {
34
45
  // This means it was explicitly enabled in either wiring or function and has to be respected
35
- if (!session) {
46
+ if (!initialSession) {
36
47
  throw new ForbiddenError('Authentication required');
37
48
  }
38
49
  }
39
50
  if (wiringAuth === undefined && funcConfig.auth === undefined) {
40
51
  // We always default to requiring auth unless explicitly disabled
41
- if (!session) {
52
+ if (!initialSession) {
53
+ // TODO: Critical, we need to figure out how to make this work with different wirings
42
54
  // throw new ForbiddenError('Authentication required')
43
55
  }
44
56
  }
@@ -54,20 +66,30 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { getAllServices,
54
66
  coerceTopLevelDataFromSchema(inputSchemaName, actualData);
55
67
  }
56
68
  }
57
- const allServices = await getAllServices(session);
58
- // Run permissions check with combined permissions: inheritedPermissions (including tags) → wirePermissions → funcPermissions
59
69
  await runPermissions(wireType, wireId, {
60
70
  wireInheritedPermissions: mergedInheritedPermissions,
61
71
  wirePermissions: wirePermissions,
62
72
  funcInheritedPermissions: funcMeta.permissions,
63
73
  funcPermissions: funcConfig.permissions,
64
- allServices,
74
+ services: singletonServices,
75
+ wire: { ...wireWithInitialSession, rpc: undefined },
65
76
  data: actualData,
66
- session,
67
77
  });
68
- return await funcConfig.func(allServices, actualData, session);
78
+ const wireServices = await createWireServices?.(singletonServices, wireWithInitialSession);
79
+ try {
80
+ const services = { ...singletonServices, ...wireServices };
81
+ const rpc = rpcService.getContextRPCService(services, wireWithInitialSession);
82
+ return await funcConfig.func(services, actualData, {
83
+ ...wireWithInitialSession,
84
+ rpc,
85
+ });
86
+ }
87
+ finally {
88
+ if (wireServices) {
89
+ await closeWireServices(singletonServices.logger, wireServices);
90
+ }
91
+ }
69
92
  };
70
- // Combine all middleware: inheritedMiddleware → wireMiddleware → funcMiddleware
71
93
  const allMiddleware = combineMiddleware(wireType, wireId, {
72
94
  wireInheritedMiddleware: inheritedMiddleware,
73
95
  wireMiddleware,
@@ -75,10 +97,7 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { getAllServices,
75
97
  funcMiddleware: funcConfig.middleware,
76
98
  });
77
99
  if (allMiddleware.length > 0) {
78
- return (await runMiddleware({
79
- ...singletonServices,
80
- userSession,
81
- }, interaction, allMiddleware, executeFunction));
100
+ return (await runMiddleware(singletonServices, wire, allMiddleware, executeFunction));
82
101
  }
83
102
  return (await executeFunction());
84
103
  };
@@ -1,33 +1,23 @@
1
- import { PikkuChannel } from '../wirings/channel/channel.types.js';
2
- import type { CoreServices, CoreSingletonServices, CoreUserSession, PikkuDocs, CorePikkuMiddleware } from '../types/core.types.js';
1
+ import type { CoreServices, CoreSingletonServices, CoreUserSession, CorePikkuMiddleware, PikkuWire, PickRequired } from '../types/core.types.js';
2
+ import { Session } from 'inspector';
3
3
  /**
4
4
  * Represents a core API function that performs an operation using core services and a user session.
5
5
  *
6
6
  * @template In - The input type.
7
7
  * @template Out - The output type.
8
- * @template ChannelData - The channel data type.
9
8
  * @template Services - The services type, defaults to `CoreServices`.
10
- * @template Session - The session type, defaults to `CoreUserSession`.
9
+ * @template Wire - The wire type, defaults to `PikkuWire<In, Out>`.
11
10
  */
12
- export type CorePikkuFunction<In, Out, ChannelData extends unknown | null = null, Services extends CoreSingletonServices = CoreServices & (ChannelData extends null ? {
13
- channel?: PikkuChannel<unknown, Out> | undefined;
14
- } : {
15
- channel: PikkuChannel<ChannelData, Out>;
16
- }), Session extends CoreUserSession = CoreUserSession> = (services: Services, data: In, session: Session) => ChannelData extends null ? Promise<Out> : Promise<Out> | Promise<void>;
11
+ export type CorePikkuFunction<In, Out, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, Out> = PikkuWire<In, Out, true, Session>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Out> : Promise<Out> | Promise<void>;
17
12
  /**
18
13
  * Represents a core API function that can be used without a session.
19
14
  *
20
15
  * @template In - The input type.
21
16
  * @template Out - The output type.
22
- * @template ChannelData - The channel data type.
23
17
  * @template Services - The services type, defaults to `CoreServices`.
24
- * @template Session - The session type, defaults to `CoreUserSession`.
18
+ * @template Wire - The wire type, defaults to `PikkuWire<In, Out>`.
25
19
  */
26
- export type CorePikkuFunctionSessionless<In, Out, ChannelData extends unknown | null = null, Services extends CoreSingletonServices = CoreServices & (ChannelData extends null ? {
27
- channel?: PikkuChannel<unknown, Out> | undefined;
28
- } : {
29
- channel: PikkuChannel<ChannelData, Out>;
30
- }), Session extends CoreUserSession = CoreUserSession> = (services: Services, data: In, session?: Session) => ChannelData extends null ? Promise<Out> : Promise<Out> | Promise<void>;
20
+ export type CorePikkuFunctionSessionless<In, Out, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, Out, false, CoreUserSession, any, any, any> = PikkuWire<In, Out, false, CoreUserSession, any, any, any>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Out> : Promise<Out> | Promise<void>;
31
21
  /**
32
22
  * Represents a function that checks permissions for a given operation.
33
23
  *
@@ -35,7 +25,7 @@ export type CorePikkuFunctionSessionless<In, Out, ChannelData extends unknown |
35
25
  * @template Services - The services type, defaults to `CoreServices`.
36
26
  * @template Session - The session type, defaults to `CoreUserSession`.
37
27
  */
38
- export type CorePikkuPermission<In = any, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = (services: Services, data: In, session?: Session) => Promise<boolean>;
28
+ export type CorePikkuPermission<In = any, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, never, false, CoreUserSession, any, never, never> = PikkuWire<In, never, false, CoreUserSession, never, never, never>> = (services: Services, data: In, wire: Wire) => Promise<boolean>;
39
29
  /**
40
30
  * Configuration object for creating a permission with metadata
41
31
  *
@@ -43,9 +33,9 @@ export type CorePikkuPermission<In = any, Services extends CoreSingletonServices
43
33
  * @template Services - The services type, defaults to `CoreServices`.
44
34
  * @template Session - The session type, defaults to `CoreUserSession`.
45
35
  */
46
- export type CorePikkuPermissionConfig<In = any, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = {
36
+ export type CorePikkuPermissionConfig<In = any, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, never, false, CoreUserSession> = PikkuWire<In, never, false, CoreUserSession>> = {
47
37
  /** The permission function */
48
- func: CorePikkuPermission<In, Services, Session>;
38
+ func: CorePikkuPermission<In, Services, Wire>;
49
39
  /** Optional human-readable name for the permission */
50
40
  name?: string;
51
41
  /** Optional description of what the permission checks */
@@ -59,8 +49,9 @@ export type CorePikkuPermissionConfig<In = any, Services extends CoreSingletonSe
59
49
  * ```typescript
60
50
  * // Direct function syntax
61
51
  * export const adminPermission = pikkuPermission(
62
- * async ({ logger }, data, session) => {
63
- * return session?.role === 'admin'
52
+ * async ({ logger }, _data, { session }) => {
53
+ * const currentSession = await session.get()
54
+ * return currentSession?.role === 'admin'
64
55
  * }
65
56
  * )
66
57
  *
@@ -68,13 +59,14 @@ export type CorePikkuPermissionConfig<In = any, Services extends CoreSingletonSe
68
59
  * export const adminPermission = pikkuPermission({
69
60
  * name: 'Admin Permission',
70
61
  * description: 'Checks if user has admin role',
71
- * func: async ({ logger }, data, session) => {
72
- * return session?.role === 'admin'
62
+ * func: async ({ logger }, _data, { session }) => {
63
+ * const currentSession = await session.get()
64
+ * return currentSession?.role === 'admin'
73
65
  * }
74
66
  * })
75
67
  * ```
76
68
  */
77
- export declare const pikkuPermission: <In = any, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession>(permission: CorePikkuPermission<In, Services, Session> | CorePikkuPermissionConfig<In, Services, Session>) => CorePikkuPermission<In, Services, Session>;
69
+ export declare const pikkuPermission: <In = any, Services extends CoreSingletonServices = CoreServices, Wire extends PickRequired<PikkuWire<In, never, false, CoreUserSession>, "session"> = PickRequired<PikkuWire<In, never, false, CoreUserSession>, "session">>(permission: CorePikkuPermission<In, Services, Wire> | CorePikkuPermissionConfig<In, Services, Wire>) => CorePikkuPermission<In, Services, Wire>;
78
70
  /**
79
71
  * A factory function that takes input and returns a permission
80
72
  * Used when permissions need configuration/input parameters
@@ -83,7 +75,7 @@ export declare const pikkuPermission: <In = any, Services extends CoreSingletonS
83
75
  * @template Services - The services type, defaults to `CoreServices`.
84
76
  * @template Session - The session type, defaults to `CoreUserSession`.
85
77
  */
86
- export type CorePikkuPermissionFactory<In = any, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession> = (input: In) => CorePikkuPermission<any, Services, Session>;
78
+ export type CorePikkuPermissionFactory<In = any, Services extends CoreSingletonServices = CoreServices, Wire extends PikkuWire<In, never, false, CoreUserSession> = PikkuWire<In, never, false, CoreUserSession>> = (input: In) => CorePikkuPermission<any, Services, Wire>;
87
79
  /**
88
80
  * Factory function for creating permission factories
89
81
  * Use this when your permission needs configuration/input parameters
@@ -93,8 +85,9 @@ export type CorePikkuPermissionFactory<In = any, Services extends CoreSingletonS
93
85
  * export const requireRole = pikkuPermissionFactory<{ role: string }>(({
94
86
  * role
95
87
  * }) => {
96
- * return pikkuPermission(async ({ logger }, data, session) => {
97
- * if (!session || session.role !== role) {
88
+ * return pikkuPermission(async ({ logger }, data, { session }) => {
89
+ * const currentSession = await session.get()
90
+ * if (!currentSession || currentSession.role !== role) {
98
91
  * logger.warn(`Permission denied: required role '${role}'`)
99
92
  * return false
100
93
  * }
@@ -105,14 +98,13 @@ export type CorePikkuPermissionFactory<In = any, Services extends CoreSingletonS
105
98
  */
106
99
  export declare const pikkuPermissionFactory: <In = any>(factory: CorePikkuPermissionFactory<In>) => CorePikkuPermissionFactory<In>;
107
100
  export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> = Record<string, PikkuPermission | PikkuPermission[]> | undefined;
108
- export type CorePikkuFunctionConfig<PikkuFunction extends CorePikkuFunction<any, any, any, any, any> | CorePikkuFunctionSessionless<any, any, any, any, any>, PikkuPermission extends CorePikkuPermission<any, any, any> = CorePikkuPermission<any>, PikkuMiddleware extends CorePikkuMiddleware<any> = CorePikkuMiddleware<any>> = {
101
+ export type CorePikkuFunctionConfig<PikkuFunction extends CorePikkuFunction<any, any, any, any> | CorePikkuFunctionSessionless<any, any, any, any>, PikkuPermission extends CorePikkuPermission<any, any, any> = CorePikkuPermission<any>, PikkuMiddleware extends CorePikkuMiddleware<any, any> = CorePikkuMiddleware<any, any>> = {
109
102
  name?: string;
103
+ tags?: string[];
110
104
  expose?: boolean;
111
105
  internal?: boolean;
112
106
  func: PikkuFunction;
113
107
  auth?: boolean;
114
108
  permissions?: CorePermissionGroup<PikkuPermission>;
115
109
  middleware?: PikkuMiddleware[];
116
- tags?: string[];
117
- docs?: PikkuDocs;
118
110
  };
@@ -6,8 +6,9 @@
6
6
  * ```typescript
7
7
  * // Direct function syntax
8
8
  * export const adminPermission = pikkuPermission(
9
- * async ({ logger }, data, session) => {
10
- * return session?.role === 'admin'
9
+ * async ({ logger }, _data, { session }) => {
10
+ * const currentSession = await session.get()
11
+ * return currentSession?.role === 'admin'
11
12
  * }
12
13
  * )
13
14
  *
@@ -15,8 +16,9 @@
15
16
  * export const adminPermission = pikkuPermission({
16
17
  * name: 'Admin Permission',
17
18
  * description: 'Checks if user has admin role',
18
- * func: async ({ logger }, data, session) => {
19
- * return session?.role === 'admin'
19
+ * func: async ({ logger }, _data, { session }) => {
20
+ * const currentSession = await session.get()
21
+ * return currentSession?.role === 'admin'
20
22
  * }
21
23
  * })
22
24
  * ```
@@ -33,8 +35,9 @@ export const pikkuPermission = (permission) => {
33
35
  * export const requireRole = pikkuPermissionFactory<{ role: string }>(({
34
36
  * role
35
37
  * }) => {
36
- * return pikkuPermission(async ({ logger }, data, session) => {
37
- * if (!session || session.role !== role) {
38
+ * return pikkuPermission(async ({ logger }, data, { session }) => {
39
+ * const currentSession = await session.get()
40
+ * if (!currentSession || currentSession.role !== role) {
38
41
  * logger.warn(`Permission denied: required role '${role}'`)
39
42
  * return false
40
43
  * }
@@ -4,7 +4,7 @@ import { PikkuHTTP } from './wirings/http/http.types.js';
4
4
  * Handle errors that occur during route processing
5
5
  *
6
6
  * @param {any} e - The error that occurred
7
- * @param {PikkuHTTP | undefined} http - HTTP interaction object
7
+ * @param {PikkuHTTP | undefined} http - HTTP wire object
8
8
  * @param {string} trackerId - Unique ID for tracking this error
9
9
  * @param {Logger} logger - Logger service
10
10
  * @param {number[]} logWarningsForStatusCodes - HTTP status codes to log as warnings
@@ -4,7 +4,7 @@ import { NotFoundError } from './errors/errors.js';
4
4
  * Handle errors that occur during route processing
5
5
  *
6
6
  * @param {any} e - The error that occurred
7
- * @param {PikkuHTTP | undefined} http - HTTP interaction object
7
+ * @param {PikkuHTTP | undefined} http - HTTP wire object
8
8
  * @param {string} trackerId - Unique ID for tracking this error
9
9
  * @param {Logger} logger - Logger service
10
10
  * @param {number[]} logWarningsForStatusCodes - HTTP status codes to log as warnings
@@ -16,8 +16,8 @@ import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
16
16
  * ])
17
17
  * ```
18
18
  */
19
- export const authAPIKey = pikkuMiddlewareFactory(({ source }) => pikkuMiddleware(async ({ userSession: userSessionService, jwt: jwtService }, { http }, next) => {
20
- if (!http?.request || userSessionService.get()) {
19
+ export const authAPIKey = pikkuMiddlewareFactory(({ source }) => pikkuMiddleware(async ({ jwt: jwtService }, { http, session: SessionService }, next) => {
20
+ if (!http?.request || !SessionService || SessionService.get()) {
21
21
  return next();
22
22
  }
23
23
  let apiKey = null;
@@ -30,7 +30,7 @@ export const authAPIKey = pikkuMiddlewareFactory(({ source }) => pikkuMiddleware
30
30
  if (apiKey && jwtService) {
31
31
  const userSession = await jwtService.decode(apiKey);
32
32
  if (userSession) {
33
- userSessionService.setInitial(userSession);
33
+ SessionService.setInitial(userSession);
34
34
  }
35
35
  }
36
36
  return next();
@@ -29,9 +29,9 @@ import { pikkuMiddleware, pikkuMiddlewareFactory, } from '../types/core.types.js
29
29
  * ])
30
30
  * ```
31
31
  */
32
- export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddleware(async ({ userSession: userSessionService, jwt: jwtService }, { http }, next) => {
32
+ export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddleware(async ({ jwt: jwtService }, { http, session }, next) => {
33
33
  // Skip if session already exists.
34
- if (!http?.request || userSessionService.get()) {
34
+ if (!http?.request || !session || session.get()) {
35
35
  return next();
36
36
  }
37
37
  const authHeader = http.request.header('authorization') ||
@@ -51,7 +51,7 @@ export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddle
51
51
  userSession = await jwtService.decode(bearerToken);
52
52
  }
53
53
  if (userSession) {
54
- userSessionService.setInitial(userSession);
54
+ session.setInitial(userSession);
55
55
  }
56
56
  }
57
57
  return next();
@@ -28,8 +28,8 @@ import { getRelativeTimeOffsetFromNow, } from '../time-utils.js';
28
28
  * ])
29
29
  * ```
30
30
  */
31
- export const authCookie = pikkuMiddlewareFactory(({ name, options, expiresIn }) => pikkuMiddleware(async ({ userSession: userSessionService, jwt: jwtService, logger }, { http }, next) => {
32
- if (!http?.request || userSessionService.get()) {
31
+ export const authCookie = pikkuMiddlewareFactory(({ name, options, expiresIn }) => pikkuMiddleware(async ({ jwt: jwtService, logger }, { http, session: SessionService }, next) => {
32
+ if (!http?.request || !SessionService || SessionService.get()) {
33
33
  return next();
34
34
  }
35
35
  // Try to decode session from cookie
@@ -37,7 +37,7 @@ export const authCookie = pikkuMiddlewareFactory(({ name, options, expiresIn })
37
37
  if (cookieValue && jwtService) {
38
38
  const userSession = await jwtService.decode(cookieValue);
39
39
  if (userSession) {
40
- userSessionService.setInitial(userSession);
40
+ SessionService.setInitial(userSession);
41
41
  }
42
42
  }
43
43
  await next();
@@ -45,8 +45,8 @@ export const authCookie = pikkuMiddlewareFactory(({ name, options, expiresIn })
45
45
  if (!http?.response) {
46
46
  return;
47
47
  }
48
- if (userSessionService.sessionChanged) {
49
- const session = userSessionService.get();
48
+ if (SessionService.sessionChanged) {
49
+ const session = SessionService.get();
50
50
  if (jwtService) {
51
51
  http.response.cookie(name, await jwtService.encode(expiresIn, session), {
52
52
  ...options,
@@ -1,8 +1,9 @@
1
1
  import { RequestTimeoutError } from '../errors/errors.js';
2
2
  import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js';
3
- export const timeout = () => pikkuMiddlewareFactory(({ timeout }) => pikkuMiddleware(async (_services, _interaction, next) => {
4
- setTimeout(() => {
3
+ export const timeout = () => pikkuMiddlewareFactory(({ timeout }) => pikkuMiddleware(async (_services, _wire, next) => {
4
+ const timeoutId = setTimeout(() => {
5
5
  throw new RequestTimeoutError();
6
6
  }, timeout);
7
7
  await next();
8
+ clearTimeout(timeoutId);
8
9
  }));
@@ -1,10 +1,9 @@
1
- import { UserSessionService } from './services/user-session-service.js';
2
- import { CoreSingletonServices, PikkuInteraction, CorePikkuMiddleware, CorePikkuMiddlewareGroup, PikkuWiringTypes, MiddlewareMetadata } from './types/core.types.js';
1
+ import { CoreSingletonServices, PikkuWire, CorePikkuMiddleware, CorePikkuMiddlewareGroup, PikkuWiringTypes, MiddlewareMetadata } from './types/core.types.js';
3
2
  /**
4
3
  * Runs a chain of middleware functions in sequence before executing the main function.
5
4
  *
6
5
  * @param services - An object containing services (e.g., singletonServices, userSession, etc.)
7
- * @param interaction - The interaction context, e.g., { http }.
6
+ * @param wire - The wire context, e.g., { http }.
8
7
  * @param middlewares - An array of middleware functions to run.
9
8
  * @param main - The main function to execute after all middleware have run.
10
9
  * @returns A promise resolving to the result of the main function.
@@ -17,9 +16,7 @@ import { CoreSingletonServices, PikkuInteraction, CorePikkuMiddleware, CorePikku
17
16
  * async () => { return await runMain(); }
18
17
  * );
19
18
  */
20
- export declare const runMiddleware: <Middleware extends CorePikkuMiddleware>(services: CoreSingletonServices & {
21
- userSession?: UserSessionService<any>;
22
- }, interaction: PikkuInteraction, middlewares: readonly Middleware[], main?: () => Promise<unknown>) => Promise<unknown>;
19
+ export declare const runMiddleware: <Middleware extends CorePikkuMiddleware>(services: CoreSingletonServices, wire: PikkuWire, middlewares: readonly Middleware[], main?: () => Promise<unknown>) => Promise<unknown>;
23
20
  /**
24
21
  * Registers global middleware for a specific tag.
25
22
  *
@@ -1,11 +1,10 @@
1
- import { PikkuWiringTypes, } from './types/core.types.js';
2
1
  import { pikkuState } from './pikku-state.js';
3
2
  import { freezeDedupe } from './utils.js';
4
3
  /**
5
4
  * Runs a chain of middleware functions in sequence before executing the main function.
6
5
  *
7
6
  * @param services - An object containing services (e.g., singletonServices, userSession, etc.)
8
- * @param interaction - The interaction context, e.g., { http }.
7
+ * @param wire - The wire context, e.g., { http }.
9
8
  * @param middlewares - An array of middleware functions to run.
10
9
  * @param main - The main function to execute after all middleware have run.
11
10
  * @returns A promise resolving to the result of the main function.
@@ -18,12 +17,12 @@ import { freezeDedupe } from './utils.js';
18
17
  * async () => { return await runMain(); }
19
18
  * );
20
19
  */
21
- export const runMiddleware = async (services, interaction, middlewares, main) => {
20
+ export const runMiddleware = async (services, wire, middlewares, main) => {
22
21
  // Deduplicate middleware using Set to avoid running the same middleware multiple times
23
22
  let result;
24
23
  const dispatch = async (index) => {
25
24
  if (middlewares && index < middlewares.length) {
26
- return await middlewares[index](services, interaction, () => dispatch(index + 1));
25
+ return await middlewares[index](services, wire, () => dispatch(index + 1));
27
26
  }
28
27
  else if (main) {
29
28
  result = await main();
@@ -87,14 +86,14 @@ export const getMiddlewareByName = (name) => {
87
86
  return middleware?.[0];
88
87
  };
89
88
  const middlewareCache = {
90
- [PikkuWiringTypes.http]: {},
91
- [PikkuWiringTypes.rpc]: {},
92
- [PikkuWiringTypes.channel]: {},
93
- [PikkuWiringTypes.queue]: {},
94
- [PikkuWiringTypes.scheduler]: {},
95
- [PikkuWiringTypes.mcp]: {},
96
- [PikkuWiringTypes.cli]: {},
97
- [PikkuWiringTypes.workflow]: {},
89
+ http: {},
90
+ rpc: {},
91
+ channel: {},
92
+ queue: {},
93
+ scheduler: {},
94
+ mcp: {},
95
+ cli: {},
96
+ workflow: {},
98
97
  };
99
98
  /**
100
99
  * Combines wiring-specific middleware with function-level middleware.
@@ -1,13 +1,13 @@
1
- import { CoreServices, CoreUserSession, PikkuWiringTypes, PermissionMetadata } from './types/core.types.js';
1
+ import { CoreServices, PikkuWiringTypes, PermissionMetadata, PikkuWire } from './types/core.types.js';
2
2
  import { CorePermissionGroup, CorePikkuPermission } from './function/functions.types.js';
3
3
  /**
4
4
  * This function validates permissions by iterating over permission groups and executing the corresponding permission functions. If all functions in at least one group return true, the permission is considered valid.
5
5
  * @param services - The core services required for permission validation.
6
6
  * @param data - The data to be used in the permission validation functions.
7
- * @param session - An optional user session for permission validation.
7
+ * @param wire - The wire object containing request/response context and session.
8
8
  * @returns A promise that resolves to void.
9
9
  */
10
- export declare const verifyPermissions: (permissions: CorePermissionGroup, services: CoreServices, data: any, session?: CoreUserSession) => Promise<boolean>;
10
+ export declare const verifyPermissions: <Out = any>(permissions: CorePermissionGroup, services: CoreServices, data: any, wire: PikkuWire<any, never, any, never, never, never>) => Promise<boolean>;
11
11
  /**
12
12
  * Registers a single permission function by name in the global permission store.
13
13
  *
@@ -117,12 +117,12 @@ export declare const combinePermissions: (wireType: PikkuWiringTypes, uid: strin
117
117
  * Runs permission checks using combined permissions from all sources.
118
118
  * Combines permissions from wire and function levels, then validates them.
119
119
  */
120
- export declare const runPermissions: (wireType: PikkuWiringTypes, uid: string, { wireInheritedPermissions, wirePermissions, funcInheritedPermissions, funcPermissions, allServices, data, session, }: {
120
+ export declare const runPermissions: (wireType: PikkuWiringTypes, uid: string, { wireInheritedPermissions, wirePermissions, funcInheritedPermissions, funcPermissions, services, wire, data, }: {
121
121
  wireInheritedPermissions?: PermissionMetadata[];
122
122
  wirePermissions?: CorePermissionGroup | CorePikkuPermission[];
123
123
  funcInheritedPermissions?: PermissionMetadata[];
124
124
  funcPermissions?: CorePermissionGroup | CorePikkuPermission[];
125
- allServices: CoreServices;
125
+ services: CoreServices;
126
+ wire: PikkuWire<any, never, any, never, never, never>;
126
127
  data: any;
127
- session?: CoreUserSession;
128
128
  }) => Promise<void>;