@spyglassmc/json 0.3.1 → 0.3.3

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.
@@ -4,5 +4,5 @@ export interface JsonCheckerContext extends CheckerContext {
4
4
  context: string;
5
5
  depth?: number;
6
6
  }
7
- export declare type JsonChecker = (node: JsonNode, ctx: JsonCheckerContext) => void;
7
+ export type JsonChecker = (node: JsonNode, ctx: JsonCheckerContext) => void;
8
8
  //# sourceMappingURL=JsonChecker.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import type { JsonNode } from '../../node/index.js';
2
2
  import type { JsonChecker, JsonCheckerContext } from '../JsonChecker.js';
3
3
  export declare function listOf(checker: JsonChecker): JsonChecker;
4
- declare type UniqueListOptions = {
4
+ type UniqueListOptions = {
5
5
  items?: (node: JsonNode) => [string | undefined, JsonNode];
6
6
  report?: (node: JsonNode, ctx: JsonCheckerContext) => unknown;
7
7
  };
@@ -5,26 +5,30 @@ export function listOf(checker) {
5
5
  return (node, ctx) => {
6
6
  node.expectation = [{ type: 'json:array', typedoc: 'Array' }];
7
7
  if (!ctx.depth || ctx.depth <= 0) {
8
+ ;
8
9
  node.expectation[0].items = expectation(checker, ctx);
9
10
  }
10
11
  if (!JsonArrayNode.is(node)) {
11
12
  ctx.err.report(localize('expected', localize('array')), node);
12
13
  }
13
14
  else {
14
- node.children.filter(e => e.value)
15
- .forEach(e => checker(e.value, ctx));
15
+ node.children
16
+ .filter((e) => e.value)
17
+ .forEach((e) => checker(e.value, ctx));
16
18
  }
17
19
  };
18
20
  }
19
21
  export function uniqueListOf(checker, options = {}) {
20
- const getItem = (options.items ?? (node => [JsonStringNode.is(node) ? node.value : undefined, node]));
21
- const reporter = options.report ?? ((node, ctx) => ctx.err.report(localize('json.checker.item.duplicate'), node, 2 /* ErrorSeverity.Warning */));
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 */));
22
26
  return (node, ctx) => {
23
27
  listOf(checker)(node, ctx);
24
28
  if (JsonArrayNode.is(node)) {
25
29
  const items = new Map();
26
30
  const duplicates = new Set();
27
- node.children.forEach(c => {
31
+ node.children.forEach((c) => {
28
32
  if (!c.value)
29
33
  return;
30
34
  const [value, item] = getItem(c.value);
@@ -37,7 +41,7 @@ export function uniqueListOf(checker, options = {}) {
37
41
  }
38
42
  items.set(value, item);
39
43
  });
40
- duplicates.forEach(node => reporter(node, ctx));
44
+ duplicates.forEach((node) => reporter(node, ctx));
41
45
  }
42
46
  };
43
47
  }
@@ -2,12 +2,18 @@ import { localize } from '@spyglassmc/locales';
2
2
  import { JsonNumberNode } from '../../node/index.js';
3
3
  const number = (type) => (min, max) => {
4
4
  return (node, ctx) => {
5
- const typedoc = 'Number' + (min === undefined && max === undefined ? '' : `(${min ?? '-∞'}, ${max ?? '+∞'})`);
5
+ const typedoc = 'Number' +
6
+ (min === undefined && max === undefined
7
+ ? ''
8
+ : `(${min ?? '-∞'}, ${max ?? '+∞'})`);
6
9
  node.expectation = [{ type: 'json:number', typedoc }];
7
- if (!JsonNumberNode.is(node) || (type === 'integer' && !Number.isInteger(node.value))) {
10
+ if (!JsonNumberNode.is(node) ||
11
+ (type === 'integer' && !Number.isInteger(node.value))) {
8
12
  ctx.err.report(localize('expected', localize(type)), node);
9
13
  }
10
- else if (min !== undefined && max !== undefined && (node.value < min || node.value > max)) {
14
+ else if (min !== undefined &&
15
+ max !== undefined &&
16
+ (node.value < min || node.value > max)) {
11
17
  ctx.err.report(localize('expected', localize('number.between', min, max)), node);
12
18
  }
13
19
  else if (min !== undefined && node.value < min) {
@@ -1,19 +1,19 @@
1
1
  import type { PairNode } from '@spyglassmc/core';
2
2
  import type { JsonNode, JsonStringNode } from '../../node/index.js';
3
3
  import type { JsonChecker, JsonCheckerContext } from '../JsonChecker.js';
4
- declare type JsonValue = string | number | boolean | null | JsonValue[] | {
4
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
5
5
  [key: string]: JsonValue;
6
6
  };
7
- declare type ComplexProperty = {
7
+ type ComplexProperty = {
8
8
  checker: JsonChecker;
9
9
  opt?: boolean;
10
10
  def?: JsonValue;
11
11
  deprecated?: boolean;
12
12
  context?: string;
13
13
  };
14
- declare type CheckerProperty = JsonChecker | ComplexProperty;
15
- declare type CheckerRecord = Record<string, CheckerProperty | undefined>;
16
- declare type ObjectCheckerOptions = {
14
+ type CheckerProperty = JsonChecker | ComplexProperty;
15
+ type CheckerRecord = Record<string, CheckerProperty | undefined>;
16
+ type ObjectCheckerOptions = {
17
17
  allowUnknownProperties?: boolean;
18
18
  };
19
19
  export declare function object(): JsonChecker;
@@ -10,36 +10,45 @@ export function object(keys, values, options = {}) {
10
10
  node.expectation = [{ type: 'json:object', typedoc: 'Object' }];
11
11
  if (!ctx.depth || ctx.depth <= 0) {
12
12
  if (Array.isArray(keys) && values) {
13
- const fields = keys.map(key => [key, values(key, ctx)]).filter(([_, v]) => v !== undefined);
14
- node.expectation[0].fields = fields.map(([key, prop]) => {
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]) => {
15
18
  return {
16
19
  key,
17
20
  value: expectation(isComplex(prop) ? prop.checker : prop, ctx),
18
- ...isComplex(prop) && (prop.opt || prop.deprecated) ? { opt: true } : {},
19
- ...isComplex(prop) && prop.deprecated ? { deprecated: true } : {},
21
+ ...(isComplex(prop) && (prop.opt || prop.deprecated)
22
+ ? { opt: true }
23
+ : {}),
24
+ ...(isComplex(prop) && prop.deprecated
25
+ ? { deprecated: true }
26
+ : {}),
20
27
  };
21
28
  });
22
29
  }
23
30
  else if (typeof keys === 'function' && values) {
24
- node.expectation[0].keys = expectation(keys, ctx)
25
- ?.filter(JsonStringExpectation.is);
31
+ ;
32
+ node.expectation[0].keys = expectation(keys, ctx)?.filter(JsonStringExpectation.is);
26
33
  }
27
34
  }
28
35
  if (!JsonObjectNode.is(node)) {
29
36
  ctx.err.report(localize('expected', localize('object')), node);
30
37
  }
31
38
  else if (Array.isArray(keys) && values) {
32
- const givenKeys = node.children.map(n => n.key?.value);
33
- keys.forEach(k => {
39
+ const givenKeys = node.children.map((n) => n.key?.value);
40
+ keys.forEach((k) => {
34
41
  const value = values(k, ctx);
35
- if (!value || isComplex(value) && (value.opt || value.deprecated)) {
42
+ if (!value || (isComplex(value) && (value.opt || value.deprecated))) {
36
43
  return;
37
44
  }
38
45
  if (!givenKeys.includes(k)) {
39
46
  ctx.err.report(localize('json.checker.property.missing', localeQuote(k)), Range.create(node.range.start, node.range.start + 1));
40
47
  }
41
48
  });
42
- node.children.filter(p => p.key).forEach(prop => {
49
+ node.children
50
+ .filter((p) => p.key)
51
+ .forEach((prop) => {
43
52
  const key = prop.key.value;
44
53
  const value = values(key, ctx);
45
54
  if (!value || !keys.includes(key)) {
@@ -51,9 +60,12 @@ export function object(keys, values, options = {}) {
51
60
  if (isComplex(value) && value.deprecated) {
52
61
  ctx.err.report(localize('json.checker.property.deprecated', localeQuote(key)), prop.key, 0 /* ErrorSeverity.Hint */, { deprecated: true });
53
62
  }
54
- const context = ctx.context + (isComplex(value) && value.context ? `.${value.context}` : '');
63
+ const context = ctx.context +
64
+ (isComplex(value) && value.context ? `.${value.context}` : '');
55
65
  const doc = localize(`json.doc.${context}`);
56
- const propNode = prop.value !== undefined ? prop.value : { type: 'json:null', range: Range.create(0) };
66
+ const propNode = prop.value !== undefined
67
+ ? prop.value
68
+ : { type: 'json:null', range: Range.create(0) };
57
69
  const checker = isComplex(value) ? value.checker : value;
58
70
  try {
59
71
  checker(propNode, { ...ctx, context: `${context}.${key}` });
@@ -63,12 +75,19 @@ export function object(keys, values, options = {}) {
63
75
  ctx.logger.error(`Checking "${key}" at ${pos.line}:${pos.character} in "${ctx.doc.uri}"`, e);
64
76
  }
65
77
  const defaultValue = isComplex(value) ? value.def : undefined;
66
- const typedoc = propNode.expectation?.map(e => e.typedoc).join(' | ');
67
- prop.key.hover = `\`\`\`typescript\n${context}.${key}: ${typedoc}\n\`\`\`${doc || defaultValue !== undefined ? '\n******\n ' : ''}${doc}${defaultValue !== undefined ? `\n\`@default\` ${JSON.stringify(defaultValue)}` : ''}`;
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
+ : ''}`;
68
85
  });
69
86
  }
70
87
  else if (typeof keys === 'function' && values) {
71
- node.children.filter(p => p.key).forEach(prop => {
88
+ node.children
89
+ .filter((p) => p.key)
90
+ .forEach((prop) => {
72
91
  keys(prop.key, ctx);
73
92
  if (prop.value !== undefined) {
74
93
  const value = values(prop.key.value, ctx);
@@ -104,12 +123,15 @@ export function dispatch(arg1, arg2) {
104
123
  ctx.err.report(localize('expected', localize('object')), node);
105
124
  }
106
125
  else if (arg2) {
107
- const dispatcherIndex = node.children.findIndex(p => p.key?.value === arg1);
126
+ const dispatcherIndex = node.children.findIndex((p) => p.key?.value === arg1);
108
127
  const dispatcher = node.children[dispatcherIndex];
109
- const value = dispatcher?.value?.type === 'json:string' ? dispatcher.value.value : undefined;
128
+ const value = dispatcher?.value?.type === 'json:string'
129
+ ? dispatcher.value.value
130
+ : undefined;
110
131
  arg2(value, node.children, ctx)(node, ctx);
111
132
  }
112
133
  else {
134
+ ;
113
135
  arg1(node.children, ctx)(node, ctx);
114
136
  }
115
137
  };
@@ -122,7 +144,7 @@ export function pick(value, cases) {
122
144
  if (properties === undefined) {
123
145
  return {};
124
146
  }
125
- Object.keys(properties).forEach(key => {
147
+ Object.keys(properties).forEach((key) => {
126
148
  const p = properties[key];
127
149
  if (p === undefined)
128
150
  return;
@@ -145,30 +167,33 @@ export function when(value, values, properties, notProperties = {}) {
145
167
  return properties;
146
168
  }
147
169
  export function extract(value, children) {
148
- const node = children?.find(p => p.key?.value === value);
170
+ const node = children?.find((p) => p.key?.value === value);
149
171
  return node?.value?.type === 'json:string' ? node.value.value : undefined;
150
172
  }
151
173
  export function extractNested(wrap, value, children) {
152
- const wrapper = children?.find(p => p.key?.value === wrap);
174
+ const wrapper = children?.find((p) => p.key?.value === wrap);
153
175
  if (wrapper?.value?.type !== 'json:object')
154
176
  return undefined;
155
- const node = wrapper.children?.find(p => p.key?.value === value);
177
+ const node = wrapper.children?.find((p) => p.key?.value ===
178
+ value);
156
179
  return node?.type === 'json:string' ? node.value : undefined;
157
180
  }
158
181
  export function extractStringArray(value, children) {
159
- const node = children?.find(p => p.key?.value === value);
160
- return node?.value?.type === 'json:array' && node.value.children?.every((n) => n.value?.type === 'json:string')
161
- ? node.value.children.map(n => n.value.value)
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)
162
186
  : undefined;
163
187
  }
164
188
  export function having(node, ctx, cases) {
165
- const givenKeys = new Set(JsonObjectNode.is(node)
166
- ? node.children.map(n => n.key?.value) : []);
167
- const key = Object.keys(cases).find(c => givenKeys.has(c));
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));
168
191
  if (key === undefined) {
169
192
  ctx.err.report(localize('json.checker.property.missing', Object.keys(cases)), Range.create(node.range.start, node.range.start + 1));
170
- return Object.fromEntries(Object.entries(cases)
171
- .map(([k, v]) => [k, opt(typeof v === 'function' ? any() : v[k] ?? any())]));
193
+ return Object.fromEntries(Object.entries(cases).map(([k, v]) => [
194
+ k,
195
+ opt(typeof v === 'function' ? any() : v[k] ?? any()),
196
+ ]));
172
197
  }
173
198
  const c = cases[key];
174
199
  return typeof c === 'function' ? c() : c;
@@ -14,7 +14,9 @@ export function literal(value) {
14
14
  }
15
15
  export function string(name, parser, checker, expectation) {
16
16
  return (node, ctx) => {
17
- node.expectation = [{ type: 'json:string', typedoc: typedoc(name), ...expectation }];
17
+ node.expectation = [
18
+ { type: 'json:string', typedoc: typedoc(name), ...expectation },
19
+ ];
18
20
  if (!JsonStringNode.is(node)) {
19
21
  ctx.err.report(localize('expected', localize('string')), node);
20
22
  }
@@ -40,8 +42,10 @@ function typedoc(id) {
40
42
  if (typeof id === 'string') {
41
43
  return `String("${id}")`;
42
44
  }
43
- return id.slice(0, 10).map(e => `"${e}"`).join(' | ')
44
- + (id.length > 10 ? ' | ...' : '');
45
+ return (id
46
+ .slice(0, 10)
47
+ .map((e) => `"${e}"`)
48
+ .join(' | ') + (id.length > 10 ? ' | ...' : ''));
45
49
  }
46
50
  export const simpleString = string();
47
51
  //# sourceMappingURL=string.js.map
@@ -3,7 +3,7 @@ import type { JsonExpectation, JsonNode } from '../../node/index.js';
3
3
  import type { JsonChecker, JsonCheckerContext } from '../JsonChecker.js';
4
4
  export declare function ref(checker: () => JsonChecker): JsonChecker;
5
5
  export declare function as(context: string, checker: JsonChecker): JsonChecker;
6
- export declare type AttemptResult = {
6
+ export type AttemptResult = {
7
7
  totalErrorSpan: number;
8
8
  maxSeverity: ErrorSeverity;
9
9
  expectation?: JsonExpectation[];
@@ -21,11 +21,11 @@ export function attempt(checker, node, ctx) {
21
21
  const tempExpectation = node.expectation;
22
22
  StateProxy.undoChanges(node);
23
23
  const totalErrorSpan = tempCtx.err.errors
24
- .map(e => e.range.end - e.range.start)
24
+ .map((e) => e.range.end - e.range.start)
25
25
  .reduce((a, b) => a + b, 0);
26
26
  return {
27
27
  totalErrorSpan,
28
- maxSeverity: Math.max(...tempCtx.err.errors.map(e => e.severity)),
28
+ maxSeverity: Math.max(...tempCtx.err.errors.map((e) => e.severity)),
29
29
  expectation: tempExpectation,
30
30
  updateNodeAndCtx: () => {
31
31
  ctx.err.absorb(tempCtx.err);
@@ -40,13 +40,15 @@ export function any(checkers = []) {
40
40
  return;
41
41
  }
42
42
  const attempts = checkers
43
- .map(checker => attempt(checker, node, ctx))
44
- .sort((a, b) => a.maxSeverity - b.maxSeverity || a.totalErrorSpan - b.totalErrorSpan);
45
- const sameTypeAttempts = attempts
46
- .filter(a => a.expectation?.map(e => e.type).includes(node.type));
47
- const allExpectations = attempts.filter(a => a.expectation).flatMap(a => a.expectation);
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);
48
50
  if (sameTypeAttempts.length === 0) {
49
- const allowedTypes = allExpectations.map(e => localize(e.type.slice(5)));
51
+ const allowedTypes = allExpectations.map((e) => localize(e.type.slice(5)));
50
52
  ctx.err.report(localize('expected', arrayToMessage(allowedTypes, false)), node);
51
53
  }
52
54
  else {
@@ -56,7 +58,10 @@ export function any(checkers = []) {
56
58
  };
57
59
  }
58
60
  export function expectation(checker, ctx) {
59
- const node = StateProxy.create({ type: 'json:null', range: Range.create(0) });
61
+ const node = StateProxy.create({
62
+ type: 'json:null',
63
+ range: Range.create(0),
64
+ });
60
65
  const tempCtx = {
61
66
  ...ctx,
62
67
  err: new ErrorReporter(),
@@ -1,9 +1,9 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import { ColorToken } from '@spyglassmc/core';
3
- export const boolean = node => {
3
+ export const boolean = (node) => {
4
4
  return [ColorToken.create(node, 'literal')];
5
5
  };
6
- export const null_ = node => {
6
+ export const null_ = (node) => {
7
7
  return [ColorToken.create(node, 'literal')];
8
8
  };
9
9
  export const object = (node, ctx) => {
@@ -15,8 +15,9 @@ export const entry = (node, ctx) => {
15
15
  export const object = core.completer.record({
16
16
  key: (record, pair, ctx, range, insertValue, insertComma) => {
17
17
  if (record.expectation) {
18
- return unique(record.expectation.filter(JsonExpectation.isObject)
19
- .flatMap(e => objectCompletion(range, record, e, ctx, insertValue, insertComma, pair?.key?.value)));
18
+ return unique(record.expectation
19
+ .filter(JsonExpectation.isObject)
20
+ .flatMap((e) => objectCompletion(range, record, e, ctx, insertValue, insertComma, pair?.key?.value)));
20
21
  }
21
22
  return [];
22
23
  },
@@ -25,10 +26,11 @@ export const object = core.completer.record({
25
26
  return core.completer.dispatch(pair.value, ctx);
26
27
  }
27
28
  if (record.expectation) {
28
- return unique(record.expectation.filter(JsonExpectation.isObject)
29
- .filter(e => e.fields)
30
- .map(e => e.fields.find(f => f.key === pair.key?.value))
31
- .flatMap(f => valueCompletion(ctx.offset, f.value, ctx)));
29
+ return unique(record.expectation
30
+ .filter(JsonExpectation.isObject)
31
+ .filter((e) => e.fields)
32
+ .map((e) => e.fields.find((f) => f.key === pair.key?.value))
33
+ .flatMap((f) => valueCompletion(ctx.offset, f.value, ctx)));
32
34
  }
33
35
  return [];
34
36
  },
@@ -41,37 +43,42 @@ export const array = (node, ctx) => {
41
43
  if (item?.value) {
42
44
  return core.completer.dispatch(item.value, ctx);
43
45
  }
44
- if (node.expectation && Range.contains(Range.translate(node, 1, -1), ctx.offset, true)) {
45
- return unique(node.expectation.filter(JsonExpectation.isArray)
46
- .filter(e => e.items)
47
- .flatMap(e => valueCompletion(ctx.offset, e.items, ctx)));
46
+ if (node.expectation &&
47
+ Range.contains(Range.translate(node, 1, -1), ctx.offset, true)) {
48
+ return unique(node.expectation
49
+ .filter(JsonExpectation.isArray)
50
+ .filter((e) => e.items)
51
+ .flatMap((e) => valueCompletion(ctx.offset, e.items, ctx)));
48
52
  }
49
53
  return [];
50
54
  };
51
55
  export const boolean = (node) => {
52
- return ['false', 'true'].map(v => simpleCompletion(node, v));
56
+ return ['false', 'true'].map((v) => simpleCompletion(node, v));
53
57
  };
54
58
  const string = (node, ctx) => {
55
59
  if (node.children?.length) {
56
60
  return core.completer.string(node, ctx);
57
61
  }
58
62
  if (node.expectation) {
59
- return unique(node.expectation.filter(JsonExpectation.isString)
60
- .flatMap(e => stringCompletion(node, e, ctx)));
63
+ return unique(node.expectation
64
+ .filter(JsonExpectation.isString)
65
+ .flatMap((e) => stringCompletion(node, e, ctx)));
61
66
  }
62
67
  return [];
63
68
  };
64
69
  function objectCompletion(range, node, expectation, ctx, insertValue, insertComma, selectedKey) {
65
70
  if (expectation.fields) {
66
- return expectation.fields
67
- .filter(f => f.key === selectedKey || !node.children.find(p => f.key === p.key?.value))
68
- .map(f => fieldCompletion(range, f, insertValue, insertComma));
71
+ return expectation
72
+ .fields.filter((f) => f.key === selectedKey ||
73
+ !node.children.find((p) => f.key === p.key?.value))
74
+ .map((f) => fieldCompletion(range, f, insertValue, insertComma));
69
75
  }
70
76
  else if (expectation.keys) {
71
- return expectation.keys.flatMap(e => stringCompletion(range, e, ctx)
72
- .map(c => ({
77
+ return expectation.keys.flatMap((e) => stringCompletion(range, e, ctx).map((c) => ({
73
78
  ...c,
74
- ...insertValue ? { insertText: `${c.insertText}: ${insertComma ? ',' : ''}` } : {},
79
+ ...(insertValue
80
+ ? { insertText: `${c.insertText}: ${insertComma ? ',' : ''}` }
81
+ : {}),
75
82
  })));
76
83
  }
77
84
  return [];
@@ -80,7 +87,7 @@ function fieldCompletion(range, field, insertValue, insertComma) {
80
87
  const value = field.value?.[0] ? SIMPLE_SNIPPETS[field.value[0].type] : '';
81
88
  return CompletionItem.create(field.key, range, {
82
89
  kind: 10 /* CompletionKind.Property */,
83
- detail: field.value?.map(e => e.typedoc).join(' | '),
90
+ detail: field.value?.map((e) => e.typedoc).join(' | '),
84
91
  sortText: `${field.deprecated ? 2 : field.opt ? 1 : 0}${field.key}`,
85
92
  deprecated: field.deprecated,
86
93
  filterText: `"${field.key}"`,
@@ -88,7 +95,7 @@ function fieldCompletion(range, field, insertValue, insertComma) {
88
95
  });
89
96
  }
90
97
  function valueCompletion(range, expectation, ctx) {
91
- return unique(expectation.flatMap(e => {
98
+ return unique(expectation.flatMap((e) => {
92
99
  switch (e.type) {
93
100
  case 'json:object':
94
101
  case 'json:array':
@@ -96,7 +103,7 @@ function valueCompletion(range, expectation, ctx) {
96
103
  case 'json:string':
97
104
  return stringCompletion(ctx.offset, e, ctx);
98
105
  case 'json:boolean':
99
- return ['false', 'true'].map(v => simpleCompletion(range, v));
106
+ return ['false', 'true'].map((v) => simpleCompletion(range, v));
100
107
  case 'json:number':
101
108
  return [simpleCompletion(range, '0')];
102
109
  }
@@ -104,7 +111,7 @@ function valueCompletion(range, expectation, ctx) {
104
111
  }
105
112
  function stringCompletion(range, expectation, ctx) {
106
113
  if (Array.isArray(expectation.pool)) {
107
- return expectation.pool.map(v => CompletionItem.create(v, range, {
114
+ return expectation.pool.map((v) => CompletionItem.create(v, range, {
108
115
  kind: 12 /* CompletionKind.Value */,
109
116
  filterText: `"${v}"`,
110
117
  insertText: `"${v}"`,
@@ -121,7 +128,7 @@ function simpleCompletion(range, value) {
121
128
  function unique(completions) {
122
129
  const ans = [];
123
130
  const labels = new Set();
124
- completions.forEach(c => {
131
+ completions.forEach((c) => {
125
132
  if (!labels.has(c.label)) {
126
133
  labels.add(c.label);
127
134
  ans.push(c);
@@ -3,8 +3,9 @@ import { indentFormatter } from '@spyglassmc/core';
3
3
  const array = (node, ctx) => {
4
4
  if (node.children.length === 0)
5
5
  return '[]';
6
- const values = node.children.map(child => {
7
- const value = child.value && ctx.meta.getFormatter(child.value.type)(child.value, indentFormatter(ctx));
6
+ const values = node.children.map((child) => {
7
+ const value = child.value &&
8
+ ctx.meta.getFormatter(child.value.type)(child.value, indentFormatter(ctx));
8
9
  return `${ctx.indent(1)}${value ?? ''}`;
9
10
  });
10
11
  return `[\n${values.join(',\n')}\n${ctx.indent()}]`;
@@ -12,9 +13,10 @@ const array = (node, ctx) => {
12
13
  const object = (node, ctx) => {
13
14
  if (node.children.length === 0)
14
15
  return '{}';
15
- const fields = node.children.map(child => {
16
+ const fields = node.children.map((child) => {
16
17
  const key = child.key && core.formatter.string(child.key, ctx);
17
- const value = child.value && ctx.meta.getFormatter(child.value.type)(child.value, indentFormatter(ctx));
18
+ const value = child.value &&
19
+ ctx.meta.getFormatter(child.value.type)(child.value, indentFormatter(ctx));
18
20
  return `${ctx.indent(1)}${key ?? ''}: ${value ?? ''}`;
19
21
  });
20
22
  return `{\n${fields.join(',\n')}\n${ctx.indent()}}`;
@@ -1,7 +1,7 @@
1
1
  import type { DeepReadonly, ItemNode, PairNode } from '@spyglassmc/core';
2
2
  import * as core from '@spyglassmc/core';
3
- export declare type JsonNode = JsonObjectNode | JsonArrayNode | JsonStringNode | JsonNumberNode | JsonBooleanNode | JsonNullNode;
4
- export declare type JsonRelatedNode = JsonNode | JsonPairNode | JsonItemNode;
3
+ export type JsonNode = JsonObjectNode | JsonArrayNode | JsonStringNode | JsonNumberNode | JsonBooleanNode | JsonNullNode;
4
+ export type JsonRelatedNode = JsonNode | JsonPairNode | JsonItemNode;
5
5
  export declare namespace JsonNode {
6
6
  function is(node: core.AstNode): node is JsonNode;
7
7
  function isRelated(node: core.AstNode): node is JsonRelatedNode;
@@ -9,7 +9,7 @@ export declare namespace JsonNode {
9
9
  interface JsonBaseAstNode {
10
10
  expectation?: JsonExpectation[];
11
11
  }
12
- export declare type JsonExpectation = JsonObjectExpectation | JsonArrayExpectation | JsonStringExpectation | JsonNumberExpectation | JsonBooleanExpectation;
12
+ export type JsonExpectation = JsonObjectExpectation | JsonArrayExpectation | JsonStringExpectation | JsonNumberExpectation | JsonBooleanExpectation;
13
13
  export declare namespace JsonExpectation {
14
14
  function isArray(e: DeepReadonly<JsonExpectation>): e is DeepReadonly<JsonArrayExpectation>;
15
15
  function isObject(e: DeepReadonly<JsonExpectation>): e is DeepReadonly<JsonObjectExpectation>;
@@ -35,7 +35,7 @@ export declare namespace JsonObjectNode {
35
35
  function is(obj: object | undefined): obj is JsonObjectNode;
36
36
  function mock(range: core.RangeLike): JsonObjectNode;
37
37
  }
38
- export declare type JsonPairNode = PairNode<JsonStringNode, JsonNode>;
38
+ export type JsonPairNode = PairNode<JsonStringNode, JsonNode>;
39
39
  export declare namespace JsonPairNode {
40
40
  function is(obj: object): obj is JsonPairNode;
41
41
  }
@@ -50,7 +50,7 @@ export declare namespace JsonArrayNode {
50
50
  function is(obj: object | undefined): obj is JsonArrayNode;
51
51
  function mock(range: core.RangeLike): JsonArrayNode;
52
52
  }
53
- export declare type JsonItemNode = ItemNode<JsonNode>;
53
+ export type JsonItemNode = ItemNode<JsonNode>;
54
54
  export declare namespace JsonItemNode {
55
55
  function is(obj: object): obj is JsonItemNode;
56
56
  }
@@ -12,9 +12,7 @@ export var JsonNode;
12
12
  }
13
13
  JsonNode.is = is;
14
14
  function isRelated(node) {
15
- return (JsonNode.is(node) ||
16
- JsonPairNode.is(node) ||
17
- JsonItemNode.is(node));
15
+ return JsonNode.is(node) || JsonPairNode.is(node) || JsonItemNode.is(node);
18
16
  }
19
17
  JsonNode.isRelated = isRelated;
20
18
  })(JsonNode || (JsonNode = {}));
@@ -5,15 +5,33 @@ import { null_ } from './null.js';
5
5
  import { number } from './number.js';
6
6
  import { object } from './object.js';
7
7
  import { string } from './string.js';
8
- const LegalNumberStart = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-']);
8
+ const LegalNumberStart = new Set([
9
+ '0',
10
+ '1',
11
+ '2',
12
+ '3',
13
+ '4',
14
+ '5',
15
+ '6',
16
+ '7',
17
+ '8',
18
+ '9',
19
+ '-',
20
+ ]);
9
21
  export function json(dumpErrors = false) {
10
22
  return (src, ctx) => {
11
23
  const result = core.select([
12
- { predicate: src => src.tryPeek('['), parser: array },
13
- { predicate: src => src.tryPeek('false') || src.tryPeek('true'), parser: boolean },
14
- { predicate: src => src.tryPeek('null'), parser: null_ },
15
- { predicate: src => LegalNumberStart.has(src.peek()), parser: number },
16
- { predicate: src => src.tryPeek('{'), parser: object },
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 },
17
35
  { parser: string },
18
36
  ])(src, ctx);
19
37
  if (dumpErrors) {
@@ -4,7 +4,13 @@ import { string } from './string.js';
4
4
  export const object = (src, ctx) => {
5
5
  return core.setType('json:object', core.record({
6
6
  start: '{',
7
- pair: { key: string, sep: ':', value: entry, end: ',', trailingEnd: false },
7
+ pair: {
8
+ key: string,
9
+ sep: ':',
10
+ value: entry,
11
+ end: ',',
12
+ trailingEnd: false,
13
+ },
8
14
  end: '}',
9
15
  }))(src, ctx);
10
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/json",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
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.0",
29
- "@spyglassmc/locales": "0.3.0"
28
+ "@spyglassmc/core": "0.4.2",
29
+ "@spyglassmc/locales": "0.3.2"
30
30
  }
31
31
  }