@sailfish-ai/recorder 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -82,38 +82,103 @@ function storeCredentialsAndConnection({ apiKey, backendApi, }) {
82
82
  sessionStorage.setItem("sailfishApiKey", apiKey);
83
83
  sessionStorage.setItem("sailfishBackendApi", backendApi);
84
84
  }
85
- // Intercepting XMLHttpRequest
85
+ // Utility function to match domains or paths with wildcard support
86
+ export function matchUrlWithWildcard(url, patterns) {
87
+ // Strip any protocol (e.g., http, https, ws, wss, ftp, etc.) from the URL
88
+ const strippedUrl = url.replace(/^[a-zA-Z]+:\/\//, "");
89
+ const parsedUrl = new URL("http://" + strippedUrl); // Add a dummy protocol for URL parsing
90
+ const { hostname, pathname } = parsedUrl;
91
+ const domain = hostname.toLowerCase();
92
+ return patterns.some((pattern) => {
93
+ // Strip any protocol from the pattern
94
+ const strippedPattern = pattern.replace(/^[a-zA-Z]+:\/\//, "");
95
+ let [patternDomain, patternPath] = strippedPattern.split("/", 2);
96
+ // Handle domain wildcards
97
+ const normalizedPatternDomain = patternDomain
98
+ .replace(/\./g, "\\.") // Escape dots for regex
99
+ .replace(/\*/g, ".*"); // Replace '*' with regex to match any characters
100
+ // Create regex for the domain pattern
101
+ const domainRegex = new RegExp(`^${normalizedPatternDomain}$`, "i");
102
+ // Strip 'www.' from both the input domain and the pattern domain for comparison
103
+ const strippedDomain = domain.startsWith("www.") ? domain.slice(4) : domain;
104
+ // Handle subdomain wildcard (*.) to match both base and subdomains
105
+ if (patternDomain.startsWith("*.") &&
106
+ (domain === patternDomain.slice(2) ||
107
+ strippedDomain === patternDomain.slice(2))) {
108
+ // Check for path match if the pattern includes a path
109
+ if (patternPath) {
110
+ const normalizedPatternPath = patternPath
111
+ .replace(/\*/g, ".*") // Replace '*' with regex to match any characters
112
+ .replace(/\/$/, ""); // Remove trailing slashes from pattern
113
+ const pathRegex = new RegExp(`^/${normalizedPatternPath}`, "i");
114
+ return pathRegex.test(pathname); // Match the path
115
+ }
116
+ return true; // Domain matched, no path required
117
+ }
118
+ // Check if the domain matches (include check for base domain without www)
119
+ if (!domainRegex.test(strippedDomain) && !domainRegex.test(domain)) {
120
+ return false;
121
+ }
122
+ // If there's a path in the pattern, match the path
123
+ if (patternPath) {
124
+ const normalizedPatternPath = patternPath
125
+ .replace(/\*/g, ".*") // Replace '*' with regex to match any characters
126
+ .replace(/\/$/, ""); // Remove trailing slashes from pattern
127
+ const pathRegex = new RegExp(`^/${normalizedPatternPath}`, "i");
128
+ return pathRegex.test(pathname); // Match the path
129
+ }
130
+ // If no path pattern, only the domain needs to match
131
+ return true;
132
+ });
133
+ }
134
+ // Updated XMLHttpRequest interceptor with single check function
86
135
  function setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo) {
87
136
  const originalOpen = XMLHttpRequest.prototype.open;
88
137
  const originalSend = XMLHttpRequest.prototype.send;
89
138
  const sessionId = getOrSetSessionId();
139
+ // Combine default and passed domains
90
140
  const combinedIgnoreDomains = [
91
141
  ...DOMAINS_TO_NOT_PROPAGATE_HEADER_TO_DEFAULT,
92
142
  ...domainsToNotPropagateHeaderTo,
93
- ].map((domain) => (domain.startsWith("www.") ? domain.slice(4) : domain)); // Remove 'www.' from ignore domains
143
+ ];
94
144
  XMLHttpRequest.prototype.open = function (...args) {
95
145
  this._url = args[1]; // Store the request URL
96
146
  originalOpen.apply(this, args);
97
147
  };
98
148
  XMLHttpRequest.prototype.send = function (...args) {
99
- const domain = getEffectiveDomain(this._url); // Use tldts to get the domain
100
- if (sessionId && !combinedIgnoreDomains.includes(domain)) {
149
+ const url = this._url;
150
+ // Check if URL matches any domain or path pattern
151
+ const shouldSkipHeader = matchUrlWithWildcard(url, combinedIgnoreDomains);
152
+ if (sessionId && !shouldSkipHeader) {
101
153
  this.setRequestHeader("X-Sf3-Rid", sessionId);
102
154
  }
103
155
  originalSend.apply(this, args);
104
156
  };
105
157
  }
106
- // Intercepting fetch API
158
+ // Updated fetch interceptor with single check function
107
159
  function setupFetchInterceptor(domainsToNotPropagateHeaderTo) {
108
160
  const originalFetch = window.fetch;
109
161
  const sessionId = getOrSetSessionId();
162
+ // Combine default and passed domains
110
163
  const combinedIgnoreDomains = [
111
164
  ...DOMAINS_TO_NOT_PROPAGATE_HEADER_TO_DEFAULT,
112
165
  ...domainsToNotPropagateHeaderTo,
113
- ].map((domain) => (domain.startsWith("www.") ? domain.slice(4) : domain)); // Remove 'www.' from ignore domains
166
+ ];
114
167
  window.fetch = async function (input, init = {}) {
115
- const domain = typeof input === "string" ? getEffectiveDomain(input) : "";
116
- if (sessionId && !combinedIgnoreDomains.includes(domain)) {
168
+ let url;
169
+ // Check if input is a string (URL) or a Request object
170
+ if (typeof input === "string") {
171
+ url = input;
172
+ }
173
+ else if (input instanceof Request) {
174
+ url = input.url;
175
+ }
176
+ else {
177
+ throw new Error("Invalid input type for fetch");
178
+ }
179
+ // Check if URL matches any domain or path pattern
180
+ const shouldSkipHeader = matchUrlWithWildcard(url, combinedIgnoreDomains);
181
+ if (sessionId && !shouldSkipHeader) {
117
182
  init.headers = {
118
183
  ...init.headers,
119
184
  "X-Sf3-Rid": sessionId,