@webiny/api-websockets-aws 0.0.0-unstable.b6d7105cee → 6.6.0-alpha.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.
@@ -0,0 +1,22 @@
1
+ import type { Container } from "@webiny/feature/api";
2
+ import { WebSocketEventHandler } from "@webiny/event-handler-aws/abstractions/handlers/WebSocketEventHandler.js";
3
+ import type { IWebSocketEvent } from "@webiny/event-handler-aws/eventTypes/WebSocketEventType.js";
4
+ import type { IAuthenticationContext } from "@webiny/api-core/features/security/authentication/AuthenticationContext/abstractions.js";
5
+ import type { IIdentityContext } from "@webiny/api-core/features/security/IdentityContext/abstractions.js";
6
+ import type { ITenantContext } from "@webiny/api-core/features/tenancy/TenantContext/abstractions.js";
7
+ import type { IGetTenantByIdUseCase } from "@webiny/api-core/features/tenancy/GetTenantById/abstractions.js";
8
+ import type { EventContext, NextFunction } from "@webiny/event-handler-core";
9
+ import type { APIGatewayProxyResult } from "@webiny/aws-sdk/types/index.js";
10
+ declare class WebSocketLambdaHandlerImpl implements WebSocketEventHandler.Interface {
11
+ private container;
12
+ private authCtx;
13
+ private identityCtx;
14
+ private tenantCtx;
15
+ private getTenantById;
16
+ constructor(container: Container, authCtx: IAuthenticationContext, identityCtx: IIdentityContext, tenantCtx: ITenantContext, getTenantById: IGetTenantByIdUseCase);
17
+ execute(eventCtx: EventContext<IWebSocketEvent>, _next: NextFunction): Promise<APIGatewayProxyResult>;
18
+ }
19
+ export declare const WebSocketLambdaHandler: typeof WebSocketLambdaHandlerImpl & {
20
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-aws/abstractions/handlers/WebSocketEventHandler.js").IWebSocketEventHandler>;
21
+ };
22
+ export {};
@@ -0,0 +1,89 @@
1
+ import { WebSocketEventHandler } from "@webiny/event-handler-aws/abstractions/handlers/WebSocketEventHandler.js";
2
+ import { RequestContainer } from "@webiny/event-handler-core";
3
+ import { AuthenticationContext } from "@webiny/api-core/features/security/authentication/AuthenticationContext/index.js";
4
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
5
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
6
+ import { GetTenantByIdUseCase } from "@webiny/api-core/features/tenancy/GetTenantById/index.js";
7
+ import { WebsocketsRunner } from "@webiny/api-websockets/runner/index.js";
8
+ import { WebsocketsResponse } from "@webiny/api-websockets/response/index.js";
9
+ import { getEventValues } from "@webiny/api-websockets/handler/headers.js";
10
+ import { WebsocketsEventRequestContextEventType, WebsocketsEventRoute } from "./handler/types.js";
11
+ const getBody = (body)=>{
12
+ if ("string" == typeof body) try {
13
+ return JSON.parse(body);
14
+ } catch {
15
+ return {};
16
+ }
17
+ return body;
18
+ };
19
+ const toWebsocketsEvent = (raw, endpoint)=>{
20
+ const rc = raw.requestContext ?? {};
21
+ const eventTypeMap = {
22
+ [WebsocketsEventRequestContextEventType.message]: "message",
23
+ [WebsocketsEventRequestContextEventType.connect]: "connect",
24
+ [WebsocketsEventRequestContextEventType.disconnect]: "disconnect"
25
+ };
26
+ const routeMap = {
27
+ [WebsocketsEventRoute.connect]: "connect",
28
+ [WebsocketsEventRoute.disconnect]: "disconnect",
29
+ [WebsocketsEventRoute["default"]]: "default"
30
+ };
31
+ const routeKey = rc.routeKey;
32
+ const route = routeMap[routeKey ?? ""] ?? "default";
33
+ return {
34
+ headers: raw.headers,
35
+ context: {
36
+ connectionId: rc.connectionId ?? "",
37
+ connectedAt: rc.connectedAt ?? 0,
38
+ host: rc.domainName ?? "",
39
+ eventType: eventTypeMap[rc.eventType ?? ""] ?? "message",
40
+ route,
41
+ endpoint
42
+ },
43
+ body: getBody(raw.body)
44
+ };
45
+ };
46
+ class WebSocketLambdaHandlerImpl {
47
+ constructor(container, authCtx, identityCtx, tenantCtx, getTenantById){
48
+ this.container = container;
49
+ this.authCtx = authCtx;
50
+ this.identityCtx = identityCtx;
51
+ this.tenantCtx = tenantCtx;
52
+ this.getTenantById = getTenantById;
53
+ }
54
+ async execute(eventCtx, _next) {
55
+ const ctx = {
56
+ container: this.container
57
+ };
58
+ const raw = eventCtx.event;
59
+ const { token, tenant, endpoint } = getEventValues(raw);
60
+ const identity = await this.authCtx.authenticate(token ?? "");
61
+ this.identityCtx.setIdentity(identity);
62
+ const tenantResult = await this.getTenantById.execute(tenant);
63
+ if (tenantResult.isOk()) this.tenantCtx.setTenant(tenantResult.value);
64
+ const response = this.container.resolve(WebsocketsResponse);
65
+ const runner = new WebsocketsRunner(ctx, response);
66
+ const event = toWebsocketsEvent(raw, endpoint);
67
+ const result = await runner.run(event);
68
+ return {
69
+ statusCode: result.statusCode,
70
+ headers: {
71
+ "sec-websocket-protocol": "webiny-ws-v1"
72
+ },
73
+ body: ""
74
+ };
75
+ }
76
+ }
77
+ const WebSocketLambdaHandler = WebSocketEventHandler.createImplementation({
78
+ implementation: WebSocketLambdaHandlerImpl,
79
+ dependencies: [
80
+ RequestContainer,
81
+ AuthenticationContext,
82
+ IdentityContext,
83
+ TenantContext,
84
+ GetTenantByIdUseCase
85
+ ]
86
+ });
87
+ export { WebSocketLambdaHandler };
88
+
89
+ //# sourceMappingURL=WebSocketLambdaHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketLambdaHandler.js","sources":["../src/WebSocketLambdaHandler.ts"],"sourcesContent":["import type { Container } from \"@webiny/feature/api\";\nimport { WebSocketEventHandler } from \"@webiny/event-handler-aws/abstractions/handlers/WebSocketEventHandler.js\";\nimport type { IWebSocketEvent } from \"@webiny/event-handler-aws/eventTypes/WebSocketEventType.js\";\nimport { RequestContainer } from \"@webiny/event-handler-core\";\nimport { AuthenticationContext } from \"@webiny/api-core/features/security/authentication/AuthenticationContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { GetTenantByIdUseCase } from \"@webiny/api-core/features/tenancy/GetTenantById/index.js\";\nimport type { IAuthenticationContext } from \"@webiny/api-core/features/security/authentication/AuthenticationContext/abstractions.js\";\nimport type { IIdentityContext } from \"@webiny/api-core/features/security/IdentityContext/abstractions.js\";\nimport type { ITenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/abstractions.js\";\nimport type { IGetTenantByIdUseCase } from \"@webiny/api-core/features/tenancy/GetTenantById/abstractions.js\";\nimport type { EventContext, NextFunction } from \"@webiny/event-handler-core\";\nimport type { APIGatewayProxyResult } from \"@webiny/aws-sdk/types/index.js\";\nimport { WebsocketsRunner } from \"@webiny/api-websockets/runner/index.js\";\nimport { WebsocketsResponse } from \"@webiny/api-websockets/response/index.js\";\nimport type {\n Context,\n IWebsocketsEvent,\n WebsocketsEventType,\n WebsocketsRoute\n} from \"@webiny/api-websockets/types.js\";\nimport { getEventValues } from \"@webiny/api-websockets/handler/headers.js\";\nimport type { IWebsocketsIncomingEvent } from \"@webiny/api-websockets/handler/types.js\";\nimport { WebsocketsEventRequestContextEventType, WebsocketsEventRoute } from \"~/handler/types.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\nconst getBody = (body: GenericRecord | string | undefined) => {\n if (typeof body === \"string\") {\n try {\n return JSON.parse(body) as GenericRecord;\n } catch {\n return {};\n }\n }\n return body;\n};\n\nconst toWebsocketsEvent = (raw: IWebsocketsIncomingEvent, endpoint: string): IWebsocketsEvent => {\n const rc = raw.requestContext ?? {};\n const eventTypeMap: Record<string, WebsocketsEventType> = {\n [WebsocketsEventRequestContextEventType.message]: \"message\",\n [WebsocketsEventRequestContextEventType.connect]: \"connect\",\n [WebsocketsEventRequestContextEventType.disconnect]: \"disconnect\"\n };\n // AWS delivers routeKey as \"$connect\"/\"$disconnect\"/\"$default\"; route handlers register under the\n // un-prefixed WebsocketsRoute (\"connect\"/\"disconnect\"/\"default\"). Without this map the runner\n // matches the raw \"$connect\" and finds no handler (\"There are no handlers for the route: $connect\").\n const routeMap: Record<string, WebsocketsRoute> = {\n [WebsocketsEventRoute.connect]: \"connect\",\n [WebsocketsEventRoute.disconnect]: \"disconnect\",\n [WebsocketsEventRoute.default]: \"default\"\n };\n const routeKey = rc.routeKey as string | undefined;\n const route = routeMap[routeKey ?? \"\"] ?? \"default\";\n\n return {\n headers: raw.headers as Record<string, string> | undefined,\n context: {\n connectionId: rc.connectionId ?? \"\",\n connectedAt: rc.connectedAt ?? 0,\n host: rc.domainName ?? \"\",\n eventType: eventTypeMap[rc.eventType ?? \"\"] ?? \"message\",\n route,\n endpoint\n },\n body: getBody(raw.body)\n };\n};\n\nclass WebSocketLambdaHandlerImpl implements WebSocketEventHandler.Interface {\n constructor(\n private container: Container,\n private authCtx: IAuthenticationContext,\n private identityCtx: IIdentityContext,\n private tenantCtx: ITenantContext,\n private getTenantById: IGetTenantByIdUseCase\n ) {}\n\n async execute(\n eventCtx: EventContext<IWebSocketEvent>,\n _next: NextFunction\n ): Promise<APIGatewayProxyResult> {\n // Route handlers and all websockets services are resolved from the DI container;\n // the runner only needs `container` on the context object.\n const ctx: Record<string, any> = { container: this.container };\n\n const raw = eventCtx.event as IWebsocketsIncomingEvent;\n const { token, tenant, endpoint } = getEventValues(raw);\n\n const identity = await this.authCtx.authenticate(token ?? \"\");\n this.identityCtx.setIdentity(identity);\n\n const tenantResult = await this.getTenantById.execute(tenant);\n if (tenantResult.isOk()) {\n this.tenantCtx.setTenant(tenantResult.value);\n }\n\n const response = this.container.resolve(WebsocketsResponse);\n const runner = new WebsocketsRunner(ctx as Context, response);\n const event = toWebsocketsEvent(raw, endpoint);\n const result = await runner.run(event);\n\n return {\n statusCode: result.statusCode,\n headers: {\n \"sec-websocket-protocol\": \"webiny-ws-v1\"\n },\n body: \"\"\n };\n }\n}\n\nexport const WebSocketLambdaHandler = WebSocketEventHandler.createImplementation({\n implementation: WebSocketLambdaHandlerImpl,\n dependencies: [\n RequestContainer,\n AuthenticationContext,\n IdentityContext,\n TenantContext,\n GetTenantByIdUseCase\n ]\n});\n"],"names":["getBody","body","JSON","toWebsocketsEvent","raw","endpoint","rc","eventTypeMap","WebsocketsEventRequestContextEventType","routeMap","WebsocketsEventRoute","routeKey","route","WebSocketLambdaHandlerImpl","container","authCtx","identityCtx","tenantCtx","getTenantById","eventCtx","_next","ctx","token","tenant","getEventValues","identity","tenantResult","response","WebsocketsResponse","runner","WebsocketsRunner","event","result","WebSocketLambdaHandler","WebSocketEventHandler","RequestContainer","AuthenticationContext","IdentityContext","TenantContext","GetTenantByIdUseCase"],"mappings":";;;;;;;;;;AA2BA,MAAMA,UAAU,CAACC;IACb,IAAI,AAAgB,YAAhB,OAAOA,MACP,IAAI;QACA,OAAOC,KAAK,KAAK,CAACD;IACtB,EAAE,OAAM;QACJ,OAAO,CAAC;IACZ;IAEJ,OAAOA;AACX;AAEA,MAAME,oBAAoB,CAACC,KAA+BC;IACtD,MAAMC,KAAKF,IAAI,cAAc,IAAI,CAAC;IAClC,MAAMG,eAAoD;QACtD,CAACC,uCAAuC,OAAO,CAAC,EAAE;QAClD,CAACA,uCAAuC,OAAO,CAAC,EAAE;QAClD,CAACA,uCAAuC,UAAU,CAAC,EAAE;IACzD;IAIA,MAAMC,WAA4C;QAC9C,CAACC,qBAAqB,OAAO,CAAC,EAAE;QAChC,CAACA,qBAAqB,UAAU,CAAC,EAAE;QACnC,CAACA,oBAAoB,CAApBA,UAA4B,CAAC,EAAE;IACpC;IACA,MAAMC,WAAWL,GAAG,QAAQ;IAC5B,MAAMM,QAAQH,QAAQ,CAACE,YAAY,GAAG,IAAI;IAE1C,OAAO;QACH,SAASP,IAAI,OAAO;QACpB,SAAS;YACL,cAAcE,GAAG,YAAY,IAAI;YACjC,aAAaA,GAAG,WAAW,IAAI;YAC/B,MAAMA,GAAG,UAAU,IAAI;YACvB,WAAWC,YAAY,CAACD,GAAG,SAAS,IAAI,GAAG,IAAI;YAC/CM;YACAP;QACJ;QACA,MAAML,QAAQI,IAAI,IAAI;IAC1B;AACJ;AAEA,MAAMS;IACF,YACYC,SAAoB,EACpBC,OAA+B,EAC/BC,WAA6B,EAC7BC,SAAyB,EACzBC,aAAoC,CAC9C;aALUJ,SAAS,GAATA;aACAC,OAAO,GAAPA;aACAC,WAAW,GAAXA;aACAC,SAAS,GAATA;aACAC,aAAa,GAAbA;IACT;IAEH,MAAM,QACFC,QAAuC,EACvCC,KAAmB,EACW;QAG9B,MAAMC,MAA2B;YAAE,WAAW,IAAI,CAAC,SAAS;QAAC;QAE7D,MAAMjB,MAAMe,SAAS,KAAK;QAC1B,MAAM,EAAEG,KAAK,EAAEC,MAAM,EAAElB,QAAQ,EAAE,GAAGmB,eAAepB;QAEnD,MAAMqB,WAAW,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAACH,SAAS;QAC1D,IAAI,CAAC,WAAW,CAAC,WAAW,CAACG;QAE7B,MAAMC,eAAe,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAACH;QACtD,IAAIG,aAAa,IAAI,IACjB,IAAI,CAAC,SAAS,CAAC,SAAS,CAACA,aAAa,KAAK;QAG/C,MAAMC,WAAW,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QACxC,MAAMC,SAAS,IAAIC,iBAAiBT,KAAgBM;QACpD,MAAMI,QAAQ5B,kBAAkBC,KAAKC;QACrC,MAAM2B,SAAS,MAAMH,OAAO,GAAG,CAACE;QAEhC,OAAO;YACH,YAAYC,OAAO,UAAU;YAC7B,SAAS;gBACL,0BAA0B;YAC9B;YACA,MAAM;QACV;IACJ;AACJ;AAEO,MAAMC,yBAAyBC,sBAAsB,oBAAoB,CAAC;IAC7E,gBAAgBrB;IAChB,cAAc;QACVsB;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
@@ -0,0 +1,16 @@
1
+ import { ConnectionRegistry } from "@webiny/api-websockets/exports/api.js";
2
+ import type { DynamoDBDocument } from "@webiny/aws-sdk/client-dynamodb/index.js";
3
+ export declare class WebsocketsConnectionRegistry implements ConnectionRegistry.Interface {
4
+ private readonly entity;
5
+ constructor(documentClient: DynamoDBDocument);
6
+ register(params: ConnectionRegistry.RegisterParams): Promise<ConnectionRegistry.Data>;
7
+ unregister(params: ConnectionRegistry.UnregisterParams): Promise<void>;
8
+ private getViaConnection;
9
+ listViaConnections(connections: string[]): Promise<ConnectionRegistry.Data[]>;
10
+ listViaIdentity(identity: string): Promise<ConnectionRegistry.Data[]>;
11
+ listViaTenant(tenant: string): Promise<ConnectionRegistry.Data[]>;
12
+ listAll(): Promise<ConnectionRegistry.Data[]>;
13
+ updateLastSeen(_connectionId: string): Promise<void>;
14
+ listStale(_olderThan: Date): Promise<ConnectionRegistry.Data[]>;
15
+ private store;
16
+ }
@@ -0,0 +1,121 @@
1
+ import error from "@webiny/error";
2
+ import { createEntity } from "./entity.js";
3
+ const PK = "WS#CONNECTIONS";
4
+ const GSI1_PK = "WS#CONNECTIONS#IDENTITY";
5
+ const GSI2_PK = "WS#CONNECTIONS#TENANT";
6
+ class WebsocketsConnectionRegistry {
7
+ constructor(documentClient){
8
+ this.entity = createEntity(documentClient);
9
+ }
10
+ async register(params) {
11
+ const { connectionId, tenant, identity, endpoint, connectedOn } = params;
12
+ const data = {
13
+ connectionId,
14
+ identity,
15
+ tenant,
16
+ endpoint,
17
+ connectedOn
18
+ };
19
+ await this.store(data);
20
+ return data;
21
+ }
22
+ async unregister(params) {
23
+ const { connectionId } = params;
24
+ const keys = {
25
+ PK: PK,
26
+ SK: connectionId
27
+ };
28
+ const original = await this.getViaConnection(connectionId);
29
+ if (!original) {
30
+ const message = `There is no connection with ID "${connectionId}".`;
31
+ console.error(message);
32
+ throw new error(message, "CONNECTION_NOT_FOUND", keys);
33
+ }
34
+ try {
35
+ await this.entity.delete(keys);
36
+ } catch (ex) {
37
+ console.error(`Could not remove connection from the database: ${original.connectionId}`);
38
+ throw new error(ex.message, ex.code, keys);
39
+ }
40
+ }
41
+ async getViaConnection(connectionId) {
42
+ const item = await this.entity.get({
43
+ PK: PK,
44
+ SK: connectionId
45
+ });
46
+ if (!item) return null;
47
+ return item?.data || null;
48
+ }
49
+ async listViaConnections(connections) {
50
+ const reader = this.entity.createEntityReader({
51
+ read: connections.map((id)=>({
52
+ PK: PK,
53
+ SK: id
54
+ }))
55
+ });
56
+ const results = await reader.execute();
57
+ return results.map((item)=>item.data);
58
+ }
59
+ async listViaIdentity(identity) {
60
+ const items = await this.entity.queryAll({
61
+ partitionKey: GSI1_PK,
62
+ options: {
63
+ index: "GSI1",
64
+ eq: identity
65
+ }
66
+ });
67
+ return items.map((item)=>item.data);
68
+ }
69
+ async listViaTenant(tenant) {
70
+ const options = {
71
+ beginsWith: `T#${tenant}`
72
+ };
73
+ const items = await this.entity.queryAll({
74
+ partitionKey: GSI2_PK,
75
+ options: {
76
+ ...options,
77
+ index: "GSI2"
78
+ }
79
+ });
80
+ return items.map((item)=>item.data);
81
+ }
82
+ async listAll() {
83
+ const items = await this.entity.queryAll({
84
+ partitionKey: PK,
85
+ options: {
86
+ gte: " "
87
+ }
88
+ });
89
+ return items.map((item)=>item.data);
90
+ }
91
+ async updateLastSeen(_connectionId) {}
92
+ async listStale(_olderThan) {
93
+ return [];
94
+ }
95
+ async store(data) {
96
+ const { connectionId, tenant, identity } = data;
97
+ const item = {
98
+ PK: PK,
99
+ SK: connectionId,
100
+ GSI1_PK: GSI1_PK,
101
+ GSI1_SK: identity.id,
102
+ GSI2_PK: GSI2_PK,
103
+ GSI2_SK: `T#${tenant}`,
104
+ GSI_TENANT: tenant,
105
+ TYPE: "ws.connection",
106
+ data
107
+ };
108
+ try {
109
+ return await this.entity.put(item);
110
+ } catch (err) {
111
+ throw error.from(err, {
112
+ message: "Could not store websockets connection data.",
113
+ code: "STORE_WEBSOCKETS_CONNECTION_DATA_ERROR",
114
+ data: item
115
+ });
116
+ }
117
+ }
118
+ }
119
+ export { WebsocketsConnectionRegistry };
120
+
121
+ //# sourceMappingURL=WebsocketsConnectionRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebsocketsConnectionRegistry.js","sources":["../src/WebsocketsConnectionRegistry.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport { ConnectionRegistry } from \"@webiny/api-websockets/exports/api.js\";\nimport { createEntity } from \"./entity.js\";\nimport type { DynamoDBDocument } from \"@webiny/aws-sdk/client-dynamodb/index.js\";\nimport type { EntityQueryOptions } from \"@webiny/db-dynamodb/toolbox.js\";\n\nconst PK = `WS#CONNECTIONS`;\nconst GSI1_PK = \"WS#CONNECTIONS#IDENTITY\";\nconst GSI2_PK = \"WS#CONNECTIONS#TENANT\";\n\nexport class WebsocketsConnectionRegistry implements ConnectionRegistry.Interface {\n private readonly entity;\n\n public constructor(documentClient: DynamoDBDocument) {\n this.entity = createEntity(documentClient);\n }\n\n public async register(\n params: ConnectionRegistry.RegisterParams\n ): Promise<ConnectionRegistry.Data> {\n const { connectionId, tenant, identity, endpoint, connectedOn } = params;\n\n const data: ConnectionRegistry.Data = {\n connectionId,\n identity,\n tenant,\n endpoint,\n connectedOn\n };\n await this.store(data);\n return data;\n }\n\n public async unregister(params: ConnectionRegistry.UnregisterParams): Promise<void> {\n const { connectionId } = params;\n\n const keys = {\n PK,\n SK: connectionId\n };\n const original = await this.getViaConnection(connectionId);\n if (!original) {\n const message = `There is no connection with ID \"${connectionId}\".`;\n console.error(message);\n throw new WebinyError(message, \"CONNECTION_NOT_FOUND\", keys);\n }\n\n try {\n await this.entity.delete(keys);\n } catch (ex) {\n console.error(\n `Could not remove connection from the database: ${original.connectionId}`\n );\n throw new WebinyError(ex.message, ex.code, keys);\n }\n }\n\n private async getViaConnection(connectionId: string): Promise<ConnectionRegistry.Data | null> {\n const item = await this.entity.get({\n PK,\n SK: connectionId\n });\n if (!item) {\n return null;\n }\n return item?.data || null;\n }\n\n public async listViaConnections(connections: string[]): Promise<ConnectionRegistry.Data[]> {\n const reader = this.entity.createEntityReader({\n read: connections.map(id => {\n return {\n PK,\n SK: id\n };\n })\n });\n\n const results = await reader.execute();\n\n return results.map(item => {\n return item.data;\n });\n }\n\n public async listViaIdentity(identity: string): Promise<ConnectionRegistry.Data[]> {\n const items = await this.entity.queryAll({\n partitionKey: GSI1_PK,\n options: {\n index: \"GSI1\",\n eq: identity\n }\n });\n return items.map(item => {\n return item.data;\n });\n }\n\n public async listViaTenant(tenant: string): Promise<ConnectionRegistry.Data[]> {\n const options: Partial<EntityQueryOptions> = {\n beginsWith: `T#${tenant}`\n };\n\n const items = await this.entity.queryAll({\n partitionKey: GSI2_PK,\n options: {\n ...options,\n index: \"GSI2\"\n }\n });\n return items.map(item => {\n return item.data;\n });\n }\n\n public async listAll(): Promise<ConnectionRegistry.Data[]> {\n const items = await this.entity.queryAll({\n partitionKey: PK,\n options: {\n gte: \" \"\n }\n });\n return items.map(item => {\n return item.data;\n });\n }\n\n /* No-op: heartbeat-based tracking is server-only; DDB registry does not track lastSeen. */\n public async updateLastSeen(_connectionId: string): Promise<void> {\n return;\n }\n\n /* No-op: stale connection cleanup is server-only; DDB registry always returns empty. */\n public async listStale(_olderThan: Date): Promise<ConnectionRegistry.Data[]> {\n return [];\n }\n\n private async store(data: ConnectionRegistry.Data) {\n const { connectionId, tenant, identity } = data;\n const item = {\n PK,\n SK: connectionId,\n GSI1_PK,\n GSI1_SK: identity.id,\n GSI2_PK,\n GSI2_SK: `T#${tenant}`,\n GSI_TENANT: tenant,\n TYPE: \"ws.connection\",\n data\n };\n try {\n return await this.entity.put(item);\n } catch (err) {\n throw WebinyError.from(err, {\n message: \"Could not store websockets connection data.\",\n code: \"STORE_WEBSOCKETS_CONNECTION_DATA_ERROR\",\n data: item\n });\n }\n }\n}\n"],"names":["PK","GSI1_PK","GSI2_PK","WebsocketsConnectionRegistry","documentClient","createEntity","params","connectionId","tenant","identity","endpoint","connectedOn","data","keys","original","message","console","WebinyError","ex","item","connections","reader","id","results","items","options","_connectionId","_olderThan","err"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type Container } from "@webiny/feature/api";
2
+ export declare const WebsocketsDdbFeature: {
3
+ name: string;
4
+ register(container: Container): void;
5
+ };
@@ -0,0 +1,16 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { DynamoDBClient } from "@webiny/db-dynamodb";
3
+ import { ConnectionRegistry } from "@webiny/api-websockets/features/ConnectionRegistry/abstractions.js";
4
+ import { WebsocketsConnectionRegistry } from "./WebsocketsConnectionRegistry.js";
5
+ const WebsocketsDdbFeature = createFeature({
6
+ name: "WebsocketsDdb",
7
+ register (container) {
8
+ container.registerFactory(ConnectionRegistry, ()=>{
9
+ const db = container.resolve(DynamoDBClient);
10
+ return new WebsocketsConnectionRegistry(db.client);
11
+ });
12
+ }
13
+ });
14
+ export { WebsocketsDdbFeature };
15
+
16
+ //# sourceMappingURL=WebsocketsDdbFeature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebsocketsDdbFeature.js","sources":["../src/WebsocketsDdbFeature.ts"],"sourcesContent":["import { type Container, createFeature } from \"@webiny/feature/api\";\nimport { DynamoDBClient } from \"@webiny/db-dynamodb\";\nimport { ConnectionRegistry } from \"@webiny/api-websockets/features/ConnectionRegistry/abstractions.js\";\nimport { WebsocketsConnectionRegistry } from \"./WebsocketsConnectionRegistry.js\";\n\nexport const WebsocketsDdbFeature = createFeature({\n name: \"WebsocketsDdb\",\n register(container: Container) {\n container.registerFactory(ConnectionRegistry, () => {\n const db = container.resolve(DynamoDBClient);\n return new WebsocketsConnectionRegistry(db.client);\n });\n }\n});\n"],"names":["WebsocketsDdbFeature","createFeature","container","ConnectionRegistry","db","DynamoDBClient","WebsocketsConnectionRegistry"],"mappings":";;;;AAKO,MAAMA,uBAAuBC,cAAc;IAC9C,MAAM;IACN,UAASC,SAAoB;QACzBA,UAAU,eAAe,CAACC,oBAAoB;YAC1C,MAAMC,KAAKF,UAAU,OAAO,CAACG;YAC7B,OAAO,IAAIC,6BAA6BF,GAAG,MAAM;QACrD;IACJ;AACJ"}
package/entity.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { DynamoDBDocument } from "@webiny/aws-sdk/client-dynamodb/index.js";
2
+ export declare const createEntity: (documentClient: DynamoDBDocument) => import("@webiny/db-dynamodb").IEntity<import("@webiny/db-dynamodb").IStandardEntityAttributes<import("@webiny/api-websockets/features/ConnectionRegistry/abstractions").IWebsocketsConnectionRegistryData>>;
package/entity.js ADDED
@@ -0,0 +1,48 @@
1
+ import { createStandardEntity, createTable } from "@webiny/db-dynamodb";
2
+ const entity_name = "SocketsConnectionRegistry";
3
+ const createEntity = (documentClient)=>{
4
+ const table = createTable({
5
+ name: String(process.env.DB_TABLE),
6
+ documentClient
7
+ });
8
+ return createStandardEntity({
9
+ name: entity_name,
10
+ table: table.table,
11
+ attributes: {
12
+ PK: {
13
+ partitionKey: true
14
+ },
15
+ SK: {
16
+ sortKey: true
17
+ },
18
+ GSI1_PK: {
19
+ type: "string",
20
+ required: true
21
+ },
22
+ GSI1_SK: {
23
+ type: "string",
24
+ required: true
25
+ },
26
+ GSI2_PK: {
27
+ type: "string",
28
+ required: true
29
+ },
30
+ GSI2_SK: {
31
+ type: "string",
32
+ required: true
33
+ },
34
+ TYPE: {
35
+ type: "string",
36
+ default: entity_name,
37
+ required: true
38
+ },
39
+ data: {
40
+ type: "map",
41
+ required: true
42
+ }
43
+ }
44
+ });
45
+ };
46
+ export { createEntity };
47
+
48
+ //# sourceMappingURL=entity.js.map
package/entity.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.js","sources":["../src/entity.ts"],"sourcesContent":["import type { DynamoDBDocument } from \"@webiny/aws-sdk/client-dynamodb/index.js\";\nimport { createStandardEntity, createTable } from \"@webiny/db-dynamodb\";\nimport { ConnectionRegistry } from \"@webiny/api-websockets/exports/api.js\";\n\nconst name = \"SocketsConnectionRegistry\";\n\nexport const createEntity = (documentClient: DynamoDBDocument) => {\n const table = createTable({\n name: String(process.env.DB_TABLE),\n documentClient\n });\n\n return createStandardEntity<ConnectionRegistry.Data>({\n name,\n table: table.table,\n attributes: {\n PK: {\n partitionKey: true\n },\n SK: {\n sortKey: true\n },\n GSI1_PK: {\n type: \"string\",\n required: true\n },\n GSI1_SK: {\n type: \"string\",\n required: true\n },\n GSI2_PK: {\n type: \"string\",\n required: true\n },\n GSI2_SK: {\n type: \"string\",\n required: true\n },\n TYPE: {\n type: \"string\",\n default: name,\n required: true\n },\n data: {\n type: \"map\",\n required: true\n }\n }\n });\n};\n"],"names":["name","createEntity","documentClient","table","createTable","String","process","createStandardEntity"],"mappings":";AAIA,MAAMA,cAAO;AAEN,MAAMC,eAAe,CAACC;IACzB,MAAMC,QAAQC,YAAY;QACtB,MAAMC,OAAOC,QAAQ,GAAG,CAAC,QAAQ;QACjCJ;IACJ;IAEA,OAAOK,qBAA8C;QACjDP,MAAAA;QACA,OAAOG,MAAM,KAAK;QAClB,YAAY;YACR,IAAI;gBACA,cAAc;YAClB;YACA,IAAI;gBACA,SAAS;YACb;YACA,SAAS;gBACL,MAAM;gBACN,UAAU;YACd;YACA,SAAS;gBACL,MAAM;gBACN,UAAU;YACd;YACA,SAAS;gBACL,MAAM;gBACN,UAAU;YACd;YACA,SAAS;gBACL,MAAM;gBACN,UAAU;YACd;YACA,MAAM;gBACF,MAAM;gBACN,SAASH;gBACT,UAAU;YACd;YACA,MAAM;gBACF,MAAM;gBACN,UAAU;YACd;QACJ;IACJ;AACJ"}
@@ -1,15 +1,6 @@
1
- import type { HandlerFactoryParams } from "@webiny/handler-aws/types.js";
2
- import type { WebsocketsResponse } from "@webiny/api-websockets/exports/api.js";
3
- import type { APIGatewayProxyResult, Context as LambdaContext } from "@webiny/aws-sdk/types/index.js";
4
1
  import type { WebsocketsRunner } from "@webiny/api-websockets/exports/api.js";
