Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@amritk/helpers

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@amritk/helpers - npm Package Compare versions

Comparing version
0.7.1
to
0.8.0
+17
dist/escape-regex-pattern.d.ts
/**
* Escapes a JSON Schema `pattern` so it can be embedded between the slashes of
* a generated regex literal (`/…/`).
*
* A `pattern` is an ECMA-262 regex *body*, and the generated text goes into a
* regex literal — not a string literal — so backslashes are regex syntax and
* must be left exactly as-is (doubling `\d` to `\\d` would change it from "a
* digit" to "a literal backslash followed by d"). The only character that would
* corrupt the surrounding literal is an *unescaped* `/`, which would close it
* early. So we escape bare slashes to `\/` while leaving every existing escape
* sequence (including an already-escaped `\/`) untouched.
*
* @example
* escapeRegexPattern('\\d{4}/\\d{2}') // → '\\d{4}\\/\\d{2}' (i.e. \d{4}\/\d{2})
*/
export declare const escapeRegexPattern: (pattern: string) => string;
//# sourceMappingURL=escape-regex-pattern.d.ts.map
{"version":3,"file":"escape-regex-pattern.d.ts","sourceRoot":"","sources":["../src/escape-regex-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB,YAAa,MAAM,KAAG,MAIwB,CAAA"}
/**
* Escapes a JSON Schema `pattern` so it can be embedded between the slashes of
* a generated regex literal (`/…/`).
*
* A `pattern` is an ECMA-262 regex *body*, and the generated text goes into a
* regex literal — not a string literal — so backslashes are regex syntax and
* must be left exactly as-is (doubling `\d` to `\\d` would change it from "a
* digit" to "a literal backslash followed by d"). The only character that would
* corrupt the surrounding literal is an *unescaped* `/`, which would close it
* early. So we escape bare slashes to `\/` while leaving every existing escape
* sequence (including an already-escaped `\/`) untouched.
*
* @example
* escapeRegexPattern('\\d{4}/\\d{2}') // → '\\d{4}\\/\\d{2}' (i.e. \d{4}\/\d{2})
*/
export const escapeRegexPattern = (pattern) =>
// Match either an escape sequence (`\` + any char, kept verbatim) or a bare
// `/` (escaped). Consuming escape pairs first means the slash in `\/` is never
// seen as bare, so it is not double-escaped.
pattern.replace(/\\[\s\S]|\//g, (match) => (match === '/' ? '\\/' : match));
import { describe, expect, it } from 'vitest'
import { escapeRegexPattern } from './escape-regex-pattern'
describe('escape-regex-pattern', () => {
it('escapes bare forward slashes so the regex literal does not close early', () => {
expect(escapeRegexPattern('a/b')).toBe('a\\/b')
// Input \d{4}/\d{2}/\d{2} → \d{4}\/\d{2}\/\d{2}
expect(escapeRegexPattern('\\d{4}/\\d{2}/\\d{2}')).toBe('\\d{4}\\/\\d{2}\\/\\d{2}')
})
it('leaves backslash escape sequences exactly as-is (does not double them)', () => {
// \d must stay \d — doubling it would match a literal backslash, not a digit.
expect(escapeRegexPattern('\\d+')).toBe('\\d+')
expect(escapeRegexPattern('\\w\\s')).toBe('\\w\\s')
})
it('does not double-escape an already-escaped slash', () => {
// \/ (escaped slash) stays \/, not \\\/.
expect(escapeRegexPattern('\\/')).toBe('\\/')
})
it('leaves regex metacharacters that do not affect the literal untouched', () => {
expect(escapeRegexPattern('^[a-z]+$')).toBe('^[a-z]+$')
})
it('round-trips: the escaped body parses to a regex equivalent to the source pattern', () => {
for (const pattern of ['\\d{4}/\\d{2}', 'a/b/c', '^https?:\\/\\/', '\\w+@\\w+']) {
// Build the literal the generator emits and read its source back out.
const re = new RegExp(escapeRegexPattern(pattern))
// The RegExp's own source, with \/ normalized back to /, equals the input.
expect(re.source.replace(/\\\//g, '/')).toBe(pattern.replace(/\\\//g, '/'))
}
})
})
/**
* Escapes a JSON Schema `pattern` so it can be embedded between the slashes of
* a generated regex literal (`/…/`).
*
* A `pattern` is an ECMA-262 regex *body*, and the generated text goes into a
* regex literal — not a string literal — so backslashes are regex syntax and
* must be left exactly as-is (doubling `\d` to `\\d` would change it from "a
* digit" to "a literal backslash followed by d"). The only character that would
* corrupt the surrounding literal is an *unescaped* `/`, which would close it
* early. So we escape bare slashes to `\/` while leaving every existing escape
* sequence (including an already-escaped `\/`) untouched.
*
* @example
* escapeRegexPattern('\\d{4}/\\d{2}') // → '\\d{4}\\/\\d{2}' (i.e. \d{4}\/\d{2})
*/
export const escapeRegexPattern = (pattern: string): string =>
// Match either an escape sequence (`\` + any char, kept verbatim) or a bare
// `/` (escaped). Consuming escape pairs first means the slash in `\/` is never
// seen as bare, so it is not double-escaped.
pattern.replace(/\\[\s\S]|\//g, (match) => (match === '/' ? '\\/' : match))
+4
-3

@@ -9,7 +9,8 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12';

*
* Only the direct properties and their nested schemas are walked — this does not need
* to be infinitely deep because the build system generates separate files for each $def,
* so each schema is relatively shallow.
* Walks both object properties and array elements, so a `$dynamicRef` nested
* inside a keyword whose value is an array of subschemas (`allOf`, `anyOf`,
* `oneOf`, `prefixItems`, …) is rewritten too. The build system generates a
* separate file per `$def`, so each schema walked here is relatively shallow.
*/
export declare const resolveDynamicRefs: (schema: JSONSchema, dynamicRefMap: Record<string, string>) => JSONSchema;
//# sourceMappingURL=resolve-dynamic-refs.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"resolve-dynamic-refs.d.ts","sourceRoot":"","sources":["../src/resolve-dynamic-refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,WAAY,UAAU,iBAAiB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,UAkC9F,CAAA"}
{"version":3,"file":"resolve-dynamic-refs.d.ts","sourceRoot":"","sources":["../src/resolve-dynamic-refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,WAAY,UAAU,iBAAiB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,UAuC9F,CAAA"}

@@ -8,5 +8,6 @@ /**

*
* Only the direct properties and their nested schemas are walked — this does not need
* to be infinitely deep because the build system generates separate files for each $def,
* so each schema is relatively shallow.
* Walks both object properties and array elements, so a `$dynamicRef` nested
* inside a keyword whose value is an array of subschemas (`allOf`, `anyOf`,
* `oneOf`, `prefixItems`, …) is rewritten too. The build system generates a
* separate file per `$def`, so each schema walked here is relatively shallow.
*/

@@ -23,5 +24,10 @@ export const resolveDynamicRefs = (schema, dynamicRefMap) => {

const walk = (obj) => {
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
if (typeof obj !== 'object' || obj === null) {
return;
}
if (Array.isArray(obj)) {
for (const item of obj)
walk(item);
return;
}
const record = obj;

@@ -28,0 +34,0 @@ if ('$dynamicRef' in record && typeof record['$dynamicRef'] === 'string') {

@@ -111,3 +111,11 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12';

};
/** Type guard to check if schema has dependentRequired (2020-12). */
export declare const hasDependentRequired: (schema: JSONSchema) => schema is SchemaObject & {
dependentRequired: Record<string, readonly string[]>;
};
/** Type guard to check if schema has a propertyNames subschema. */
export declare const hasPropertyNames: (schema: JSONSchema) => schema is SchemaObject & {
propertyNames: JSONSchema;
};
export { hasRef } from './has-ref.js';
//# sourceMappingURL=schema-guards.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"schema-guards.d.ts","sourceRoot":"","sources":["../src/schema-guards.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"schema-guards.d.ts","sourceRoot":"","sources":["../src/schema-guards.ts"],"names":[],"mappings":"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"}

@@ -120,2 +120,13 @@ /** Type guard to check if schema is not false */

};
/** Type guard to check if schema has dependentRequired (2020-12). */
export const hasDependentRequired = (schema) => {
return (isSchemaObject(schema) &&
'dependentRequired' in schema &&
typeof schema.dependentRequired === 'object' &&
schema.dependentRequired !== null);
};
/** Type guard to check if schema has a propertyNames subschema. */
export const hasPropertyNames = (schema) => {
return isSchemaObject(schema) && 'propertyNames' in schema;
};
export { hasRef } from './has-ref.js';
{
"name": "@amritk/helpers",
"version": "0.7.1",
"version": "0.8.0",
"description": "Shared utilities for the mjst code generation ecosystem.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -70,2 +70,14 @@ import { describe, expect, it } from 'vitest'

it('replaces $dynamicRef nested inside an array keyword (allOf)', () => {
const schema = {
allOf: [{ $dynamicRef: '#meta' }, { type: 'object' as const, properties: { x: { $dynamicRef: '#meta' } } }],
}
const result = resolveDynamicRefs(schema, { '#meta': '#/$defs/schema' })
expect(result).toEqual({
allOf: [{ $ref: '#/$defs/schema' }, { type: 'object', properties: { x: { $ref: '#/$defs/schema' } } }],
})
})
it('handles nested $dynamicRef in property sub-schemas', () => {

@@ -72,0 +84,0 @@ const schema = {

@@ -10,5 +10,6 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'

*
* Only the direct properties and their nested schemas are walked — this does not need
* to be infinitely deep because the build system generates separate files for each $def,
* so each schema is relatively shallow.
* Walks both object properties and array elements, so a `$dynamicRef` nested
* inside a keyword whose value is an array of subschemas (`allOf`, `anyOf`,
* `oneOf`, `prefixItems`, …) is rewritten too. The build system generates a
* separate file per `$def`, so each schema walked here is relatively shallow.
*/

@@ -28,6 +29,11 @@ export const resolveDynamicRefs = (schema: JSONSchema, dynamicRefMap: Record<string, string>): JSONSchema => {

const walk = (obj: unknown): void => {
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
if (typeof obj !== 'object' || obj === null) {
return
}
if (Array.isArray(obj)) {
for (const item of obj) walk(item)
return
}
const record = obj as Record<string, unknown>

@@ -34,0 +40,0 @@

@@ -10,2 +10,3 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'

hasDefault,
hasDependentRequired,
hasEnum,

@@ -29,2 +30,3 @@ hasExamples,

hasProperties,
hasPropertyNames,
hasRef,

@@ -391,2 +393,21 @@ hasRequired,

// hasDependentRequired
it('hasDependentRequired returns true for an object value', () => {
expect(hasDependentRequired({ dependentRequired: { a: ['b'] } })).toBe(true)
})
it('hasDependentRequired returns false when missing or non-object', () => {
expect(hasDependentRequired({})).toBe(false)
expect(hasDependentRequired({ dependentRequired: null } as unknown as JSONSchema)).toBe(false)
})
// hasPropertyNames
it('hasPropertyNames returns true when the keyword is present', () => {
expect(hasPropertyNames({ propertyNames: { pattern: '^[a-z]+$' } })).toBe(true)
})
it('hasPropertyNames returns false when missing', () => {
expect(hasPropertyNames({})).toBe(false)
})
// hasRef

@@ -393,0 +414,0 @@ it('hasRef returns true when $ref is a string', () => {

@@ -160,2 +160,19 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12'

/** Type guard to check if schema has dependentRequired (2020-12). */
export const hasDependentRequired = (
schema: JSONSchema,
): schema is SchemaObject & { dependentRequired: Record<string, readonly string[]> } => {
return (
isSchemaObject(schema) &&
'dependentRequired' in schema &&
typeof schema.dependentRequired === 'object' &&
schema.dependentRequired !== null
)
}
/** Type guard to check if schema has a propertyNames subschema. */
export const hasPropertyNames = (schema: JSONSchema): schema is SchemaObject & { propertyNames: JSONSchema } => {
return isSchemaObject(schema) && 'propertyNames' in schema
}
export { hasRef } from './has-ref'