@dev-anywhere/relay 0.4.79 → 0.4.81

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.
@@ -617,6 +617,21 @@ var relayControlDefinitions = [
617
617
  url: z8.string().optional(),
618
618
  expiresAt: z8.number().int().nonnegative().optional()
619
619
  }),
620
+ control("remote_file_metadata_request", {
621
+ ...RequiredRequestIdShape,
622
+ sessionId: IdSchema,
623
+ path: z8.string().min(1)
624
+ }),
625
+ control("remote_file_metadata_response", {
626
+ ...RequiredRequestIdShape,
627
+ ...RequestErrorShape,
628
+ sessionId: IdSchema,
629
+ path: z8.string().optional(),
630
+ success: z8.boolean(),
631
+ mimeType: z8.string().optional(),
632
+ size: z8.number().int().nonnegative().optional(),
633
+ fileName: z8.string().optional()
634
+ }),
620
635
  control("remote_file_stream_request", {
621
636
  streamId: IdSchema,
622
637
  sessionId: IdSchema,
@@ -1768,6 +1783,10 @@ function handleProxyConnection(ws, registry, logger, chaos, remoteFileBridge) {
1768
1783
  remoteFileBridge?.handleProxyControl(proxyWs.proxyId, result.message);
1769
1784
  return;
1770
1785
  }
1786
+ if (proxyWs.proxyId && result.message.type === "remote_file_metadata_response") {
1787
+ remoteFileBridge?.handleProxyControl(proxyWs.proxyId, result.message);
1788
+ return;
1789
+ }
1771
1790
  if (proxyWs.proxyId && result.message.type === "remote_file_stream_complete") {
1772
1791
  remoteFileBridge?.handleProxyControl(proxyWs.proxyId, result.message);
1773
1792
  return;
@@ -2773,24 +2792,44 @@ function handleClientConnection(ws, registry, logger, chaos, voiceConfigStore, v
2773
2792
  );
2774
2793
  return;
2775
2794
  }
2776
- const { url, expiresAt } = remoteFileBridge.createUrl({
2795
+ void remoteFileBridge.createUrl({
2777
2796
  clientId: clientWs.clientId,
2778
2797
  proxyId: targetProxyId,
2779
2798
  sessionId: msg.sessionId,
2780
2799
  path: msg.path,
2781
2800
  disposition: msg.disposition
2801
+ }).then((result2) => {
2802
+ if (clientWs.readyState !== WebSocket7.OPEN) return;
2803
+ if (!result2.success) {
2804
+ sendRemoteFileUrlFailure(
2805
+ clientWs,
2806
+ msg.requestId,
2807
+ msg.sessionId,
2808
+ result2.error,
2809
+ result2.errorCode
2810
+ );
2811
+ return;
2812
+ }
2813
+ clientWs.send(
2814
+ serializeControl({
2815
+ type: "remote_file_url_response",
2816
+ requestId: msg.requestId,
2817
+ sessionId: msg.sessionId,
2818
+ path: result2.path,
2819
+ success: true,
2820
+ url: result2.url,
2821
+ expiresAt: result2.expiresAt
2822
+ })
2823
+ );
2824
+ }).catch((err) => {
2825
+ if (clientWs.readyState !== WebSocket7.OPEN) return;
2826
+ sendRemoteFileUrlFailure(
2827
+ clientWs,
2828
+ msg.requestId,
2829
+ msg.sessionId,
2830
+ err instanceof Error ? err.message : String(err)
2831
+ );
2782
2832
  });
2783
- clientWs.send(
2784
- serializeControl({
2785
- type: "remote_file_url_response",
2786
- requestId: msg.requestId,
2787
- sessionId: msg.sessionId,
2788
- path: msg.path,
2789
- success: true,
2790
- url,
2791
- expiresAt
2792
- })
2793
- );
2794
2833
  return;
2795
2834
  }
2796
2835
  if (msg.type === "remote_file_upload_url_request") {
@@ -3578,8 +3617,10 @@ function encodeContentDisposition(disposition, fileName) {
3578
3617
  function statusForErrorCode(errorCode) {
3579
3618
  switch (errorCode) {
3580
3619
  case ControlErrorCode.SESSION_NOT_FOUND:
3620
+ case ControlErrorCode.PATH_NOT_FOUND:
3581
3621
  return 404;
3582
3622
  case ControlErrorCode.INVALID_PATH:
3623
+ case ControlErrorCode.PATH_NOT_DIRECTORY:
3583
3624
  return 400;
3584
3625
  case ControlErrorCode.PATH_ACCESS_DENIED:
3585
3626
  return 403;
@@ -3594,22 +3635,54 @@ var RemoteFileBridge = class {
3594
3635
  deps;
3595
3636
  tokens = /* @__PURE__ */ new Map();
3596
3637
  uploadTokens = /* @__PURE__ */ new Map();
3638
+ pendingUrlMetadata = /* @__PURE__ */ new Map();
3597
3639
  pendingStreams = /* @__PURE__ */ new Map();
3598
3640
  pendingUploads = /* @__PURE__ */ new Map();
3599
3641
  createUrl(input) {
3600
3642
  this.cleanupExpiredTokens();
3601
- const token = nanoid3(32);
3602
- const expiresAt = Date.now() + REMOTE_FILE_TOKEN_TTL_MS;
3603
- this.tokens.set(token, {
3604
- token,
3605
- clientId: input.clientId,
3606
- proxyId: input.proxyId,
3607
- sessionId: input.sessionId,
3608
- path: input.path,
3609
- disposition: input.disposition,
3610
- expiresAt
3643
+ const proxyWs = this.deps.registry.getProxy(input.proxyId);
3644
+ if (!proxyWs || proxyWs.readyState !== WebSocket11.OPEN) {
3645
+ return Promise.resolve({
3646
+ success: false,
3647
+ path: input.path,
3648
+ error: "\u5F53\u524D\u672A\u8FDE\u63A5\u5F00\u53D1\u673A",
3649
+ errorCode: ControlErrorCode.PROXY_OFFLINE
3650
+ });
3651
+ }
3652
+ const requestId = nanoid3(21);
3653
+ return new Promise((resolve2) => {
3654
+ const timer = setTimeout(() => {
3655
+ this.pendingUrlMetadata.delete(requestId);
3656
+ resolve2({
3657
+ success: false,
3658
+ path: input.path,
3659
+ error: "\u8BFB\u53D6\u6587\u4EF6\u5143\u6570\u636E\u8D85\u65F6",
3660
+ errorCode: ControlErrorCode.UNKNOWN
3661
+ });
3662
+ }, REMOTE_FILE_METADATA_TIMEOUT_MS);
3663
+ this.pendingUrlMetadata.set(requestId, {
3664
+ requestId,
3665
+ clientId: input.clientId,
3666
+ proxyId: input.proxyId,
3667
+ sessionId: input.sessionId,
3668
+ path: input.path,
3669
+ disposition: input.disposition,
3670
+ timer,
3671
+ resolve: resolve2
3672
+ });
3673
+ proxyWs.send(
3674
+ serializeControl({
3675
+ type: "remote_file_metadata_request",
3676
+ requestId,
3677
+ sessionId: input.sessionId,
3678
+ path: input.path
3679
+ })
3680
+ );
3681
+ this.deps.logger.info(
3682
+ { requestId, proxyId: input.proxyId, sessionId: input.sessionId, path: input.path },
3683
+ "Remote file URL metadata requested"
3684
+ );
3611
3685
  });
3612
- return { url: `/api/remote-files/${token}`, expiresAt };
3613
3686
  }
3614
3687
  createUploadUrl(input) {
3615
3688
  this.cleanupExpiredTokens();
@@ -3748,6 +3821,9 @@ var RemoteFileBridge = class {
3748
3821
  if (msg.type === "remote_file_upload_stream_response") {
3749
3822
  return this.handleUploadResponse(proxyId, msg);
3750
3823
  }
3824
+ if (msg.type === "remote_file_metadata_response") {
3825
+ return this.handleUrlMetadataResponse(proxyId, msg);
3826
+ }
3751
3827
  const pending = this.pendingStreams.get(msg.streamId);
3752
3828
  if (!pending) return true;
3753
3829
  if (pending.token.proxyId !== proxyId) {
@@ -3764,6 +3840,50 @@ var RemoteFileBridge = class {
3764
3840
  this.handleStreamComplete(pending, msg);
3765
3841
  return true;
3766
3842
  }
3843
+ issueUrlToken(input) {
3844
+ const token = nanoid3(32);
3845
+ const expiresAt = Date.now() + REMOTE_FILE_TOKEN_TTL_MS;
3846
+ this.tokens.set(token, {
3847
+ token,
3848
+ clientId: input.clientId,
3849
+ proxyId: input.proxyId,
3850
+ sessionId: input.sessionId,
3851
+ path: input.path,
3852
+ disposition: input.disposition,
3853
+ expiresAt
3854
+ });
3855
+ return { url: `/api/remote-files/${token}`, expiresAt };
3856
+ }
3857
+ handleUrlMetadataResponse(proxyId, msg) {
3858
+ const pending = this.pendingUrlMetadata.get(msg.requestId);
3859
+ if (!pending) return true;
3860
+ if (pending.proxyId !== proxyId) {
3861
+ this.deps.logger.warn(
3862
+ { requestId: msg.requestId, expectedProxyId: pending.proxyId, proxyId },
3863
+ "Remote file metadata ignored: proxy mismatch"
3864
+ );
3865
+ return true;
3866
+ }
3867
+ this.pendingUrlMetadata.delete(msg.requestId);
3868
+ clearTimeout(pending.timer);
3869
+ if (!msg.success) {
3870
+ pending.resolve({
3871
+ success: false,
3872
+ path: pending.path,
3873
+ error: msg.error ?? "\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25",
3874
+ ...msg.errorCode ? { errorCode: msg.errorCode } : {}
3875
+ });
3876
+ return true;
3877
+ }
3878
+ const { url, expiresAt } = this.issueUrlToken(pending);
3879
+ pending.resolve({
3880
+ success: true,
3881
+ path: pending.path,
3882
+ url,
3883
+ expiresAt
3884
+ });
3885
+ return true;
3886
+ }
3767
3887
  handleProxyBinary(proxyId, data) {
3768
3888
  const decoded = decodeFileStreamFrame(data);
3769
3889
  if (!decoded) return false;
@@ -4153,4 +4273,4 @@ export {
4153
4273
  parseRelayChaosFromEnv,
4154
4274
  createRelayServer
4155
4275
  };
4156
- //# sourceMappingURL=chunk-L2KEGMDB.js.map
4276
+ //# sourceMappingURL=chunk-XJZ3HOPH.js.map