@zintrust/socket 0.4.61 → 0.4.63

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.
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@zintrust/socket",
3
- "version": "0.4.61",
4
- "buildDate": "2026-04-05T07:58:39.948Z",
3
+ "version": "0.4.63",
4
+ "buildDate": "2026-04-05T13:13:05.363Z",
5
5
  "buildEnvironment": {
6
6
  "node": "v22.22.1",
7
7
  "platform": "darwin",
8
8
  "arch": "arm64"
9
9
  },
10
10
  "git": {
11
- "commit": "b4dbe529",
11
+ "commit": "533afc24",
12
12
  "branch": "release"
13
13
  },
14
14
  "package": {
@@ -26,12 +26,12 @@
26
26
  "sha256": "a55e096a80190637fe7d56c36e53865451f623c88ceb5ccb7b9124e4a14335bb"
27
27
  },
28
28
  "index.d.ts": {
29
- "size": 932,
30
- "sha256": "6432952783fd7eacfc46813fcbd6e96672ff94c73fb0bad8e2f20fc278c64377"
29
+ "size": 1393,
30
+ "sha256": "c3b8e8d96234c34a42f08dd14fadab504cb6f2bd76c15bce5fb23e5acde4941f"
31
31
  },
32
32
  "index.js": {
33
- "size": 35299,
34
- "sha256": "112c1becf555e48ea7f0ca52b4e0588c764777cefc90c33dd8c8fe52715b54ce"
33
+ "size": 38284,
34
+ "sha256": "cf683327a9a0d2ba1b349cc059c2113c76e36e130b56e613932fdccd5c4f435f"
35
35
  },
36
36
  "register.d.ts": {
37
37
  "size": 16,
package/dist/index.d.ts CHANGED
@@ -1,4 +1,19 @@
1
- import { type IRouter, type SocketRouteRegistrar } from '@zintrust/core';
1
+ import { type IRequest, type IRouter, type SocketRouteRegistrar } from '@zintrust/core';
2
+ type ServerSideSocketPublishInput = Readonly<{
3
+ channels: readonly string[];
4
+ event: string;
5
+ data: unknown;
6
+ socketId?: string;
7
+ request?: IRequest;
8
+ user?: unknown;
9
+ }>;
10
+ declare const publishSocketEventFromServer: (input: ServerSideSocketPublishInput) => Promise<{
11
+ ok: true;
12
+ transport: "node" | "cloudflare";
13
+ channels: readonly string[];
14
+ event: string;
15
+ deliveries: number;
16
+ }>;
2
17
  declare const socketRuntime: any;
3
18
  declare const registerSocketRoutes: (router: IRouter) => void;
4
19
  declare const socketRouteRegistrar: SocketRouteRegistrar;
@@ -16,5 +31,5 @@ export declare class ZintrustSocketHub {
16
31
  private handlePublishRequest;
17
32
  }
18
33
  export declare const publishSocketEvent: (channels: string[], event: string, data: unknown, excludeSocketId?: string) => number;
19
- export { registerSocketRoutes, socketRouteRegistrar, socketRuntime };
34
+ export { publishSocketEventFromServer, registerSocketRoutes, socketRouteRegistrar, socketRuntime };
20
35
  export default SocketPackage;
package/dist/index.js CHANGED
@@ -1,15 +1,4 @@
1
- /**
2
- * @zintrust/socket v0.4.60
3
- *
4
- * Unified socket runtime for ZinTrust.
5
- *
6
- * Build Information:
7
- * Built: 2026-04-05T07:58:23.814Z
8
- * Node: >=20.0.0
9
- * License: MIT
10
- *
11
- */
12
- import { Cloudflare, broadcastConfig, ErrorFactory, isArray, isNonEmptyString, Logger, middlewareConfig, Router, SocketFeature, } from '@zintrust/core';
1
+ import { broadcastConfig, Cloudflare, ErrorFactory, isArray, isNonEmptyString, Logger, middlewareConfig, Router, SocketFeature, } from '@zintrust/core';
13
2
  const encoder = new TextEncoder();
14
3
  const websocketGuid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
15
4
  const socketHubBindingName = 'ZT_SOCKET_HUB';
@@ -57,7 +46,11 @@ const normalizeSocketPath = (value) => {
57
46
  if (trimmed === '' || trimmed === '/')
58
47
  return '/app';
59
48
  const normalized = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
60
- return normalized.length > 1 ? normalized.replace(/\/+$/, '') : normalized;
49
+ let end = normalized.length;
50
+ while (end > 1 && normalized[end - 1] === '/') {
51
+ end -= 1;
52
+ }
53
+ return end === normalized.length ? normalized : normalized.slice(0, end);
61
54
  };
62
55
  const pickFirstNonEmpty = (...values) => {
63
56
  for (const value of values) {
@@ -669,6 +662,76 @@ const normalizePublishDecisionPayload = (payload, decision) => {
669
662
  })(),
670
663
  };
671
664
  };
