@spyglassmc/java-edition 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.
Files changed (44) hide show
  1. package/lib/binder/index.d.ts +1 -1
  2. package/lib/binder/index.js +110 -19
  3. package/lib/common/index.js +10 -7
  4. package/lib/dependency/common.d.ts +1 -1
  5. package/lib/dependency/index.js +11 -9
  6. package/lib/dependency/mcmeta.d.ts +4 -4
  7. package/lib/dependency/mcmeta.js +32 -15
  8. package/lib/index.js +18 -6
  9. package/lib/json/checker/data/advancement.js +24 -13
  10. package/lib/json/checker/data/biome.js +3 -3
  11. package/lib/json/checker/data/common.js +29 -30
  12. package/lib/json/checker/data/dimension.js +7 -18
  13. package/lib/json/checker/data/feature.js +45 -27
  14. package/lib/json/checker/data/index.d.ts +1 -1
  15. package/lib/json/checker/data/index.js +3 -3
  16. package/lib/json/checker/data/loot_table.js +40 -21
  17. package/lib/json/checker/data/recipe.js +1 -1
  18. package/lib/json/checker/data/structure.js +24 -14
  19. package/lib/json/checker/data/tag.js +2 -2
  20. package/lib/json/checker/data/text_component.js +24 -8
  21. package/lib/json/checker/index.d.ts +10 -3
  22. package/lib/json/checker/index.js +231 -3
  23. package/lib/json/checker/util/advancement.js +3 -2
  24. package/lib/json/checker/util/block_states.d.ts +2 -2
  25. package/lib/json/checker/util/block_states.js +7 -5
  26. package/lib/json/checker/util/color.js +8 -2
  27. package/lib/json/checker/util/nbt.d.ts +1 -1
  28. package/lib/json/checker/util/nbt.js +4 -2
  29. package/lib/json/checker/util/recipe.js +7 -6
  30. package/lib/json/checker/util/version.d.ts +1 -1
  31. package/lib/json/checker/util/version.js +2 -2
  32. package/lib/mcfunction/checker/index.js +14 -11
  33. package/lib/mcfunction/colorizer/index.js +2 -4
  34. package/lib/mcfunction/common/index.js +46 -15
  35. package/lib/mcfunction/completer/argument.js +53 -24
  36. package/lib/mcfunction/index.js +13 -1
  37. package/lib/mcfunction/inlayHintProvider.js +8 -3
  38. package/lib/mcfunction/node/argument.d.ts +6 -6
  39. package/lib/mcfunction/node/argument.js +57 -17
  40. package/lib/mcfunction/parser/argument.js +158 -63
  41. package/lib/mcfunction/signatureHelpProvider.js +9 -4
  42. package/lib/mcfunction/tree/argument.d.ts +1 -1
  43. package/lib/mcfunction/tree/patch.js +132 -126
  44. package/package.json +7 -7
@@ -1,6 +1,6 @@
1
1
  import { integer } from '@spyglassmc/core';
