@scalar/json-magic 0.12.2 → 0.12.4
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 +15 -0
- package/dist/bundle/bundle.js +476 -250
- package/dist/bundle/index.js +1 -6
- package/dist/bundle/plugins/browser.js +4 -9
- package/dist/bundle/plugins/fetch-urls/index.js +76 -49
- package/dist/bundle/plugins/node.js +5 -11
- package/dist/bundle/plugins/parse-json/index.js +30 -23
- package/dist/bundle/plugins/parse-yaml/index.js +31 -24
- package/dist/bundle/plugins/read-files/index.js +50 -29
- package/dist/bundle/value-generator.js +118 -49
- package/dist/dereference/dereference.js +66 -36
- package/dist/dereference/index.js +1 -5
- package/dist/diff/apply.js +69 -36
- package/dist/diff/diff.js +68 -32
- package/dist/diff/index.js +4 -9
- package/dist/diff/merge.js +122 -60
- package/dist/diff/trie.js +100 -77
- package/dist/diff/utils.js +96 -41
- package/dist/helpers/convert-to-local-ref.js +30 -23
- package/dist/helpers/escape-json-pointer.js +7 -6
- package/dist/helpers/get-schemas.js +59 -32
- package/dist/helpers/get-segments-from-path.js +13 -9
- package/dist/helpers/get-value-by-path.js +38 -22
- package/dist/helpers/is-file-path.js +19 -9
- package/dist/helpers/is-http-url.js +20 -11
- package/dist/helpers/is-json-object.js +29 -15
- package/dist/helpers/is-yaml.js +17 -6
- package/dist/helpers/json-path-utils.js +30 -15
- package/dist/helpers/normalize.js +27 -26
- package/dist/helpers/resolve-reference-path.js +28 -16
- package/dist/helpers/set-value-at-path.js +72 -26
- package/dist/helpers/to-relative-path.js +40 -28
- package/dist/helpers/unescape-json-pointer.js +8 -6
- package/dist/magic-proxy/index.js +1 -6
- package/dist/magic-proxy/proxy.js +245 -186
- package/dist/types.js +1 -1
- package/package.json +5 -7
- package/dist/bundle/bundle.js.map +0 -7
- package/dist/bundle/index.js.map +0 -7
- package/dist/bundle/plugins/browser.js.map +0 -7
- package/dist/bundle/plugins/fetch-urls/index.js.map +0 -7
- package/dist/bundle/plugins/node.js.map +0 -7
- package/dist/bundle/plugins/parse-json/index.js.map +0 -7
- package/dist/bundle/plugins/parse-yaml/index.js.map +0 -7
- package/dist/bundle/plugins/read-files/index.js.map +0 -7
- package/dist/bundle/value-generator.js.map +0 -7
- package/dist/dereference/dereference.js.map +0 -7
- package/dist/dereference/index.js.map +0 -7
- package/dist/diff/apply.js.map +0 -7
- package/dist/diff/diff.js.map +0 -7
- package/dist/diff/index.js.map +0 -7
- package/dist/diff/merge.js.map +0 -7
- package/dist/diff/trie.js.map +0 -7
- package/dist/diff/utils.js.map +0 -7
- package/dist/helpers/convert-to-local-ref.js.map +0 -7
- package/dist/helpers/escape-json-pointer.js.map +0 -7
- package/dist/helpers/get-schemas.js.map +0 -7
- package/dist/helpers/get-segments-from-path.js.map +0 -7
- package/dist/helpers/get-value-by-path.js.map +0 -7
- package/dist/helpers/is-file-path.js.map +0 -7
- package/dist/helpers/is-http-url.js.map +0 -7
- package/dist/helpers/is-json-object.js.map +0 -7
- package/dist/helpers/is-yaml.js.map +0 -7
- package/dist/helpers/json-path-utils.js.map +0 -7
- package/dist/helpers/normalize.js.map +0 -7
- package/dist/helpers/resolve-reference-path.js.map +0 -7
- package/dist/helpers/set-value-at-path.js.map +0 -7
- package/dist/helpers/to-relative-path.js.map +0 -7
- package/dist/helpers/unescape-json-pointer.js.map +0 -7
- package/dist/magic-proxy/index.js.map +0 -7
- package/dist/magic-proxy/proxy.js.map +0 -7
- package/dist/types.js.map +0 -7
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/bundle/plugins/read-files/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { LoaderPlugin, ResolveResult } from '@/bundle'\nimport { isFilePath } from '@/helpers/is-file-path'\nimport { normalize } from '@/helpers/normalize'\n\n/**\n * Reads and normalizes data from a local file\n * @param path - The file path to read from\n * @returns A promise that resolves to either the normalized data or an error result\n * @example\n * ```ts\n * const result = await readFile('./schemas/user.json')\n * if (result.ok) {\n * console.log(result.data) // The normalized data\n * } else {\n * console.log('Failed to read file')\n * }\n * ```\n */\nexport async function readFile(path: string): Promise<ResolveResult> {\n const fs = typeof window === 'undefined' ? await import('node:fs/promises') : undefined\n\n if (fs === undefined) {\n throw 'Can not use readFiles plugin outside of a node environment'\n }\n\n try {\n const fileContents = await fs.readFile(path, { encoding: 'utf-8' })\n\n return {\n ok: true,\n data: normalize(fileContents),\n raw: fileContents,\n }\n } catch {\n return {\n ok: false,\n }\n }\n}\n\n/**\n * Creates a plugin for handling local file references.\n * This plugin validates and reads data from local filesystem paths.\n *\n * @returns A plugin object with validate and exec functions\n * @example\n * const filePlugin = readFiles()\n * if (filePlugin.validate('./local-schema.json')) {\n * const result = await filePlugin.exec('./local-schema.json')\n * }\n */\nexport function readFiles(): LoaderPlugin {\n return {\n type: 'loader',\n validate: isFilePath,\n exec: readFile,\n }\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAgB1B,eAAsB,SAAS,MAAsC;AACnE,QAAM,KAAK,OAAO,WAAW,cAAc,MAAM,OAAO,kBAAkB,IAAI;AAE9E,MAAI,OAAO,QAAW;AACpB,UAAM;AAAA,EACR;AAEA,MAAI;AACF,UAAM,eAAe,MAAM,GAAG,SAAS,MAAM,EAAE,UAAU,QAAQ,CAAC;AAElE,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,UAAU,YAAY;AAAA,MAC5B,KAAK;AAAA,IACP;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,IAAI;AAAA,IACN;AAAA,EACF;AACF;AAaO,SAAS,YAA0B;AACxC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/bundle/value-generator.ts"],
|
|
4
|
-
"sourcesContent": ["import { generateHash } from '@scalar/helpers/string/generate-hash'\n\n/**\n * Generates a short hash from a string value using xxhash.\n *\n * This function is used to create unique identifiers for external references\n * while keeping the hash length manageable. It uses xxhash-wasm instead of\n * crypto.subtle because crypto.subtle is only available in secure contexts (HTTPS) or on localhost.\n * Returns the first 7 characters of the hash string.\n * If the hash would be all numbers, it ensures at least one letter is included.\n *\n * @param value - The string to hash\n * @returns A Promise that resolves to a 7-character hexadecimal hash with at least one letter\n * @example\n * // Returns \"2ae91d7\"\n * getHash(\"https://example.com/schema.json\")\n */\nexport function getHash(value: string): string {\n // Hash the data using xxhash\n const hashHex = generateHash(value)\n\n // Return first 7 characters of the hash, ensuring at least one letter\n const hash = hashHex.substring(0, 7)\n return hash.match(/^\\d+$/) ? 'a' + hash.substring(1) : hash\n}\n\n/**\n * Generates a unique compressed value for a string, handling collisions by recursively compressing\n * until a unique value is found. This is used to create unique identifiers for external\n * references in the bundled OpenAPI document.\n *\n * @param compress - Function that generates a compressed value from a string\n * @param value - The original string value to compress\n * @param compressedToValue - Object mapping compressed values to their original values\n * @param prevCompressedValue - Optional previous compressed value to use as input for generating a new value\n * @param depth - Current recursion depth to prevent infinite loops\n * @returns A unique compressed value that doesn't conflict with existing values\n *\n * @example\n * const valueMap = {}\n * // First call generates compressed value for \"example.com/schema.json\"\n * const value1 = await generateUniqueValue(compress, \"example.com/schema.json\", valueMap)\n * // Returns something like \"2ae91d7\"\n *\n * // Second call with same value returns same compressed value\n * const value2 = await generateUniqueValue(compress, \"example.com/schema.json\", valueMap)\n * // Returns same value as value1\n *\n * // Call with different value generates new unique compressed value\n * const value3 = await generateUniqueValue(compress, \"example.com/other.json\", valueMap)\n * // Returns different value like \"3bf82e9\"\n */\nexport async function generateUniqueValue(\n compress: (value: string) => Promise<string> | string,\n value: string,\n compressedToValue: Record<string, string>,\n prevCompressedValue?: string,\n depth = 0,\n) {\n // Prevent infinite recursion by limiting depth\n const MAX_DEPTH = 100\n\n if (depth >= MAX_DEPTH) {\n throw 'Can not generate unique compressed values'\n }\n\n // Compress the value, using previous compressed value if provided\n const compressedValue = await compress(prevCompressedValue ?? value)\n\n // Handle collision by recursively trying with compressed value as input\n if (compressedToValue[compressedValue] !== undefined && compressedToValue[compressedValue] !== value) {\n return generateUniqueValue(compress, value, compressedToValue, compressedValue, depth + 1)\n }\n\n // Store mapping and return unique compressed value\n compressedToValue[compressedValue] = value\n return compressedValue\n}\n\n/**\n * Factory function that creates a value generator with caching capabilities.\n * The generator maintains a bidirectional mapping between original values and their compressed forms.\n *\n * @param compress - Function that generates a compressed value from a string\n * @param compressedToValue - Initial mapping of compressed values to their original values\n * @returns An object with a generate method that produces unique compressed values\n *\n * @example\n * const compress = (value) => value.substring(0, 6) // Simple compression example\n * const initialMap = { 'abc123': 'example.com/schema.json' }\n * const generator = uniqueValueGeneratorFactory(compress, initialMap)\n *\n * // Generate compressed value for new string\n * const compressed = await generator.generate('example.com/other.json')\n * // Returns something like 'example'\n *\n * // Generate compressed value for existing string\n * const cached = await generator.generate('example.com/schema.json')\n * // Returns 'abc123' from cache\n */\nexport const uniqueValueGeneratorFactory = (\n compress: (value: string) => Promise<string> | string,\n compressedToValue: Record<string, string>,\n) => {\n // Create a reverse mapping from original values to their compressed forms\n const valueToCompressed = Object.fromEntries(Object.entries(compressedToValue).map(([key, value]) => [value, key]))\n\n return {\n /**\n * Generates a unique compressed value for the given input string.\n * First checks if a compressed value already exists in the cache.\n * If not, generates a new unique compressed value and stores it in the cache.\n *\n * @param value - The original string value to compress\n * @returns A Promise that resolves to the compressed string value\n *\n * @example\n * const generator = uniqueValueGeneratorFactory(compress, {})\n * const compressed = await generator.generate('example.com/schema.json')\n * // Returns a unique compressed value like 'example'\n */\n generate: async (value: string) => {\n // Check if we already have a compressed value for this input\n const cache = valueToCompressed[value]\n if (cache) {\n return cache\n }\n\n // Generate a new unique compressed value\n const generatedValue = await generateUniqueValue(compress, value, compressedToValue)\n\n // Ensure the generated string contains at least one non-numeric character\n // This prevents the `setValueAtPath` function from interpreting the value as an array index\n // by forcing it to be treated as an object property name\n const compressedValue = generatedValue.match(/^\\d+$/) ? `a${generatedValue}` : generatedValue\n\n // Store the new mapping in our cache\n valueToCompressed[value] = compressedValue\n\n return compressedValue\n },\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAiBtB,SAAS,QAAQ,OAAuB;AAE7C,QAAM,UAAU,aAAa,KAAK;AAGlC,QAAM,OAAO,QAAQ,UAAU,GAAG,CAAC;AACnC,SAAO,KAAK,MAAM,OAAO,IAAI,MAAM,KAAK,UAAU,CAAC,IAAI;AACzD;AA4BA,eAAsB,oBACpB,UACA,OACA,mBACA,qBACA,QAAQ,GACR;AAEA,QAAM,YAAY;AAElB,MAAI,SAAS,WAAW;AACtB,UAAM;AAAA,EACR;AAGA,QAAM,kBAAkB,MAAM,SAAS,uBAAuB,KAAK;AAGnE,MAAI,kBAAkB,eAAe,MAAM,UAAa,kBAAkB,eAAe,MAAM,OAAO;AACpG,WAAO,oBAAoB,UAAU,OAAO,mBAAmB,iBAAiB,QAAQ,CAAC;AAAA,EAC3F;AAGA,oBAAkB,eAAe,IAAI;AACrC,SAAO;AACT;AAuBO,MAAM,8BAA8B,CACzC,UACA,sBACG;AAEH,QAAM,oBAAoB,OAAO,YAAY,OAAO,QAAQ,iBAAiB,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;AAElH,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcL,UAAU,OAAO,UAAkB;AAEjC,YAAM,QAAQ,kBAAkB,KAAK;AACrC,UAAI,OAAO;AACT,eAAO;AAAA,MACT;AAGA,YAAM,iBAAiB,MAAM,oBAAoB,UAAU,OAAO,iBAAiB;AAKnF,YAAM,kBAAkB,eAAe,MAAM,OAAO,IAAI,IAAI,cAAc,KAAK;AAG/E,wBAAkB,KAAK,IAAI;AAE3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/dereference/dereference.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Plugin, bundle } from '@/bundle'\nimport { fetchUrls } from '@/bundle/plugins/fetch-urls'\nimport { createMagicProxy } from '@/magic-proxy'\nimport type { UnknownObject } from '@/types'\n\ntype DereferenceResult =\n | {\n success: true\n data: UnknownObject\n }\n | {\n success: false\n errors: string[]\n }\n\ntype ReturnDereferenceResult<Opt extends { sync?: boolean }> = Opt['sync'] extends true\n ? DereferenceResult\n : Promise<DereferenceResult>\n\n/**\n * Dereferences a JSON object, resolving all $ref pointers.\n *\n * This function can operate synchronously (no remote refs, no async plugins) or asynchronously (with remote refs).\n * If `options.sync` is true, it simply wraps the input in a magic proxy and returns it.\n * Otherwise, it bundles the document, resolving all $refs (including remote ones), and returns a promise.\n *\n * @param input - JSON Schema object to dereference.\n * @param options - Optional settings. If `sync` is true, dereferencing is synchronous. If `plugins` is provided, those plugins are used for resolution instead of the default `fetchUrls()`.\n * @returns A DereferenceResult (or Promise thereof) indicating success and the dereferenced data, or errors.\n *\n * @example\n * // Synchronous dereference (no remote refs)\n * const result = dereference({ openapi: '3.0.0', info: { title: 'My API', version: '1.0.0' } }, { sync: true });\n * if (result.success) {\n * console.log(result.data); // Magic proxy-wrapped document\n * }\n *\n * @example\n * // Asynchronous dereference (with remote refs)\n * dereference({ $ref: 'https://example.com/api.yaml' })\n * .then(result => {\n * if (result.success) {\n * console.log(result.data); // Fully dereferenced document\n * } else {\n * console.error(result.errors);\n * }\n * });\n *\n * @example\n * // Asynchronous dereference (with custom loader plugin)\n * const plugin = { type: 'loader', validate: (v) => v.startsWith('workspace:'), exec: (v) => resolve(v) };\n * const result = await dereference({ $ref: 'workspace:my-schema' }, { plugins: [plugin] });\n */\nexport const dereference = <Opts extends { sync?: boolean; plugins?: Plugin[] }>(\n input: UnknownObject,\n options?: Opts,\n): ReturnDereferenceResult<Opts> => {\n if (options?.sync) {\n return {\n success: true,\n data: createMagicProxy(input),\n } as ReturnDereferenceResult<Opts>\n }\n\n const errors: string[] = []\n const plugins = options?.plugins || [fetchUrls()]\n\n return bundle(input, {\n plugins,\n treeShake: false,\n urlMap: true,\n hooks: {\n onResolveError(node) {\n errors.push(`Failed to resolve ${node.$ref}`)\n },\n },\n }).then((result) => {\n if (errors.length > 0) {\n return {\n success: false,\n errors,\n }\n }\n\n return {\n success: true,\n data: createMagicProxy(result as UnknownObject),\n }\n }) as ReturnDereferenceResult<Opts>\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAsB,cAAc;AACpC,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AAmD1B,MAAM,cAAc,CACzB,OACA,YACkC;AAClC,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,iBAAiB,KAAK;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAU,SAAS,WAAW,CAAC,UAAU,CAAC;AAEhD,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,MACL,eAAe,MAAM;AACnB,eAAO,KAAK,qBAAqB,KAAK,IAAI,EAAE;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAC,EAAE,KAAK,CAAC,WAAW;AAClB,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,iBAAiB,MAAuB;AAAA,IAChD;AAAA,EACF,CAAC;AACH;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/diff/apply.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/diff/apply.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Difference } from '@/diff/diff'\n\nexport class InvalidChangesDetectedError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidChangesDetectedError'\n }\n}\n\n/**\n * Applies a set of differences to a document object.\n * The function traverses the document structure following the paths specified in the differences\n * and applies the corresponding changes (add, update, or delete) at each location.\n *\n * @param document - The original document to apply changes to\n * @param diff - Array of differences to apply, each containing a path and change type\n * @returns The modified document with all changes applied\n *\n * @example\n * const original = {\n * paths: {\n * '/users': {\n * get: { responses: { '200': { description: 'OK' } } }\n * }\n * }\n * }\n *\n * const changes = [\n * {\n * path: ['paths', '/users', 'get', 'responses', '200', 'content'],\n * type: 'add',\n * changes: { 'application/json': { schema: { type: 'object' } } }\n * }\n * ]\n *\n * const updated = apply(original, changes)\n * // Result: original document with content added to the 200 response\n */\nexport const apply = <T extends Record<string, unknown>>(\n document: Record<string, unknown>,\n diff: Difference<T>[],\n): T => {\n // Traverse the object and apply the change\n const applyChange = (current: any, path: string[], d: Difference<T>, depth = 0) => {\n if (path[depth] === undefined) {\n throw new InvalidChangesDetectedError(\n `Process aborted. Path ${path.join('.')} at depth ${depth} is undefined, check diff object`,\n )\n }\n\n // We reach where we want to be, now we can apply changes\n if (depth >= path.length - 1) {\n if (d.type === 'add' || d.type === 'update') {\n current[path[depth]] = d.changes\n } else {\n // For arrays we don't use delete operator since it will leave blank spots and not actually remove the element\n if (Array.isArray(current)) {\n current.splice(Number.parseInt(path[depth]), 1)\n } else {\n delete current[path[depth]]\n }\n }\n return\n }\n\n // Throw an error\n // This scenario should not happen\n // 1- if we are adding a new entry, the diff should only give us the higher level diff\n // 2- if we are updating/deleting an entry, the path to that entry should exists\n if (current[path[depth]] === undefined || typeof current[path[depth]] !== 'object') {\n throw new InvalidChangesDetectedError('Process aborted, check diff object')\n }\n applyChange(current[path[depth]], path, d, depth + 1)\n }\n\n for (const d of diff) {\n applyChange(document, d.path, d)\n }\n\n // It is safe to cast here because this function mutates the input document\n // to match the target type T as described by the diff changeset.\n return document as T\n}\n"],
|
|
5
|
-
"mappings": "AAEO,MAAM,oCAAoC,MAAM;AAAA,EACrD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AA+BO,MAAM,QAAQ,CACnB,UACA,SACM;AAEN,QAAM,cAAc,CAAC,SAAc,MAAgB,GAAkB,QAAQ,MAAM;AACjF,QAAI,KAAK,KAAK,MAAM,QAAW;AAC7B,YAAM,IAAI;AAAA,QACR,yBAAyB,KAAK,KAAK,GAAG,CAAC,aAAa,KAAK;AAAA,MAC3D;AAAA,IACF;AAGA,QAAI,SAAS,KAAK,SAAS,GAAG;AAC5B,UAAI,EAAE,SAAS,SAAS,EAAE,SAAS,UAAU;AAC3C,gBAAQ,KAAK,KAAK,CAAC,IAAI,EAAE;AAAA,MAC3B,OAAO;AAEL,YAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,kBAAQ,OAAO,OAAO,SAAS,KAAK,KAAK,CAAC,GAAG,CAAC;AAAA,QAChD,OAAO;AACL,iBAAO,QAAQ,KAAK,KAAK,CAAC;AAAA,QAC5B;AAAA,MACF;AACA;AAAA,IACF;AAMA,QAAI,QAAQ,KAAK,KAAK,CAAC,MAAM,UAAa,OAAO,QAAQ,KAAK,KAAK,CAAC,MAAM,UAAU;AAClF,YAAM,IAAI,4BAA4B,oCAAoC;AAAA,IAC5E;AACA,gBAAY,QAAQ,KAAK,KAAK,CAAC,GAAG,MAAM,GAAG,QAAQ,CAAC;AAAA,EACtD;AAEA,aAAW,KAAK,MAAM;AACpB,gBAAY,UAAU,EAAE,MAAM,CAAC;AAAA,EACjC;AAIA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/diff/diff.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/diff/diff.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Represents the possible types of changes that can be made to a document.\n * - 'add': A new property is added\n * - 'update': An existing property's value is changed\n * - 'delete': A property is removed\n */\ntype ChangeType = 'add' | 'update' | 'delete'\n\n/**\n * Represents a single difference between two documents.\n * @property path - Array of strings representing the path to the changed property\n * @property changes - The new value for the property (for add/update) or the old value (for delete)\n * @property type - The type of change that occurred\n */\nexport type Difference<_T> = { path: string[]; changes: any; type: ChangeType }\n\n/**\n * Get the difference between two objects.\n *\n * This function performs a breadth-first comparison between two objects and returns\n * a list of operations needed to transform the first object into the second.\n *\n * @param doc1 - The source object to compare from\n * @param doc2 - The target object to compare to\n * @returns A list of operations (add/update/delete) with their paths and changes\n *\n * @example\n * // Compare two simple objects\n * const original = { name: 'John', age: 30 }\n * const updated = { name: 'John', age: 31, city: 'New York' }\n * const differences = diff(original, updated)\n * // Returns:\n * // [\n * // { path: ['age'], changes: 31, type: 'update' },\n * // { path: ['city'], changes: 'New York', type: 'add' }\n * // ]\n *\n * @example\n * // Compare nested objects\n * const original = {\n * user: { name: 'John', settings: { theme: 'light' } }\n * }\n * const updated = {\n * user: { name: 'John', settings: { theme: 'dark' } }\n * }\n * const differences = diff(original, updated)\n * // Returns:\n * // [\n * // { path: ['user', 'settings', 'theme'], changes: 'dark', type: 'update' }\n * // ]\n */\nexport const diff = <T extends Record<string, unknown>>(doc1: Record<string, unknown>, doc2: T) => {\n const diff: Difference<T>[] = []\n\n const bfs = (el1: unknown, el2: unknown, prefix = []) => {\n // If the types are different, we know that the property has been added, deleted or updated\n if (typeof el1 !== typeof el2) {\n if (typeof el1 === 'undefined') {\n diff.push({ path: prefix, changes: el2, type: 'add' })\n return\n }\n\n if (typeof el2 === 'undefined') {\n diff.push({ path: prefix, changes: el1, type: 'delete' })\n return\n }\n\n diff.push({ path: prefix, changes: el2, type: 'update' })\n return\n }\n\n // We now can assume that el1 and el2 are of the same type\n\n // For nested objects, we need to recursively check the properties\n if (typeof el1 === 'object' && typeof el2 === 'object' && el1 !== null && el2 !== null) {\n const keys = new Set([...Object.keys(el1), ...Object.keys(el2)])\n\n for (const key of keys) {\n bfs(el1[key], el2[key], [...prefix, key])\n }\n return\n }\n\n // For primitives, we can just compare the values\n if (el1 !== el2) {\n diff.push({ path: prefix, changes: el2, type: 'update' })\n }\n }\n\n // Run breadth-first search\n bfs(doc1, doc2)\n return diff\n}\n"],
|
|
5
|
-
"mappings": "AAmDO,MAAM,OAAO,CAAoC,MAA+B,SAAY;AACjG,QAAMA,QAAwB,CAAC;AAE/B,QAAM,MAAM,CAAC,KAAc,KAAc,SAAS,CAAC,MAAM;AAEvD,QAAI,OAAO,QAAQ,OAAO,KAAK;AAC7B,UAAI,OAAO,QAAQ,aAAa;AAC9B,QAAAA,MAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,KAAK,MAAM,MAAM,CAAC;AACrD;AAAA,MACF;AAEA,UAAI,OAAO,QAAQ,aAAa;AAC9B,QAAAA,MAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,KAAK,MAAM,SAAS,CAAC;AACxD;AAAA,MACF;AAEA,MAAAA,MAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,KAAK,MAAM,SAAS,CAAC;AACxD;AAAA,IACF;AAKA,QAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,YAAY,QAAQ,QAAQ,QAAQ,MAAM;AACtF,YAAM,OAAO,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,GAAG,GAAG,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC;AAE/D,iBAAW,OAAO,MAAM;AACtB,YAAI,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC;AAAA,MAC1C;AACA;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK;AACf,MAAAA,MAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,KAAK,MAAM,SAAS,CAAC;AAAA,IAC1D;AAAA,EACF;AAGA,MAAI,MAAM,IAAI;AACd,SAAOA;AACT;",
|
|
6
|
-
"names": ["diff"]
|
|
7
|
-
}
|
package/dist/diff/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/diff/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { apply } from '@/diff/apply'\nimport { type Difference, diff } from '@/diff/diff'\nimport { merge } from '@/diff/merge'\n\nexport { diff, apply, merge, type Difference }\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa;AACtB,SAA0B,YAAY;AACtC,SAAS,aAAa;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/diff/merge.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/diff/merge.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Difference } from '@/diff/diff'\nimport { Trie } from '@/diff/trie'\nimport { isArrayEqual, isKeyCollisions, mergeObjects } from '@/diff/utils'\n\n/**\n * Merges two sets of differences from the same document and resolves conflicts.\n * This function combines changes from two diff lists while handling potential conflicts\n * that arise when both diffs modify the same paths. It uses a trie data structure for\n * efficient path matching and conflict detection.\n *\n * @param diff1 - First list of differences\n * @param diff2 - Second list of differences\n * @returns Object containing:\n * - diffs: Combined list of non-conflicting differences\n * - conflicts: Array of conflicting difference pairs that need manual resolution\n *\n * @example\n * // Merge two sets of changes to a user profile\n * const diff1 = [\n * { path: ['name'], changes: 'John', type: 'update' },\n * { path: ['age'], changes: 30, type: 'add' }\n * ]\n * const diff2 = [\n * { path: ['name'], changes: 'Johnny', type: 'update' },\n * { path: ['address'], changes: { city: 'NY' }, type: 'add' }\n * ]\n * const { diffs, conflicts } = merge(diff1, diff2)\n * // Returns:\n * // {\n * // diffs: [\n * // { path: ['age'], changes: 30, type: 'add' },\n * // { path: ['address'], changes: { city: 'NY' }, type: 'add' }\n * // ],\n * // conflicts: [\n * // [\n * // [{ path: ['name'], changes: 'John', type: 'update' }],\n * // [{ path: ['name'], changes: 'Johnny', type: 'update' }]\n * // ]\n * // ]\n * // }\n */\nexport const merge = <T>(diff1: Difference<T>[], diff2: Difference<T>[]) => {\n // Here we need to use a trie to optimize searching for a prefix\n // With the naive approach time complexity of the algorithm would be\n // O(n * m)\n // ^ ^\n // n is the length off diff1 | | m length of diff2\n //\n // Assuming that the maximum depth of the nested objects would be constant lets say 0 <= D <= 100\n // we try to optimize for that using the tire data structure.\n // So the new time complexity would be O(n * D) where D is the maximum depth of the nested object\n const trie = new Trie<{ index: number; changes: Difference<T> }>()\n\n // Create the trie\n for (const [index, diff] of diff1.entries()) {\n trie.addPath(diff.path, { index, changes: diff })\n }\n\n const skipDiff1 = new Set<number>()\n const skipDiff2 = new Set<number>()\n\n // Keep related conflicts together for easy A, B pick conflict resolution\n // map key is going to be conflicting index of first diff list where the diff will be\n // a delete operation or an add/update operation with a one to many conflicts\n const conflictsMap1 = new Map<number, [Difference<T>[], Difference<T>[]]>()\n // map key will be the index from the second diff list where the diff will be\n // a delete operation with one to many conflicts\n const conflictsMap2 = new Map<number, [Difference<T>[], Difference<T>[]]>()\n\n for (const [index, diff] of diff2.entries()) {\n trie.findMatch(diff.path, (value) => {\n if (diff.type === 'delete') {\n if (value.changes.type === 'delete') {\n // Keep the highest depth delete operation and skip the other\n if (value.changes.path.length > diff.path.length) {\n skipDiff1.add(value.index)\n } else {\n skipDiff2.add(value.index)\n }\n } else {\n // Take care of updates/add on the same path (we are sure they will be on the\n // same path since the change comes from the same document)\n skipDiff1.add(value.index)\n skipDiff2.add(index)\n\n const conflictEntry = conflictsMap2.get(index)\n\n if (conflictEntry !== undefined) {\n conflictEntry[0].push(value.changes)\n } else {\n conflictsMap2.set(index, [[value.changes], [diff]])\n }\n }\n }\n\n if (diff.type === 'add' || diff.type === 'update') {\n // For add -> add / update -> update operation we try to first see if we can merge this operations\n if (\n isArrayEqual(diff.path, value.changes.path) &&\n value.changes.type !== 'delete' &&\n !isKeyCollisions(diff.changes, value.changes.changes)\n ) {\n skipDiff1.add(value.index)\n // For non primitive values we merge object keys into diff2\n if (typeof diff.changes === 'object') {\n mergeObjects(diff.changes, value.changes.changes)\n }\n return\n }\n\n // add/update -> delete operations always resolve in conflicts\n skipDiff1.add(value.index)\n skipDiff2.add(index)\n\n const conflictEntry = conflictsMap1.get(value.index)\n\n if (conflictEntry !== undefined) {\n conflictEntry[1].push(diff)\n } else {\n conflictsMap1.set(value.index, [[value.changes], [diff]])\n }\n }\n })\n }\n\n const conflicts: [Difference<T>[], Difference<T>[]][] = [...conflictsMap1.values(), ...conflictsMap2.values()]\n\n // Filter all changes that should be skipped because of conflicts\n // or auto conflict resolution\n const diffs: Difference<T>[] = [\n ...diff1.filter((_, index) => !skipDiff1.has(index)),\n ...diff2.filter((_, index) => !skipDiff2.has(index)),\n ]\n\n return { diffs, conflicts }\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,oBAAoB;AAuCrD,MAAM,QAAQ,CAAI,OAAwB,UAA2B;AAU1E,QAAM,OAAO,IAAI,KAAgD;AAGjE,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,SAAK,QAAQ,KAAK,MAAM,EAAE,OAAO,SAAS,KAAK,CAAC;AAAA,EAClD;AAEA,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,YAAY,oBAAI,IAAY;AAKlC,QAAM,gBAAgB,oBAAI,IAAgD;AAG1E,QAAM,gBAAgB,oBAAI,IAAgD;AAE1E,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,SAAK,UAAU,KAAK,MAAM,CAAC,UAAU;AACnC,UAAI,KAAK,SAAS,UAAU;AAC1B,YAAI,MAAM,QAAQ,SAAS,UAAU;AAEnC,cAAI,MAAM,QAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ;AAChD,sBAAU,IAAI,MAAM,KAAK;AAAA,UAC3B,OAAO;AACL,sBAAU,IAAI,MAAM,KAAK;AAAA,UAC3B;AAAA,QACF,OAAO;AAGL,oBAAU,IAAI,MAAM,KAAK;AACzB,oBAAU,IAAI,KAAK;AAEnB,gBAAM,gBAAgB,cAAc,IAAI,KAAK;AAE7C,cAAI,kBAAkB,QAAW;AAC/B,0BAAc,CAAC,EAAE,KAAK,MAAM,OAAO;AAAA,UACrC,OAAO;AACL,0BAAc,IAAI,OAAO,CAAC,CAAC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,SAAS,KAAK,SAAS,UAAU;AAEjD,YACE,aAAa,KAAK,MAAM,MAAM,QAAQ,IAAI,KAC1C,MAAM,QAAQ,SAAS,YACvB,CAAC,gBAAgB,KAAK,SAAS,MAAM,QAAQ,OAAO,GACpD;AACA,oBAAU,IAAI,MAAM,KAAK;AAEzB,cAAI,OAAO,KAAK,YAAY,UAAU;AACpC,yBAAa,KAAK,SAAS,MAAM,QAAQ,OAAO;AAAA,UAClD;AACA;AAAA,QACF;AAGA,kBAAU,IAAI,MAAM,KAAK;AACzB,kBAAU,IAAI,KAAK;AAEnB,cAAM,gBAAgB,cAAc,IAAI,MAAM,KAAK;AAEnD,YAAI,kBAAkB,QAAW;AAC/B,wBAAc,CAAC,EAAE,KAAK,IAAI;AAAA,QAC5B,OAAO;AACL,wBAAc,IAAI,MAAM,OAAO,CAAC,CAAC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,YAAkD,CAAC,GAAG,cAAc,OAAO,GAAG,GAAG,cAAc,OAAO,CAAC;AAI7G,QAAM,QAAyB;AAAA,IAC7B,GAAG,MAAM,OAAO,CAAC,GAAG,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC;AAAA,IACnD,GAAG,MAAM,OAAO,CAAC,GAAG,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC;AAAA,EACrD;AAEA,SAAO,EAAE,OAAO,UAAU;AAC5B;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/diff/trie.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/diff/trie.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Trie data structure\n *\n * Read more: https://en.wikipedia.org/wiki/Trie\n */\n\n/**\n * Represents a node in the trie data structure.\n * Each node can store a value and has a map of child nodes.\n *\n * @template Value - The type of value that can be stored in the node\n */\nexport class TrieNode<Value> {\n constructor(\n public value: Value | null,\n public children: Record<string, TrieNode<Value>>,\n ) {}\n}\n\n/**\n * A trie (prefix tree) data structure implementation.\n * This class provides efficient storage and retrieval of values associated with string paths.\n *\n * @template Value - The type of value to store at each node\n *\n * @example\n * const trie = new Trie<number>()\n * trie.addPath(['a', 'b', 'c'], 1)\n * trie.addPath(['a', 'b', 'd'], 2)\n * trie.findMatch(['a', 'b'], (value) => console.log(value)) // Logs: 1, 2\n */\nexport class Trie<Value> {\n private root: TrieNode<Value>\n constructor() {\n this.root = new TrieNode<Value>(null, {})\n }\n\n /**\n * Adds a value to the trie at the specified path.\n * Creates new nodes as needed to build the path.\n *\n * @param path - Array of strings representing the path to store the value\n * @param value - The value to store at the end of the path\n *\n * @example\n * const trie = new Trie<number>()\n * trie.addPath(['users', 'john', 'age'], 30)\n */\n addPath(path: string[], value: Value) {\n let current = this.root\n for (const dir of path) {\n if (current.children[dir]) {\n current = current.children[dir]\n } else {\n current.children[dir] = new TrieNode<Value>(null, {})\n current = current.children[dir]\n }\n }\n\n current.value = value\n }\n\n /**\n * Finds all matches along a given path in the trie.\n * This method traverses both the exact path and all deeper paths,\n * executing a callback for each matching value found.\n *\n * The search is performed in two phases:\n * 1. Traverse the exact path, checking for matches at each node\n * 2. Perform a depth-first search from the end of the path to find all deeper matches\n *\n * @param path - Array of strings representing the path to search\n * @param callback - Function to execute for each matching value found\n *\n * @example\n * const trie = new Trie<number>()\n * trie.addPath(['a', 'b', 'c'], 1)\n * trie.addPath(['a', 'b', 'd'], 2)\n * trie.findMatch(['a', 'b'], (value) => console.log(value)) // Logs: 1, 2\n */\n findMatch(path: string[], callback: (value: Value) => void) {\n let current = this.root\n\n for (const dir of path) {\n // Note: the last callback wont fire here because it will fire on the dfs\n if (current.value !== null) {\n callback(current.value)\n }\n\n const next = current.children[dir]\n if (!next) {\n return\n }\n\n current = next\n }\n\n const dfs = (current: TrieNode<Value> | undefined) => {\n for (const child of Object.keys(current?.children ?? {})) {\n if (current && Object.hasOwn(current.children, child)) {\n dfs(current?.children[child])\n }\n }\n\n if (current?.value) {\n callback(current.value)\n }\n }\n\n // Dfs for the rest of the path\n dfs(current)\n }\n}\n"],
|
|
5
|
-
"mappings": "AAYO,MAAM,SAAgB;AAAA,EAC3B,YACS,OACA,UACP;AAFO;AACA;AAAA,EACN;AACL;AAcO,MAAM,KAAY;AAAA,EACf;AAAA,EACR,cAAc;AACZ,SAAK,OAAO,IAAI,SAAgB,MAAM,CAAC,CAAC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,QAAQ,MAAgB,OAAc;AACpC,QAAI,UAAU,KAAK;AACnB,eAAW,OAAO,MAAM;AACtB,UAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,kBAAU,QAAQ,SAAS,GAAG;AAAA,MAChC,OAAO;AACL,gBAAQ,SAAS,GAAG,IAAI,IAAI,SAAgB,MAAM,CAAC,CAAC;AACpD,kBAAU,QAAQ,SAAS,GAAG;AAAA,MAChC;AAAA,IACF;AAEA,YAAQ,QAAQ;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,UAAU,MAAgB,UAAkC;AAC1D,QAAI,UAAU,KAAK;AAEnB,eAAW,OAAO,MAAM;AAEtB,UAAI,QAAQ,UAAU,MAAM;AAC1B,iBAAS,QAAQ,KAAK;AAAA,MACxB;AAEA,YAAM,OAAO,QAAQ,SAAS,GAAG;AACjC,UAAI,CAAC,MAAM;AACT;AAAA,MACF;AAEA,gBAAU;AAAA,IACZ;AAEA,UAAM,MAAM,CAACA,aAAyC;AACpD,iBAAW,SAAS,OAAO,KAAKA,UAAS,YAAY,CAAC,CAAC,GAAG;AACxD,YAAIA,YAAW,OAAO,OAAOA,SAAQ,UAAU,KAAK,GAAG;AACrD,cAAIA,UAAS,SAAS,KAAK,CAAC;AAAA,QAC9B;AAAA,MACF;AAEA,UAAIA,UAAS,OAAO;AAClB,iBAASA,SAAQ,KAAK;AAAA,MACxB;AAAA,IACF;AAGA,QAAI,OAAO;AAAA,EACb;AACF;",
|
|
6
|
-
"names": ["current"]
|
|
7
|
-
}
|
package/dist/diff/utils.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/diff/utils.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Deep check for objects for collisions\n * Check primitives if their values are different\n *\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if there is a collision, false otherwise\n *\n * @example\n * // Objects with different values for same key\n * isKeyCollisions({ a: 1 }, { a: 2 }) // true\n *\n * // Objects with different types\n * isKeyCollisions({ a: 1 }, { a: '1' }) // true\n *\n * // Objects with no collisions\n * isKeyCollisions({ a: 1 }, { b: 2 }) // false\n *\n * // Nested objects with collision\n * isKeyCollisions({ a: { b: 1 } }, { a: { b: 2 } }) // true\n */\nexport const isKeyCollisions = (a: unknown, b: unknown) => {\n if (typeof a !== typeof b) {\n return true\n }\n\n if (typeof a === 'object' && typeof b === 'object' && a !== null && b !== null) {\n const keys = new Set([...Object.keys(a), ...Object.keys(b)])\n\n for (const key of keys) {\n if (a[key] !== undefined && b[key] !== undefined) {\n if (isKeyCollisions(a[key], b[key])) {\n return true\n }\n }\n }\n return false\n }\n\n // We handle all primitives here\n return a !== b\n}\n\n/**\n * Deep merges two objects, combining their properties recursively.\n *\n * \u26A0\uFE0F Note: This operation assumes there are no key collisions between the objects.\n * Use isKeyCollisions() to check for collisions before merging.\n *\n * @param a - Target object to merge into\n * @param b - Source object to merge from\n * @returns The merged object (mutates and returns a)\n *\n * @example\n * // Simple merge\n * const a = { name: 'John' }\n * const b = { age: 30 }\n * mergeObjects(a, b) // { name: 'John', age: 30 }\n *\n * // Nested merge\n * const a = { user: { name: 'John' } }\n * const b = { user: { age: 30 } }\n * mergeObjects(a, b) // { user: { name: 'John', age: 30 } }\n */\nexport const mergeObjects = (a: Record<string, unknown>, b: Record<string, unknown>): Record<string, unknown> => {\n for (const key in b) {\n if (!(key in a)) {\n a[key] = b[key]\n } else {\n const aValue = a[key]\n const bValue = b[key]\n\n if (typeof aValue === 'object' && aValue !== null && typeof bValue === 'object' && bValue !== null) {\n a[key] = mergeObjects(aValue as Record<string, unknown>, bValue as Record<string, unknown>)\n }\n }\n }\n\n return a\n}\n\n/**\n * Checks if two arrays have the same elements in the same order.\n *\n * @param a - First array to compare\n * @param b - Second array to compare\n * @returns True if arrays have same length and elements, false otherwise\n *\n * @example\n * // Arrays with same elements\n * isArrayEqual([1, 2, 3], [1, 2, 3]) // true\n *\n * // Arrays with different elements\n * isArrayEqual([1, 2, 3], [1, 2, 4]) // false\n *\n * // Arrays with different lengths\n * isArrayEqual([1, 2], [1, 2, 3]) // false\n */\nexport const isArrayEqual = <T>(a: T[], b: T[]) => {\n if (a.length !== b.length) {\n return false\n }\n\n for (let i = 0; i <= a.length; ++i) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n\n return true\n}\n"],
|
|
5
|
-
"mappings": "AAqBO,MAAM,kBAAkB,CAAC,GAAY,MAAe;AACzD,MAAI,OAAO,MAAM,OAAO,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM;AAC9E,UAAM,OAAO,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC;AAE3D,eAAW,OAAO,MAAM;AACtB,UAAI,EAAE,GAAG,MAAM,UAAa,EAAE,GAAG,MAAM,QAAW;AAChD,YAAI,gBAAgB,EAAE,GAAG,GAAG,EAAE,GAAG,CAAC,GAAG;AACnC,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,SAAO,MAAM;AACf;AAuBO,MAAM,eAAe,CAAC,GAA4B,MAAwD;AAC/G,aAAW,OAAO,GAAG;AACnB,QAAI,EAAE,OAAO,IAAI;AACf,QAAE,GAAG,IAAI,EAAE,GAAG;AAAA,IAChB,OAAO;AACL,YAAM,SAAS,EAAE,GAAG;AACpB,YAAM,SAAS,EAAE,GAAG;AAEpB,UAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,OAAO,WAAW,YAAY,WAAW,MAAM;AAClG,UAAE,GAAG,IAAI,aAAa,QAAmC,MAAiC;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAmBO,MAAM,eAAe,CAAI,GAAQ,MAAW;AACjD,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,WAAO;AAAA,EACT;AAEA,WAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,EAAE,GAAG;AAClC,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG;AACjB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/convert-to-local-ref.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Translates a JSON Reference ($ref) to a local object path within the root schema.\n *\n * @param ref - The JSON Reference string (e.g., \"#/foo/bar\", \"other.json#/baz\", \"other.json#anchor\")\n * @param currentContext - The current base context (usually the $id of the current schema or parent)\n * @param schemas - A map of schema identifiers ($id, $anchor) to their local object paths\n * @returns The local object path as a string, or undefined if the reference cannot be resolved\n */\nexport const convertToLocalRef = (\n ref: string,\n currentContext: string,\n schemas: Map<string, string>,\n): string | undefined => {\n // Split the reference into base URL and path/anchor (e.g., \"foo.json#/bar\" => [\"foo.json\", \"/bar\"])\n const [baseUrl, pathOrAnchor] = ref.split('#', 2)\n\n if (baseUrl) {\n if (!schemas.has(baseUrl)) {\n return undefined\n }\n\n if (!pathOrAnchor) {\n return schemas.get(baseUrl)\n }\n\n // If the pathOrAnchor is a JSON pointer, we need to append it to the baseUrl\n if (pathOrAnchor.startsWith('/')) {\n return `${schemas.get(baseUrl)}${pathOrAnchor}`\n }\n\n // If the pathOrAnchor is an anchor, we need to return the anchor\n return schemas.get(`${baseUrl}#${pathOrAnchor}`)\n }\n\n if (pathOrAnchor) {\n if (pathOrAnchor.startsWith('/')) {\n return pathOrAnchor.slice(1)\n }\n return schemas.get(`${currentContext}#${pathOrAnchor}`)\n }\n\n return undefined\n}\n"],
|
|
5
|
-
"mappings": "AAQO,MAAM,oBAAoB,CAC/B,KACA,gBACA,YACuB;AAEvB,QAAM,CAAC,SAAS,YAAY,IAAI,IAAI,MAAM,KAAK,CAAC;AAEhD,MAAI,SAAS;AACX,QAAI,CAAC,QAAQ,IAAI,OAAO,GAAG;AACzB,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,cAAc;AACjB,aAAO,QAAQ,IAAI,OAAO;AAAA,IAC5B;AAGA,QAAI,aAAa,WAAW,GAAG,GAAG;AAChC,aAAO,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,YAAY;AAAA,IAC/C;AAGA,WAAO,QAAQ,IAAI,GAAG,OAAO,IAAI,YAAY,EAAE;AAAA,EACjD;AAEA,MAAI,cAAc;AAChB,QAAI,aAAa,WAAW,GAAG,GAAG;AAChC,aAAO,aAAa,MAAM,CAAC;AAAA,IAC7B;AACA,WAAO,QAAQ,IAAI,GAAG,cAAc,IAAI,YAAY,EAAE;AAAA,EACxD;AAEA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/escape-json-pointer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Escapes a JSON pointer string.\n *\n * Example: `/foo/bar~baz` -> `'~1foo~1bar~0baz'`\n */\nexport function escapeJsonPointer(str: string) {\n return str.replace(/~/g, '~0').replace(/\\//g, '~1')\n}\n"],
|
|
5
|
-
"mappings": "AAKO,SAAS,kBAAkB,KAAa;AAC7C,SAAO,IAAI,QAAQ,MAAM,IAAI,EAAE,QAAQ,OAAO,IAAI;AACpD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/get-schemas.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Retrieves the $id property from the input object if it exists and is a string.\n *\n * @param input - The object to extract the $id from.\n * @returns The $id string if present, otherwise undefined.\n */\nexport const getId = (input: unknown): string | undefined => {\n if (input && typeof input === 'object' && input['$id'] && typeof input['$id'] === 'string') {\n return input['$id']\n }\n return undefined\n}\n\n/**\n * Joins an array of path segments into a single string separated by '/'.\n *\n * @param segments - The array of path segments.\n * @returns The joined path string.\n */\nconst getPath = (segments: string[]): string => {\n return segments.join('/')\n}\n\n/**\n * Recursively traverses the input object to collect all schemas identified by $id and $anchor properties.\n *\n * - If an object has a $id property, it is added to the map with its $id as the key.\n * - If an object has a $anchor property, it is added to the map with a key composed of the current base and the anchor.\n * - The function performs a depth-first search (DFS) through all nested objects.\n *\n * @param input - The input object to traverse.\n * @param base - The current base URI, used for resolving anchors.\n * @param map - The map collecting found schemas.\n * @returns A map of schema identifiers to their corresponding objects.\n */\nexport const getSchemas = (\n input: unknown,\n base: string = '',\n segments: string[] = [],\n map = new Map<string, string>(),\n visited = new WeakSet(),\n) => {\n // Only process non-null objects\n if (typeof input !== 'object' || input === null) {\n return map\n }\n\n // If the object has already been visited, return the map\n if (visited.has(input)) {\n return map\n }\n\n // Add the object to the visited set\n visited.add(input)\n\n // Attempt to get $id from the current object\n const id = getId(input)\n\n // If $id exists, add the object to the map with $id as the key\n if (id) {\n map.set(id, getPath(segments))\n }\n\n // Update the base for nested anchors\n const newBase = id ?? base\n\n // If $anchor exists, add the object to the map with base#anchor as the key\n if (input['$anchor'] && typeof input['$anchor'] === 'string') {\n map.set(`${newBase}#${input['$anchor']}`, getPath(segments))\n }\n\n // Recursively traverse all properties (DFS)\n for (const key in input) {\n if (typeof input[key] === 'object' && input[key] !== null) {\n getSchemas(input[key], newBase, [...segments, key], map, visited)\n }\n }\n\n return map\n}\n"],
|
|
5
|
-
"mappings": "AAMO,MAAM,QAAQ,CAAC,UAAuC;AAC3D,MAAI,SAAS,OAAO,UAAU,YAAY,MAAM,KAAK,KAAK,OAAO,MAAM,KAAK,MAAM,UAAU;AAC1F,WAAO,MAAM,KAAK;AAAA,EACpB;AACA,SAAO;AACT;AAQA,MAAM,UAAU,CAAC,aAA+B;AAC9C,SAAO,SAAS,KAAK,GAAG;AAC1B;AAcO,MAAM,aAAa,CACxB,OACA,OAAe,IACf,WAAqB,CAAC,GACtB,MAAM,oBAAI,IAAoB,GAC9B,UAAU,oBAAI,QAAQ,MACnB;AAEH,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,IAAI,KAAK,GAAG;AACtB,WAAO;AAAA,EACT;AAGA,UAAQ,IAAI,KAAK;AAGjB,QAAM,KAAK,MAAM,KAAK;AAGtB,MAAI,IAAI;AACN,QAAI,IAAI,IAAI,QAAQ,QAAQ,CAAC;AAAA,EAC/B;AAGA,QAAM,UAAU,MAAM;AAGtB,MAAI,MAAM,SAAS,KAAK,OAAO,MAAM,SAAS,MAAM,UAAU;AAC5D,QAAI,IAAI,GAAG,OAAO,IAAI,MAAM,SAAS,CAAC,IAAI,QAAQ,QAAQ,CAAC;AAAA,EAC7D;AAGA,aAAW,OAAO,OAAO;AACvB,QAAI,OAAO,MAAM,GAAG,MAAM,YAAY,MAAM,GAAG,MAAM,MAAM;AACzD,iBAAW,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,GAAG,KAAK,OAAO;AAAA,IAClE;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/get-segments-from-path.ts"],
|
|
4
|
-
"sourcesContent": ["import { unescapeJsonPointer } from './unescape-json-pointer'\n\n/**\n * Translate `/paths/~1test` to `['paths', '/test']`\n */\nexport function getSegmentsFromPath(path: string) {\n return (\n // /paths/~1test\n path\n // ['', 'paths', '~1test']\n .split('/')\n // ['paths', '~test']\n .slice(1)\n // ['paths', '/test']\n .map(unescapeJsonPointer)\n )\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,2BAA2B;AAK7B,SAAS,oBAAoB,MAAc;AAChD;AAAA;AAAA,IAEE,KAEG,MAAM,GAAG,EAET,MAAM,CAAC,EAEP,IAAI,mBAAmB;AAAA;AAE9B;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/get-value-by-path.ts"],
|
|
4
|
-
"sourcesContent": ["import { getId } from '@/helpers/get-schemas'\n\n/**\n * Traverses an object using an array of string segments (path keys) and returns\n * the value at the specified path along with its context (id if available).\n *\n * @param target - The root object to traverse.\n * @param segments - An array of string keys representing the path to traverse.\n * @returns An object containing the final context (id or previous context) and the value at the path.\n *\n * @example\n * const obj = {\n * foo: {\n * bar: {\n * baz: 42\n * }\n * }\n * };\n * // Returns: { context: '', value: 42 }\n * getValueByPath(obj, ['foo', 'bar', 'baz']);\n */\nexport function getValueByPath(target: unknown, segments: string[]): { context: string; value: any } {\n return segments.reduce<{ context: string; value: unknown }>(\n (acc, key) => {\n // If the accumulator is undefined, the path does not exist\n if (acc.value === undefined) {\n return { context: '', value: undefined }\n }\n // If the accumulator is not an object or is null, stop traversal\n if (typeof acc.value !== 'object' || acc.value === null) {\n return { context: '', value: undefined }\n }\n // Attempt to get the id from the current value for context tracking\n const id = getId(acc.value)\n\n // Return the next context and value for the next iteration\n return { context: id ?? acc.context, value: acc.value?.[key] }\n },\n {\n context: '',\n value: target,\n },\n )\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa;AAqBf,SAAS,eAAe,QAAiB,UAAqD;AACnG,SAAO,SAAS;AAAA,IACd,CAAC,KAAK,QAAQ;AAEZ,UAAI,IAAI,UAAU,QAAW;AAC3B,eAAO,EAAE,SAAS,IAAI,OAAO,OAAU;AAAA,MACzC;AAEA,UAAI,OAAO,IAAI,UAAU,YAAY,IAAI,UAAU,MAAM;AACvD,eAAO,EAAE,SAAS,IAAI,OAAO,OAAU;AAAA,MACzC;AAEA,YAAM,KAAK,MAAM,IAAI,KAAK;AAG1B,aAAO,EAAE,SAAS,MAAM,IAAI,SAAS,OAAO,IAAI,QAAQ,GAAG,EAAE;AAAA,IAC/D;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/is-file-path.ts"],
|
|
4
|
-
"sourcesContent": ["import { isHttpUrl } from '@/helpers/is-http-url'\nimport { isJsonObject } from '@/helpers/is-json-object'\nimport { isYaml } from '@/helpers/is-yaml'\n\n/**\n * Checks if a string represents a file path by ensuring it's not a remote URL,\n * YAML content, or JSON content.\n *\n * @param value - The string to check\n * @returns true if the string appears to be a file path, false otherwise\n * @example\n * ```ts\n * isFilePath('./schemas/user.json') // true\n * isFilePath('https://example.com/schema.json') // false\n * isFilePath('{\"type\": \"object\"}') // false\n * isFilePath('type: object') // false\n * ```\n */\nexport function isFilePath(value: string) {\n return !isHttpUrl(value) && !isYaml(value) && !isJsonObject(value)\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AAgBhB,SAAS,WAAW,OAAe;AACxC,SAAO,CAAC,UAAU,KAAK,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,aAAa,KAAK;AACnE;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/is-http-url.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Checks if a string is a remote URL (starts with http:// or https://)\n * @param value - The URL string to check\n * @returns true if the string is a remote URL, false otherwise\n * @example\n * ```ts\n * isHttpUrl('https://example.com/schema.json') // true\n * isHttpUrl('http://api.example.com/schemas/user.json') // true\n * isHttpUrl('#/components/schemas/User') // false\n * isHttpUrl('./local-schema.json') // false\n * ```\n */\nexport function isHttpUrl(value: string) {\n try {\n const url = new URL(value)\n return url.protocol === 'http:' || url.protocol === 'https:'\n } catch {\n return false\n }\n}\n"],
|
|
5
|
-
"mappings": "AAYO,SAAS,UAAU,OAAe;AACvC,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,WAAO,IAAI,aAAa,WAAW,IAAI,aAAa;AAAA,EACtD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/is-json-object.ts"],
|
|
4
|
-
"sourcesContent": ["import { isObject } from '@scalar/helpers/object/is-object'\n\n/**\n * Determines if a string represents a valid JSON object (i.e., a plain object, not an array, primitive, or null).\n * The function first checks if the string appears to start with an opening curly brace (ignoring leading whitespace),\n * which is a quick heuristic to rule out arrays, primitives, and most invalid JSON. If this check passes,\n * it attempts to parse the string with JSON.parse. The result is then checked to ensure it is a plain object\n * (not an array, null, or primitive) using the isObject utility.\n *\n * @param value - The string to evaluate\n * @returns true if the string is valid JSON and parses to a plain object, false otherwise\n *\n * @example\n * isJsonObject('{\"foo\": \"bar\"}') // true\n * isJsonObject('[1,2,3]') // false\n * isJsonObject('not json') // false\n * isJsonObject('42') // false\n */\nexport function isJsonObject(value: string) {\n // Quickly rule out anything that doesn't start with an object brace\n if (!/^\\s*(\\{)/.test(value.slice(0, 500))) {\n return false\n }\n\n try {\n const val = JSON.parse(value)\n return isObject(val)\n } catch {\n return false\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,gBAAgB;AAkBlB,SAAS,aAAa,OAAe;AAE1C,MAAI,CAAC,WAAW,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG;AACzC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,WAAO,SAAS,GAAG;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/is-yaml.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Checks if a string appears to be YAML content.\n * This function uses a simple heuristic: it looks for a line that starts with an optional dash,\n * followed by a key (alphanumeric or dash), a colon, and a value, and then at least one more line.\n * This is not a full YAML parser, but works for basic detection.\n *\n * @param value - The string to check\n * @returns true if the string looks like YAML, false otherwise\n *\n * @example\n * isYaml('openapi: 3.0.0\\ninfo:\\n title: Example') // true\n * isYaml('{\"openapi\": \"3.0.0\", \"info\": {\"title\": \"Example\"}}') // false\n * isYaml('- name: value\\n- name: value2') // true\n * isYaml('type: object') // false (only one line)\n */\nexport function isYaml(value: string): boolean {\n return /^\\s*(?:-\\s*)?[\\w\\-]+\\s*:\\s*.+\\n.*/.test(value)\n}\n"],
|
|
5
|
-
"mappings": "AAeO,SAAS,OAAO,OAAwB;AAC7C,SAAO,oCAAoC,KAAK,KAAK;AACvD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/json-path-utils.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Creates a nested path in an object from an array of path segments.\n * Only creates intermediate objects/arrays if they don't already exist.\n *\n * @param obj - The target object to create the path in\n * @param segments - Array of path segments to create\n * @returns The final nested object/array at the end of the path\n *\n * @example\n * ```ts\n * const obj = {}\n * createPathFromSegments(obj, ['components', 'schemas', 'User'])\n * // Creates: { components: { schemas: { User: {} } } }\n *\n * createPathFromSegments(obj, ['items', '0', 'name'])\n * // Creates: { items: [{ name: {} }] }\n * ```\n */\nexport function createPathFromSegments(obj: any, segments: string[]) {\n return segments.reduce((acc, part) => {\n if (acc[part] === undefined) {\n if (isNaN(Number(part))) {\n acc[part] = {}\n } else {\n acc[part] = []\n }\n }\n return acc[part]\n }, obj)\n}\n"],
|
|
5
|
-
"mappings": "AAkBO,SAAS,uBAAuB,KAAU,UAAoB;AACnE,SAAO,SAAS,OAAO,CAAC,KAAK,SAAS;AACpC,QAAI,IAAI,IAAI,MAAM,QAAW;AAC3B,UAAI,MAAM,OAAO,IAAI,CAAC,GAAG;AACvB,YAAI,IAAI,IAAI,CAAC;AAAA,MACf,OAAO;AACL,YAAI,IAAI,IAAI,CAAC;AAAA,MACf;AAAA,IACF;AACA,WAAO,IAAI,IAAI;AAAA,EACjB,GAAG,GAAG;AACR;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/normalize.ts"],
|
|
4
|
-
"sourcesContent": ["import { parse } from 'yaml'\n\n/**\n * Normalize a string (YAML, JSON, object) to a JavaScript datatype.\n */\nexport function normalize(content: any) {\n if (content === null) {\n return undefined\n }\n\n if (typeof content === 'string') {\n if (content.trim() === '') {\n return undefined\n }\n\n try {\n return JSON.parse(content)\n } catch (_error) {\n // Does it look like YAML?\n const hasColon = /^[^:]+:/.test(content)\n const isJson = content.slice(0, 50).trimStart().startsWith('{')\n\n if (!hasColon || isJson) {\n return undefined\n }\n\n return parse(content, {\n maxAliasCount: 10000,\n merge: true,\n })\n }\n }\n\n return content\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa;AAKf,SAAS,UAAU,SAAc;AACtC,MAAI,YAAY,MAAM;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,UAAU;AAC/B,QAAI,QAAQ,KAAK,MAAM,IAAI;AACzB,aAAO;AAAA,IACT;AAEA,QAAI;AACF,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,SAAS,QAAQ;AAEf,YAAM,WAAW,UAAU,KAAK,OAAO;AACvC,YAAM,SAAS,QAAQ,MAAM,GAAG,EAAE,EAAE,UAAU,EAAE,WAAW,GAAG;AAE9D,UAAI,CAAC,YAAY,QAAQ;AACvB,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,SAAS;AAAA,QACpB,eAAe;AAAA,QACf,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/resolve-reference-path.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'pathe'\n\nimport { isHttpUrl } from '@/helpers/is-http-url'\n\n/**\n * Resolves a reference path by combining a base path with a relative path.\n * Handles both remote URLs and local file paths.\n *\n * @param base - The base path (can be a URL or local file path)\n * @param relativePath - The relative path to resolve against the base\n * @returns The resolved absolute path\n * @example\n * // Resolve remote URL\n * resolveReferencePath('https://example.com/api/schema.json', 'user.json')\n * // Returns: 'https://example.com/api/user.json'\n *\n * // Resolve local path\n * resolveReferencePath('/path/to/schema.json', 'user.json')\n * // Returns: '/path/to/user.json'\n */\nexport const resolveReferencePath = (base: string, relativePath: string) => {\n if (isHttpUrl(relativePath)) {\n return relativePath\n }\n\n if (isHttpUrl(base)) {\n const baseUrl = new URL(base)\n baseUrl.pathname = path.posix.resolve('/', path.dirname(baseUrl.pathname), relativePath)\n return baseUrl.toString()\n }\n\n return path.resolve(path.dirname(base), relativePath)\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,UAAU;AAEjB,SAAS,iBAAiB;AAkBnB,MAAM,uBAAuB,CAAC,MAAc,iBAAyB;AAC1E,MAAI,UAAU,YAAY,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,YAAQ,WAAW,KAAK,MAAM,QAAQ,KAAK,KAAK,QAAQ,QAAQ,QAAQ,GAAG,YAAY;AACvF,WAAO,QAAQ,SAAS;AAAA,EAC1B;AAEA,SAAO,KAAK,QAAQ,KAAK,QAAQ,IAAI,GAAG,YAAY;AACtD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/set-value-at-path.ts"],
|
|
4
|
-
"sourcesContent": ["import { preventPollution } from '@scalar/helpers/object/prevent-pollution'\n\nimport { getSegmentsFromPath } from '@/helpers/get-segments-from-path'\n\n/**\n * Sets a value at a specified path in an object, creating intermediate objects/arrays as needed.\n * This function traverses the object structure and creates any missing intermediate objects\n * or arrays based on the path segments. If the next segment is a numeric string, it creates\n * an array instead of an object.\n *\n * \u26A0\uFE0F Warning: Be careful with object keys that look like numbers (e.g. \"123\") as this function\n * will interpret them as array indices and create arrays instead of objects. If you need to\n * use numeric-looking keys, consider prefixing them with a non-numeric character.\n *\n * @param obj - The target object to set the value in\n * @param path - The JSON pointer path where the value should be set\n * @param value - The value to set at the specified path\n * @throws {Error} If attempting to set a value at the root path ('')\n *\n * @example\n * const obj = {}\n * setValueAtPath(obj, '/foo/bar/0', 'value')\n * // Result:\n * // {\n * // foo: {\n * // bar: ['value']\n * // }\n * // }\n *\n * @example\n * const obj = { existing: { path: 'old' } }\n * setValueAtPath(obj, '/existing/path', 'new')\n * // Result:\n * // {\n * // existing: {\n * // path: 'new'\n * // }\n * // }\n *\n * @example\n * // \u26A0\uFE0F Warning: This will create an array instead of an object with key \"123\"\n * setValueAtPath(obj, '/foo/123/bar', 'value')\n * // Result:\n * // {\n * // foo: [\n * // undefined,\n * // undefined,\n * // undefined,\n * // { bar: 'value' }\n * // ]\n * // }\n */\nexport function setValueAtPath(obj: any, path: string, value: any): void {\n if (path === '') {\n throw new Error(\"Cannot set value at root ('') pointer\")\n }\n\n const parts = getSegmentsFromPath(path)\n\n // Prevent prototype pollution\n parts.forEach((part) => preventPollution(part))\n\n let current = obj\n\n for (let i = 0; i < parts.length; i++) {\n const key = parts[i]\n const isLast = i === parts.length - 1\n\n const nextKey = parts[i + 1]\n const shouldBeArray = /^\\d+$/.test(nextKey ?? '')\n\n if (isLast) {\n current[key] = value\n } else {\n if (!(key in current) || typeof current[key] !== 'object') {\n current[key] = shouldBeArray ? [] : {}\n }\n current = current[key]\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,wBAAwB;AAEjC,SAAS,2BAA2B;AAkD7B,SAAS,eAAe,KAAU,MAAc,OAAkB;AACvE,MAAI,SAAS,IAAI;AACf,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,QAAM,QAAQ,oBAAoB,IAAI;AAGtC,QAAM,QAAQ,CAAC,SAAS,iBAAiB,IAAI,CAAC;AAE9C,MAAI,UAAU;AAEd,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,MAAM,MAAM,CAAC;AACnB,UAAM,SAAS,MAAM,MAAM,SAAS;AAEpC,UAAM,UAAU,MAAM,IAAI,CAAC;AAC3B,UAAM,gBAAgB,QAAQ,KAAK,WAAW,EAAE;AAEhD,QAAI,QAAQ;AACV,cAAQ,GAAG,IAAI;AAAA,IACjB,OAAO;AACL,UAAI,EAAE,OAAO,YAAY,OAAO,QAAQ,GAAG,MAAM,UAAU;AACzD,gBAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC;AAAA,MACvC;AACA,gBAAU,QAAQ,GAAG;AAAA,IACvB;AAAA,EACF;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/to-relative-path.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'pathe'\n\nimport { isHttpUrl } from '@/helpers/is-http-url'\n\n/**\n * Converts an input path or URL to a relative path based on the provided base.\n * Handles both remote URLs and local file system paths.\n * - If both input and base are remote URLs and share the same origin, computes the relative pathname.\n * - If base is a remote URL but input is local, returns a remote URL with a relative pathname.\n * - If input is a remote URL but base is local, returns input as is.\n * - Otherwise, computes the relative path between two local paths.\n */\nexport const toRelativePath = (input: string, base: string) => {\n // Both input and base are remote URLs\n if (isHttpUrl(input) && isHttpUrl(base)) {\n const inputUrl = new URL(input)\n const baseUrl = new URL(base)\n // If origins aren't the same, return input as is\n if (inputUrl.origin !== baseUrl.origin) {\n return input\n }\n\n // Get the directory of the base URL pathname (not the file itself)\n const baseDir = path.dirname(path.posix.resolve('/', baseUrl.pathname))\n const inputPath = path.posix.resolve('/', inputUrl.pathname)\n // Return the relative path from baseDir to inputPath\n return path.posix.relative(baseDir, inputPath)\n }\n\n // Base is a remote URL, input is a local path\n if (isHttpUrl(base)) {\n const baseUrl = new URL(base)\n const baseDir = path.dirname(path.posix.resolve('/', baseUrl.pathname))\n // Set the pathname of the base URL to the relative path and return the URL as a string\n baseUrl.pathname = path.posix.relative(baseDir, path.posix.resolve('/', input))\n return baseUrl.toString()\n }\n\n // Input is a remote URL, base is a local path; just return input\n if (isHttpUrl(input)) {\n return input\n }\n\n // Both input and base are local paths; return the relative path\n const baseDir = path.dirname(path.resolve(base))\n const inputPath = path.resolve(input)\n return path.relative(baseDir, inputPath)\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,UAAU;AAEjB,SAAS,iBAAiB;AAUnB,MAAM,iBAAiB,CAAC,OAAe,SAAiB;AAE7D,MAAI,UAAU,KAAK,KAAK,UAAU,IAAI,GAAG;AACvC,UAAM,WAAW,IAAI,IAAI,KAAK;AAC9B,UAAM,UAAU,IAAI,IAAI,IAAI;AAE5B,QAAI,SAAS,WAAW,QAAQ,QAAQ;AACtC,aAAO;AAAA,IACT;AAGA,UAAMA,WAAU,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,QAAQ,QAAQ,CAAC;AACtE,UAAMC,aAAY,KAAK,MAAM,QAAQ,KAAK,SAAS,QAAQ;AAE3D,WAAO,KAAK,MAAM,SAASD,UAASC,UAAS;AAAA,EAC/C;AAGA,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,UAAU,IAAI,IAAI,IAAI;AAC5B,UAAMD,WAAU,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,QAAQ,QAAQ,CAAC;AAEtE,YAAQ,WAAW,KAAK,MAAM,SAASA,UAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,CAAC;AAC9E,WAAO,QAAQ,SAAS;AAAA,EAC1B;AAGA,MAAI,UAAU,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,KAAK,QAAQ,KAAK,QAAQ,IAAI,CAAC;AAC/C,QAAM,YAAY,KAAK,QAAQ,KAAK;AACpC,SAAO,KAAK,SAAS,SAAS,SAAS;AACzC;",
|
|
6
|
-
"names": ["baseDir", "inputPath"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/helpers/unescape-json-pointer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Unescape JSON pointer\n *\n * Examples:\n * /foo~1bar~0baz -> /foo/bar~baz\n */\nexport function unescapeJsonPointer(uri: string) {\n return decodeURI(uri.replace(/~1/g, '/').replace(/~0/g, '~'))\n}\n"],
|
|
5
|
-
"mappings": "AAMO,SAAS,oBAAoB,KAAa;AAC/C,SAAO,UAAU,IAAI,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,CAAC;AAC9D;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/magic-proxy/proxy.ts"],
|
|
4
|
-
"sourcesContent": ["import { parseJsonPointerSegments } from '@scalar/helpers/json/parse-json-pointer-segments'\nimport { isObject } from '@scalar/helpers/object/is-object'\n\nimport { convertToLocalRef } from '@/helpers/convert-to-local-ref'\nimport { getId, getSchemas } from '@/helpers/get-schemas'\nimport { getValueByPath } from '@/helpers/get-value-by-path'\nimport { createPathFromSegments } from '@/helpers/json-path-utils'\nimport type { UnknownObject } from '@/types'\n\nconst isMagicProxy = Symbol('isMagicProxy')\nconst magicProxyTarget = Symbol('magicProxyTarget')\n\nconst REF_VALUE = '$ref-value'\nconst REF_KEY = '$ref'\n\n/**\n * Creates a \"magic\" proxy for a given object or array, enabling transparent access to\n * JSON Reference ($ref) values as if they were directly present on the object.\n *\n * Features:\n * - If an object contains a `$ref` property, accessing the special `$ref-value` property will resolve and return the referenced value from the root object.\n * - All nested objects and arrays are recursively wrapped in proxies, so reference resolution works at any depth.\n * - Properties starting with `__scalar_` are considered internal and are hidden by default: they return undefined on access, are excluded from enumeration, and `'in'` checks return false. This can be overridden with the `showInternal` option.\n * - Setting, deleting, and enumerating properties works as expected, including for proxied references.\n * - Ensures referential stability by caching proxies for the same target object.\n *\n * @param target - The object or array to wrap in a magic proxy\n * @param options - Optional settings (e.g., showInternal to expose internal properties)\n * @param args - Internal arguments for advanced usage (root object, proxy/cache maps, current context)\n * @returns A proxied version of the input object/array with magic $ref-value support\n *\n * @example\n * const input = {\n * definitions: {\n * foo: { bar: 123 }\n * },\n * refObj: { $ref: '#/definitions/foo' },\n * __scalar_internal: 'hidden property'\n * }\n * const proxy = createMagicProxy(input)\n *\n * // Accessing proxy.refObj['$ref-value'] will resolve to { bar: 123 }\n * console.log(proxy.refObj['$ref-value']) // { bar: 123 }\n *\n * // Properties starting with __scalar_ are hidden\n * console.log(proxy.__scalar_internal) // undefined\n * console.log('__scalar_internal' in proxy) // false\n * console.log(Object.keys(proxy)) // ['definitions', 'refObj'] (no '__scalar_internal')\n *\n * // Setting and deleting properties works as expected\n * proxy.refObj.extra = 'hello'\n * delete proxy.refObj.extra\n */\nexport const createMagicProxy = <T extends Record<keyof T & symbol, unknown>, S extends UnknownObject>(\n target: T,\n options?: Partial<{ showInternal: boolean }>,\n args: {\n /**\n * The root object for resolving local JSON references.\n */\n root: S | T\n /**\n * Cache to store already created proxies for target objects to ensure referential stability.\n *\n * It is helpful when dealing with reactive frameworks like Vue,\n */\n proxyCache: WeakMap<object, T>\n /**\n * Cache to store resolved JSON references.\n */\n cache: Map<string, unknown>\n /**\n * Map of all schemas by their $id or $anchor for cross-document reference resolution.\n */\n schemas: Map<string, string>\n /**\n * The current JSON path context within the root object.\n *\n * Used to resolve $anchor references correctly.\n */\n currentContext: string\n } = {\n root: target,\n proxyCache: new WeakMap(),\n cache: new Map(),\n schemas: getSchemas(target),\n currentContext: '',\n },\n): T => {\n if (!isObject(target) && !Array.isArray(target)) {\n return target\n }\n\n // Return existing proxy for the same target to ensure referential stability\n if (args.proxyCache.has(target)) {\n return args.proxyCache.get(target)\n }\n\n const handler: ProxyHandler<T> = {\n /**\n * Proxy \"get\" trap for magic proxy.\n * - If accessing the special isMagicProxy symbol, return true to identify proxy.\n * - If accessing the magicProxyTarget symbol, return the original target object.\n * - Hide properties starting with __scalar_ by returning undefined.\n * - If accessing \"$ref-value\" and the object has a local $ref, resolve and return the referenced value as a new magic proxy.\n * - For all other properties, recursively wrap the returned value in a magic proxy (if applicable).\n */\n get(target, prop, receiver) {\n if (prop === isMagicProxy) {\n // Used to identify if an object is a magic proxy\n return true\n }\n\n if (prop === magicProxyTarget) {\n // Used to retrieve the original target object from the proxy\n return target\n }\n\n // Hide properties starting with __scalar_ - these are considered internal/private properties\n // and should not be accessible through the magic proxy interface\n if (typeof prop === 'string' && prop.startsWith('__scalar_') && !options?.showInternal) {\n return undefined\n }\n\n // Get the $ref value of the current target (if any)\n const ref = Reflect.get(target, REF_KEY, receiver)\n // Get the identifier ($id) of the current target for context tracking\n const id = getId(target)\n\n // If accessing \"$ref-value\" and $ref is a local reference, resolve and return the referenced value\n if (prop === REF_VALUE && typeof ref === 'string') {\n // Check cache first for performance optimization\n if (args.cache.has(ref)) {\n return args.cache.get(ref)\n }\n\n const path = convertToLocalRef(ref, id ?? args.currentContext, args.schemas)\n\n if (path === undefined) {\n return undefined\n }\n\n // Resolve the reference and create a new magic proxy\n const resolvedValue = getValueByPath(args.root, parseJsonPointerSegments(`/${path}`))\n // Return early if the value is already a magic proxy\n if (isMagicProxyObject(resolvedValue.value)) {\n return resolvedValue.value\n }\n const proxiedValue = createMagicProxy(resolvedValue.value, options, {\n ...args,\n currentContext: resolvedValue.context,\n })\n\n // Store in cache for future lookups\n args.cache.set(ref, proxiedValue)\n return proxiedValue\n }\n\n // For all other properties, recursively wrap the value in a magic proxy\n const value = Reflect.get(target, prop, receiver)\n\n // Return early if the value is already a magic proxy\n if (isMagicProxyObject(value)) {\n return value\n }\n\n return createMagicProxy(value as T, options, { ...args, currentContext: id ?? args.currentContext })\n },\n /**\n * Proxy \"set\" trap for magic proxy.\n * Allows setting properties on the proxied object.\n * This will update the underlying target object.\n *\n * Note: it will not update if the property starts with __scalar_\n * Those will be considered private properties by the proxy\n */\n set(target, prop, newValue, receiver) {\n const ref = Reflect.get(target, REF_KEY, receiver)\n\n if (typeof prop === 'string' && prop.startsWith('__scalar_') && !options?.showInternal) {\n return true\n }\n\n if (prop === REF_VALUE && typeof ref === 'string') {\n const id = getId(target)\n const path = convertToLocalRef(ref, id ?? args.currentContext, args.schemas)\n\n if (path === undefined) {\n return undefined\n }\n\n const segments = parseJsonPointerSegments(`/${path}`)\n\n if (segments.length === 0) {\n return false // Can not set top level $ref-value\n }\n\n // Get the parent node or create it if it does not exist\n const getParentNode = () => getValueByPath(args.root, segments.slice(0, -1)).value\n\n if (getParentNode() === undefined) {\n createPathFromSegments(args.root, segments.slice(0, -1))\n\n // In this case the ref is pointing to an invalid path, so we warn the user\n console.warn(\n `Trying to set $ref-value for invalid reference: ${ref}\\n\\nPlease fix your input file to fix this issue.`,\n )\n }\n\n // Set the value on the parent node\n getParentNode()[segments.at(-1)] = newValue\n return true\n }\n\n return Reflect.set(target, prop, newValue, receiver)\n },\n /**\n * Proxy \"deleteProperty\" trap for magic proxy.\n * Allows deleting properties from the proxied object.\n * This will update the underlying target object.\n */\n deleteProperty(target, prop) {\n return Reflect.deleteProperty(target, prop)\n },\n /**\n * Proxy \"has\" trap for magic proxy.\n * - Pretend that \"$ref-value\" exists if \"$ref\" exists on the target.\n * This allows expressions like `\"$ref-value\" in obj` to return true for objects with a $ref,\n * even though \"$ref-value\" is a virtual property provided by the proxy.\n * - Hide properties starting with __scalar_ by returning false.\n * - For all other properties, defer to the default Reflect.has behavior.\n */\n has(target, prop) {\n // Hide properties starting with __scalar_\n if (typeof prop === 'string' && prop.startsWith('__scalar_') && !options?.showInternal) {\n return false\n }\n\n // Pretend that \"$ref-value\" exists if \"$ref\" exists\n if (prop === REF_VALUE && REF_KEY in target) {\n return true\n }\n return Reflect.has(target, prop)\n },\n /**\n * Proxy \"ownKeys\" trap for magic proxy.\n * - Returns the list of own property keys for the proxied object.\n * - If the object has a \"$ref\" property, ensures that \"$ref-value\" is also included in the keys,\n * even though \"$ref-value\" is a virtual property provided by the proxy.\n * This allows Object.keys, Reflect.ownKeys, etc. to include \"$ref-value\" for objects with $ref.\n * - Filters out properties starting with __scalar_.\n */\n ownKeys(target) {\n const keys = Reflect.ownKeys(target)\n\n // Filter out properties starting with __scalar_\n const filteredKeys = keys.filter(\n (key) => typeof key !== 'string' || !(key.startsWith('__scalar_') && !options?.showInternal),\n )\n\n if (REF_KEY in target && !filteredKeys.includes(REF_VALUE)) {\n filteredKeys.push(REF_VALUE)\n }\n return filteredKeys\n },\n\n /**\n * Proxy \"getOwnPropertyDescriptor\" trap for magic proxy.\n * - For the virtual \"$ref-value\" property, returns a descriptor that makes it appear as a regular property.\n * - Hide properties starting with __scalar_ by returning undefined.\n * - For all other properties, delegates to the default Reflect.getOwnPropertyDescriptor behavior.\n * - This ensures that Object.getOwnPropertyDescriptor and similar methods work correctly with the virtual property.\n */\n getOwnPropertyDescriptor(target, prop) {\n // Hide properties starting with __scalar_\n if (typeof prop === 'string' && prop.startsWith('__scalar_') && !options?.showInternal) {\n return undefined\n }\n\n const ref = Reflect.get(target, REF_KEY)\n\n if (prop === REF_VALUE && typeof ref === 'string') {\n return {\n configurable: true,\n enumerable: true,\n value: undefined,\n writable: false,\n }\n }\n\n // Otherwise, delegate to the default behavior\n return Reflect.getOwnPropertyDescriptor(target, prop)\n },\n }\n\n const proxied = new Proxy<T>(target, handler)\n args.proxyCache.set(target, proxied)\n return proxied\n}\n\nconst isMagicProxyObject = (obj: unknown): boolean => {\n return typeof obj === 'object' && obj !== null && (obj as { [isMagicProxy]: boolean })[isMagicProxy] === true\n}\n\n/**\n * Gets the raw (non-proxied) version of an object created by createMagicProxy.\n * This is useful when you need to access the original object without the magic proxy wrapper.\n *\n * @param obj - The magic proxy object to get the raw version of\n * @returns The raw version of the object\n * @example\n * const proxy = createMagicProxy({ foo: { $ref: '#/bar' } })\n * const raw = getRaw(proxy) // { foo: { $ref: '#/bar' } }\n */\nexport function getRaw<T>(obj: T): T {\n if (typeof obj !== 'object' || obj === null) {\n return obj\n }\n\n if ((obj as T & { [isMagicProxy]: boolean | undefined })[isMagicProxy]) {\n return (obj as T & { [magicProxyTarget]: T })[magicProxyTarget]\n }\n\n return obj\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["target"]
|
|
7
|
-
}
|