@spyglassmc/json 0.1.0

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.
Files changed (49) hide show
  1. package/lib/checker/JsonChecker.d.ts +8 -0
  2. package/lib/checker/JsonChecker.js +3 -0
  3. package/lib/checker/index.d.ts +3 -0
  4. package/lib/checker/index.js +15 -0
  5. package/lib/checker/primitives/boolean.d.ts +4 -0
  6. package/lib/checker/primitives/boolean.js +13 -0
  7. package/lib/checker/primitives/index.d.ts +7 -0
  8. package/lib/checker/primitives/index.js +19 -0
  9. package/lib/checker/primitives/list.d.ts +10 -0
  10. package/lib/checker/primitives/list.js +49 -0
  11. package/lib/checker/primitives/number.d.ts +6 -0
  12. package/lib/checker/primitives/number.js +28 -0
  13. package/lib/checker/primitives/object.d.ts +34 -0
  14. package/lib/checker/primitives/object.js +190 -0
  15. package/lib/checker/primitives/string.d.ts +12 -0
  16. package/lib/checker/primitives/string.js +72 -0
  17. package/lib/checker/primitives/util.d.ts +15 -0
  18. package/lib/checker/primitives/util.js +77 -0
  19. package/lib/colorizer/index.d.ts +7 -0
  20. package/lib/colorizer/index.js +55 -0
  21. package/lib/completer/index.d.ts +9 -0
  22. package/lib/completer/index.js +165 -0
  23. package/lib/formatter/index.d.ts +3 -0
  24. package/lib/formatter/index.js +53 -0
  25. package/lib/index.d.ts +9 -0
  26. package/lib/index.js +49 -0
  27. package/lib/node/JsonAstNode.d.ts +97 -0
  28. package/lib/node/JsonAstNode.js +152 -0
  29. package/lib/node/index.d.ts +2 -0
  30. package/lib/node/index.js +14 -0
  31. package/lib/parser/array.d.ts +4 -0
  32. package/lib/parser/array.js +38 -0
  33. package/lib/parser/boolean.d.ts +4 -0
  34. package/lib/parser/boolean.js +44 -0
  35. package/lib/parser/entry.d.ts +5 -0
  36. package/lib/parser/entry.js +49 -0
  37. package/lib/parser/index.d.ts +6 -0
  38. package/lib/parser/index.js +18 -0
  39. package/lib/parser/null.d.ts +4 -0
  40. package/lib/parser/null.js +36 -0
  41. package/lib/parser/number.d.ts +4 -0
  42. package/lib/parser/number.js +34 -0
  43. package/lib/parser/object.d.ts +4 -0
  44. package/lib/parser/object.js +34 -0
  45. package/lib/parser/string.d.ts +5 -0
  46. package/lib/parser/string.js +38 -0
  47. package/lib/util.d.ts +1 -0
  48. package/lib/util.js +2 -0
  49. package/package.json +30 -0