2
- import { any, as, boolean, dispatch, extract, having, int, listOf, literal, opt, pick, record, ref, resource, simpleString, string } from '@spyglassmc/json/lib/checker/primitives/index.js';
3
- import { deprecated, nbt, nbtPath, stringColor, uuid, versioned } from '../util/index.js';
2
+ import { any, as, boolean, dispatch, extract, having, int, listOf, literal, opt, pick, record, ref, resource, simpleString, string, } from '@spyglassmc/json/lib/checker/primitives/index.js';
3
+ import { deprecated, nbt, nbtPath, stringColor, uuid, versioned, } from '../util/index.js';
4
4
  const Keybinds = [
5
5
  'key.jump',
6
6
  'key.sneak',
@@ -69,11 +69,15 @@ const text_component_object = as('text_component', (node, ctx) => record({
69
69
  },
70
70
  entity: {
71
71
  entity: simpleString,
72
- nbt: nbtPath({ registry: 'entity_type' /* FIXME: import { getTypesFromEntity } from '../../../../mcfunction/checker'; ids: getTypesFromEntity(somehowGetTheNodeHere, ctx) */ }),
72
+ nbt: nbtPath({
73
+ registry: 'entity_type', /* FIXME: import { getTypesFromEntity } from '../../../../mcfunction/checker'; ids: getTypesFromEntity(somehowGetTheNodeHere, ctx) */
74
+ }),
73
75
  },
74
76
  storage: {
75
77
  storage: resource('storage'),
76
- nbt: nbtPath({ registry: 'storage' /* FIXME:, id: extract('storage', props) */ }),
78
+ nbt: nbtPath({
79
+ registry: 'storage', /* FIXME:, id: extract('storage', props) */
80
+ }),
77
81
  },
78
82
  }),
79
83
  interpret: opt(boolean, false),
@@ -89,7 +93,14 @@ const text_component_object = as('text_component', (node, ctx) => record({
89
93
  obfuscated: opt(boolean),
90
94
  insertion: opt(simpleString),
91
95
  clickEvent: opt(dispatch('action', (action) => record({
92
- action: literal(['open_url', 'open_file', 'run_command', 'suggest_command', 'change_page', 'copy_to_clipboard']),
96
+ action: literal([
97
+ 'open_url',
98
+ 'open_file',
99
+ 'run_command',
100
+ 'suggest_command',
101
+ 'change_page',
102
+ 'copy_to_clipboard',
103
+ ]),
93
104
  value: simpleString,
94
105
  ...pick(action, {
95
106
  run_command: {
@@ -108,11 +119,16 @@ const text_component_object = as('text_component', (node, ctx) => record({
108
119
  contents: opt(versioned(ctx, '1.16', text_component)),
109
120
  },
110
121
  show_item: {
111
- value: deprecated(ctx, '1.16', nbt({ definition: '::minecraft::util::invitem::InventoryItem' })),
112
- contents: opt(versioned(ctx, '1.16', dispatch(props => record({
122
+ value: deprecated(ctx, '1.16', nbt({
123
+ definition: '::minecraft::util::invitem::InventoryItem',
124
+ })),
125
+ contents: opt(versioned(ctx, '1.16', dispatch((props) => record({
113
126
  id: resource('item'),
114
127
  count: opt(int),
115
- tag: opt(nbt({ registry: 'item', id: extract('id', props) })),
128
+ tag: opt(nbt({
129
+ registry: 'item',
130
+ id: extract('id', props),
131
+ })),
116
132
  })))),
117
133
  },
118
134
  show_entity: {
@@ -1,5 +1,12 @@
1
- import type { Checker, MetaRegistry } from '@spyglassmc/core';
1
+ import * as core from '@spyglassmc/core';
2
2
  import type { JsonNode } from '@spyglassmc/json';
3
- export declare const entry: Checker<JsonNode>;
4
- export declare function register(meta: MetaRegistry): void;
3
+ import * as mcdoc from '@spyglassmc/mcdoc';
4
+ export declare const entry: core.Checker<JsonNode>;
5
+ export declare function register(meta: core.MetaRegistry): void;
6
+ /**
7
+ * @param identifier An identifier of mcdoc compound definition. e.g. `::minecraft::util::invitem::InventoryItem`
8
+ */
9
+ export declare function definition(identifier: `::${string}::${string}`): core.SyncChecker<JsonNode>;
10
+ export declare function object(typeDef: mcdoc.StructType): core.SyncChecker<JsonNode>;
11
+ export declare function fieldValue(type: mcdoc.McdocType): core.SyncChecker<JsonNode>;
5
12
  //# sourceMappingURL=index.d.ts.map
@@ -1,12 +1,62 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import { JsonObjectNode } from '@spyglassmc/json';
3
+ import { localeQuote, localize } from '@spyglassmc/locales';
4
+ import * as mcdoc from '@spyglassmc/mcdoc';
1
5
  import { dissectUri } from '../../binder/index.js';
2
- import { Checkers, pack_mcmeta } from './data/index.js';
6
+ const Checkers = new Map([
7
+ ['advancement', '::java::data::advancement::Advancement'],
8
+ ['dimension', '::java::data::worldgen::dimension::Dimension'],
9
+ ['dimension_type', '::java::data::worldgen::dimension::DimensionType'],
10
+ ['item_modifier', '::java::data::item_modifier::ItemModifier'],
11
+ ['loot_table', '::java::data::loot::LootTable'],
12
+ ['predicate', '::java::data::predicate::Predicate'],
13
+ ['recipe', '::java::data::recipe::Recipe'],
14
+ ['worldgen/biome', '::java::data::worldgen::biome::Biome'],
15
+ [
16
+ 'worldgen/configured_carver',
17
+ '::java::data::worldgen::carver::ConfiguredCarver',
18
+ ],
19
+ [
20
+ 'worldgen/configured_surface_builder',
21
+ '::java::data::worldgen::surface_builder::ConfiguredSurfaceBuilder',
22
+ ],
23
+ ['worldgen/configured_feature', '::java::data::feature::ConfiguredFeature'],
24
+ [
25
+ 'worldgen/configured_structure_feature',
26
+ '::java::data::worldgen::structure::Structure',
27
+ ],
28
+ [
29
+ 'worldgen/density_function',
30
+ '::java::data::worldgen::density_function::DensityFunction',
31
+ ],
32
+ [
33
+ 'worldgen/noise',
34
+ '::java::data::worldgen::dimension::biome_source::NoiseParameters',
35
+ ],
36
+ [
37
+ 'worldgen/noise_settings',
38
+ '::java::data::worldgen::noise_settings::NoiseGeneratorSettings',
39
+ ],
40
+ [
41
+ 'worldgen/processor_list',
42
+ '::java::data::worldgen::processor_list::ProcessorList',
43
+ ],
44
+ [
45
+ 'worldgen/template_pool',
46
+ '::java::data::worldgen::template_pool::TemplatePool',
47
+ ],
48
+ ]);
3
49
  export const entry = (node, ctx) => {
4
50
  const parts = dissectUri(ctx.doc.uri, ctx);
5
51
  if (parts && Checkers.has(parts.category)) {
6
- Checkers.get(parts.category)(node, { ...ctx, context: '' });
52
+ const identifier = Checkers.get(parts.category);
53
+ return definition(identifier)(node, ctx);
54
+ }
55
+ else if (parts?.category.startsWith('tag/')) {
56
+ // TODO
7
57
  }
8
58
  else if (ctx.doc.uri.endsWith('/pack.mcmeta')) {
9
- pack_mcmeta(node, { ...ctx, context: '' });
59
+ return definition('::java::Pack')(node, ctx);
10
60
  }
11
61
  else {
12
62
  return;
@@ -20,4 +70,182 @@ export function register(meta) {
20
70
  meta.registerChecker('json:object', entry);
21
71
  meta.registerChecker('json:string', entry);
22
72
  }
73
+ /**
74
+ * @param identifier An identifier of mcdoc compound definition. e.g. `::minecraft::util::invitem::InventoryItem`
75
+ */
76
+ export function definition(identifier) {
77
+ return (node, ctx) => {
78
+ const symbol = ctx.symbols.query(ctx.doc, 'mcdoc', identifier);
79
+ const typeDef = symbol.getData(mcdoc.binder.TypeDefSymbolData.is)?.typeDef;
80
+ if (!typeDef) {
81
+ return;
82
+ }
83
+ switch (typeDef.kind) {
84
+ case 'struct':
85
+ object(typeDef)(node, ctx);
86
+ break;
87
+ default:
88
+ ctx.logger.error(`[json.checker.definition] Expected a struct type, but got ${typeDef.kind}`);
89
+ }
90
+ };
91
+ }
92
+ export function object(typeDef) {
93
+ return (node, ctx) => {
94
+ if (!JsonObjectNode.is(node)) {
95
+ // TODO
96
+ return;
97
+ }
98
+ for (const { key: keyNode, value: valueNode } of node.children) {
99
+ if (!keyNode || !valueNode) {
100
+ continue;
101
+ }
102
+ const key = keyNode.value;
103
+ // TODO: handle spread types
104
+ const fieldDef = typeDef.fields.find((p) => p.kind === 'pair' && p.key === key);
105
+ if (fieldDef) {
106
+ // TODO: enter a reference to the mcdoc key
107
+ fieldValue(fieldDef.type)(valueNode, ctx);
108
+ }
109
+ else {
110
+ ctx.err.report(localize('unknown-key', localeQuote(key)), keyNode, 2 /* core.ErrorSeverity.Warning */);
111
+ }
112
+ }
113
+ // TODO: check for required fields
114
+ };
115
+ }
116
+ export function fieldValue(type) {
117
+ const isInRange = (value, { kind, min = -Infinity, max = Infinity }) => {
118
+ const comparator = (a, b, exclusive) => exclusive ? a < b : a <= b;
119
+ return (comparator(min, value, kind & 0b10) &&
120
+ comparator(value, max, kind & 0b01));
121
+ };
122
+ const ExpectedTypes = {
123
+ boolean: 'json:boolean',
124
+ byte: 'json:number',
125
+ byte_array: 'json:array',
126
+ double: 'json:number',
127
+ float: 'json:number',
128
+ int: 'json:number',
129
+ int_array: 'json:array',
130
+ list: 'json:array',
131
+ long: 'json:number',
132
+ long_array: 'json:array',
133
+ short: 'json:number',
134
+ string: 'json:string',
135
+ struct: 'json:object',
136
+ tuple: 'json:array',
137
+ };
138
+ return (node, ctx) => {
139
+ // Rough type check.
140
+ if (type.kind !== 'any' &&
141
+ type.kind !== 'dispatcher' &&
142
+ type.kind !== 'enum' &&
143
+ type.kind !== 'literal' &&
144
+ type.kind !== 'reference' &&
145
+ type.kind !== 'union' &&
146
+ type.kind !== 'attributed' &&
147
+ type.kind !== 'unsafe' &&
148
+ type.kind !== 'concrete' &&
149
+ type.kind !== 'indexed' &&
150
+ type.kind !== 'template' &&
151
+ node.type !== ExpectedTypes[type.kind]) {
152
+ ctx.err.report(localize('expected', localizeTag(ExpectedTypes[type.kind])), node, 2 /* core.ErrorSeverity.Warning */);
153
+ return;
154
+ }
155
+ switch (type.kind) {
156
+ case 'boolean':
157
+ break;
158
+ case 'byte_array':
159
+ case 'int_array':
160
+ case 'long_array':
161
+ node = node;
162
+ if (type.lengthRange &&
163
+ !isInRange(node.children.length, type.lengthRange)) {
164
+ ctx.err.report(localize('expected', localize('json.checker.array.length-between', localizeTag(node.type), type.lengthRange.min ?? '-∞', type.lengthRange.max ?? '+∞')), node, 2 /* core.ErrorSeverity.Warning */);
165
+ }
166
+ if (type.valueRange) {
167
+ for (const { value: childNode } of node.children) {
168
+ if (childNode?.type !== 'json:number') {
169
+ ctx.err.report(localize('expected', localizeTag('json:number')), node, 2 /* core.ErrorSeverity.Warning */);
170
+ }
171
+ else if (childNode &&
172
+ !isInRange(Number(childNode.value), type.valueRange)) {
173
+ ctx.err.report(localize('number.between', type.valueRange.min ?? '-∞', type.valueRange.max ?? '+∞'), node, 2 /* core.ErrorSeverity.Warning */);
174
+ }
175
+ }
176
+ }
177
+ break;
178
+ case 'byte':
179
+ case 'short':
180
+ case 'int':
181
+ case 'long':
182
+ case 'float':
183
+ case 'double':
184
+ node = node;
185
+ if (type.valueRange &&
186
+ !isInRange(Number(node.value), type.valueRange)) {
187
+ ctx.err.report(localize('number.between', type.valueRange.min ?? '-∞', type.valueRange.max ?? '+∞'), node, 2 /* core.ErrorSeverity.Warning */);
188
+ }
189
+ break;
190
+ case 'dispatcher':
191
+ node = node;
192
+ // const id = resolveFieldPath(node.parent?.parent, type.index.path)
193
+ // if (type.index.registry) {
194
+ // if (ExtendableRootRegistry.is(type.index.registry)) {
195
+ // index(type.index.registry, id ? core.ResourceLocation.lengthen(id) : undefined, options)(node, ctx)
196
+ // } else if (id) {
197
+ // index(type.index.registry, core.ResourceLocation.lengthen(id), options)(node, ctx)
198
+ // }
199
+ // }
200
+ break;
201
+ case 'list':
202
+ node = node;
203
+ type = mcdoc.simplifyListType(type);
204
+ if (type.lengthRange &&
205
+ !isInRange(node.children.length, type.lengthRange)) {
206
+ ctx.err.report(localize('expected', localize('json.checker.collection.length-between', localizeTag(node.type), type.lengthRange.min ?? '-∞', type.lengthRange.max ?? '+∞')), node, 2 /* core.ErrorSeverity.Warning */);
207
+ }
208
+ for (const { value: childNode } of node.children) {
209
+ if (childNode) {
210
+ fieldValue(type.item)(childNode, ctx);
211
+ }
212
+ }
213
+ break;
214
+ case 'struct':
215
+ node = node;
216
+ object(type)(node, ctx);
217
+ break;
218
+ case 'string':
219
+ break;
220
+ case 'reference':
221
+ // node = node as JsonObjectNode
222
+ // if (type.symbol) {
223
+ // const { allowUnknownKey, value } = resolveSymbolPaths([type.symbol], ctx, node)
224
+ // compound(value, { ...options, allowUnknownKey: options.allowUnknownKey || allowUnknownKey })(node, ctx)
225
+ // }
226
+ break;
227
+ case 'union':
228
+ type = mcdoc.flattenUnionType(type);
229
+ if (type.members.length === 0) {
230
+ ctx.err.report(localize('json.checker.object.field.union-empty-members'), core.PairNode.is(node.parent)
231
+ ? node.parent.key ?? node.parent
232
+ : node, 2 /* core.ErrorSeverity.Warning */);
233
+ }
234
+ else {
235
+ ;
236
+ core.checker.any(type.members.map((t) => fieldValue(t)))(node, ctx);
237
+ }
238
+ break;
239
+ case 'attributed':
240
+ // TODO: don't just ignore the attribute
241
+ fieldValue(type.child)(node, ctx);
242
+ break;
243
+ }
244
+ };
245
+ }
246
+ function localizeTag(type) {
247
+ const key = `json.node.${type.replace(/^json:/, '')}`;
248
+ const res = localize(key);
249
+ return res;
250
+ }
23
251
  //# sourceMappingURL=index.js.map
@@ -7,9 +7,10 @@ export function criterionReference(advancement) {
7
7
  return;
8
8
  }
9
9
  const criteria = Object.values(ctx.symbols.query(ctx.doc, 'advancement', advancement).symbol
10
- ?.members ?? {})
10
+ ?.members ??
11
+ {})
11
12
  .filter((m) => m?.subcategory === 'criterion')
12
- .map(s => s.identifier);
13
+ .map((s) => s.identifier);
13
14
  literal(criteria)(node, ctx);
14
15
  };
15
16
  }
@@ -7,7 +7,7 @@ interface Options {
7
7
  mixedTypes?: boolean;
8
8
  requireAll?: boolean;
9
9
  }
10
- export declare function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }: Options): JsonChecker;
11
- export declare function blockStateList({ category, id, ids, tag }: Options): JsonChecker;
10
+ export declare function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll, }: Options): JsonChecker;
11
+ export declare function blockStateList({ category, id, ids, tag, }: Options): JsonChecker;
12
12
  export {};
13
13
  //# sourceMappingURL=block_states.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import * as core from '@spyglassmc/core';
2
- import { any, boolean, intRange, listOf, literal, object, opt, record, simpleString } from '@spyglassmc/json/lib/checker/index.js';
2
+ import { any, boolean, intRange, listOf, literal, object, opt, record, simpleString, } from '@spyglassmc/json/lib/checker/index.js';
3
3
  import { getTagValues } from '../../../common/index.js';
4
- export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }) {
4
+ export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll, }) {
5
5
  return (node, ctx) => {
6
6
  if (tag) {
7
7
  ids = getTagValues(`tag/${category ?? 'block'}`, tag, ctx);
@@ -11,8 +11,10 @@ export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }
11
11
  }
12
12
  // FIXME: Temporary solution to make tests pass when ensureBindingStarted is not given.
13
13
  if (!ids?.length || !ctx.ensureBindingStarted) {
14
- const values = mixedTypes ? any([boolean, simpleString, intBounds()]) : simpleString;
15
- object(simpleString, () => requireAll ? values : opt(values))(node, ctx);
14
+ const values = mixedTypes
15
+ ? any([boolean, simpleString, intBounds()])
16
+ : simpleString;
17
+ object(simpleString, () => (requireAll ? values : opt(values)))(node, ctx);
16
18
  return;
17
19
  }
18
20
  const states = core.getStates(category ?? 'block', ids, ctx);
@@ -32,7 +34,7 @@ export function blockStateMap({ category, id, ids, tag, mixedTypes, requireAll }
32
34
  })(node, ctx);
33
35
  };
34
36
  }
35
- export function blockStateList({ category, id, ids, tag }) {
37
+ export function blockStateList({ category, id, ids, tag, }) {
36
38
  return (node, ctx) => {
37
39
  if (tag) {
38
40
  ids = getTagValues(`tag/${category ?? 'block'}`, tag, ctx);
@@ -1,4 +1,4 @@
1
- import { Color, ColorFormat, Failure, parseStringValue, Range } from '@spyglassmc/core';
1
+ import { Color, ColorFormat, Failure, parseStringValue, Range, } from '@spyglassmc/core';
2
2
  import { JsonNumberNode, JsonStringNode } from '@spyglassmc/json';
3
3
  import { localize } from '@spyglassmc/locales';
4
4
  export function stringColor() {
@@ -27,7 +27,13 @@ export function stringColor() {
27
27
  return Color.fromCompositeInt(value);
28
28
  };
29
29
  return (node, ctx) => {
30
- node.expectation = [{ type: 'json:string', typedoc: 'String("Color")', pool: Color.ColorNames }];
30
+ node.expectation = [
31
+ {
32
+ type: 'json:string',
33
+ typedoc: 'String("Color")',
34
+ pool: Color.ColorNames,
35
+ },
36
+ ];
31
37
  if (!JsonStringNode.is(node)) {
32
38
  ctx.err.report(localize('expected', localize('string')), node);
33
39
  }
@@ -9,7 +9,7 @@ interface RegistryOptions {
9
9
  ids?: readonly string[] | undefined;
10
10
  tag?: string | undefined;
11
11
  }
12
- declare type Options = DefinitionOptions | RegistryOptions;
12
+ type Options = DefinitionOptions | RegistryOptions;
13
13
  export declare function nbt(options: Options): JsonChecker;
14
14
  export declare function nbtPath(options: RegistryOptions): JsonChecker;
15
15
  export {};
@@ -53,9 +53,11 @@ export function nbtPath(options) {
53
53
  }
54
54
  function getIds({ registry, id, idOrTag, ids, tag }, ctx) {
55
55
  if (idOrTag) {
56
- idOrTag.startsWith('#') ? tag = idOrTag.slice(1) : id = idOrTag;
56
+ idOrTag.startsWith('#') ? (tag = idOrTag.slice(1)) : (id = idOrTag);
57
57
  }
58
- if (tag && (registry === 'block' || registry === 'item' || registry === 'entity_type')) {
58
+ if (tag &&
59
+ (registry === 'block' || registry === 'item' ||
60
+ registry === 'entity_type')) {
59
61
  ids = getTagValues(`tag/${registry}`, tag, ctx);
60
62
  }
61
63
  else if (id) {
@@ -2,11 +2,12 @@ import { symbol } from '@spyglassmc/core';
2
2
  import { string } from '@spyglassmc/json/lib/checker/index.js';
3
3
  export const recipeGroup = string('recipe_group', symbol('recipe_group'));
4
4
  export function patternKeys(props) {
5
- return [...new Set((props
6
- .find(p => p.key?.value === 'pattern' && p.value?.type === 'json:array')?.value?.children ?? [])
7
- .map(n => n.value)
8
- .filter(n => n && n.type === 'json:string')
9
- .flatMap(n => [...n.value])
10
- .filter(v => v !== ' '))];
5
+ return [
6
+ ...new Set((props.find((p) => p.key?.value === 'pattern' && p.value?.type === 'json:array')?.value?.children ?? [])
7
+ .map((n) => n.value)
8
+ .filter((n) => n && n.type === 'json:string')
9
+ .flatMap((n) => [...n.value])
10
+ .filter((v) => v !== ' ')),
11
+ ];
11
12
  }
12
13
  //# sourceMappingURL=recipe.js.map
@@ -1,6 +1,6 @@
1
1
  import type { JsonChecker, JsonCheckerContext, record } from '@spyglassmc/json/lib/checker/index.js';
2
2
  import { ReleaseVersion } from '../../../dependency/index.js';
3
- declare type CheckerRecord = Parameters<typeof record>[0];
3
+ type CheckerRecord = Parameters<typeof record>[0];
4
4
  export declare function versioned(ctx: JsonCheckerContext, version: ReleaseVersion, checker: string[]): string[];
5
5
  export declare function versioned(ctx: JsonCheckerContext, version: ReleaseVersion, checker: JsonChecker | undefined): JsonChecker | undefined;
6
6
  export declare function versioned(ctx: JsonCheckerContext, version: ReleaseVersion, checker: CheckerRecord | undefined): CheckerRecord | undefined;
@@ -25,10 +25,10 @@ export function versioned(ctx, arg1, arg2, arg3) {
25
25
  return arg1;
26
26
  }
27
27
  else if (Array.isArray(arg1)) {
28
- return check ? arg1 : (arg3 ?? []);
28
+ return check ? arg1 : arg3 ?? [];
29
29
  }
30
30
  else {
31
- return check ? arg1 : (arg3 ?? undefined);
31
+ return check ? arg1 : arg3 ?? undefined;
32
32
  }
33
33
  }
34
34
  }
@@ -19,7 +19,7 @@ const getNode = (nodes, index) => {
19
19
  return nodes[index]?.children[0];
20
20
  };
21
21
  const rootCommand = (nodes, index, ctx) => {
22
- for (const { children: [node] } of nodes) {
22
+ for (const { children: [node], } of nodes) {
23
23
  if (BlockNode.is(node)) {
24
24
  block(node, ctx);
25
25
  }
@@ -108,7 +108,8 @@ const rootCommand = (nodes, index, ctx) => {
108
108
  }
109
109
  else if (getName(nodes, index) === 'execute') {
110
110
  for (let i = index + 1; i < nodes.length; i++) {
111
- if ((getName(nodes, i) === 'if' || getName(nodes, i) === 'unless') && getName(nodes, i + 1) === 'data') {
111
+ if ((getName(nodes, i) === 'if' || getName(nodes, i) === 'unless') &&
112
+ getName(nodes, i + 1) === 'data') {
112
113
  // `if|unless data <$nbtPath$>`
113
114
  nbtPath(nodes, i + 2, ctx);
114
115
  i += 2;
@@ -123,7 +124,7 @@ const rootCommand = (nodes, index, ctx) => {
123
124
  summonNbt(nodes, index + 1, ctx);
124
125
  }
125
126
  };
126
- //#region Checkers for argument nodes
127
+ // #region Checkers for argument nodes
127
128
  const block = (node, ctx) => {
128
129
  if (!node.nbt) {
129
130
  return;
@@ -131,7 +132,7 @@ const block = (node, ctx) => {
131
132
  nbt.checker.index('block', core.ResourceLocationNode.toString(node.id, 'full'))(node.nbt, ctx);
132
133
  };
133
134
  const entity = (node, ctx) => {
134
- const nbtPair = node.selector?.arguments?.children.find(pair => pair.key?.value === 'nbt');
135
+ const nbtPair = node.selector?.arguments?.children.find((pair) => pair.key?.value === 'nbt');
135
136
  if (!nbtPair) {
136
137
  return;
137
138
  }
@@ -148,8 +149,8 @@ const item = (node, ctx) => {
148
149
  const particle = (node, ctx) => {
149
150
  core.checker.dispatchSync(node, ctx);
150
151
  };
151
- //#endregion
152
- //#region Checkers for command argument structure.
152
+ // #endregion
153
+ // #region Checkers for command argument structure.
153
154
  /**
154
155
  * - `block <targetPos: block_pos> <nbt: nbt_compound_tag>`
155
156
  * - `entity <target: entity> <nbt: nbt_compound_tag>`
@@ -177,7 +178,8 @@ const dataMergeTarget = (nodes, index, ctx) => {
177
178
  case 'storage': {
178
179
  const idNode = getNode(nodes, index + 1);
179
180
  const nbtNode = getNode(nodes, index + 2);
180
- if (core.ResourceLocationNode.is(idNode) && nbt.NbtCompoundNode.is(nbtNode)) {
181
+ if (core.ResourceLocationNode.is(idNode) &&
182
+ nbt.NbtCompoundNode.is(nbtNode)) {
181
183
  nbt.checker.index('storage', core.ResourceLocationNode.toString(idNode, 'full'))(nbtNode, ctx);
182
184
  }
183
185
  break;
@@ -224,11 +226,12 @@ const nbtPath = (nodes, index, ctx) => {
224
226
  const summonNbt = (nodes, index, ctx) => {
225
227
  const typeNode = getNode(nodes, index);
226
228
  const nbtNode = getNode(nodes, index + 2);
227
- if (core.ResourceLocationNode.is(typeNode) && nbt.NbtCompoundNode.is(nbtNode)) {
229
+ if (core.ResourceLocationNode.is(typeNode) &&
230
+ nbt.NbtCompoundNode.is(nbtNode)) {
228
231
  nbt.checker.index('entity_type', core.ResourceLocationNode.toString(typeNode, 'full'))(nbtNode, ctx);
229
232
  }
230
233
  };
231
- //#endregion
234
+ // #endregion
232
235
  export const getTypesFromEntity = (entity, ctx) => {
233
236
  if (entity.playerName !== undefined || entity.selector?.playersOnly) {
234
237
  return ['minecraft:player'];
@@ -247,10 +250,10 @@ export const getTypesFromEntity = (entity, ctx) => {
247
250
  if (!valueNode || valueNode.inverted) {
248
251
  continue;
249
252
  }
250
- const value = core.ResourceLocationNode.toString(valueNode.value, 'full');
253
+ const value = core.ResourceLocationNode.toString(valueNode.value, 'full', true);
251
254
  if (value.startsWith(core.ResourceLocation.TagPrefix)) {
252
255
  const tagValues = getTagValues('tag/entity_type', value.slice(1), ctx);
253
- types = types.filter(t => tagValues.includes(t));
256
+ types = types.filter((t) => tagValues.includes(t));
254
257
  }
255
258
  else {
256
259
  types = [value];
@@ -1,8 +1,6 @@
1
1
  import * as core from '@spyglassmc/core';
2
- export const objectiveCriterion = node => [
3
- core.ColorToken.create(node, 'type'),
4
- ];
5
- export const vector = node => {
2
+ export const objectiveCriterion = (node) => [core.ColorToken.create(node, 'type')];
3
+ export const vector = (node) => {
6
4
  return [core.ColorToken.create(node, 'vector')];
7
5
  };
8
6
  export function register(meta) {
@@ -2,24 +2,55 @@ import * as core from '@spyglassmc/core';
2
2
  export const ColorArgumentValues = [...core.Color.ColorNames, 'reset'];
3
3
  export const EntityAnchorArgumentValues = ['feet', 'eyes'];
4
4
  export const ItemSlotArgumentValues = [
5
- ...[...Array(54).keys()].map(n => `container.${n}`),
6
- ...[...Array(27).keys()].map(n => `enderchest.${n}`),
7
- ...[...Array(15).keys()].map(n => `horse.${n}`),
8
- ...[...Array(9).keys()].map(n => `hotbar.${n}`),
9
- ...[...Array(27).keys()].map(n => `inventory.${n}`),
10
- ...[...Array(8).keys()].map(n => `villager.${n}`),
11
- 'armor.chest', 'armor.feet', 'armor.head', 'armor.legs',
12
- 'horse.armor', 'horse.chest', 'horse.saddle',
13
- 'weapon', 'weapon.mainhand', 'weapon.offhand',
5
+ ...[...Array(54).keys()].map((n) => `container.${n}`),
6
+ ...[...Array(27).keys()].map((n) => `enderchest.${n}`),
7
+ ...[...Array(15).keys()].map((n) => `horse.${n}`),
8
+ ...[...Array(9).keys()].map((n) => `hotbar.${n}`),
9
+ ...[...Array(27).keys()].map((n) => `inventory.${n}`),
10
+ ...[...Array(8).keys()].map((n) => `villager.${n}`),
11
+ 'armor.chest',
12
+ 'armor.feet',
13
+ 'armor.head',
14
+ 'armor.legs',
15
+ 'horse.armor',
16
+ 'horse.chest',
17
+ 'horse.saddle',
18
+ 'weapon',
19
+ 'weapon.mainhand',
20
+ 'weapon.offhand',
21
+ ];
22
+ export const OperationArgumentValues = [
23
+ '=',
24
+ '+=',
25
+ '-=',
26
+ '*=',
27
+ '/=',
28
+ '%=',
29
+ '<',
30
+ '>',
31
+ '><',
14
32
  ];
15
- export const OperationArgumentValues = ['=', '+=', '-=', '*=', '/=', '%=', '<', '>', '><'];
16
33
  export const ScoreboardSlotArgumentValues = [
17
- 'belowName', 'list', 'sidebar',
18
- ...core.Color.ColorNames.map(n => `sidebar.team.${n}`),
34
+ 'belowName',
35
+ 'list',
36
+ 'sidebar',
37
+ ...core.Color.ColorNames.map((n) => `sidebar.team.${n}`),
19
38
  ];
20
39
  export const SwizzleArgumentValues = [
21
- 'x', 'xy', 'xz', 'xyz', 'xzy',
22
- 'y', 'yx', 'yz', 'yxz', 'yzx',
23
- 'z', 'zx', 'zy', 'zxy', 'zyx',
40
+ 'x',
41
+ 'xy',
42
+ 'xz',
43
+ 'xyz',
44
+ 'xzy',
45
+ 'y',
46
+ 'yx',
47
+ 'yz',
48
+ 'yxz',
49
+ 'yzx',
50
+ 'z',
51
+ 'zx',
52
+ 'zy',
53
+ 'zxy',
54
+ 'zyx',
24
55
  ];
25
56
  //# sourceMappingURL=index.js.map