5
2
  import type { GenericRecord } from "@webiny/api/types.js";
6
3
  import type { PartialDeep } from "type-fest";
7
- export interface HandlerCallable {
8
- (event: IAwsWebsocketsIncomingEvent, context: LambdaContext): Promise<APIGatewayProxyResult>;
9
- }
10
- export interface HandlerParams extends HandlerFactoryParams {
11
- response?: WebsocketsResponse.Interface;
12
- }
13
4
  export declare enum WebsocketsEventRoute {
14
5
  connect = "$connect",
15
6
  disconnect = "$disconnect",
@@ -1 +1 @@
1
- {"version":3,"file":"handler/types.js","sources":["../../src/handler/types.ts"],"sourcesContent":["import type { HandlerFactoryParams } from \"@webiny/handler-aws/types.js\";\nimport type { WebsocketsResponse } from \"@webiny/api-websockets/exports/api.js\";\nimport type {\n APIGatewayProxyResult,\n Context as LambdaContext\n} from \"@webiny/aws-sdk/types/index.js\";\nimport type { WebsocketsRunner } from \"@webiny/api-websockets/exports/api.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\nimport type { PartialDeep } from \"type-fest\";\n\nexport interface HandlerCallable {\n (event: IAwsWebsocketsIncomingEvent, context: LambdaContext): Promise<APIGatewayProxyResult>;\n}\n\nexport interface HandlerParams extends HandlerFactoryParams {\n response?: WebsocketsResponse.Interface;\n}\n\nexport enum WebsocketsEventRoute {\n connect = \"$connect\",\n disconnect = \"$disconnect\",\n default = \"$default\"\n}\n\nexport enum WebsocketsEventRequestContextEventType {\n message = \"MESSAGE\",\n connect = \"CONNECT\",\n disconnect = \"DISCONNECT\"\n}\n\nexport interface IAwsWebsocketsEventRequestContext {\n connectionId: string;\n connectedAt: number;\n domainName: string;\n eventType: WebsocketsEventRequestContextEventType;\n routeKey: WebsocketsEventRoute | string;\n stage: string;\n}\n\nexport interface IAwsWebsocketsEventHeaders {\n \"Accept-Encoding\"?: string;\n \"Accept-Language\"?: string;\n \"Cache-Control\"?: string;\n Host?: string;\n Origin?: string;\n Pragma?: string;\n \"Sec-WebSocket-Extensions\"?: string;\n \"Sec-WebSocket-Key\"?: string;\n \"Sec-WebSocket-Version\"?: string;\n \"Sec-WebSocket-Protocol\"?: string;\n \"User-Agent\"?: string;\n \"X-Amzn-Trace-Id\"?: string;\n \"X-Forwarded-For\"?: string;\n \"X-Forwarded-Port\"?: `${number}`;\n \"X-Forwarded-Proto\"?: \"https\" | \"http\";\n [\"x-tenant\"]?: string;\n [\"x-webiny-cms-endpoint\"]?: string;\n}\n\nexport interface IAwsWebsocketsEventQueryStringParameters {\n tenant?: string;\n token?: string;\n}\n\nexport interface IAwsWebsocketsEvent<\n T extends WebsocketsRunner.EventData = WebsocketsRunner.EventData\n> {\n headers?: IAwsWebsocketsEventHeaders;\n queryStringParameters?: IAwsWebsocketsEventQueryStringParameters;\n requestContext: IAwsWebsocketsEventRequestContext;\n body?: T;\n}\n\nexport interface IAwsWebsocketsIncomingEvent extends PartialDeep<\n Omit<IAwsWebsocketsEvent, \"body\">\n> {\n body?: string | GenericRecord;\n}\n"],"names":["WebsocketsEventRoute","WebsocketsEventRequestContextEventType"],"mappings":"AAkBO,IAAKA,6BAAoBA,WAAAA,GAAAA,SAApBA,oBAAoB;;;;WAApBA;;AAML,IAAKC,+CAAsCA,WAAAA,GAAAA,SAAtCA,sCAAsC;;;;WAAtCA"}
1
+ {"version":3,"file":"handler/types.js","sources":["../../src/handler/types.ts"],"sourcesContent":["import type { WebsocketsRunner } from \"@webiny/api-websockets/exports/api.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\nimport type { PartialDeep } from \"type-fest\";\n\nexport enum WebsocketsEventRoute {\n connect = \"$connect\",\n disconnect = \"$disconnect\",\n default = \"$default\"\n}\n\nexport enum WebsocketsEventRequestContextEventType {\n message = \"MESSAGE\",\n connect = \"CONNECT\",\n disconnect = \"DISCONNECT\"\n}\n\nexport interface IAwsWebsocketsEventRequestContext {\n connectionId: string;\n connectedAt: number;\n domainName: string;\n eventType: WebsocketsEventRequestContextEventType;\n routeKey: WebsocketsEventRoute | string;\n stage: string;\n}\n\nexport interface IAwsWebsocketsEventHeaders {\n \"Accept-Encoding\"?: string;\n \"Accept-Language\"?: string;\n \"Cache-Control\"?: string;\n Host?: string;\n Origin?: string;\n Pragma?: string;\n \"Sec-WebSocket-Extensions\"?: string;\n \"Sec-WebSocket-Key\"?: string;\n \"Sec-WebSocket-Version\"?: string;\n \"Sec-WebSocket-Protocol\"?: string;\n \"User-Agent\"?: string;\n \"X-Amzn-Trace-Id\"?: string;\n \"X-Forwarded-For\"?: string;\n \"X-Forwarded-Port\"?: `${number}`;\n \"X-Forwarded-Proto\"?: \"https\" | \"http\";\n [\"x-tenant\"]?: string;\n [\"x-webiny-cms-endpoint\"]?: string;\n}\n\nexport interface IAwsWebsocketsEventQueryStringParameters {\n tenant?: string;\n token?: string;\n}\n\nexport interface IAwsWebsocketsEvent<\n T extends WebsocketsRunner.EventData = WebsocketsRunner.EventData\n> {\n headers?: IAwsWebsocketsEventHeaders;\n queryStringParameters?: IAwsWebsocketsEventQueryStringParameters;\n requestContext: IAwsWebsocketsEventRequestContext;\n body?: T;\n}\n\nexport interface IAwsWebsocketsIncomingEvent extends PartialDeep<\n Omit<IAwsWebsocketsEvent, \"body\">\n> {\n body?: string | GenericRecord;\n}\n"],"names":["WebsocketsEventRoute","WebsocketsEventRequestContextEventType"],"mappings":"AAIO,IAAKA,6BAAoBA,WAAAA,GAAAA,SAApBA,oBAAoB;;;;WAApBA;;AAML,IAAKC,+CAAsCA,WAAAA,GAAAA,SAAtCA,sCAAsC;;;;WAAtCA"}
package/index.d.ts CHANGED
@@ -1,2 +1,9 @@
1
- import "./handler/register.js";
2
- export declare const createAwsWebsockets: () => import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types.js").Context>[];
1
+ export { AwsWebsocketsTransport } from "./transport/AwsWebsocketsTransport.js";
2
+ export { WebsocketsConnectionRegistry } from "./WebsocketsConnectionRegistry.js";
3
+ export { WebsocketsDdbFeature } from "./WebsocketsDdbFeature.js";
4
+ export declare const WebsocketsAwsFeature: {
5
+ name: string;
6
+ register(container: import("@webiny/di").Container): void;
7
+ };
8
+ /** @deprecated use WebsocketsAwsFeature.register(container) */
9
+ export declare const createAwsWebsockets: () => never[];
package/index.js CHANGED
@@ -1,15 +1,19 @@
1
- import "./handler/register.js";
2
- import { createRegisterExtensionPlugin } from "@webiny/handler";
1
+ import { createFeature } from "@webiny/feature/api";
3
2
  import { AwsWebsocketsTransport } from "./transport/AwsWebsocketsTransport.js";
3
+ import { WebSocketLambdaHandler } from "./WebSocketLambdaHandler.js";
4
+ const WebsocketsAwsFeature = createFeature({
5
+ name: "WebsocketsAws",
6
+ register (container) {
7
+ container.register(WebSocketLambdaHandler);
8
+ container.register(AwsWebsocketsTransport);
9
+ }
10
+ });
4
11
  const createAwsWebsockets = ()=>{
5
- const plugin = createRegisterExtensionPlugin((context)=>{
6
- context.container.register(AwsWebsocketsTransport).inSingletonScope();
7
- });
8
- plugin.name = "websockets.aws.transport";
9
- return [
10
- plugin
11
- ];
12
+ console.warn("[api-websockets-aws] createAwsWebsockets() is deprecated. Use WebsocketsAwsFeature.register(container) instead.");
13
+ return [];
12
14
  };
13
- export { createAwsWebsockets };
15
+ export { WebsocketsConnectionRegistry } from "./WebsocketsConnectionRegistry.js";
16
+ export { WebsocketsDdbFeature } from "./WebsocketsDdbFeature.js";
17
+ export { AwsWebsocketsTransport, WebsocketsAwsFeature, createAwsWebsockets };
14
18
 
15
19
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import \"./handler/register.js\";\nimport { createRegisterExtensionPlugin } from \"@webiny/handler\";\nimport { AwsWebsocketsTransport } from \"~/transport/AwsWebsocketsTransport.js\";\n\nexport const createAwsWebsockets = () => {\n const plugin = createRegisterExtensionPlugin(context => {\n context.container.register(AwsWebsocketsTransport).inSingletonScope();\n });\n plugin.name = \"websockets.aws.transport\";\n return [plugin];\n};\n"],"names":["createAwsWebsockets","plugin","createRegisterExtensionPlugin","context","AwsWebsocketsTransport"],"mappings":";;;AAIO,MAAMA,sBAAsB;IAC/B,MAAMC,SAASC,8BAA8BC,CAAAA;QACzCA,QAAQ,SAAS,CAAC,QAAQ,CAACC,wBAAwB,gBAAgB;IACvE;IACAH,OAAO,IAAI,GAAG;IACd,OAAO;QAACA;KAAO;AACnB"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { AwsWebsocketsTransport } from \"~/transport/AwsWebsocketsTransport.js\";\nimport { WebSocketLambdaHandler } from \"~/WebSocketLambdaHandler.js\";\n\nexport { AwsWebsocketsTransport } from \"~/transport/AwsWebsocketsTransport.js\";\nexport { WebsocketsConnectionRegistry } from \"~/WebsocketsConnectionRegistry.js\";\nexport { WebsocketsDdbFeature } from \"~/WebsocketsDdbFeature.js\";\n\nexport const WebsocketsAwsFeature = createFeature({\n name: \"WebsocketsAws\",\n register(container) {\n container.register(WebSocketLambdaHandler);\n container.register(AwsWebsocketsTransport);\n }\n});\n\n/** @deprecated use WebsocketsAwsFeature.register(container) */\nexport const createAwsWebsockets = () => {\n console.warn(\n \"[api-websockets-aws] createAwsWebsockets() is deprecated. Use WebsocketsAwsFeature.register(container) instead.\"\n );\n return [];\n};\n"],"names":["WebsocketsAwsFeature","createFeature","container","WebSocketLambdaHandler","AwsWebsocketsTransport","createAwsWebsockets","console"],"mappings":";;;AAQO,MAAMA,uBAAuBC,cAAc;IAC9C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;IACvB;AACJ;AAGO,MAAMC,sBAAsB;IAC/BC,QAAQ,IAAI,CACR;IAEJ,OAAO,EAAE;AACb"}
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@webiny/api-websockets-aws",
3
- "version": "0.0.0-unstable.b6d7105cee",
3
+ "version": "6.6.0-alpha.1",
4
4
  "type": "module",
