@spyglassmc/java-edition 0.3.26 → 0.3.28

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.
@@ -1,11 +1,23 @@
1
- import type { CheckerContext, Config, RootUriString, UriBinder, UriBinderContext } from '@spyglassmc/core';
1
+ import type { CheckerContext, Config, FileCategory, MetaRegistry, RootUriString, UriBinder, UriBinderContext } from '@spyglassmc/core';
2
+ import { ReleaseVersion } from '../dependency/index.js';
3
+ interface Resource {
4
+ path: string;
5
+ category: FileCategory;
6
+ ext: `.${string}`;
7
+ pack: 'data' | 'assets';
8
+ identifier?: string;
9
+ since?: ReleaseVersion;
10
+ until?: ReleaseVersion;
11
+ }
12
+ export declare function getResources(): Generator<Resource, undefined, undefined>;
2
13
  export declare function getRels(uri: string, rootUris: readonly RootUriString[]): Generator<string, undefined, unknown>;
14
+ export declare function getRoots(uri: string, rootUris: readonly RootUriString[]): Generator<RootUriString, undefined, unknown>;
3
15
  export declare function dissectUri(uri: string, ctx: UriBinderContext): {
4
16
  namespace: string;
5
17
  identifier: string;
6
18
  expected: string | undefined;
7
19
  path: string;
8
- category: "function" | "advancement" | "banner_pattern" | "chat_type" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "predicate" | "recipe" | "structure" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_variant" | "tag/function" | "tag/activity" | "tag/armor_material" | "tag/attribute" | "tag/block" | "tag/block_entity_type" | "tag/block_predicate_type" | "tag/block_type" | "tag/cat_variant" | "tag/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_type" | "tag/decorated_pot_pattern" | "tag/decorated_pot_patterns" | "tag/enchantment_effect_component_type" | "tag/enchantment_entity_effect_type" | "tag/enchantment_level_based_value_type" | "tag/enchantment_location_based_effect_type" | "tag/enchantment_provider_type" | "tag/enchantment_value_effect_type" | "tag/entity_sub_predicate_type" | "tag/entity_type" | "tag/float_provider_type" | "tag/fluid" | "tag/frog_variant" | "tag/game_event" | "tag/height_provider_type" | "tag/instrument" | "tag/int_provider_type" | "tag/item" | "tag/item_sub_predicate_type" | "tag/loot_condition_type" | "tag/loot_function_type" | "tag/loot_nbt_provider_type" | "tag/loot_number_provider_type" | "tag/loot_pool_entry_type" | "tag/loot_score_provider_type" | "tag/map_decoration_type" | "tag/memory_module_type" | "tag/menu" | "tag/mob_effect" | "tag/motive" | "tag/number_format_type" | "tag/particle_type" | "tag/point_of_interest_type" | "tag/pos_rule_test" | "tag/position_source_type" | "tag/potion" | "tag/recipe_book_category" | "tag/recipe_display" | "tag/recipe_serializer" | "tag/recipe_type" | "tag/rule_block_entity_modifier" | "tag/rule_test" | "tag/schedule" | "tag/sensor_type" | "tag/slot_display" | "tag/sound_event" | "tag/stat_type" | "tag/trigger_type" | "tag/villager_profession" | "tag/villager_type" | "tag/worldgen/biome_source" | "tag/worldgen/block_placer_type" | "tag/worldgen/block_state_provider_type" | "tag/worldgen/carver" | "tag/worldgen/chunk_generator" | "tag/worldgen/decorator" | "tag/worldgen/density_function_type" | "tag/worldgen/feature" | "tag/worldgen/feature_size_type" | "tag/worldgen/foliage_placer_type" | "tag/worldgen/material_condition" | "tag/worldgen/material_rule" | "tag/worldgen/placement_modifier_type" | "tag/worldgen/pool_alias_binding" | "tag/worldgen/root_placer_type" | "tag/worldgen/structure_feature" | "tag/worldgen/structure_piece" | "tag/worldgen/structure_placement" | "tag/worldgen/structure_pool_element" | "tag/worldgen/structure_processor" | "tag/worldgen/structure_type" | "tag/worldgen/surface_builder" | "tag/worldgen/tree_decorator_type" | "tag/worldgen/trunk_placer_type" | "tag/advancement" | "tag/banner_pattern" | "tag/chat_type" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_variant" | "tag/worldgen/biome" | "tag/worldgen/configured_carver" | "tag/worldgen/configured_feature" | "tag/worldgen/configured_structure_feature" | "tag/worldgen/configured_surface_builder" | "tag/worldgen/density_function" | "tag/worldgen/flat_level_generator_preset" | "tag/worldgen/multi_noise_biome_source_parameter_list" | "tag/worldgen/noise" | "tag/worldgen/noise_settings" | "tag/worldgen/placed_feature" | "tag/worldgen/processor_list" | "tag/worldgen/structure" | "tag/worldgen/structure_set" | "tag/worldgen/template_pool" | "tag/worldgen/world_preset" | "worldgen/biome" | "worldgen/configured_carver" | "worldgen/configured_feature" | "worldgen/configured_structure_feature" | "worldgen/configured_surface_builder" | "worldgen/density_function" | "worldgen/flat_level_generator_preset" | "worldgen/multi_noise_biome_source_parameter_list" | "worldgen/noise" | "worldgen/noise_settings" | "worldgen/placed_feature" | "worldgen/processor_list" | "worldgen/structure" | "worldgen/structure_set" | "worldgen/template_pool" | "worldgen/world_preset" | "atlas" | "block_definition" | "equipment" | "font" | "font/ttf" | "font/otf" | "font/unihex" | "gpu_warnlist" | "item_definition" | "lang" | "lang/deprecated" | "model" | "particle" | "post_effect" | "regional_compliancies" | "shader" | "shader/fragment" | "shader/vertex" | "sound" | "sounds" | "texture" | "texture_meta";
20
+ category: "function" | "advancement" | "banner_pattern" | "chat_type" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "pig_variant" | "predicate" | "recipe" | "structure" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_variant" | "tag/function" | "tag/activity" | "tag/armor_material" | "tag/attribute" | "tag/block" | "tag/block_entity_type" | "tag/block_predicate_type" | "tag/block_type" | "tag/cat_variant" | "tag/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_type" | "tag/decorated_pot_pattern" | "tag/decorated_pot_patterns" | "tag/enchantment_effect_component_type" | "tag/enchantment_entity_effect_type" | "tag/enchantment_level_based_value_type" | "tag/enchantment_location_based_effect_type" | "tag/enchantment_provider_type" | "tag/enchantment_value_effect_type" | "tag/entity_sub_predicate_type" | "tag/entity_type" | "tag/float_provider_type" | "tag/fluid" | "tag/frog_variant" | "tag/game_event" | "tag/height_provider_type" | "tag/instrument" | "tag/int_provider_type" | "tag/item" | "tag/item_sub_predicate_type" | "tag/loot_condition_type" | "tag/loot_function_type" | "tag/loot_nbt_provider_type" | "tag/loot_number_provider_type" | "tag/loot_pool_entry_type" | "tag/loot_score_provider_type" | "tag/map_decoration_type" | "tag/memory_module_type" | "tag/menu" | "tag/mob_effect" | "tag/motive" | "tag/number_format_type" | "tag/particle_type" | "tag/point_of_interest_type" | "tag/pos_rule_test" | "tag/position_source_type" | "tag/potion" | "tag/recipe_book_category" | "tag/recipe_display" | "tag/recipe_serializer" | "tag/recipe_type" | "tag/rule_block_entity_modifier" | "tag/rule_test" | "tag/schedule" | "tag/sensor_type" | "tag/slot_display" | "tag/sound_event" | "tag/stat_type" | "tag/trigger_type" | "tag/villager_profession" | "tag/villager_type" | "tag/worldgen/biome_source" | "tag/worldgen/block_placer_type" | "tag/worldgen/block_state_provider_type" | "tag/worldgen/carver" | "tag/worldgen/chunk_generator" | "tag/worldgen/decorator" | "tag/worldgen/density_function_type" | "tag/worldgen/feature" | "tag/worldgen/feature_size_type" | "tag/worldgen/foliage_placer_type" | "tag/worldgen/material_condition" | "tag/worldgen/material_rule" | "tag/worldgen/placement_modifier_type" | "tag/worldgen/pool_alias_binding" | "tag/worldgen/root_placer_type" | "tag/worldgen/structure_feature" | "tag/worldgen/structure_piece" | "tag/worldgen/structure_placement" | "tag/worldgen/structure_pool_element" | "tag/worldgen/structure_processor" | "tag/worldgen/structure_type" | "tag/worldgen/surface_builder" | "tag/worldgen/tree_decorator_type" | "tag/worldgen/trunk_placer_type" | "tag/advancement" | "tag/banner_pattern" | "tag/chat_type" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/pig_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_variant" | "tag/worldgen/biome" | "tag/worldgen/configured_carver" | "tag/worldgen/configured_feature" | "tag/worldgen/configured_structure_feature" | "tag/worldgen/configured_surface_builder" | "tag/worldgen/density_function" | "tag/worldgen/flat_level_generator_preset" | "tag/worldgen/multi_noise_biome_source_parameter_list" | "tag/worldgen/noise" | "tag/worldgen/noise_settings" | "tag/worldgen/placed_feature" | "tag/worldgen/processor_list" | "tag/worldgen/structure" | "tag/worldgen/structure_set" | "tag/worldgen/template_pool" | "tag/worldgen/world_preset" | "worldgen/biome" | "worldgen/configured_carver" | "worldgen/configured_feature" | "worldgen/configured_structure_feature" | "worldgen/configured_surface_builder" | "worldgen/density_function" | "worldgen/flat_level_generator_preset" | "worldgen/multi_noise_biome_source_parameter_list" | "worldgen/noise" | "worldgen/noise_settings" | "worldgen/placed_feature" | "worldgen/processor_list" | "worldgen/structure" | "worldgen/structure_set" | "worldgen/template_pool" | "worldgen/world_preset" | "atlas" | "block_definition" | "equipment" | "font" | "font/ttf" | "font/otf" | "font/unihex" | "gpu_warnlist" | "item_definition" | "lang" | "lang/deprecated" | "model" | "particle" | "post_effect" | "regional_compliancies" | "shader" | "shader/fragment" | "shader/vertex" | "sound" | "sounds" | "texture" | "texture_meta";
9
21
  ext: `.${string}`;
10
22
  pack: "assets" | "data";
11
23
  since?: `1.${number}` | undefined;
@@ -15,4 +27,6 @@ export declare function dissectUri(uri: string, ctx: UriBinderContext): {
15
27
  export declare const uriBinder: UriBinder;
16
28
  export declare function registerCustomResources(config: Config): void;
17
29
  export declare function reportDissectError(realPath: string, expectedPath: string | undefined, ctx: CheckerContext): void;
30
+ export declare function registerUriBuilders(meta: MetaRegistry): void;
31
+ export {};
18
32
  //# sourceMappingURL=index.d.ts.map
@@ -52,6 +52,7 @@ resource('enchantment_provider', { since: '1.21' });
52
52
  resource('instrument', { since: '1.21.2' });
53
53
  resource('jukebox_song', { since: '1.21' });
54
54
  resource('painting_variant', { since: '1.21' });
55
+ resource('pig_variant', { since: '1.21.5' });
55
56
  resource('trial_spawner', { since: '1.21.2' });
56
57
  resource('trim_pattern', { since: '1.19.4' });
57
58
  resource('trim_material', { since: '1.19.4' });
@@ -127,6 +128,12 @@ resource('', {
127
128
  identifier: 'regional_compliancies',
128
129
  });
129
130
  resource('', { pack: 'assets', category: 'gpu_warnlist', identifier: 'gpu_warnlist' });
131
+ export function* getResources() {
132
+ for (const resources of Resources.values()) {
133
+ yield* resources;
134
+ }
135
+ return undefined;
136
+ }
130
137
  export function* getRels(uri, rootUris) {
131
138
  yield* fileUtil.getRels(uri, rootUris);
132
139
  const parts = uri.split('/');
@@ -137,6 +144,16 @@ export function* getRels(uri, rootUris) {
137
144
  }
138
145
  return undefined;
139
146
  }
147
+ export function* getRoots(uri, rootUris) {
148
+ yield* fileUtil.getRoots(uri, rootUris);
149
+ const parts = uri.split('/');
150
+ for (let i = parts.length - 2; i >= 0; i--) {
151
+ if (parts[i] === 'data' || parts[i] === 'assets') {
152
+ yield `${parts.slice(0, i).join('/')}/`;
153
+ }
154
+ }
155
+ return undefined;
156
+ }
140
157
  export function dissectUri(uri, ctx) {
141
158
  const rels = getRels(uri, ctx.roots);
142
159
  const release = ctx.project['loadedVersion'];
@@ -249,4 +266,36 @@ export function reportDissectError(realPath, expectedPath, ctx) {
249
266
  ctx.err.report(localize('java-edition.binder.wrong-version', localeQuote(realPath), release), Range.Beginning, 0 /* ErrorSeverity.Hint */);
250
267
  }
251
268
  }
269
+ function uriBuilder(resources) {
270
+ return (identifier, ctx) => {
271
+ const root = getRoots(ctx.doc.uri, ctx.roots).next().value;
272
+ if (!root) {
273
+ return undefined;
274
+ }
275
+ const release = ctx.project['loadedVersion'];
276
+ if (!release) {
277
+ return undefined;
278
+ }
279
+ const resource = resources.find(r => matchVersion(release, r.since, r.until));
280
+ if (!resource) {
281
+ return undefined;
282
+ }
283
+ const sepIndex = identifier.indexOf(':');
284
+ const namespace = sepIndex > 0 ? identifier.slice(0, sepIndex) : 'minecraft';
285
+ const path = identifier.slice(sepIndex + 1);
286
+ return `${root}${resource.pack}/${namespace}/${resource.path}/${path}${resource.ext}`;
287
+ };
288
+ }
289
+ export function registerUriBuilders(meta) {
290
+ const resourcesByCategory = new Map();
291
+ for (const resource of getResources()) {
292
+ resourcesByCategory.set(resource.category, [
293
+ ...resourcesByCategory.get(resource.category) ?? [],
294
+ resource,
295
+ ]);
296
+ }
297
+ for (const [category, resources] of resourcesByCategory.entries()) {
298
+ meta.registerUriBuilder(category, uriBuilder(resources));
299
+ }
300
+ }
252
301
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import type { PackMcmeta, VersionInfo } from './common.js';
3
3
  import { ReleaseVersion } from './common.js';
4
- export declare const NEXT_RELEASE_VERSION = "1.21.4";
4
+ export declare const NEXT_RELEASE_VERSION = "1.21.5";
5
5
  /**
6
6
  * @param inputVersion {@link core.Config.env.gameVersion}
7
7
  */
@@ -1,7 +1,7 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import { ReleaseVersion } from './common.js';
3
3
  // DOCS: Update this when a new snapshot cycle begins
4
- export const NEXT_RELEASE_VERSION = '1.21.4';
4
+ export const NEXT_RELEASE_VERSION = '1.21.5';
5
5
  /**
6
6
  * @param inputVersion {@link core.Config.env.gameVersion}
7
7
  */
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@ import * as core from '@spyglassmc/core';
2
2
  import * as json from '@spyglassmc/json';
3
3
  import * as mcdoc from '@spyglassmc/mcdoc';
4
4
  import * as nbt from '@spyglassmc/nbt';
5
- import { uriBinder } from './binder/index.js';
5
+ import { registerUriBuilders, uriBinder } from './binder/index.js';
6
6
  import { getMcmetaSummary, getVanillaDatapack, getVanillaMcdoc, getVanillaResourcepack, getVersions, PackMcmeta, resolveConfiguredVersion, symbolRegistrar, } from './dependency/index.js';
7
7
  import * as jeJson from './json/index.js';
8
8
  import { registerMcdocAttributes, registerPackFormatAttribute } from './mcdocAttributes.js';
@@ -52,6 +52,7 @@ export const initialize = async (ctx) => {
52
52
  return packs;
53
53
  }
54
54
  meta.registerUriBinder(uriBinder);
55
+ registerUriBuilders(meta);
55
56
  const versions = await getVersions(ctx.externals, ctx.downloader);
56
57
  if (!versions) {
57
58
  ctx.logger.error('[je-initialize] Failed loading game version list. Expect everything to be broken.');
@@ -51,6 +51,9 @@ const rootCommand = (nodes, index, ctx) => {
51
51
  else if (json.TypedJsonNode.is(node)) {
52
52
  json.checker.typed(node, ctx);
53
53
  }
54
+ else if (nbt.TypedNbtNode.is(node)) {
55
+ nbt.checker.typed(node, ctx);
56
+ }
54
57
  else if (NbtNode.is(node) && node.properties) {
55
58
  const dispatchedBy = getEarlierNode(nodes, i, node.properties.dispatchedBy);
56
59
  const indexedBy = getEarlierNode(nodes, i, node.properties.indexedBy);
@@ -150,10 +150,10 @@ const block = (node, ctx) => {
150
150
  if (Range.contains(node.id, ctx.offset, true)) {
151
151
  ans.push(...completer.resourceLocation(node.id, ctx));
152
152
  }
153
- if (node.states && Range.contains(Range.translate(node.states, 1, -1), ctx.offset, true)) {
153
+ if (node.states?.innerRange && Range.contains(node.states.innerRange, ctx.offset, true)) {
154
154
  ans.push(...blockStates(node.states, ctx));
155
155
  }
156
- if (node.nbt && Range.contains(Range.translate(node.nbt, 1, -1), ctx.offset, true)) {
156
+ if (node.nbt?.innerRange && Range.contains(node.nbt.innerRange, ctx.offset, true)) {
157
157
  ans.push(...completer.dispatch(node.nbt, ctx));
158
158
  }
159
159
  return ans;
@@ -183,7 +183,7 @@ const blockStates = (node, ctx) => {
183
183
  })(node, ctx);
184
184
  };
185
185
  const componentList = (node, ctx) => {
186
- if (!Range.contains(Range.translate(node, 1, -1), ctx.offset, true)) {
186
+ if (!node.innerRange || !Range.contains(node.innerRange, ctx.offset, true)) {
187
187
  return [];
188
188
  }
189
189
  const completeKey = (key) => {
@@ -326,7 +326,7 @@ const selector = (node, ctx) => {
326
326
  if (Range.contains(node.children[0], ctx.offset, true)) {
327
327
  return completer.literal(node.children[0], ctx);
328
328
  }
329
- if (node.arguments && Range.contains(Range.translate(node.arguments, 1, -1), ctx.offset, true)) {
329
+ if (node.arguments?.innerRange && Range.contains(node.arguments.innerRange, ctx.offset, true)) {
330
330
  return selectorArguments(node.arguments, ctx);
331
331
  }
332
332
  return [];
@@ -124,6 +124,7 @@ export declare namespace ItemStackNode {
124
124
  export interface ComponentListNode extends core.AstNode {
125
125
  type: 'mcfunction:component_list';
126
126
  children: (ComponentNode | ComponentRemovalNode)[];
127
+ innerRange?: core.Range;
127
128
  }
128
129
  export declare namespace ComponentListNode {
129
130
  function is(node: core.AstNode): node is ComponentListNode;
@@ -1,6 +1,7 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import * as json from '@spyglassmc/json';
3
3
  import * as mcf from '@spyglassmc/mcfunction';
4
+ import * as nbt from '@spyglassmc/nbt';
4
5
  import type { BlockNode, EntityNode, ParticleNode, ScoreHolderNode, UuidNode } from '../node/index.js';
5
6
  import { EntitySelectorNode } from '../node/index.js';
6
7
  /**
@@ -11,7 +12,9 @@ export declare const argument: mcf.ArgumentParserGetter;
11
12
  export declare const blockPredicate: core.InfallibleParser<BlockNode>;
12
13
  export declare function criterion(advancement: core.FullResourceLocation, usageType?: core.SymbolUsageType, terminators?: string[]): core.InfallibleParser<core.SymbolNode>;
13
14
  export declare function entity(amount: 'multiple' | 'single', type: 'entities' | 'players'): core.Parser<EntityNode>;
15
+ export declare function typeRefParser(typeRef: `::${string}::${string}`): core.Parser<json.TypedJsonNode | nbt.TypedNbtNode>;
14
16
  export declare function jsonParser(typeRef: `::${string}::${string}`): core.Parser<json.TypedJsonNode>;
17
+ export declare function nbtParser(typeRef: `::${string}::${string}`): core.Parser<nbt.TypedNbtNode>;
15
18
  export declare const particle: core.InfallibleParser<ParticleNode>;
16
19
  /**
17
20
  * Failure when not beginning with `@[parse]`
@@ -87,7 +87,7 @@ export const argument = (rawTreeNode, prevNodes) => {
87
87
  case 'minecraft:column_pos':
88
88
  return wrap(vector({ dimension: 2, integersOnly: true }));
89
89
  case 'minecraft:component':
90
- return wrap(jsonParser('::java::server::util::text::Text'));
90
+ return wrap(typeRefParser('::java::server::util::text::Text'));
91
91
  case 'minecraft:dimension':
92
92
  return wrap(core.resourceLocation({ category: 'dimension' }));
93
93
  case 'minecraft:entity':
@@ -133,11 +133,11 @@ export const argument = (rawTreeNode, prevNodes) => {
133
133
  case 'minecraft:mob_effect':
134
134
  return wrap(core.resourceLocation({ category: 'mob_effect' }));
135
135
  case 'minecraft:nbt_compound_tag':
136
- return wrap(nbtParser(nbt.parser.compound, treeNode.properties));
136
+ return wrap(nbtDispatchedParser(nbt.parser.compound, treeNode.properties));
137
137
  case 'minecraft:nbt_path':
138
138
  return wrap(nbtPathParser(nbt.parser.path, treeNode.properties));
139
139
  case 'minecraft:nbt_tag':
140
- return wrap(nbtParser(nbt.parser.entry, treeNode.properties));
140
+ return wrap(nbtDispatchedParser(nbt.parser.entry, treeNode.properties));
141
141
  case 'minecraft:objective':
142
142
  return wrap(objective(core.SymbolUsageType.is(treeNode.properties?.usageType)
143
143
  ? treeNode.properties?.usageType
@@ -171,7 +171,7 @@ export const argument = (rawTreeNode, prevNodes) => {
171
171
  return commandLiteral({ pool: getScoreboardSlotArgumentValues(ctx) })(src, ctx);
172
172
  });
173
173
  case 'minecraft:style':
174
- return wrap(jsonParser('::java::server::util::text::TextStyle'));
174
+ return wrap(typeRefParser('::java::server::util::text::TextStyle'));
175
175
  case 'minecraft:swizzle':
176
176
  return wrap(commandLiteral({ pool: SwizzleArgumentValues }));
177
177
  case 'minecraft:team':
@@ -358,6 +358,15 @@ const itemPredicate = (src, ctx) => {
358
358
  return ans;
359
359
  })(src, ctx);
360
360
  };
361
+ export function typeRefParser(typeRef) {
362
+ return (src, ctx) => {
363
+ const release = ctx.project['loadedVersion'];
364
+ if (!release || ReleaseVersion.cmp(release, '1.21.5') < 0) {
365
+ return jsonParser(typeRef)(src, ctx);
366
+ }
367
+ return nbtParser(typeRef)(src, ctx);
368
+ };
369
+ }
361
370
  export function jsonParser(typeRef) {
362
371
  return core.map(json.parser.entry, (res) => ({
363
372
  type: 'json:typed',
@@ -366,6 +375,14 @@ export function jsonParser(typeRef) {
366
375
  targetType: { kind: 'reference', path: typeRef },
367
376
  }));
368
377
  }
378
+ export function nbtParser(typeRef) {
379
+ return core.map(nbt.parser.entry, (res) => ({
380
+ type: 'nbt:typed',
381
+ range: res.range,
382
+ children: [res],
383
+ targetType: { kind: 'reference', path: typeRef },
384
+ }));
385
+ }
369
386
  function commandLiteral(options) {
370
387
  return (src, ctx) => {
371
388
  const ans = core.literal(options)(src, ctx);
@@ -392,7 +409,7 @@ const message = (src, ctx) => {
392
409
  }
393
410
  return ans;
394
411
  };
395
- function nbtParser(parser, properties) {
412
+ function nbtDispatchedParser(parser, properties) {
396
413
  return core.map(parser, (res) => {
397
414
  const ans = { type: 'mcfunction:nbt', range: res.range, children: [res], properties };
398
415
  return ans;
@@ -1085,6 +1102,7 @@ const components = (src, ctx) => {
1085
1102
  if (!src.trySkip('[')) {
1086
1103
  return core.Failure;
1087
1104
  }
1105
+ ans.innerRange = core.Range.create(src);
1088
1106
  src.skipWhitespace();
1089
1107
  while (src.canRead() && src.peek() !== ']') {
1090
1108
  const start = src.cursor;
@@ -1139,6 +1157,7 @@ const components = (src, ctx) => {
1139
1157
  }
1140
1158
  }
1141
1159
  src.skipWhitespace();
1160
+ ans.innerRange.end = src.cursor;
1142
1161
  core.literal(']')(src, ctx);
1143
1162
  ans.range.end = src.cursor;
1144
1163
  return ans;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/java-edition",
3
- "version": "0.3.26",
3
+ "version": "0.3.28",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -17,12 +17,12 @@
17
17
  "release:dry": "npm publish --dry-run"
18
18
  },
19
19
  "dependencies": {
20
- "@spyglassmc/core": "0.4.20",
21
- "@spyglassmc/json": "0.3.23",
22
- "@spyglassmc/locales": "0.3.11",
23
- "@spyglassmc/mcfunction": "0.2.22",
24
- "@spyglassmc/mcdoc": "0.3.24",
25
- "@spyglassmc/nbt": "0.3.24"
20
+ "@spyglassmc/core": "0.4.22",
21
+ "@spyglassmc/json": "0.3.25",
22
+ "@spyglassmc/locales": "0.3.12",
23
+ "@spyglassmc/mcfunction": "0.2.24",
24
+ "@spyglassmc/mcdoc": "0.3.26",
25
+ "@spyglassmc/nbt": "0.3.26"
26
26
  },
27
27
  "devDependencies": {},
28
28
  "publishConfig": {