@pikku/lambda 0.12.2 → 0.12.4
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 +35 -0
- package/dist/handler-factories.d.ts +17 -0
- package/dist/handler-factories.js +91 -0
- package/dist/handler-factories.js.map +1 -0
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +3 -0
- package/dist/http/index.js.map +1 -1
- package/dist/http/request-converter-v2.d.ts +2 -0
- package/dist/http/request-converter-v2.js +25 -0
- package/dist/http/request-converter-v2.js.map +1 -0
- package/dist/http/response-converter-v2.d.ts +2 -0
- package/dist/http/response-converter-v2.js +31 -0
- package/dist/http/response-converter-v2.js.map +1 -0
- package/dist/http/run-fetch-v2.d.ts +2 -0
- package/dist/http/run-fetch-v2.js +25 -0
- package/dist/http/run-fetch-v2.js.map +1 -0
- package/dist/http/run-fetch.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lambda-deployment-service.d.ts +14 -0
- package/dist/lambda-deployment-service.js +89 -0
- package/dist/lambda-deployment-service.js.map +1 -0
- package/dist/queue/sqs-worker.js +1 -1
- package/dist/queue/sqs-worker.js.map +1 -1
- package/dist/scheduled/index.d.ts +1 -0
- package/dist/scheduled/index.js +2 -0
- package/dist/scheduled/index.js.map +1 -0
- package/dist/scheduled/run-scheduled.d.ts +2 -0
- package/dist/scheduled/run-scheduled.js +14 -0
- package/dist/scheduled/run-scheduled.js.map +1 -0
- package/dist/sqs-queue-service.d.ts +10 -0
- package/dist/sqs-queue-service.js +52 -0
- package/dist/sqs-queue-service.js.map +1 -0
- package/dist/websocket/utils.d.ts +1 -1
- package/package.json +12 -6
- package/src/handler-factories.ts +165 -0
- package/src/http/index.ts +3 -0
- package/src/http/request-converter-v2.ts +36 -0
- package/src/http/response-converter-v2.ts +40 -0
- package/src/http/run-fetch-v2.ts +42 -0
- package/src/http/run-fetch.ts +1 -1
- package/src/index.test.ts +13 -0
- package/src/index.ts +4 -0
- package/src/lambda-deployment-service.ts +134 -0
- package/src/queue/sqs-worker.ts +1 -1
- package/src/scheduled/index.ts +1 -0
- package/src/scheduled/run-scheduled.ts +30 -0
- package/src/sqs-queue-service.ts +91 -0
- package/src/websocket/lambda-eventhub-service.ts +3 -3
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
|
+
## 0.12.4
|
|
2
|
+
|
|
3
|
+
### Patch Changes
|
|
4
|
+
|
|
5
|
+
- 41ce2cb: Upgrade to TypeScript 6 and raise the minimum Node.js version to 22.
|
|
6
|
+
|
|
7
|
+
All packages now build against `typescript@^6.0.3` and declare `engines.node >= 22`. Internal tooling (`ts-json-schema-generator`, `zod-to-ts`) was bumped to TypeScript 6-compatible releases.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [41ce2cb]
|
|
10
|
+
- @pikku/core@0.12.44
|
|
11
|
+
|
|
1
12
|
## 0.12.0
|
|
2
13
|
|
|
14
|
+
## 0.12.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- e3142ad: Fix OPTIONS method comparison to use uppercase, matching the Fetch API Request.method convention. Previously the CORS preflight handler was dead code.
|
|
19
|
+
- 87433f0: Replace full SQS event logging with message count to prevent sensitive data leaking into CloudWatch logs.
|
|
20
|
+
- Updated dependencies [e412b4d]
|
|
21
|
+
- Updated dependencies [53dc8c8]
|
|
22
|
+
- Updated dependencies [0a1cc51]
|
|
23
|
+
- Updated dependencies [0a1cc51]
|
|
24
|
+
- Updated dependencies [0a1cc51]
|
|
25
|
+
- Updated dependencies [0a1cc51]
|
|
26
|
+
- Updated dependencies [0a1cc51]
|
|
27
|
+
- Updated dependencies [0a1cc51]
|
|
28
|
+
- Updated dependencies [0a1cc51]
|
|
29
|
+
- Updated dependencies [0a1cc51]
|
|
30
|
+
- Updated dependencies [0a1cc51]
|
|
31
|
+
- Updated dependencies [8b9b2e9]
|
|
32
|
+
- Updated dependencies [8b9b2e9]
|
|
33
|
+
- Updated dependencies [b973d44]
|
|
34
|
+
- Updated dependencies [8b9b2e9]
|
|
35
|
+
- Updated dependencies [8b9b2e9]
|
|
36
|
+
- @pikku/core@0.12.9
|
|
37
|
+
|
|
3
38
|
## 0.12.2
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LocalVariablesService } from '@pikku/core/services';
|
|
2
|
+
import type { CoreSingletonServices } from '@pikku/core';
|
|
3
|
+
import type { APIGatewayEvent, APIGatewayProxyEventV2 } from 'aws-lambda';
|
|
4
|
+
export interface LambdaServiceFactories {
|
|
5
|
+
createConfig: (variables: LocalVariablesService, ...args: unknown[]) => Promise<unknown>;
|
|
6
|
+
createSingletonServices: (config: unknown, existingServices?: Partial<Record<string, unknown>>) => Promise<CoreSingletonServices>;
|
|
7
|
+
createPlatformServices?: () => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
8
|
+
}
|
|
9
|
+
export declare function createLambdaHandler(factories: LambdaServiceFactories, handlerTypes: string[]): Record<string, unknown>;
|
|
10
|
+
export declare function createLambdaWorkerHandler(factories: LambdaServiceFactories): {
|
|
11
|
+
handler(event: APIGatewayProxyEventV2): Promise<import("aws-lambda").APIGatewayProxyStructuredResultV2>;
|
|
12
|
+
};
|
|
13
|
+
export declare function createLambdaWebSocketHandler(factories: LambdaServiceFactories): {
|
|
14
|
+
connect(event: APIGatewayEvent): Promise<import("aws-lambda").APIGatewayProxyResult>;
|
|
15
|
+
disconnect(event: APIGatewayEvent): Promise<import("aws-lambda").APIGatewayProxyResult>;
|
|
16
|
+
default(event: APIGatewayEvent): Promise<import("aws-lambda").APIGatewayProxyResult>;
|
|
17
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { LocalVariablesService, LocalSecretService } from '@pikku/core/services';
|
|
2
|
+
import { runFetchV2 } from './http/run-fetch-v2.js';
|
|
3
|
+
import { runSQSQueueWorker } from './queue/sqs-worker.js';
|
|
4
|
+
import { runLambdaScheduled } from './scheduled/run-scheduled.js';
|
|
5
|
+
let cachedServices = null;
|
|
6
|
+
async function setupServices(factories) {
|
|
7
|
+
if (cachedServices)
|
|
8
|
+
return cachedServices;
|
|
9
|
+
const variables = new LocalVariablesService(process.env);
|
|
10
|
+
const config = await factories.createConfig(variables);
|
|
11
|
+
const secrets = new LocalSecretService(variables);
|
|
12
|
+
const platformServices = factories.createPlatformServices
|
|
13
|
+
? await factories.createPlatformServices()
|
|
14
|
+
: {};
|
|
15
|
+
cachedServices = await factories.createSingletonServices(config, {
|
|
16
|
+
variables,
|
|
17
|
+
secrets,
|
|
18
|
+
...platformServices,
|
|
19
|
+
});
|
|
20
|
+
return cachedServices;
|
|
21
|
+
}
|
|
22
|
+
export function createLambdaHandler(factories, handlerTypes) {
|
|
23
|
+
const result = {};
|
|
24
|
+
if (handlerTypes.includes('fetch')) {
|
|
25
|
+
result.handler = async (event) => {
|
|
26
|
+
await setupServices(factories);
|
|
27
|
+
return runFetchV2(event);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (handlerTypes.includes('queue')) {
|
|
31
|
+
result.queue = async (event) => {
|
|
32
|
+
const services = await setupServices(factories);
|
|
33
|
+
return runSQSQueueWorker(services.logger, event);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (handlerTypes.includes('scheduled')) {
|
|
37
|
+
result.scheduled = async (event) => {
|
|
38
|
+
await setupServices(factories);
|
|
39
|
+
return runLambdaScheduled(event);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (!handlerTypes.includes('fetch')) {
|
|
43
|
+
const activeHandlers = handlerTypes.join(', ');
|
|
44
|
+
result.handler = async () => ({
|
|
45
|
+
statusCode: 200,
|
|
46
|
+
body: `Lambda active (handlers: ${activeHandlers})`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
export function createLambdaWorkerHandler(factories) {
|
|
52
|
+
return {
|
|
53
|
+
async handler(event) {
|
|
54
|
+
await setupServices(factories);
|
|
55
|
+
return runFetchV2(event);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function createLambdaWebSocketHandler(factories) {
|
|
60
|
+
const getChannelStore = () => {
|
|
61
|
+
if (!cachedServices) {
|
|
62
|
+
throw new Error('Services not initialized for WebSocket handler');
|
|
63
|
+
}
|
|
64
|
+
const channelStore = cachedServices
|
|
65
|
+
.channelStore;
|
|
66
|
+
if (!channelStore) {
|
|
67
|
+
throw new Error('channelStore not found in singleton services. Ensure it is configured for channel units.');
|
|
68
|
+
}
|
|
69
|
+
return channelStore;
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
async connect(event) {
|
|
73
|
+
await setupServices(factories);
|
|
74
|
+
const { connectWebsocket } = await import('./websocket/index.js');
|
|
75
|
+
return connectWebsocket(event, { channelStore: getChannelStore() });
|
|
76
|
+
},
|
|
77
|
+
async disconnect(event) {
|
|
78
|
+
await setupServices(factories);
|
|
79
|
+
const { disconnectWebsocket } = await import('./websocket/index.js');
|
|
80
|
+
return disconnectWebsocket(event, { channelStore: getChannelStore() });
|
|
81
|
+
},
|
|
82
|
+
async default(event) {
|
|
83
|
+
await setupServices(factories);
|
|
84
|
+
const { processWebsocketMessage } = await import('./websocket/index.js');
|
|
85
|
+
return processWebsocketMessage(event, {
|
|
86
|
+
channelStore: getChannelStore(),
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=handler-factories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-factories.js","sourceRoot":"","sources":["../src/handler-factories.ts"],"names":[],"mappings":"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"}
|
package/dist/http/index.d.ts
CHANGED
package/dist/http/index.js
CHANGED
package/dist/http/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const lambdaV2EventToRequest = (event) => {
|
|
2
|
+
const host = event.headers?.host ?? event.requestContext?.domainName ?? 'localhost';
|
|
3
|
+
const url = new URL(event.rawPath, `https://${host}`);
|
|
4
|
+
if (event.rawQueryString) {
|
|
5
|
+
url.search = `?${event.rawQueryString}`;
|
|
6
|
+
}
|
|
7
|
+
const body = event.body && event.isBase64Encoded
|
|
8
|
+
? Buffer.from(event.body, 'base64')
|
|
9
|
+
: event.body || undefined;
|
|
10
|
+
const method = event.requestContext?.http?.method || 'GET';
|
|
11
|
+
const headers = {};
|
|
12
|
+
if (event.headers) {
|
|
13
|
+
for (const [key, value] of Object.entries(event.headers)) {
|
|
14
|
+
if (value != null) {
|
|
15
|
+
headers[key] = value;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return new Request(url.toString(), {
|
|
20
|
+
method,
|
|
21
|
+
headers,
|
|
22
|
+
body: ['GET', 'HEAD'].includes(method.toUpperCase()) ? undefined : body,
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=request-converter-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-converter-v2.js","sourceRoot":"","sources":["../../src/http/request-converter-v2.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,KAA6B,EACpB,EAAE;IACX,MAAM,IAAI,GACR,KAAK,CAAC,OAAO,EAAE,IAAI,IAAI,KAAK,CAAC,cAAc,EAAE,UAAU,IAAI,WAAW,CAAA;IACxE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC,CAAA;IAErD,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QAEzB,GAAG,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,cAAc,EAAE,CAAA;IACzC,CAAC;IAED,MAAM,IAAI,GACR,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,eAAe;QACjC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;QACnC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,CAAA;IAE7B,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,CAAA;IAE1D,MAAM,OAAO,GAA2B,EAAE,CAAA;IAC1C,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QACjC,MAAM;QACN,OAAO;QACP,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;KACxE,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const responseToLambdaV2Result = async (response) => {
|
|
2
|
+
const cookies = response.headers.getSetCookie
|
|
3
|
+
? response.headers.getSetCookie()
|
|
4
|
+
: [];
|
|
5
|
+
const headers = {};
|
|
6
|
+
response.headers.forEach((value, key) => {
|
|
7
|
+
if (key.toLowerCase() === 'set-cookie' && cookies.length > 0)
|
|
8
|
+
return;
|
|
9
|
+
headers[key.toLowerCase()] = value;
|
|
10
|
+
});
|
|
11
|
+
let body;
|
|
12
|
+
let isBase64Encoded = false;
|
|
13
|
+
const contentType = response.headers.get('content-type') || '';
|
|
14
|
+
const isBinary = !/^text\/|application\/(json|javascript|xml)/.test(contentType);
|
|
15
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
16
|
+
if (isBinary) {
|
|
17
|
+
body = buffer.toString('base64');
|
|
18
|
+
isBase64Encoded = true;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
body = buffer.toString('utf-8');
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
statusCode: response.status,
|
|
25
|
+
headers,
|
|
26
|
+
body,
|
|
27
|
+
isBase64Encoded,
|
|
28
|
+
...(cookies.length > 0 ? { cookies } : {}),
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=response-converter-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-converter-v2.js","sourceRoot":"","sources":["../../src/http/response-converter-v2.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAC3C,QAAkB,EAC0B,EAAE;IAE9C,MAAM,OAAO,GAAa,QAAQ,CAAC,OAAO,CAAC,YAAY;QACrD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE;QACjC,CAAC,CAAC,EAAE,CAAA;IAEN,MAAM,OAAO,GAA2B,EAAE,CAAA;IAC1C,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtC,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QACpE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,IAAI,IAAY,CAAA;IAChB,IAAI,eAAe,GAAG,KAAK,CAAA;IAE3B,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;IAC9D,MAAM,QAAQ,GAAG,CAAC,4CAA4C,CAAC,IAAI,CACjE,WAAW,CACZ,CAAA;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACxD,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAChC,eAAe,GAAG,IAAI,CAAA;IACxB,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IAED,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,MAAM;QAC3B,OAAO;QACP,IAAI;QACJ,eAAe;QACf,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PikkuFetchHTTPResponse, fetchData } from '@pikku/core/http';
|
|
2
|
+
import { responseToLambdaV2Result } from './response-converter-v2.js';
|
|
3
|
+
import { lambdaV2EventToRequest } from './request-converter-v2.js';
|
|
4
|
+
export const runFetchV2 = async (event) => {
|
|
5
|
+
const request = lambdaV2EventToRequest(event);
|
|
6
|
+
const response = new PikkuFetchHTTPResponse();
|
|
7
|
+
if (request.method === 'OPTIONS') {
|
|
8
|
+
response.header('Access-Control-Allow-Origin', request.headers.get('origin') || '*');
|
|
9
|
+
response.header('Access-Control-Allow-Headers', 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent');
|
|
10
|
+
response.header('Access-Control-Allow-Methods', 'OPTIONS,DELETE,GET,HEAD,PATCH,POST,PUT');
|
|
11
|
+
response.status(200);
|
|
12
|
+
return responseToLambdaV2Result(response.toResponse());
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
await fetchData(request, response);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error('fetchData error:', err);
|
|
19
|
+
response.status(500);
|
|
20
|
+
response.header('content-type', 'application/json');
|
|
21
|
+
response.json({ error: 'Internal Server Error' });
|
|
22
|
+
}
|
|
23
|
+
return responseToLambdaV2Result(response.toResponse());
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=run-fetch-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-fetch-v2.js","sourceRoot":"","sources":["../../src/http/run-fetch-v2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAKpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAElE,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,KAA6B,EACe,EAAE;IAC9C,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,IAAI,sBAAsB,EAAE,CAAA;IAE7C,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,MAAM,CACb,6BAA6B,EAC7B,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CACrC,CAAA;QACD,QAAQ,CAAC,MAAM,CACb,8BAA8B,EAC9B,uFAAuF,CACxF,CAAA;QACD,QAAQ,CAAC,MAAM,CACb,8BAA8B,EAC9B,wCAAwC,CACzC,CAAA;QACD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACpB,OAAO,wBAAwB,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;QACtC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACpB,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;QACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAA;IACnD,CAAC;IAED,OAAO,wBAAwB,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;AACxD,CAAC,CAAA"}
|
package/dist/http/run-fetch.js
CHANGED
|
@@ -4,7 +4,7 @@ import { lambdaEventToRequest } from '../request-converter.js';
|
|
|
4
4
|
export const runFetch = async (event) => {
|
|
5
5
|
const request = lambdaEventToRequest(event);
|
|
6
6
|
const response = new PikkuFetchHTTPResponse();
|
|
7
|
-
if (request.method === '
|
|
7
|
+
if (request.method === 'OPTIONS') {
|
|
8
8
|
response.header('Access-Control-Allow-Headers', 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent');
|
|
9
9
|
response.header('Access-Control-Allow-Methods', 'OPTIONS,DELETE,GET,HEAD,PATCH,POST,PUT');
|
|
10
10
|
response.status(200);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export * from './http/index.js';
|
|
2
2
|
export * from './websocket/index.js';
|
|
3
3
|
export * from './queue/index.js';
|
|
4
|
+
export * from './scheduled/index.js';
|
|
5
|
+
export * from './handler-factories.js';
|
|
6
|
+
export { SQSQueueService } from './sqs-queue-service.js';
|
|
7
|
+
export { LambdaDeploymentService } from './lambda-deployment-service.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export * from './http/index.js';
|
|
2
2
|
export * from './websocket/index.js';
|
|
3
3
|
export * from './queue/index.js';
|
|
4
|
+
export * from './scheduled/index.js';
|
|
5
|
+
export * from './handler-factories.js';
|
|
6
|
+
export { SQSQueueService } from './sqs-queue-service.js';
|
|
7
|
+
export { LambdaDeploymentService } from './lambda-deployment-service.js';
|
|
4
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DeploymentService, DeploymentConfig } from '@pikku/core/services';
|
|
2
|
+
import type { JWTService } from '@pikku/core/services';
|
|
3
|
+
import type { SecretService } from '@pikku/core/services';
|
|
4
|
+
export declare class LambdaDeploymentService implements DeploymentService {
|
|
5
|
+
private jwt;
|
|
6
|
+
private secrets;
|
|
7
|
+
private client;
|
|
8
|
+
private bindings;
|
|
9
|
+
constructor(jwt: JWTService | undefined, secrets: SecretService, functionBindings: Record<string, string>);
|
|
10
|
+
init(): Promise<void>;
|
|
11
|
+
start(_config: DeploymentConfig): Promise<void>;
|
|
12
|
+
stop(): Promise<void>;
|
|
13
|
+
invoke(funcName: string, data: unknown, session?: unknown, traceId?: string): Promise<unknown>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
|
|
2
|
+
import { encryptJSON } from '@pikku/core/crypto-utils';
|
|
3
|
+
export class LambdaDeploymentService {
|
|
4
|
+
jwt;
|
|
5
|
+
secrets;
|
|
6
|
+
client;
|
|
7
|
+
bindings;
|
|
8
|
+
constructor(jwt, secrets, functionBindings) {
|
|
9
|
+
this.jwt = jwt;
|
|
10
|
+
this.secrets = secrets;
|
|
11
|
+
this.client = new LambdaClient({});
|
|
12
|
+
this.bindings = new Map(Object.entries(functionBindings));
|
|
13
|
+
}
|
|
14
|
+
async init() { }
|
|
15
|
+
async start(_config) { }
|
|
16
|
+
async stop() { }
|
|
17
|
+
async invoke(funcName, data, session, traceId) {
|
|
18
|
+
const lambdaFunctionName = this.bindings.get(funcName);
|
|
19
|
+
if (!lambdaFunctionName) {
|
|
20
|
+
throw new Error(`No Lambda binding for function '${funcName}'. ` +
|
|
21
|
+
`Available bindings: ${[...this.bindings.keys()].join(', ')}`);
|
|
22
|
+
}
|
|
23
|
+
const headers = {
|
|
24
|
+
'content-type': 'application/json',
|
|
25
|
+
...(traceId && { 'x-request-id': traceId }),
|
|
26
|
+
};
|
|
27
|
+
let secret;
|
|
28
|
+
try {
|
|
29
|
+
secret = await this.secrets.getSecret('PIKKU_REMOTE_SECRET');
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
if (secret && this.jwt) {
|
|
33
|
+
const sessionEnc = session
|
|
34
|
+
? await encryptJSON(secret, { session })
|
|
35
|
+
: undefined;
|
|
36
|
+
const token = await this.jwt.encode({ value: 5, unit: 'minute' }, {
|
|
37
|
+
aud: 'pikku-remote',
|
|
38
|
+
fn: funcName,
|
|
39
|
+
iat: Math.floor(Date.now() / 1000),
|
|
40
|
+
session: sessionEnc,
|
|
41
|
+
});
|
|
42
|
+
headers.authorization = `Bearer ${token}`;
|
|
43
|
+
}
|
|
44
|
+
const rpcPath = `/remote/rpc/${encodeURIComponent(funcName)}`;
|
|
45
|
+
const apiGatewayEvent = {
|
|
46
|
+
httpMethod: 'POST',
|
|
47
|
+
path: rpcPath,
|
|
48
|
+
headers,
|
|
49
|
+
body: JSON.stringify({ data }),
|
|
50
|
+
isBase64Encoded: false,
|
|
51
|
+
queryStringParameters: null,
|
|
52
|
+
pathParameters: null,
|
|
53
|
+
stageVariables: null,
|
|
54
|
+
requestContext: {
|
|
55
|
+
httpMethod: 'POST',
|
|
56
|
+
path: rpcPath,
|
|
57
|
+
stage: 'prod',
|
|
58
|
+
requestId: crypto.randomUUID(),
|
|
59
|
+
identity: {},
|
|
60
|
+
},
|
|
61
|
+
resource: rpcPath,
|
|
62
|
+
};
|
|
63
|
+
const response = await this.client.send(new InvokeCommand({
|
|
64
|
+
FunctionName: lambdaFunctionName,
|
|
65
|
+
Payload: JSON.stringify(apiGatewayEvent),
|
|
66
|
+
}));
|
|
67
|
+
if (response.FunctionError) {
|
|
68
|
+
const errorPayload = response.Payload
|
|
69
|
+
? new TextDecoder().decode(response.Payload)
|
|
70
|
+
: 'Unknown error';
|
|
71
|
+
throw new Error(`Remote RPC call to '${funcName}' failed: Lambda error: ${errorPayload}`);
|
|
72
|
+
}
|
|
73
|
+
if (!response.Payload) {
|
|
74
|
+
throw new Error(`Remote RPC call to '${funcName}' returned no payload`);
|
|
75
|
+
}
|
|
76
|
+
const lambdaResult = JSON.parse(new TextDecoder().decode(response.Payload));
|
|
77
|
+
if (lambdaResult.statusCode && lambdaResult.statusCode >= 400) {
|
|
78
|
+
throw new Error(`Remote RPC call to '${funcName}' failed: ${lambdaResult.statusCode} ${lambdaResult.body}`);
|
|
79
|
+
}
|
|
80
|
+
const body = lambdaResult.body;
|
|
81
|
+
try {
|
|
82
|
+
return JSON.parse(body);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return body;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=lambda-deployment-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lambda-deployment-service.js","sourceRoot":"","sources":["../src/lambda-deployment-service.ts"],"names":[],"mappings":"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"}
|
package/dist/queue/sqs-worker.js
CHANGED
|
@@ -34,7 +34,7 @@ export function mapSQSRecordToQueueJob(record, maxAttempts) {
|
|
|
34
34
|
return job;
|
|
35
35
|
}
|
|
36
36
|
export const runSQSQueueWorker = async (logger, event) => {
|
|
37
|
-
|
|
37
|
+
logger.info(`Processing ${event.Records.length} SQS messages`);
|
|
38
38
|
const jobs = event.Records.map(mapSQSRecordToQueueJob);
|
|
39
39
|
const results = await Promise.allSettled(jobs.map(async (job) => {
|
|
40
40
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqs-worker.js","sourceRoot":"","sources":["../../src/queue/sqs-worker.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,mBAAmB,CAAA;AAO1B,MAAM,UAAU,sBAAsB,CACpC,MAAiB,EACjB,WAAoB;IAEpB,IAAI,IAAS,CAAA;IAEb,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;IAC5D,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAA;IAEzD,MAAM,GAAG,GAAa;QACpB,SAAS;QACT,IAAI;QACJ,EAAE,EAAE,MAAM,CAAC,SAAS;QACpB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,QAA0B;QAC9C,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACf,WAAW,EAAE,IAAI,IAAI,EAAE;YACvB,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,uBAAuB,CAAC,GAAG,CAAC;YACrE,WAAW;YACX,MAAM,EAAE,SAAS;YACjB,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YAC9D,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,SAAS;SACjB,CAAC;QACF,iBAAiB,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAA;QACH,CAAC;KACF,CAAA;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAKD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,MAAc,EACd,KAAe,EACY,EAAE;IAC7B,
|
|
1
|
+
{"version":3,"file":"sqs-worker.js","sourceRoot":"","sources":["../../src/queue/sqs-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { runLambdaScheduled } from './run-scheduled.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scheduled/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { runScheduledTask, getScheduledTasks } from '@pikku/core/scheduler';
|
|
2
|
+
export const runLambdaScheduled = async (_event) => {
|
|
3
|
+
const scheduledTasks = getScheduledTasks();
|
|
4
|
+
for (const [name] of scheduledTasks) {
|
|
5
|
+
const traceId = `cron-${crypto.randomUUID()}`;
|
|
6
|
+
try {
|
|
7
|
+
await runScheduledTask({ name, traceId });
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
console.error(`Scheduled task '${name}' (traceId: ${traceId}) failed:`, err);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=run-scheduled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-scheduled.js","sourceRoot":"","sources":["../../src/scheduled/run-scheduled.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,MAAsB,EACP,EAAE;IACjB,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAA;IAI1C,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,QAAQ,MAAM,CAAC,UAAU,EAAE,EAAE,CAAA;QAC7C,IAAI,CAAC;YACH,MAAM,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,mBAAmB,IAAI,eAAe,OAAO,WAAW,EACxD,GAAG,CACJ,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { QueueService, QueueJob, JobOptions } from '@pikku/core/queue';
|
|
2
|
+
export declare class SQSQueueService implements QueueService {
|
|
3
|
+
private queueUrlMap?;
|
|
4
|
+
readonly supportsResults = false;
|
|
5
|
+
private client;
|
|
6
|
+
constructor(queueUrlMap?: Record<string, string> | undefined);
|
|
7
|
+
add<T>(queueName: string, data: T, options?: JobOptions): Promise<string>;
|
|
8
|
+
getJob<T, R>(_queueName: string, _jobId: string): Promise<QueueJob<T, R> | null>;
|
|
9
|
+
private resolveQueueUrl;
|
|
10
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SQSClient, SendMessageCommand } from '@aws-sdk/client-sqs';
|
|
2
|
+
export class SQSQueueService {
|
|
3
|
+
queueUrlMap;
|
|
4
|
+
supportsResults = false;
|
|
5
|
+
client;
|
|
6
|
+
constructor(queueUrlMap) {
|
|
7
|
+
this.queueUrlMap = queueUrlMap;
|
|
8
|
+
this.client = new SQSClient({});
|
|
9
|
+
}
|
|
10
|
+
async add(queueName, data, options) {
|
|
11
|
+
const queueUrl = this.resolveQueueUrl(queueName);
|
|
12
|
+
const messageId = crypto.randomUUID();
|
|
13
|
+
const message = {
|
|
14
|
+
id: messageId,
|
|
15
|
+
queueName,
|
|
16
|
+
data,
|
|
17
|
+
pikkuUserId: options?.pikkuUserId,
|
|
18
|
+
};
|
|
19
|
+
const result = await this.client.send(new SendMessageCommand({
|
|
20
|
+
QueueUrl: queueUrl,
|
|
21
|
+
MessageBody: JSON.stringify(message),
|
|
22
|
+
DelaySeconds: options?.delay
|
|
23
|
+
? Math.min(Math.ceil(options.delay / 1000), 900)
|
|
24
|
+
: undefined,
|
|
25
|
+
}));
|
|
26
|
+
return result.MessageId ?? messageId;
|
|
27
|
+
}
|
|
28
|
+
async getJob(_queueName, _jobId) {
|
|
29
|
+
throw new Error('SQSQueueService does not support getJob(). ' +
|
|
30
|
+
'SQS is fire-and-forget. ' +
|
|
31
|
+
'Use BullMQ or PgBoss if you need job result tracking.');
|
|
32
|
+
}
|
|
33
|
+
resolveQueueUrl(queueName) {
|
|
34
|
+
if (this.queueUrlMap?.[queueName]) {
|
|
35
|
+
return this.queueUrlMap[queueName];
|
|
36
|
+
}
|
|
37
|
+
const envKey = `SQS_QUEUE_URL_${toScreamingSnake(queueName)}`;
|
|
38
|
+
const url = process.env[envKey];
|
|
39
|
+
if (!url) {
|
|
40
|
+
throw new Error(`SQS queue URL not found for queue "${queueName}". ` +
|
|
41
|
+
`Set environment variable ${envKey} or pass queueUrlMap to constructor.`);
|
|
42
|
+
}
|
|
43
|
+
return url;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function toScreamingSnake(name) {
|
|
47
|
+
return name
|
|
48
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
49
|
+
.replace(/-/g, '_')
|
|
50
|
+
.toUpperCase();
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=sqs-queue-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqs-queue-service.js","sourceRoot":"","sources":["../src/sqs-queue-service.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAGnE,MAAM,OAAO,eAAe;IAIN;IAHX,eAAe,GAAG,KAAK,CAAA;IACxB,MAAM,CAAW;IAEzB,YAAoB,WAAoC;QAApC,gBAAW,GAAX,WAAW,CAAyB;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,GAAG,CACP,SAAiB,EACjB,IAAO,EACP,OAAoB;QAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;QAErC,MAAM,OAAO,GAAG;YACd,EAAE,EAAE,SAAS;YACb,SAAS;YACT,IAAI;YACJ,WAAW,EAAE,OAAO,EAAE,WAAW;SAClC,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CACnC,IAAI,kBAAkB,CAAC;YACrB,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YACpC,YAAY,EAAE,OAAO,EAAE,KAAK;gBAC1B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC;gBAChD,CAAC,CAAC,SAAS;SACd,CAAC,CACH,CAAA;QAED,OAAO,MAAM,CAAC,SAAS,IAAI,SAAS,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,UAAkB,EAClB,MAAc;QAEd,MAAM,IAAI,KAAK,CACb,6CAA6C;YAC3C,0BAA0B;YAC1B,uDAAuD,CAC1D,CAAA;IACH,CAAC;IASO,eAAe,CAAC,SAAiB;QACvC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;QACpC,CAAC;QAED,MAAM,MAAM,GAAG,iBAAiB,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAA;QAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAE/B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,sCAAsC,SAAS,KAAK;gBAClD,4BAA4B,MAAM,sCAAsC,CAC3E,CAAA;QACH,CAAC;QAED,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,IAAI;SACR,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,WAAW,EAAE,CAAA;AAClB,CAAC"}
|
|
@@ -9,5 +9,5 @@ export declare const getServerlessDependencies: (channelStore: ChannelStore, eve
|
|
|
9
9
|
channelId: string;
|
|
10
10
|
callbackAPI: ApiGatewayManagementApiClient;
|
|
11
11
|
channelHandlerFactory: import("@pikku/core/channel").PikkuChannelHandlerFactory;
|
|
12
|
-
channelStore: ChannelStore<unknown, unknown, import("@pikku/core
|
|
12
|
+
channelStore: ChannelStore<unknown, unknown, import("@pikku/core/channel").Channel<unknown, unknown>>;
|
|
13
13
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/lambda",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "yasser.fadl@gmail.com",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -13,25 +13,31 @@
|
|
|
13
13
|
"release": "npm run build && npm test",
|
|
14
14
|
"test": "bash run-tests.sh",
|
|
15
15
|
"test:watch": "bash run-tests.sh --watch",
|
|
16
|
-
"test:coverage": "bash run-tests.sh --coverage"
|
|
16
|
+
"test:coverage": "bash run-tests.sh --coverage",
|
|
17
|
+
"prepublishOnly": "yarn build"
|
|
17
18
|
},
|
|
18
19
|
"exports": {
|
|
19
20
|
".": "./dist/index.js",
|
|
20
21
|
"./http": "./dist/http/index.js",
|
|
21
22
|
"./websocket": "./dist/websocket/index.js",
|
|
22
|
-
"./queue": "./dist/queue/index.js"
|
|
23
|
+
"./queue": "./dist/queue/index.js",
|
|
24
|
+
"./scheduled": "./dist/scheduled/index.js"
|
|
23
25
|
},
|
|
24
26
|
"peerDependencies": {
|
|
25
27
|
"@aws-sdk/client-apigatewaymanagementapi": "^3.713.0",
|
|
26
|
-
"@
|
|
28
|
+
"@aws-sdk/client-lambda": "^3.713.0",
|
|
29
|
+
"@aws-sdk/client-sqs": "^3.713.0",
|
|
30
|
+
"@pikku/core": "^0.12.44",
|
|
27
31
|
"@types/aws-lambda": "^8.10.161"
|
|
28
32
|
},
|
|
29
33
|
"devDependencies": {
|
|
30
34
|
"@aws-sdk/client-apigatewaymanagementapi": "^3.1000.0",
|
|
35
|
+
"@aws-sdk/client-lambda": "^3.1000.0",
|
|
36
|
+
"@aws-sdk/client-sqs": "^3.1000.0",
|
|
31
37
|
"@types/aws-lambda": "^8.10.161",
|
|
32
|
-
"typescript": "^
|
|
38
|
+
"typescript": "^6.0.3"
|
|
33
39
|
},
|
|
34
40
|
"engines": {
|
|
35
|
-
"node": ">=
|
|
41
|
+
"node": ">=22"
|
|
36
42
|
}
|
|
37
43
|
}
|