5
+ "keywords": [
6
+ "@webiny/api-websockets",
7
+ "storage-operations",
8
+ "dynamodb",
9
+ "ddb",
10
+ "sau:ddb"
11
+ ],
5
12
  "repository": {
6
13
  "type": "git",
7
14
  "url": "https://github.com/webiny/webiny-js.git"
@@ -16,29 +23,33 @@
16
23
  },
17
24
  "license": "MIT",
18
25
  "dependencies": {
19
- "@webiny/api": "0.0.0-unstable.b6d7105cee",
20
- "@webiny/api-websockets": "0.0.0-unstable.b6d7105cee",
21
- "@webiny/aws-sdk": "0.0.0-unstable.b6d7105cee",
22
- "@webiny/error": "0.0.0-unstable.b6d7105cee",
23
- "@webiny/handler": "0.0.0-unstable.b6d7105cee",
24
- "@webiny/handler-aws": "0.0.0-unstable.b6d7105cee",
25
- "@webiny/plugins": "0.0.0-unstable.b6d7105cee",
26
- "@webiny/utils": "0.0.0-unstable.b6d7105cee",
26
+ "@webiny/api": "6.6.0-alpha.1",
27
+ "@webiny/api-websockets": "6.6.0-alpha.1",
28
+ "@webiny/aws-sdk": "6.6.0-alpha.1",
29
+ "@webiny/db-dynamodb": "6.6.0-alpha.1",
30
+ "@webiny/error": "6.6.0-alpha.1",
31
+ "@webiny/event-handler-aws": "6.6.0-alpha.1",
32
+ "@webiny/feature": "6.6.0-alpha.1",
33
+ "@webiny/handler": "6.6.0-alpha.1",
34
+ "@webiny/utils": "6.6.0-alpha.1",
27
35
  "type-fest": "5.8.0",
28
36
  "zod": "4.4.3"
29
37
  },
