@spyglassmc/java-edition 0.3.35 → 0.3.37

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,4 +1,4 @@
1
- import type { CheckerContext, Config, FileCategory, MetaRegistry, RootUriString, UriBinder, UriBinderContext } from '@spyglassmc/core';
1
+ import type { CheckerContext, Config, FileCategory, MetaRegistry, RootUriString, UriBinder, UriBinderContext, UriPredicate } from '@spyglassmc/core';
2
2
  import { ReleaseVersion } from '../dependency/index.js';
3
3
  interface Resource {
4
4
  path: string;
@@ -13,11 +13,11 @@ export declare function getResources(): Generator<Resource, undefined, undefined
13
13
  export declare function getRels(uri: string, rootUris: readonly RootUriString[]): Generator<string, undefined, unknown>;
14
14
  export declare function getRoots(uri: string, rootUris: readonly RootUriString[]): Generator<RootUriString, undefined, unknown>;
15
15
  export declare function dissectUri(uri: string, ctx: UriBinderContext): {
16
+ expected: string | undefined;
16
17
  namespace: string;
17
18
  identifier: string;
18
- expected: string | undefined;
19
19
  path: string;
20
- category: "function" | "advancement" | "banner_pattern" | "cat_variant" | "chat_type" | "cow_variant" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "frog_variant" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "pig_variant" | "predicate" | "recipe" | "structure" | "test_environment" | "test_instance" | "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/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_predicate_type" | "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/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/spawn_condition_type" | "tag/stat_type" | "tag/test_environment_definition_type" | "tag/test_function" | "tag/test_instance_type" | "tag/trigger_type" | "tag/ticket_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/cat_variant" | "tag/chat_type" | "tag/cow_variant" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/frog_variant" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/pig_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/test_environment" | "tag/test_instance" | "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" | "cat_variant" | "chat_type" | "cow_variant" | "damage_type" | "dimension" | "dimension_type" | "enchantment" | "enchantment_provider" | "frog_variant" | "instrument" | "item_modifier" | "jukebox_song" | "loot_table" | "painting_variant" | "pig_variant" | "predicate" | "recipe" | "structure" | "test_environment" | "test_instance" | "trial_spawner" | "trim_material" | "trim_pattern" | "wolf_sound_variant" | "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/chunk_status" | "tag/command_argument_type" | "tag/consume_effect_type" | "tag/creative_mode_tab" | "tag/custom_stat" | "tag/data_component_predicate_type" | "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/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/spawn_condition_type" | "tag/stat_type" | "tag/test_environment_definition_type" | "tag/test_function" | "tag/test_instance_type" | "tag/trigger_type" | "tag/ticket_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/cat_variant" | "tag/chat_type" | "tag/cow_variant" | "tag/damage_type" | "tag/dimension" | "tag/dimension_type" | "tag/enchantment" | "tag/enchantment_provider" | "tag/frog_variant" | "tag/item_modifier" | "tag/jukebox_song" | "tag/loot_table" | "tag/painting_variant" | "tag/pig_variant" | "tag/predicate" | "tag/recipe" | "tag/structure" | "tag/test_environment" | "tag/test_instance" | "tag/trial_spawner" | "tag/trim_material" | "tag/trim_pattern" | "tag/wolf_sound_variant" | "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";
21
21
  ext: `.${string}`;
22
22
  pack: "assets" | "data";
23
23
  since?: `1.${number}` | undefined;
@@ -28,5 +28,11 @@ export declare const uriBinder: UriBinder;
28
28
  export declare function registerCustomResources(config: Config): void;
29
29
  export declare function reportDissectError(realPath: string, expectedPath: string | undefined, ctx: CheckerContext): void;
30
30
  export declare function registerUriBuilders(meta: MetaRegistry): void;
31
+ /**
32
+ * Returns true for JSON file URIs that belong to any known resource category. No version check is
33
+ * performed as we would like to provide errors even for files in the wrong folder or files for the
34
+ * wrong version.
35
+ */
36
+ export declare const jsonUriPredicate: UriPredicate;
31
37
  export {};
32
38
  //# sourceMappingURL=index.d.ts.map
@@ -61,6 +61,7 @@ resource('test_environment', { since: '1.21.5' });
61
61
  resource('trial_spawner', { since: '1.21.2' });
62
62
  resource('trim_pattern', { since: '1.19.4' });
63
63
  resource('trim_material', { since: '1.19.4' });
64
+ resource('wolf_sound_variant', { since: '1.21.5' });
64
65
  resource('wolf_variant', { since: '1.20.5' });
65
66
  // Worldgen
66
67
  resource('dimension', { since: '1.16' });
@@ -159,6 +160,52 @@ export function* getRoots(uri, rootUris) {
159
160
  }
160
161
  return undefined;
161
162
  }
163
+ function getCandidateResourcesForRel(rel) {
164
+ const parts = rel.split('/');
165
+ if (parts.length < 3) {
166
+ return [];
167
+ }
168
+ const [pack, namespace, ...rest] = parts;
169
+ if (pack !== 'data' && pack !== 'assets') {
170
+ return [];
171
+ }
172
+ const candidateResources = [];
173
+ if (rest.length === 1) {
174
+ const resources = Resources.get('');
175
+ for (const res of resources ?? []) {
176
+ if (res.pack !== pack) {
177
+ continue;
178
+ }
179
+ let identifier = rest[0];
180
+ if (!identifier.endsWith(res.ext)) {
181
+ continue;
182
+ }
183
+ identifier = identifier.slice(0, -res.ext.length);
184
+ if (res.identifier && identifier !== res.identifier) {
185
+ continue;
186
+ }
187
+ candidateResources.push({ ...res, namespace, identifier });
188
+ }
189
+ }
190
+ for (let i = 1; i < rest.length; i += 1) {
191
+ const resources = Resources.get(rest.slice(0, i).join('/'));
192
+ for (const res of resources ?? []) {
193
+ if (res.pack !== pack) {
194
+ continue;
195
+ }
196
+ let identifier = rest.slice(i).join('/');
197
+ if (!identifier.endsWith(res.ext)) {
198
+ continue;
199
+ }
200
+ identifier = identifier.slice(0, -res.ext.length);
201
+ if (res.identifier && identifier !== res.identifier) {
202
+ continue;
203
+ }
204
+ candidateResources.push({ ...res, namespace, identifier });
205
+ }
206
+ }
207
+ return candidateResources;
208
+ }
162
209
  export function dissectUri(uri, ctx) {
163
210
  const rels = getRels(uri, ctx.roots);
164
211
  const release = ctx.project['loadedVersion'];
@@ -166,63 +213,21 @@ export function dissectUri(uri, ctx) {
166
213
  return undefined;
167
214
  }
168
215
  for (const rel of rels) {
169
- const parts = rel.split('/');
170
- if (parts.length < 3) {
171
- continue;
172
- }
173
- const [pack, namespace, ...rest] = parts;
174
- if (pack !== 'data' && pack !== 'assets') {
175
- continue;
176
- }
177
- const candidateResources = [];
178
- if (rest.length === 1) {
179
- const resources = Resources.get('');
180
- for (const res of resources ?? []) {
181
- if (res.pack !== pack) {
182
- continue;
183
- }
184
- let identifier = rest[0];
185
- if (!identifier.endsWith(res.ext)) {
186
- continue;
187
- }
188
- identifier = identifier.slice(0, -res.ext.length);
189
- if (res.identifier && identifier !== res.identifier) {
190
- continue;
191
- }
192
- candidateResources.push([res, identifier]);
193
- }
194
- }
195
- for (let i = 1; i < rest.length; i += 1) {
196
- const resources = Resources.get(rest.slice(0, i).join('/'));
197
- for (const res of resources ?? []) {
198
- if (res.pack !== pack) {
199
- continue;
200
- }
201
- let identifier = rest.slice(i).join('/');
202
- if (!identifier.endsWith(res.ext)) {
203
- continue;
204
- }
205
- identifier = identifier.slice(0, -res.ext.length);
206
- if (res.identifier && identifier !== res.identifier) {
207
- continue;
208
- }
209
- candidateResources.push([res, identifier]);
210
- }
211
- }
216
+ const candidateResources = getCandidateResourcesForRel(rel);
212
217
  if (candidateResources.length === 0) {
213
218
  continue;
214
219
  }
215
220
  // Finding the last, because that will be the deepest match
216
- let res = candidateResources.findLast(([res]) => matchVersion(release, res.since, res.until));
221
+ let res = candidateResources.findLast((res) => matchVersion(release, res.since, res.until));
217
222
  if (res !== undefined) {
218
- return { ok: true, ...res[0], namespace, identifier: res[1], expected: undefined };
223
+ return { ok: true, ...res, expected: undefined };
219
224
  }
220
225
  // Try to find the expected path that matches the current version
221
226
  res = candidateResources[candidateResources.length - 1];
222
227
  let expected = undefined;
223
228
  for (const [path, others] of Resources) {
224
229
  for (const other of others) {
225
- if (other.category !== res[0].category) {
230
+ if (other.category !== res.category) {
226
231
  continue;
227
232
  }
228
233
  if (matchVersion(release, other.since, other.until)) {
@@ -231,7 +236,7 @@ export function dissectUri(uri, ctx) {
231
236
  }
232
237
  }
233
238
  }
234
- return { ok: false, ...res[0], namespace, identifier: res[1], expected };
239
+ return { ok: false, ...res, expected };
235
240
  }
236
241
  return undefined;
237
242
  }
@@ -303,4 +308,13 @@ export function registerUriBuilders(meta) {
303
308
  meta.registerUriBuilder(category, uriBuilder(resources));
304
309
  }
305
310
  }
311
+ /**
312
+ * Returns true for JSON file URIs that belong to any known resource category. No version check is
313
+ * performed as we would like to provide errors even for files in the wrong folder or files for the
314
+ * wrong version.
315
+ */
316
+ export const jsonUriPredicate = (uri, ctx) => {
317
+ const rels = [...getRels(uri, ctx.roots)];
318
+ return rels.some((rel) => getCandidateResourcesForRel(rel).length > 0);
319
+ };
306
320
  //# sourceMappingURL=index.js.map
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 { registerUriBuilders, uriBinder } from './binder/index.js';
5
+ import { jsonUriPredicate, 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';
@@ -111,7 +111,6 @@ export const initialize = async (ctx) => {
111
111
  });
112
112
  registerMcdocAttributes(meta, summary.commands, release);
113
113
  registerPackFormatAttribute(meta, release, versions, packs);
114
- registerPackFormatAttribute(meta, release, versions, packs);
115
114
  meta.registerLanguage('zip', { extensions: ['.zip'] });
116
115
  meta.registerLanguage('png', { extensions: ['.png'] });
117
116
  meta.registerLanguage('ogg', { extensions: ['.ogg'] });
@@ -119,7 +118,7 @@ export const initialize = async (ctx) => {
119
118
  meta.registerLanguage('otf', { extensions: ['.otf'] });
120
119
  meta.registerLanguage('fsh', { extensions: ['.fsh'] });
121
120
  meta.registerLanguage('vsh', { extensions: ['.vsh'] });
122
- json.initialize(ctx);
121
+ json.getInitializer(jsonUriPredicate)(ctx);
123
122
  jeJson.initialize(ctx);
124
123
  jeMcf.initialize(ctx, summary.commands, release);
125
124
  nbt.initialize(ctx);
@@ -60,10 +60,10 @@ export const translationValueParser = (src, ctx) => {
60
60
  hasInteger = true;
61
61
  }
62
62
  if (hasInteger && !src.trySkip('$')) {
63
- ctx.err.report(localize('expected', localeQuote('$')), src);
63
+ ctx.err.report(localize('java-edition.translation-value.percent-escape-hint', localize('expected', localeQuote('$'))), src);
64
64
  }
65
65
  if (!src.trySkip('s')) {
66
- ctx.err.report(localize('expected', localeQuote('s')), src);
66
+ ctx.err.report(localize('java-edition.translation-value.percent-escape-hint', localize('expected', localeQuote('s'))), src);
67
67
  }
68
68
  const token = src.sliceToCursor(argStart);
69
69
  ans.children.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/java-edition",
3
- "version": "0.3.35",
3
+ "version": "0.3.37",
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.26",
21
- "@spyglassmc/json": "0.3.30",
22
- "@spyglassmc/locales": "0.3.12",
23
- "@spyglassmc/mcfunction": "0.2.28",
24
- "@spyglassmc/mcdoc": "0.3.30",
25
- "@spyglassmc/nbt": "0.3.31"
20
+ "@spyglassmc/core": "0.4.28",
21
+ "@spyglassmc/json": "0.3.32",
22
+ "@spyglassmc/locales": "0.3.14",
23
+ "@spyglassmc/mcfunction": "0.2.30",
24
+ "@spyglassmc/mcdoc": "0.3.32",
25
+ "@spyglassmc/nbt": "0.3.33"
26
26
  },
27
27
  "devDependencies": {},
28
28
  "publishConfig": {