@sandstone-mc/mcdoc-ts-generator 0.1.0

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 (46) hide show
  1. package/README.md +15 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +3150 -0
  4. package/dist/index.d.ts +17 -0
  5. package/dist/index.js +3086 -0
  6. package/dist/typegen/compile.d.ts +2 -0
  7. package/dist/typegen/export.d.ts +39 -0
  8. package/dist/typegen/import.d.ts +6 -0
  9. package/dist/typegen/index.d.ts +38 -0
  10. package/dist/typegen/mcdoc/assert.d.ts +427 -0
  11. package/dist/typegen/mcdoc/bind.d.ts +61 -0
  12. package/dist/typegen/mcdoc/complex/dispatcher.d.ts +34 -0
  13. package/dist/typegen/mcdoc/complex/index.d.ts +3 -0
  14. package/dist/typegen/mcdoc/complex/indexed.d.ts +47 -0
  15. package/dist/typegen/mcdoc/complex/template.d.ts +54 -0
  16. package/dist/typegen/mcdoc/dispatcher_symbol.d.ts +58 -0
  17. package/dist/typegen/mcdoc/index.d.ts +425 -0
  18. package/dist/typegen/mcdoc/list/array/byte.d.ts +20 -0
  19. package/dist/typegen/mcdoc/list/array/index.d.ts +3 -0
  20. package/dist/typegen/mcdoc/list/array/int.d.ts +20 -0
  21. package/dist/typegen/mcdoc/list/array/long.d.ts +20 -0
  22. package/dist/typegen/mcdoc/list/index.d.ts +2 -0
  23. package/dist/typegen/mcdoc/list/list.d.ts +66 -0
  24. package/dist/typegen/mcdoc/multi/enum.d.ts +8 -0
  25. package/dist/typegen/mcdoc/multi/index.d.ts +4 -0
  26. package/dist/typegen/mcdoc/multi/struct.d.ts +31 -0
  27. package/dist/typegen/mcdoc/multi/tuple.d.ts +62 -0
  28. package/dist/typegen/mcdoc/multi/union.d.ts +62 -0
  29. package/dist/typegen/mcdoc/primitives/any.d.ts +7 -0
  30. package/dist/typegen/mcdoc/primitives/boolean.d.ts +7 -0
  31. package/dist/typegen/mcdoc/primitives/byte.d.ts +19 -0
  32. package/dist/typegen/mcdoc/primitives/concrete.d.ts +37 -0
  33. package/dist/typegen/mcdoc/primitives/double.d.ts +27 -0
  34. package/dist/typegen/mcdoc/primitives/float.d.ts +19 -0
  35. package/dist/typegen/mcdoc/primitives/index.d.ts +12 -0
  36. package/dist/typegen/mcdoc/primitives/int.d.ts +35 -0
  37. package/dist/typegen/mcdoc/primitives/literal.d.ts +14 -0
  38. package/dist/typegen/mcdoc/primitives/long.d.ts +19 -0
  39. package/dist/typegen/mcdoc/primitives/reference.d.ts +54 -0
  40. package/dist/typegen/mcdoc/primitives/short.d.ts +19 -0
  41. package/dist/typegen/mcdoc/primitives/string.d.ts +28 -0
  42. package/dist/typegen/mcdoc/utils.d.ts +20 -0
  43. package/dist/util/config.d.ts +1 -0
  44. package/dist/util/fetch.d.ts +18 -0
  45. package/dist/util/index.d.ts +22 -0
  46. package/package.json +58 -0
