@spyglassmc/java-edition 0.3.19 → 0.3.21

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.
@@ -5,7 +5,7 @@ export declare const NEXT_RELEASE_VERSION = "1.21.4";
5
5
  /**
6
6
  * @param inputVersion {@link core.Config.env.gameVersion}
7
7
  */
8
- export declare function resolveConfiguredVersion(inputVersion: string, versions: McmetaVersions, packMcmeta: PackMcmeta | undefined, packType: 'assets' | 'data' | undefined): VersionInfo;
8
+ export declare function resolveConfiguredVersion(inputVersion: string, versions: McmetaVersions, packMcmeta: PackMcmeta | undefined, packType: 'assets' | 'data' | undefined, logger: core.Logger): VersionInfo;
9
9
  export declare function getMcmetaSummaryUris(version: string, isLatest: boolean, source: string): {
10
10
  blocks: core.RemoteUriString;
11
11
  commands: core.RemoteUriString;
@@ -5,7 +5,7 @@ export const NEXT_RELEASE_VERSION = '1.21.4';
5
5
  /**
6
6
  * @param inputVersion {@link core.Config.env.gameVersion}
7
7
  */
8
- export function resolveConfiguredVersion(inputVersion, versions, packMcmeta, packType) {
8
+ export function resolveConfiguredVersion(inputVersion, versions, packMcmeta, packType, logger) {
9
9
  function findReleaseTarget(version) {
10
10
  if (version.release_target) {
11
11
  return version.release_target;
@@ -34,6 +34,12 @@ export function resolveConfiguredVersion(inputVersion, versions, packMcmeta, pac
34
34
  if (versions.length === 0) {
35
35
  throw new Error('mcmeta version list is empty');
36
36
  }
37
+ // This should never happen, but for some reason happens sometimes
38
+ // https://github.com/SpyglassMC/Spyglass/issues/1621
39
+ if (inputVersion === undefined) {
40
+ logger.warn('[resolveConfiguredVersion] Input version was undefined! Falling back to "auto"');
41
+ inputVersion = 'auto';
42
+ }
37
43
  inputVersion = inputVersion.toLowerCase();
38
44
  versions = versions.sort((a, b) => b.data_version - a.data_version);
39
45
  const latestRelease = versions.find((v) => v.type === 'release');
@@ -130,52 +136,55 @@ export function symbolRegistrar(summary, release) {
130
136
  });
131
137
  });
132
138
  }
133
- symbols.query(McmetaSummaryUri, 'mcdoc/dispatcher', 'mcdoc:block_states').enter({
134
- usage: { type: 'declaration' },
135
- }).onEach(Object.entries(summary.blocks), ([id, [properties]], blockQuery) => {
136
- const data = {
137
- typeDef: {
138
- kind: 'struct',
139
- fields: Object.entries(properties).map(([propKey, propValues]) => ({
140
- kind: 'pair',
141
- key: propKey,
142
- optional: true,
143
- type: {
144
- kind: 'union',
145
- members: propValues.map(value => ({
146
- kind: 'literal',
147
- value: { kind: 'string', value },
148
- })),
149
- },
150
- })),
151
- },
152
- };
153
- blockQuery.member(id, (stateQuery) => {
154
- stateQuery.enter({
155
- data: { data },
156
- usage: { type: 'declaration' },
139
+ const stateTypes = { block: summary.blocks, fluid: summary.fluids };
140
+ for (const [type, states] of Object.entries(stateTypes)) {
141
+ symbols.query(McmetaSummaryUri, 'mcdoc/dispatcher', `mcdoc:${type}_states`)
142
+ .enter({ usage: { type: 'declaration' } })
143
+ .onEach(Object.entries(states), ([id, [properties]], query) => {
144
+ const data = {
145
+ typeDef: {
146
+ kind: 'struct',
147
+ fields: Object.entries(properties).map(([propKey, propValues]) => ({
148
+ kind: 'pair',
149
+ key: propKey,
150
+ optional: true,
151
+ type: {
152
+ kind: 'union',
153
+ members: propValues.map(value => ({
154
+ kind: 'literal',
155
+ value: { kind: 'string', value },
156
+ })),
157
+ },
158
+ })),
159
+ },
160
+ };
161
+ query.member(id, (stateQuery) => {
162
+ stateQuery.enter({
163
+ data: { data },
164
+ usage: { type: 'declaration' },
165
+ });
157
166
  });
158
167
  });
159
- });
160
- symbols.query(McmetaSummaryUri, 'mcdoc/dispatcher', 'mcdoc:block_state_keys').enter({
161
- usage: { type: 'declaration' },
162
- }).onEach(Object.entries(summary.blocks), ([id, [properties]], blockQuery) => {
163
- const data = {
164
- typeDef: {
165
- kind: 'union',
166
- members: Object.keys(properties).map(propKey => ({
167
- kind: 'literal',
168
- value: { kind: 'string', value: propKey },
169
- })),
170
- },
171
- };
172
- blockQuery.member(id, (stateQuery) => {
173
- stateQuery.enter({
174
- data: { data },
175
- usage: { type: 'declaration' },
168
+ symbols.query(McmetaSummaryUri, 'mcdoc/dispatcher', `mcdoc:${type}_state_keys`)
169
+ .enter({ usage: { type: 'declaration' } })
170
+ .onEach(Object.entries(states), ([id, [properties]], query) => {
171
+ const data = {
172
+ typeDef: {
173
+ kind: 'union',
174
+ members: Object.keys(properties).map(propKey => ({
175
+ kind: 'literal',
176
+ value: { kind: 'string', value: propKey },
177
+ })),
178
+ },
179
+ };
180
+ query.member(id, (stateQuery) => {
181
+ stateQuery.enter({
182
+ data: { data },
183
+ usage: { type: 'declaration' },
184
+ });
176
185
  });
177
186
  });
178
- });
187
+ }
179
188
  }
180
189
  function addRegistriesSymbols(registries, symbols) {
181
190
  function isCategory(str) {
package/lib/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as core from '@spyglassmc/core';
2
2
  export * as binder from './binder/index.js';
3
3
  export * as dependency from './dependency/index.js';
4
4
  export * as json from './json/index.js';
5
+ export * from './mcdocAttributes.js';
5
6
  export * as mcf from './mcfunction/index.js';
6
7
  export declare const initialize: core.ProjectInitializer;
7
8
  //# sourceMappingURL=index.d.ts.map
package/lib/index.js CHANGED
@@ -10,6 +10,7 @@ import * as jeMcf from './mcfunction/index.js';
10
10
  export * as binder from './binder/index.js';
11
11
  export * as dependency from './dependency/index.js';
12
12
  export * as json from './json/index.js';
13
+ export * from './mcdocAttributes.js';
13
14
  export * as mcf from './mcfunction/index.js';
14
15
  export const initialize = async (ctx) => {
15
16
  const { config, downloader, externals, logger, meta, projectRoots } = ctx;
@@ -43,7 +44,7 @@ export const initialize = async (ctx) => {
43
44
  readPackMcmeta(uri),
44
45
  PackMcmeta.getType(packRoot, externals),
45
46
  ]);
46
- const versionInfo = resolveConfiguredVersion(config.env.gameVersion, versions, packMcmeta, type);
47
+ const versionInfo = resolveConfiguredVersion(config.env.gameVersion, versions, packMcmeta, type, logger);
47
48
  packs.push({ type, packRoot, packMcmeta, versionInfo });
48
49
  }
49
50
  }
@@ -62,7 +63,7 @@ export const initialize = async (ctx) => {
62
63
  const pack = packs.find(p => p.packMcmeta !== undefined && p.type === 'data')
63
64
  ?? packs.find(p => p.packMcmeta !== undefined && p.type === 'assets');
64
65
  const version = pack === undefined
65
- ? resolveConfiguredVersion(config.env.gameVersion, versions, undefined, undefined)
66
+ ? resolveConfiguredVersion(config.env.gameVersion, versions, undefined, undefined, logger)
66
67
  : pack.versionInfo;
67
68
  const packMessage = pack === undefined
68
69
  ? 'Failed finding a valid pack.mcmeta'
@@ -89,7 +90,7 @@ export const initialize = async (ctx) => {
89
90
  return;
90
91
  }
91
92
  meta.registerSymbolRegistrar('mcmeta-summary', {
92
- checksum: `${summary.checksum}_v2`,
93
+ checksum: `${summary.checksum}_v3`,
93
94
  registrar: symbolRegistrar(summary, release),
94
95
  });
95
96
  meta.registerLinter('nameOfNbtKey', {
@@ -1,6 +1,6 @@
1
1
  import * as core from '@spyglassmc/core';
2
- import type { McmetaVersions, PackInfo } from './dependency';
3
- import { ReleaseVersion } from './dependency';
2
+ import { ReleaseVersion } from './dependency/index.js';
3
+ import type { McmetaVersions, PackInfo } from './dependency/index.js';
4
4
  export declare function registerMcdocAttributes(meta: core.MetaRegistry, release: ReleaseVersion): void;
5
5
  export declare function registerPackFormatAttribute(meta: core.MetaRegistry, release: ReleaseVersion, versions: McmetaVersions, packs: PackInfo[]): void;
6
6
  //# sourceMappingURL=mcdocAttributes.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import * as core from '@spyglassmc/core';
2
2
  import { localize } from '@spyglassmc/locales';
3
3
  import * as mcdoc from '@spyglassmc/mcdoc';
4
- import { NEXT_RELEASE_VERSION, ReleaseVersion } from './dependency';
4
+ import { NEXT_RELEASE_VERSION, ReleaseVersion } from './dependency/index.js';
5
5
  export function registerMcdocAttributes(meta, release) {
6
6
  mcdoc.runtime.registerAttribute(meta, 'since', mcdoc.runtime.attribute.validator.string, {
7
7
  filterElement: (config, ctx) => {
@@ -269,16 +269,13 @@ const particle = (node, ctx) => {
269
269
  return;
270
270
  }
271
271
  const options = node.children?.find(nbt.NbtCompoundNode.is);
272
- if (ParticleNode.requiresOptions(id)) {
273
- if (options) {
274
- nbt.checker.index('minecraft:particle', core.ResourceLocation.lengthen(id))(options, ctx);
275
- }
276
- else {
277
- ctx.err.report(localize('expected', localize('nbt.node.compound')), core.Range.create(node.id.range.end, node.id.range.end + 1));
278
- }
272
+ if (options) {
273
+ // Even if particle isn't explicitly marked as requiring options,
274
+ // run the type checker anyways to allow an empty compound
275
+ nbt.checker.index('minecraft:particle', core.ResourceLocation.lengthen(id))(options, ctx);
279
276
  }
280
- else if (options) {
281
- ctx.err.report(localize('expected', localize('nothing')), options);
277
+ else if (ParticleNode.requiresOptions(id)) {
278
+ ctx.err.report(localize('expected', localize('nbt.node.compound')), core.Range.create(node.id.range.end, node.id.range.end + 1));
282
279
  }
283
280
  };
284
281
  // #endregion
@@ -341,8 +341,10 @@ export var ParticleNode;
341
341
  // since 1.20.5
342
342
  const OptionTypes = new Set([
343
343
  ...SpecialTypes,
344
+ 'block_crumble',
344
345
  'dust_pillar',
345
346
  'entity_effect',
347
+ 'trail',
346
348
  ]);
347
349
  function requiresOptions(type) {
348
350
  return OptionTypes.has(type);
@@ -97,7 +97,7 @@ export const argument = (rawTreeNode, prevNodes) => {
97
97
  case 'minecraft:entity_summon':
98
98
  return wrap(core.resourceLocation({ category: 'entity_type' }));
99
99
  case 'minecraft:float_range':
100
- return wrap(range('float'));
100
+ return wrap(range('float', treeNode.properties?.min, treeNode.properties?.max, treeNode.properties?.minSpan, treeNode.properties?.maxSpan));
101
101
  case 'minecraft:function':
102
102
  return wrap(core.resourceLocation({ category: 'function', allowTag: true }));
103
103
  case 'minecraft:gamemode':
@@ -107,7 +107,7 @@ export const argument = (rawTreeNode, prevNodes) => {
107
107
  case 'minecraft:heightmap':
108
108
  return wrap(core.literal(...HeightmapValues));
109
109
  case 'minecraft:int_range':
110
- return wrap(range('integer'));
110
+ return wrap(range('integer', treeNode.properties?.min, treeNode.properties?.max, treeNode.properties?.minSpan, treeNode.properties?.maxSpan));
111
111
  case 'minecraft:item_enchantment':
112
112
  return wrap(core.resourceLocation({ category: 'enchantment' }));
113
113
  case 'minecraft:item_predicate':
@@ -453,7 +453,7 @@ export const particle = (src, ctx) => {
453
453
  return ans;
454
454
  })(src, ctx);
455
455
  };
456
- function range(type, min, max, cycleable) {
456
+ function range(type, min, max, minSpan, maxSpan, cycleable) {
457
457
  const number = type === 'float'
458
458
  ? float(min, max)
459
459
  : integer(min, max);
@@ -488,6 +488,17 @@ function range(type, min, max, cycleable) {
488
488
  && ans.value[0] > ans.value[1]) {
489
489
  ctx.err.report(localize('mcfunction.parser.range.min>max', ans.value[0], ans.value[1]), res);
490
490
  }
491
+ else if (minSpan !== undefined || maxSpan !== undefined) {
492
+ const span = ans.value[0] !== undefined && ans.value[1] !== undefined
493
+ ? Math.abs(ans.value[0] - ans.value[1])
494
+ : (ans.value[0] ?? ans.value[1] ?? Infinity);
495
+ if (minSpan !== undefined && span < minSpan) {
496
+ ctx.err.report(localize('mcfunction.parser.range.span-too-small', span, minSpan), res);
497
+ }
498
+ else if (maxSpan !== undefined && span > maxSpan) {
499
+ ctx.err.report(localize('mcfunction.parser.range.span-too-large', span, maxSpan), res);
500
+ }
501
+ }
491
502
  return ans;
492
503
  });
493
504
  }
@@ -798,7 +809,7 @@ export function selector(ignoreInvalidPrefix = false) {
798
809
  });
799
810
  case 'x_rotation':
800
811
  case 'y_rotation':
801
- return core.map(range('float', undefined, undefined, true), (res, _, ctx) => {
812
+ return core.map(range('float', undefined, undefined, undefined, undefined, true), (res, _, ctx) => {
802
813
  if (hasKey(key.value)) {
803
814
  ctx.err.report(localize('duplicate-key', localeQuote(key.value)), key);
804
815
  }
@@ -74,8 +74,15 @@ export interface MinecraftEntityAnchorArgumentTreeNode extends mcf.ArgumentTreeN
74
74
  export interface MinecraftEntitySummonArgumentTreeNode extends mcf.ArgumentTreeNode {
75
75
  parser: 'minecraft:entity_summon';
76
76
  }
77
+ export interface RangeProperties extends Record<string, unknown> {
78
+ min: number;
79
+ max: number;
80
+ minSpan: number;
81
+ maxSpan: number;
82
+ }
77
83
  export interface MinecraftFloatRangeArgumentTreeNode extends mcf.ArgumentTreeNode {
78
84
  parser: 'minecraft:float_range';
85
+ properties?: RangeProperties;
79
86
  }
80
87
  export interface MinecraftFunctionArgumentTreeNode extends mcf.ArgumentTreeNode {
81
88
  parser: 'minecraft:function';
@@ -91,6 +98,7 @@ export interface MinecraftHeightmapArgumentTreeNode extends mcf.ArgumentTreeNode
91
98
  }
92
99
  export interface MinecraftIntRangeArgumentTreeNode extends mcf.ArgumentTreeNode {
93
100
  parser: 'minecraft:int_range';
101
+ properties?: RangeProperties;
94
102
  }
95
103
  export interface MinecraftItemEnchantmentArgumentTreeNode extends mcf.ArgumentTreeNode {
96
104
  parser: 'minecraft:item_enchantment';
@@ -515,6 +515,10 @@ export function getPatch(release) {
515
515
  roll: {
516
516
  children: {
517
517
  range: {
518
+ properties: {
519
+ minSpan: 1,
520
+ maxSpan: 2147483646,
521
+ },
518
522
  children: {
519
523
  sequence: {
520
524
  properties: {
@@ -529,6 +533,10 @@ export function getPatch(release) {
529
533
  value: {
530
534
  children: {
531
535
  range: {
536
+ properties: {
537
+ minSpan: 1,
538
+ maxSpan: 2147483646,
539
+ },
532
540
  children: {
533
541
  sequence: {
534
542
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/java-edition",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
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.15",
21
- "@spyglassmc/json": "0.3.17",
22
- "@spyglassmc/locales": "0.3.9",
23
- "@spyglassmc/mcfunction": "0.2.17",
24
- "@spyglassmc/mcdoc": "0.3.18",
25
- "@spyglassmc/nbt": "0.3.18"
20
+ "@spyglassmc/core": "0.4.16",
21
+ "@spyglassmc/json": "0.3.18",
22
+ "@spyglassmc/locales": "0.3.10",
23
+ "@spyglassmc/mcfunction": "0.2.18",
24
+ "@spyglassmc/mcdoc": "0.3.19",
25
+ "@spyglassmc/nbt": "0.3.19"
26
26
  },
27
27
  "devDependencies": {
28
28
  "fast-glob": "^3.2.5"