@spyglassmc/java-edition 0.3.58 → 0.3.60
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.
- package/lib/binder/index.d.ts +4 -4
- package/lib/mcfunction/common/index.js +15 -3
- package/lib/mcfunction/completer/argument.js +3 -1
- package/lib/mcfunction/node/argument.d.ts +10 -10
- package/lib/mcfunction/node/argument.js +2 -4
- package/lib/mcfunction/parser/argument.js +7 -0
- package/lib/mcfunction/tree/argument.d.ts +4 -1
- package/package.json +6 -6
package/lib/binder/index.d.ts
CHANGED
|
@@ -13,16 +13,16 @@ export declare function getResources(): Generator<Resource, undefined, unknown>;
|
|
|
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;
|
|
17
|
-
namespace: string;
|
|
18
|
-
identifier: string;
|
|
19
16
|
path: string;
|
|
20
17
|
category: FileCategory;
|
|
21
18
|
ext: `.${string}`;
|
|
22
|
-
pack:
|
|
19
|
+
pack: 'data' | 'assets';
|
|
23
20
|
since?: ReleaseVersion;
|
|
24
21
|
until?: ReleaseVersion;
|
|
22
|
+
namespace: string;
|
|
23
|
+
identifier: string;
|
|
25
24
|
ok: boolean;
|
|
25
|
+
expected: string | undefined;
|
|
26
26
|
} | undefined;
|
|
27
27
|
export declare const uriBinder: UriBinder;
|
|
28
28
|
export declare function registerCustomResources(config: Config): void;
|
|
@@ -11,7 +11,6 @@ export function getItemSlotArgumentValues(ctx) {
|
|
|
11
11
|
...[...Array(15).keys()].map((n) => `horse.${n}`),
|
|
12
12
|
...[...Array(9).keys()].map((n) => `hotbar.${n}`),
|
|
13
13
|
...[...Array(27).keys()].map((n) => `inventory.${n}`),
|
|
14
|
-
...[...Array(8).keys()].map((n) => `villager.${n}`),
|
|
15
14
|
'armor.chest',
|
|
16
15
|
'armor.feet',
|
|
17
16
|
'armor.head',
|
|
@@ -33,11 +32,18 @@ export function getItemSlotArgumentValues(ctx) {
|
|
|
33
32
|
else {
|
|
34
33
|
output.push('horse.saddle');
|
|
35
34
|
}
|
|
35
|
+
if (ReleaseVersion.cmp(release, '26.1') >= 0) {
|
|
36
|
+
output.push(...[...Array(8).keys()].map((n) => `mob.inventory.${n}`));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
output.push(...[...Array(8).keys()].map((n) => `villager.${n}`));
|
|
40
|
+
}
|
|
36
41
|
return output;
|
|
37
42
|
}
|
|
38
43
|
// Only exists since 1.20.5
|
|
39
44
|
export function getItemSlotsArgumentValues(ctx) {
|
|
40
|
-
|
|
45
|
+
const release = ctx.project['loadedVersion'];
|
|
46
|
+
const output = [
|
|
41
47
|
...getItemSlotArgumentValues(ctx),
|
|
42
48
|
'armor.*',
|
|
43
49
|
'container.*',
|
|
@@ -46,9 +52,15 @@ export function getItemSlotsArgumentValues(ctx) {
|
|
|
46
52
|
'hotbar.*',
|
|
47
53
|
'inventory.*',
|
|
48
54
|
'player.crafting.*',
|
|
49
|
-
'villager.*',
|
|
50
55
|
'weapon.*',
|
|
51
56
|
];
|
|
57
|
+
if (ReleaseVersion.cmp(release, '26.1') >= 0) {
|
|
58
|
+
output.push('mob.inventory.*');
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
output.push('villager.*');
|
|
62
|
+
}
|
|
63
|
+
return output;
|
|
52
64
|
}
|
|
53
65
|
export const OperationArgumentValues = ['=', '+=', '-=', '*=', '/=', '%=', '<', '>', '><'];
|
|
54
66
|
export function getScoreboardSlotArgumentValues(ctx) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AstNode, binarySearch, BooleanNode, BrigadierStringOptions, completer, CompletionItem, FloatNode, getStates, InsertTextBuilder, IntegerNode, LiteralNode, Range, ResourceLocation, ResourceLocationNode, StringNode, SymbolNode, } from '@spyglassmc/core';
|
|
1
|
+
import { AstNode, binarySearch, BooleanNode, BrigadierStringOptions, Color, completer, CompletionItem, FloatNode, getStates, InsertTextBuilder, IntegerNode, LiteralNode, Range, ResourceLocation, ResourceLocationNode, StringNode, SymbolNode, } from '@spyglassmc/core';
|
|
2
2
|
import * as json from '@spyglassmc/json';
|
|
3
3
|
import { localeQuote, localize } from '@spyglassmc/locales';
|
|
4
4
|
import { getTagValues } from '../../common/index.js';
|
|
@@ -116,6 +116,8 @@ export const getMockNodes = (rawTreeNode, prevNodes, ctx) => {
|
|
|
116
116
|
return LiteralNode.mock(range, { pool: SwizzleArgumentValues });
|
|
117
117
|
case 'minecraft:team':
|
|
118
118
|
return SymbolNode.mock(range, { category: 'team' });
|
|
119
|
+
case 'minecraft:team_color':
|
|
120
|
+
return LiteralNode.mock(range, { pool: Color.ColorNames });
|
|
119
121
|
case 'minecraft:template_mirror':
|
|
120
122
|
return LiteralNode.mock(range, { pool: MirrorValues });
|
|
121
123
|
case 'minecraft:template_rotation':
|
|
@@ -20,8 +20,8 @@ export declare namespace BlockNode {
|
|
|
20
20
|
function is(node: core.DeepReadonly<core.AstNode> | undefined): node is BlockNode;
|
|
21
21
|
function mock(range: core.RangeLike, isPredicate: boolean): BlockNode;
|
|
22
22
|
}
|
|
23
|
-
export declare const CoordinateNotations: readonly [
|
|
24
|
-
export type CoordinateNodeNotation = typeof CoordinateNotations[number];
|
|
23
|
+
export declare const CoordinateNotations: readonly ['', '~', '^'];
|
|
24
|
+
export type CoordinateNodeNotation = (typeof CoordinateNotations)[number];
|
|
25
25
|
export interface CoordinateNode extends core.FloatBaseNode {
|
|
26
26
|
type: 'mcfunction:coordinate';
|
|
27
27
|
notation: CoordinateNodeNotation;
|
|
@@ -57,19 +57,19 @@ export interface EntitySelectorArgumentsNode extends core.RecordBaseNode<core.St
|
|
|
57
57
|
export declare namespace EntitySelectorArgumentsNode {
|
|
58
58
|
function is(node: core.AstNode): node is EntitySelectorArgumentsNode;
|
|
59
59
|
}
|
|
60
|
-
declare const EntitySelectorVariables: readonly [
|
|
61
|
-
export type EntitySelectorVariable = typeof EntitySelectorVariables[number];
|
|
60
|
+
declare const EntitySelectorVariables: readonly ['a', 'e', 'p', 'r', 's', 'n'];
|
|
61
|
+
export type EntitySelectorVariable = (typeof EntitySelectorVariables)[number];
|
|
62
62
|
export declare namespace EntitySelectorVariable {
|
|
63
63
|
function is(value: string): value is EntitySelectorVariable;
|
|
64
64
|
}
|
|
65
|
-
declare const EntitySelectorAtVariables: ("@
|
|
66
|
-
export type EntitySelectorAtVariable = typeof EntitySelectorAtVariables[number];
|
|
65
|
+
declare const EntitySelectorAtVariables: ("@a" | "@e" | "@n" | "@p" | "@r" | "@s")[];
|
|
66
|
+
export type EntitySelectorAtVariable = (typeof EntitySelectorAtVariables)[number];
|
|
67
67
|
export declare namespace EntitySelectorAtVariable {
|
|
68
68
|
function is(value: string): value is EntitySelectorAtVariable;
|
|
69
69
|
/**
|
|
70
70
|
* Should be used to get a list of available selectors for the current version.
|
|
71
71
|
*/
|
|
72
|
-
function filterAvailable(ctx: core.ContextBase): ("@
|
|
72
|
+
function filterAvailable(ctx: core.ContextBase): ("@a" | "@e" | "@n" | "@p" | "@r" | "@s")[];
|
|
73
73
|
}
|
|
74
74
|
export interface EntitySelectorNode extends core.AstNode {
|
|
75
75
|
type: 'mcfunction:entity_selector';
|
|
@@ -87,7 +87,7 @@ export interface EntitySelectorNode extends core.AstNode {
|
|
|
87
87
|
export declare namespace EntitySelectorNode {
|
|
88
88
|
function is<T extends core.DeepReadonly<core.AstNode> | undefined>(node: T): node is core.InheritReadonly<EntitySelectorNode, T>;
|
|
89
89
|
function mock(range: core.RangeLike, options: core.LiteralOptions): EntitySelectorNode;
|
|
90
|
-
const ArgumentKeys: Set<"
|
|
90
|
+
const ArgumentKeys: Set<"advancements" | "distance" | "dx" | "dy" | "dz" | "gamemode" | "level" | "limit" | "name" | "nbt" | "predicate" | "scores" | "sort" | "tag" | "team" | "type" | "x" | "x_rotation" | "y" | "y_rotation" | "z">;
|
|
91
91
|
type ArgumentKey = typeof ArgumentKeys extends Set<infer T> ? T : undefined;
|
|
92
92
|
const enum Result {
|
|
93
93
|
Ok = 0,
|
|
@@ -253,7 +253,7 @@ export interface ObjectiveCriteriaNode extends core.AstNode {
|
|
|
253
253
|
}
|
|
254
254
|
export declare namespace ObjectiveCriteriaNode {
|
|
255
255
|
const SimpleValues: string[];
|
|
256
|
-
const ComplexCategories: Map<string, "
|
|
256
|
+
const ComplexCategories: Map<string, "activity" | "armor_material" | "attribute" | "attribute_type" | "block" | "block_entity_type" | "block_predicate_type" | "block_type" | "chunk_status" | "command_argument_type" | "consume_effect_type" | "creative_mode_tab" | "custom_stat" | "data_component_predicate_type" | "data_component_type" | "debug_subscription" | "decorated_pot_pattern" | "decorated_pot_patterns" | "dialog_action_type" | "dialog_body_type" | "dialog_type" | "enchantment_effect_component_type" | "enchantment_entity_effect_type" | "enchantment_level_based_value_type" | "enchantment_location_based_effect_type" | "enchantment_provider_type" | "enchantment_value_effect_type" | "entity_sub_predicate_type" | "entity_type" | "environment_attribute" | "float_provider_type" | "fluid" | "game_event" | "game_rule" | "height_provider_type" | "incoming_rpc_methods" | "input_control_type" | "instrument" | "int_provider_type" | "item" | "item_sub_predicate_type" | "loot_condition_type" | "loot_function_type" | "loot_nbt_provider_type" | "loot_number_provider_type" | "loot_pool_entry_type" | "loot_score_provider_type" | "map_decoration_type" | "memory_module_type" | "menu" | "mob_effect" | "motive" | "number_format_type" | "outgoing_rpc_methods" | "particle_type" | "permission_check_type" | "permission_type" | "point_of_interest_type" | "pos_rule_test" | "position_source_type" | "potion" | "recipe_book_category" | "recipe_display" | "recipe_serializer" | "recipe_type" | "rule_block_entity_modifier" | "rule_test" | "schedule" | "sensor_type" | "slot_display" | "slot_source_type" | "sound_event" | "spawn_condition_type" | "stat_type" | "test_environment_definition_type" | "test_function" | "test_instance_type" | "ticket_type" | "trigger_type" | "villager_profession" | "villager_type" | "worldgen/biome_source" | "worldgen/block_placer_type" | "worldgen/block_state_provider_type" | "worldgen/carver" | "worldgen/chunk_generator" | "worldgen/decorator" | "worldgen/density_function_type" | "worldgen/feature" | "worldgen/feature_size_type" | "worldgen/foliage_placer_type" | "worldgen/material_condition" | "worldgen/material_rule" | "worldgen/placement_modifier_type" | "worldgen/pool_alias_binding" | "worldgen/root_placer_type" | "worldgen/structure_feature" | "worldgen/structure_piece" | "worldgen/structure_placement" | "worldgen/structure_pool_element" | "worldgen/structure_processor" | "worldgen/structure_type" | "worldgen/surface_builder" | "worldgen/tree_decorator_type" | "worldgen/trunk_placer_type">;
|
|
257
257
|
const ComplexSep = ":";
|
|
258
258
|
function mock(range: core.RangeLike): ObjectiveCriteriaNode;
|
|
259
259
|
}
|
|
@@ -263,7 +263,7 @@ export interface ParticleNode extends core.AstNode {
|
|
|
263
263
|
id: core.ResourceLocationNode;
|
|
264
264
|
}
|
|
265
265
|
export declare namespace ParticleNode {
|
|
266
|
-
const SpecialTypes: Set<"block" | "
|
|
266
|
+
const SpecialTypes: Set<"block" | "block_marker" | "dust" | "dust_color_transition" | "falling_dust" | "item" | "sculk_charge" | "shriek" | "vibration">;
|
|
267
267
|
export type SpecialType = typeof SpecialTypes extends Set<infer T> ? T : undefined;
|
|
268
268
|
export function isSpecialType(type: string | undefined): type is SpecialType;
|
|
269
269
|
export type OptionType = typeof SpecialTypes extends Set<infer T> ? T : undefined;
|
|
@@ -142,10 +142,8 @@ export var EntitySelectorNode;
|
|
|
142
142
|
case 'limit':
|
|
143
143
|
case 'sort':
|
|
144
144
|
return selector.currentEntity
|
|
145
|
-
? 2 /* Result.NotApplicable */
|
|
146
|
-
:
|
|
147
|
-
? 1 /* Result.Duplicated */
|
|
148
|
-
: 0 /* Result.Ok */;
|
|
145
|
+
? 2 /* Result.NotApplicable */ : hasKey(key)
|
|
146
|
+
? 1 /* Result.Duplicated */ : 0 /* Result.Ok */;
|
|
149
147
|
case 'type':
|
|
150
148
|
return selector.typeLimited
|
|
151
149
|
? hasKey(key) ? 1 /* Result.Duplicated */ : 2 /* Result.NotApplicable */
|
|
@@ -182,6 +182,13 @@ export const argument = (rawTreeNode, prevNodes) => {
|
|
|
182
182
|
return wrap(team(core.SymbolUsageType.is(treeNode.properties?.usageType)
|
|
183
183
|
? treeNode.properties?.usageType
|
|
184
184
|
: undefined));
|
|
185
|
+
case 'minecraft:team_color':
|
|
186
|
+
return wrap(core.map(commandLiteral({ pool: core.Color.ColorNames }), (res) => ({
|
|
187
|
+
...res,
|
|
188
|
+
color: core.Color.NamedColors.has(res.value)
|
|
189
|
+
? core.Color.fromCompositeRGB(core.Color.NamedColors.get(res.value))
|
|
190
|
+
: undefined,
|
|
191
|
+
})));
|
|
185
192
|
case 'minecraft:template_mirror':
|
|
186
193
|
return wrap(commandLiteral({ pool: MirrorValues }));
|
|
187
194
|
case 'minecraft:template_rotation':
|
|
@@ -255,6 +255,9 @@ export interface MinecraftSwizzleArgumentTreeNode extends mcf.ArgumentTreeNode {
|
|
|
255
255
|
export interface MinecraftTeamArgumentTreeNode extends mcf.ArgumentTreeNode {
|
|
256
256
|
parser: 'minecraft:team';
|
|
257
257
|
}
|
|
258
|
+
export interface MinecraftTeamColorArgumentTreeNode extends mcf.ArgumentTreeNode {
|
|
259
|
+
parser: 'minecraft:team_color';
|
|
260
|
+
}
|
|
258
261
|
export interface MinecraftTemplateMirrorArgumentTreeNode extends mcf.ArgumentTreeNode {
|
|
259
262
|
parser: 'minecraft:template_mirror';
|
|
260
263
|
}
|
|
@@ -280,5 +283,5 @@ export interface SpyglassmcCriterionArgumentTreeNode extends mcf.ArgumentTreeNod
|
|
|
280
283
|
export interface SpyglassmcTagArgumentTreeNode extends mcf.ArgumentTreeNode {
|
|
281
284
|
parser: 'spyglassmc:tag';
|
|
282
285
|
}
|
|
283
|
-
export type ArgumentTreeNode = BrigadierBoolArgumentTreeNode | BrigadierDoubleArgumentTreeNode | BrigadierFloatArgumentTreeNode | BrigadierIntegerArgumentTreeNode | BrigadierLongArgumentTreeNode | BrigadierStringArgumentTreeNode | MinecraftAngleArgumentTreeNode | MinecraftBlockPosArgumentTreeNode | MinecraftBlockPredicateArgumentTreeNode | MinecraftBlockStateArgumentTreeNode | MinecraftColorArgumentTreeNode | MinecraftColumnPosArgumentTreeNode | MinecraftComponentArgumentTreeNode | MinecraftDialogArgumentTreeNode | MinecraftDimensionArgumentTreeNode | MinecraftEntityArgumentTreeNode | MinecraftEntityAnchorArgumentTreeNode | MinecraftEntitySummonArgumentTreeNode | MinecraftFloatRangeArgumentTreeNode | MinecraftFunctionArgumentTreeNode | MinecraftGamemodeArgumentTreeNode | MinecraftGameProfileArgumentTreeNode | MinecraftHeightmapArgumentTreeNode | MinecraftIntRangeArgumentTreeNode | MinecraftItemEnchantmentArgumentTreeNode | MinecraftItemPredicateArgumentTreeNode | MinecraftItemSlotArgumentTreeNode | MinecraftItemSlotsArgumentTreeNode | MinecraftItemStackArgumentTreeNode | MinecraftLootModifierArgumentTreeNode | MinecraftLootPredicateArgumentTreeNode | MinecraftLootTableArgumentTreeNode | MinecraftMessageArgumentTreeNode | MinecraftMobEffectArgumentTreeNode | MinecraftNbtCompoundTagArgumentTreeNode | MinecraftNbtPathArgumentTreeNode | MinecraftNbtTagArgumentTreeNode | MinecraftObjectiveArgumentTreeNode | MinecraftObjectiveCriteriaArgumentTreeNode | MinecraftOperationArgumentTreeNode | MinecraftParticleArgumentTreeNode | MinecraftResourceArgumentTreeNode | MinecraftResourceKeyArgumentTreeNode | MinecraftResourceLocationArgumentTreeNode | MinecraftResourceOrTagArgumentTreeNode | MinecraftResourceOrTagKeyArgumentTreeNode | MinecraftResourceSelectorTreeNode | MinecraftRotationArgumentTreeNode | MinecraftScoreHolderArgumentTreeNode | MinecraftScoreboardSlotArgumentTreeNode | MinecraftStyleArgumentTreeNode | MinecraftSwizzleArgumentTreeNode | MinecraftTeamArgumentTreeNode | MinecraftTemplateMirrorArgumentTreeNode | MinecraftTemplateRotationArgumentTreeNode | MinecraftTimeArgumentTreeNode | MinecraftUuidArgumentTreeNode | MinecraftVec2ArgumentTreeNode | MinecraftVec3ArgumentTreeNode | SpyglassmcCriterionArgumentTreeNode | SpyglassmcTagArgumentTreeNode;
|
|
286
|
+
export type ArgumentTreeNode = BrigadierBoolArgumentTreeNode | BrigadierDoubleArgumentTreeNode | BrigadierFloatArgumentTreeNode | BrigadierIntegerArgumentTreeNode | BrigadierLongArgumentTreeNode | BrigadierStringArgumentTreeNode | MinecraftAngleArgumentTreeNode | MinecraftBlockPosArgumentTreeNode | MinecraftBlockPredicateArgumentTreeNode | MinecraftBlockStateArgumentTreeNode | MinecraftColorArgumentTreeNode | MinecraftColumnPosArgumentTreeNode | MinecraftComponentArgumentTreeNode | MinecraftDialogArgumentTreeNode | MinecraftDimensionArgumentTreeNode | MinecraftEntityArgumentTreeNode | MinecraftEntityAnchorArgumentTreeNode | MinecraftEntitySummonArgumentTreeNode | MinecraftFloatRangeArgumentTreeNode | MinecraftFunctionArgumentTreeNode | MinecraftGamemodeArgumentTreeNode | MinecraftGameProfileArgumentTreeNode | MinecraftHeightmapArgumentTreeNode | MinecraftIntRangeArgumentTreeNode | MinecraftItemEnchantmentArgumentTreeNode | MinecraftItemPredicateArgumentTreeNode | MinecraftItemSlotArgumentTreeNode | MinecraftItemSlotsArgumentTreeNode | MinecraftItemStackArgumentTreeNode | MinecraftLootModifierArgumentTreeNode | MinecraftLootPredicateArgumentTreeNode | MinecraftLootTableArgumentTreeNode | MinecraftMessageArgumentTreeNode | MinecraftMobEffectArgumentTreeNode | MinecraftNbtCompoundTagArgumentTreeNode | MinecraftNbtPathArgumentTreeNode | MinecraftNbtTagArgumentTreeNode | MinecraftObjectiveArgumentTreeNode | MinecraftObjectiveCriteriaArgumentTreeNode | MinecraftOperationArgumentTreeNode | MinecraftParticleArgumentTreeNode | MinecraftResourceArgumentTreeNode | MinecraftResourceKeyArgumentTreeNode | MinecraftResourceLocationArgumentTreeNode | MinecraftResourceOrTagArgumentTreeNode | MinecraftResourceOrTagKeyArgumentTreeNode | MinecraftResourceSelectorTreeNode | MinecraftRotationArgumentTreeNode | MinecraftScoreHolderArgumentTreeNode | MinecraftScoreboardSlotArgumentTreeNode | MinecraftStyleArgumentTreeNode | MinecraftSwizzleArgumentTreeNode | MinecraftTeamArgumentTreeNode | MinecraftTeamColorArgumentTreeNode | MinecraftTemplateMirrorArgumentTreeNode | MinecraftTemplateRotationArgumentTreeNode | MinecraftTimeArgumentTreeNode | MinecraftUuidArgumentTreeNode | MinecraftVec2ArgumentTreeNode | MinecraftVec3ArgumentTreeNode | SpyglassmcCriterionArgumentTreeNode | SpyglassmcTagArgumentTreeNode;
|
|
284
287
|
//# sourceMappingURL=argument.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spyglassmc/java-edition",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.60",
|
|
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 --tag latest --dry-run"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@spyglassmc/core": "0.4.
|
|
21
|
-
"@spyglassmc/json": "0.3.
|
|
20
|
+
"@spyglassmc/core": "0.4.47",
|
|
21
|
+
"@spyglassmc/json": "0.3.51",
|
|
22
22
|
"@spyglassmc/locales": "0.3.24",
|
|
23
|
-
"@spyglassmc/mcfunction": "0.2.
|
|
24
|
-
"@spyglassmc/mcdoc": "0.3.
|
|
25
|
-
"@spyglassmc/nbt": "0.3.
|
|
23
|
+
"@spyglassmc/mcfunction": "0.2.50",
|
|
24
|
+
"@spyglassmc/mcdoc": "0.3.51",
|
|
25
|
+
"@spyglassmc/nbt": "0.3.53"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {},
|
|
28
28
|
"publishConfig": {
|