@@ -0,0 +1,2 @@
1
+ import ts from 'typescript';
2
+ export declare function compile_types(nodes: ts.Node[], file?: string): Promise<string>;
@@ -0,0 +1,39 @@
1
+ import ts from 'typescript';
2
+ import { type NonEmptyList } from './mcdoc/utils';
3
+ import type { ResolvedDispatcher, ResolvedRegistry } from '.';
4
+ export declare function export_registry(resolved_registries: Map<string, ResolvedRegistry>): {
5
+ readonly exports: ts.TypeAliasDeclaration[];
6
+ readonly paths: Set<string>;
7
+ } | {
8
+ readonly imports: {
9
+ readonly ordered: NonEmptyList<string>;
10
+ readonly check: Map<string, number>;
11
+ };
12
+ readonly exports: ts.TypeAliasDeclaration[];
13
+ readonly paths: Set<string>;
14
+ };
15
+ /**
16
+ * Generates a `Dispatcher` type system with type-safe generic enforcement.
17
+ *
18
+ * Example output:
19
+ * ```ts
20
+ * interface DispatcherRequiredArgs {
21
+ * 'minecraft:data_component': []
22
+ * 'minecraft:entity_effect': [unknown]
23
+ * }
24
+ * type DefaultArgs<R extends keyof DispatcherRequiredArgs> = ...
25
+ * type ApplyDispatcher<R, Args> = ...
26
+ * export type Dispatcher<R, Args> = ApplyDispatcher<R, Args>
27
+ * ```
28
+ */
29
+ export declare function export_dispatcher(resolved_dispatchers: Map<string, ResolvedDispatcher>): {
30
+ readonly exports: ts.TypeAliasDeclaration[];
31
+ readonly paths: Set<string>;
32
+ } | {
33
+ readonly imports: {
34
+ readonly ordered: NonEmptyList<string>;
35
+ readonly check: Map<string, number>;
36
+ };
37
+ readonly exports: ts.TypeAliasDeclaration[];
38
+ readonly paths: Set<string>;
39
+ };
@@ -0,0 +1,6 @@
1
+ import ts from 'typescript';
2
+ import type { NonEmptyList } from './mcdoc/utils';
3
+ export declare function handle_imports(imports?: {
4
+ readonly ordered: NonEmptyList<string>;
5
+ readonly check: Map<string, number>;
6
+ }): ts.ImportDeclaration[];
@@ -0,0 +1,38 @@
1
+ import { type SymbolUtil } from '@spyglassmc/core';
2
+ import ts from 'typescript';
3
+ import { type TypeHandlerResult } from './mcdoc';
4
+ import { Set } from './mcdoc/utils';
5
+ export type ResolvedSymbol = {
6
+ readonly paths: Set<string>;
7
+ readonly imports?: NonNullable<TypeHandlerResult['imports']>;
8
+ readonly exports: (ts.TypeAliasDeclaration | ts.EnumDeclaration | ts.VariableStatement)[];
9
+ };
10
+ export type ResolvedRegistry = {
11
+ import_path: string;
12
+ registry: ts.Identifier;
13
+ };
14
+ export type ResolvedDispatcher = {
15
+ import_path: string;
16
+ type: ts.TypeReferenceNode;
17
+ /**
18
+ * Number of required generic parameters (excluding CASE)
19
+ */
20
+ generic_count: number;
21
+ /**
22
+ * The symbol type name (e.g., "SymbolDataComponent")
23
+ */
24
+ symbol_name: string;
25
+ };
26
+ export declare class TypesGenerator {
27
+ readonly resolved_registries: Map<string, ResolvedRegistry>;
28
+ readonly dispatcher_properties: Map<string, {
29
+ supports_none?: true;
30
+ }>;
31
+ readonly resolved_symbols: Map<string, ResolvedSymbol>;
32
+ readonly resolved_dispatchers: Map<string, ResolvedDispatcher>;
33
+ constructor();
34
+ resolve_types(symbols: SymbolUtil): void;
35
+ private resolve_registry_symbols;
36
+ private resolve_module_symbols;
37
+ private resolve_dispatcher_symbols;
38
+ }
@@ -0,0 +1,427 @@
1
+ import * as mcdoc from '@spyglassmc/mcdoc';
2
+ import { Set } from './utils';
3
+ type ReferenceType = {
4
+ kind: 'reference';
5
+ path: string;
6
+ attributes: never;
7
+ };
8
+ type StringLiteral = Omit<(mcdoc.LiteralType & {
9
+ value: mcdoc.LiteralStringValue;
10
+ }), 'attributes'>;
11
+ /**
12
+ * These Attribute types are based on what actually appears in vanilla-mcdoc to simplify handling, these may need updates in the future.
13
+ */
14
+ type AttributeTreeChildType = ((ReferenceType | (mcdoc.LiteralType & {
15
+ value: mcdoc.LiteralStringValue | mcdoc.LiteralBooleanValue;
16
+ }) | (mcdoc.AttributeTreeValue & {
17
+ values: Record<`${number}`, StringLiteral>;
18
+ })) & {
19
+ attributes: never;
20
+ });
21
+ type AttributeRootValueType = ((mcdoc.DispatcherType | ReferenceType | StringLiteral | (mcdoc.AttributeTreeValue & {
22
+ values: Record<string, AttributeTreeChildType>;
23
+ })) & {
24
+ attributes: never;
25
+ });
26
+ type AttributeType = mcdoc.Attribute & {
27
+ value: AttributeRootValueType;
28
+ };
29
+ type CommandAttributeExtras = {
30
+ empty?: {
31
+ attributes: never;
32
+ kind: 'literal';
33
+ value: {
34
+ attributes: never;
35
+ kind: 'string';
36
+ value: 'allowed';
37
+ };
38
+ };
39
+ max_length?: {
40
+ attributes: never;
41
+ kind: 'literal';
42
+ value: {
43
+ attributes: never;
44
+ kind: 'int';
45
+ value: number;
46
+ };
47
+ };
48
+ incomplete?: {
49
+ attributes: never;
50
+ kind: 'literal';
51
+ value: {
52
+ attributes: never;
53
+ kind: 'string';
54
+ value: 'allowed';
55
+ };
56
+ };
57
+ };
58
+ type ImplementedAttributes = {
59
+ id: (undefined | {
60
+ attributes: never;
61
+ kind: 'literal';
62
+ value: {
63
+ attributes: never;
64
+ kind: 'string';
65
+ value: string;
66
+ };
67
+ } | {
68
+ attributes: never;
69
+ kind: 'tree';
70
+ values: {
71
+ registry: {
72
+ attributes: never;
73
+ kind: 'literal';
74
+ value: {
75
+ attributes: never;
76
+ kind: 'string';
77
+ value: string;
78
+ };
79
+ };
80
+ path?: {
81
+ attributes: never;
82
+ kind: 'literal';
83
+ value: {
84
+ attributes: never;
85
+ kind: 'string';
86
+ value: `${string}/`;
87
+ };
88
+ };
89
+ definition?: {
90
+ attributes: never;
91
+ kind: 'literal';
92
+ value: {
93
+ attributes: never;
94
+ kind: 'boolean';
95
+ value: true;
96
+ };
97
+ };
98
+ exclude?: {
99
+ attributes: never;
100
+ kind: 'tree';
101
+ values: {
102
+ [K in `${number}`]: {
103
+ attributes: never;
104
+ kind: 'literal';
105
+ value: {
106
+ attributes: never;
107
+ kind: 'string';
108
+ value: string;
109
+ };
110
+ };
111
+ };
112
+ };
113
+ tags?: {
114
+ attributes: never;
115
+ kind: 'literal';
116
+ value: {
117
+ attributes: never;
118
+ kind: 'string';
119
+ value: KindType<typeof AssertKinds.RegistryAttributeTagsArgument>;
120
+ };
121
+ };
122
+ empty?: {
123
+ attributes: never;
124
+ kind: 'literal';
125
+ value: {
126
+ attributes: never;
127
+ kind: 'string';
128
+ value: 'allowed';
129
+ };
130
+ };
131
+ prefix?: {
132
+ attributes: never;
133
+ kind: 'literal';
134
+ value: {
135
+ attributes: never;
136
+ kind: 'string';
137
+ value: '!';
138
+ };
139
+ };
140
+ };
141
+ });
142
+ since: {
143
+ attributes: never;
144
+ kind: 'literal';
145
+ value: {
146
+ attributes: never;
147
+ kind: 'string';
148
+ value: `${number}.${number}.${number}`;
149
+ };
150
+ };
151
+ until: {
152
+ attributes: never;
153
+ kind: 'literal';
154
+ value: {
155
+ attributes: never;
156
+ kind: 'string';
157
+ value: `${number}.${number}.${number}`;
158
+ };
159
+ };
160
+ permutation: {
161
+ attributes: never;
162
+ kind: 'tree';
163
+ values: {
164
+ definition: {
165
+ attributes: never;
166
+ kind: 'literal';
167
+ value: {
168
+ kind: 'boolean';
169
+ value: true;
170
+ };
171
+ };
172
+ };
173
+ };
174
+ texture_slot: {
175
+ attributes: never;
176
+ kind: 'tree';
177
+ values: {
178
+ kind: {
179
+ attributes: never;
180
+ kind: 'literal';
181
+ value: {
182
+ attributes: never;
183
+ kind: 'string';
184
+ value: KindType<typeof AssertKinds.TextureSlotAttributeKind>;
185
+ };
186
+ };
187
+ };
188
+ };
189
+ item_slots: undefined;
190
+ tag: undefined;
191
+ team: undefined;
192
+ translation_key: undefined;
193
+ translation_value: undefined;
194
+ crafting_ingredient: (undefined | {
195
+ attributes: never;
196
+ kind: 'tree';
197
+ values: {
198
+ definition: {
199
+ attributes: never;
200
+ kind: 'literal';
201
+ value: {
202
+ attributes: never;
203
+ kind: 'boolean';
204
+ value: true;
205
+ };
206
+ };
207
+ };
208
+ });
209
+ objective: undefined;
210
+ dispatcher_key: {
211
+ attributes: never;
212
+ kind: 'literal';
213
+ value: {
214
+ attributes: never;
215
+ kind: 'string';
216
+ value: `${string}:${string}`;
217
+ };
218
+ };
219
+ regex_pattern: undefined;
220
+ canonical: undefined;
221
+ color: {
222
+ attributes: never;
223
+ kind: 'literal';
224
+ value: {
225
+ attributes: never;
226
+ kind: 'string';
227
+ value: KindType<typeof AssertKinds.ColorAttributeKind>;
228
+ };
229
+ };
230
+ time_pattern: undefined;
231
+ criterion: (undefined | {
232
+ attributes: never;
233
+ kind: 'tree';
234
+ values: {
235
+ definition: {
236
+ attributes: never;
237
+ kind: 'literal';
238
+ value: {
239
+ attributes: never;
240
+ kind: 'boolean';
241
+ value: true;
242
+ };
243
+ };
244
+ };
245
+ });
246
+ nbt: (undefined | mcdoc.DispatcherType | ReferenceType);
247
+ nbt_path: (undefined | mcdoc.DispatcherType);
248
+ match_regex: {
249
+ attributes: never;
250
+ kind: 'literal';
251
+ value: {
252
+ attributes: never;
253
+ kind: 'string';
254
+ value: string;
255
+ };
256
+ };
257
+ deprecated: undefined;
258
+ command: {
259
+ attributes: never;
260
+ kind: 'tree';
261
+ values: (({
262
+ macro: {
263
+ attributes: never;
264
+ kind: 'literal';
265
+ value: {
266
+ attributes: never;
267
+ kind: 'string';
268
+ value: 'implicit' | 'allowed';
269
+ };
270
+ };
271
+ } & CommandAttributeExtras) | ({
272
+ slash: {
273
+ attributes: never;
274
+ kind: 'literal';
275
+ value: {
276
+ attributes: never;
277
+ kind: 'string';
278
+ value: KindType<typeof AssertKinds.CommandAttributeSlashKind>;
279
+ };
280
+ };
281
+ } & CommandAttributeExtras));
282
+ };
283
+ uuid: undefined;
284
+ url: undefined;
285
+ random: undefined;
286
+ divisible_by: {
287
+ attributes: never;
288
+ kind: 'literal';
289
+ value: {
290
+ attributes: never;
291
+ kind: 'int';
292
+ value: number;
293
+ };
294
+ };
295
+ entity: (undefined | {
296
+ attributes: never;
297
+ kind: 'tree';
298
+ values: {
299
+ amount?: {
300
+ attributes: never;
301
+ kind: 'literal';
302
+ value: {
303
+ attributes: never;
304
+ kind: 'string';
305
+ value: 'single' | 'multiple';
306
+ };
307
+ };
308
+ type?: {
309
+ attributes: never;
310
+ kind: 'literal';
311
+ value: {
312
+ attributes: never;
313
+ kind: 'string';
314
+ value: 'entities' | 'players';
315
+ };
316
+ };
317
+ };
318
+ });
319
+ integer: {
320
+ attributes: never;
321
+ kind: 'tree';
322
+ values: {
323
+ min: {
324
+ attributes: never;
325
+ kind: 'literal';
326
+ value: {
327
+ attributes: never;
328
+ kind: 'int';
329
+ value: 1;
330
+ };
331
+ };
332
+ };
333
+ };
334
+ /**
335
+ * This isn't correct, but ICBA
336
+ */
337
+ game_rule: undefined;
338
+ score_holder: undefined;
339
+ vector: {
340
+ attributes: never;
341
+ kind: 'tree';
342
+ values: {
343
+ dimension: {
344
+ attributes: never;
345
+ kind: 'literal';
346
+ value: {
347
+ attributes: never;
348
+ kind: 'int';
349
+ value: 3;
350
+ };
351
+ };
352
+ integer: {
353
+ attributes: never;
354
+ kind: 'literal';
355
+ value: {
356
+ attributes: never;
357
+ kind: 'boolean';
358
+ value: true;
359
+ };
360
+ };
361
+ };
362
+ };
363
+ bitfield: ReferenceType;
364
+ text_component: undefined;
365
+ block_predicate: undefined;
366
+ };
367
+ export type ImplementedAttributeType<KIND extends (keyof ImplementedAttributes | undefined) = undefined> = mcdoc.Attribute & (KIND extends undefined ? ({
368
+ [K in keyof ImplementedAttributes]: ({
369
+ name: K;
370
+ } & (ImplementedAttributes[K] extends undefined ? {} : {
371
+ value: ImplementedAttributes[K];
372
+ }));
373
+ }[keyof ImplementedAttributes]) : (ImplementedAttributes[Extract<KIND, string>] extends undefined ? {
374
+ name: KIND;
375
+ } : (Extract<ImplementedAttributes[Extract<KIND, string>], undefined> extends never ? {
376
+ name: KIND;
377
+ value: ImplementedAttributes[Extract<KIND, string>];
378
+ } : {
379
+ name: KIND;
380
+ value?: NonNullable<ImplementedAttributes[Extract<KIND, string>]>;
381
+ })));
382
+ export type KindType<T> = T extends Set<infer U> ? U : never;
383
+ export declare class AssertKinds {
384
+ static readonly AttributeRootValueKind: Set<"reference" | "literal" | "tree" | "dispatcher">;
385
+ static readonly AttributeTreeChildKind: Set<"reference" | "literal" | "tree">;
386
+ static readonly ImplementedAttributes: Set<"objective" | "score_holder" | "tag" | "team" | "texture_slot" | "translation_key" | "game_rule" | "id" | "since" | "until" | "permutation" | "item_slots" | "translation_value" | "crafting_ingredient" | "dispatcher_key" | "regex_pattern" | "canonical" | "color" | "time_pattern" | "criterion" | "nbt" | "nbt_path" | "match_regex" | "deprecated" | "command" | "uuid" | "url" | "random" | "divisible_by" | "entity" | "integer" | "vector" | "bitfield" | "text_component" | "block_predicate">;
387
+ static readonly RegistryAttributeArgument: Set<"definition" | "registry" | "path" | "exclude" | "tags" | "empty" | "prefix">;
388
+ static readonly RegistryAttributeTagsArgument: Set<"allowed" | "implicit" | "required">;
389
+ static readonly ColorAttributeKind: Set<"particle" | "composite_rgb" | "composite_argb" | "hex_rgb" | "hex_argb" | "dec_rgb" | "dec_rgba" | "named">;
390
+ static readonly CommandAttributeArgument: Set<"empty" | "macro" | "slash" | "incomplete" | "max_length">;
391
+ static readonly CommandAttributeSlashKind: Set<"allowed" | "required" | "chat" | "none">;
392
+ static readonly TextureSlotAttributeKind: Set<"reference" | "value" | "definition">;
393
+ static readonly ArrayKind: Set<"byte_array" | "int_array" | "long_array">;
394
+ static readonly StructKeyKind: Set<"string" | "reference" | "concrete" | "union">;
395
+ static readonly StructSpreadKind: Set<"reference" | "dispatcher" | "concrete" | "union" | "template" | "struct">;
396
+ static readonly NumericKind: Set<string>;
397
+ }
398
+ export declare class Assert {
399
+ static Attributes<IMPLEMENTED extends (undefined | true)>(type: mcdoc.Attribute[], implemented?: IMPLEMENTED): asserts type is (IMPLEMENTED extends true ? ImplementedAttributeType[] : AttributeType[]);
400
+ static DispatcherType(type: mcdoc.McdocType): asserts type is mcdoc.DispatcherType;
401
+ static IndexedType(type: mcdoc.McdocType): asserts type is mcdoc.IndexedType;
402
+ static TemplateType(type: mcdoc.McdocType): asserts type is mcdoc.TemplateType;
403
+ static ArrayType<KIND extends ('byte_array' | 'int_array' | 'long_array' | undefined) = undefined>(type: mcdoc.McdocType): asserts type is (KIND extends undefined ? never : mcdoc.PrimitiveArrayType & {
404
+ kind: KIND;
405
+ });
406
+ static ListType(type: mcdoc.McdocType): asserts type is mcdoc.ListType;
407
+ static EnumType(type: mcdoc.McdocType): asserts type is mcdoc.EnumType;
408
+ static StructType(type: mcdoc.McdocType): asserts type is mcdoc.StructType;
409
+ static StructKeyType(type: mcdoc.McdocType): asserts type is (ReferenceType | mcdoc.ConcreteType | mcdoc.StringType | mcdoc.UnionType);
410
+ static StructSpreadType(type: mcdoc.McdocType): asserts type is (ReferenceType | mcdoc.DispatcherType | mcdoc.ConcreteType | mcdoc.TemplateType | mcdoc.StructType | mcdoc.UnionType);
411
+ static TupleType(type: mcdoc.McdocType): asserts type is mcdoc.TupleType;
412
+ static UnionType(type: mcdoc.McdocType): asserts type is mcdoc.UnionType;
413
+ static KeywordType<KIND extends (mcdoc.KeywordType['kind'] | undefined) = undefined>(type: mcdoc.McdocType): asserts type is (KIND extends undefined ? never : mcdoc.KeywordType & {
414
+ kind: KIND;
415
+ });
416
+ static NumericType<KIND extends (mcdoc.NumericTypeKind | undefined) = undefined>(type: mcdoc.McdocType): asserts type is (KIND extends undefined ? never : mcdoc.NumericType & {
417
+ kind: KIND;
418
+ });
419
+ static ConcreteType(type: mcdoc.McdocType): asserts type is (mcdoc.ConcreteType & {
420
+ child: (ReferenceType | mcdoc.DispatcherType);
421
+ });
422
+ static LiteralType(type: mcdoc.McdocType): asserts type is mcdoc.LiteralType;
423
+ static ReferenceType(type: mcdoc.McdocType): asserts type is ReferenceType;
424
+ static StringType(type: mcdoc.McdocType): asserts type is mcdoc.StringType;
425
+ static ColorStringType(type: KindType<typeof AssertKinds.ColorAttributeKind>): asserts type is ('hex_argb' | 'hex_rgb');
426
+ }
427
+ export {};
@@ -0,0 +1,61 @@
1
+ import ts from 'typescript';
2
+ type NonEmptyList<T> = T[] & {
3
+ 0: T;
4
+ };
5
+ export declare class Bind {
6
+ static NumericLiteral(literal: number): ts.LiteralTypeNode;
7
+ static StringLiteral(literal: string): ts.LiteralTypeNode;
8
+ /**
9
+ * Creates a template literal type that represents a non-empty string.
10
+ * ```ts
11
+ * type NonEmptyString = `${any}${string}` // <-- This type
12
+ * ```
13
+ */
14
+ static readonly NonEmptyString: ts.TemplateLiteralTypeNode;
15
+ /**
16
+ * Creates a template literal type that represents a namespaced identifier.
17
+ * ```ts
18
+ * type Namespaced = `${string}:${string}` // <-- This type
19
+ * ```
20
+ */
21
+ static readonly Namespaced: ts.TemplateLiteralTypeNode;
22
+ /**
23
+ * Creates a mapped type with optional properties.
24
+ *
25
+ * The key type is always wrapped in `Extract<KeyType, string>` for safety.
26
+ *
27
+ * @param key_type - The type to iterate over (will be wrapped in Extract)
28
+ * @param value_type - The type of each property value
29
+ * @param options.key_name - The name of the type parameter (default `'Key'`)
30
+ * @param options.parenthesized - Whether to wrap the result in parentheses (default `true`)
31
+ * @returns A mapped type node: `({ [Key in Extract<KeyType, string>]?: ValueType })`
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // Default usage:
36
+ * Bind.MappedType(keyType, valueType)
37
+ * // Produces: ({ [Key in Extract<KeyType, string>]?: ValueType })
38
+ *
39
+ * // Custom key name, no parentheses:
40
+ * Bind.MappedType(keyType, valueType, { key_name: 'S', parenthesized: false })
41
+ * // Produces: { [S in Extract<KeyType, string>]?: ValueType }
42
+ * ```
43
+ */
44
+ static MappedType(key_type: ts.TypeNode, value_type: ts.TypeNode, options?: {
45
+ key_name?: string;
46
+ parenthesized?: boolean;
47
+ }): ts.MappedTypeNode | ts.ParenthesizedTypeNode;
48
+ /**
49
+ * Creates a TypeScript type that represents an empty object.
50
+ * ```ts
51
+ * type EmptyObject = Record<string, never>
52
+ * ```
53
+ */
54
+ static readonly EmptyObject: ts.TypeReferenceNode;
55
+ static DocPart(doc: string): string[];
56
+ /**
57
+ * https://stackoverflow.com/questions/67575784/typescript-ast-factory-how-to-use-comments
58
+ */
59
+ static Doc<N extends ts.Node>(node: N, docs?: NonEmptyList<string | [string]>): N;
60
+ }
61
+ export {};
@@ -0,0 +1,34 @@
1
+ import ts from 'typescript';
2
+ import * as mcdoc from '@spyglassmc/mcdoc';
3
+ import type { NonEmptyList } from '..';
4
+ /**
5
+ * Handles `dispatcher` types which reference a dispatcher symbol map.
6
+ *
7
+ * A dispatcher type has:
8
+ * - `registry`: The dispatcher identifier (e.g., `minecraft:entity_effect`)
9
+ * - `parallelIndices`: How to look up into the dispatcher (static or dynamic)
10
+ *
11
+ * The generated type references the central Dispatcher type:
12
+ * - Static index: `Dispatcher<'minecraft:entity_effect'>['specific_key']`
13
+ * - Dynamic index: `Dispatcher<'minecraft:entity_effect'>[Key]`
14
+ * - Fallback: `Dispatcher<'minecraft:entity_effect', ['%fallback']>`
15
+ * - None: `Dispatcher<'minecraft:entity_effect', ['%none']>`
16
+ */
17
+ declare function mcdoc_dispatcher(type: mcdoc.McdocType): (args: Record<string, unknown>) => {
18
+ readonly type: ts.TypeNode;
19
+ readonly imports: {
20
+ readonly ordered: NonEmptyList<string>;
21
+ readonly check: Map<string, number>;
22
+ };
23
+ } | {
24
+ readonly child_dispatcher: [parent_count: number, property: string][] & {
25
+ 0: [parent_count: number, property: string];
26
+ };
27
+ readonly type: ts.TypeNode;
28
+ readonly imports: {
29
+ readonly ordered: NonEmptyList<string>;
30
+ readonly check: Map<string, number>;
31
+ };
32
+ };
33
+ export declare const McdocDispatcher: typeof mcdoc_dispatcher;
34
+ export {};
@@ -0,0 +1,3 @@
1
+ export { McdocDispatcher } from './dispatcher';
2
+ export { McdocIndexed } from './indexed';
3
+ export { McdocTemplate } from './template';
@@ -0,0 +1,47 @@
1
+ import * as mcdoc from '@spyglassmc/mcdoc';
2
+ import type { NonEmptyList } from '..';
3
+ /**
4
+ * Handles `indexed` types which access a specific property from a dispatcher type.
5
+ *
6
+ * An indexed type has:
7
+ * - `child`: The type to index into (typically a dispatcher)
8
+ * - `parallelIndices`: The indices to access (static string keys)
9
+ *
10
+ * Example from vanilla-mcdoc:
11
+ * ```mcdoc
12
+ * struct EnvironmentAttributeTrackMap {
13
+ * [#[id="environment_attribute"] string]: minecraft:environment_attribute[[%key]][attribute_track],
14
+ * }
15
+ * ```
16
+ *
17
+ * The `[attribute_track]` is an indexed access into the dispatcher result.
18
+ * This needs to generate:
19
+ * ```ts
20
+ * SymbolEnvironmentAttribute[K]['attribute_track']
21
+ * ```
22
+ *
23
+ * Symbol structure:
24
+ * ```json
25
+ * {"kind":"indexed","child":{"kind":"dispatcher","parallelIndices":[{"kind":"dynamic","accessor":[{"keyword":"key"}]}],"registry":"minecraft:environment_attribute"},"parallelIndices":[{"kind":"static","value":"attribute_track"}]}
26
+ * ```
27
+ *
28
+ * The index keys are passed through to the dispatcher handler via args.
29
+ */
30
+ declare function mcdoc_indexed(type: mcdoc.McdocType): (args: Record<string, unknown>) => {
31
+ readonly type: import("typescript").TypeNode;
32
+ readonly imports: {
33
+ readonly ordered: NonEmptyList<string>;
34
+ readonly check: Map<string, number>;
35
+ };
36
+ } | {
37
+ readonly child_dispatcher: [parent_count: number, property: string][] & {
38
+ 0: [parent_count: number, property: string];
39
+ };
40
+ readonly type: import("typescript").TypeNode;
41
+ readonly imports: {
42
+ readonly ordered: NonEmptyList<string>;
43
+ readonly check: Map<string, number>;
44
+ };
45
+ };
46
+ export declare const McdocIndexed: typeof mcdoc_indexed;
47
+ export {};