30
38
  "devDependencies": {
31
- "@webiny/api-core": "0.0.0-unstable.b6d7105cee",
32
- "@webiny/api-headless-cms": "0.0.0-unstable.b6d7105cee",
33
- "@webiny/build-tools": "0.0.0-unstable.b6d7105cee",
34
- "@webiny/handler-db": "0.0.0-unstable.b6d7105cee",
35
- "@webiny/handler-graphql": "0.0.0-unstable.b6d7105cee",
36
- "@webiny/project-utils": "0.0.0-unstable.b6d7105cee",
39
+ "@webiny/api-core": "6.6.0-alpha.1",
40
+ "@webiny/api-core-testing": "6.6.0-alpha.1",
41
+ "@webiny/api-graphql": "6.6.0-alpha.1",
42
+ "@webiny/api-headless-cms": "6.6.0-alpha.1",
43
+ "@webiny/build-tools": "6.6.0-alpha.1",
44
+ "@webiny/di": "1.1.0",
45
+ "@webiny/event-handler-core": "6.6.0-alpha.1",
46
+ "@webiny/wcp": "6.6.0-alpha.1",
47
+ "aws-sdk-client-mock": "4.1.0",
37
48
  "graphql": "16.14.2",
38
49
  "rimraf": "6.1.3",
39
50
  "type-fest": "5.8.0",
40
51
  "typescript": "7.0.2",
41
- "vitest": "4.1.10"
52
+ "vitest": "4.1.11"
42
53
  },
