@openclaw/zoom-meetings 2026.8.1-beta.2 → 2026.9.1-beta.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.
Files changed (127) hide show
  1. package/dist/index.js +40 -225
  2. package/node_modules/typebox/build/format/date.d.mts +1 -1
  3. package/node_modules/typebox/build/format/date.mjs +1 -1
  4. package/node_modules/typebox/build/format/date_time.d.mts +2 -2
  5. package/node_modules/typebox/build/format/date_time.mjs +3 -3
  6. package/node_modules/typebox/build/format/email.d.mts +1 -1
  7. package/node_modules/typebox/build/format/email.mjs +2 -2
  8. package/node_modules/typebox/build/format/hostname.mjs +2 -10
  9. package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
  10. package/node_modules/typebox/build/format/idn_email.mjs +3 -3
  11. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
  12. package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
  13. package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
  14. package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
  15. package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
  16. package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
  17. package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
  18. package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
  19. package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
  20. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
  21. package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
  22. package/node_modules/typebox/build/format/idna/index.mjs +2 -0
  23. package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
  24. package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
  25. package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
  26. package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
  27. package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
  28. package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
  29. package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
  30. package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
  31. package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
  32. package/node_modules/typebox/build/format/ipv4.mjs +2 -32
  33. package/node_modules/typebox/build/format/ipv6.mjs +2 -61
  34. package/node_modules/typebox/build/format/iri.d.mts +2 -2
  35. package/node_modules/typebox/build/format/iri.mjs +26 -8
  36. package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
  37. package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
  38. package/node_modules/typebox/build/format/regex.d.mts +1 -2
  39. package/node_modules/typebox/build/format/regex.mjs +2 -6
  40. package/node_modules/typebox/build/format/time.d.mts +2 -2
  41. package/node_modules/typebox/build/format/time.mjs +19 -14
  42. package/node_modules/typebox/build/format/uri.d.mts +1 -1
  43. package/node_modules/typebox/build/format/uri.mjs +3 -130
  44. package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
  45. package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
  46. package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
  47. package/node_modules/typebox/build/format/uri_template.mjs +4 -5
  48. package/node_modules/typebox/build/format/url.d.mts +3 -3
  49. package/node_modules/typebox/build/format/url.mjs +4 -5
  50. package/node_modules/typebox/build/guard/emit.d.mts +3 -1
  51. package/node_modules/typebox/build/guard/emit.mjs +12 -5
  52. package/node_modules/typebox/build/guard/guard.d.mts +8 -2
  53. package/node_modules/typebox/build/guard/guard.mjs +25 -4
  54. package/node_modules/typebox/build/guard/string.d.mts +2 -2
  55. package/node_modules/typebox/build/guard/string.mjs +7 -7
  56. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
  57. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
  58. package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
  59. package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
  60. package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
  61. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
  62. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
  63. package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
  64. package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
  65. package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
  66. package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
  67. package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
  68. package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
  69. package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
  70. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
  71. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
  72. package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
  73. package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
  74. package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
  75. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
  76. package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
  77. package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
  78. package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
  79. package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
  80. package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
  81. package/node_modules/typebox/build/schema/types/index.mjs +0 -2
  82. package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
  83. package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
  84. package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
  85. package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
  86. package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
  87. package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
  88. package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
  89. package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
  90. package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
  91. package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
  92. package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
  93. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
  94. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
  95. package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
  96. package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
  97. package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
  98. package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
  99. package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
  100. package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
  101. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
  102. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
  103. package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
  104. package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
  105. package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
  106. package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
  107. package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
  108. package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
  109. package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
  110. package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
  111. package/node_modules/typebox/build/type/script/parser.mjs +27 -23
  112. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
  113. package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
  114. package/node_modules/typebox/package.json +27 -27
  115. package/node_modules/typebox/readme.md +79 -82
  116. package/openclaw.plugin.json +7 -0
  117. package/package.json +5 -5
  118. package/node_modules/typebox/build/format/_idna.d.mts +0 -2
  119. package/node_modules/typebox/build/format/_idna.mjs +0 -246
  120. package/node_modules/typebox/build/format/_puny.d.mts +0 -1
  121. package/node_modules/typebox/build/format/_puny.mjs +0 -77
  122. package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
  123. package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
  124. package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
  125. package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
  126. package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
  127. package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { n as zoomMeetingsInvalidRequest, r as zoomMeetingsConfig, t as ZoomMeet
2
2
  import { MeetingPlatformAdapter } from "openclaw/plugin-sdk/meeting-runtime";
3
3
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
4
4
  import { Type } from "typebox";
5
+ import { createMeetingLeaveSource, createMeetingTranscriptSource } from "openclaw/plugin-sdk/meeting-page-script-runtime";
5
6
  //#region extensions/zoom-meetings/src/transports/zoom-meetings-selectors.ts
6
7
  const ZOOM_MEETING_SELECTORS = {
7
8
  continueInBrowser: [],
@@ -622,7 +623,6 @@ function isRecoverableZoomMeetingTab(tab, url) {
622
623
  }
623
624
  //#endregion
624
625
  //#region extensions/zoom-meetings/src/transports/zoom-meetings-page-scripts.ts
625
- const ZOOM_MEETING_TRANSCRIPT_MAX_LINES = 500;
626
626
  function pageIdentityFunctionSource() {
627
627
  return `const meetingIdentity = (rawUrl) => {
628
628
  try {
@@ -680,168 +680,23 @@ function zoomMeetingStatusScript(params) {
680
680
  }) + zoomMeetingStatusCallSource();
681
681
  }
682
682
  function zoomMeetingTranscriptScript(meetingUrl, meetingSessionId, finalize) {
683
- const expectedIdentity = normalizeZoomMeetingUrlForReuse(meetingUrl);
684
- return `() => {
685
- ${pageIdentityFunctionSource()}
686
- const expectedIdentity = ${JSON.stringify(expectedIdentity)};
687
- const expectedSessionId = ${JSON.stringify(meetingSessionId)};
688
- const currentIdentity = meetingIdentity(location.href);
689
- const state = window.__openclawZoomMeeting;
690
- const activeCaptions = window.__openclawZoomCaptions;
691
- const archivedCaptions = window.__openclawZoomCaptionArchive?.[expectedSessionId];
692
- const captions = activeCaptions &&
693
- (!activeCaptions.sessionId || activeCaptions.sessionId === expectedSessionId)
694
- ? activeCaptions
695
- : archivedCaptions;
696
- // A same-session finalized buffer belongs to the departed call even if Zoom
697
- // immediately navigated this tab into another meeting before transcript pickup.
698
- const useFinalizedCaptions = Boolean(
699
- captions?.finalized === true &&
700
- captions?.identity === expectedIdentity &&
701
- (!captions?.sessionId || captions.sessionId === expectedSessionId)
702
- );
703
- const effectiveIdentity = useFinalizedCaptions
704
- ? captions.identity
705
- : currentIdentity || state?.identity || captions?.identity;
706
- if (!expectedIdentity || effectiveIdentity !== expectedIdentity) {
707
- return JSON.stringify({ urlMatched: false, droppedLines: 0, lines: [] });
708
- }
709
- if (!useFinalizedCaptions && state?.sessionId && state.sessionId !== expectedSessionId) {
710
- return JSON.stringify({ urlMatched: true, sessionMatched: false, droppedLines: 0, lines: [] });
711
- }
712
- if (captions?.sessionId && captions.sessionId !== expectedSessionId) {
713
- return JSON.stringify({ urlMatched: true, sessionMatched: false, droppedLines: 0, lines: [] });
714
- }
715
- if (${JSON.stringify(finalize)} && Array.isArray(captions?.visible) && captions.visible.length > 0) {
716
- if (captions.settleTimer !== undefined) clearTimeout(captions.settleTimer);
717
- captions.settleTimer = undefined;
718
- captions.lines = Array.isArray(captions.lines) ? captions.lines : [];
719
- captions.lines.push(...captions.visible.map((entry) => ({
720
- at: entry.at,
721
- speaker: entry.speaker,
722
- text: entry.text,
723
- })));
724
- captions.visible = [];
725
- const excess = captions.lines.length - ${ZOOM_MEETING_TRANSCRIPT_MAX_LINES};
726
- if (excess > 0) {
727
- captions.lines.splice(0, excess);
728
- captions.droppedLines = (captions.droppedLines || 0) + excess;
729
- }
730
- }
731
- if (${JSON.stringify(finalize)} && captions) {
732
- if (captions.settleTimer !== undefined) clearTimeout(captions.settleTimer);
733
- captions.settleTimer = undefined;
734
- captions.observer?.disconnect?.();
735
- captions.observer = undefined;
736
- captions.observerInstalled = false;
737
- captions.identity = expectedIdentity;
738
- captions.finalized = true;
739
- captions.finalizedAt = Date.now();
740
- }
741
- const allLines = [
742
- ...(Array.isArray(captions?.lines) ? captions.lines : []),
743
- ...(${JSON.stringify(finalize)} || !Array.isArray(captions?.visible) ? [] : captions.visible),
744
- ];
745
- const visibleOverflow = Math.max(0, allLines.length - ${ZOOM_MEETING_TRANSCRIPT_MAX_LINES});
746
- const lines = allLines.slice(-${ZOOM_MEETING_TRANSCRIPT_MAX_LINES});
747
- const result = {
748
- urlMatched: true,
749
- sessionMatched: true,
750
- epoch: typeof captions?.epoch === "string" ? captions.epoch : undefined,
751
- droppedLines: (Number.isFinite(captions?.droppedLines)
752
- ? Math.max(0, Math.trunc(captions.droppedLines))
753
- : 0) + visibleOverflow,
754
- lines: lines.map((line) => ({
755
- at: typeof line?.at === "string" ? line.at : undefined,
756
- speaker: typeof line?.speaker === "string" ? line.speaker : undefined,
757
- text: typeof line?.text === "string" ? line.text : "",
758
- })).filter((line) => line.text),
759
- };
760
- return JSON.stringify(result);
761
- }`;
683
+ return createMeetingTranscriptSource({
684
+ expectedIdentity: normalizeZoomMeetingUrlForReuse(meetingUrl),
685
+ finalize,
686
+ globals: {
687
+ captionArchive: "__openclawZoomCaptionArchive",
688
+ captions: "__openclawZoomCaptions",
689
+ meeting: "__openclawZoomMeeting"
690
+ },
691
+ meetingSessionId,
692
+ pageIdentitySource: pageIdentityFunctionSource(),
693
+ platformDisplayName: "Zoom"
694
+ });
762
695
  }
763
696
  function zoomMeetingLeaveScript(params) {
764
697
  const selectors = JSON.stringify(ZOOM_MEETING_SELECTORS);
765
- const expectedIdentity = normalizeZoomMeetingUrlForReuse(params.meetingUrl);
766
- return `() => {
767
- ${pageIdentityFunctionSource()}
768
- const topDocument = globalThis.document;
769
- const document = topDocument.querySelector("#webclient")?.contentDocument || topDocument;
770
- const selectors = ${selectors};
771
- const expectedIdentity = ${JSON.stringify(expectedIdentity)};
772
- const expectedSessionId = ${JSON.stringify(params.meetingSessionId)};
773
- const leaveInitiated = ${JSON.stringify(params.leaveInitiated)};
774
- const currentIdentity = meetingIdentity(location.href);
775
- const state = window.__openclawZoomMeeting;
776
- const enforceSessionOwnership = Boolean(expectedSessionId);
777
- if (enforceSessionOwnership && state?.sessionId && state.sessionId !== expectedSessionId) {
778
- return JSON.stringify({ departed: false, sessionConflict: true, sessionMatched: false, urlMatched: true });
779
- }
780
- const sessionAdoptedFromUrl = Boolean(
781
- enforceSessionOwnership &&
782
- !state?.sessionId &&
783
- currentIdentity === expectedIdentity &&
784
- (!state?.identity || state.identity === expectedIdentity)
785
- );
786
- const sessionMatched = !enforceSessionOwnership ||
787
- state?.sessionId === expectedSessionId ||
788
- sessionAdoptedFromUrl;
789
- const retainedLeaveOwnership = Boolean(!sessionMatched && leaveInitiated);
790
- if (!sessionMatched && !retainedLeaveOwnership) {
791
- return JSON.stringify({ departed: false, sessionMatched: false, urlMatched: true });
792
- }
793
- const retireOwnedAudioBridges = () => {
794
- const entries = Array.isArray(window.__openclawZoomAudioOutputs)
795
- ? window.__openclawZoomAudioOutputs
796
- : [];
797
- const retained = [];
798
- const activeSessionId = expectedSessionId || state?.sessionId;
799
- for (const entry of entries) {
800
- const ownedByActiveSession = Boolean(
801
- !entry?.sessionId || (activeSessionId && entry.sessionId === activeSessionId)
802
- );
803
- if (!ownedByActiveSession) {
804
- retained.push(entry);
805
- continue;
806
- }
807
- const mediaSourceUrl = (element) => String(element?.currentSrc || element?.src || "");
808
- const sources = Array.isArray(entry?.sources)
809
- ? entry.sources
810
- : entry?.source
811
- ? [{ element: entry.source, muted: Boolean(entry.sourceMuted), stream: entry.stream, url: entry.sourceUrl }]
812
- : [];
813
- for (const source of sources) {
814
- const element = source?.element;
815
- const sourceMatches = source?.stream || element?.srcObject
816
- ? element?.srcObject === source?.stream
817
- : Boolean(source?.url && mediaSourceUrl(element) === source.url);
818
- const sourceIsEmpty = Boolean(element && !element.srcObject && !mediaSourceUrl(element));
819
- if (!element) continue;
820
- if (sourceIsEmpty) {
821
- element.muted = true;
822
- continue;
823
- }
824
- if (!sourceMatches) continue;
825
- const detachedLiveSource = Boolean(
826
- element.isConnected === false &&
827
- element.srcObject?.getAudioTracks?.().some((track) => track.readyState === "live")
828
- );
829
- if (detachedLiveSource) {
830
- element.muted = true;
831
- element.pause?.();
832
- element.srcObject = null;
833
- } else {
834
- element.muted = Boolean(source.muted);
835
- }
836
- }
837
- entry?.bridge?.pause?.();
838
- if (entry?.bridge) entry.bridge.srcObject = null;
839
- entry?.bridge?.remove?.();
840
- }
841
- if (retained.length > 0) window.__openclawZoomAudioOutputs = retained;
842
- else delete window.__openclawZoomAudioOutputs;
843
- };
844
- const first = (list) => {
698
+ return createMeetingLeaveSource({
699
+ controlSource: `const first = (list) => {
845
700
  for (const selector of list) {
846
701
  const node = document.querySelector(selector);
847
702
  if (!node) continue;
@@ -865,73 +720,33 @@ function zoomMeetingLeaveScript(params) {
865
720
  try {
866
721
  const currentUrl = new URL(location.href);
867
722
  webClientHome = !leave && currentUrl.hostname === "app.zoom.us" && /^\\/wc\\/?$/.test(currentUrl.pathname);
868
- } catch {}
869
- const preservedCallMatches = Boolean(
870
- expectedIdentity &&
871
- !currentIdentity &&
872
- state?.identity === expectedIdentity &&
873
- state?.inCallControl === leave &&
874
- state?.inCallUrl === location.href &&
875
- leave &&
876
- leave.isConnected !== false
877
- );
878
- const pendingLeaveMatches = Boolean(
879
- expectedIdentity &&
880
- state?.identity === expectedIdentity &&
881
- state?.leavePending === true &&
882
- state?.inCallUrl === location.href &&
883
- Date.now() - state?.leavePendingAt < 10_000
884
- );
885
- const rerenderPendingMatches = Boolean(
886
- expectedIdentity &&
887
- !currentIdentity &&
888
- state?.identity === expectedIdentity &&
889
- state?.inCallControl?.isConnected === false &&
890
- state?.inCallUrl === location.href &&
891
- Date.now() - state?.verifiedAt < 5_000 &&
892
- !leave
893
- );
894
- const meetingIdentityMatches = Boolean(
895
- currentUrlMatches || preservedCallMatches || pendingLeaveMatches || rerenderPendingMatches
896
- );
897
- // Zoom can replace the document between our Leave click and its post-call marker.
898
- // Retain request ownership only while no identity or live-call control contradicts it.
899
- const initiatedLeaveTransitionMatches = Boolean(
900
- leaveInitiated &&
901
- !currentIdentity &&
902
- !leave &&
723
+ } catch {}`,
724
+ departedMarkerSource: "(postCall || webClientHome)",
725
+ documentSetupSource: `const topDocument = globalThis.document;
726
+ const document = topDocument.querySelector("#webclient")?.contentDocument || topDocument;`,
727
+ expectedIdentity: normalizeZoomMeetingUrlForReuse(params.meetingUrl),
728
+ leaveInitiated: params.leaveInitiated,
729
+ meetingSessionId: params.meetingSessionId,
730
+ meetingStateSource: "sessionId: expectedSessionId || state?.sessionId,",
731
+ pageIdentitySource: pageIdentityFunctionSource(),
732
+ platform: {
733
+ displayName: "Zoom",
734
+ globals: {
735
+ audioOutputs: "__openclawZoomAudioOutputs",
736
+ meeting: "__openclawZoomMeeting"
737
+ }
738
+ },
739
+ selectors,
740
+ sessionMatchSource: `const sessionAdoptedFromUrl = Boolean(
741
+ enforceSessionOwnership &&
742
+ !state?.sessionId &&
743
+ currentIdentity === expectedIdentity &&
903
744
  (!state?.identity || state.identity === expectedIdentity)
904
745
  );
905
- if ((postCall || webClientHome) && (meetingIdentityMatches || initiatedLeaveTransitionMatches)) {
906
- retireOwnedAudioBridges();
907
- if (sessionMatched) delete window.__openclawZoomMeeting;
908
- return JSON.stringify({ departed: true, sessionMatched: true, urlMatched: true });
909
- }
910
- if (!meetingIdentityMatches && !initiatedLeaveTransitionMatches) {
911
- return JSON.stringify({ departed: false, urlMatched: false });
912
- }
913
- if (!sessionMatched) {
914
- return JSON.stringify({ departed: false, urlMatched: true });
915
- }
916
- if (confirmation) {
917
- confirmation.click();
918
- return JSON.stringify({ departed: false, leaveAction: "confirm", urlMatched: true });
919
- }
920
- if (leave) {
921
- window.__openclawZoomMeeting = {
922
- ...state,
923
- identity: expectedIdentity,
924
- sessionId: expectedSessionId || state?.sessionId,
925
- inCallControl: leave,
926
- inCallUrl: location.href,
927
- leavePending: true,
928
- leavePendingAt: Date.now(),
929
- };
930
- leave.click();
931
- return JSON.stringify({ departed: false, leaveAction: "leave", urlMatched: true });
932
- }
933
- return JSON.stringify({ departed: false, urlMatched: true });
934
- }`;
746
+ const sessionMatched = !enforceSessionOwnership ||
747
+ state?.sessionId === expectedSessionId ||
748
+ sessionAdoptedFromUrl;`
749
+ });
935
750
  }
936
751
  //#endregion
937
752
  //#region extensions/zoom-meetings/src/transports/zoom-meetings-platform-constants.ts
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a ISO8601 Date component string
3
- * @source ajv-formats
3
+ * @description https://datatracker.ietf.org/doc/html/rfc3339
4
4
  * @example `2020-12-12`
5
5
  */
6
6
  export declare function IsDate(value: string): boolean;
@@ -5,7 +5,7 @@ function IsLeapYear(year) {
5
5
  }
6
6
  /**
7
7
  * Returns true if the value is a ISO8601 Date component string
8
- * @source ajv-formats
8
+ * @description https://datatracker.ietf.org/doc/html/rfc3339
9
9
  * @example `2020-12-12`
10
10
  */
11
11
  export function IsDate(value) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a ISO8601 DateTime string
3
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc3339
4
4
  * @example `2020-12-12T20:20:40+00:00`
5
5
  */
6
- export declare function IsDateTime(value: string, strictTimeZone?: boolean): boolean;
6
+ export declare function IsDateTime(value: string): boolean;
@@ -2,10 +2,10 @@ import { IsDate } from './date.mjs';
2
2
  import { IsTime } from './time.mjs';
3
3
  /**
4
4
  * Returns true if the value is a ISO8601 DateTime string
5
- * @source ajv-formats
5
+ * @specification https://datatracker.ietf.org/doc/html/rfc3339
6
6
  * @example `2020-12-12T20:20:40+00:00`
7
7
  */
8
- export function IsDateTime(value, strictTimeZone = true) {
8
+ export function IsDateTime(value) {
9
9
  const dateTime = value.split(/T/i);
10
- return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1], strictTimeZone);
10
+ return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1]);
11
11
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Returns true if the value is an Email
3
- * @specification ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc5322
4
4
  */
5
5
  export declare function IsEmail(value: string): boolean;
@@ -1,7 +1,7 @@
1
- const Email = /^(?!.*\.\.)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i;
1
+ const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\.)*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
2
2
  /**
3
3
  * Returns true if the value is an Email
4
- * @specification ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc5322
5
5
  */
6
6
  export function IsEmail(value) {
7
7
  return Email.test(value);
@@ -1,4 +1,4 @@
1
- import * as Idna from './_idna.mjs';
1
+ import * as Idna from './idna/index.mjs';
2
2
  /**
3
3
  * Returns true if the value is a valid hostname.
4
4
  * @specification https://tools.ietf.org/html/rfc1123
@@ -6,13 +6,5 @@ import * as Idna from './_idna.mjs';
6
6
  * @specification https://tools.ietf.org/html/rfc5892
7
7
  */
8
8
  export function IsHostname(value) {
9
- if (value.length === 0 || value.length > 253)
10
- return false;
11
- if (value.charCodeAt(value.length - 1) === 46)
12
- return false;
13
- for (const label of value.split('.')) {
14
- if (!Idna.IsLabel(label))
15
- return false;
16
- }
17
- return true;
9
+ return Idna.IsHostname(value);
18
10
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Returns true if the value is an IdnEmail
3
- * @specification ajv-formats (unicode-extension)
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc4952
4
4
  */
5
5
  export declare function IsIdnEmail(value: string): boolean;
@@ -1,8 +1,8 @@
1
- const IdnEmail = /^(?!.*\.\.)[\p{L}\p{N}!#$%&'*+/=?^_`{|}~-]+(?:\.[\p{L}\p{N}!#$%&'*+/=?^_`{|}~-]+)*@[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,61}[\p{L}\p{N}])?(?:\.[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,61}[\p{L}\p{N}])?)*$/iu;
1
+ const IdnEmail = /^(?:[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+(?:\.[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+)*|"(?:[^"\\]|\\.)*")@[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,62})(?<!-)(?:\.[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,62})(?<!-))*$/iu;
2
2
  /**
3
3
  * Returns true if the value is an IdnEmail
4
- * @specification ajv-formats (unicode-extension)
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc4952
5
5
  */
6
6
  export function IsIdnEmail(value) {
7
- return IdnEmail.test(value);
7
+ return IdnEmail.test(value.normalize('NFC'));
8
8
  }
@@ -3,5 +3,6 @@
3
3
  * @specification https://tools.ietf.org/html/rfc3490
4
4
  * @specification https://tools.ietf.org/html/rfc5891
5
5
  * @specification https://tools.ietf.org/html/rfc5892
6
+ * @specification https://tools.ietf.org/html/rfc5893
6
7
  */
7
8
  export declare function IsIdnHostname(value: string): boolean;
@@ -1,19 +1,11 @@
1
- import { IsIdnLabel } from './_idna.mjs';
1
+ import * as Idna from './idna/index.mjs';
2
2
  /**
3
3
  * Returns true if the value is a valid internationalized (IDN) hostname.
4
4
  * @specification https://tools.ietf.org/html/rfc3490
5
5
  * @specification https://tools.ietf.org/html/rfc5891
6
6
  * @specification https://tools.ietf.org/html/rfc5892
7
+ * @specification https://tools.ietf.org/html/rfc5893
7
8
  */
8
9
  export function IsIdnHostname(value) {
9
- if (value.length === 0 || value.includes(' '))
10
- return false;
11
- const canonical = value.normalize('NFC').replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.');
12
- if (canonical.length > 253)
13
- return false;
14
- for (const label of canonical.split('.')) {
15
- if (!IsIdnLabel(label))
16
- return false;
17
- }
18
- return true;
10
+ return Idna.IsIdnHostname(value);
19
11
  }
@@ -0,0 +1,3 @@
1
+ export declare function HasBidiChars(value: string): boolean;
2
+ export declare function HasRightToLeftCharacters(value: string): boolean;
3
+ export declare function SatisfiesBidiRule(value: string): boolean;
@@ -0,0 +1,98 @@
1
+ // deno-fmt-ignore-file
2
+ import * as FormatPuny from './puny.mjs';
3
+ import * as Pattern from '../pattern/pattern.mjs';
4
+ // ------------------------------------------------------------------
5
+ // LOCAL REGEX: Allowed Bidi classes per direction (RFC 5893)
6
+ // ------------------------------------------------------------------
7
+ const RE_RTL_ALLOWED = /^(?:R|AL|AN|EN|ES|CS|ET|ON|BN|NSM)$/;
8
+ const RE_LTR_ALLOWED = /^(?:L|EN|ES|CS|ET|ON|BN|NSM)$/;
9
+ const RE_RTL_CLASSES = /^(?:R|AL|AN)$/;
10
+ // ------------------------------------------------------------------
11
+ // HasBidiChars
12
+ //
13
+ // Decodes a punycode label to its Unicode form (if it is one) and
14
+ // checks whether the result is an RTL label per RFC 5893 §1.4.
15
+ // ------------------------------------------------------------------
16
+ export function HasBidiChars(value) {
17
+ if (FormatPuny.IsAcePrefixed(value)) {
18
+ try {
19
+ return HasRightToLeftCharacters(FormatPuny.Decode(value.slice(4).toLowerCase()));
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ return HasRightToLeftCharacters(value);
26
+ }
27
+ // ------------------------------------------------------------------
28
+ // GetBidiClass
29
+ // ------------------------------------------------------------------
30
+ function GetBidiClass(codePoint) {
31
+ const char = String.fromCodePoint(codePoint);
32
+ return (Pattern.RE_EUROPEAN_NUMBER.test(char) ? 'EN' :
33
+ Pattern.RE_ARABIC_INDIC_DIGIT.test(char) ? 'AN' :
34
+ // Pattern.RE_EUROPEAN_SEPARATOR.test(char) ? 'ES' : // (no-spec-coverage)
35
+ // Pattern.RE_COMMON_SEPARATOR.test(char) ? 'CS' : // (no-spec-coverage)
36
+ Pattern.RE_MARK_NONSPACING.test(char) ? 'NSM' :
37
+ Pattern.RE_SCRIPT_HEBREW.test(char) ? 'R' :
38
+ Pattern.RE_SCRIPT_ARABIC_LETTER.test(char) ? 'AL' :
39
+ Pattern.RE_LETTER.test(char) ? 'L' :
40
+ 'ON');
41
+ }
42
+ // ------------------------------------------------------------------
43
+ // HasRightToLeftCharacters
44
+ //
45
+ // Per RFC 5893 §1.4: "An RTL label is a label that contains at least
46
+ // one character of type R, AL, or AN." Used to determine whether a
47
+ // domain name is a "Bidi domain name" (RFC 5893 §1.4), in which case
48
+ // the Bidi Rule applies to every label in the domain.
49
+ // ------------------------------------------------------------------
50
+ export function HasRightToLeftCharacters(value) {
51
+ for (const ch of value)
52
+ if (RE_RTL_CLASSES.test(GetBidiClass(ch.codePointAt(0))))
53
+ return true;
54
+ return false;
55
+ }
56
+ // ------------------------------------------------------------------
57
+ // SatisfiesBidiRule
58
+ // ------------------------------------------------------------------
59
+ export function SatisfiesBidiRule(value) {
60
+ let isRtl = false;
61
+ let allowed = RE_LTR_ALLOWED;
62
+ let sawEN = false;
63
+ let sawAN = false;
64
+ let isFirst = true;
65
+ // let lastClass: string | null = null // (no-spec-coverage)
66
+ for (const ch of value) {
67
+ const bidiClass = GetBidiClass(ch.codePointAt(0));
68
+ if (isFirst) {
69
+ // 1. The first character must be a character with Bidi property L, R, or AL.
70
+ if (bidiClass !== 'L' && bidiClass !== 'R' && bidiClass !== 'AL')
71
+ return false;
72
+ isRtl = bidiClass === 'R' || bidiClass === 'AL';
73
+ allowed = isRtl ? RE_RTL_ALLOWED : RE_LTR_ALLOWED;
74
+ isFirst = false;
75
+ }
76
+ // 2 / 5. Only characters in the allowed set for this direction may appear.
77
+ if (!allowed.test(bidiClass))
78
+ return false;
79
+ if (bidiClass === 'EN')
80
+ sawEN = true;
81
+ else if (bidiClass === 'AN')
82
+ sawAN = true;
83
+ // if (bidiClass !== 'NSM') lastClass = bidiClass // (no-spec-coverage)
84
+ }
85
+ if (isRtl && sawEN && sawAN)
86
+ return false; // spec coverage path
87
+ // (no-spec-coverage)
88
+ // if (isRtl) {
89
+ // // 3. The end of the label must be R, AL, EN, or AN (ignoring trailing NSM).
90
+ // // if (lastClass !== 'R' && lastClass !== 'AL' && lastClass !== 'EN' && lastClass !== 'AN') return false
91
+ // // 4. If an EN is present, no AN may be present, and vice versa.
92
+ // if (sawEN && sawAN) return false
93
+ // } else {
94
+ // // 6. The end of the label must be L or EN (ignoring trailing NSM).
95
+ // // if (lastClass !== 'L' && lastClass !== 'EN') return false
96
+ // }
97
+ return true;
98
+ }
@@ -0,0 +1,3 @@
1
+ export declare function IsAcePrefixed(value: string): boolean;
2
+ export declare function Decode(value: string): string;
3
+ export declare function Encode(input: string): string;