diff --git a/.nvmrc b/.nvmrc index 521af05..7b16f79 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v12.14.0 +v14.19.0 diff --git a/docs/API.md b/docs/API.md index 7940f37..779a439 100644 --- a/docs/API.md +++ b/docs/API.md @@ -225,6 +225,12 @@ it can be handy to arbitrary modify the schema injecting a fragment

ObjectSchema([options])StringSchema

Represents a ObjectSchema.

+
id(id)
+

It defines a URI for the schema, and the base URI that other URI references within the schema are resolved against. +Calling id on an ObjectSchema will alway set the id on the root of the object rather than in its "properties", which +differs from other schema types.

+

reference

+
additionalProperties(value)FluentSchema

This keyword determines how child instances validate for objects, and does not directly validate the immediate instance itself. Validation with "additionalProperties" applies only to the child values of instance names that do not match any names in "properties", @@ -276,10 +282,12 @@ Note the property name that the schema is testing will always be a string.

reference

only(properties)ObjectSchema
-

Returns an object schema with only a subset of keys provided

+

Returns an object schema with only a subset of keys provided. If called on an ObjectSchema with an +$id, it will be removed and the return value will be considered a new schema.

without(properties)ObjectSchema
-

Returns an object schema without a subset of keys provided

+

Returns an object schema without a subset of keys provided. If called on an ObjectSchema with an +$id, it will be removed and the return value will be considered a new schema.

definition(name, props)FluentSchema

The "definitions" keywords provides a standardized location for schema authors to inline re-usable JSON Schemas into a more general schema. @@ -951,6 +959,21 @@ Represents a ObjectSchema. | [options.schema] | [StringSchema](#StringSchema) | | Default schema | | [options.generateIds] | [boolean](#boolean) | false | generate the id automatically e.g. #properties.foo | + + +## id(id) +It defines a URI for the schema, and the base URI that other URI references within the schema are resolved against. +Calling `id` on an ObjectSchema will alway set the id on the root of the object rather than in its "properties", which +differs from other schema types. + +[reference](https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8.2) + +**Kind**: global function + +| Param | Type | Description | +| --- | --- | --- | +| id | [string](#string) | an #id | + ## additionalProperties(value) ⇒ FluentSchema @@ -1086,7 +1109,8 @@ The value of "properties" MUST be an object. Each value of this object MUST be a ## only(properties) ⇒ [ObjectSchema](#ObjectSchema) -Returns an object schema with only a subset of keys provided +Returns an object schema with only a subset of keys provided. If called on an ObjectSchema with an +`$id`, it will be removed and the return value will be considered a new schema. **Kind**: global function @@ -1097,7 +1121,8 @@ Returns an object schema with only a subset of keys provided ## without(properties) ⇒ [ObjectSchema](#ObjectSchema) -Returns an object schema without a subset of keys provided +Returns an object schema without a subset of keys provided. If called on an ObjectSchema with an +`$id`, it will be removed and the return value will be considered a new schema. **Kind**: global function diff --git a/src/ObjectSchema.js b/src/ObjectSchema.js index f9e1347..dc94852 100644 --- a/src/ObjectSchema.js +++ b/src/ObjectSchema.js @@ -36,6 +36,21 @@ const ObjectSchema = ({ schema = initialState, ...options } = {}) => { return { ...BaseSchema({ ...options, schema }), + /** + * It defines a URI for the schema, and the base URI that other URI references within the schema are resolved against. + * Calling `id` on an ObjectSchema will alway set the id on the root of the object rather than in its "properties", which + * differs from other schema types. + * + * {@link https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8.2|reference} + * @param {string} id - an #id + **/ + id: id => { + if (!id) + throw new FluentSchemaError( + `id should not be an empty fragment <#> or an empty string <> (e.g. #myId)` + ) + return options.factory({ schema: { ...schema, $id: id }, ...options }) + }, /** * This keyword determines how child instances validate for objects, and does not directly validate the immediate instance itself. * Validation with "additionalProperties" applies only to the child values of instance names that do not match any names in "properties", @@ -335,7 +350,8 @@ const ObjectSchema = ({ schema = initialState, ...options } = {}) => { }, /** - * Returns an object schema with only a subset of keys provided + * Returns an object schema with only a subset of keys provided. If called on an ObjectSchema with an + * `$id`, it will be removed and the return value will be considered a new schema. * * @param properties a list of properties you want to keep * @returns {ObjectSchema} @@ -343,7 +359,7 @@ const ObjectSchema = ({ schema = initialState, ...options } = {}) => { only: properties => { return ObjectSchema({ schema: { - ...schema, + ...omit(schema, ['$id', 'properties']), properties: schema.properties.filter(({ name }) => properties.includes(name)), required: schema.required.filter(p => properties.includes(p)) }, @@ -352,7 +368,8 @@ const ObjectSchema = ({ schema = initialState, ...options } = {}) => { }, /** - * Returns an object schema without a subset of keys provided + * Returns an object schema without a subset of keys provided. If called on an ObjectSchema with an + * `$id`, it will be removed and the return value will be considered a new schema. * * @param properties a list of properties you dont want to keep * @returns {ObjectSchema} @@ -360,7 +377,7 @@ const ObjectSchema = ({ schema = initialState, ...options } = {}) => { without: properties => { return ObjectSchema({ schema: { - ...schema, + ...omit(schema, ['$id', 'properties']), properties: schema.properties.filter(({ name }) => !properties.includes(name)), required: schema.required.filter(p => !properties.includes(p)) }, diff --git a/src/ObjectSchema.test.js b/src/ObjectSchema.test.js index 7f2ebfe..0d3e6bb 100644 --- a/src/ObjectSchema.test.js +++ b/src/ObjectSchema.test.js @@ -93,6 +93,15 @@ describe('ObjectSchema', () => { type: 'object' }) }) + it('invalid', () => { + expect(() => { + ObjectSchema().id('') + }).toThrowError( + new S.FluentSchemaError( + 'id should not be an empty fragment <#> or an empty string <> (e.g. #myId)' + ) + ) + }) }) }) @@ -213,14 +222,15 @@ describe('ObjectSchema', () => { describe('id', () => { it('valid', () => { const id = 'myId' - const prop = 'prop' expect( ObjectSchema() .prop('prop') .id(id) - .valueOf().properties[prop] + .valueOf() ).toEqual({ - $id: id + $id: id, + properties: {'prop': {}}, + type: 'object' }) }) @@ -915,7 +925,6 @@ describe('ObjectSchema', () => { expect(only.valueOf()).toEqual({ $schema: 'http://json-schema.org/draft-07/schema#', - $id: 'base', title: 'base', properties: { foo: { @@ -939,7 +948,6 @@ describe('ObjectSchema', () => { expect(only.valueOf()).toEqual({ $schema: 'http://json-schema.org/draft-07/schema#', - $id: 'base', title: 'base', properties: { foo: { @@ -974,7 +982,6 @@ describe('ObjectSchema', () => { expect(without.valueOf()).toEqual({ $schema: 'http://json-schema.org/draft-07/schema#', - $id: 'base', title: 'base', properties: { bar: { @@ -1001,7 +1008,6 @@ describe('ObjectSchema', () => { expect(without.valueOf()).toEqual({ $schema: 'http://json-schema.org/draft-07/schema#', - $id: 'base', title: 'base', properties: { baz: {