@optique/core 0.5.0 → 0.6.0-dev.102

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/dist/parser.d.ts CHANGED
@@ -78,6 +78,19 @@ interface Parser<TValue, TState> {
78
78
  * it should return an error message.
79
79
  */
80
80
  complete(state: TState): ValueParserResult<TValue>;
81
+ /**
82
+ * Generates next-step suggestions based on the current context
83
+ * and an optional prefix. This can be used to provide shell completion
84
+ * suggestions or to guide users in constructing valid commands.
85
+ * @param context The context of the parser, which includes the input buffer
86
+ * and the current state.
87
+ * @param prefix A prefix string that can be used to filter suggestions.
88
+ * Can be an empty string if no prefix is provided.
89
+ * @returns An iterable of {@link Suggestion} objects, each containing
90
+ * a suggestion text and an optional description.
91
+ * @since 0.6.0
92
+ */
93
+ suggest(context: ParserContext<TState>, prefix: string): Iterable<Suggestion>;
81
94
  /**
82
95
  * Generates a documentation fragment for this parser, which can be used
83
96
  * to describe the parser's usage, description, and default value.
@@ -113,6 +126,51 @@ interface ParserContext<TState> {
113
126
  */
114
127
  readonly optionsTerminated: boolean;
115
128
  }
129
+ /**
130
+ * Represents a suggestion for command-line completion or guidance.
131
+ * @since 0.6.0
132
+ */
133
+ type Suggestion = {
134
+ /**
135
+ * A literal text suggestion.
136
+ */
137
+ readonly kind: "literal";
138
+ /**
139
+ * The suggestion text that can be used for completion or guidance.
140
+ */
141
+ readonly text: string;
142
+ /**
143
+ * An optional description providing additional context
144
+ * or information about the suggestion.
145
+ */
146
+ readonly description?: Message;
147
+ } | {
148
+ /**
149
+ * A file system completion suggestion that uses native shell completion.
150
+ */
151
+ readonly kind: "file";
152
+ /**
153
+ * The current prefix/pattern for fallback when native completion is unavailable.
154
+ */
155
+ readonly pattern?: string;
156
+ /**
157
+ * The type of file system entries to complete.
158
+ */
159
+ readonly type: "file" | "directory" | "any";
160
+ /**
161
+ * File extensions to filter by (e.g., [".ts", ".js"]).
162
+ */
163
+ readonly extensions?: readonly string[];
164
+ /**
165
+ * Whether to include hidden files (those starting with a dot).
166
+ */
167
+ readonly includeHidden?: boolean;
168
+ /**
169
+ * An optional description providing additional context
170
+ * or information about the suggestion.
171
+ */
172
+ readonly description?: Message;
173
+ };
116
174
  /**
117
175
  * A discriminated union type representing the result of a parser operation.
118
176
  * It can either indicate a successful parse with the next state and context,
@@ -193,6 +251,35 @@ type Result<T> = {
193
251
  * failure.
194
252
  */
195
253
  declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]): Result<T>;
254
+ /**
255
+ * Generates command-line suggestions based on current parsing state.
256
+ * This function processes the input arguments up to the last argument,
257
+ * then calls the parser's suggest method with the remaining prefix.
258
+ * @template T The type of the value produced by the parser.
259
+ * @param parser The {@link Parser} to use for generating suggestions.
260
+ * @param args The array of command-line arguments including the partial
261
+ * argument to complete. The last element is treated as
262
+ * the prefix for suggestions.
263
+ * @returns An array of {@link Suggestion} objects containing completion
264
+ * candidates.
265
+ * @example
266
+ * ```typescript
267
+ * const parser = object({
268
+ * verbose: option("-v", "--verbose"),
269
+ * format: option("-f", "--format", choice(["json", "yaml"]))
270
+ * });
271
+ *
272
+ * // Get suggestions for options starting with "--"
273
+ * const suggestions = suggest(parser, ["--"]);
274
+ * // Returns: [{ text: "--verbose" }, { text: "--format" }]
275
+ *
276
+ * // Get suggestions after parsing some arguments
277
+ * const suggestions2 = suggest(parser, ["-v", "--format="]);
278
+ * // Returns: [{ text: "--format=json" }, { text: "--format=yaml" }]
279
+ * ```
280
+ * @since 0.6.0
281
+ */
282
+ declare function suggest<T>(parser: Parser<T, unknown>, args: readonly [string, ...readonly string[]]): readonly Suggestion[];
196
283
  /**
197
284
  * Generates a documentation page for a parser based on its current state after
198
285
  * attempting to parse the provided arguments. This function is useful for
@@ -228,4 +315,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
228
315
  */