665
+ const createServerSidePublishRequest = (input) => {
666
+ return {
667
+ getBody: () => null,
668
+ getHeader: () => undefined,
669
+ getParam: () => undefined,
670
+ user: input.user ?? null,
671
+ };
672
+ };
673
+ const getResponseDeliveries = (payload) => {
674
+ if (typeof payload !== 'object' || payload === null) {
675
+ return 0;
676
+ }
677
+ const deliveries = payload.deliveries;
678
+ return typeof deliveries === 'number' && Number.isFinite(deliveries) ? deliveries : 0;
679
+ };
680
+ const publishSocketEventFromServer = async (input) => {
681
+ const settings = getSocketRuntimeSettings(Cloudflare.getWorkersEnv());
682
+ if (!settings.enabled || settings.appKey.trim() === '') {
683
+ throw ErrorFactory.createConfigError('Socket runtime is not enabled.');
684
+ }
685
+ const request = input.request ?? createServerSidePublishRequest(input);
686
+ const payload = {
687
+ channels: input.channels.map((channel) => channel.trim()),
688
+ event: input.event.trim(),
689
+ data: input.data ?? {},
690
+ ...(isNonEmptyString(input.socketId) ? { socket_id: input.socketId.trim() } : {}),
691
+ };
692
+ const publishPolicy = resolveSocketPublishPolicy();
693
+ const decision = await publishPolicy.authorize(request, {
694
+ appId: settings.appId,
695
+ channels: payload.channels,
696
+ event: payload.event,
697
+ data: payload.data,
698
+ socketId: payload.socket_id,
699
+ user: input.user ?? request.user ?? null,
700
+ });
701
+ if (decision.allowed !== true) {
702
+ throw ErrorFactory.createForbiddenError(decision.message ?? 'Forbidden', {
703
+ statusCode: decision.statusCode ?? 403,
704
+ });
705
+ }
706
+ const allowedPayload = normalizePublishDecisionPayload(payload, decision);
707
+ if (allowedPayload === null) {
708
+ throw ErrorFactory.createValidationError('Socket publish policy must return a non-empty event and channels.');
709
+ }
710
+ if (shouldUseCloudflareHub(settings)) {
711
+ const response = await forwardPublishToHub(settings, allowedPayload, Cloudflare.getWorkersEnv());
712
+ const responseBody = await parseJsonResponse(response);
713
+ if (!response.ok) {
714
+ throw ErrorFactory.createTryCatchError(`Socket publish request failed (${response.status})`, {
715
+ status: response.status,
716
+ body: responseBody,
717
+ });
718
+ }
719
+ return {
720
+ ok: true,
721
+ transport: 'cloudflare',
722
+ channels: allowedPayload.channels,
723
+ event: allowedPayload.event,
724
+ deliveries: getResponseDeliveries(responseBody),
725
+ };
726
+ }
727
+ return {
728
+ ok: true,
729
+ transport: 'node',
730
+ channels: allowedPayload.channels,
731
+ event: allowedPayload.event,
732
+ deliveries: publishToChannels(getNodeSocketState(), allowedPayload.channels, allowedPayload.event, allowedPayload.data, allowedPayload.socket_id),
733
+ };
734
+ };
672
735
  const forwardPublishToHub = async (settings, payload, envSource) => {
673
736
  const stub = getSocketHubStub(settings, envSource);
674
737
  if (stub === null) {
@@ -935,5 +998,5 @@ export class ZintrustSocketHub {
935
998
  export const publishSocketEvent = (channels, event, data, excludeSocketId) => {
936
999
  return publishToChannels(getNodeSocketState(), channels, event, data, excludeSocketId);
937
1000
  };
938
- export { registerSocketRoutes, socketRouteRegistrar, socketRuntime };
1001
+ export { publishSocketEventFromServer, registerSocketRoutes, socketRouteRegistrar, socketRuntime };
939
1002
  export default SocketPackage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/socket",
3
- "version": "0.4.61",
3
+ "version": "0.4.63",
4
4
  "description": "Unified socket runtime for ZinTrust.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  "node": ">=20.0.0"
24
24
  },
25
25
  "peerDependencies": {
26
- "@zintrust/core": "^0.4.61"
26
+ "@zintrust/core": "^0.4.63"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
@@ -34,5 +34,8 @@
34
34
  "websocket",
35
35
  "broadcast"
36
36
  ],
37
- "scripts": {}
38
- }
37
+ "scripts": {
38
+ "build": "tsc -p tsconfig.json",
39
+ "prepublishOnly": "npm run build"
40
+ }
41
+ }