@@ -0,0 +1,8 @@
1
+ import type { CheckerContext } from '@spyglassmc/core';
2
+ import type { JsonNode } from '../node';
3
+ export interface JsonCheckerContext extends CheckerContext {
4
+ context: string;
5
+ depth?: number;
6
+ }
7
+ export declare type JsonChecker = (node: JsonNode, ctx: JsonCheckerContext) => void;
8
+ //# sourceMappingURL=JsonChecker.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=JsonChecker.js.map
@@ -0,0 +1,3 @@
1
+ export * from './JsonChecker';
2
+ export * from './primitives';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./JsonChecker"), exports);
14
+ __exportStar(require("./primitives"), exports);
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ import type { JsonNode } from '../../node';
2
+ import type { JsonCheckerContext } from '../JsonChecker';
3
+ export declare function boolean(node: JsonNode, ctx: JsonCheckerContext): void;
4
+ //# sourceMappingURL=boolean.d.ts.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.boolean = void 0;
4
+ const locales_1 = require("@spyglassmc/locales");
5
+ const node_1 = require("../../node");
6
+ function boolean(node, ctx) {
7
+ ctx.ops.set(node, 'expectation', [{ type: 'json:boolean', typedoc: 'Boolean' }]);
8
+ if (!node_1.JsonBooleanNode.is(node)) {
9
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('boolean')), node);
10
+ }
11
+ }
12
+ exports.boolean = boolean;
13
+ //# sourceMappingURL=boolean.js.map
@@ -0,0 +1,7 @@
1
+ export * from './boolean';
2
+ export * from './list';
3
+ export * from './number';
4
+ export * from './object';
5
+ export * from './string';
6
+ export * from './util';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./boolean"), exports);
14
+ __exportStar(require("./list"), exports);
15
+ __exportStar(require("./number"), exports);
16
+ __exportStar(require("./object"), exports);
17
+ __exportStar(require("./string"), exports);
18
+ __exportStar(require("./util"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ import type { JsonNode } from '../../node';
2
+ import type { JsonChecker, JsonCheckerContext } from '../JsonChecker';
3
+ export declare function listOf(checker: JsonChecker): JsonChecker;
4
+ declare 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
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uniqueListOf = exports.listOf = void 0;
4
+ const locales_1 = require("@spyglassmc/locales");
5
+ const node_1 = require("../../node");
6
+ const util_1 = require("./util");
7
+ function listOf(checker) {
8
+ return (node, ctx) => {
9
+ ctx.ops.set(node, 'expectation', [{ type: 'json:array', typedoc: 'Array' }]);
10
+ if (!ctx.depth || ctx.depth <= 0) {
11
+ ctx.ops.set(node.expectation[0], 'items', (0, util_1.expectation)(checker, ctx));
12
+ }
13
+ if (!node_1.JsonArrayNode.is(node)) {
14
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('array')), node);
15
+ }
16
+ else {
17
+ node.children.filter(e => e.value)
18
+ .forEach(e => checker(e.value, ctx));
19
+ }
20
+ };
21
+ }
22
+ exports.listOf = listOf;
23
+ function uniqueListOf(checker, options = {}) {
24
+ const getItem = (options.items ?? (node => [node_1.JsonStringNode.is(node) ? node.value : undefined, node]));
25
+ const reporter = options.report ?? ((node, ctx) => ctx.err.report((0, locales_1.localize)('json.checker.item.duplicate'), node, 2 /* Warning */));
26
+ return (node, ctx) => {
27
+ listOf(checker)(node, ctx);
28
+ if (node_1.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
+ exports.uniqueListOf = uniqueListOf;
49
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1,6 @@
1
+ import type { JsonChecker } from '../JsonChecker';
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
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.floatRange = exports.intRange = exports.float = exports.int = void 0;
4
+ const locales_1 = require("@spyglassmc/locales");
5
+ const node_1 = require("../../node");
6
+ const number = (type) => (min, max) => {
7
+ return (node, ctx) => {
8
+ const typedoc = 'Number' + (min === undefined && max === undefined ? '' : `(${min ?? '-∞'}, ${max ?? '+∞'})`);
9
+ ctx.ops.set(node, 'expectation', [{ type: 'json:number', typedoc }]);
10
+ if (!node_1.JsonNumberNode.is(node) || (type === 'integer' && !Number.isInteger(node.value))) {
11
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)(type)), node);
12
+ }
13
+ else if (min !== undefined && max !== undefined && (node.value < min || node.value > max)) {
14
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('number.between', min, max)), node);
15
+ }
16
+ else if (min !== undefined && node.value < min) {
17
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('number.>=', min)), node);
18
+ }
19
+ else if (max !== undefined && node.value > max) {
20
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('number.<=', max)), node);
21
+ }
22
+ };
23
+ };
24
+ exports.int = number('integer')(undefined, undefined);
25
+ exports.float = number('float')(undefined, undefined);
26
+ exports.intRange = number('integer');
27
+ exports.floatRange = number('float');
28
+ //# sourceMappingURL=number.js.map
@@ -0,0 +1,34 @@
1
+ import type { PairNode } from '@spyglassmc/core';
2
+ import type { JsonNode, JsonStringNode } from '../../node';
3
+ import type { JsonChecker, JsonCheckerContext } from '../JsonChecker';
4
+ declare type JsonValue = string | number | boolean | null | JsonValue[] | {
5
+ [key: string]: JsonValue;
6
+ };
7
+ declare type ComplexProperty = {
8
+ checker: JsonChecker;
9
+ opt?: boolean;
10
+ def?: JsonValue;
11
+ deprecated?: boolean;
12
+ context?: string;
13
+ };
14
+ declare type CheckerProperty = JsonChecker | ComplexProperty;
15
+ declare type CheckerRecord = Record<string, CheckerProperty | undefined>;
16
+ declare 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
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.having = exports.extractStringArray = exports.extractNested = exports.extract = exports.when = exports.pick = exports.dispatch = exports.deprecate = exports.opt = exports.record = exports.object = void 0;
4
+ const core_1 = require("@spyglassmc/core");
5
+ const locales_1 = require("@spyglassmc/locales");
6
+ const node_1 = require("../../node");
7
+ const util_1 = require("./util");
8
+ function isComplex(checker) {
9
+ return checker?.checker !== undefined;
10
+ }
11
+ function object(keys, values, options = {}) {
12
+ return (node, ctx) => {
13
+ ctx.ops.set(node, 'expectation', [{ type: 'json:object', typedoc: 'Object' }]);
14
+ if (!ctx.depth || ctx.depth <= 0) {
15
+ if (Array.isArray(keys) && values) {
16
+ const fields = keys.map(key => [key, values(key, ctx)]).filter(([_, v]) => v !== undefined);
17
+ ctx.ops.set(node.expectation[0], 'fields', fields.map(([key, prop]) => {
18
+ return {
19
+ key,
20
+ value: (0, util_1.expectation)(isComplex(prop) ? prop.checker : prop, ctx),
21
+ ...isComplex(prop) && (prop.opt || prop.deprecated) ? { opt: true } : {},
22
+ ...isComplex(prop) && prop.deprecated ? { deprecated: true } : {},
23
+ };
24
+ }));
25
+ }
26
+ else if (typeof keys === 'function' && values) {
27
+ ctx.ops.set(node.expectation[0], 'keys', (0, util_1.expectation)(keys, ctx)
28
+ ?.filter(node_1.JsonStringExpectation.is));
29
+ }
30
+ }
31
+ if (!node_1.JsonObjectNode.is(node)) {
32
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('object')), node);
33
+ }
34
+ else if (Array.isArray(keys) && values) {
35
+ const givenKeys = node.children.map(n => n.key?.value);
36
+ keys.forEach(k => {
37
+ const value = values(k, ctx);
38
+ if (!value || isComplex(value) && (value.opt || value.deprecated)) {
39
+ return;
40
+ }
41
+ if (!givenKeys.includes(k)) {
42
+ ctx.err.report((0, locales_1.localize)('json.checker.property.missing', (0, locales_1.localeQuote)(k)), core_1.Range.create(node.range.start, node.range.start + 1));
43
+ }
44
+ });
45
+ node.children.filter(p => p.key).forEach(prop => {
46
+ const key = prop.key.value;
47
+ const value = values(key, ctx);
48
+ if (!value || !keys.includes(key)) {
49
+ if (!options.allowUnknownProperties) {
50
+ ctx.err.report((0, locales_1.localize)('json.checker.property.unknown', (0, locales_1.localeQuote)(key)), prop.key, 2 /* Warning */);
51
+ }
52
+ return;
53
+ }
54
+ if (isComplex(value) && value.deprecated) {
55
+ ctx.err.report((0, locales_1.localize)('json.checker.property.deprecated', (0, locales_1.localeQuote)(key)), prop.key, 0 /* Hint */, { deprecated: true });
56
+ }
57
+ const context = ctx.context + (isComplex(value) && value.context ? `.${value.context}` : '');
58
+ const doc = (0, locales_1.localize)(`json.doc.${context}`);
59
+ const propNode = prop.value !== undefined ? prop.value : { type: 'json:null', range: core_1.Range.create(0) };
60
+ const checker = isComplex(value) ? value.checker : value;
61
+ try {
62
+ checker(propNode, { ...ctx, context: `${context}.${key}` });
63
+ }
64
+ catch (e) {
65
+ const pos = ctx.doc.positionAt(prop.range.start);
66
+ ctx.logger.error(`Checking "${key}" at ${pos.line}:${pos.character} in "${ctx.doc.uri}"`, e);
67
+ }
68
+ const defaultValue = isComplex(value) ? value.def : undefined;
69
+ const typedoc = propNode.expectation?.map(e => e.typedoc).join(' | ');
70
+ prop.key.hover = `\`\`\`typescript\n${context}.${key}: ${typedoc}\n\`\`\`${doc || defaultValue !== undefined ? '\n******\n ' : ''}${doc}${defaultValue !== undefined ? `\n\`@default\` ${JSON.stringify(defaultValue)}` : ''}`;
71
+ });
72
+ }
73
+ else if (typeof keys === 'function' && values) {
74
+ node.children.filter(p => p.key).forEach(prop => {
75
+ keys(prop.key, ctx);
76
+ if (prop.value !== undefined) {
77
+ const value = values(prop.key.value, ctx);
78
+ if (value) {
79
+ const checker = isComplex(value) ? value.checker : value;
80
+ checker(prop.value, ctx);
81
+ }
82
+ }
83
+ });
84
+ }
85
+ };
86
+ }
87
+ exports.object = object;
88
+ function record(properties, options) {
89
+ return object(Object.keys(properties), (key) => properties[key], options);
90
+ }
91
+ exports.record = record;
92
+ function opt(checker, defaultValue) {
93
+ if (checker === undefined)
94
+ return undefined;
95
+ return isComplex(checker)
96
+ ? { ...checker, opt: true, def: defaultValue }
97
+ : { checker, opt: true, def: defaultValue };
98
+ }
99
+ exports.opt = opt;
100
+ function deprecate(checker) {
101
+ if (checker === undefined)
102
+ return undefined;
103
+ return isComplex(checker)
104
+ ? { ...checker, deprecated: true }
105
+ : { checker, deprecated: true };
106
+ }
107
+ exports.deprecate = deprecate;
108
+ function dispatch(arg1, arg2) {
109
+ return (node, ctx) => {
110
+ if (!node_1.JsonObjectNode.is(node)) {
111
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('object')), node);
112
+ }
113
+ else if (arg2) {
114
+ const dispatcherIndex = node.children.findIndex(p => p.key?.value === arg1);
115
+ const dispatcher = node.children[dispatcherIndex];
116
+ const value = dispatcher?.value?.type === 'json:string' ? dispatcher.value.value : undefined;
117
+ arg2(value, node.children, ctx)(node, ctx);
118
+ }
119
+ else {
120
+ arg1(node.children, ctx)(node, ctx);
121
+ }
122
+ };
123
+ }
124
+ exports.dispatch = dispatch;
125
+ function pick(value, cases) {
126
+ if (value === undefined) {
127
+ return {};
128
+ }
129
+ const properties = cases[core_1.ResourceLocation.shorten(value)];
130
+ if (properties === undefined) {
131
+ return {};
132
+ }
133
+ Object.keys(properties).forEach(key => {
134
+ const p = properties[key];
135
+ if (p === undefined)
136
+ return;
137
+ properties[key] = {
138
+ checker: isComplex(p) ? p.checker : p,
139
+ opt: isComplex(p) ? p.opt : undefined,
140
+ deprecated: isComplex(p) ? p.deprecated : undefined,
141
+ context: core_1.ResourceLocation.shorten(value),
142
+ };
143
+ });
144
+ return properties;
145
+ }
146
+ exports.pick = pick;
147
+ function when(value, values, properties, notProperties = {}) {
148
+ if (value === undefined) {
149
+ return {};
150
+ }
151
+ if (!values.includes(core_1.ResourceLocation.shorten(value))) {
152
+ return notProperties;
153
+ }
154
+ return properties;
155
+ }
156
+ exports.when = when;
157
+ function extract(value, children) {
158
+ const node = children?.find(p => p.key?.value === value);
159
+ return node?.value?.type === 'json:string' ? node.value.value : undefined;
160
+ }
161
+ exports.extract = extract;
162
+ function extractNested(wrap, value, children) {
163
+ const wrapper = children?.find(p => p.key?.value === wrap);
164
+ if (wrapper?.value?.type !== 'json:object')
165
+ return undefined;
166
+ const node = wrapper.children?.find(p => p.key?.value === value);
167
+ return node?.type === 'json:string' ? node.value : undefined;
168
+ }
169
+ exports.extractNested = extractNested;
170
+ function extractStringArray(value, children) {
171
+ const node = children?.find(p => p.key?.value === value);
172
+ return node?.value?.type === 'json:array' && node.value.children?.every((n) => n.value?.type === 'json:string')
173
+ ? node.value.children.map(n => n.value.value)
174
+ : undefined;
175
+ }
176
+ exports.extractStringArray = extractStringArray;
177
+ function having(node, ctx, cases) {
178
+ const givenKeys = new Set(node_1.JsonObjectNode.is(node)
179
+ ? node.children.map(n => n.key?.value) : []);
180
+ const key = Object.keys(cases).find(c => givenKeys.has(c));
181
+ if (key === undefined) {
182
+ ctx.err.report((0, locales_1.localize)('json.checker.property.missing', Object.keys(cases)), core_1.Range.create(node.range.start, node.range.start + 1));
183
+ return Object.fromEntries(Object.entries(cases)
184
+ .map(([k, v]) => [k, opt(typeof v === 'function' ? (0, util_1.any)() : v[k] ?? (0, util_1.any)())]));
185
+ }
186
+ const c = cases[key];
187
+ return typeof c === 'function' ? c() : c;
188
+ }
189
+ exports.having = having;
190
+ //# sourceMappingURL=object.js.map
@@ -0,0 +1,12 @@
1
+ import type { AllCategory, AstNode, Checker, Parser, ResourceLocationCategory, TaggableResourceLocationCategory } from '@spyglassmc/core';
2
+ import { Lazy } from '@spyglassmc/core';
3
+ import type { JsonExpectation } from '../../node';
4
+ import { JsonStringNode } from '../../node';
5
+ import type { JsonChecker } from '../JsonChecker';
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<Checker<T>>, expectation?: Partial<JsonExpectation>): JsonChecker;
10
+ export declare function string(name?: string | readonly string[], parser?: undefined, checker?: Lazy<Checker<JsonStringNode>>, expectation?: Partial<JsonExpectation>): JsonChecker;
11
+ export declare const simpleString: JsonChecker;
12
+ //# sourceMappingURL=string.d.ts.map
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.simpleString = exports.string = exports.literal = exports.resource = void 0;
23
+ const core = __importStar(require("@spyglassmc/core"));
24
+ const core_1 = require("@spyglassmc/core");
25
+ const locales_1 = require("@spyglassmc/locales");
26
+ const node_1 = require("../../node");
27
+ function resource(id, allowTag = false) {
28
+ return string(id, core.resourceLocation(typeof id === 'string'
29
+ ? { category: id, allowTag }
30
+ : { pool: id.map(core_1.ResourceLocation.lengthen) }), core.checker.resourceLocation);
31
+ }
32
+ exports.resource = resource;
33
+ function literal(value) {
34
+ return typeof value === 'string'
35
+ ? string(value, core.symbol(value))
36
+ : string(value, core.literal(...value));
37
+ }
38
+ exports.literal = literal;
39
+ function string(name, parser, checker, expectation) {
40
+ return (node, ctx) => {
41
+ ctx.ops.set(node, 'expectation', [{ type: 'json:string', typedoc: typedoc(name), ...expectation }]);
42
+ if (!node_1.JsonStringNode.is(node)) {
43
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.localize)('string')), node);
44
+ }
45
+ else if (parser) {
46
+ const result = core.parseStringValue(core_1.Lazy.resolve(parser), node.value, node.valueMap, ctx);
47
+ if (result !== core_1.Failure) {
48
+ node.children = [result];
49
+ result.parent = node;
50
+ if (checker) {
51
+ core_1.Lazy.resolve(checker)(result, ctx);
52
+ }
53
+ }
54
+ }
55
+ else if (checker) {
56
+ core_1.Lazy.resolve(checker)(node, ctx);
57
+ }
58
+ };
59
+ }
60
+ exports.string = string;
61
+ function typedoc(id) {
62
+ if (!id) {
63
+ return 'String';
64
+ }
65
+ if (typeof id === 'string') {
66
+ return `String("${id}")`;
67
+ }
68
+ return id.slice(0, 10).map(e => `"${e}"`).join(' | ')
69
+ + (id.length > 10 ? ' | ...' : '');
70
+ }
71
+ exports.simpleString = string();
72
+ //# sourceMappingURL=string.js.map
@@ -0,0 +1,15 @@
1
+ import type { ErrorSeverity } from '@spyglassmc/core';
2
+ import type { JsonExpectation, JsonNode } from '../../node';
3
+ import type { JsonChecker, JsonCheckerContext } from '../JsonChecker';
4
+ export declare function ref(checker: () => JsonChecker): JsonChecker;
5
+ export declare function as(context: string, checker: JsonChecker): JsonChecker;
6
+ export declare 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
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expectation = exports.any = exports.attempt = exports.as = exports.ref = void 0;
4
+ const core_1 = require("@spyglassmc/core");
5
+ const locales_1 = require("@spyglassmc/locales");
6
+ function ref(checker) {
7
+ return (node, ctx) => {
8
+ return checker()(node, ctx);
9
+ };
10
+ }
11
+ exports.ref = ref;
12
+ function as(context, checker) {
13
+ return (node, ctx) => {
14
+ checker(node, { ...ctx, context });
15
+ };
16
+ }
17
+ exports.as = as;
18
+ function attempt(checker, node, ctx) {
19
+ // TODO: The code below is mostly copied from core with some changes to support `expectation`. Could be refactored... I guess.
20
+ const tempCtx = {
21
+ ...ctx,
22
+ err: new core_1.ErrorReporter(),
23
+ ops: new core_1.Operations(),
24
+ symbols: ctx.symbols.clone(),
25
+ };
26
+ checker(node, tempCtx);
27
+ const tempExpectation = node.expectation;
28
+ tempCtx.ops.undo();
29
+ const totalErrorSpan = tempCtx.err.errors
30
+ .map(e => e.range.end - e.range.start)
31
+ .reduce((a, b) => a + b, 0);
32
+ return {
33
+ totalErrorSpan,
34
+ maxSeverity: Math.max(...tempCtx.err.errors.map(e => e.severity)),
35
+ expectation: tempExpectation,
36
+ updateNodeAndCtx: () => {
37
+ ctx.err.absorb(tempCtx.err);
38
+ tempCtx.ops.redo();
39
+ tempCtx.symbols.applyDelayedEdits();
40
+ },
41
+ };
42
+ }
43
+ exports.attempt = attempt;
44
+ function any(checkers = []) {
45
+ return (node, ctx) => {
46
+ if (checkers.length === 0) {
47
+ return;
48
+ }
49
+ const attempts = checkers
50
+ .map(checker => attempt(checker, node, ctx))
51
+ .sort((a, b) => a.maxSeverity - b.maxSeverity || a.totalErrorSpan - b.totalErrorSpan);
52
+ const sameTypeAttempts = attempts
53
+ .filter(a => a.expectation?.map(e => e.type).includes(node.type));
54
+ const allExpectations = attempts.filter(a => a.expectation).flatMap(a => a.expectation);
55
+ if (sameTypeAttempts.length === 0) {
56
+ const allowedTypes = allExpectations.map(e => (0, locales_1.localize)(e.type.slice(5)));
57
+ ctx.err.report((0, locales_1.localize)('expected', (0, locales_1.arrayToMessage)(allowedTypes, false)), node);
58
+ }
59
+ else {
60
+ sameTypeAttempts[0].updateNodeAndCtx();
61
+ }
62
+ ctx.ops.set(node, 'expectation', allExpectations);
63
+ };
64
+ }
65
+ exports.any = any;
66
+ function expectation(checker, ctx) {
67
+ const node = { type: 'json:null', range: core_1.Range.create(0) };
68
+ const tempCtx = {
69
+ ...ctx,
70
+ err: new core_1.ErrorReporter(),
71
+ depth: (ctx.depth ?? 0) + 1,
72
+ };
73
+ checker(node, tempCtx);
74
+ return node.expectation;
75
+ }
76
+ exports.expectation = expectation;
77
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1,7 @@
1
+ import type { Colorizer, MetaRegistry } from '@spyglassmc/core';
2
+ import type { JsonBooleanNode, JsonNullNode, JsonObjectNode } from '../node';
3
+ export declare const boolean: Colorizer<JsonBooleanNode>;
4
+ export declare const null_: Colorizer<JsonNullNode>;
5
+ export declare const object: Colorizer<JsonObjectNode>;
6
+ export declare function register(meta: MetaRegistry): void;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.register = exports.object = exports.null_ = exports.boolean = void 0;
23
+ const core = __importStar(require("@spyglassmc/core"));
24
+ const core_1 = require("@spyglassmc/core");
25
+ const boolean = node => {
26
+ return [core_1.ColorToken.create(node, 'literal')];
27
+ };
28
+ exports.boolean = boolean;
29
+ const null_ = node => {
30
+ return [core_1.ColorToken.create(node, 'literal')];
31
+ };
32
+ exports.null_ = null_;
33
+ const object = (node, ctx) => {
34
+ const ans = [];
35
+ for (const pair of node.children) {
36
+ if (pair.key) {
37
+ ans.push(core_1.ColorToken.create(pair.key, 'property'));
38
+ }
39
+ if (pair.value) {
40
+ const colorizer = ctx.meta.getColorizer(pair.value.type);
41
+ ans.push(...colorizer(pair.value, ctx));
42
+ }
43
+ }
44
+ return ans;
45
+ };
46
+ exports.object = object;
47
+ function register(meta) {
48
+ meta.registerColorizer('json:boolean', exports.boolean);
49
+ meta.registerColorizer('json:null', exports.null_);
50
+ meta.registerColorizer('json:number', core.colorizer.number);
51
+ meta.registerColorizer('json:object', exports.object);
52
+ meta.registerColorizer('json:string', core.colorizer.string);
53
+ }
54
+ exports.register = register;
55
+ //# sourceMappingURL=index.js.map