229
316
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
230
317
  //#endregion
231
- export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, DocState, FlagErrorOptions, FlagOptions, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MultipleErrorOptions, MultipleOptions, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
318
+ export { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, DocState, FlagErrorOptions, FlagOptions, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MultipleErrorOptions, MultipleOptions, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OrErrorOptions, OrOptions, Parser, ParserContext, ParserResult, Result, Suggestion, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
package/dist/parser.js CHANGED
@@ -48,6 +48,51 @@ function parse(parser, args) {
48
48
  };
49
49
  }
50
50
  /**
51
+ * Generates command-line suggestions based on current parsing state.
52
+ * This function processes the input arguments up to the last argument,
53
+ * then calls the parser's suggest method with the remaining prefix.
54
+ * @template T The type of the value produced by the parser.
55
+ * @param parser The {@link Parser} to use for generating suggestions.
56
+ * @param args The array of command-line arguments including the partial
57
+ * argument to complete. The last element is treated as
58
+ * the prefix for suggestions.
59
+ * @returns An array of {@link Suggestion} objects containing completion
60
+ * candidates.
61
+ * @example
62
+ * ```typescript
63
+ * const parser = object({
64
+ * verbose: option("-v", "--verbose"),
65
+ * format: option("-f", "--format", choice(["json", "yaml"]))
66
+ * });
67
+ *
68
+ * // Get suggestions for options starting with "--"
69
+ * const suggestions = suggest(parser, ["--"]);
70
+ * // Returns: [{ text: "--verbose" }, { text: "--format" }]
71
+ *
72
+ * // Get suggestions after parsing some arguments
73
+ * const suggestions2 = suggest(parser, ["-v", "--format="]);
74
+ * // Returns: [{ text: "--format=json" }, { text: "--format=yaml" }]
75
+ * ```
76
+ * @since 0.6.0
77
+ */
78
+ function suggest(parser, args) {
79
+ const allButLast = args.slice(0, -1);
80
+ const prefix = args[args.length - 1];
81
+ let context = {
82
+ buffer: allButLast,
83
+ optionsTerminated: false,
84
+ state: parser.initialState
85
+ };
86
+ while (context.buffer.length > 0) {
87
+ const result = parser.parse(context);
88
+ if (!result.success) return Array.from(parser.suggest(context, prefix));
89
+ const previousBuffer = context.buffer;
90
+ context = result.next;
91
+ if (context.buffer.length > 0 && context.buffer.length === previousBuffer.length && context.buffer[0] === previousBuffer[0]) return [];
92
+ }
93
+ return Array.from(parser.suggest(context, prefix));
94
+ }
95
+ /**
51
96
  * Generates a documentation page for a parser based on its current state after
52
97
  * attempting to parse the provided arguments. This function is useful for
53
98
  * creating help documentation that reflects the current parsing context.
@@ -126,4 +171,4 @@ function getDocPage(parser, args = []) {
126
171
  }
127
172
 
128
173
  //#endregion
129
- export { WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
174
+ export { WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, suggest, tuple, withDefault };
@@ -27,6 +27,9 @@ function constant(value) {
27
27
  value: state
28
28
  };
29
29
  },
30
+ suggest(_context, _prefix) {
31
+ return [];
32
+ },
30
33
  getDocFragments(_state, _defaultValue) {
31
34
  return { fragments: [] };
32
35
  }
@@ -199,6 +202,51 @@ function option(...args) {
199
202
  error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(state.error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${state.error}`
200
203
  };
201
204
  },
205
+ suggest(context, prefix) {
206
+ const suggestions = [];
207
+ const equalsIndex = prefix.indexOf("=");
208
+ if (equalsIndex >= 0) {
209
+ const optionPart = prefix.slice(0, equalsIndex);
210
+ const valuePart = prefix.slice(equalsIndex + 1);
211
+ if (optionNames$1.includes(optionPart)) {
212
+ if (valueParser && valueParser.suggest) {
213
+ const valueSuggestions = valueParser.suggest(valuePart);
214
+ for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") suggestions.push({
215
+ kind: "literal",
216
+ text: `${optionPart}=${suggestion.text}`,
217
+ description: suggestion.description
218
+ });
219
+ else suggestions.push({
220
+ kind: "literal",
221
+ text: `${optionPart}=${suggestion.pattern || ""}`,
222
+ description: suggestion.description
223
+ });
224
+ }
225
+ }
226
+ } else {
227
+ if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
228
+ for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
229
+ if (prefix === "-" && optionName$1.length !== 2) continue;
230
+ suggestions.push({
231
+ kind: "literal",
232
+ text: optionName$1
233
+ });
234
+ }
235
+ }
236
+ if (valueParser && valueParser.suggest) {
237
+ let shouldSuggestValues = false;
238
+ if (context.buffer.length > 0) {
239
+ const lastToken = context.buffer[context.buffer.length - 1];
240
+ if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
241
+ } else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
242
+ if (shouldSuggestValues) {
243
+ const valueSuggestions = valueParser.suggest(prefix);
244
+ suggestions.push(...valueSuggestions);
245
+ }
246
+ }
247
+ }
248
+ return suggestions;
249
+ },
202
250
  getDocFragments(_state, defaultValue) {
203
251
  const fragments = [{
204
252
  type: "entry",
@@ -358,6 +406,19 @@ function flag(...args) {
358
406
  error: require_message.message`${require_message.optionNames(optionNames$1)}: ${state.error}`
359
407
  };
360
408
  },
409
+ suggest(_context, prefix) {
410
+ const suggestions = [];
411
+ if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
412
+ for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
413
+ if (prefix === "-" && optionName$1.length !== 2) continue;
414
+ suggestions.push({
415
+ kind: "literal",
416
+ text: optionName$1
417
+ });
418
+ }
419
+ }
420
+ return suggestions;
421
+ },
361
422
  getDocFragments(_state, _defaultValue) {
362
423
  const fragments = [{
363
424
  type: "entry",
@@ -452,6 +513,14 @@ function argument(valueParser, options = {}) {
452
513
  error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(state.error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${state.error}`
453
514
  };
454
515
  },
516
+ suggest(_context, prefix) {
517
+ const suggestions = [];
518
+ if (valueParser.suggest) {
519
+ const valueSuggestions = valueParser.suggest(prefix);
520
+ suggestions.push(...valueSuggestions);
521
+ }
522
+ return suggestions;
523
+ },
455
524
  getDocFragments(_state, defaultValue) {
456
525
  const fragments = [{
457
526
  type: "entry",
@@ -559,6 +628,29 @@ function command(name, parser, options = {}) {
559
628
  error: options.errors?.invalidState ?? require_message.message`Invalid command state during completion.`
560
629
  };
561
630
  },
631
+ suggest(context, prefix) {
632
+ const suggestions = [];
633
+ if (context.state === void 0) {
634
+ if (name.startsWith(prefix)) suggestions.push({
635
+ kind: "literal",
636
+ text: name,
637
+ ...options.description && { description: options.description }
638
+ });
639
+ } else if (context.state[0] === "matched") {
640
+ const innerSuggestions = parser.suggest({
641
+ ...context,
642
+ state: parser.initialState
643
+ }, prefix);
644
+ suggestions.push(...innerSuggestions);
645
+ } else if (context.state[0] === "parsing") {
646
+ const innerSuggestions = parser.suggest({
647
+ ...context,
648
+ state: context.state[1]
649
+ }, prefix);
650
+ suggestions.push(...innerSuggestions);
651
+ }
652
+ return suggestions;
653
+ },
562
654
  getDocFragments(state, defaultValue) {
563
655
  if (state.kind === "unavailable" || typeof state.state === "undefined") return {
564
656
  description: options.description,
@@ -27,6 +27,9 @@ function constant(value) {
27
27
  value: state
28
28
  };
29
29
  },
30
+ suggest(_context, _prefix) {
31
+ return [];
32
+ },
30
33
  getDocFragments(_state, _defaultValue) {
31
34
  return { fragments: [] };
32
35
  }
@@ -199,6 +202,51 @@ function option(...args) {
199
202
  error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(state.error) : options.errors.invalidValue : message`${optionNames(optionNames$1)}: ${state.error}`
200
203
  };
201
204
  },
205
+ suggest(context, prefix) {
206
+ const suggestions = [];
207
+ const equalsIndex = prefix.indexOf("=");
208
+ if (equalsIndex >= 0) {
209
+ const optionPart = prefix.slice(0, equalsIndex);
210
+ const valuePart = prefix.slice(equalsIndex + 1);
211
+ if (optionNames$1.includes(optionPart)) {
212
+ if (valueParser && valueParser.suggest) {
213
+ const valueSuggestions = valueParser.suggest(valuePart);
214
+ for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") suggestions.push({
215
+ kind: "literal",
216
+ text: `${optionPart}=${suggestion.text}`,
217
+ description: suggestion.description
218
+ });
219
+ else suggestions.push({
220
+ kind: "literal",
221
+ text: `${optionPart}=${suggestion.pattern || ""}`,
222
+ description: suggestion.description
223
+ });
224
+ }
225
+ }
226
+ } else {
227
+ if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
228
+ for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
229
+ if (prefix === "-" && optionName$1.length !== 2) continue;
230
+ suggestions.push({
231
+ kind: "literal",
232
+ text: optionName$1
233
+ });
234
+ }
235
+ }
236
+ if (valueParser && valueParser.suggest) {
237
+ let shouldSuggestValues = false;
238
+ if (context.buffer.length > 0) {
239
+ const lastToken = context.buffer[context.buffer.length - 1];
240
+ if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
241
+ } else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
242
+ if (shouldSuggestValues) {
243
+ const valueSuggestions = valueParser.suggest(prefix);
244
+ suggestions.push(...valueSuggestions);
245
+ }
246
+ }
247
+ }
248
+ return suggestions;
249
+ },
202
250
  getDocFragments(_state, defaultValue) {
203
251
  const fragments = [{
204
252
  type: "entry",
@@ -358,6 +406,19 @@ function flag(...args) {
358
406
  error: message`${optionNames(optionNames$1)}: ${state.error}`
359
407
  };
360
408
  },
409
+ suggest(_context, prefix) {
410
+ const suggestions = [];
411
+ if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
412
+ for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
413
+ if (prefix === "-" && optionName$1.length !== 2) continue;
414
+ suggestions.push({
415
+ kind: "literal",
416
+ text: optionName$1
417
+ });
418
+ }
419
+ }
420
+ return suggestions;
421
+ },
361
422
  getDocFragments(_state, _defaultValue) {
362
423
  const fragments = [{
363
424
  type: "entry",
@@ -452,6 +513,14 @@ function argument(valueParser, options = {}) {
452
513
  error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(state.error) : options.errors.invalidValue : message`${metavar(valueParser.metavar)}: ${state.error}`
453
514
  };
454
515
  },
516
+ suggest(_context, prefix) {
517
+ const suggestions = [];
518
+ if (valueParser.suggest) {
519
+ const valueSuggestions = valueParser.suggest(prefix);
520
+ suggestions.push(...valueSuggestions);
521
+ }
522
+ return suggestions;
523
+ },
455
524
  getDocFragments(_state, defaultValue) {
456
525
  const fragments = [{
457
526
  type: "entry",
@@ -559,6 +628,29 @@ function command(name, parser, options = {}) {
559
628
  error: options.errors?.invalidState ?? message`Invalid command state during completion.`
560
629
  };
561
630
  },
631
+ suggest(context, prefix) {
632
+ const suggestions = [];
633
+ if (context.state === void 0) {
634
+ if (name.startsWith(prefix)) suggestions.push({
635
+ kind: "literal",
636
+ text: name,
637
+ ...options.description && { description: options.description }
638
+ });
639
+ } else if (context.state[0] === "matched") {
640
+ const innerSuggestions = parser.suggest({
641
+ ...context,
642
+ state: parser.initialState
643
+ }, prefix);
644
+ suggestions.push(...innerSuggestions);
645
+ } else if (context.state[0] === "parsing") {
646
+ const innerSuggestions = parser.suggest({
647
+ ...context,
648
+ state: context.state[1]
649
+ }, prefix);
650
+ suggestions.push(...innerSuggestions);
651
+ }
652
+ return suggestions;
653
+ },
562
654
  getDocFragments(state, defaultValue) {
563
655
  if (state.kind === "unavailable" || typeof state.state === "undefined") return {
564
656
  description: options.description,
@@ -39,6 +39,16 @@ function choice(values, options = {}) {
39
39
  },
40
40
  format(value) {
41
41
  return value;
42
+ },
43
+ suggest(prefix) {
44
+ const normalizedPrefix = options.caseInsensitive ? prefix.toLowerCase() : prefix;
45
+ return values.filter((value) => {
46
+ const normalizedValue = options.caseInsensitive ? value.toLowerCase() : value;
47
+ return normalizedValue.startsWith(normalizedPrefix);
48
+ }).map((value) => ({
49
+ kind: "literal",
50
+ text: value
51
+ }));
42
52
  }
43
53
  };
44
54
  }
@@ -236,6 +246,15 @@ function url(options = {}) {
236
246
  },
237
247
  format(value) {
238
248
  return value.href;
249
+ },
250
+ *suggest(prefix) {
251
+ if (allowedProtocols && prefix.length > 0 && !prefix.includes("://")) for (const protocol of allowedProtocols) {
252
+ const cleanProtocol = protocol.replace(/:+$/, "");
253
+ if (cleanProtocol.startsWith(prefix.toLowerCase())) yield {
254
+ kind: "literal",
255
+ text: `${cleanProtocol}://`
256
+ };
257
+ }
239
258
  }
240
259
  };
241
260
  }
@@ -270,6 +289,236 @@ function locale(options = {}) {
270
289
  },
271
290
  format(value) {
272
291
  return value.baseName;
292
+ },
293
+ *suggest(prefix) {
294
+ const commonLocales = [
295
+ "en",
296
+ "en-US",
297
+ "en-GB",
298
+ "en-CA",
299
+ "en-AU",
300
+ "en-NZ",
301
+ "en-IE",
302
+ "en-ZA",
303
+ "en-IN",
304
+ "es",
305
+ "es-ES",
306
+ "es-MX",
307
+ "es-AR",
308
+ "es-CL",
309
+ "es-CO",
310
+ "es-PE",
311
+ "es-VE",
312
+ "es-EC",
313
+ "es-GT",
314
+ "es-CU",
315
+ "es-BO",
316
+ "es-DO",
317
+ "es-HN",
318
+ "es-PY",
319
+ "es-SV",
320
+ "es-NI",
321
+ "es-CR",
322
+ "es-PA",
323
+ "es-UY",
324
+ "es-PR",
325
+ "fr",
326
+ "fr-FR",
327
+ "fr-CA",
328
+ "fr-BE",
329
+ "fr-CH",
330
+ "fr-LU",
331
+ "fr-MC",
332
+ "de",
333
+ "de-DE",
334
+ "de-AT",
335
+ "de-CH",
336
+ "de-BE",
337
+ "de-LU",
338
+ "de-LI",
339
+ "it",
340
+ "it-IT",
341
+ "it-CH",
342
+ "it-SM",
343
+ "it-VA",
344
+ "pt",
345
+ "pt-BR",
346
+ "pt-PT",
347
+ "pt-AO",
348
+ "pt-MZ",
349
+ "pt-CV",
350
+ "pt-GW",
351
+ "pt-ST",
352
+ "pt-TL",
353
+ "ru",
354
+ "ru-RU",
355
+ "ru-BY",
356
+ "ru-KZ",
357
+ "ru-KG",
358
+ "ru-MD",
359
+ "uk",
360
+ "uk-UA",
361
+ "be",
362
+ "be-BY",
363
+ "bg",
364
+ "bg-BG",
365
+ "cs",
366
+ "cs-CZ",
367
+ "sk",
368
+ "sk-SK",
369
+ "sl",
370
+ "sl-SI",
371
+ "hr",
372
+ "hr-HR",
373
+ "sr",
374
+ "sr-RS",
375
+ "mk",
376
+ "mk-MK",
377
+ "ja",
378
+ "ja-JP",
379
+ "ko",
380
+ "ko-KR",
381
+ "zh",
382
+ "zh-CN",
383
+ "zh-TW",
384
+ "zh-HK",
385
+ "zh-SG",
386
+ "zh-MO",
387
+ "ar",
388
+ "ar-SA",
389
+ "ar-AE",
390
+ "ar-BH",
391
+ "ar-DZ",
392
+ "ar-EG",
393
+ "ar-IQ",
394
+ "ar-JO",
395
+ "ar-KW",
396
+ "ar-LB",
397
+ "ar-LY",
398
+ "ar-MA",
399
+ "ar-OM",
400
+ "ar-QA",
401
+ "ar-SY",
402
+ "ar-TN",
403
+ "ar-YE",
404
+ "hi",
405
+ "hi-IN",
406
+ "bn",
407
+ "bn-BD",
408
+ "bn-IN",
409
+ "ur",
410
+ "ur-PK",
411
+ "ta",
412
+ "ta-IN",
413
+ "te",
414
+ "te-IN",
415
+ "mr",
416
+ "mr-IN",
417
+ "gu",
418
+ "gu-IN",
419
+ "kn",
420
+ "kn-IN",
421
+ "ml",
422
+ "ml-IN",
423
+ "pa",
424
+ "pa-IN",
425
+ "tr",
426
+ "tr-TR",
427
+ "tr-CY",
428
+ "pl",
429
+ "pl-PL",
430
+ "nl",
431
+ "nl-NL",
432
+ "nl-BE",
433
+ "nl-SR",
434
+ "sv",
435
+ "sv-SE",
436
+ "sv-FI",
437
+ "da",
438
+ "da-DK",
439
+ "no",
440
+ "no-NO",
441
+ "nb",
442
+ "nb-NO",
443
+ "nn",
444
+ "nn-NO",
445
+ "fi",
446
+ "fi-FI",
447
+ "is",
448
+ "is-IS",
449
+ "el",
450
+ "el-GR",
451
+ "el-CY",
452
+ "hu",
453
+ "hu-HU",
454
+ "ro",
455
+ "ro-RO",
456
+ "et",
457
+ "et-EE",
458
+ "lv",
459
+ "lv-LV",
460
+ "lt",
461
+ "lt-LT",
462
+ "mt",
463
+ "mt-MT",
464
+ "ga",
465
+ "ga-IE",
466
+ "cy",
467
+ "cy-GB",
468
+ "eu",
469
+ "eu-ES",
470
+ "ca",
471
+ "ca-ES",
472
+ "ca-AD",
473
+ "th",
474
+ "th-TH",
475
+ "vi",
476
+ "vi-VN",
477
+ "id",
478
+ "id-ID",
479
+ "ms",
480
+ "ms-MY",
481
+ "ms-BN",
482
+ "ms-SG",
483
+ "tl",
484
+ "tl-PH",
485
+ "km",
486
+ "km-KH",
487
+ "my",
488
+ "my-MM",
489
+ "lo",
490
+ "lo-LA",
491
+ "si",
492
+ "si-LK",
493
+ "ne",
494
+ "ne-NP",
495
+ "sw",
496
+ "sw-TZ",
497
+ "sw-KE",
498
+ "am",
499
+ "am-ET",
500
+ "ha",
501
+ "ha-NG",
502
+ "yo",
503
+ "yo-NG",
504
+ "ig",
505
+ "ig-NG",
506
+ "zu",
507
+ "zu-ZA",
508
+ "xh",
509
+ "xh-ZA",
510
+ "af",
511
+ "af-ZA",
512
+ "he",
513
+ "he-IL",
514
+ "fa",
515
+ "fa-IR",
516
+ "fa-AF"
517
+ ];
518
+ for (const locale$1 of commonLocales) if (locale$1.toLowerCase().startsWith(prefix.toLowerCase())) yield {
519
+ kind: "literal",
520
+ text: locale$1
521
+ };
273
522
  }
274
523
  };
275
524
  }