Path: blob/main/extensions/terminal-suggest/src/fig/fig-autocomplete-shared/specMetadata.ts
3520 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Subcommand, convertSubcommand, Initializer } from './convert';6import { makeArray, SpecLocationSource } from './utils';78type FigLoadSpecFn = Fig.LoadSpec extends infer U ? (U extends Function ? U : never) : never;9export type LoadSpec<ArgT = ArgMeta, OptionT = OptionMeta, SubcommandT = SubcommandMeta> =10| Fig.SpecLocation[]11| Subcommand<ArgT, OptionT, SubcommandT>12| ((13...args: Parameters<FigLoadSpecFn>14) => Promise<Fig.SpecLocation[] | Subcommand<ArgT, OptionT, SubcommandT>>);1516export type OptionMeta = Omit<Fig.Option, 'args' | 'name'>;17export type ArgMeta = Omit<Fig.Arg, 'template' | 'generators' | 'loadSpec'> & {18generators: Fig.Generator[];19loadSpec?: LoadSpec<ArgMeta, OptionMeta, SubcommandMeta>;20};2122type SubcommandMetaExcludes =23| 'subcommands'24| 'options'25| 'loadSpec'26| 'persistentOptions'27| 'args'28| 'name';29export type SubcommandMeta = Omit<Fig.Subcommand, SubcommandMetaExcludes> & {30loadSpec?: LoadSpec<ArgMeta, OptionMeta, SubcommandMeta>;31};3233export function convertLoadSpec<ArgT, OptionT, SubcommandT>(34loadSpec: Fig.LoadSpec,35initialize: Initializer<ArgT, OptionT, SubcommandT>36): LoadSpec<ArgT, OptionT, SubcommandT> {37if (typeof loadSpec === 'string') {38return [{ name: loadSpec, type: SpecLocationSource.GLOBAL }];39}4041if (typeof loadSpec === 'function') {42return (...args) =>43loadSpec(...args).then((result) => {44if (Array.isArray(result)) {45return result;46}47if ('type' in result) {48return [result];49}50return convertSubcommand(result, initialize);51});52}5354return convertSubcommand(loadSpec, initialize);55}5657function initializeOptionMeta(option: Fig.Option): OptionMeta {58return option;59}6061// Default initialization functions:62function initializeArgMeta(arg: Fig.Arg): ArgMeta {63const { template, ...rest } = arg;64const generators = template ? [{ template }] : makeArray(arg.generators ?? []);65return {66...rest,67loadSpec: arg.loadSpec68? convertLoadSpec(arg.loadSpec, {69option: initializeOptionMeta,70subcommand: initializeSubcommandMeta,71arg: initializeArgMeta,72})73: undefined,74generators: generators.map((generator) => {75let { trigger, getQueryTerm } = generator;76if (generator.template) {77const templates = makeArray(generator.template);78if (templates.includes('folders') || templates.includes('filepaths')) {79trigger = trigger ?? '/';80getQueryTerm = getQueryTerm ?? '/';81}82}83return { ...generator, trigger, getQueryTerm };84}),85};86}8788function initializeSubcommandMeta(subcommand: Fig.Subcommand): SubcommandMeta {89return {90...subcommand,91loadSpec: subcommand.loadSpec92? convertLoadSpec(subcommand.loadSpec, {93subcommand: initializeSubcommandMeta,94option: initializeOptionMeta,95arg: initializeArgMeta,96})97: undefined,98};99}100101export const initializeDefault: Initializer<ArgMeta, OptionMeta, SubcommandMeta> = {102subcommand: initializeSubcommandMeta,103option: initializeOptionMeta,104arg: initializeArgMeta,105};106107108