@spyglassmc/json 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type * as core from '@spyglassmc/core';
2
- export * as checker from './checker/index.js';
1
+ import * as core from '@spyglassmc/core';
3
2
  export * as colorizer from './colorizer/index.js';
4
3
  export * as completer from './completer/index.js';
5
4
  export * as formatter from './formatter/index.js';
package/lib/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /* istanbul ignore file */
2
+ import * as core from '@spyglassmc/core';
2
3
  import * as colorizer from './colorizer/index.js';
3
4
  import * as completer from './completer/index.js';
4
5
  import * as formatter from './formatter/index.js';
5
6
  import * as parser from './parser/index.js';
6
- export * as checker from './checker/index.js';
7
7
  export * as colorizer from './colorizer/index.js';
8
8
  export * as completer from './completer/index.js';
9
9
  export * as formatter from './formatter/index.js';
@@ -13,7 +13,7 @@ export const initialize = ({ meta }) => {
13
13
  meta.registerLanguage('json', {
14
14
  extensions: ['.json', '.mcmeta'],
15
15
  triggerCharacters: completer.JsonTriggerCharacters,
16
- parser: parser.entry,
16
+ parser: core.dumpErrors(parser.entry),
17
17
  });
18
18
  meta.registerParser('json:entry', parser.entry);
19
19
  colorizer.register(meta);
@@ -1,5 +1,4 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import type { JsonNode } from '../node/index.js';
3
- export declare function json(dumpErrors?: boolean): core.Parser<JsonNode>;
4
3
  export declare const entry: core.Parser<JsonNode>;
5
4
  //# sourceMappingURL=entry.d.ts.map
@@ -18,27 +18,18 @@ const LegalNumberStart = new Set([
18
18
  '9',
19
19
  '-',
20
20
  ]);
21
- export function json(dumpErrors = false) {
22
- return (src, ctx) => {
23
- const result = core.select([
24
- { predicate: (src) => src.tryPeek('['), parser: array },
25
- {
26
- predicate: (src) => src.tryPeek('false') || src.tryPeek('true'),
27
- parser: boolean,
28
- },
29
- { predicate: (src) => src.tryPeek('null'), parser: null_ },
30
- {
31
- predicate: (src) => LegalNumberStart.has(src.peek()),
32
- parser: number,
33
- },
34
- { predicate: (src) => src.tryPeek('{'), parser: object },
35
- { parser: string },
36
- ])(src, ctx);
37
- if (dumpErrors) {
38
- ctx.err.dump();
39
- }
40
- return result;
41
- };
42
- }
43
- export const entry = json(true);
21
+ export const entry = (src, ctx) => core.select([
22
+ { predicate: (src) => src.tryPeek('['), parser: array },
23
+ {
24
+ predicate: (src) => src.tryPeek('false') || src.tryPeek('true'),
25
+ parser: boolean,
26
+ },
27
+ { predicate: (src) => src.tryPeek('null'), parser: null_ },
28
+ {
29
+ predicate: (src) => LegalNumberStart.has(src.peek()),
30
+ parser: number,
31
+ },
32
+ { predicate: (src) => src.tryPeek('{'), parser: object },
33
+ { parser: string },
34
+ ])(src, ctx);
44
35
  //# sourceMappingURL=entry.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/json",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "url": "https://github.com/SpyglassMC/Spyglass/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@spyglassmc/core": "0.4.2",
29
- "@spyglassmc/locales": "0.3.2"
28
+ "@spyglassmc/core": "0.4.4",
29
+ "@spyglassmc/locales": "0.3.4"
30
30
  }
31
31
  }
