diff --git a/src/djv.ts b/src/djv.ts index bc8b3a2..097963d 100644 --- a/src/djv.ts +++ b/src/djv.ts @@ -33,18 +33,58 @@ import { add, use } from './utils/environment.js'; * const env = new djv({ errorHandler: () => ';' }); * ``` */ + +export interface IOptions { + version: string; + versionConfigure?: Function; + formats?: IFormats; + inner: boolean; + errorHandler?: Function; +} + +interface IFormats { + [key: string]: Function; +} + +export interface ISchema { + id: string; + toString:(a: string) => string +} + +interface IResolve { + name: string; + schema: any; + fn: any; +} + +type INoNameResolve = Omit + class Environment { static expression = expression state: State + options: IOptions; + private defaultOptions: IOptions = { + version: 'draft-06', + inner: false, + } + resolved: { + [key: string]: IResolve + }; - constructur(this: Environment, options = {}) { - this.options = options; + constructor(options: Partial = {}) { + const enrichedOptions: IOptions = { + ...this.defaultOptions, + ...options + } + const {version, versionConfigure} = enrichedOptions; + this.options = enrichedOptions; this.resolved = {}; this.state = new State(null, this); - - this.useVersion(options.version, options.versionConfigure); - this.addFormat(options.formats); + + this.useVersion(version, versionConfigure); + formats.setFormatters(enrichedOptions.formats || {}) + } /** * check if object correspond to schema @@ -76,10 +116,9 @@ class Environment { * * @param {string?} name * @param {object} schema - * @param {object} schema * @returns {resolved} */ - addSchema(name: string, schema: object) { + addSchema(name: string, schema: ISchema): INoNameResolve { const realSchema = typeof name === 'object' ? name : schema; const resolved = { schema: realSchema, @@ -87,10 +126,10 @@ class Environment { }; [name, schema.id] - .filter(id => typeof id === 'string') - .forEach((id) => { - this.resolved[id] = Object.assign({ name: id }, resolved); - }); + // .filter(id => typeof id === 'string') + .forEach((id) => { + this.resolved[id] = Object.assign({ name: id }, resolved); + }); return resolved; } @@ -125,11 +164,11 @@ class Environment { * @param {string} name * @returns {resolved} */ - resolve(name: string) { + resolve(name: string): INoNameResolve { if (typeof name === 'object' || !this.resolved[name]) { return this.addSchema( - name, - this.state.resolve(name) + name, + this.state.resolve(name) ); } @@ -149,13 +188,13 @@ class Environment { * @returns {serializedInternalState} */ export(name: string) { - let resolved; + let resolved: any; if (name) { - resolved = this.resolve(name); + const resolvedNoName = this.resolve(name); resolved = { name, - schema: resolved.schema, - fn: resolved.fn.toString() + schema: resolvedNoName.schema, + fn: resolvedNoName.fn.toString() }; } else { resolved = {}; @@ -217,16 +256,23 @@ class Environment { * @param {string/object?} name * @param {string/function} formatter */ - addFormat(name: string, formatter: Function) { - if (typeof name === 'string') { - formats[name] = formatter; - return; - } - if (typeof name === 'object') { - Object.assign(formats, name); - } - } + + // + // addFormat(name: string | IFormats, formatter?: Function) { + // if (typeof name === 'string' && formatter) { + // formats.setFormatter(name, formatter) + // return; + // } + // + // if (typeof name === 'object') { + // formats.setFormatters() + // Object.assign(formats, name); + // } + // } + + + /** * @name setErrorHandler * @type function @@ -265,19 +311,19 @@ class Environment { */ setErrorHandler(errorHandler: Function) { Object.assign(this.options, { errorHandler }); - } + } /** - * @name useVersion - * @type {function} - * @description - * Add a specification version for environment - * A configure function is called with exposed environments, like keys, formats, etc. - * Updates internals utilities and configurations to fix versions implementation conflicts - * @param {string} version of json-schema specification to use - * @param {function} configure - * @returns void - */ - useVersion(version: string, configure: Function) { + * @name useVersion + * @type {function} + * @description + * Add a specification version for environment + * A configure function is called with exposed environments, like keys, formats, etc. + * Updates internals utilities and configurations to fix versions implementation conflicts + * @param {string} version of json-schema specification to use + * @param {function} configure + * @returns void + */ + useVersion(version: string, configure?: Function) { if (typeof configure !== 'function' && version === 'draft-04') { /* eslint-disable no-param-reassign, global-require, import/no-extraneous-dependencies */ configure = require('@korzio/djv-draft-04'); diff --git a/src/utils/environment.ts b/src/utils/environment.ts index ebaeb35..3108f40 100644 --- a/src/utils/environment.ts +++ b/src/utils/environment.ts @@ -11,13 +11,17 @@ import formats from './formats'; import { keys } from './uri'; import { transformation } from './schema'; -const environmentConfig = {}; +type envConf = { + [key: string]: Function | undefined; +} + +const environmentConfig: envConf = {}; -function add(version, config) { +function add(version: string, config: Function) { environmentConfig[version] = config; } -function use(version) { +function use(version?: string) { if (!version || !environmentConfig[version]) { return; } diff --git a/src/utils/formats.ts b/src/utils/formats.ts index f971ece..d99f787 100644 --- a/src/utils/formats.ts +++ b/src/utils/formats.ts @@ -7,7 +7,24 @@ import { expression } from './template'; -export default { +interface IFormatsFuncs { + [key: string]: Function | undefined; +} + +interface IFormatsSetters { + setFormatter: (name: string, func: Function) => void; + setFormatters: (formatters: IFormatsFuncs) => void; +} + +type IFormats = IFormatsFuncs & IFormatsSetters + +const formats: IFormats = { + setFormatter(name: string, func) { + this[name] = func + }, + setFormatters(obj: IFormatsFuncs){ + Object.assign(this, obj) + }, alpha: expression`!/^[a-zA-Z]+$/.test(${'data'})`, alphanumeric: expression`!/^[a-zA-Z0-9]+$/.test(${'data'})`, identifier: expression`!/^[-_a-zA-Z0-9]+$/.test(${'data'})`, @@ -27,3 +44,5 @@ export default { 'uri-reference': expression`!/^(?:[A-Za-z][A-Za-z0-9+\\-.]*:(?:\\/\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:]|%[0-9A-Fa-f]{2})*@)?(?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-._~!$&\'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=]|%[0-9A-Fa-f]{2})*)(?::[0-9]*)?(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|)(?:\\?(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?(?:\\#(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?|(?:\\/\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:]|%[0-9A-Fa-f]{2})*@)?(?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-._~!$&\'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=]|%[0-9A-Fa-f]{2})*)(?::[0-9]*)?(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|)(?:\\?(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?(?:\\#(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?)$/i.test(${'data'})`, 'uri-template': expression`!/^(?:(?:[^\\x00-\\x20"\'<>%\\\\^\`{|}]|%[0-9a-f]{2})|\\{[+#.\\/;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?:\\:[1-9][0-9]{0,3}|\\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?:\\:[1-9][0-9]{0,3}|\\*)?)*\\})*$/i.test(${'data'})`, }; + +export default formats diff --git a/src/utils/index.ts b/src/utils/index.ts index 750551c..24dd2ae 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -4,6 +4,8 @@ * Basic utilities for djv project */ +import {ISchema} from "../djv"; + /** * @name asExpression * @type {function} @@ -15,7 +17,7 @@ * @param {object} tpl templater instance * @returns {string} expression */ -function asExpression(fn, schema, tpl) { +function asExpression(fn: Function, schema: ISchema, tpl) { if (typeof fn !== 'function') { return fn; } diff --git a/src/utils/state.ts b/src/utils/state.ts index a10917f..20c5a2b 100644 --- a/src/utils/state.ts +++ b/src/utils/state.ts @@ -9,37 +9,18 @@ import { hasProperty } from './'; import { normalize, makePath, head, isFullUri, fragment, keys } from './uri'; import { is as isSchema, transform as transformSchema, Schema } from './schema'; import { Validators } from '../validators'; +import Environment, {IOptions, ISchema} from "../djv"; -function State(schema: Schema = {}, env) { - Object.assign(this, { - context: [], - entries: new Map(), - env, - }); -} -/** - * @name generate - * @type {function} - * @description - * The main schema process function. - * Available and used both in external and internal generation. - * Saves the state for internal recursive calls. - * @param {object} env - djv environment - * @param {object} schema - to process - * @param {State} state - saved state - * @param {Environment} options - * @returns {function} restoredFunction - */ -function generate(env, schema, state = new State(schema, env), options) { - const tpl = template(state, options); - tpl.visit(schema); - - const source = body(tpl, state, options); - return restore(source, schema, options); -} - -State.prototype = Object.assign(Object.create(Array.prototype), { +class State { + context: any[]; + entries: Map + env: any; + constructor(schema: Schema | null = {}, env: Environment) { + this.context = []; + this.entries = new Map(); + this.env = env; + } /** * @name addEntry * @type {function} @@ -52,7 +33,7 @@ State.prototype = Object.assign(Object.create(Array.prototype), { * @param {object} schema * @returns {number/boolean} index */ - addEntry(url, schema) { + addEntry(url: string, schema: ISchema) { let entry = this.entries.get(schema); if (entry === false) { // has already been added to process queue @@ -69,7 +50,7 @@ State.prototype = Object.assign(Object.create(Array.prototype), { } return this.context.push(entry); - }, + } /** * @name revealReference * @type {function} @@ -79,15 +60,15 @@ State.prototype = Object.assign(Object.create(Array.prototype), { * @param {object} schema * @returns {void} */ - revealReference(schema) { + revealReference(schema: ISchema) { for ( - let doubled = this.context.indexOf(schema); - doubled !== -1; - doubled = this.context.indexOf(schema) + let doubled = this.context.indexOf(schema); + doubled !== -1; + doubled = this.context.indexOf(schema) ) { this.context[doubled] = this.context.length; } - }, + } /** * @name link * @type {function} @@ -96,11 +77,11 @@ State.prototype = Object.assign(Object.create(Array.prototype), { * @param {string} url * @returns {string} entry */ - link(url) { + link(url: string) { const schema = this.resolve(url); const entry = this.addEntry(url, schema); return entry; - }, + } /** * @name resolveReference * @type {function} @@ -140,7 +121,7 @@ State.prototype = Object.assign(Object.create(Array.prototype), { // attach reference and make path const path = makePath([lastFullURIReference, ...partialReferences, reference]); return path; - }, + } /** * @name ascend * @private @@ -157,18 +138,18 @@ State.prototype = Object.assign(Object.create(Array.prototype), { // Search while it is a full schema, not a ref while ( - parentSchema.$ref && - // avoid infinite loop - head(parentSchema.$ref) !== head(reference) && - // > All other properties in a "$ref" object MUST be ignored. - // @see https://tools.ietf.org/html/draft-wright-json-schema-01#section-8 - Object.keys(parentSchema).length === 1 - ) { + parentSchema.$ref && + // avoid infinite loop + head(parentSchema.$ref) !== head(reference) && + // > All other properties in a "$ref" object MUST be ignored. + // @see https://tools.ietf.org/html/draft-wright-json-schema-01#section-8 + Object.keys(parentSchema).length === 1 + ) { parentSchema = this.ascend(parentSchema.$ref); } return parentSchema; - }, + } /** * @name descend * @private @@ -191,27 +172,27 @@ State.prototype = Object.assign(Object.create(Array.prototype), { const parts = uriFragment.split('/'); const currentSchema = parts - .map(normalize) - .reduce((schema, part, index) => { - let subSchema = schema[part]; - if (!isSchema(subSchema)) { - subSchema = schema.definitions && schema.definitions[part]; - } + .map(normalize) + .reduce((schema, part, index) => { + let subSchema = schema[part]; + if (!isSchema(subSchema)) { + subSchema = schema.definitions && schema.definitions[part]; + } - if ( - // last will be pushed on visit - // @see /draft4/refRemote.json:http://localhost:1234/scope_change_defs2.json - index !== parts.length - 1 && - hasProperty(subSchema, keys.id) - ) { - this.push(subSchema); - } + if ( + // last will be pushed on visit + // @see /draft4/refRemote.json:http://localhost:1234/scope_change_defs2.json + index !== parts.length - 1 && + hasProperty(subSchema, keys.id) + ) { + this.push(subSchema); + } - return subSchema; - }, parentSchema); + return subSchema; + }, parentSchema); return isSchema(currentSchema) ? currentSchema : parentSchema; - }, + } /** * @name resolve * @type {function} @@ -230,7 +211,7 @@ State.prototype = Object.assign(Object.create(Array.prototype), { const subSchema = this.descend(reference, parentSchema); return subSchema; - }, + } /** * @name visit * @type {function} @@ -247,13 +228,34 @@ State.prototype = Object.assign(Object.create(Array.prototype), { this.push(schema); Validators.list.some(validator => ( - /// - validator(schema, tpl) + /// + validator(schema, tpl) )); this.length = initialLength; - }, -}); + } +} + +/** + * @name generate + * @type {function} + * @description + * The main schema process function. + * Available and used both in external and internal generation. + * Saves the state for internal recursive calls. + * @param {object} env - djv environment + * @param {object} schema - to process + * @param {State} state - saved state + * @param {Environment} options + * @returns {function} restoredFunction + */ +function generate(env: Environment, schema: ISchema, state: State = new State(schema, env), options: IOptions) { + const tpl = template(state, options); + tpl.visit(schema); + + const source = body(tpl, state, options); + return restore(source, schema, options); +} export { State, diff --git a/src/utils/template.ts b/src/utils/template.ts index 5995e0e..d93820b 100644 --- a/src/utils/template.ts +++ b/src/utils/template.ts @@ -4,6 +4,9 @@ * Defines a small templater functionality for creating functions body. */ +import {State} from "./state"; +import {IOptions, ISchema} from "../djv"; + /** * @name template * @type function @@ -20,25 +23,31 @@ export type TemplaterData = Array export interface Templater { (expression: string, ...args: any[]): Templater; cachedIndex: number; + cached: any[], + schema: ISchema; + cache: (v: string) => string; data: TemplaterData; - error(errorType: string, data: TemplaterData): string + error(errorType: string, data: TemplaterData): string; + lines: string[]; + link: (l:string) => string; + visit: (schema: any) => void; } -function template(state, options) { - const tpl: Templater = (expression, ...args) => { - let last; +function template(state: State, options: IOptions): Templater { + const tpl: Templater = (expression: string, ...args: any[]) => { + let last: string; tpl.lines.push( - expression - .replace(/%i/g, () => 'i') - .replace(/\$(\d)/g, (match, index) => `${args[index - 1]}`) - .replace(/(%[sd])/g, () => { - if (args.length) { - last = args.shift(); - } - - return `${last}`; - }) + expression + .replace(/%i/g, () => 'i') + .replace(/\$(\d)/g, (match, index) => `${args[index - 1]}`) + .replace(/(%[sd])/g, () => { + if (args.length) { + last = args.shift(); + } + + return `${last}`; + }) ); return tpl; @@ -46,38 +55,38 @@ function template(state, options) { function clearDecode(tplString: string) { return tplString - .replace('[', '') - .replace(']', '') - .replace('(', '') - .replace(')', '') - .replace('decodeURIComponent', ''); + .replace('[', '') + .replace(']', '') + .replace('(', '') + .replace(')', '') + .replace('decodeURIComponent', ''); } const error = typeof options.errorHandler === 'function' ? - options.errorHandler : - function defaultErrorHandler(errorType) { - const path = this.data.toString() - .replace(/^data/, ''); - const dataPath = path - .replace(/\['([^']+)'\]/ig, '.$1') - .replace(/\[(i[0-9]*)\]/ig, '[\'+$1+\']'); - const schemaPath = `#${ - path - .replace(/\[i([0-9]*)\]/ig, '/items') - .replace(/\['([^']+)'\]/ig, '/properties/$1') + options.errorHandler : + function defaultErrorHandler(errorType: string) { + const path = this.data.toString() + .replace(/^data/, ''); + const dataPath = path + .replace(/\['([^']+)'\]/ig, '.$1') + .replace(/\[(i[0-9]*)\]/ig, '[\'+$1+\']'); + const schemaPath = `#${ + path + .replace(/\[i([0-9]*)\]/ig, '/items') + .replace(/\['([^']+)'\]/ig, '/properties/$1') }/${errorType}`; - return `return { + return `return { keyword: '${errorType}', dataPath: decodeURIComponent("${clearDecode(dataPath)}"), schemaPath: decodeURIComponent("${clearDecode(schemaPath)}") };`; - }; + }; Object.assign(tpl, { cachedIndex: 0, cached: [], - cache(expression) { + cache(expression: string) { const layer = tpl.cached[tpl.cached.length - 1]; if (layer[expression]) { return `i${layer[expression]}`; @@ -101,7 +110,7 @@ function template(state, options) { * @param {string} url * @return {string} functionName */ - link(url) { + link(url: string) { return `f${state.link(url)}`; }, /** @@ -112,14 +121,14 @@ function template(state, options) { * @param {object} schema * @return {void} */ - visit(schema) { + visit(schema: ISchema) { tpl.cached.push({}); state.visit(schema, tpl); tpl.cached.pop(); }, }); - function dataToString() { + function dataToString(this: string[]) { return this.join('.').replace(/\.\[/g, '['); } tpl.data.toString = dataToString; @@ -173,17 +182,17 @@ function restore(source, schema, { inner } = {}) { * @param {TemplateOptions} options * @return {string} variables */ -function makeVariables({ defineErrors, index }) { +function makeVariables({ defineErrors, index }: {index: number; defineErrors: boolean}) { /** * @var {array} errors - empty array for pushing errors ability * @see errorHandler */ const errors = defineErrors ? 'const errors = [];' : ''; const variables = index ? - `let i${Array(...Array(index)) - .map((value, i) => i + 1) - .join(',i')};` : - ''; + `let i${Array(...Array(index)) + .map((value, i) => i + 1) + .join(',i')};` : + ''; // @see map array with holes trick // http://2ality.com/2013/11/initializing-arrays.html @@ -204,22 +213,22 @@ function makeVariables({ defineErrors, index }) { * @param {TemplateOptions} options * @return {string} functions */ -function makeHelpers({ context, inner }) { +function makeHelpers({ context, inner }: {context: string[]; inner: string}) { if (inner || !context.length) { return ''; } - const functions = []; - const references = []; + const functions: string[] = []; + const references: string[] = []; context - .forEach((value, i) => { - if (typeof value === 'number') { - references.push(`${i + 1} = f${value + 1}`); - return; - } - functions.push(`${i + 1} = ${value}`); - }); + .forEach((value, i) => { + if (typeof value === 'number') { + references.push(`${i + 1} = f${value + 1}`); + return; + } + functions.push(`${i + 1} = ${value}`); + }); return `const f${functions.concat(references).join(', f')};`; } @@ -234,7 +243,10 @@ function makeHelpers({ context, inner }) { * @param {TemplateOptions} options * @return {string} functions */ -function makeContent(options) { +function makeContent(options: { + lines: string[]; + defineErrors: boolean; +}) { const { defineErrors, lines } = options; const variables = makeVariables(options); @@ -289,7 +301,7 @@ function body({ cachedIndex, lines }, { context }, { inner, errorHandler } = {}) * Transforms a validator utilities into generated functions body * @return {function} template */ -function templateExpression(strings, ...keys) { +function templateExpression(strings: string[], ...keys: any[]) { return (...values) => { let dict = values[values.length - 1] || {}; let result = [strings[0]]; diff --git a/src/utils/uri.ts b/src/utils/uri.ts index ff5d568..6da7ceb 100644 --- a/src/utils/uri.ts +++ b/src/utils/uri.ts @@ -28,7 +28,7 @@ const keys = { * @param {string} id * @returns {string} cleaned */ -function head(uri) { +function head(uri?: string) { if (typeof uri !== 'string') { return uri; } @@ -37,7 +37,7 @@ function head(uri) { return parts[0]; } -function isFullUri(uri) { +function isFullUri(uri: string) { return REGEXP_URI.test(uri); } @@ -52,7 +52,7 @@ function isFullUri(uri) { * @param {string} uri * @returns {string} path */ -function path(uri) { +function path(uri: string) { return uri.replace(REGEXP_URI_PATH, '$1'); } @@ -63,7 +63,7 @@ function path(uri) { * @param {string} uri * @returns {string} fragment */ -function fragment(uri) { +function fragment(uri?: string) { if (typeof uri !== 'string') { return uri; } @@ -81,7 +81,7 @@ function fragment(uri) { * @param {array} parts * @returns {string} uri */ -function makePath(parts) { +function makePath(parts: string[]) { return parts .filter(part => typeof part === 'string') .reduce((uri, id) => { @@ -119,7 +119,7 @@ function makePath(parts) { * @param {string} uri * @returns {string} normalizedUri */ -function normalize(uri) { +function normalize(uri: string) { return decodeURIComponent(uri.replace(/~1/g, '/').replace(/~0/g, '~')); }