Skip to content

Commit 0a60a23

Browse files
authored
Merge pull request #325 from eemeli/customy
2 parents daaa5b4 + e35f950 commit 0a60a23

File tree

8 files changed

+94
-15
lines changed

8 files changed

+94
-15
lines changed

docs/03_options.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ The `!!value` and `!!yaml` types are not supported.
7171

7272
Used by: `parse()`, `parseDocument()`, `parseAllDocuments()`, `stringify()`, `new Composer()`, `new Document()`, and `doc.setSchema()`
7373

74-
| Name | Type | Default | Description |
75-
| ---------------- | --------------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76-
| customTags | `Tag[] ⎮ function` | | Array of [additional tags](#custom-data-types) to include in the schema |
77-
| merge | `boolean` | 1.1:&nbsp;`true` 1.2:&nbsp;`false` | Enable support for `<<` merge keys. Default value depends on YAML version. |
78-
| resolveKnownTags | `boolean` | `true` | When using the `'core'` schema, support parsing values with these explicit [YAML 1.1 tags]: `!!binary`, `!!omap`, `!!pairs`, `!!set`, `!!timestamp`. By default `true`. |
79-
| schema | `'core' ⎮ 'failsafe' ⎮` `'json' ⎮ 'yaml-1.1'` | 1.1:&nbsp;`'yaml-1.1` 1.2:&nbsp;`'core'` | The base schema to use. Default value depends on YAML version. |
80-
| sortMapEntries | `boolean ⎮` `(a, b: Pair) => number` | `false` | When stringifying, sort map entries. If `true`, sort by comparing key values using the native less-than `<` operator. |
74+
| Name | Type | Default | Description |
75+
| ---------------- | ------------------------------------------------------ | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76+
| customTags | `Tag[] ⎮ function` | | Array of [additional tags](#custom-data-types) to include in the schema |
77+
| merge | `boolean` | 1.1:&nbsp;`true` 1.2:&nbsp;`false` | Enable support for `<<` merge keys. Default value depends on YAML version. |
78+
| resolveKnownTags | `boolean` | `true` | When using the `'core'` schema, support parsing values with these explicit [YAML 1.1 tags]: `!!binary`, `!!omap`, `!!pairs`, `!!set`, `!!timestamp`. By default `true`. |
79+
| schema | `'core' ⎮ 'failsafe' ⎮` `'json' ⎮ 'yaml-1.1' ⎮ string` | 1.1:&nbsp;`'yaml-1.1` 1.2:&nbsp;`'core'` | The base schema to use. Default value depends on YAML version. If using a custom value, `customTags` must be an array of tags. |
80+
| sortMapEntries | `boolean ⎮` `(a, b: Pair) => number` | `false` | When stringifying, sort map entries. If `true`, sort by comparing key values using the native less-than `<` operator. |
8181

8282
[yaml 1.1 tags]: https://yaml.org/type/
8383

docs/06_custom_tags.md

+3
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ import {
137137
debug, // (logLevel, ...messages) => void -- Log debug messages to console
138138
findPair, // (items, key) => Pair? -- Given a key, find a matching Pair
139139
foldFlowLines, // (text, indent, mode, options) => string -- Fold long lines
140+
mapTag, // CollectionTag
141+
seqTag, // CollectionTag
142+
stringTag, // ScalarTag
140143
stringifyNumber, // (node) => string
141144
stringifyString, // (node, ctx, ...) => string
142145
toJS, // (value, arg, ctx) => any -- Recursively convert to plain JS

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"files": [
1515
"browser/",
1616
"dist/",
17+
"util.d.ts",
1718
"util.js"
1819
],
1920
"type": "commonjs",

src/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export { Composer } from './compose/composer.js'
33
export { Document } from './doc/Document.js'
44
export { Schema } from './schema/Schema.js'
55

6-
export { YAMLError, YAMLParseError, YAMLWarning } from './errors.js'
6+
export { ErrorCode, YAMLError, YAMLParseError, YAMLWarning } from './errors.js'
77

88
export { Alias } from './nodes/Alias.js'
99
export {
@@ -16,7 +16,8 @@ export {
1616
isScalar,
1717
isSeq,
1818
Node,
19-
ParsedNode
19+
ParsedNode,
20+
Range
2021
} from './nodes/Node.js'
2122
export { Pair } from './nodes/Pair.js'
2223
export { Scalar } from './nodes/Scalar.js'

src/schema/tags.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,16 @@ export function getTags(
6363
) {
6464
let tags: Tags = schemas[schemaName]
6565
if (!tags) {
66-
const keys = Object.keys(schemas)
67-
.filter(key => key !== 'yaml11')
68-
.map(key => JSON.stringify(key))
69-
.join(', ')
70-
throw new Error(`Unknown schema "${schemaName}"; use one of ${keys}`)
66+
if (Array.isArray(customTags)) tags = []
67+
else {
68+
const keys = Object.keys(schemas)
69+
.filter(key => key !== 'yaml11')
70+
.map(key => JSON.stringify(key))
71+
.join(', ')
72+
throw new Error(
73+
`Unknown schema "${schemaName}"; use one of ${keys} or define customTags array`
74+
)
75+
}
7176
}
7277

7378
if (Array.isArray(customTags)) {

src/util.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
export { debug, LogLevelId, warn } from './log.js'
22
export { findPair } from './nodes/YAMLMap.js'
33
export { toJS, ToJSContext } from './nodes/toJS.js'
4+
export { map as mapTag } from './schema/common/map.js'
5+
export { seq as seqTag } from './schema/common/seq.js'
6+
export { string as stringTag } from './schema/common/string.js'
47
export { foldFlowLines } from './stringify/foldFlowLines'
58
export { stringifyNumber } from './stringify/stringifyNumber.js'
69
export { stringifyString } from './stringify/stringifyString.js'

tests/doc/types.js

+64-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as YAML from 'yaml'
22
import { Scalar, YAMLSeq } from 'yaml'
3-
import { stringifyString } from 'yaml/util'
3+
import { seqTag, stringTag, stringifyString } from 'yaml/util'
44
import { source } from '../_utils'
55

66
describe('json schema', () => {
@@ -774,6 +774,69 @@ describe('custom tags', () => {
774774
const str = YAML.stringify(obj, { customTags: [[regexp, sharedSymbol]] })
775775
expect(str).toBe('re: !re /re/g\nsymbol: !symbol/shared foo\n')
776776
})
777+
778+
describe('completely custom schema', () => {
779+
test('customTags is required', () => {
780+
expect(() =>
781+
YAML.parseDocument('foo', { schema: 'custom-test' })
782+
).toThrow(/Unknown schema "custom-test"/)
783+
})
784+
785+
test('parse success', () => {
786+
const src = '- foo\n- !re /bar/\n'
787+
const doc = YAML.parseDocument(src, {
788+
customTags: [seqTag, stringTag, regexp],
789+
schema: 'custom-test'
790+
})
791+
expect(doc.errors).toEqual([])
792+
expect(doc.warnings).toEqual([])
793+
expect(doc.schema.name).toBe('custom-test')
794+
expect(doc.toJS()).toEqual(['foo', /bar/])
795+
})
796+
797+
test('parse fail', () => {
798+
// map, seq & string are always parsed, even if not included
799+
const src = '- foo\n- !re /bar/\n'
800+
const doc = YAML.parseDocument(src, {
801+
customTags: [],
802+
schema: 'custom-test'
803+
})
804+
expect(doc.errors).toEqual([])
805+
expect(doc.warnings).toHaveLength(1)
806+
expect(doc.warnings[0].message).toMatch(/Unresolved tag: !re/)
807+
})
808+
809+
test('stringify success', () => {
810+
let src = '- foo\n'
811+
let doc = YAML.parseDocument(src, {
812+
customTags: [seqTag, stringTag],
813+
schema: 'custom-test'
814+
})
815+
expect(doc.toString()).toBe(src)
816+
817+
src = '- foo\n- !re /bar/\n'
818+
doc = YAML.parseDocument(src, {
819+
customTags: [seqTag, stringTag, regexp],
820+
schema: 'custom-test'
821+
})
822+
expect(doc.toString()).toBe(src)
823+
})
824+
825+
test('stringify fail', () => {
826+
const src = '- foo\n'
827+
let doc = YAML.parseDocument(src, {
828+
customTags: [],
829+
schema: 'custom-test'
830+
})
831+
expect(() => String(doc)).toThrow(/Tag not resolved for YAMLSeq value/)
832+
833+
doc = YAML.parseDocument(src, {
834+
customTags: [seqTag],
835+
schema: 'custom-test'
836+
})
837+
expect(() => String(doc)).toThrow(/Tag not resolved for String value/)
838+
})
839+
})
777840
})
778841

779842
describe('schema changes', () => {

util.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Workaround for incomplete exports support in TypeScript
2+
// https://github.com/microsoft/TypeScript/issues/33079
3+
export * from './dist/util.js'

0 commit comments

Comments
 (0)