@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.
- package/CHANGELOG.md +11 -1
- package/dist/errors/errors.d.ts +1 -1
- package/dist/errors/errors.js +3 -3
- package/dist/function/function-runner.d.ts +6 -7
- package/dist/function/function-runner.js +35 -16
- package/dist/function/functions.types.d.ts +22 -30
- package/dist/function/functions.types.js +9 -6
- package/dist/handle-error.d.ts +1 -1
- package/dist/handle-error.js +1 -1
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.js +3 -3
- package/dist/middleware/auth-cookie.js +5 -5
- package/dist/middleware/timeout.js +3 -2
- package/dist/middleware-runner.d.ts +3 -6
- package/dist/middleware-runner.js +11 -12
- package/dist/permissions.d.ts +6 -6
- package/dist/permissions.js +15 -16
- package/dist/services/user-session-service.d.ts +7 -3
- package/dist/services/user-session-service.js +8 -1
- package/dist/types/core.types.d.ts +29 -38
- package/dist/types/core.types.js +3 -14
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -3
- package/dist/wirings/channel/channel-common.js +2 -3
- package/dist/wirings/channel/channel-handler.d.ts +3 -2
- package/dist/wirings/channel/channel-handler.js +6 -9
- package/dist/wirings/channel/channel-runner.d.ts +2 -2
- package/dist/wirings/channel/channel.types.d.ts +10 -5
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.js +19 -26
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +41 -46
- package/dist/wirings/cli/cli-runner.d.ts +5 -5
- package/dist/wirings/cli/cli-runner.js +10 -28
- package/dist/wirings/cli/cli.types.d.ts +15 -11
- package/dist/wirings/http/http-runner.d.ts +6 -6
- package/dist/wirings/http/http-runner.js +25 -39
- package/dist/wirings/http/http.types.d.ts +5 -10
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -2
- package/dist/wirings/mcp/mcp-runner.js +12 -19
- package/dist/wirings/mcp/mcp.types.d.ts +6 -0
- package/dist/wirings/queue/queue-runner.d.ts +3 -3
- package/dist/wirings/queue/queue-runner.js +7 -17
- package/dist/wirings/queue/queue.types.d.ts +4 -11
- package/dist/wirings/rpc/rpc-runner.d.ts +10 -8
- package/dist/wirings/rpc/rpc-runner.js +36 -47
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -3
- package/dist/wirings/scheduler/scheduler-runner.js +13 -24
- package/dist/wirings/scheduler/scheduler.types.d.ts +3 -8
- package/dist/wirings/workflow/index.d.ts +11 -2
- package/dist/wirings/workflow/index.js +10 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +12 -4
- package/dist/wirings/workflow/pikku-workflow-service.js +61 -79
- package/dist/wirings/workflow/workflow-runner.d.ts +3 -4
- package/dist/wirings/workflow/workflow-runner.js +11 -14
- package/dist/wirings/workflow/workflow.types.d.ts +114 -29
- package/package.json +2 -2
- package/src/errors/errors.ts +3 -3
- package/src/factory-functions.test.ts +9 -36
- package/src/function/function-runner.test.ts +57 -68
- package/src/function/function-runner.ts +51 -28
- package/src/function/function-runner.ts.bak +188 -0
- package/src/function/functions.types.ts +68 -51
- package/src/handle-error.ts +1 -1
- package/src/middleware/auth-apikey.test.ts +360 -0
- package/src/middleware/auth-apikey.ts +3 -7
- package/src/middleware/auth-bearer.test.ts +447 -0
- package/src/middleware/auth-bearer.ts +27 -33
- package/src/middleware/auth-cookie.test.ts +525 -0
- package/src/middleware/auth-cookie.ts +6 -6
- package/src/middleware/timeout.ts +4 -2
- package/src/middleware-runner.test.ts +58 -127
- package/src/middleware-runner.ts +13 -16
- package/src/permissions.test.ts +41 -45
- package/src/permissions.ts +21 -21
- package/src/services/user-session-service.ts +14 -4
- package/src/types/core.types.ts +67 -55
- package/src/utils.ts +4 -4
- package/src/wirings/channel/channel-common.ts +4 -7
- package/src/wirings/channel/channel-handler.ts +16 -22
- package/src/wirings/channel/channel-runner.ts +2 -2
- package/src/wirings/channel/channel.types.ts +14 -11
- package/src/wirings/channel/local/local-channel-runner.test.ts +5 -3
- package/src/wirings/channel/local/local-channel-runner.ts +23 -38
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +51 -77
- package/src/wirings/cli/cli-runner.test.ts +7 -7
- package/src/wirings/cli/cli-runner.ts +24 -62
- package/src/wirings/cli/cli.types.ts +22 -16
- package/src/wirings/http/http-runner.test.ts +8 -8
- package/src/wirings/http/http-runner.ts +29 -56
- package/src/wirings/http/http.types.ts +5 -14
- package/src/wirings/mcp/mcp-runner.ts +23 -48
- package/src/wirings/mcp/mcp.types.ts +6 -0
- package/src/wirings/queue/queue-runner.test.ts +641 -0
- package/src/wirings/queue/queue-runner.ts +10 -32
- package/src/wirings/queue/queue.types.ts +4 -11
- package/src/wirings/rpc/rpc-runner.ts +41 -55
- package/src/wirings/scheduler/scheduler-runner.test.ts +627 -0
- package/src/wirings/scheduler/scheduler-runner.ts +24 -50
- package/src/wirings/scheduler/scheduler.types.ts +3 -9
- package/src/wirings/workflow/index.ts +24 -3
- package/src/wirings/workflow/pikku-workflow-service.ts +83 -93
- package/src/wirings/workflow/workflow-runner.ts +12 -25
- package/src/wirings/workflow/workflow.types.ts +144 -54
- package/tsconfig.tsbuildinfo +1 -1
package/dist/permissions.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { PikkuWiringTypes, } from './types/core.types.js';
|
|
2
1
|
import { pikkuState } from './pikku-state.js';
|
|
3
2
|
import { ForbiddenError } from './errors/errors.js';
|
|
4
3
|
import { freezeDedupe } from './utils.js';
|
|
@@ -6,10 +5,10 @@ import { freezeDedupe } from './utils.js';
|
|
|
6
5
|
* 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.
|
|
7
6
|
* @param services - The core services required for permission validation.
|
|
8
7
|
* @param data - The data to be used in the permission validation functions.
|
|
9
|
-
* @param
|
|
8
|
+
* @param wire - The wire object containing request/response context and session.
|
|
10
9
|
* @returns A promise that resolves to void.
|
|
11
10
|
*/
|
|
12
|
-
export const verifyPermissions = async (permissions, services, data,
|
|
11
|
+
export const verifyPermissions = async (permissions, services, data, wire) => {
|
|
13
12
|
if (!permissions) {
|
|
14
13
|
return true;
|
|
15
14
|
}
|
|
@@ -20,13 +19,13 @@ export const verifyPermissions = async (permissions, services, data, session) =>
|
|
|
20
19
|
}
|
|
21
20
|
for (const funcs of permissionGroups) {
|
|
22
21
|
if (funcs instanceof Array) {
|
|
23
|
-
const permissioned = await Promise.all(funcs.map((func) => func(services, data,
|
|
22
|
+
const permissioned = await Promise.all(funcs.map((func) => func(services, data, wire)));
|
|
24
23
|
if (permissioned.every((result) => result)) {
|
|
25
24
|
valid = true;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
else {
|
|
29
|
-
valid = await funcs(services, data,
|
|
28
|
+
valid = await funcs(services, data, wire);
|
|
30
29
|
}
|
|
31
30
|
if (valid) {
|
|
32
31
|
return true;
|
|
@@ -147,14 +146,14 @@ export const getPermissionsForTags = (tags) => {
|
|
|
147
146
|
return applicablePermissions;
|
|
148
147
|
};
|
|
149
148
|
const combinedPermissionsCache = {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
149
|
+
http: {},
|
|
150
|
+
rpc: {},
|
|
151
|
+
channel: {},
|
|
152
|
+
queue: {},
|
|
153
|
+
scheduler: {},
|
|
154
|
+
mcp: {},
|
|
155
|
+
cli: {},
|
|
156
|
+
workflow: {},
|
|
158
157
|
};
|
|
159
158
|
/**
|
|
160
159
|
* Combines wiring-specific permissions with function-level permissions.
|
|
@@ -265,7 +264,7 @@ export const combinePermissions = (wireType, uid, { wireInheritedPermissions, wi
|
|
|
265
264
|
* Runs permission checks using combined permissions from all sources.
|
|
266
265
|
* Combines permissions from wire and function levels, then validates them.
|
|
267
266
|
*/
|
|
268
|
-
export const runPermissions = async (wireType, uid, { wireInheritedPermissions, wirePermissions, funcInheritedPermissions, funcPermissions,
|
|
267
|
+
export const runPermissions = async (wireType, uid, { wireInheritedPermissions, wirePermissions, funcInheritedPermissions, funcPermissions, services, wire, data, }) => {
|
|
269
268
|
// Combine all permissions: wireInheritedPermissions → wirePermissions → funcInheritedPermissions → funcPermissions
|
|
270
269
|
const allPermissions = combinePermissions(wireType, uid, {
|
|
271
270
|
wireInheritedPermissions,
|
|
@@ -277,14 +276,14 @@ export const runPermissions = async (wireType, uid, { wireInheritedPermissions,
|
|
|
277
276
|
if (allPermissions.length > 0) {
|
|
278
277
|
let permissioned = false;
|
|
279
278
|
for (const permission of allPermissions) {
|
|
280
|
-
const result = await verifyPermissions(typeof permission === 'function' ? { permission } : permission,
|
|
279
|
+
const result = await verifyPermissions(typeof permission === 'function' ? { permission } : permission, services, data, wire);
|
|
281
280
|
if (result) {
|
|
282
281
|
permissioned = true;
|
|
283
282
|
// Continue executing all permissions (don't break early)
|
|
284
283
|
}
|
|
285
284
|
}
|
|
286
285
|
if (!permissioned) {
|
|
287
|
-
|
|
286
|
+
services.logger.debug('Permission denied - combined permissions');
|
|
288
287
|
throw new ForbiddenError('Permission denied');
|
|
289
288
|
}
|
|
290
289
|
}
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { ChannelStore } from '../wirings/channel/channel-store.js';
|
|
2
2
|
import { CoreUserSession } from '../types/core.types.js';
|
|
3
|
-
export interface
|
|
3
|
+
export interface SessionService<UserSession extends CoreUserSession> {
|
|
4
4
|
sessionChanged: boolean;
|
|
5
|
+
initial: UserSession | undefined;
|
|
5
6
|
setInitial(session: UserSession): void;
|
|
7
|
+
freezeInitial(): UserSession | undefined;
|
|
6
8
|
set(session: UserSession): Promise<void> | void;
|
|
7
9
|
clear(): Promise<void> | void;
|
|
8
|
-
get(): Promise<UserSession
|
|
10
|
+
get(): Promise<UserSession> | UserSession | undefined;
|
|
9
11
|
}
|
|
10
|
-
export declare class
|
|
12
|
+
export declare class PikkuSessionService<UserSession extends CoreUserSession> implements SessionService<UserSession> {
|
|
11
13
|
private channelStore?;
|
|
12
14
|
private channelId?;
|
|
13
15
|
sessionChanged: boolean;
|
|
16
|
+
initial: UserSession | undefined;
|
|
14
17
|
private session;
|
|
15
18
|
constructor(channelStore?: ChannelStore<unknown, unknown, UserSession> | undefined, channelId?: string | undefined);
|
|
16
19
|
setInitial(session: UserSession): void;
|
|
20
|
+
freezeInitial(): UserSession | undefined;
|
|
17
21
|
set(session: UserSession): void | Promise<void> | undefined;
|
|
18
22
|
clear(): void | Promise<void> | undefined;
|
|
19
23
|
get(): Promise<UserSession> | UserSession | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export class
|
|
1
|
+
export class PikkuSessionService {
|
|
2
2
|
channelStore;
|
|
3
3
|
channelId;
|
|
4
4
|
sessionChanged = false;
|
|
5
|
+
initial;
|
|
5
6
|
session;
|
|
6
7
|
constructor(channelStore, channelId) {
|
|
7
8
|
this.channelStore = channelStore;
|
|
@@ -13,6 +14,12 @@ export class PikkuUserSessionService {
|
|
|
13
14
|
setInitial(session) {
|
|
14
15
|
this.session = session;
|
|
15
16
|
}
|
|
17
|
+
freezeInitial() {
|
|
18
|
+
if (this.initial === undefined) {
|
|
19
|
+
this.initial = this.session;
|
|
20
|
+
}
|
|
21
|
+
return this.initial;
|
|
22
|
+
}
|
|
16
23
|
set(session) {
|
|
17
24
|
this.sessionChanged = true;
|
|
18
25
|
this.session = session;
|
|
@@ -3,25 +3,16 @@ import { VariablesService } from '../services/variables-service.js';
|
|
|
3
3
|
import { SchemaService } from '../services/schema-service.js';
|
|
4
4
|
import { JWTService } from '../services/jwt-service.js';
|
|
5
5
|
import { PikkuHTTP } from '../wirings/http/http.types.js';
|
|
6
|
-
import {
|
|
6
|
+
import { SessionService } from '../services/user-session-service.js';
|
|
7
7
|
import { PikkuChannel } from '../wirings/channel/channel.types.js';
|
|
8
8
|
import { PikkuRPC } from '../wirings/rpc/rpc-types.js';
|
|
9
9
|
import { PikkuMCP } from '../wirings/mcp/mcp.types.js';
|
|
10
10
|
import { PikkuScheduledTask } from '../wirings/scheduler/scheduler.types.js';
|
|
11
11
|
import { PikkuQueue, QueueService } from '../wirings/queue/queue.types.js';
|
|
12
12
|
import { PikkuCLI } from '../wirings/cli/cli.types.js';
|
|
13
|
-
import {
|
|
13
|
+
import { PikkuWorkflowWire, WorkflowService, WorkflowServiceConfig, WorkflowStepWire } from '../wirings/workflow/workflow.types.js';
|
|
14
14
|
import { SchedulerService } from '../services/scheduler-service.js';
|
|
15
|
-
export
|
|
16
|
-
http = "http",
|
|
17
|
-
scheduler = "scheduler",
|
|
18
|
-
channel = "channel",
|
|
19
|
-
rpc = "rpc",
|
|
20
|
-
queue = "queue",
|
|
21
|
-
mcp = "mcp",
|
|
22
|
-
cli = "cli",
|
|
23
|
-
workflow = "workflow"
|
|
24
|
-
}
|
|
15
|
+
export type PikkuWiringTypes = 'http' | 'scheduler' | 'channel' | 'rpc' | 'queue' | 'mcp' | 'cli' | 'workflow';
|
|
25
16
|
export interface FunctionServicesMeta {
|
|
26
17
|
optimized: boolean;
|
|
27
18
|
services: string[];
|
|
@@ -70,14 +61,13 @@ export type FunctionRuntimeMeta = {
|
|
|
70
61
|
export type FunctionMeta = FunctionRuntimeMeta & Partial<{
|
|
71
62
|
name: string;
|
|
72
63
|
services: FunctionServicesMeta;
|
|
64
|
+
usedWires: string[];
|
|
73
65
|
inputs: string[] | null;
|
|
74
66
|
outputs: string[] | null;
|
|
75
|
-
tags: string[];
|
|
76
|
-
docs: PikkuDocs;
|
|
77
|
-
isDirectFunction: boolean;
|
|
78
67
|
middleware: MiddlewareMetadata[];
|
|
79
68
|
permissions: PermissionMetadata[];
|
|
80
|
-
|
|
69
|
+
isDirectFunction: boolean;
|
|
70
|
+
} & CommonWireMeta>;
|
|
81
71
|
export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>;
|
|
82
72
|
export type FunctionsMeta = Record<string, FunctionMeta>;
|
|
83
73
|
export type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
|
@@ -142,25 +132,25 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
|
|
|
142
132
|
schedulerService?: SchedulerService;
|
|
143
133
|
}
|
|
144
134
|
/**
|
|
145
|
-
* Represents different forms of
|
|
135
|
+
* Represents different forms of wire within Pikku and the outside world.
|
|
146
136
|
*/
|
|
147
|
-
export type
|
|
137
|
+
export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boolean = false, UserSession extends CoreUserSession = CoreUserSession, TypedRPC extends PikkuRPC = PikkuRPC, IsChannel extends true | null = null, MCPTools extends string | never = never, TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire> = Partial<{
|
|
148
138
|
http: PikkuHTTP<In>;
|
|
149
|
-
mcp: PikkuMCP
|
|
150
|
-
rpc:
|
|
151
|
-
channel: PikkuChannel<unknown, Out
|
|
139
|
+
mcp: PikkuMCP<MCPTools>;
|
|
140
|
+
rpc: TypedRPC;
|
|
141
|
+
channel: [IsChannel] extends [null] ? PikkuChannel<unknown, Out> : PikkuChannel<unknown, Out> | undefined;
|
|
152
142
|
scheduledTask: PikkuScheduledTask;
|
|
153
143
|
queue: PikkuQueue;
|
|
154
144
|
cli: PikkuCLI;
|
|
155
|
-
workflow:
|
|
156
|
-
workflowStep:
|
|
145
|
+
workflow: TypedWorkflow;
|
|
146
|
+
workflowStep: WorkflowStepWire;
|
|
147
|
+
initialSession: HasInitialSession extends true ? UserSession : UserSession | undefined;
|
|
148
|
+
session: SessionService<UserSession>;
|
|
157
149
|
}>;
|
|
158
150
|
/**
|
|
159
|
-
* A function that can wrap an
|
|
151
|
+
* A function that can wrap an wire and be called before or after
|
|
160
152
|
*/
|
|
161
|
-
export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices
|
|
162
|
-
userSession: UserSessionService<UserSession>;
|
|
163
|
-
}, interactions: PikkuInteraction, next: () => Promise<void>) => Promise<void>;
|
|
153
|
+
export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wires: PikkuWire<unknown, unknown, false, UserSession>, next: () => Promise<void>) => Promise<void>;
|
|
164
154
|
/**
|
|
165
155
|
* Configuration object for creating middleware with metadata
|
|
166
156
|
*
|
|
@@ -193,7 +183,7 @@ export type CorePikkuMiddlewareGroup<SingletonServices extends CoreSingletonServ
|
|
|
193
183
|
* ```typescript
|
|
194
184
|
* // Direct function syntax
|
|
195
185
|
* export const logMiddleware = pikkuMiddleware(
|
|
196
|
-
* async ({ logger },
|
|
186
|
+
* async ({ logger }, next) => {
|
|
197
187
|
* logger.info('Request started')
|
|
198
188
|
* await next()
|
|
199
189
|
* }
|
|
@@ -203,7 +193,7 @@ export type CorePikkuMiddlewareGroup<SingletonServices extends CoreSingletonServ
|
|
|
203
193
|
* export const logMiddleware = pikkuMiddleware({
|
|
204
194
|
* name: 'Request Logger',
|
|
205
195
|
* description: 'Logs request information',
|
|
206
|
-
* func: async ({ logger },
|
|
196
|
+
* func: async ({ logger }, next) => {
|
|
207
197
|
* logger.info('Request started')
|
|
208
198
|
* await next()
|
|
209
199
|
* }
|
|
@@ -221,7 +211,7 @@ export declare const pikkuMiddleware: <SingletonServices extends CoreSingletonSe
|
|
|
221
211
|
* message,
|
|
222
212
|
* level = 'info'
|
|
223
213
|
* }) => {
|
|
224
|
-
* return pikkuMiddleware(async ({ logger },
|
|
214
|
+
* return pikkuMiddleware(async ({ logger }, next) => {
|
|
225
215
|
* logger[level](message)
|
|
226
216
|
* await next()
|
|
227
217
|
* })
|
|
@@ -230,12 +220,10 @@ export declare const pikkuMiddleware: <SingletonServices extends CoreSingletonSe
|
|
|
230
220
|
*/
|
|
231
221
|
export declare const pikkuMiddlewareFactory: <In = any>(factory: CorePikkuMiddlewareFactory<In>) => CorePikkuMiddlewareFactory<In>;
|
|
232
222
|
/**
|
|
233
|
-
* Represents the core services used by Pikku, including singleton services
|
|
223
|
+
* Represents the core services used by Pikku, including singleton services.
|
|
234
224
|
*/
|
|
235
|
-
export type CoreServices<SingletonServices = CoreSingletonServices
|
|
236
|
-
|
|
237
|
-
};
|
|
238
|
-
export type SessionServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services = CoreServices<SingletonServices>> = Omit<Services, keyof SingletonServices | keyof PikkuInteraction | 'session'>;
|
|
225
|
+
export type CoreServices<SingletonServices = CoreSingletonServices> = SingletonServices;
|
|
226
|
+
export type WireServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services = CoreServices<SingletonServices>> = Omit<Services, keyof SingletonServices | 'session'>;
|
|
239
227
|
/**
|
|
240
228
|
* Defines a function type for creating singleton services from the given configuration.
|
|
241
229
|
*/
|
|
@@ -243,7 +231,7 @@ export type CreateSingletonServices<Config extends CoreConfig, SingletonServices
|
|
|
243
231
|
/**
|
|
244
232
|
* Defines a function type for creating session-specific services.
|
|
245
233
|
*/
|
|
246
|
-
export type
|
|
234
|
+
export type CreateWireServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services extends CoreServices<SingletonServices> = CoreServices<SingletonServices>, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wire: PikkuWire<unknown, unknown, false, UserSession>) => Promise<WireServices<Services, SingletonServices>>;
|
|
247
235
|
/**
|
|
248
236
|
* Defines a function type for creating config.
|
|
249
237
|
*/
|
|
@@ -251,11 +239,14 @@ export type CreateConfig<Config extends CoreConfig, RemainingArgs extends any[]
|
|
|
251
239
|
/**
|
|
252
240
|
* Represents the documentation for a route, including summary, description, tags, and errors.
|
|
253
241
|
*/
|
|
254
|
-
export type
|
|
242
|
+
export type CommonWireMeta = {
|
|
243
|
+
pikkuFuncName: string;
|
|
244
|
+
tags?: string[];
|
|
255
245
|
summary?: string;
|
|
256
246
|
description?: string;
|
|
257
|
-
tags?: string[];
|
|
258
247
|
errors?: string[];
|
|
248
|
+
middleware?: MiddlewareMetadata[];
|
|
249
|
+
permissions?: PermissionMetadata[];
|
|
259
250
|
};
|
|
260
251
|
/**
|
|
261
252
|
* Serialized error for storage
|
package/dist/types/core.types.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
export var PikkuWiringTypes;
|
|
2
|
-
(function (PikkuWiringTypes) {
|
|
3
|
-
PikkuWiringTypes["http"] = "http";
|
|
4
|
-
PikkuWiringTypes["scheduler"] = "scheduler";
|
|
5
|
-
PikkuWiringTypes["channel"] = "channel";
|
|
6
|
-
PikkuWiringTypes["rpc"] = "rpc";
|
|
7
|
-
PikkuWiringTypes["queue"] = "queue";
|
|
8
|
-
PikkuWiringTypes["mcp"] = "mcp";
|
|
9
|
-
PikkuWiringTypes["cli"] = "cli";
|
|
10
|
-
PikkuWiringTypes["workflow"] = "workflow";
|
|
11
|
-
})(PikkuWiringTypes || (PikkuWiringTypes = {}));
|
|
12
1
|
/**
|
|
13
2
|
* Factory function for creating middleware with tree-shaking support
|
|
14
3
|
* Supports both direct function and configuration object syntax
|
|
@@ -17,7 +6,7 @@ export var PikkuWiringTypes;
|
|
|
17
6
|
* ```typescript
|
|
18
7
|
* // Direct function syntax
|
|
19
8
|
* export const logMiddleware = pikkuMiddleware(
|
|
20
|
-
* async ({ logger },
|
|
9
|
+
* async ({ logger }, next) => {
|
|
21
10
|
* logger.info('Request started')
|
|
22
11
|
* await next()
|
|
23
12
|
* }
|
|
@@ -27,7 +16,7 @@ export var PikkuWiringTypes;
|
|
|
27
16
|
* export const logMiddleware = pikkuMiddleware({
|
|
28
17
|
* name: 'Request Logger',
|
|
29
18
|
* description: 'Logs request information',
|
|
30
|
-
* func: async ({ logger },
|
|
19
|
+
* func: async ({ logger }, next) => {
|
|
31
20
|
* logger.info('Request started')
|
|
32
21
|
* await next()
|
|
33
22
|
* }
|
|
@@ -47,7 +36,7 @@ export const pikkuMiddleware = (middleware) => {
|
|
|
47
36
|
* message,
|
|
48
37
|
* level = 'info'
|
|
49
38
|
* }) => {
|
|
50
|
-
* return pikkuMiddleware(async ({ logger },
|
|
39
|
+
* return pikkuMiddleware(async ({ logger }, next) => {
|
|
51
40
|
* logger[level](message)
|
|
52
41
|
* await next()
|
|
53
42
|
* })
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Logger } from './services/logger.js';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const closeWireServices: (logger: Logger, wireServices: Record<string, any>) => Promise<void>;
|
|
3
3
|
export declare const createWeakUID: () => string;
|
|
4
4
|
export declare const isSerializable: (data: any) => boolean;
|
|
5
5
|
export declare const freezeDedupe: <T>(arr?: readonly T[] | T[] | undefined) => readonly T[];
|
package/dist/utils.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// TODO:
|
|
1
|
+
// TODO: WireServices probably needs it's own type
|
|
2
2
|
// but is an issue for the future and will be tackled
|
|
3
3
|
// with dependency injection
|
|
4
|
-
export const
|
|
5
|
-
await Promise.all(Object.values(
|
|
4
|
+
export const closeWireServices = async (logger, wireServices) => {
|
|
5
|
+
await Promise.all(Object.values(wireServices).map(async (service) => {
|
|
6
6
|
if (service?.close) {
|
|
7
7
|
try {
|
|
8
8
|
await service.close();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { PikkuWiringTypes, } from '../../types/core.types.js';
|
|
2
1
|
import { combineMiddleware, runMiddleware } from '../../middleware-runner.js';
|
|
3
2
|
import { runPikkuFuncDirectly } from '../../function/function-runner.js';
|
|
4
3
|
/**
|
|
@@ -24,13 +23,13 @@ export const runChannelLifecycleWithMiddleware = async ({ channelConfig, meta, l
|
|
|
24
23
|
? lifecycleConfig.middleware || []
|
|
25
24
|
: [];
|
|
26
25
|
// Use combineMiddleware to properly resolve metadata + inline middleware
|
|
27
|
-
const allMiddleware = combineMiddleware(
|
|
26
|
+
const allMiddleware = combineMiddleware('channel', `${channelConfig.name}:${lifecycleType}`, {
|
|
28
27
|
wireInheritedMiddleware: meta.middleware,
|
|
29
28
|
wireMiddleware: lifecycleMiddleware,
|
|
30
29
|
});
|
|
31
30
|
// Run the lifecycle function
|
|
32
31
|
const runLifecycle = async () => {
|
|
33
|
-
return await runPikkuFuncDirectly(meta.pikkuFuncName,
|
|
32
|
+
return await runPikkuFuncDirectly(meta.pikkuFuncName, services, { channel }, data);
|
|
34
33
|
};
|
|
35
34
|
// Run with middleware if any
|
|
36
35
|
if (allMiddleware.length > 0) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { CoreServices } from '../../types/core.types.js';
|
|
1
|
+
import { CoreServices, CoreUserSession } from '../../types/core.types.js';
|
|
2
2
|
import { CoreChannel, PikkuChannelHandler } from './channel.types.js';
|
|
3
|
-
|
|
3
|
+
import { SessionService } from '../../services/user-session-service.js';
|
|
4
|
+
export declare const processMessageHandlers: (services: CoreServices, channelConfig: CoreChannel<any, any>, channelHandler: PikkuChannelHandler, userSession?: SessionService<CoreUserSession>) => (rawData: any) => Promise<unknown>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { PikkuWiringTypes, } from '../../types/core.types.js';
|
|
2
1
|
import { pikkuState } from '../../pikku-state.js';
|
|
3
2
|
import { runPikkuFunc } from '../../function/function-runner.js';
|
|
4
3
|
const getRouteMeta = (channelName, routingProperty, routerValue) => {
|
|
@@ -32,7 +31,7 @@ const validateAuth = (requiresSession, session, onMessage) => {
|
|
|
32
31
|
}
|
|
33
32
|
return true;
|
|
34
33
|
};
|
|
35
|
-
export const processMessageHandlers = (services, channelConfig, channelHandler) => {
|
|
34
|
+
export const processMessageHandlers = (services, channelConfig, channelHandler, userSession) => {
|
|
36
35
|
const logger = services.logger;
|
|
37
36
|
const requiresSession = channelConfig.auth !== false;
|
|
38
37
|
const processMessage = async (data, onMessage, routingProperty, routerValue) => {
|
|
@@ -69,20 +68,18 @@ export const processMessageHandlers = (services, channelConfig, channelHandler)
|
|
|
69
68
|
const cacheKey = routingProperty
|
|
70
69
|
? `${channelConfig.name}:${routingProperty}:${routerValue}`
|
|
71
70
|
: `${channelConfig.name}:default`;
|
|
72
|
-
return await runPikkuFunc(
|
|
71
|
+
return await runPikkuFunc('channel', cacheKey, pikkuFuncName, {
|
|
73
72
|
singletonServices: services,
|
|
74
|
-
getAllServices: () => ({
|
|
75
|
-
...services,
|
|
76
|
-
channel: channelHandler.getChannel(),
|
|
77
|
-
}),
|
|
78
73
|
data: () => data,
|
|
79
|
-
userSession: services.userSession,
|
|
80
74
|
inheritedMiddleware,
|
|
81
75
|
wireMiddleware,
|
|
82
76
|
inheritedPermissions,
|
|
83
77
|
wirePermissions,
|
|
84
78
|
tags: channelConfig.tags,
|
|
85
|
-
|
|
79
|
+
wire: {
|
|
80
|
+
channel: channelHandler.getChannel(),
|
|
81
|
+
session: userSession,
|
|
82
|
+
},
|
|
86
83
|
});
|
|
87
84
|
};
|
|
88
85
|
return async (rawData) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CorePikkuPermission } from '../../function/functions.types.js';
|
|
2
|
-
import {
|
|
2
|
+
import { SessionService } from '../../services/user-session-service.js';
|
|
3
3
|
import { CorePikkuMiddleware } from '../../types/core.types.js';
|
|
4
4
|
import { ChannelMeta, CoreChannel, RunChannelOptions, RunChannelParams } from './channel.types.js';
|
|
5
5
|
/**
|
|
@@ -8,7 +8,7 @@ import { ChannelMeta, CoreChannel, RunChannelOptions, RunChannelParams } from '.
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const wireChannel: <In, Channel extends string, PikkuPermission extends CorePikkuPermission<In>, PikkuMiddleware extends CorePikkuMiddleware, ChannelFunction>(channel: CoreChannel<In, Channel, PikkuPermission, PikkuMiddleware, ChannelFunction>) => void;
|
|
10
10
|
export declare const openChannel: ({ route, singletonServices, coerceDataFromSchema, request, }: Pick<CoreChannel<unknown, string>, "route"> & RunChannelParams<unknown> & {
|
|
11
|
-
userSession:
|
|
11
|
+
userSession: SessionService<any>;
|
|
12
12
|
} & RunChannelOptions) => Promise<{
|
|
13
13
|
openingData: unknown;
|
|
14
14
|
channelConfig: CoreChannel<unknown, any>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PikkuError } from '../../errors/error-handler.js';
|
|
2
2
|
import { HTTPFunctionMetaInputTypes, PikkuHTTPRequest, PikkuHTTPResponse } from '../http/http.types.js';
|
|
3
|
-
import {
|
|
3
|
+
import { CoreSingletonServices, CreateWireServices, CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
|
|
4
4
|
import { CorePermissionGroup, CorePikkuFunction, CorePikkuFunctionConfig, CorePikkuFunctionSessionless, CorePikkuPermission } from '../../function/functions.types.js';
|
|
5
5
|
export type RunChannelOptions = Partial<{
|
|
6
6
|
skipUserSession: boolean;
|
|
@@ -14,11 +14,14 @@ export type RunChannelParams<ChannelData> = {
|
|
|
14
14
|
singletonServices: CoreSingletonServices;
|
|
15
15
|
request?: PikkuHTTPRequest<ChannelData>;
|
|
16
16
|
response?: PikkuHTTPResponse;
|
|
17
|
-
|
|
17
|
+
createWireServices?: CreateWireServices;
|
|
18
18
|
};
|
|
19
19
|
export interface ChannelMessageMeta {
|
|
20
20
|
pikkuFuncName: string;
|
|
21
|
-
|
|
21
|
+
summary?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
errors?: string[];
|
|
24
|
+
tags?: string[];
|
|
22
25
|
middleware?: MiddlewareMetadata[];
|
|
23
26
|
permissions?: PermissionMetadata[];
|
|
24
27
|
}
|
|
@@ -33,13 +36,15 @@ export interface ChannelMeta {
|
|
|
33
36
|
disconnect: ChannelMessageMeta | null;
|
|
34
37
|
message: ChannelMessageMeta | null;
|
|
35
38
|
messageWirings: Record<string, Record<string, ChannelMessageMeta>>;
|
|
36
|
-
|
|
39
|
+
summary?: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
errors?: string[];
|
|
37
42
|
tags?: string[];
|
|
38
43
|
middleware?: MiddlewareMetadata[];
|
|
39
44
|
permissions?: PermissionMetadata[];
|
|
40
45
|
}
|
|
41
46
|
export type ChannelsMeta = Record<string, ChannelMeta>;
|
|
42
|
-
export type CoreChannel<ChannelData, Channel extends string, ChannelConnect = CorePikkuFunctionConfig<CorePikkuFunction<void, unknown
|
|
47
|
+
export type CoreChannel<ChannelData, Channel extends string, ChannelConnect = CorePikkuFunctionConfig<CorePikkuFunction<void, unknown> | CorePikkuFunctionSessionless<void, unknown>, CorePikkuPermission<void>, CorePikkuMiddleware>, ChannelDisconnect = CorePikkuFunctionConfig<CorePikkuFunction<void, void> | CorePikkuFunctionSessionless<void, void>, CorePikkuPermission<void>, CorePikkuMiddleware>, ChannelFunctionMessage = CorePikkuFunctionConfig<CorePikkuFunction<unknown, unknown> | CorePikkuFunctionSessionless<unknown, unknown>, CorePikkuPermission<unknown>, CorePikkuMiddleware>, PikkuPermission = CorePikkuPermission<ChannelData>, PikkuMiddleware = CorePikkuMiddleware> = {
|
|
43
48
|
name: string;
|
|
44
49
|
route: Channel;
|
|
45
50
|
onConnect?: ChannelConnect | {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CoreChannel, RunChannelOptions, RunChannelParams } from '../channel.types.js';
|
|
2
2
|
import { PikkuLocalChannelHandler } from './local-channel-handler.js';
|
|
3
|
-
export declare const runLocalChannel: ({ singletonServices, channelId, request, response, route,
|
|
3
|
+
export declare const runLocalChannel: ({ singletonServices, channelId, request, response, route, createWireServices, skipUserSession, respondWith404, coerceDataFromSchema, logWarningsForStatusCodes, bubbleErrors, }: Partial<Pick<CoreChannel<unknown, any>, "route">> & RunChannelOptions & RunChannelParams<unknown>) => Promise<PikkuLocalChannelHandler | void>;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { openChannel } from '../channel-runner.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { createHTTPWire } from '../../http/http-runner.js';
|
|
3
|
+
import { closeWireServices } from '../../../utils.js';
|
|
4
4
|
import { processMessageHandlers } from '../channel-handler.js';
|
|
5
5
|
import { PikkuLocalChannelHandler } from './local-channel-handler.js';
|
|
6
6
|
import { handleHTTPError } from '../../../handle-error.js';
|
|
7
|
-
import {
|
|
8
|
-
import { rpcService } from '../../rpc/rpc-runner.js';
|
|
7
|
+
import { PikkuSessionService } from '../../../services/user-session-service.js';
|
|
9
8
|
import { runChannelLifecycleWithMiddleware } from '../channel-common.js';
|
|
10
|
-
export const runLocalChannel = async ({ singletonServices, channelId, request, response, route,
|
|
11
|
-
let
|
|
9
|
+
export const runLocalChannel = async ({ singletonServices, channelId, request, response, route, createWireServices, skipUserSession = false, respondWith404 = true, coerceDataFromSchema = true, logWarningsForStatusCodes = [], bubbleErrors = false, }) => {
|
|
10
|
+
let wireServices;
|
|
12
11
|
let channelHandler;
|
|
13
|
-
const userSession = new
|
|
12
|
+
const userSession = new PikkuSessionService();
|
|
14
13
|
let http;
|
|
15
14
|
if (request) {
|
|
16
|
-
http =
|
|
15
|
+
http = createHTTPWire(request, response);
|
|
17
16
|
route = http?.request?.path();
|
|
18
17
|
}
|
|
19
18
|
let openingData, channelConfig, meta;
|
|
@@ -21,7 +20,7 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
|
|
|
21
20
|
;
|
|
22
21
|
({ openingData, channelConfig, meta } = await openChannel({
|
|
23
22
|
channelId,
|
|
24
|
-
|
|
23
|
+
createWireServices,
|
|
25
24
|
respondWith404,
|
|
26
25
|
request,
|
|
27
26
|
response,
|
|
@@ -40,17 +39,11 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
|
|
|
40
39
|
try {
|
|
41
40
|
channelHandler = new PikkuLocalChannelHandler(channelId, channelConfig.name, openingData);
|
|
42
41
|
const channel = channelHandler.getChannel();
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
|
|
42
|
+
const wire = { channel, session: userSession };
|
|
43
|
+
if (createWireServices) {
|
|
44
|
+
wireServices = await createWireServices(singletonServices, wire);
|
|
46
45
|
}
|
|
47
|
-
const
|
|
48
|
-
...singletonServices,
|
|
49
|
-
...sessionServices,
|
|
50
|
-
channel,
|
|
51
|
-
userSession,
|
|
52
|
-
}, interaction, requiresAuth);
|
|
53
|
-
const interaction = { channel };
|
|
46
|
+
const services = { ...singletonServices, ...wireServices };
|
|
54
47
|
channelHandler.registerOnOpen(async () => {
|
|
55
48
|
if (channelConfig.onConnect && meta.connect) {
|
|
56
49
|
try {
|
|
@@ -59,7 +52,7 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
|
|
|
59
52
|
meta: meta.connect,
|
|
60
53
|
lifecycleConfig: channelConfig.onConnect,
|
|
61
54
|
lifecycleType: 'connect',
|
|
62
|
-
services
|
|
55
|
+
services,
|
|
63
56
|
channel,
|
|
64
57
|
data: openingData,
|
|
65
58
|
});
|
|
@@ -81,7 +74,7 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
|
|
|
81
74
|
meta: meta.disconnect,
|
|
82
75
|
lifecycleConfig: channelConfig.onDisconnect,
|
|
83
76
|
lifecycleType: 'disconnect',
|
|
84
|
-
services
|
|
77
|
+
services,
|
|
85
78
|
channel,
|
|
86
79
|
});
|
|
87
80
|
}
|
|
@@ -90,11 +83,11 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
|
|
|
90
83
|
channel.send({ error: e.message || 'Unknown error' });
|
|
91
84
|
}
|
|
92
85
|
}
|
|
93
|
-
if (
|
|
94
|
-
await
|
|
86
|
+
if (wireServices) {
|
|
87
|
+
await closeWireServices(singletonServices.logger, wireServices);
|
|
95
88
|
}
|
|
96
89
|
});
|
|
97
|
-
const onMessage = processMessageHandlers(
|
|
90
|
+
const onMessage = processMessageHandlers(services, channelConfig, channelHandler, userSession);
|
|
98
91
|
channelHandler.registerOnMessage(async (data) => {
|
|
99
92
|
try {
|
|
100
93
|
const result = await onMessage(data);
|
|
@@ -110,8 +103,8 @@ export const runLocalChannel = async ({ singletonServices, channelId, request, r
|
|
|
110
103
|
handleHTTPError(e, http, channelId, singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
|
|
111
104
|
}
|
|
112
105
|
finally {
|
|
113
|
-
if (
|
|
114
|
-
await
|
|
106
|
+
if (wireServices) {
|
|
107
|
+
await closeWireServices(singletonServices.logger, wireServices);
|
|
115
108
|
}
|
|
116
109
|
}
|
|
117
110
|
};
|
|
@@ -5,6 +5,6 @@ export interface RunServerlessChannelParams<ChannelData> extends RunChannelParam
|
|
|
5
5
|
channelHandlerFactory: PikkuChannelHandlerFactory;
|
|
6
6
|
channelObject?: unknown;
|
|
7
7
|
}
|
|
8
|
-
export declare const runChannelConnect: ({ singletonServices, channelId, channelObject, request, response, route,
|
|
8
|
+
export declare const runChannelConnect: ({ singletonServices, channelId, channelObject, request, response, route, createWireServices, channelStore, channelHandlerFactory, coerceDataFromSchema, logWarningsForStatusCodes, respondWith404, bubbleErrors, }: Pick<CoreChannel<unknown, any>, "route"> & RunChannelOptions & RunServerlessChannelParams<unknown>) => Promise<void>;
|
|
9
9
|
export declare const runChannelDisconnect: ({ singletonServices, ...params }: RunServerlessChannelParams<unknown>) => Promise<void>;
|
|
10
10
|
export declare const runChannelMessage: ({ singletonServices, ...params }: RunServerlessChannelParams<unknown>, data: unknown) => Promise<unknown>;
|