@amritk/adapters
Advanced tools
| {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEnD;;;;;;;;;GASG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAC7E,CAAA"} |
| {"version":3,"file":"effect-to-json-schema.d.ts","sourceRoot":"","sources":["../src/effect-to-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AA4BjE;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,WAAkB,OAAO,KAAG,OAAO,CAAC,UAAU,CAmB5E,CAAA"} |
| {"version":3,"file":"get-adapter.d.ts","sourceRoot":"","sources":["../src/get-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAyBnD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,WAAY,YAAY,KAAG,OAgBjD,CAAA"} |
| {"version":3,"file":"source-format.d.ts","sourceRoot":"","sources":["../src/source-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAA"} |
| {"version":3,"file":"typebox-to-json-schema.d.ts","sourceRoot":"","sources":["../src/typebox-to-json-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAwDjE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,WAAY,OAAO,KAAG,UAUrD,CAAA"} |
| {"version":3,"file":"valibot-to-json-schema.d.ts","sourceRoot":"","sources":["../src/valibot-to-json-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAuCjE;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,WAAkB,OAAO,KAAG,OAAO,CAAC,UAAU,CA0B7E,CAAA"} |
| {"version":3,"file":"zod-to-json-schema.d.ts","sourceRoot":"","sources":["../src/zod-to-json-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AA4CjE;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,WAAkB,OAAO,KAAG,OAAO,CAAC,UAAU,CA+BzE,CAAA"} |
| import type { JSONSchema } from 'json-schema-typed/draft-2020-12'; | ||
| import type { SourceFormat } from './source-format'; | ||
| import type { SourceFormat } from './source-format.js'; | ||
| /** | ||
@@ -23,1 +23,2 @@ * Converts a schema authored in some external library into a Draft 2020-12 | ||
| }; | ||
| //# sourceMappingURL=adapter.d.ts.map |
@@ -12,1 +12,2 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'; | ||
| export declare const effectToJsonSchema: (source: unknown) => Promise<JSONSchema>; | ||
| //# sourceMappingURL=effect-to-json-schema.d.ts.map |
@@ -1,3 +0,3 @@ | ||
| import type { Adapter } from './adapter'; | ||
| import type { SourceFormat } from './source-format'; | ||
| import type { Adapter } from './adapter.js'; | ||
| import type { SourceFormat } from './source-format.js'; | ||
| /** | ||
@@ -12,1 +12,2 @@ * Resolves the adapter for a non-JSON source format. | ||
| export declare const getAdapter: (format: SourceFormat) => Adapter; | ||
| //# sourceMappingURL=get-adapter.d.ts.map |
@@ -12,1 +12,2 @@ /** | ||
| export type SourceFormat = 'json' | 'typebox' | 'zod' | 'valibot' | 'effect'; | ||
| //# sourceMappingURL=source-format.d.ts.map |
@@ -14,1 +14,2 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'; | ||
| export declare const typeboxToJsonSchema: (source: unknown) => JSONSchema; | ||
| //# sourceMappingURL=typebox-to-json-schema.d.ts.map |
@@ -1,65 +0,73 @@ | ||
| var __defProp = Object.defineProperty; | ||
| var __returnValue = (v) => v; | ||
| function __exportSetter(name, newValue) { | ||
| this[name] = __returnValue.bind(null, newValue); | ||
| } | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { | ||
| get: all[name], | ||
| enumerable: true, | ||
| configurable: true, | ||
| set: __exportSetter.bind(all, name) | ||
| }); | ||
| import { MJST_EXTENSION_KEY } from '@amritk/helpers/mjst-extension'; | ||
| // The seven core JSON Schema 2020-12 types. Anything else in a `type` slot is a | ||
| // TypeBox extended type with no native JSON Schema equivalent. | ||
| const JSON_SCHEMA_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'object', 'array', 'null']); | ||
| // Maps a TypeBox extended `type` string to the runtime class an `x-mjst` | ||
| // instanceOf hint should reference. Add entries here as more extended types | ||
| // gain generator support. | ||
| const EXTENDED_TYPE_TO_INSTANCE = { | ||
| Date: 'Date', | ||
| }; | ||
| var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res); | ||
| // ../helpers/dist/mjst-extension.js | ||
| var MJST_EXTENSION_KEY = "x-mjst"; | ||
| var SUPPORTED_PRIMITIVES = new Set(["bigint"]); | ||
| // src/typebox-to-json-schema.ts | ||
| var JSON_SCHEMA_TYPES = new Set(["string", "number", "integer", "boolean", "object", "array", "null"]); | ||
| var EXTENDED_TYPE_TO_INSTANCE = { | ||
| Date: "Date" | ||
| // Maps a TypeBox extended `type` string to a non-JSON `x-mjst` primitive hint | ||
| // (e.g. Type.BigInt() emits `{ type: 'bigint' }`). | ||
| const EXTENDED_TYPE_TO_PRIMITIVE = { | ||
| bigint: 'bigint', | ||
| }; | ||
| var EXTENDED_TYPE_TO_PRIMITIVE = { | ||
| bigint: "bigint" | ||
| /** | ||
| * Recursively rewrites TypeBox extended types into an `x-mjst` instanceOf hint. | ||
| * | ||
| * TypeBox emits non-standard `type` strings for runtime classes (e.g. | ||
| * `Type.Date()` produces `{ type: 'Date' }`). We drop the bogus `type` and | ||
| * record the class under `x-mjst` so the generators can emit the right | ||
| * TypeScript type and `instanceof` checks. Extended types we do not yet map are | ||
| * left untouched with a warning, preserving a permissive best-effort fallback. | ||
| */ | ||
| const rewriteExtendedTypes = (value) => { | ||
| if (Array.isArray(value)) | ||
| return value.map(rewriteExtendedTypes); | ||
| if (typeof value !== 'object' || value === null) | ||
| return value; | ||
| const source = value; | ||
| const result = {}; | ||
| for (const [key, val] of Object.entries(source)) { | ||
| result[key] = rewriteExtendedTypes(val); | ||
| } | ||
| const type = result['type']; | ||
| if (typeof type === 'string' && !JSON_SCHEMA_TYPES.has(type)) { | ||
| const primitive = EXTENDED_TYPE_TO_PRIMITIVE[type]; | ||
| const instanceOf = EXTENDED_TYPE_TO_INSTANCE[type]; | ||
| if (primitive) { | ||
| delete result['type']; | ||
| result[MJST_EXTENSION_KEY] = { primitive }; | ||
| } | ||
| else if (instanceOf) { | ||
| delete result['type']; | ||
| result[MJST_EXTENSION_KEY] = { instanceOf }; | ||
| } | ||
| else { | ||
| console.warn(`[mjst] TypeBox type '${type}' has no JSON Schema or x-mjst mapping; leaving it unchanged.`); | ||
| } | ||
| } | ||
| return result; | ||
| }; | ||
| var rewriteExtendedTypes = (value) => { | ||
| if (Array.isArray(value)) | ||
| return value.map(rewriteExtendedTypes); | ||
| if (typeof value !== "object" || value === null) | ||
| return value; | ||
| const source = value; | ||
| const result = {}; | ||
| for (const [key, val] of Object.entries(source)) { | ||
| result[key] = rewriteExtendedTypes(val); | ||
| } | ||
| const type = result["type"]; | ||
| if (typeof type === "string" && !JSON_SCHEMA_TYPES.has(type)) { | ||
| const primitive = EXTENDED_TYPE_TO_PRIMITIVE[type]; | ||
| const instanceOf = EXTENDED_TYPE_TO_INSTANCE[type]; | ||
| if (primitive) { | ||
| delete result["type"]; | ||
| result[MJST_EXTENSION_KEY] = { primitive }; | ||
| } else if (instanceOf) { | ||
| delete result["type"]; | ||
| result[MJST_EXTENSION_KEY] = { instanceOf }; | ||
| } else { | ||
| console.warn(`[mjst] TypeBox type '${type}' has no JSON Schema or x-mjst mapping; leaving it unchanged.`); | ||
| /** | ||
| * TypeBox schemas are already JSON Schema objects at runtime, but they carry | ||
| * non-enumerable symbol keys (`Kind`, `Optional`, ...) that TypeBox uses for its | ||
| * own type machinery. A JSON round-trip drops those symbols (and any `undefined` | ||
| * values), leaving a clean, plain JSON Schema. We then rewrite TypeBox's | ||
| * extended types (Date, ...) into `x-mjst` hints the generators understand. | ||
| * | ||
| * We deliberately do not import TypeBox here: the conversion only touches the | ||
| * plain-object shape, so TypeBox stays an optional peer dependency used solely | ||
| * by the consumer's schema module, never by mjst itself. | ||
| */ | ||
| export const typeboxToJsonSchema = (source) => { | ||
| if (typeof source !== 'object' || source === null) { | ||
| const received = source === null ? 'null' : typeof source; | ||
| throw new Error(`TypeBox adapter expected a schema object but received ${received}.`); | ||
| } | ||
| } | ||
| return result; | ||
| // Boundary cast: JSON.parse yields `unknown`, and the round-tripped, rewritten | ||
| // TypeBox schema is a valid JSON Schema by construction. | ||
| const sanitized = JSON.parse(JSON.stringify(source)); | ||
| return rewriteExtendedTypes(sanitized); | ||
| }; | ||
| var typeboxToJsonSchema = (source) => { | ||
| if (typeof source !== "object" || source === null) { | ||
| const received = source === null ? "null" : typeof source; | ||
| throw new Error(`TypeBox adapter expected a schema object but received ${received}.`); | ||
| } | ||
| const sanitized = JSON.parse(JSON.stringify(source)); | ||
| return rewriteExtendedTypes(sanitized); | ||
| }; | ||
| export { | ||
| typeboxToJsonSchema | ||
| }; |
@@ -13,1 +13,2 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'; | ||
| export declare const valibotToJsonSchema: (source: unknown) => Promise<JSONSchema>; | ||
| //# sourceMappingURL=valibot-to-json-schema.d.ts.map |
@@ -1,676 +0,57 @@ | ||
| var __defProp = Object.defineProperty; | ||
| var __returnValue = (v) => v; | ||
| function __exportSetter(name, newValue) { | ||
| this[name] = __returnValue.bind(null, newValue); | ||
| } | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { | ||
| get: all[name], | ||
| enumerable: true, | ||
| configurable: true, | ||
| set: __exportSetter.bind(all, name) | ||
| }); | ||
| }; | ||
| var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res); | ||
| // ../../node_modules/.bun/@valibot+to-json-schema@1.7.0+731820d9428d8f81/node_modules/@valibot/to-json-schema/dist/index.mjs | ||
| var exports_dist = {}; | ||
| __export(exports_dist, { | ||
| toStandardJsonSchema: () => toStandardJsonSchema, | ||
| toJsonSchemaDefs: () => toJsonSchemaDefs, | ||
| toJsonSchema: () => toJsonSchema, | ||
| getGlobalDefs: () => getGlobalDefs, | ||
| addGlobalDefs: () => addGlobalDefs | ||
| }); | ||
| function addError(errors, message) { | ||
| if (errors) { | ||
| errors.push(message); | ||
| return errors; | ||
| } | ||
| return [message]; | ||
| } | ||
| function escapeRegExp(string) { | ||
| return string.replace(ESCAPE_REGEX, "\\$&"); | ||
| } | ||
| function handleError(message, config) { | ||
| switch (config?.errorMode) { | ||
| case "ignore": | ||
| break; | ||
| case "warn": | ||
| console.warn(message); | ||
| break; | ||
| default: | ||
| throw new Error(message); | ||
| } | ||
| } | ||
| function isJsonConstValue(value) { | ||
| return typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || typeof value === "string"; | ||
| } | ||
| function isJsonEnumValues(values) { | ||
| return values.every(isJsonConstValue); | ||
| } | ||
| function convertAction(jsonSchema, valibotAction, config) { | ||
| if (config?.ignoreActions?.includes(valibotAction.type)) | ||
| return jsonSchema; | ||
| let errors; | ||
| switch (valibotAction.type) { | ||
| case "base64": | ||
| jsonSchema.contentEncoding = "base64"; | ||
| break; | ||
| case "bic": | ||
| case "cuid2": | ||
| case "decimal": | ||
| case "digits": | ||
| case "domain": | ||
| case "emoji": | ||
| case "hash": | ||
| case "hexadecimal": | ||
| case "hex_color": | ||
| case "isrc": | ||
| case "iso_time_second": | ||
| case "iso_week": | ||
| case "mac": | ||
| case "mac48": | ||
| case "mac64": | ||
| case "nanoid": | ||
| case "octal": | ||
| case "slug": | ||
| case "ulid": | ||
| if (jsonSchema.pattern) | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`); | ||
| else | ||
| jsonSchema.pattern = valibotAction.requirement.source; | ||
| break; | ||
| case "description": | ||
| jsonSchema.description = valibotAction.description; | ||
| break; | ||
| case "email": | ||
| case "rfc_email": | ||
| jsonSchema.format = "email"; | ||
| break; | ||
| case "ends_with": | ||
| if (jsonSchema.pattern) | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`); | ||
| else | ||
| jsonSchema.pattern = `${escapeRegExp(valibotAction.requirement)}$`; | ||
| break; | ||
| case "empty": | ||
| if (jsonSchema.type === "array") | ||
| jsonSchema.maxItems = 0; | ||
| else { | ||
| if (jsonSchema.type !== "string") | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.maxLength = 0; | ||
| } | ||
| break; | ||
| case "entries": | ||
| jsonSchema.minProperties = valibotAction.requirement; | ||
| jsonSchema.maxProperties = valibotAction.requirement; | ||
| break; | ||
| case "examples": | ||
| if (Array.isArray(jsonSchema.examples)) | ||
| jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.examples]; | ||
| else | ||
| jsonSchema.examples = valibotAction.examples; | ||
| break; | ||
| case "gt_value": | ||
| if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") | ||
| errors = addError(errors, `The "gt_value" action is not supported on type "${jsonSchema.type}".`); | ||
| if (config?.target === "openapi-3.0") { | ||
| errors = addError(errors, 'The "gt_value" action is not supported for OpenAPI 3.0.'); | ||
| break; | ||
| } | ||
| jsonSchema.exclusiveMinimum = valibotAction.requirement; | ||
| break; | ||
| case "includes": | ||
| if (jsonSchema.pattern) | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`); | ||
| else | ||
| jsonSchema.pattern = escapeRegExp(valibotAction.requirement); | ||
| break; | ||
| case "integer": | ||
| jsonSchema.type = "integer"; | ||
| break; | ||
| case "ipv4": | ||
| jsonSchema.format = "ipv4"; | ||
| break; | ||
| case "ipv6": | ||
| jsonSchema.format = "ipv6"; | ||
| break; | ||
| case "iso_date": | ||
| jsonSchema.format = "date"; | ||
| break; | ||
| case "iso_date_time": | ||
| case "iso_timestamp": | ||
| jsonSchema.format = "date-time"; | ||
| break; | ||
| case "iso_time": | ||
| jsonSchema.format = "time"; | ||
| break; | ||
| case "jws_compact": | ||
| if (jsonSchema.pattern) | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`); | ||
| else | ||
| jsonSchema.pattern = valibotAction.requirement.source; | ||
| break; | ||
| case "length": | ||
| if (jsonSchema.type === "array") { | ||
| jsonSchema.minItems = valibotAction.requirement; | ||
| jsonSchema.maxItems = valibotAction.requirement; | ||
| } else { | ||
| if (jsonSchema.type !== "string") | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.minLength = valibotAction.requirement; | ||
| jsonSchema.maxLength = valibotAction.requirement; | ||
| } | ||
| break; | ||
| case "lt_value": | ||
| if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") | ||
| errors = addError(errors, `The "lt_value" action is not supported on type "${jsonSchema.type}".`); | ||
| if (config?.target === "openapi-3.0") { | ||
| errors = addError(errors, 'The "lt_value" action is not supported for OpenAPI 3.0.'); | ||
| break; | ||
| } | ||
| jsonSchema.exclusiveMaximum = valibotAction.requirement; | ||
| break; | ||
| case "max_entries": | ||
| jsonSchema.maxProperties = valibotAction.requirement; | ||
| break; | ||
| case "max_length": | ||
| if (jsonSchema.type === "array") | ||
| jsonSchema.maxItems = valibotAction.requirement; | ||
| else { | ||
| if (jsonSchema.type !== "string") | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.maxLength = valibotAction.requirement; | ||
| } | ||
| break; | ||
| case "max_value": | ||
| if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") | ||
| errors = addError(errors, `The "max_value" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.maximum = valibotAction.requirement; | ||
| break; | ||
| case "metadata": | ||
| if (typeof valibotAction.metadata.title === "string") | ||
| jsonSchema.title = valibotAction.metadata.title; | ||
| if (typeof valibotAction.metadata.description === "string") | ||
| jsonSchema.description = valibotAction.metadata.description; | ||
| if (Array.isArray(valibotAction.metadata.examples)) | ||
| if (Array.isArray(jsonSchema.examples)) | ||
| jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.metadata.examples]; | ||
| else | ||
| jsonSchema.examples = valibotAction.metadata.examples; | ||
| break; | ||
| case "min_entries": | ||
| jsonSchema.minProperties = valibotAction.requirement; | ||
| break; | ||
| case "min_length": | ||
| if (jsonSchema.type === "array") | ||
| jsonSchema.minItems = valibotAction.requirement; | ||
| else { | ||
| if (jsonSchema.type !== "string") | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.minLength = valibotAction.requirement; | ||
| } | ||
| break; | ||
| case "min_value": | ||
| if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") | ||
| errors = addError(errors, `The "min_value" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.minimum = valibotAction.requirement; | ||
| break; | ||
| case "multiple_of": | ||
| jsonSchema.multipleOf = valibotAction.requirement; | ||
| break; | ||
| case "non_empty": | ||
| if (jsonSchema.type === "array") | ||
| jsonSchema.minItems = 1; | ||
| else { | ||
| if (jsonSchema.type !== "string") | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`); | ||
| jsonSchema.minLength = 1; | ||
| } | ||
| break; | ||
| case "not_value": | ||
| if (!isJsonConstValue(valibotAction.requirement)) { | ||
| errors = addError(errors, 'The requirement of the "not_value" action is not JSON compatible.'); | ||
| break; | ||
| } | ||
| if (config?.target === "openapi-3.0") | ||
| jsonSchema.not = { enum: [valibotAction.requirement] }; | ||
| else | ||
| jsonSchema.not = { const: valibotAction.requirement }; | ||
| break; | ||
| case "not_values": | ||
| if (!isJsonEnumValues(valibotAction.requirement)) { | ||
| errors = addError(errors, 'A requirement of the "not_values" action is not JSON compatible.'); | ||
| break; | ||
| } | ||
| jsonSchema.not = { enum: valibotAction.requirement }; | ||
| break; | ||
| case "regex": | ||
| if (valibotAction.requirement.flags) | ||
| errors = addError(errors, "RegExp flags are not supported by JSON Schema."); | ||
| if (jsonSchema.pattern) | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`); | ||
| else | ||
| jsonSchema.pattern = valibotAction.requirement.source; | ||
| break; | ||
| case "safe_integer": | ||
| jsonSchema.type = "integer"; | ||
| if (typeof jsonSchema.minimum !== "number" || jsonSchema.minimum < Number.MIN_SAFE_INTEGER) | ||
| jsonSchema.minimum = Number.MIN_SAFE_INTEGER; | ||
| if (typeof jsonSchema.maximum !== "number" || jsonSchema.maximum > Number.MAX_SAFE_INTEGER) | ||
| jsonSchema.maximum = Number.MAX_SAFE_INTEGER; | ||
| break; | ||
| case "starts_with": | ||
| if (jsonSchema.pattern) | ||
| errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`); | ||
| else | ||
| jsonSchema.pattern = `^${escapeRegExp(valibotAction.requirement)}`; | ||
| break; | ||
| case "title": | ||
| jsonSchema.title = valibotAction.title; | ||
| break; | ||
| case "url": | ||
| jsonSchema.format = "uri"; | ||
| break; | ||
| case "uuid": | ||
| jsonSchema.format = "uuid"; | ||
| break; | ||
| case "value": | ||
| if (!isJsonConstValue(valibotAction.requirement)) { | ||
| errors = addError(errors, 'The requirement of the "value" action is not JSON compatible.'); | ||
| break; | ||
| } | ||
| if (config?.target === "openapi-3.0") | ||
| jsonSchema.enum = [valibotAction.requirement]; | ||
| else | ||
| jsonSchema.const = valibotAction.requirement; | ||
| break; | ||
| case "values": | ||
| if (!isJsonEnumValues(valibotAction.requirement)) { | ||
| errors = addError(errors, 'A requirement of the "values" action is not JSON compatible.'); | ||
| break; | ||
| } | ||
| jsonSchema.enum = valibotAction.requirement; | ||
| break; | ||
| default: | ||
| errors = addError(errors, `The "${valibotAction.type}" action cannot be converted to JSON Schema.`); | ||
| } | ||
| if (config?.overrideAction) { | ||
| const actionOverride = config.overrideAction({ | ||
| valibotAction, | ||
| jsonSchema, | ||
| errors | ||
| }); | ||
| if (actionOverride) | ||
| return { ...actionOverride }; | ||
| } | ||
| if (errors) | ||
| for (const message of errors) | ||
| handleError(message, config); | ||
| return jsonSchema; | ||
| } | ||
| function flattenPipe(pipe) { | ||
| return pipe.flatMap((item) => ("pipe" in item) ? flattenPipe(item.pipe) : item); | ||
| } | ||
| function convertSchema(jsonSchema, valibotSchema, config, context, skipRef = false) { | ||
| if (!skipRef) { | ||
| const referenceId = context.referenceMap.get(valibotSchema); | ||
| if (referenceId) { | ||
| jsonSchema.$ref = `#/$defs/${referenceId}`; | ||
| if (config?.overrideRef) { | ||
| const refOverride = config.overrideRef({ | ||
| ...context, | ||
| referenceId, | ||
| valibotSchema, | ||
| jsonSchema | ||
| }); | ||
| if (refOverride) | ||
| jsonSchema.$ref = refOverride; | ||
| } | ||
| return jsonSchema; | ||
| import { MJST_EXTENSION_KEY } from '@amritk/helpers/mjst-extension'; | ||
| /** | ||
| * Resolves `@valibot/to-json-schema`'s `toJsonSchema` from a runtime import, | ||
| * throwing a clear error when the converter is missing. | ||
| */ | ||
| const loadToJsonSchema = async () => { | ||
| let mod; | ||
| try { | ||
| mod = (await import('@valibot/to-json-schema')); | ||
| } | ||
| } | ||
| if ("pipe" in valibotSchema) { | ||
| const flatPipe = flattenPipe(valibotSchema.pipe); | ||
| let startIndex = 0; | ||
| let stopIndex = flatPipe.length - 1; | ||
| if (config?.typeMode === "input") { | ||
| const inputStopIndex = flatPipe.slice(1).findIndex((item) => item.kind === "schema" || item.kind === "transformation" && (item.type === "find_item" || item.type === "parse_json" || item.type === "raw_transform" || item.type === "reduce_items" || item.type === "stringify_json" || item.type === "to_bigint" || item.type === "to_boolean" || item.type === "to_date" || item.type === "to_number" || item.type === "to_string" || item.type === "transform")); | ||
| if (inputStopIndex !== -1) | ||
| stopIndex = inputStopIndex; | ||
| } else if (config?.typeMode === "output") { | ||
| const outputStartIndex = flatPipe.findLastIndex((item) => item.kind === "schema"); | ||
| if (outputStartIndex !== -1) | ||
| startIndex = outputStartIndex; | ||
| catch { | ||
| throw new Error("The Valibot adapter requires '@valibot/to-json-schema' (and 'valibot') to be installed in your project."); | ||
| } | ||
| for (let index = startIndex;index <= stopIndex; index++) { | ||
| const valibotPipeItem = flatPipe[index]; | ||
| if (valibotPipeItem.kind === "schema") { | ||
| if (index > startIndex) | ||
| handleError('Set the "typeMode" config to "input" or "output" to convert pipelines with multiple schemas.', config); | ||
| jsonSchema = convertSchema(jsonSchema, valibotPipeItem, config, context, true); | ||
| } else | ||
| jsonSchema = convertAction(jsonSchema, valibotPipeItem, config); | ||
| const named = mod['toJsonSchema']; | ||
| const fromDefault = mod['default']?.['toJsonSchema']; | ||
| const converter = typeof named === 'function' ? named : typeof fromDefault === 'function' ? fromDefault : undefined; | ||
| if (!converter) { | ||
| throw new Error("'@valibot/to-json-schema' did not export 'toJsonSchema'."); | ||
| } | ||
| return jsonSchema; | ||
| } | ||
| let errors; | ||
| switch (valibotSchema.type) { | ||
| case "boolean": | ||
| jsonSchema.type = "boolean"; | ||
| break; | ||
| case "null": | ||
| if (config?.target === "openapi-3.0") | ||
| jsonSchema.enum = [null]; | ||
| else | ||
| jsonSchema.type = "null"; | ||
| break; | ||
| case "number": | ||
| jsonSchema.type = "number"; | ||
| break; | ||
| case "string": | ||
| jsonSchema.type = "string"; | ||
| break; | ||
| case "array": | ||
| jsonSchema.type = "array"; | ||
| jsonSchema.items = convertSchema({}, valibotSchema.item, config, context); | ||
| break; | ||
| case "tuple": | ||
| case "tuple_with_rest": | ||
| case "loose_tuple": | ||
| case "strict_tuple": | ||
| jsonSchema.type = "array"; | ||
| if (config?.target === "openapi-3.0") { | ||
| jsonSchema.items = { anyOf: [] }; | ||
| jsonSchema.minItems = valibotSchema.items.length; | ||
| for (const item of valibotSchema.items) | ||
| jsonSchema.items.anyOf.push(convertSchema({}, item, config, context)); | ||
| if (valibotSchema.type === "tuple_with_rest") | ||
| jsonSchema.items.anyOf.push(convertSchema({}, valibotSchema.rest, config, context)); | ||
| else if (valibotSchema.type === "strict_tuple" || valibotSchema.type === "tuple") | ||
| jsonSchema.maxItems = valibotSchema.items.length; | ||
| } else if (config?.target === "draft-2020-12") { | ||
| jsonSchema.prefixItems = []; | ||
| jsonSchema.minItems = valibotSchema.items.length; | ||
| for (const item of valibotSchema.items) | ||
| jsonSchema.prefixItems.push(convertSchema({}, item, config, context)); | ||
| if (valibotSchema.type === "tuple_with_rest") | ||
| jsonSchema.items = convertSchema({}, valibotSchema.rest, config, context); | ||
| else if (valibotSchema.type === "strict_tuple") | ||
| jsonSchema.items = false; | ||
| } else { | ||
| jsonSchema.items = []; | ||
| jsonSchema.minItems = valibotSchema.items.length; | ||
| for (const item of valibotSchema.items) | ||
| jsonSchema.items.push(convertSchema({}, item, config, context)); | ||
| if (valibotSchema.type === "tuple_with_rest") | ||
| jsonSchema.additionalItems = convertSchema({}, valibotSchema.rest, config, context); | ||
| else if (valibotSchema.type === "strict_tuple") | ||
| jsonSchema.additionalItems = false; | ||
| } | ||
| break; | ||
| case "object": | ||
| case "object_with_rest": | ||
| case "loose_object": | ||
| case "strict_object": | ||
| jsonSchema.type = "object"; | ||
| jsonSchema.properties = {}; | ||
| jsonSchema.required = []; | ||
| for (const key in valibotSchema.entries) { | ||
| const entry = valibotSchema.entries[key]; | ||
| jsonSchema.properties[key] = convertSchema({}, entry, config, context); | ||
| if (entry.type !== "exact_optional" && entry.type !== "nullish" && entry.type !== "optional") | ||
| jsonSchema.required.push(key); | ||
| } | ||
| if (valibotSchema.type === "object_with_rest") | ||
| jsonSchema.additionalProperties = convertSchema({}, valibotSchema.rest, config, context); | ||
| else if (valibotSchema.type === "strict_object") | ||
| jsonSchema.additionalProperties = false; | ||
| break; | ||
| case "record": | ||
| if (config?.target === "openapi-3.0" && "pipe" in valibotSchema.key) | ||
| errors = addError(errors, 'The "record" schema with a schema for the key that contains a "pipe" cannot be converted to JSON Schema.'); | ||
| if (valibotSchema.key.type !== "string") | ||
| errors = addError(errors, `The "record" schema with the "${valibotSchema.key.type}" schema for the key cannot be converted to JSON Schema.`); | ||
| jsonSchema.type = "object"; | ||
| if (config?.target !== "openapi-3.0") | ||
| jsonSchema.propertyNames = convertSchema({}, valibotSchema.key, config, context); | ||
| jsonSchema.additionalProperties = convertSchema({}, valibotSchema.value, config, context); | ||
| break; | ||
| case "any": | ||
| case "unknown": | ||
| break; | ||
| case "never": | ||
| jsonSchema.not = {}; | ||
| break; | ||
| case "nullable": | ||
| case "nullish": | ||
| if (config?.target === "openapi-3.0") { | ||
| const innerSchema = convertSchema({}, valibotSchema.wrapped, config, context); | ||
| Object.assign(jsonSchema, innerSchema); | ||
| jsonSchema.nullable = true; | ||
| } else | ||
| jsonSchema.anyOf = [convertSchema({}, valibotSchema.wrapped, config, context), { type: "null" }]; | ||
| if (valibotSchema.default !== undefined) | ||
| jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default; | ||
| break; | ||
| case "exact_optional": | ||
| case "optional": | ||
| case "undefinedable": | ||
| jsonSchema = convertSchema(jsonSchema, valibotSchema.wrapped, config, context); | ||
| if (valibotSchema.default !== undefined) | ||
| jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default; | ||
| break; | ||
| case "literal": | ||
| if (typeof valibotSchema.literal !== "boolean" && typeof valibotSchema.literal !== "number" && typeof valibotSchema.literal !== "string") | ||
| errors = addError(errors, 'The value of the "literal" schema is not JSON compatible.'); | ||
| if (config?.target === "openapi-3.0") | ||
| jsonSchema.enum = [valibotSchema.literal]; | ||
| else | ||
| jsonSchema.const = valibotSchema.literal; | ||
| break; | ||
| case "enum": | ||
| jsonSchema.enum = valibotSchema.options; | ||
| if (valibotSchema.options.every((option) => typeof option === "string")) | ||
| jsonSchema.type = "string"; | ||
| else if (valibotSchema.options.every((option) => typeof option === "number")) | ||
| jsonSchema.type = "number"; | ||
| else if (config?.target !== "openapi-3.0") | ||
| jsonSchema.type = ["string", "number"]; | ||
| break; | ||
| case "picklist": { | ||
| const hasInvalidOption = valibotSchema.options.some((option) => typeof option !== "number" && typeof option !== "string"); | ||
| if (hasInvalidOption) | ||
| errors = addError(errors, 'An option of the "picklist" schema is not JSON compatible.'); | ||
| jsonSchema.enum = valibotSchema.options; | ||
| if (valibotSchema.options.every((option) => typeof option === "string")) | ||
| jsonSchema.type = "string"; | ||
| else if (valibotSchema.options.every((option) => typeof option === "number")) | ||
| jsonSchema.type = "number"; | ||
| else if (!hasInvalidOption && config?.target !== "openapi-3.0") | ||
| jsonSchema.type = ["string", "number"]; | ||
| break; | ||
| return converter; | ||
| }; | ||
| /** | ||
| * Converts a Valibot schema into a Draft 2020-12 JSON Schema via | ||
| * `@valibot/to-json-schema`. | ||
| * | ||
| * Valibot's `date` schema has no JSON Schema representation and would otherwise | ||
| * throw, so we run with `errorMode: 'ignore'` (other unsupported constructs | ||
| * degrade to an open schema rather than failing the whole conversion) and use | ||
| * the `overrideSchema` hook to rewrite dates into the shared `x-mjst` instanceOf | ||
| * extension — the same handling TypeBox and Zod dates receive. | ||
| */ | ||
| export const valibotToJsonSchema = async (source) => { | ||
| if (typeof source !== 'object' || source === null) { | ||
| const received = source === null ? 'null' : typeof source; | ||
| throw new Error(`Valibot adapter expected a Valibot schema but received ${received}.`); | ||
| } | ||
| case "union": | ||
| jsonSchema.anyOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context)); | ||
| break; | ||
| case "variant": | ||
| jsonSchema.oneOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context)); | ||
| break; | ||
| case "intersect": | ||
| jsonSchema.allOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context)); | ||
| break; | ||
| case "lazy": { | ||
| let wrappedValibotSchema = context.getterMap.get(valibotSchema.getter); | ||
| if (!wrappedValibotSchema) { | ||
| wrappedValibotSchema = valibotSchema.getter(undefined); | ||
| context.getterMap.set(valibotSchema.getter, wrappedValibotSchema); | ||
| } | ||
| let referenceId = context.referenceMap.get(wrappedValibotSchema); | ||
| if (!referenceId) { | ||
| referenceId = `${refCount++}`; | ||
| context.referenceMap.set(wrappedValibotSchema, referenceId); | ||
| context.definitions[referenceId] = convertSchema({}, wrappedValibotSchema, config, context, true); | ||
| } | ||
| jsonSchema.$ref = `#/$defs/${referenceId}`; | ||
| if (config?.overrideRef) { | ||
| const refOverride = config.overrideRef({ | ||
| ...context, | ||
| referenceId, | ||
| valibotSchema: wrappedValibotSchema, | ||
| jsonSchema | ||
| const toJsonSchema = await loadToJsonSchema(); | ||
| let json; | ||
| try { | ||
| json = toJsonSchema(source, { | ||
| errorMode: 'ignore', | ||
| overrideSchema: (ctx) => { | ||
| if (ctx.valibotSchema?.type === 'date') | ||
| return { [MJST_EXTENSION_KEY]: { instanceOf: 'Date' } }; | ||
| if (ctx.valibotSchema?.type === 'bigint') | ||
| return { [MJST_EXTENSION_KEY]: { primitive: 'bigint' } }; | ||
| return undefined; | ||
| }, | ||
| }); | ||
| if (refOverride) | ||
| jsonSchema.$ref = refOverride; | ||
| } | ||
| break; | ||
| } | ||
| default: | ||
| errors = addError(errors, `The "${valibotSchema.type}" schema cannot be converted to JSON Schema.`); | ||
| } | ||
| if (config?.overrideSchema) { | ||
| const schemaOverride = config.overrideSchema({ | ||
| ...context, | ||
| referenceId: context.referenceMap.get(valibotSchema), | ||
| valibotSchema, | ||
| jsonSchema, | ||
| errors | ||
| }); | ||
| if (schemaOverride) | ||
| return { ...schemaOverride }; | ||
| } | ||
| if (errors) | ||
| for (const message of errors) | ||
| handleError(message, config); | ||
| return jsonSchema; | ||
| } | ||
| function addGlobalDefs(definitions) { | ||
| store = { | ||
| ...store ?? {}, | ||
| ...definitions | ||
| }; | ||
| } | ||
| function getGlobalDefs() { | ||
| return store; | ||
| } | ||
| function toJsonSchema(schema, config) { | ||
| const context = { | ||
| definitions: {}, | ||
| referenceMap: /* @__PURE__ */ new Map, | ||
| getterMap: /* @__PURE__ */ new Map | ||
| }; | ||
| const definitions = config?.definitions ?? getGlobalDefs(); | ||
| if (definitions) { | ||
| for (const key in definitions) | ||
| context.referenceMap.set(definitions[key], key); | ||
| for (const key in definitions) | ||
| context.definitions[key] = convertSchema({}, definitions[key], config, context, true); | ||
| } | ||
| const jsonSchema = convertSchema({}, schema, config, context); | ||
| const target = config?.target ?? "draft-07"; | ||
| if (target === "draft-2020-12") | ||
| jsonSchema.$schema = "https://json-schema.org/draft/2020-12/schema"; | ||
| else if (target === "draft-07") | ||
| jsonSchema.$schema = "http://json-schema.org/draft-07/schema#"; | ||
| if (context.referenceMap.size) | ||
| jsonSchema.$defs = context.definitions; | ||
| return jsonSchema; | ||
| } | ||
| function toJsonSchemaDefs(definitions, config) { | ||
| const context = { | ||
| definitions: {}, | ||
| referenceMap: /* @__PURE__ */ new Map, | ||
| getterMap: /* @__PURE__ */ new Map | ||
| }; | ||
| for (const key in definitions) | ||
| context.referenceMap.set(definitions[key], key); | ||
| for (const key in definitions) | ||
| context.definitions[key] = convertSchema({}, definitions[key], config, context, true); | ||
| return context.definitions; | ||
| } | ||
| function toStandardJsonSchema(schema) { | ||
| return { "~standard": { | ||
| ...schema["~standard"], | ||
| jsonSchema: { | ||
| input(options) { | ||
| if (SUPPORTED_TARGETS.includes(options.target)) | ||
| return toJsonSchema(schema, { | ||
| typeMode: "input", | ||
| target: options.target, | ||
| ...options.libraryOptions | ||
| }); | ||
| throw new Error(`Unsupported target: ${options.target}`); | ||
| }, | ||
| output(options) { | ||
| if (SUPPORTED_TARGETS.includes(options.target)) | ||
| return toJsonSchema(schema, { | ||
| typeMode: "output", | ||
| target: options.target, | ||
| ...options.libraryOptions | ||
| }); | ||
| throw new Error(`Unsupported target: ${options.target}`); | ||
| } | ||
| catch (error) { | ||
| throw new Error(`Valibot adapter failed to convert the schema. Is it a valid Valibot schema?\n${String(error)}`); | ||
| } | ||
| } }; | ||
| } | ||
| var ESCAPE_REGEX, refCount = 0, store, SUPPORTED_TARGETS; | ||
| var init_dist = __esm(() => { | ||
| ESCAPE_REGEX = /[.*+?^${}()|[\]\\]/g; | ||
| SUPPORTED_TARGETS = [ | ||
| "draft-07", | ||
| "draft-2020-12", | ||
| "openapi-3.0" | ||
| ]; | ||
| }); | ||
| // ../helpers/dist/mjst-extension.js | ||
| var MJST_EXTENSION_KEY = "x-mjst"; | ||
| var SUPPORTED_PRIMITIVES = new Set(["bigint"]); | ||
| // src/valibot-to-json-schema.ts | ||
| var loadToJsonSchema = async () => { | ||
| let mod; | ||
| try { | ||
| mod = await Promise.resolve().then(() => (init_dist(), exports_dist)); | ||
| } catch { | ||
| throw new Error("The Valibot adapter requires '@valibot/to-json-schema' (and 'valibot') to be installed in your project."); | ||
| } | ||
| const named = mod["toJsonSchema"]; | ||
| const fromDefault = mod["default"]?.["toJsonSchema"]; | ||
| const converter = typeof named === "function" ? named : typeof fromDefault === "function" ? fromDefault : undefined; | ||
| if (!converter) { | ||
| throw new Error("'@valibot/to-json-schema' did not export 'toJsonSchema'."); | ||
| } | ||
| return converter; | ||
| // Valibot emits a draft-07 dialect marker; the generators target 2020-12. | ||
| delete json['$schema']; | ||
| return json; | ||
| }; | ||
| var valibotToJsonSchema = async (source) => { | ||
| if (typeof source !== "object" || source === null) { | ||
| const received = source === null ? "null" : typeof source; | ||
| throw new Error(`Valibot adapter expected a Valibot schema but received ${received}.`); | ||
| } | ||
| const toJsonSchema2 = await loadToJsonSchema(); | ||
| let json; | ||
| try { | ||
| json = toJsonSchema2(source, { | ||
| errorMode: "ignore", | ||
| overrideSchema: (ctx) => { | ||
| if (ctx.valibotSchema?.type === "date") | ||
| return { [MJST_EXTENSION_KEY]: { instanceOf: "Date" } }; | ||
| if (ctx.valibotSchema?.type === "bigint") | ||
| return { [MJST_EXTENSION_KEY]: { primitive: "bigint" } }; | ||
| return; | ||
| } | ||
| }); | ||
| } catch (error) { | ||
| throw new Error(`Valibot adapter failed to convert the schema. Is it a valid Valibot schema? | ||
| ${String(error)}`); | ||
| } | ||
| delete json["$schema"]; | ||
| return json; | ||
| }; | ||
| export { | ||
| valibotToJsonSchema | ||
| }; |
@@ -13,1 +13,2 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'; | ||
| export declare const zodToJsonSchema: (source: unknown) => Promise<JSONSchema>; | ||
| //# sourceMappingURL=zod-to-json-schema.d.ts.map |
+12
-12
| { | ||
| "name": "@amritk/adapters", | ||
| "version": "0.2.5", | ||
| "version": "0.2.6", | ||
| "description": "Convert schemas from external libraries (TypeBox, Zod, ...) into JSON Schema for mjst.", | ||
@@ -35,9 +35,9 @@ "type": "module", | ||
| "scripts": { | ||
| "build": "bun run build:code && bun run build:types", | ||
| "build:code": "bun build ./src/adapter.ts ./src/source-format.ts ./src/get-adapter.ts ./src/typebox-to-json-schema.ts ./src/zod-to-json-schema.ts ./src/valibot-to-json-schema.ts ./src/effect-to-json-schema.ts --outdir=dist --root=src --target=node", | ||
| "build:types": "tsc -p ." | ||
| "build": "tsgo -p tsconfig.build.json && tsc-alias -p tsconfig.build.json -f", | ||
| "types:check": "tsgo -p . --noEmit", | ||
| "test": "NODE_ENV=production vitest run --root ../.. adapters" | ||
| }, | ||
| "dependencies": { | ||
| "json-schema-typed": "^8.0.1", | ||
| "@amritk/helpers": "0.6.2" | ||
| "@amritk/helpers": "0.7.0" | ||
| }, | ||
@@ -47,3 +47,3 @@ "exports": { | ||
| "./adapter": { | ||
| "bun": "./src/adapter.ts", | ||
| "development": "./src/adapter.ts", | ||
| "default": "./dist/adapter.js", | ||
@@ -53,3 +53,3 @@ "types": "./dist/adapter.d.ts" | ||
| "./source-format": { | ||
| "bun": "./src/source-format.ts", | ||
| "development": "./src/source-format.ts", | ||
| "default": "./dist/source-format.js", | ||
@@ -59,3 +59,3 @@ "types": "./dist/source-format.d.ts" | ||
| "./get-adapter": { | ||
| "bun": "./src/get-adapter.ts", | ||
| "development": "./src/get-adapter.ts", | ||
| "default": "./dist/get-adapter.js", | ||
@@ -65,3 +65,3 @@ "types": "./dist/get-adapter.d.ts" | ||
| "./typebox-to-json-schema": { | ||
| "bun": "./src/typebox-to-json-schema.ts", | ||
| "development": "./src/typebox-to-json-schema.ts", | ||
| "default": "./dist/typebox-to-json-schema.js", | ||
@@ -71,3 +71,3 @@ "types": "./dist/typebox-to-json-schema.d.ts" | ||
| "./zod-to-json-schema": { | ||
| "bun": "./src/zod-to-json-schema.ts", | ||
| "development": "./src/zod-to-json-schema.ts", | ||
| "default": "./dist/zod-to-json-schema.js", | ||
@@ -77,3 +77,3 @@ "types": "./dist/zod-to-json-schema.d.ts" | ||
| "./valibot-to-json-schema": { | ||
| "bun": "./src/valibot-to-json-schema.ts", | ||
| "development": "./src/valibot-to-json-schema.ts", | ||
| "default": "./dist/valibot-to-json-schema.js", | ||
@@ -83,3 +83,3 @@ "types": "./dist/valibot-to-json-schema.d.ts" | ||
| "./effect-to-json-schema": { | ||
| "bun": "./src/effect-to-json-schema.ts", | ||
| "development": "./src/effect-to-json-schema.ts", | ||
| "default": "./dist/effect-to-json-schema.js", | ||
@@ -86,0 +86,0 @@ "types": "./dist/effect-to-json-schema.d.ts" |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
34
25.93%0
-100%51509
-99.15%1082
-99.34%1
Infinity%+ Added
- Removed
Updated