@@ -1,8 +0,0 @@
1
- import type { CheckerContext } from '@spyglassmc/core';
2
- import type { JsonNode } from '../node/index.js';
3
- export interface JsonCheckerContext extends CheckerContext {
4
- context: string;
5
- depth?: number;
6
- }
7
- export type JsonChecker = (node: JsonNode, ctx: JsonCheckerContext) => void;
8
- //# sourceMappingURL=JsonChecker.d.ts.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=JsonChecker.js.map
@@ -1,3 +0,0 @@
1
- export * from './JsonChecker.js';
2
- export * from './primitives/index.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,3 +0,0 @@
1
- export * from './JsonChecker.js';
2
- export * from './primitives/index.js';
3
- //# sourceMappingURL=index.js.map
@@ -1,4 +0,0 @@
1
- import type { JsonNode } from '../../node/index.js';
2
- import type { JsonCheckerContext } from '../JsonChecker.js';
3
- export declare function boolean(node: JsonNode, ctx: JsonCheckerContext): void;
4
- //# sourceMappingURL=boolean.d.ts.map
@@ -1,9 +0,0 @@
1
- import { localize } from '@spyglassmc/locales';
2
- import { JsonBooleanNode } from '../../node/index.js';
3
- export function boolean(node, ctx) {
4
- node.expectation = [{ type: 'json:boolean', typedoc: 'Boolean' }];
5
- if (!JsonBooleanNode.is(node)) {
6
- ctx.err.report(localize('expected', localize('boolean')), node);
7
- }
8
- }
9
- //# sourceMappingURL=boolean.js.map
@@ -1,7 +0,0 @@
1
- export * from './boolean.js';
2
- export * from './list.js';
3
- export * from './number.js';
4
- export * from './object.js';
5
- export * from './string.js';
6
- export * from './util.js';
7
- //# sourceMappingURL=index.d.ts.map
@@ -1,7 +0,0 @@
1
- export * from './boolean.js';
2
- export * from './list.js';
3
- export * from './number.js';
4
- export * from './object.js';
5
- export * from './string.js';
6
- export * from './util.js';
7
- //# sourceMappingURL=index.js.map
@@ -1,10 +0,0 @@
1
- import type { JsonNode } from '../../node/index.js';
2
- import type { JsonChecker, JsonCheckerContext } from '../JsonChecker.js';
3
- export declare function listOf(checker: JsonChecker): JsonChecker;
4
- type UniqueListOptions = {
5
- items?: (node: JsonNode) => [string | undefined, JsonNode];
6
- report?: (node: JsonNode, ctx: JsonCheckerContext) => unknown;
7
- };
8
- export declare function uniqueListOf(checker: JsonChecker, options?: UniqueListOptions): JsonChecker;
9
- export {};
10
- //# sourceMappingURL=list.d.ts.map
@@ -1,48 +0,0 @@
1
- import { localize } from '@spyglassmc/locales';
2
- import { JsonArrayNode, JsonStringNode } from '../../node/index.js';
3
- import { expectation } from './util.js';
4
- export function listOf(checker) {
5
- return (node, ctx) => {
6
- node.expectation = [{ type: 'json:array', typedoc: 'Array' }];
7
- if (!ctx.depth || ctx.depth <= 0) {
8
- ;
9
- node.expectation[0].items = expectation(checker, ctx);
10
- }
11
- if (!JsonArrayNode.is(node)) {
12
- ctx.err.report(localize('expected', localize('array')), node);
13
- }
14
- else {
15
- node.children
16
- .filter((e) => e.value)
17
- .forEach((e) => checker(e.value, ctx));
18
- }
19
- };
20
- }
21
- export function uniqueListOf(checker, options = {}) {
22
- const getItem = options.items ??
23
- ((node) => [JsonStringNode.is(node) ? node.value : undefined, node]);
24
- const reporter = options.report ??
25
- ((node, ctx) => ctx.err.report(localize('json.checker.item.duplicate'), node, 2 /* ErrorSeverity.Warning */));
26
- return (node, ctx) => {
27
- listOf(checker)(node, ctx);
28
- if (JsonArrayNode.is(node)) {
29
- const items = new Map();
30
- const duplicates = new Set();
31
- node.children.forEach((c) => {
32
- if (!c.value)
33
- return;
34
- const [value, item] = getItem(c.value);
35
- if (!value)
36
- return;
37
- const existing = items.get(value);
38
- if (existing) {
39
- duplicates.add(existing);
40
- duplicates.add(item);
41
- }
42
- items.set(value, item);
43
- });
44
- duplicates.forEach((node) => reporter(node, ctx));
45
- }
46
- };
47
- }
48
- //# sourceMappingURL=list.js.map
@@ -1,6 +0,0 @@
1
- import type { JsonChecker } from '../JsonChecker.js';
2
- export declare const int: JsonChecker;
3
- export declare const float: JsonChecker;
4
- export declare const intRange: (min: number | undefined, max: number | undefined) => JsonChecker;
5
- export declare const floatRange: (min: number | undefined, max: number | undefined) => JsonChecker;
6
- //# sourceMappingURL=number.d.ts.map
@@ -1,31 +0,0 @@
1
- import { localize } from '@spyglassmc/locales';
2
- import { JsonNumberNode } from '../../node/index.js';
3
- const number = (type) => (min, max) => {
4
- return (node, ctx) => {
5
- const typedoc = 'Number' +
6
- (min === undefined && max === undefined
7
- ? ''
8
- : `(${min ?? '-∞'}, ${max ?? '+∞'})`);
9
- node.expectation = [{ type: 'json:number', typedoc }];
10
- if (!JsonNumberNode.is(node) ||
11
- (type === 'integer' && !Number.isInteger(node.value))) {
12
- ctx.err.report(localize('expected', localize(type)), node);
13
- }
14
- else if (min !== undefined &&
15
- max !== undefined &&
16
- (node.value < min || node.value > max)) {
17
- ctx.err.report(localize('expected', localize('number.between', min, max)), node);
18
- }
19
- else if (min !== undefined && node.value < min) {
20
- ctx.err.report(localize('expected', localize('number.>=', min)), node);
21
- }
22
- else if (max !== undefined && node.value > max) {
23
- ctx.err.report(localize('expected', localize('number.<=', max)), node);
24
- }
25
- };
26
- };
27
- export const int = number('integer')(undefined, undefined);
28
- export const float = number('float')(undefined, undefined);
29
- export const intRange = number('integer');
30
- export const floatRange = number('float');
31
- //# sourceMappingURL=number.js.map
@@ -1,34 +0,0 @@
1
- import type { PairNode } from '@spyglassmc/core';
2
- import type { JsonNode, JsonStringNode } from '../../node/index.js';
3
- import type { JsonChecker, JsonCheckerContext } from '../JsonChecker.js';
4
- type JsonValue = string | number | boolean | null | JsonValue[] | {
5
- [key: string]: JsonValue;
6
- };
7
- type ComplexProperty = {
8
- checker: JsonChecker;
9
- opt?: boolean;
10
- def?: JsonValue;
11
- deprecated?: boolean;
12
- context?: string;
13
- };
14
- type CheckerProperty = JsonChecker | ComplexProperty;
15
- type CheckerRecord = Record<string, CheckerProperty | undefined>;
16
- type ObjectCheckerOptions = {
17
- allowUnknownProperties?: boolean;
18
- };
19
- export declare function object(): JsonChecker;
20
- export declare function object(keys: string[], values: (key: string, ctx: JsonCheckerContext) => CheckerProperty | undefined, options?: ObjectCheckerOptions): JsonChecker;
21
- export declare function object(keys: JsonChecker, values: (key: string, ctx: JsonCheckerContext) => CheckerProperty | undefined, options?: ObjectCheckerOptions): JsonChecker;
22
- export declare function record(properties: CheckerRecord, options?: ObjectCheckerOptions): JsonChecker;
23
- export declare function opt(checker?: JsonChecker | ComplexProperty, defaultValue?: JsonValue): ComplexProperty | undefined;
24
- export declare function deprecate(checker?: JsonChecker | ComplexProperty): ComplexProperty | undefined;
25
- export declare function dispatch(values: (children: PairNode<JsonStringNode, JsonNode>[], ctx: JsonCheckerContext) => JsonChecker): JsonChecker;
26
- export declare function dispatch(keyName: string, values: (value: string | undefined, children: PairNode<JsonStringNode, JsonNode>[], ctx: JsonCheckerContext) => JsonChecker): JsonChecker;
27
- export declare function pick(value: string | undefined, cases: Record<string, CheckerRecord>): CheckerRecord;
28
- export declare function when(value: string | undefined, values: string[], properties: CheckerRecord, notProperties?: CheckerRecord): CheckerRecord;
29
- export declare function extract(value: string, children: PairNode<JsonStringNode, JsonNode>[] | undefined): string | undefined;
30
- export declare function extractNested(wrap: string, value: string, children: PairNode<JsonStringNode, JsonNode>[] | undefined): string | undefined;
31
- export declare function extractStringArray(value: string, children?: PairNode<JsonStringNode, JsonNode>[] | undefined): readonly string[] | undefined;
32
- export declare function having(node: JsonNode, ctx: JsonCheckerContext, cases: Record<string, CheckerRecord | (() => CheckerRecord)>): CheckerRecord;
33
- export {};
34
- //# sourceMappingURL=object.d.ts.map
@@ -1,201 +0,0 @@
1
- import { Range, ResourceLocation } from '@spyglassmc/core';
2
- import { localeQuote, localize } from '@spyglassmc/locales';
3
- import { JsonObjectNode, JsonStringExpectation } from '../../node/index.js';
4
- import { any, expectation } from './util.js';
5
- function isComplex(checker) {
6
- return checker?.checker !== undefined;
7
- }
8
- export function object(keys, values, options = {}) {
9
- return (node, ctx) => {
10
- node.expectation = [{ type: 'json:object', typedoc: 'Object' }];
11
- if (!ctx.depth || ctx.depth <= 0) {
12
- if (Array.isArray(keys) && values) {
13
- const fields = keys
14
- .map((key) => [key, values(key, ctx)])
15
- .filter(([_, v]) => v !== undefined);
16
- node.expectation[0].fields = fields
17
- .map(([key, prop]) => {
18
- return {
19
- key,
20
- value: expectation(isComplex(prop) ? prop.checker : prop, ctx),
21
- ...(isComplex(prop) && (prop.opt || prop.deprecated)
22
- ? { opt: true }
23
- : {}),
24
- ...(isComplex(prop) && prop.deprecated
25
- ? { deprecated: true }
26
- : {}),
27
- };
28
- });
29
- }
30
- else if (typeof keys === 'function' && values) {
31
- ;
32
- node.expectation[0].keys = expectation(keys, ctx)?.filter(JsonStringExpectation.is);
33
- }
34
- }
35
- if (!JsonObjectNode.is(node)) {
36
- ctx.err.report(localize('expected', localize('object')), node);
37
- }
38
- else if (Array.isArray(keys) && values) {
39
- const givenKeys = node.children.map((n) => n.key?.value);
40
- keys.forEach((k) => {
41
- const value = values(k, ctx);
42
- if (!value || (isComplex(value) && (value.opt || value.deprecated))) {
43
- return;
44
- }
45
- if (!givenKeys.includes(k)) {
46
- ctx.err.report(localize('json.checker.property.missing', localeQuote(k)), Range.create(node.range.start, node.range.start + 1));
47
- }
48
- });
49
- node.children
50
- .filter((p) => p.key)
51
- .forEach((prop) => {
52
- const key = prop.key.value;
53
- const value = values(key, ctx);
54
- if (!value || !keys.includes(key)) {
55
- if (!options.allowUnknownProperties) {
56
- ctx.err.report(localize('json.checker.property.unknown', localeQuote(key)), prop.key, 2 /* ErrorSeverity.Warning */);
57
- }
58
- return;
59
- }
60
- if (isComplex(value) && value.deprecated) {
61
- ctx.err.report(localize('json.checker.property.deprecated', localeQuote(key)), prop.key, 0 /* ErrorSeverity.Hint */, { deprecated: true });
62
- }
63
- const context = ctx.context +
64
- (isComplex(value) && value.context ? `.${value.context}` : '');
65
- const doc = localize(`json.doc.${context}`);
66
- const propNode = prop.value !== undefined
67
- ? prop.value
68
- : { type: 'json:null', range: Range.create(0) };
69
- const checker = isComplex(value) ? value.checker : value;
70
- try {
71
- checker(propNode, { ...ctx, context: `${context}.${key}` });
72
- }
73
- catch (e) {
74
- const pos = ctx.doc.positionAt(prop.range.start);
75
- ctx.logger.error(`Checking "${key}" at ${pos.line}:${pos.character} in "${ctx.doc.uri}"`, e);
76
- }
77
- const defaultValue = isComplex(value) ? value.def : undefined;
78
- const typedoc = propNode.expectation
79
- ?.map((e) => e.typedoc)
80
- .join(' | ');
81
- prop.key.hover =
82
- `\`\`\`typescript\n${context}.${key}: ${typedoc}\n\`\`\`${doc || defaultValue !== undefined ? '\n******\n ' : ''}${doc}${defaultValue !== undefined
83
- ? `\n\`@default\` ${JSON.stringify(defaultValue)}`
84
- : ''}`;
85
- });
86
- }
87
- else if (typeof keys === 'function' && values) {
88
- node.children
89
- .filter((p) => p.key)
90
- .forEach((prop) => {
91
- keys(prop.key, ctx);
92
- if (prop.value !== undefined) {
93
- const value = values(prop.key.value, ctx);
94
- if (value) {
95
- const checker = isComplex(value) ? value.checker : value;
96
- checker(prop.value, ctx);
97
- }
98
- }
99
- });
100
- }
101
- };
102
- }
103
- export function record(properties, options) {
104
- return object(Object.keys(properties), (key) => properties[key], options);
105
- }
106
- export function opt(checker, defaultValue) {
107
- if (checker === undefined)
108
- return undefined;
109
- return isComplex(checker)
110
- ? { ...checker, opt: true, def: defaultValue }
111
- : { checker, opt: true, def: defaultValue };
112
- }
113
- export function deprecate(checker) {
114
- if (checker === undefined)
115
- return undefined;
116
- return isComplex(checker)
117
- ? { ...checker, deprecated: true }
118
- : { checker, deprecated: true };
119
- }
120
- export function dispatch(arg1, arg2) {
121
- return (node, ctx) => {
122
- if (!JsonObjectNode.is(node)) {
123
- ctx.err.report(localize('expected', localize('object')), node);
124
- }
125
- else if (arg2) {
126
- const dispatcherIndex = node.children.findIndex((p) => p.key?.value === arg1);
127
- const dispatcher = node.children[dispatcherIndex];
128
- const value = dispatcher?.value?.type === 'json:string'
129
- ? dispatcher.value.value
130
- : undefined;
131
- arg2(value, node.children, ctx)(node, ctx);
132
- }
133
- else {
134
- ;
135
- arg1(node.children, ctx)(node, ctx);
136
- }
137
- };
138
- }
139
- export function pick(value, cases) {
140
- if (value === undefined) {
141
- return {};
142
- }
143
- const properties = cases[ResourceLocation.shorten(value)];
144
- if (properties === undefined) {
145
- return {};
146
- }
147
- Object.keys(properties).forEach((key) => {
148
- const p = properties[key];
149
- if (p === undefined)
150
- return;
151
- properties[key] = {
152
- checker: isComplex(p) ? p.checker : p,
153
- opt: isComplex(p) ? p.opt : undefined,
154
- deprecated: isComplex(p) ? p.deprecated : undefined,
155
- context: ResourceLocation.shorten(value),
156
- };
157
- });
158
- return properties;
159
- }
160
- export function when(value, values, properties, notProperties = {}) {
161
- if (value === undefined) {
162
- return {};
163
- }
164
- if (!values.includes(ResourceLocation.shorten(value))) {
165
- return notProperties;
166
- }
167
- return properties;
168
- }
169
- export function extract(value, children) {
170
- const node = children?.find((p) => p.key?.value === value);
171
- return node?.value?.type === 'json:string' ? node.value.value : undefined;
172
- }
173
- export function extractNested(wrap, value, children) {
174
- const wrapper = children?.find((p) => p.key?.value === wrap);
175
- if (wrapper?.value?.type !== 'json:object')
176
- return undefined;
177
- const node = wrapper.children?.find((p) => p.key?.value ===
178
- value);
179
- return node?.type === 'json:string' ? node.value : undefined;
180
- }
181
- export function extractStringArray(value, children) {
182
- const node = children?.find((p) => p.key?.value === value);
183
- return node?.value?.type === 'json:array' &&
184
- node.value.children?.every((n) => n.value?.type === 'json:string')
185
- ? node.value.children.map((n) => n.value.value)
186
- : undefined;
187
- }
188
- export function having(node, ctx, cases) {
189
- const givenKeys = new Set(JsonObjectNode.is(node) ? node.children.map((n) => n.key?.value) : []);
190
- const key = Object.keys(cases).find((c) => givenKeys.has(c));
191
- if (key === undefined) {
192
- ctx.err.report(localize('json.checker.property.missing', Object.keys(cases)), Range.create(node.range.start, node.range.start + 1));
193
- return Object.fromEntries(Object.entries(cases).map(([k, v]) => [
194
- k,
195
- opt(typeof v === 'function' ? any() : v[k] ?? any()),
196
- ]));
197
- }
198
- const c = cases[key];
199
- return typeof c === 'function' ? c() : c;
200
- }
201
- //# sourceMappingURL=object.js.map
@@ -1,12 +0,0 @@
1
- import type { AllCategory, AstNode, Parser, ResourceLocationCategory, SyncChecker, TaggableResourceLocationCategory } from '@spyglassmc/core';
2
- import { Lazy } from '@spyglassmc/core';
3
- import type { JsonExpectation } from '../../node/index.js';
4
- import { JsonStringNode } from '../../node/index.js';
5
- import type { JsonChecker } from '../JsonChecker.js';
6
- export declare function resource(id: TaggableResourceLocationCategory, allowTag?: boolean): JsonChecker;
7
- export declare function resource(id: ResourceLocationCategory | string[], allowTag?: false): JsonChecker;
8
- export declare function literal(value: AllCategory | readonly string[]): JsonChecker;
9
- export declare function string<T extends AstNode>(name: string | readonly string[] | undefined, parser: Lazy<Parser<T>>, checker?: Lazy<SyncChecker<T>>, expectation?: Partial<JsonExpectation>): JsonChecker;
10
- export declare function string(name?: string | readonly string[], parser?: undefined, checker?: Lazy<SyncChecker<JsonStringNode>>, expectation?: Partial<JsonExpectation>): JsonChecker;
11
- export declare const simpleString: JsonChecker;
12
- //# sourceMappingURL=string.d.ts.map
@@ -1,51 +0,0 @@
1
- import * as core from '@spyglassmc/core';
2
- import { Failure, Lazy, ResourceLocation } from '@spyglassmc/core';
3
- import { localize } from '@spyglassmc/locales';
4
- import { JsonStringNode } from '../../node/index.js';
5
- export function resource(id, allowTag = false) {
6
- return string(id, core.resourceLocation(typeof id === 'string'
7
- ? { category: id, allowTag }
8
- : { pool: id.map(ResourceLocation.lengthen) }), core.checker.resourceLocation);
9
- }
10
- export function literal(value) {
11
- return typeof value === 'string'
12
- ? string(value, core.symbol(value))
13
- : string(value, core.literal(...value));
14
- }
15
- export function string(name, parser, checker, expectation) {
16
- return (node, ctx) => {
17
- node.expectation = [
18
- { type: 'json:string', typedoc: typedoc(name), ...expectation },
19
- ];
20
- if (!JsonStringNode.is(node)) {
21
- ctx.err.report(localize('expected', localize('string')), node);
22
- }
23
- else if (parser) {
24
- const result = core.parseStringValue(Lazy.resolve(parser), node.value, node.valueMap, ctx);
25
- if (result !== Failure) {
26
- node.children = [result];
27
- result.parent = node;
28
- if (checker) {
29
- Lazy.resolve(checker)(result, ctx);
30
- }
31
- }
32
- }
33
- else if (checker) {
34
- Lazy.resolve(checker)(node, ctx);
35
- }
36
- };
37
- }
38
- function typedoc(id) {
39
- if (!id) {
40
- return 'String';
41
- }
42
- if (typeof id === 'string') {
43
- return `String("${id}")`;
44
- }
45
- return (id
46
- .slice(0, 10)
47
- .map((e) => `"${e}"`)
48
- .join(' | ') + (id.length > 10 ? ' | ...' : ''));
49
- }
50
- export const simpleString = string();
51
- //# sourceMappingURL=string.js.map
@@ -1,15 +0,0 @@
1
- import type { ErrorSeverity } from '@spyglassmc/core';
2
- import type { JsonExpectation, JsonNode } from '../../node/index.js';
3
- import type { JsonChecker, JsonCheckerContext } from '../JsonChecker.js';
4
- export declare function ref(checker: () => JsonChecker): JsonChecker;
5
- export declare function as(context: string, checker: JsonChecker): JsonChecker;
6
- export type AttemptResult = {
7
- totalErrorSpan: number;
8
- maxSeverity: ErrorSeverity;
9
- expectation?: JsonExpectation[];
10
- updateNodeAndCtx: () => void;
11
- };
12
- export declare function attempt(checker: JsonChecker, node: JsonNode, ctx: JsonCheckerContext): AttemptResult;
13
- export declare function any(checkers?: JsonChecker[]): JsonChecker;
14
- export declare function expectation(checker: JsonChecker, ctx: JsonCheckerContext): JsonExpectation[] | undefined;
15
- //# sourceMappingURL=util.d.ts.map
@@ -1,73 +0,0 @@
1
- import { ErrorReporter, Range, StateProxy } from '@spyglassmc/core';
2
- import { arrayToMessage, localize } from '@spyglassmc/locales';
3
- export function ref(checker) {
4
- return (node, ctx) => {
5
- return checker()(node, ctx);
6
- };
7
- }
8
- export function as(context, checker) {
9
- return (node, ctx) => {
10
- checker(node, { ...ctx, context });
11
- };
12
- }
13
- export function attempt(checker, node, ctx) {
14
- // TODO: The code below is mostly copied from core with some changes to support `expectation`. Could be refactored... I guess.
15
- const tempCtx = {
16
- ...ctx,
17
- err: new ErrorReporter(),
18
- symbols: ctx.symbols.clone(),
19
- };
20
- checker(node, tempCtx);
21
- const tempExpectation = node.expectation;
22
- StateProxy.undoChanges(node);
23
- const totalErrorSpan = tempCtx.err.errors
24
- .map((e) => e.range.end - e.range.start)
25
- .reduce((a, b) => a + b, 0);
26
- return {
27
- totalErrorSpan,
28
- maxSeverity: Math.max(...tempCtx.err.errors.map((e) => e.severity)),
29
- expectation: tempExpectation,
30
- updateNodeAndCtx: () => {
31
- ctx.err.absorb(tempCtx.err);
32
- StateProxy.redoChanges(node);
33
- tempCtx.symbols.applyDelayedEdits();
34
- },
35
- };
36
- }
37
- export function any(checkers = []) {
38
- return (node, ctx) => {
39
- if (checkers.length === 0) {
40
- return;
41
- }
42
- const attempts = checkers
43
- .map((checker) => attempt(checker, node, ctx))
44
- .sort((a, b) => a.maxSeverity - b.maxSeverity ||
45
- a.totalErrorSpan - b.totalErrorSpan);
46
- const sameTypeAttempts = attempts.filter((a) => a.expectation?.map((e) => e.type).includes(node.type));
47
- const allExpectations = attempts
48
- .filter((a) => a.expectation)
49
- .flatMap((a) => a.expectation);
50
- if (sameTypeAttempts.length === 0) {
51
- const allowedTypes = allExpectations.map((e) => localize(e.type.slice(5)));
52
- ctx.err.report(localize('expected', arrayToMessage(allowedTypes, false)), node);
53
- }
54
- else {
55
- sameTypeAttempts[0].updateNodeAndCtx();
56
- }
57
- node.expectation = allExpectations;
58
- };
59
- }
60
- export function expectation(checker, ctx) {
61
- const node = StateProxy.create({
62
- type: 'json:null',
63
- range: Range.create(0),
64
- });
65
- const tempCtx = {
66
- ...ctx,
67
- err: new ErrorReporter(),
68
- depth: (ctx.depth ?? 0) + 1,
69
- };
70
- checker(node, tempCtx);
71
- return node.expectation;
72
- }
73
- //# sourceMappingURL=util.js.map