@scalar/helpers 0.0.6 → 0.0.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @scalar/helpers
2
2
 
3
+ ## 0.0.8
4
+
5
+ ### Patch Changes
6
+
7
+ - 66b18fc: feat: update the references to handle $refs from the magic proxy
8
+
9
+ ## 0.0.7
10
+
11
+ ### Patch Changes
12
+
13
+ - c0d6793: feat: ensure we use the path routing base path for relative document url resolution
14
+ - f3d0216: feat: lazy loading v1.5
15
+
3
16
  ## 0.0.6
4
17
 
5
18
  ### Patch Changes
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Freezes an element at the top of the viewport using a mutation observer to check if the element has entered the dom
3
+ * Differs from freezeElement as the element doesn't need to exist yet
4
+ */
5
+ export declare const freezeAtTop: (id: string) => () => void;
6
+ //# sourceMappingURL=freeze-at-top.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freeze-at-top.d.ts","sourceRoot":"","sources":["../../src/dom/freeze-at-top.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,OAAQ,MAAM,eAyCrC,CAAA"}
@@ -0,0 +1,34 @@
1
+ const freezeAtTop = (id) => {
2
+ if (!id) {
3
+ return () => null;
4
+ }
5
+ let rafId = null;
6
+ let element = document.getElementById(id);
7
+ const observer = new MutationObserver(() => {
8
+ element ||= document.getElementById(id);
9
+ if (!element) {
10
+ return;
11
+ }
12
+ if (rafId !== null) {
13
+ cancelAnimationFrame(rafId);
14
+ }
15
+ rafId = requestAnimationFrame(() => {
16
+ element?.scrollIntoView();
17
+ rafId = null;
18
+ });
19
+ });
20
+ observer.observe(document.body, {
21
+ childList: true,
22
+ subtree: true
23
+ });
24
+ return () => {
25
+ if (rafId !== null) {
26
+ cancelAnimationFrame(rafId);
27
+ }
28
+ observer.disconnect();
29
+ };
30
+ };
31
+ export {
32
+ freezeAtTop
33
+ };
34
+ //# sourceMappingURL=freeze-at-top.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/dom/freeze-at-top.ts"],
4
+ "sourcesContent": ["/**\n * Freezes an element at the top of the viewport using a mutation observer to check if the element has entered the dom\n * Differs from freezeElement as the element doesn't need to exist yet\n */\nexport const freezeAtTop = (id: string) => {\n if (!id) {\n return () => null\n }\n\n let rafId: number | null = null\n let element = document.getElementById(id)\n\n // Create mutation observer to watch for DOM changes\n const observer = new MutationObserver(() => {\n element ||= document.getElementById(id)\n\n if (!element) {\n return\n }\n\n // Cancel any pending animation frame\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n }\n\n // Schedule the scroll adjustment for the next frame\n rafId = requestAnimationFrame(() => {\n element?.scrollIntoView()\n rafId = null\n })\n })\n\n // Start observing with more specific configuration\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n })\n\n // Return function to stop maintaining position\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n }\n observer.disconnect()\n }\n}\n"],
5
+ "mappings": "AAIO,MAAM,cAAc,CAAC,OAAe;AACzC,MAAI,CAAC,IAAI;AACP,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,QAAuB;AAC3B,MAAI,UAAU,SAAS,eAAe,EAAE;AAGxC,QAAM,WAAW,IAAI,iBAAiB,MAAM;AAC1C,gBAAY,SAAS,eAAe,EAAE;AAEtC,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAGA,QAAI,UAAU,MAAM;AAClB,2BAAqB,KAAK;AAAA,IAC5B;AAGA,YAAQ,sBAAsB,MAAM;AAClC,eAAS,eAAe;AACxB,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AAGD,WAAS,QAAQ,SAAS,MAAM;AAAA,IAC9B,WAAW;AAAA,IACX,SAAS;AAAA,EACX,CAAC;AAGD,SAAO,MAAM;AACX,QAAI,UAAU,MAAM;AAClB,2BAAqB,KAAK;AAAA,IAC5B;AACA,aAAS,WAAW;AAAA,EACtB;AACF;",
6
+ "names": []
7
+ }
@@ -3,5 +3,5 @@ export declare const HTTP_METHODS: readonly ["connect", "delete", "get", "head",
3
3
  /** All http methods we support */
4
4
  export type HttpMethod = (typeof HTTP_METHODS)[number];
5
5
  /** Set of all http methods we support */
6
- export declare const httpMethods: Set<"connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace">;
6
+ export declare const httpMethods: Readonly<Set<"connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace">>;
7
7
  //# sourceMappingURL=http-methods.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-methods.d.ts","sourceRoot":"","sources":["../../src/http/http-methods.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,eAAO,MAAM,YAAY,2FAA4F,CAAA;AAErH,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,yCAAyC;AACzC,eAAO,MAAM,WAAW,6FAAwB,CAAA"}
1
+ {"version":3,"file":"http-methods.d.ts","sourceRoot":"","sources":["../../src/http/http-methods.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,eAAO,MAAM,YAAY,2FAA4F,CAAA;AAErH,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,yCAAyC;AACzC,eAAO,MAAM,WAAW,uGAAuC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  const HTTP_METHODS = ["connect", "delete", "get", "head", "options", "patch", "post", "put", "trace"];
2
- const httpMethods = new Set(HTTP_METHODS);
2
+ const httpMethods = Object.freeze(new Set(HTTP_METHODS));
3
3
  export {
4
4
  HTTP_METHODS,
5
5
  httpMethods
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/http/http-methods.ts"],
4
- "sourcesContent": ["/** All OpenAPI HTTP methods plus connect */\nexport const HTTP_METHODS = ['connect', 'delete', 'get', 'head', 'options', 'patch', 'post', 'put', 'trace'] as const\n\n/** All http methods we support */\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\n/** Set of all http methods we support */\nexport const httpMethods = new Set(HTTP_METHODS)\n"],
5
- "mappings": "AACO,MAAM,eAAe,CAAC,WAAW,UAAU,OAAO,QAAQ,WAAW,SAAS,QAAQ,OAAO,OAAO;AAMpG,MAAM,cAAc,IAAI,IAAI,YAAY;",
4
+ "sourcesContent": ["/** All OpenAPI HTTP methods plus connect */\nexport const HTTP_METHODS = ['connect', 'delete', 'get', 'head', 'options', 'patch', 'post', 'put', 'trace'] as const\n\n/** All http methods we support */\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\n/** Set of all http methods we support */\nexport const httpMethods = Object.freeze(new Set(HTTP_METHODS))\n"],
5
+ "mappings": "AACO,MAAM,eAAe,CAAC,WAAW,UAAU,OAAO,QAAQ,WAAW,SAAS,QAAQ,OAAO,OAAO;AAMpG,MAAM,cAAc,OAAO,OAAO,IAAI,IAAI,YAAY,CAAC;",
6
6
  "names": []
7
7
  }
@@ -18,7 +18,15 @@ export declare const LS_KEYS: {
18
18
  * to ensure we do not have any conflicts
19
19
  */
20
20
  export declare const REFERENCE_LS_KEYS: {
21
- readonly SELECTED_CLIENT: "scalar-reference-selected-client";
21
+ /**
22
+ * We should remove after some time as we no longer store an object
23
+ * @deprecated
24
+ */
25
+ readonly SELECTED_CLIENT_DEPRECATED: "scalar-reference-selected-client";
26
+ /**
27
+ * Store the selected client as a string in localStorage
28
+ */
29
+ readonly SELECTED_CLIENT: "scalar-reference-selected-client-v2";
22
30
  };
23
31
  /**
24
32
  * localStorage keys for all client resources
@@ -1 +1 @@
1
- {"version":3,"file":"local-storage.d.ts","sourceRoot":"","sources":["../../src/object/local-storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;CAUV,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;CAEpB,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,cAAc;;;CAGjB,CAAA;AAEV,sCAAsC;AACtC,eAAO,MAAM,gBAAgB;;;;CAOX,CAAA"}
1
+ {"version":3,"file":"local-storage.d.ts","sourceRoot":"","sources":["../../src/object/local-storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;CAUV,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,iBAAiB;IAC5B;;;OAGG;;IAEH;;OAEG;;CAEK,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,cAAc;;;CAGjB,CAAA;AAEV,sCAAsC;AACtC,eAAO,MAAM,gBAAgB;;;;CAOX,CAAA"}
@@ -10,7 +10,15 @@ const LS_KEYS = {
10
10
  WORKSPACE: "workspace"
11
11
  };
12
12
  const REFERENCE_LS_KEYS = {
13
- SELECTED_CLIENT: "scalar-reference-selected-client"
13
+ /**
14
+ * We should remove after some time as we no longer store an object
15
+ * @deprecated
16
+ */
17
+ SELECTED_CLIENT_DEPRECATED: "scalar-reference-selected-client",
18
+ /**
19
+ * Store the selected client as a string in localStorage
20
+ */
21
+ SELECTED_CLIENT: "scalar-reference-selected-client-v2"
14
22
  };
15
23
  const CLIENT_LS_KEYS = {
16
24
  AUTH: "scalar-client-auth",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/object/local-storage.ts"],
4
- "sourcesContent": ["/**\n * localStorage keys for resources\n * DO NOT CHANGE THESE AS IT WILL BREAK THE MIGRATION\n */\nexport const LS_KEYS = {\n COLLECTION: 'collection',\n COOKIE: 'cookie',\n ENVIRONMENT: 'environment',\n REQUEST: 'request',\n REQUEST_EXAMPLE: 'requestExample',\n SECURITY_SCHEME: 'securityScheme',\n SERVER: 'server',\n TAG: 'tag',\n WORKSPACE: 'workspace',\n} as const\n\n/**\n * localStorage keys for all reference resources\n * to ensure we do not have any conflicts\n */\nexport const REFERENCE_LS_KEYS = {\n SELECTED_CLIENT: 'scalar-reference-selected-client',\n} as const\n\n/**\n * localStorage keys for all client resources\n * to ensure we do not have any conflicts\n */\nexport const CLIENT_LS_KEYS = {\n AUTH: 'scalar-client-auth',\n SELECTED_SECURITY_SCHEMES: 'scalar-client-selected-security-schemes',\n} as const\n\n/** SSR safe alias for localStorage */\nexport const safeLocalStorage = () =>\n typeof window === 'undefined'\n ? {\n getItem: () => null,\n setItem: () => null,\n removeItem: () => null,\n }\n : localStorage\n"],
5
- "mappings": "AAIO,MAAM,UAAU;AAAA,EACrB,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,WAAW;AACb;AAMO,MAAM,oBAAoB;AAAA,EAC/B,iBAAiB;AACnB;AAMO,MAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,2BAA2B;AAC7B;AAGO,MAAM,mBAAmB,MAC9B,OAAO,WAAW,cACd;AAAA,EACE,SAAS,MAAM;AAAA,EACf,SAAS,MAAM;AAAA,EACf,YAAY,MAAM;AACpB,IACA;",
4
+ "sourcesContent": ["/**\n * localStorage keys for resources\n * DO NOT CHANGE THESE AS IT WILL BREAK THE MIGRATION\n */\nexport const LS_KEYS = {\n COLLECTION: 'collection',\n COOKIE: 'cookie',\n ENVIRONMENT: 'environment',\n REQUEST: 'request',\n REQUEST_EXAMPLE: 'requestExample',\n SECURITY_SCHEME: 'securityScheme',\n SERVER: 'server',\n TAG: 'tag',\n WORKSPACE: 'workspace',\n} as const\n\n/**\n * localStorage keys for all reference resources\n * to ensure we do not have any conflicts\n */\nexport const REFERENCE_LS_KEYS = {\n /**\n * We should remove after some time as we no longer store an object\n * @deprecated\n */\n SELECTED_CLIENT_DEPRECATED: 'scalar-reference-selected-client',\n /**\n * Store the selected client as a string in localStorage\n */\n SELECTED_CLIENT: 'scalar-reference-selected-client-v2',\n} as const\n\n/**\n * localStorage keys for all client resources\n * to ensure we do not have any conflicts\n */\nexport const CLIENT_LS_KEYS = {\n AUTH: 'scalar-client-auth',\n SELECTED_SECURITY_SCHEMES: 'scalar-client-selected-security-schemes',\n} as const\n\n/** SSR safe alias for localStorage */\nexport const safeLocalStorage = () =>\n typeof window === 'undefined'\n ? {\n getItem: () => null,\n setItem: () => null,\n removeItem: () => null,\n }\n : localStorage\n"],
5
+ "mappings": "AAIO,MAAM,UAAU;AAAA,EACrB,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,WAAW;AACb;AAMO,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/B,4BAA4B;AAAA;AAAA;AAAA;AAAA,EAI5B,iBAAiB;AACnB;AAMO,MAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,2BAA2B;AAC7B;AAGO,MAAM,mBAAmB,MAC9B,OAAO,WAAW,cACd;AAAA,EACE,SAAS,MAAM;AAAA,EACf,SAAS,MAAM;AAAA,EACf,YAAY,MAAM;AACpB,IACA;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Find all strings wrapped in {} or {{}} in value.
3
3
  */
4
- export declare const findVariables: (value: string) => string[];
4
+ export declare const findVariables: (value: string) => (string | undefined)[];
5
5
  //# sourceMappingURL=find-variables.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-variables.d.ts","sourceRoot":"","sources":["../../src/regex/find-variables.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,aAAa,UAAW,MAAM,aACiE,CAAA"}
1
+ {"version":3,"file":"find-variables.d.ts","sourceRoot":"","sources":["../../src/regex/find-variables.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,aAAa,UAAW,MAAM,2BACiE,CAAA"}
@@ -1,8 +1,14 @@
1
1
  /** Spy on console.warn */
2
- export declare const consoleWarnSpy: import("vitest").MockInstance<[message?: any, ...optionalParams: any[]], void>;
2
+ export declare const consoleWarnSpy: import("vitest").MockInstance<{
3
+ (...data: any[]): void;
4
+ (message?: any, ...optionalParams: any[]): void;
5
+ }>;
3
6
  export declare let isConsoleWarnEnabled: boolean;
4
7
  /** Spy on console.error */
5
- export declare const consoleErrorSpy: import("vitest").MockInstance<[message?: any, ...optionalParams: any[]], void>;
8
+ export declare const consoleErrorSpy: import("vitest").MockInstance<{
9
+ (...data: any[]): void;
10
+ (message?: any, ...optionalParams: any[]): void;
11
+ }>;
6
12
  export declare let isConsoleErrorEnabled: boolean;
7
13
  /** Reset the spies */
8
14
  export declare const resetConsoleSpies: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"console-spies.d.ts","sourceRoot":"","sources":["../../src/testing/console-spies.ts"],"names":[],"mappings":"AAEA,0BAA0B;AAC1B,eAAO,MAAM,cAAc,gFAA4B,CAAA;AACvD,eAAO,IAAI,oBAAoB,SAAQ,CAAA;AAEvC,2BAA2B;AAC3B,eAAO,MAAM,eAAe,gFAA6B,CAAA;AACzD,eAAO,IAAI,qBAAqB,SAAQ,CAAA;AAExC,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,YAG7B,CAAA;AAED,8CAA8C;AAC9C,eAAO,MAAM,iBAAiB,eAAsC,CAAA;AAEpE,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,eAAuC,CAAA;AAEtE,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,eAAuC,CAAA;AAEtE,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,eAAwC,CAAA"}
1
+ {"version":3,"file":"console-spies.d.ts","sourceRoot":"","sources":["../../src/testing/console-spies.ts"],"names":[],"mappings":"AAEA,0BAA0B;AAC1B,eAAO,MAAM,cAAc;;;EAA4B,CAAA;AACvD,eAAO,IAAI,oBAAoB,SAAQ,CAAA;AAEvC,2BAA2B;AAC3B,eAAO,MAAM,eAAe;;;EAA6B,CAAA;AACzD,eAAO,IAAI,qBAAqB,SAAQ,CAAA;AAExC,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,YAG7B,CAAA;AAED,8CAA8C;AAC9C,eAAO,MAAM,iBAAiB,eAAsC,CAAA;AAEpE,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,eAAuC,CAAA;AAEtE,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,eAAuC,CAAA;AAEtE,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,eAAwC,CAAA"}
@@ -1,26 +1,31 @@
1
- /** Function overload for createApiReference to allow multiple different signatures */
2
- export type Measure = {
3
- <T>(name: string, fn: () => T): T;
4
- <T>(name: string, fn: () => Promise<T>): Promise<T>;
5
- <T>(name: string, fn: () => T | Promise<T>): T | Promise<T>;
6
- };
7
1
  /**
8
2
  * Measures the execution time of a function and logs it.
9
- * Works with both async and sync functions.
10
- * Returns the result of the measured function.
3
+ *
4
+ * Works only with sync functions and returns the result of the measured function.
11
5
  *
12
6
  * @example
13
- * ```ts
14
- * // Async function
15
- * const result = await measure('api-call', async () => {
16
- * return await fetchData()
17
- * })
18
7
  *
8
+ * ```ts
19
9
  * // Sync function
20
- * const result = measure('computation', () => {
10
+ * const result = measureSync('computation', () => {
21
11
  * return heavyComputation()
22
12
  * })
23
13
  * ```
24
14
  */
25
- export declare const measure: Measure;
15
+ export declare const measureSync: <T>(name: string, fn: () => T) => T;
16
+ /**
17
+ * Measures the execution time of an async function and logs it.
18
+ *
19
+ * Works only with async functions and returns the result of the measured function.
20
+ *
21
+ * @example
22
+ *
23
+ * ```ts
24
+ * // Async function
25
+ * const result = await measure('api-call', async () => {
26
+ * return await fetchData()
27
+ * })
28
+ * ````
29
+ */
30
+ export declare const measureAsync: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
26
31
  //# sourceMappingURL=measure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../src/testing/measure.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,MAAM,MAAM,OAAO,GAAG;IACpB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAA;IACjC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC5D,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,OAAO,EAAE,OAWrB,CAAA"}
1
+ {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../src/testing/measure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,QAAQ,MAAM,MAAM,MAAM,CAAC,KAAG,CAW1D,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,GAAU,CAAC,QAAQ,MAAM,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAWnF,CAAA"}
@@ -1,4 +1,4 @@
1
- const measure = (name, fn) => {
1
+ const measureSync = (name, fn) => {
2
2
  const start = performance.now();
3
3
  const result = fn();
4
4
  const end = performance.now();
@@ -6,7 +6,16 @@ const measure = (name, fn) => {
6
6
  console.info(`${name}: ${duration} ms`);
7
7
  return result;
8
8
  };
9
+ const measureAsync = async (name, fn) => {
10
+ const start = performance.now();
11
+ const result = await fn();
12
+ const end = performance.now();
13
+ const duration = Math.round(end - start);
14
+ console.info(`${name}: ${duration} ms`);
15
+ return result;
16
+ };
9
17
  export {
10
- measure
18
+ measureAsync,
19
+ measureSync
11
20
  };
12
21
  //# sourceMappingURL=measure.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/testing/measure.ts"],
4
- "sourcesContent": ["/** Function overload for createApiReference to allow multiple different signatures */\nexport type Measure = {\n <T>(name: string, fn: () => T): T\n <T>(name: string, fn: () => Promise<T>): Promise<T>\n <T>(name: string, fn: () => T | Promise<T>): T | Promise<T>\n}\n\n/**\n * Measures the execution time of a function and logs it.\n * Works with both async and sync functions.\n * Returns the result of the measured function.\n *\n * @example\n * ```ts\n * // Async function\n * const result = await measure('api-call', async () => {\n * return await fetchData()\n * })\n *\n * // Sync function\n * const result = measure('computation', () => {\n * return heavyComputation()\n * })\n * ```\n */\nexport const measure: Measure = (name, fn) => {\n const start = performance.now()\n\n const result = fn()\n\n const end = performance.now()\n const duration = Math.round(end - start)\n\n console.info(`${name}: ${duration} ms`)\n\n return result\n}\n"],
5
- "mappings": "AAyBO,MAAM,UAAmB,CAAC,MAAM,OAAO;AAC5C,QAAM,QAAQ,YAAY,IAAI;AAE9B,QAAM,SAAS,GAAG;AAElB,QAAM,MAAM,YAAY,IAAI;AAC5B,QAAM,WAAW,KAAK,MAAM,MAAM,KAAK;AAEvC,UAAQ,KAAK,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEtC,SAAO;AACT;",
4
+ "sourcesContent": ["/**\n * Measures the execution time of a function and logs it.\n *\n * Works only with sync functions and returns the result of the measured function.\n *\n * @example\n *\n * ```ts\n * // Sync function\n * const result = measureSync('computation', () => {\n * return heavyComputation()\n * })\n * ```\n */\nexport const measureSync = <T>(name: string, fn: () => T): T => {\n const start = performance.now()\n\n const result = fn()\n\n const end = performance.now()\n const duration = Math.round(end - start)\n\n console.info(`${name}: ${duration} ms`)\n\n return result\n}\n\n/**\n * Measures the execution time of an async function and logs it.\n *\n * Works only with async functions and returns the result of the measured function.\n *\n * @example\n *\n * ```ts\n * // Async function\n * const result = await measure('api-call', async () => {\n * return await fetchData()\n * })\n * ````\n */\nexport const measureAsync = async <T>(name: string, fn: () => Promise<T>): Promise<T> => {\n const start = performance.now()\n\n const result = await fn()\n\n const end = performance.now()\n const duration = Math.round(end - start)\n\n console.info(`${name}: ${duration} ms`)\n\n return result\n}\n"],
5
+ "mappings": "AAcO,MAAM,cAAc,CAAI,MAAc,OAAmB;AAC9D,QAAM,QAAQ,YAAY,IAAI;AAE9B,QAAM,SAAS,GAAG;AAElB,QAAM,MAAM,YAAY,IAAI;AAC5B,QAAM,WAAW,KAAK,MAAM,MAAM,KAAK;AAEvC,UAAQ,KAAK,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEtC,SAAO;AACT;AAgBO,MAAM,eAAe,OAAU,MAAc,OAAqC;AACvF,QAAM,QAAQ,YAAY,IAAI;AAE9B,QAAM,SAAS,MAAM,GAAG;AAExB,QAAM,MAAM,YAAY,IAAI;AAC5B,QAAM,WAAW,KAAK,MAAM,MAAM,KAAK;AAEvC,UAAQ,KAAK,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEtC,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,13 @@
1
1
  /**
2
- * Pass an URL or a relative URL and get an absolute URL
2
+ * Converts a relative URL to an absolute URL using the provided base URL or current window location.
3
+ * @param url - The URL to make absolute
4
+ * @param options - Configuration options
5
+ * @param options.baseUrl - Optional base URL to resolve against (defaults to window.location.href)
6
+ * @param options.basePath - If provided, combines with baseUrl or window.location.origin before resolving
7
+ * @returns The absolute URL, or the original URL if it's already absolute or invalid
3
8
  */
4
- export declare const makeUrlAbsolute: (url?: string, baseUrl?: string) => string | undefined;
9
+ export declare const makeUrlAbsolute: (url: string, { baseUrl, basePath, }?: {
10
+ baseUrl?: string;
11
+ basePath?: string;
12
+ }) => string;
5
13
  //# sourceMappingURL=make-url-absolute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"make-url-absolute.d.ts","sourceRoot":"","sources":["../../src/url/make-url-absolute.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,eAAe,SAAU,MAAM,YAAY,MAAM,uBAiB7D,CAAA"}
1
+ {"version":3,"file":"make-url-absolute.d.ts","sourceRoot":"","sources":["../../src/url/make-url-absolute.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,QACrB,MAAM,2BAMR;IACD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,KACA,MA6BF,CAAA"}
@@ -1,11 +1,28 @@
1
- const makeUrlAbsolute = (url, baseUrl) => {
2
- if (!url || url.startsWith("http://") || url.startsWith("https://") || typeof window === "undefined" && !baseUrl) {
1
+ import { combineUrlAndPath } from "../url/merge-urls.js";
2
+ const makeUrlAbsolute = (url, {
3
+ /** Optional base URL to resolve against (defaults to window.location.href) */
4
+ baseUrl,
5
+ /** If we have a basePath then we resolve against window.location.origin + basePath */
6
+ basePath
7
+ } = {}) => {
8
+ if (typeof window === "undefined" && !baseUrl) {
9
+ return url;
10
+ }
11
+ try {
12
+ new URL(url);
13
+ return url;
14
+ } catch {
15
+ }
16
+ try {
17
+ let base = baseUrl || window.location.href;
18
+ if (basePath) {
19
+ const origin = baseUrl ? new URL(baseUrl).origin : window.location.origin;
20
+ base = combineUrlAndPath(origin, basePath + "/");
21
+ }
22
+ return new URL(url, base).toString();
23
+ } catch {
3
24
  return url;
4
25
  }
5
- const base = baseUrl || window.location.href;
6
- const cleanBaseUrl = base.split("?")[0]?.split("#")[0];
7
- const normalizedBaseUrl = cleanBaseUrl?.endsWith("/") ? cleanBaseUrl : cleanBaseUrl?.substring(0, cleanBaseUrl?.lastIndexOf("/") + 1);
8
- return new URL(url, normalizedBaseUrl).toString();
9
26
  };
10
27
  export {
11
28
  makeUrlAbsolute
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/url/make-url-absolute.ts"],
4
- "sourcesContent": ["/**\n * Pass an URL or a relative URL and get an absolute URL\n */\nexport const makeUrlAbsolute = (url?: string, baseUrl?: string) => {\n if (!url || url.startsWith('http://') || url.startsWith('https://') || (typeof window === 'undefined' && !baseUrl)) {\n return url\n }\n\n const base = baseUrl || window.location.href\n\n // Remove any query parameters or hash from the base URL\n const cleanBaseUrl = base.split('?')[0]?.split('#')[0]\n\n // For base URLs with a path component, we want to remove the last path segment\n // if it doesn't end with a slash\n const normalizedBaseUrl = cleanBaseUrl?.endsWith('/')\n ? cleanBaseUrl\n : cleanBaseUrl?.substring(0, cleanBaseUrl?.lastIndexOf('/') + 1)\n\n return new URL(url, normalizedBaseUrl).toString()\n}\n"],
5
- "mappings": "AAGO,MAAM,kBAAkB,CAAC,KAAc,YAAqB;AACjE,MAAI,CAAC,OAAO,IAAI,WAAW,SAAS,KAAK,IAAI,WAAW,UAAU,KAAM,OAAO,WAAW,eAAe,CAAC,SAAU;AAClH,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,WAAW,OAAO,SAAS;AAGxC,QAAM,eAAe,KAAK,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC;AAIrD,QAAM,oBAAoB,cAAc,SAAS,GAAG,IAChD,eACA,cAAc,UAAU,GAAG,cAAc,YAAY,GAAG,IAAI,CAAC;AAEjE,SAAO,IAAI,IAAI,KAAK,iBAAiB,EAAE,SAAS;AAClD;",
4
+ "sourcesContent": ["import { combineUrlAndPath } from '@/url/merge-urls'\n\n/**\n * Converts a relative URL to an absolute URL using the provided base URL or current window location.\n * @param url - The URL to make absolute\n * @param options - Configuration options\n * @param options.baseUrl - Optional base URL to resolve against (defaults to window.location.href)\n * @param options.basePath - If provided, combines with baseUrl or window.location.origin before resolving\n * @returns The absolute URL, or the original URL if it's already absolute or invalid\n */\nexport const makeUrlAbsolute = (\n url: string,\n {\n /** Optional base URL to resolve against (defaults to window.location.href) */\n baseUrl,\n /** If we have a basePath then we resolve against window.location.origin + basePath */\n basePath,\n }: {\n baseUrl?: string\n basePath?: string\n } = {},\n): string => {\n // If no base URL provided and we're not in a browser environment, return as-is\n if (typeof window === 'undefined' && !baseUrl) {\n return url\n }\n\n try {\n // If we can create a URL object without a base, it's already absolute\n new URL(url)\n return url\n } catch {\n // URL is relative, proceed with resolution\n }\n\n // Use URL constructor which handles path normalization automatically\n try {\n let base = baseUrl || window.location.href\n\n // If basePath is provided, combine it with the base URL\n if (basePath) {\n const origin = baseUrl ? new URL(baseUrl).origin : window.location.origin\n base = combineUrlAndPath(origin, basePath + '/')\n }\n\n return new URL(url, base).toString()\n } catch {\n // If URL construction fails, return the original URL\n return url\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,yBAAyB;AAU3B,MAAM,kBAAkB,CAC7B,KACA;AAAA;AAAA,EAEE;AAAA;AAAA,EAEA;AACF,IAGI,CAAC,MACM;AAEX,MAAI,OAAO,WAAW,eAAe,CAAC,SAAS;AAC7C,WAAO;AAAA,EACT;AAEA,MAAI;AAEF,QAAI,IAAI,GAAG;AACX,WAAO;AAAA,EACT,QAAQ;AAAA,EAER;AAGA,MAAI;AACF,QAAI,OAAO,WAAW,OAAO,SAAS;AAGtC,QAAI,UAAU;AACZ,YAAM,SAAS,UAAU,IAAI,IAAI,OAAO,EAAE,SAAS,OAAO,SAAS;AACnE,aAAO,kBAAkB,QAAQ,WAAW,GAAG;AAAA,IACjD;AAEA,WAAO,IAAI,IAAI,KAAK,IAAI,EAAE,SAAS;AAAA,EACrC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "helpers",
15
15
  "js"
16
16
  ],
17
- "version": "0.0.6",
17
+ "version": "0.0.8",
18
18
  "engines": {
19
19
  "node": ">=20"
20
20
  },
@@ -78,9 +78,9 @@
78
78
  ],
79
79
  "module": "dist/index.js",
80
80
  "devDependencies": {
81
- "vite": "5.4.19",
82
- "vitest": "^1.6.1",
83
- "@scalar/build-tooling": "0.2.4"
81
+ "vite": "6.1.6",
82
+ "vitest": "^3.2.4",
83
+ "@scalar/build-tooling": "0.2.6"
84
84
  },
85
85
  "scripts": {
86
86
  "build": "scalar-build-esbuild",