43
54
  "publishConfig": {
44
55
  "access": "public"
@@ -1,2 +0,0 @@
1
- import type { HandlerCallable, HandlerParams } from "./types.js";
2
- export declare const createHandler: (params: HandlerParams) => HandlerCallable;
@@ -1,105 +0,0 @@
1
- import { createHandler } from "@webiny/handler";
2
- import { registerDefaultPlugins } from "@webiny/handler-aws/plugins/index.js";
3
- import { execute } from "@webiny/handler-aws/execute.js";
4
- import { PluginsContainer } from "@webiny/plugins";
5
- import { WebsocketsResponse, WebsocketsRunner, WebsocketsTransport, createWebsocketsRoutePlugins } from "@webiny/api-websockets/exports/api.js";
6
- import { getEventValues } from "./headers.js";
7
- import { AwsWebsocketsEventValidator } from "../validator/AwsWebsocketsEventValidator.js";
8
- const url = "/webiny-websockets";
9
- const createPluginsContainer = (plugins)=>{
10
- if (plugins instanceof PluginsContainer) return plugins;
11
- return new PluginsContainer(plugins || []);
12
- };
13
- const handler_createHandler = (params)=>{
14
- const plugins = createPluginsContainer(params.plugins);
15
- plugins.register(...createWebsocketsRoutePlugins());
16
- const validator = new AwsWebsocketsEventValidator();
17
- return async (event)=>{
18
- const app = createHandler({
19
- ...params,
20
- plugins,
21
- options: {
22
- logger: true === params.debug,
23
- ...params.options || {}
24
- }
25
- });
26
- registerDefaultPlugins(app.webiny);
27
- await app.register(async (wsApp)=>{
28
- wsApp.setErrorHandler(async (error, _, reply)=>{
29
- app.__webiny_raw_result = {
30
- error: {
31
- message: error.message,
32
- code: error.code,
33
- data: error.data
34
- },
35
- statusCode: 200
36
- };
37
- return reply.send({});
38
- });
39
- wsApp.post(url, async (_, reply)=>{
40
- const { response } = params;
41
- const context = app.webiny;
42
- const responseObj = response || context.container.resolve(WebsocketsResponse);
43
- const runner = new WebsocketsRunner(context, responseObj);
44
- let validatedEvent;
45
- try {
46
- validatedEvent = await validator.validate(event);
47
- } catch (ex) {
48
- const errorResult = responseObj.error({
49
- message: "Validation failed.",
50
- error: {
51
- message: ex.message,
52
- code: ex.code,
53
- data: ex.data,
54
- stack: ex.stack
55
- }
56
- });
57
- const { connectionId, domainName, stage, eventType } = event.requestContext || {};
58
- if (connectionId && domainName && stage && "MESSAGE" === eventType) try {
59
- const transport = context.container.resolve(WebsocketsTransport);
60
- const endpoint = `https://${domainName}/${stage}`;
61
- await transport.send([
62
- {
63
- connectionId,
64
- endpoint
65
- }
66
- ], errorResult);
67
- } catch {}
68
- app.__webiny_raw_result = {
69
- statusCode: errorResult.statusCode,
70
- headers: {
71
- "sec-websocket-protocol": "webiny-ws-v1"
72
- }
73
- };
74
- return reply.send();
75
- }
76
- const result = await runner.run(validatedEvent);
77
- app.__webiny_raw_result = {
78
- statusCode: result.statusCode,
79
- headers: {
80
- "sec-websocket-protocol": "webiny-ws-v1"
81
- }
82
- };
83
- return reply.send();
84
- });
85
- });
86
- const { tenant, endpoint, token } = getEventValues(event);
87
- const headers = {
88
- Authorization: `Bearer ${token}`,
89
- ["x-tenant"]: tenant,
90
- ["x-webiny-cms-endpoint"]: endpoint,
91
- ...event.headers
92
- };
93
- return execute({
94
- app,
95
- url: url,
96
- payload: {
97
- ...event,
98
- headers
99
- }
100
- });
101
- };
102
- };
103
- export { handler_createHandler as createHandler };
104
-
105
- //# sourceMappingURL=handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler/handler.js","sources":["../../src/handler/handler.ts"],"sourcesContent":["import type WebinyError from \"@webiny/error\";\nimport { createHandler as createBaseHandler } from \"@webiny/handler\";\nimport { registerDefaultPlugins } from \"@webiny/handler-aws/plugins/index.js\";\nimport { execute } from \"@webiny/handler-aws/execute.js\";\nimport { PluginsContainer } from \"@webiny/plugins\";\nimport {\n createWebsocketsRoutePlugins,\n WebsocketsRunner,\n WebsocketsTransport,\n WebsocketsResponse\n} from \"@webiny/api-websockets/exports/api.js\";\nimport type { DbContext } from \"@webiny/handler-db/types.js\";\nimport type { ApiCoreContext } from \"@webiny/api-core/types/core.js\";\n\ntype Context = DbContext & ApiCoreContext;\nimport type { PluginCollection } from \"@webiny/plugins/types.js\";\nimport type { HandlerCallable, HandlerParams } from \"./types.js\";\nimport { getEventValues } from \"./headers.js\";\nimport { AwsWebsocketsEventValidator } from \"~/validator/AwsWebsocketsEventValidator.js\";\n\nconst url = \"/webiny-websockets\";\n\nconst createPluginsContainer = (\n plugins?: PluginsContainer | PluginCollection\n): PluginsContainer => {\n if (plugins instanceof PluginsContainer) {\n return plugins;\n }\n return new PluginsContainer(plugins || []);\n};\n\nexport const createHandler = (params: HandlerParams): HandlerCallable => {\n const plugins = createPluginsContainer(params.plugins);\n plugins.register(...createWebsocketsRoutePlugins());\n\n const validator = new AwsWebsocketsEventValidator();\n\n return async event => {\n const app = createBaseHandler({\n ...params,\n plugins,\n options: {\n logger: params.debug === true,\n ...(params.options || {})\n }\n });\n\n registerDefaultPlugins(app.webiny);\n\n await app.register(async wsApp => {\n wsApp.setErrorHandler<WebinyError>(async (error, _, reply) => {\n app.__webiny_raw_result = {\n error: {\n message: error.message,\n code: error.code,\n data: error.data\n },\n statusCode: 200\n };\n return reply.send({});\n });\n\n wsApp.post(url, async (_, reply) => {\n const { response } = params;\n const context = app.webiny as Context;\n\n const responseObj = response || context.container.resolve(WebsocketsResponse);\n const runner = new WebsocketsRunner(context, responseObj);\n\n let validatedEvent;\n try {\n validatedEvent = await validator.validate(event);\n } catch (ex) {\n const errorResult = responseObj.error({\n message: \"Validation failed.\",\n error: {\n message: ex.message,\n code: ex.code,\n data: ex.data,\n stack: ex.stack\n }\n });\n\n const { connectionId, domainName, stage, eventType } =\n event.requestContext || {};\n if (connectionId && domainName && stage && eventType === \"MESSAGE\") {\n try {\n const transport = context.container.resolve(WebsocketsTransport);\n const endpoint = `https://${domainName}/${stage}`;\n await transport.send([{ connectionId, endpoint }], errorResult);\n } catch {\n /* best effort. */\n }\n }\n\n app.__webiny_raw_result = {\n statusCode: errorResult.statusCode,\n headers: {\n \"sec-websocket-protocol\": \"webiny-ws-v1\"\n }\n };\n return reply.send();\n }\n\n const result = await runner.run(validatedEvent);\n\n app.__webiny_raw_result = {\n statusCode: result.statusCode,\n headers: {\n \"sec-websocket-protocol\": \"webiny-ws-v1\"\n }\n };\n\n return reply.send();\n });\n });\n\n const { tenant, endpoint, token } = getEventValues(event);\n\n const headers = {\n Authorization: `Bearer ${token}`,\n [\"x-tenant\"]: tenant,\n [\"x-webiny-cms-endpoint\"]: endpoint,\n ...event.headers\n };\n\n return execute({\n app,\n url,\n payload: {\n ...event,\n headers\n }\n });\n };\n};\n"],"names":["url","createPluginsContainer","plugins","PluginsContainer","createHandler","params","createWebsocketsRoutePlugins","validator","AwsWebsocketsEventValidator","event","app","createBaseHandler","registerDefaultPlugins","wsApp","error","_","reply","response","context","responseObj","WebsocketsResponse","runner","WebsocketsRunner","validatedEvent","ex","errorResult","connectionId","domainName","stage","eventType","transport","WebsocketsTransport","endpoint","result","tenant","token","getEventValues","headers","execute"],"mappings":";;;;;;;AAoBA,MAAMA,MAAM;AAEZ,MAAMC,yBAAyB,CAC3BC;IAEA,IAAIA,mBAAmBC,kBACnB,OAAOD;IAEX,OAAO,IAAIC,iBAAiBD,WAAW,EAAE;AAC7C;AAEO,MAAME,wBAAgB,CAACC;IAC1B,MAAMH,UAAUD,uBAAuBI,OAAO,OAAO;IACrDH,QAAQ,QAAQ,IAAII;IAEpB,MAAMC,YAAY,IAAIC;IAEtB,OAAO,OAAMC;QACT,MAAMC,MAAMC,cAAkB;YAC1B,GAAGN,MAAM;YACTH;YACA,SAAS;gBACL,QAAQG,AAAiB,SAAjBA,OAAO,KAAK;gBACpB,GAAIA,OAAO,OAAO,IAAI,CAAC,CAAC;YAC5B;QACJ;QAEAO,uBAAuBF,IAAI,MAAM;QAEjC,MAAMA,IAAI,QAAQ,CAAC,OAAMG;YACrBA,MAAM,eAAe,CAAc,OAAOC,OAAOC,GAAGC;gBAChDN,IAAI,mBAAmB,GAAG;oBACtB,OAAO;wBACH,SAASI,MAAM,OAAO;wBACtB,MAAMA,MAAM,IAAI;wBAChB,MAAMA,MAAM,IAAI;oBACpB;oBACA,YAAY;gBAChB;gBACA,OAAOE,MAAM,IAAI,CAAC,CAAC;YACvB;YAEAH,MAAM,IAAI,CAACb,KAAK,OAAOe,GAAGC;gBACtB,MAAM,EAAEC,QAAQ,EAAE,GAAGZ;gBACrB,MAAMa,UAAUR,IAAI,MAAM;gBAE1B,MAAMS,cAAcF,YAAYC,QAAQ,SAAS,CAAC,OAAO,CAACE;gBAC1D,MAAMC,SAAS,IAAIC,iBAAiBJ,SAASC;gBAE7C,IAAII;gBACJ,IAAI;oBACAA,iBAAiB,MAAMhB,UAAU,QAAQ,CAACE;gBAC9C,EAAE,OAAOe,IAAI;oBACT,MAAMC,cAAcN,YAAY,KAAK,CAAC;wBAClC,SAAS;wBACT,OAAO;4BACH,SAASK,GAAG,OAAO;4BACnB,MAAMA,GAAG,IAAI;4BACb,MAAMA,GAAG,IAAI;4BACb,OAAOA,GAAG,KAAK;wBACnB;oBACJ;oBAEA,MAAM,EAAEE,YAAY,EAAEC,UAAU,EAAEC,KAAK,EAAEC,SAAS,EAAE,GAChDpB,MAAM,cAAc,IAAI,CAAC;oBAC7B,IAAIiB,gBAAgBC,cAAcC,SAASC,AAAc,cAAdA,WACvC,IAAI;wBACA,MAAMC,YAAYZ,QAAQ,SAAS,CAAC,OAAO,CAACa;wBAC5C,MAAMC,WAAW,CAAC,QAAQ,EAAEL,WAAW,CAAC,EAAEC,OAAO;wBACjD,MAAME,UAAU,IAAI,CAAC;4BAAC;gCAAEJ;gCAAcM;4BAAS;yBAAE,EAAEP;oBACvD,EAAE,OAAM,CAER;oBAGJf,IAAI,mBAAmB,GAAG;wBACtB,YAAYe,YAAY,UAAU;wBAClC,SAAS;4BACL,0BAA0B;wBAC9B;oBACJ;oBACA,OAAOT,MAAM,IAAI;gBACrB;gBAEA,MAAMiB,SAAS,MAAMZ,OAAO,GAAG,CAACE;gBAEhCb,IAAI,mBAAmB,GAAG;oBACtB,YAAYuB,OAAO,UAAU;oBAC7B,SAAS;wBACL,0BAA0B;oBAC9B;gBACJ;gBAEA,OAAOjB,MAAM,IAAI;YACrB;QACJ;QAEA,MAAM,EAAEkB,MAAM,EAAEF,QAAQ,EAAEG,KAAK,EAAE,GAAGC,eAAe3B;QAEnD,MAAM4B,UAAU;YACZ,eAAe,CAAC,OAAO,EAAEF,OAAO;YAChC,CAAC,WAAW,EAAED;YACd,CAAC,wBAAwB,EAAEF;YAC3B,GAAGvB,MAAM,OAAO;QACpB;QAEA,OAAO6B,QAAQ;YACX5B;YACAV,KAAAA;YACA,SAAS;gBACL,GAAGS,KAAK;gBACR4B;YACJ;QACJ;IACJ;AACJ"}
@@ -1,6 +0,0 @@
1
- import type { IAwsWebsocketsIncomingEvent } from "../handler/types.js";
2
- export declare const getEventValues: (event: IAwsWebsocketsIncomingEvent) => {
3
- tenant: string;
4
- token: string | null;
5
- endpoint: string;
6
- };
@@ -1,27 +0,0 @@
1
- const getEventBody = (event)=>{
2
- if (!event.body) return {};
3
- if ("object" == typeof event.body) return event.body;
4
- if ("string" == typeof event.body) try {
5
- return JSON.parse(event.body);
6
- } catch (ex) {
7
- console.log(ex.message);
8
- return {};
9
- }
10
- console.log("Unexpected event.body type:", typeof event.body);
11
- return {};
12
- };
13
- const getToken = (body, event)=>body?.token || event.queryStringParameters?.token || null;
14
- const getTenant = (body, event)=>body?.tenant || event.queryStringParameters?.tenant || "root";
15
- const getEventValues = (event)=>{
16
- const body = getEventBody(event);
17
- const token = getToken(body, event);
18
- const tenant = getTenant(body, event);
19
- return {
20
- tenant,
21
- token,
22
- endpoint: "manage"
23
- };
24
- };
25
- export { getEventValues };
26
-
27
- //# sourceMappingURL=headers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler/headers.js","sources":["../../src/handler/headers.ts"],"sourcesContent":["import type { WebsocketsRunner } from \"@webiny/api-websockets/exports/api.js\";\nimport type { IAwsWebsocketsIncomingEvent } from \"~/handler/types.js\";\n\nconst getEventBody = (event: IAwsWebsocketsIncomingEvent): WebsocketsRunner.EventData => {\n if (!event.body) {\n return {};\n } else if (typeof event.body === \"object\") {\n return event.body;\n } else if (typeof event.body === \"string\") {\n try {\n return JSON.parse(event.body);\n } catch (ex) {\n console.log(ex.message);\n return {};\n }\n }\n console.log(\"Unexpected event.body type:\", typeof event.body);\n return {};\n};\n\nconst getToken = (\n body: WebsocketsRunner.EventData,\n event: IAwsWebsocketsIncomingEvent\n): string | null => {\n return body?.token || event.queryStringParameters?.token || null;\n};\n\nconst getTenant = (\n body: WebsocketsRunner.EventData,\n event: IAwsWebsocketsIncomingEvent\n): string => {\n return body?.tenant || event.queryStringParameters?.tenant || \"root\";\n};\n\nexport const getEventValues = (event: IAwsWebsocketsIncomingEvent) => {\n const body = getEventBody(event);\n\n const token = getToken(body, event);\n const tenant = getTenant(body, event);\n return {\n tenant,\n token,\n endpoint: \"manage\"\n };\n};\n"],"names":["getEventBody","event","JSON","ex","console","getToken","body","getTenant","getEventValues","token","tenant"],"mappings":"AAGA,MAAMA,eAAe,CAACC;IAClB,IAAI,CAACA,MAAM,IAAI,EACX,OAAO,CAAC;IACL,IAAI,AAAsB,YAAtB,OAAOA,MAAM,IAAI,EACxB,OAAOA,MAAM,IAAI;IACd,IAAI,AAAsB,YAAtB,OAAOA,MAAM,IAAI,EACxB,IAAI;QACA,OAAOC,KAAK,KAAK,CAACD,MAAM,IAAI;IAChC,EAAE,OAAOE,IAAI;QACTC,QAAQ,GAAG,CAACD,GAAG,OAAO;QACtB,OAAO,CAAC;IACZ;IAEJC,QAAQ,GAAG,CAAC,+BAA+B,OAAOH,MAAM,IAAI;IAC5D,OAAO,CAAC;AACZ;AAEA,MAAMI,WAAW,CACbC,MACAL,QAEOK,MAAM,SAASL,MAAM,qBAAqB,EAAE,SAAS;AAGhE,MAAMM,YAAY,CACdD,MACAL,QAEOK,MAAM,UAAUL,MAAM,qBAAqB,EAAE,UAAU;AAG3D,MAAMO,iBAAiB,CAACP;IAC3B,MAAMK,OAAON,aAAaC;IAE1B,MAAMQ,QAAQJ,SAASC,MAAML;IAC7B,MAAMS,SAASH,UAAUD,MAAML;IAC/B,OAAO;QACHS;QACAD;QACA,UAAU;IACd;AACJ"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,16 +0,0 @@
1
- import { registry } from "@webiny/handler-aws/registry.js";
2
- import { createSourceHandler } from "@webiny/handler-aws";
3
- const handler = createSourceHandler({
4
- name: "handler-webiny-websockets",
5
- canUse: (event)=>{
6
- const { routeKey, connectionId, eventType } = event.requestContext || {};
7
- return !!routeKey && !!connectionId && !!eventType;
8
- },
9
- handle: async ({ params, event, context })=>{
10
- const { createHandler } = await import("./handler.js");
11
- return createHandler(params)(event, context);
12
- }
13
- });
14
- registry.register(handler);
15
-
16
- //# sourceMappingURL=register.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler/register.js","sources":["../../src/handler/register.ts"],"sourcesContent":["import { registry } from \"@webiny/handler-aws/registry.js\";\nimport { createSourceHandler } from \"@webiny/handler-aws\";\nimport type { HandlerParams, IAwsWebsocketsIncomingEvent } from \"./types.js\";\n\nconst handler = createSourceHandler<IAwsWebsocketsIncomingEvent, HandlerParams>({\n name: \"handler-webiny-websockets\",\n canUse: event => {\n const { routeKey, connectionId, eventType } = event.requestContext || {};\n return !!routeKey && !!connectionId && !!eventType;\n },\n handle: async ({ params, event, context }) => {\n const { createHandler } = await import(\n /* webpackChunkName: \"SocketsHandler\" */\n \"./handler.js\"\n );\n return createHandler(params)(event, context);\n }\n});\n\nregistry.register(handler);\n"],"names":["handler","createSourceHandler","event","routeKey","connectionId","eventType","params","context","createHandler","registry"],"mappings":";;AAIA,MAAMA,UAAUC,oBAAgE;IAC5E,MAAM;IACN,QAAQC,CAAAA;QACJ,MAAM,EAAEC,QAAQ,EAAEC,YAAY,EAAEC,SAAS,EAAE,GAAGH,MAAM,cAAc,IAAI,CAAC;QACvE,OAAO,CAAC,CAACC,YAAY,CAAC,CAACC,gBAAgB,CAAC,CAACC;IAC7C;IACA,QAAQ,OAAO,EAAEC,MAAM,EAAEJ,KAAK,EAAEK,OAAO,EAAE;QACrC,MAAM,EAAEC,aAAa,EAAE,GAAG,MAAM,MAAM,CAAN;QAIhC,OAAOA,cAAcF,QAAQJ,OAAOK;IACxC;AACJ;AAEAE,SAAS,QAAQ,CAACT"}