Skip to content

Commit

Permalink
feat: add uriresolver option
Browse files Browse the repository at this point in the history
  • Loading branch information
zekth committed Dec 20, 2021
1 parent d21fa70 commit f68fea2
Show file tree
Hide file tree
Showing 6 changed files with 410 additions and 368 deletions.
11 changes: 8 additions & 3 deletions lib/compile/index.ts
Expand Up @@ -257,9 +257,14 @@ export function resolveSchema(
root: SchemaEnv, // root object with properties schema, refs TODO below SchemaEnv is assigned to it
ref: string // reference to resolve
): SchemaEnv | undefined {
const p = URI.parse(ref)
const refPath = _getFullPath(p)
let baseId = getFullPath(root.baseId)
let p: URI.URIComponents
if (this.opts.uriResolver) {
p = this.opts.uriResolver.parse(ref)
} else {
p = URI.parse(ref)
}
const refPath = _getFullPath(p, this.opts.uriResolver)
let baseId = getFullPath(root.baseId, undefined, this.opts.uriResolver)
// TODO `Object.keys(root.schema).length > 0` should not be needed - but removing breaks 2 tests
if (Object.keys(root.schema).length > 0 && refPath === baseId) {
return getJsonPointer.call(this, p, root)
Expand Down
28 changes: 21 additions & 7 deletions lib/compile/resolve.ts
@@ -1,4 +1,4 @@
import type {AnySchema, AnySchemaObject} from "../types"
import type {AnySchema, AnySchemaObject, UriResolver} from "../types"
import type Ajv from "../ajv"
import {eachItem} from "./util"
import * as equal from "fast-deep-equal"
Expand Down Expand Up @@ -67,14 +67,25 @@ function countKeys(schema: AnySchemaObject): number {
return count
}

export function getFullPath(id = "", normalize?: boolean): string {
export function getFullPath(id = "", normalize?: boolean, resolver?: UriResolver): string {
if (normalize !== false) id = normalizeId(id)
const p = URI.parse(id)
return _getFullPath(p)
let p: URI.URIComponents
if (resolver !== undefined) {
p = resolver.parse(id)
} else {
p = URI.parse(id)
}
return _getFullPath(p, resolver)
}

export function _getFullPath(p: URI.URIComponents): string {
return URI.serialize(p).split("#")[0] + "#"
export function _getFullPath(p: URI.URIComponents, resolver?: UriResolver): string {
let serialized: string
if (resolver !== undefined) {
serialized = resolver.serialize(p)
} else {
serialized = URI.serialize(p)
}
return serialized.split("#")[0] + "#"
}

const TRAILING_SLASH_HASH = /#\/?$/
Expand Down Expand Up @@ -108,7 +119,10 @@ export function getSchemaRefs(this: Ajv, schema: AnySchema, baseId: string): Loc
baseIds[jsonPtr] = baseId

function addRef(this: Ajv, ref: string): string {
ref = normalizeId(baseId ? URI.resolve(baseId, ref) : ref)
const _resolve =
// eslint-disable-next-line @typescript-eslint/unbound-method
this.opts.uriResolver !== undefined ? this.opts.uriResolver?.resolve : URI.resolve
ref = normalizeId(baseId ? _resolve(baseId, ref) : ref)
if (schemaRefs.has(ref)) throw ambiguos(ref)
schemaRefs.add(ref)
let schOrRef = this.refs[ref]
Expand Down
3 changes: 2 additions & 1 deletion lib/core.ts
Expand Up @@ -49,6 +49,7 @@ import type {
Format,
AddedFormat,
RegExpEngine,
UriResolver,
} from "./types"
import type {JSONSchemaType} from "./types/json-schema"
import type {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema"
Expand All @@ -60,7 +61,6 @@ import {Code, ValueScope} from "./compile/codegen"
import {normalizeId, getSchemaRefs} from "./compile/resolve"
import {getJSONTypes} from "./compile/validate/dataType"
import {eachItem} from "./compile/util"

import * as $dataRefSchema from "./refs/data.json"

const defaultRegExp: RegExpEngine = (str, flags) => new RegExp(str, flags)
Expand Down Expand Up @@ -136,6 +136,7 @@ export interface CurrentOptions {
int32range?: boolean // JTD only
messages?: boolean
code?: CodeOptions // NEW
uriResolver?: UriResolver
}

export interface CodeOptions {
Expand Down
7 changes: 7 additions & 0 deletions lib/types/index.ts
@@ -1,3 +1,4 @@
import * as URI from "uri-js"
import type {CodeGen, Code, Name, ScopeValueSets, ValueScopeName} from "../compile/codegen"
import type {SchemaEnv, SchemaCxt, SchemaObjCxt} from "../compile"
import type {JSONType} from "../compile/rules"
Expand Down Expand Up @@ -231,3 +232,9 @@ export interface RegExpEngine {
export interface RegExpLike {
test: (s: string) => boolean
}

export interface UriResolver {
parse(uri: string): URI.URIComponents
resolve(base: string, path: string): string
serialize(component: URI.URIComponents): string
}
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -83,6 +83,7 @@
"dayjs-plugin-utc": "^0.1.2",
"eslint": "^7.8.1",
"eslint-config-prettier": "^7.0.0",
"fast-uri": "^0.0.1",
"glob": "^7.0.0",
"husky": "^7.0.1",
"if-node-version": "^1.0.0",
Expand Down

0 comments on commit f68fea2

Please sign in to comment.