change-case#paramCase TypeScript Examples

The following examples show how to use change-case#paramCase. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From jsonapi-fractal with MIT License 7 votes vote down vote up
/**
 * Used to change the case (e.g. captalization) of the keys of a object
 *
 * @param originalAttributes
 * @param caseType
 * @param deep
 */
export function changeCase(originalAttributes: AttributesObject, caseType: CaseType, deep = false): AttributesObject {
  const caseTypes: Record<CaseType, CaseFunction> = {
    [CaseType.camelCase]: camelCase,
    [CaseType.snakeCase]: snakeCase,
    [CaseType.kebabCase]: paramCase,
  }

  const caseFunction = caseTypes[caseType]

  if (!caseFunction) {
    throw new Error('Invalid case type: ' + caseType)
  }

  const parsedAttributes: AttributesObject = {}

  for (const key of Object.keys(originalAttributes)) {
    let value = originalAttributes[key]

    if (deep && value) {
      if (Array.isArray(value)) {
        value = value.map((value) => (isObject(value) ? changeCase(value as JsonObject, caseType, deep) : value))
      } else if (isObject(value)) {
        value = changeCase(value as JsonObject, caseType, deep)
      }
    }

    parsedAttributes[caseFunction(key)] = value
  }

  return parsedAttributes
}
Example #2
Source File: index.ts    From graphql-mesh with MIT License 6 votes vote down vote up
NAMING_CONVENTIONS: Record<NamingConventionType, NamingConventionFn> = {
  camelCase,
  capitalCase,
  constantCase,
  dotCase,
  headerCase,
  noCase,
  paramCase,
  pascalCase,
  pathCase,
  sentenceCase,
  snakeCase,
  upperCase,
  lowerCase,
}
Example #3
Source File: run.ts    From design-systems-cli with MIT License 6 votes vote down vote up
/** Determine the destination directory of the templated package. */
function getDestDirectory(
  command: CreationChoice,
  name: string,
  dest?: string
) {
  const pascal = pascalCase(name);
  const kebab = paramCase(name);

  return (
    (command === 'component' &&
      path.join(BASE_DIR, dest ?? 'components', pascal)) ||
    (command === 'package' && path.join(BASE_DIR, dest ?? 'packages', kebab)) ||
    dest ||
    name
  );
}
Example #4
Source File: run.ts    From design-systems-cli with MIT License 6 votes vote down vote up
askName = async (type: CreationChoice, force?: boolean) =>
  prompt({
    type: 'input',
    message: `What's the ${type} name?`,

    /** Validate the user's name input */
    validate: input => {
      if (force) {
        return true;
      }

      if (!input) {
        return 'Name is required';
      }

      if (fs.existsSync(getDestDirectory(type, input))) {
        return 'Name already exists as a directory';
      }

      if (type !== 'system') {
        try {
          const name = `@${monorepoName()}/${paramCase(input)}`;
          execSync(`npm view ${name}`, { stdio: 'ignore' });

          return `Package already exists on the registry: "${name}"`;
        } catch (error) {}
      }

      return true;
    }
  })
Example #5
Source File: FormatHelpers.ts    From modelina with Apache License 2.0 5 votes vote down vote up
/**
   * Transform into a lower cased string with dashes between words.
   * @param {string} value to transform
   * @returns {string}
   */
  static toParamCase = paramCase;
Example #6
Source File: ScanBricksAndTemplates.ts    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
export function ScanBricksAndTemplates({
  storyboard,
  version,
  dependencies,
}: ScanBricksAndTemplatesParams): ScanBricksAndTemplatesResult {
  const processors = scanProcessorsInStoryboard(storyboard);
  const { bricks, customApis } = scanStoryboard(storyboard);
  const templates = scanTemplatesInStoryboard(storyboard);

  const legacyCustomApis: string[] = [];
  const flowApis: string[] = [];

  for (const api of customApis) {
    (api.includes(":") ? flowApis : legacyCustomApis).push(api);
  }

  let contractData: string;
  if (version && storyboard.app) {
    const dependenciesMap = new Map(
      dependencies?.map(({ name, constraint }) => [name, constraint]) ?? []
    );

    const deps: DependContract[] = [];
    for (const api of flowApis) {
      const [contract, v] = api.split(":");
      deps.push({
        type: "contract",
        contract: contract.replace("@", "."),
        version: v,
      });
    }

    for (const brick of bricks) {
      deps.push({
        type: "brick",
        brick,
        version: dependenciesMap.get(`${brick.split(".")[0]}-NB`) ?? "*",
      });
    }

    for (const template of templates) {
      deps.push({
        type: "template",
        template,
        version: dependenciesMap.get(`${template.split(".")[0]}-NT`) ?? "*",
      });
    }

    const contracts: ImplementedContract[] = [
      {
        type: "route",
        path: storyboard.app.homepage,
        version,
        deps,
      },
    ];
    contractData = safeDump(
      { contracts },
      {
        indent: 2,
        schema: JSON_SCHEMA,
        skipInvalid: true,
        noRefs: true,
        noCompatMode: true,
      }
    );
  }

  return {
    apis: mapCustomApisToNameAndNamespace(legacyCustomApis),
    bricks,
    templates,
    processors,
    processorPackages: uniq(
      // The package name should always be the param-case of processor's namespace.
      processors.map((item) => paramCase(item.split(".")[0]))
    ),
    contractData,
  };
}
Example #7
Source File: cssModules.ts    From reskript with MIT License 5 votes vote down vote up
generateScopedStyleName = (name: string, filename: string): string => {
    const hash = hasha(filename + name, {algorithm: 'md5'});
    const basename = path.basename(filename, path.extname(filename));
    const componentName = basename === 'index' ? path.basename(path.dirname(filename)) : basename;
    return `${paramCase(componentName)}-${name}-${hash.slice(0, 5)}`;
}
Example #8
Source File: RelativeCommentsPlugin.ts    From design-systems-cli with MIT License 5 votes vote down vote up
apply(compiler: webpack.Compiler) {
    compiler.hooks.compilation.tap('RelativeCommentsPlugin', compilation => {
      compilation.hooks.optimizeChunkAssets.tap(
        'RelativeCommentsPlugin',
        chunks => {
          chunks.forEach(chunk => {
            const transformList: string[] = chunk.files.filter(
              file => /\.js$/.test(file) && !/^css/.test(file)
            );

            if (!transformList.length) {
              return;
            }

            transformList.forEach(file => {
              /** Normalize the path in a comment */
              const replacePath = (match: string, p1: string) => {
                let newPath = p1;

                if (p1.includes('node_modules')) {
                  newPath = p1
                    .split('node_modules/')[1]
                    .replace(this.options.importName, '.');
                } else if (p1.startsWith('../') && p1.includes('dist/')) {
                  newPath = p1.replace(
                    /\.\.\/([a-zA-Z0-9_-]+)\//,
                    (whole: string, packageName: string) =>
                      `@${monorepoName()}/${paramCase(packageName)}/`.trim()
                  );
                }

                return match.replace(p1, newPath);
              };

              const modifiedSource = compilation.assets[file]
                .source()
                .replace(/\/\/ CONCATENATED MODULE: (\S+)/g, replacePath)
                .replace(/\/\/ EXTERNAL MODULE: (\S+)/g, replacePath)
                .split('\n')
                .filter((p: string) => p.trim() !== '')
                .join('\n');

              // eslint-disable-next-line no-param-reassign
              compilation.assets[file] = new RawSource(modifiedSource);
            });
          });
        }
      );
    });
  }
Example #9
Source File: index.tsx    From devtools-ds with MIT License 5 votes vote down vote up
main = async () => {
  signale.start("Starting devtools-ds project generation..");
  const defaultName = defaultAuthorName();
  const defaultEmail = defaultAuthorEmail();
  try {
    let responses = (await prompt([
      {
        type: "select",
        name: "template",
        message: "What template would you like to use?",
        choices: getTemplates(),
      },
      {
        type: "input",
        name: "projectName",
        message: "What is your devtools project's name?",
        initial: "my-devtools",
      },
      {
        type: "input",
        name: "devName",
        message: "What is your name?",
        initial: defaultName,
      },
      {
        type: "input",
        name: "devEmail",
        message: "What is your email?",
        initial: defaultEmail,
      },
      {
        type: "input",
        name: "projectOrg",
        message: "What will your project's GitHub organization be?",
        initial: paramCase(defaultName),
      },
    ])) as any;

    let { projectName } = responses;
    const projectNameConstant = constantCase(projectName);
    const projectNameCapital = capitalCase(projectName);
    projectName = paramCase(projectName);

    responses = {
      ...responses,
      projectName,
      projectNameCapital,
      projectNameConstant,
      uuid: `{${uuid()}}`,
    };

    signale.success("Recorded responses");
    signale.await(`Loading ${responses.template} template..`);

    const srcPath = getTemplatePath(responses.template);
    const outPath = `${process.cwd()}/${responses.projectName}/`;

    copy(srcPath, outPath, responses, async (err, createdFiles) => {
      if (err) throw err;
      createdFiles.forEach((filePath) =>
        signale.complete(`Created ${filePath}`)
      );

      // Copy assets which may get damaged by the templates
      await reflect({
        src: `${srcPath}/src/assets`,
        dest: `${outPath}/src/assets`,
        recursive: false,
      });

      signale.complete(`Copied assets`);

      signale.success(
        `Navigate into ${responses.projectName}/ to get started!`
      );
    });
  } catch (e) {
    signale.complete("Cancelling template creation");
  }
}
Example #10
Source File: BuildProjectOfTemplates.ts    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export async function BuildProjectOfTemplates({
  appId,
  projectId,
}: BuildProjectOfTemplatesParams): Promise<BuildInfoForProjectOfTemplates> {
  const templatesGraphReq = InstanceGraphApi_traverseGraphV2(
    getBaseGraphParams({
      projectId,
      objectId: MODEL_STORYBOARD_TEMPLATE,
    })
  );

  const snippetsGraphReq = InstanceGraphApi_traverseGraphV2(
    getBaseGraphParams({
      projectId,
      objectId: MODEL_STORYBOARD_SNIPPET,
    })
  );

  const imagesAndFunctionsReq = InstanceApi_getDetail(
    "PROJECT_MICRO_APP",
    projectId,
    {
      fields:
        "imgs.url,imgs.name,functions.name,functions.source,functions.typescript,i18n.name,i18n.zh,i18n.en",
    }
  );

  // Make parallel requests.
  const [templatesResponse, snippetsResponse, projectDetailResponse] =
    await Promise.all([
      templatesGraphReq,
      snippetsGraphReq,
      imagesAndFunctionsReq,
    ]);

  const getThumbnailList = (): ImageFiles["imagesPath"] => {
    return []
      .concat(
        templatesResponse.topic_vertices?.map((item) => item.thumbnail),
        snippetsResponse.topic_vertices?.map((item) => item.thumbnail)
      )
      .filter((item) => item)
      .map((thumbnailUrl: string) => ({
        imageOssPath: thumbnailUrl,
        fileName: getBaseName(thumbnailUrl),
      }));
  };

  const getTransformFilePath = (fileName: string): string => {
    return `${
      window.PUBLIC_ROOT ?? ""
    }bricks/${appId}/${IMAGE_SAVE_FILE_PATH}/${fileName}`;
  };

  const thumbnailList = getThumbnailList();

  const templateTreeList = pipes.graphTree(
    templatesResponse as pipes.GraphData,
    {
      sort: {
        key: "sort",
        order: 1,
      },
    }
  );

  const internalTemplateNames = new Set(
    templateTreeList.map((item) => item.templateId) as string[]
  );

  const templates: CustomTemplate[] = templateTreeList.map<CustomTemplate>(
    (item) => ({
      name: `${appId}.${item.templateId}`,
      proxy: getCleanProxy(item.proxy),
      state: item.state
        ? (safeJSONParse(item.state) as CustomTemplateState[])
        : undefined,
      bricks: replaceWidgetFunctions(
        buildBricks(item.children, {
          appId,
          internalTemplateNames,
        }) as BrickConfInTemplate[],
        appId
      ),
    })
  );

  const snippets: SnippetDefinition[] = pipes
    .graphTree(snippetsResponse as pipes.GraphData, {
      sort: {
        key: "sort",
        order: 1,
      },
    })
    .map((item) => ({
      id: `${appId}.${item.snippetId}`,
      category: item.category,
      subCategory: item.subCategory,
      layerType: item.layerType,
      text: item.text,
      description: item.description,
      thumbnail:
        item.thumbnail &&
        getTransformFilePath(
          thumbnailList.find(
            (thumbnailItem) => thumbnailItem.imageOssPath === item.thumbnail
          ).fileName
        ),
      bricks: buildBricks(item.children, {
        appId,
        internalTemplateNames,
      }),
    }));

  const depMap = new Map<string, string[]>();
  const createStories = (templateItem: pipes.GraphVertex): Story => {
    const getDocContent = (obj: PlainObject, type: DocType): unknown => {
      if (!isObject(obj) || isEmpty(obj)) return;
      const getDefaultValue = (v: unknown): unknown => {
        return v ? v : "-";
      };
      return Object.entries(obj).map(([key, value]) => {
        switch (type) {
          case DocType.properties:
            return {
              name: key,
              type: getDefaultValue(value.type),
              required: getDefaultValue(value.required),
              default: getDefaultValue(value.default),
              description: getDefaultValue(value.description),
            };
          case DocType.events:
            return {
              type: key,
              detail: getDefaultValue(value.detail),
              description: getDefaultValue(value.description),
            };
          case DocType.methods:
            return {
              name: key,
              params: getDefaultValue(value.params),
              description: getDefaultValue(value.description),
            };
          case DocType.slots:
            return {
              name: key,
              description: getDefaultValue(value.description),
            };
        }
      });
    };
    const getInterface = (
      interfaceObj: Record<string, PlainObject>
    ): unknown => {
      if (!interfaceObj) return;
      return Object.entries(interfaceObj).map(([name, interfaceBody]) => ({
        kind: "interface",
        name: name,
        typeParameter: null,
        children: Object.entries(interfaceBody).map(([k, v]) => {
          if (typeof v === "string") {
            return {
              description: "",
              name: k,
              required: false,
              type: v,
            };
          }
          return {
            description: v?.description,
            name: k,
            required: v?.required,
            type: v?.type,
          };
        }),
      }));
    };
    const useWidget: Array<string> = [];
    const walkChildren = (data: pipes.GraphVertex, isParent = true): void => {
      if (!data) return;
      if (Array.isArray(data.children)) {
        data.children.forEach((child: pipes.GraphVertex) =>
          walkChildren(child, false)
        );
      }
      if (
        typeof data.brick === "string" &&
        data.brick.includes("-") &&
        !data.brick.includes(".") &&
        internalTemplateNames &&
        internalTemplateNames.has(data.brick)
      ) {
        data.brick = `${appId}.${data.brick}`;
        if (!isParent) {
          useWidget.push(data.brick);
        }
      }
    };
    walkChildren(templateItem);
    const { thumbnail, ...restTemplateData } = templateItem;
    const storyId = `${appId}.${templateItem.templateId}`;
    const stories = {
      // 基础信息存放
      storyId: storyId,
      category: templateItem.category,
      type: "brick",
      layerType: "widget",
      author: templateItem.creator,
      text: templateItem.text,
      description: templateItem.description,
      isCustomTemplate: true,
      thumbnail:
        thumbnail &&
        getTransformFilePath(
          thumbnailList.find(
            (thumbnailItem) => thumbnailItem.imageOssPath === thumbnail
          ).fileName
        ),
      doc: {
        id: storyId,
        name: storyId,
        dockind: "brick",
        properties: null,
        author: templateItem.creator,
        slots: null,
        history: null,
      },
      conf: [],
      originData: restTemplateData as BuilderCustomTemplateNode,
      useWidget,
    } as Story;
    if (templateItem.proxy) {
      // 如果有代理属性
      const {
        properties,
        events,
        methods,
        slots,
        interfaces,
        examples: conf,
      } = JSON.parse(templateItem.proxy);
      stories.doc = Object.assign(stories.doc, {
        properties: getDocContent(properties, DocType.properties),
        events: getDocContent(events, DocType.events),
        methods: getDocContent(methods, DocType.methods),
        slots: getDocContent(slots, DocType.slots),
        interface: getInterface(interfaces as Record<string, PlainObject>),
      });
      if (Array.isArray(conf)) {
        stories.conf = conf;
      } else if (isObject(conf)) {
        stories.conf = [conf];
      }
      // Allow examples to use `<% IMG.get(...) %>`
      stories.conf = replaceWidgetFunctions(stories.conf, appId);
    }

    depMap.set(storyId, useWidget);

    return stories;
  };

  const stories = templateTreeList.map((templateItem) =>
    createStories(templateItem)
  );

  stories.forEach((storyItem) => {
    if (Array.isArray(storyItem.useWidget)) {
      storyItem.useWidget = storyItem.useWidget.concat(
        getDeepDependencies(storyItem.useWidget, depMap)
      );
    }
  });

  const indexJsContent = getBrickPackageIndexJs({
    appId,
    templates,
    functions: projectDetailResponse.functions as StoryboardFunction[],
    i18n: projectDetailResponse.i18n as I18nNode[],
  });
  const storiesJSONContent = JSON.stringify(stories, null, 2);

  const images: ImageFiles = {
    imagesDir: IMAGE_SAVE_FILE_PATH,
    imagesPath: thumbnailList,
  };

  if (Array.isArray(projectDetailResponse.imgs)) {
    projectDetailResponse.imgs.forEach((file) => {
      images.imagesPath.push({
        imageOssPath: file.url,
        fileName: getBaseName(file.url),
      });
    });
  }

  /** deprecated */
  const replaceImageUrl = (str: string): string => {
    let newStr = str;
    images.imagesPath.forEach((imageItem) => {
      const reg = new RegExp(imageItem.imageOssPath, "g");
      newStr = newStr.replace(reg, getTransformFilePath(imageItem.fileName));
    });
    return newStr;
  };

  const files = [
    {
      path: "dist/bricks.json",
      content: JSON.stringify(
        {
          bricks: templates.map((tpl) => tpl.name),
        },
        null,
        2
      ),
    },
    {
      path: `dist/index.${simpleHash(indexJsContent)}.js`,
      content: replaceImageUrl(indexJsContent),
    },
    {
      path: "dist/stories.json",
      content: replaceImageUrl(storiesJSONContent),
    },
  ];

  if (snippets.length > 0) {
    files.push({
      path: "dist/snippets.json",
      content: JSON.stringify({ snippets }, null, 2),
    });
  }

  const storyboard = {
    meta: {
      customTemplates: templates,
    },
  } as Partial<Storyboard> as Storyboard;

  const dependBricks = scanBricksInStoryboard(storyboard);
  const processors = scanProcessorsInStoryboard(storyboard);
  const dependProcessorPackages = uniq(
    // The package name should always be the param-case of processor's namespace.
    processors.map((item) => paramCase(item.split(".")[0]))
  );

  return {
    files,
    images,
    dependBricks,
    dependProcessorPackages,
  };
}
Example #11
Source File: base.ts    From reskript with MIT License 4 votes vote down vote up
factory: ConfigurationFactory = async entry => {
    const {
        usage,
        cwd,
        srcDirectory,
        hostPackageName,
        mode,
        features,
        buildTarget,
        buildVersion,
        buildTime,
        entries,
        cache = 'persist',
        cacheDirectory,
        projectSettings: {
            build: {
                publicPath,
                thirdParty,
                reportLintErrors,
                style: {
                    extract,
                },
            },
        },
    } = entry;
    const tasks = [
        computeCacheKey(entry),
        Promise.all(Object.values(rules).map(rule => rule(entry))),
        resolve('eslint'),
        resolve('stylelint'),
        resolve('regenerator-runtime'),
    ] as const;
    const [cacheKey, moduleRules, eslintPath, stylelintPath, regeneratorRuntimePath] = await Promise.all(tasks);
    const defines: DefineContext = {
        features,
        mode,
        buildVersion,
        buildTarget,
        buildTime,
        env: process.env,
    };
    const eslintOptions = {
        eslintPath,
        baseConfig: getScriptLintBaseConfig({cwd}),
        exclude: ['node_modules', 'externals'],
        extensions: ['js', 'cjs', 'mjs', 'jsx', 'ts', 'tsx'],
        emitError: true,
        emitWarning: usage === 'devServer',
    };
    const styleLintOptions = {
        stylelintPath,
        config: getStyleLintBaseConfig({cwd}),
        emitErrors: true,
        allowEmptyInput: true,
        failOnError: mode === 'production',
        files: `${srcDirectory}/**/*.{css,less}`,
    };
    const htmlPlugins = thirdParty ? [] : createHtmlPluginInstances(entry);
    const cssOutput = thirdParty ? 'index.css' : '[name].[contenthash].css';
    const plugins = [
        ...htmlPlugins,
        createTransformHtmlPluginInstance(entry),
        (usage === 'build' && extract) && new MiniCssExtractPlugin({filename: cssOutput}),
        new ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en|zh-cn)$/),
        new DefinePlugin(constructDynamicDefines(defines)),
        new InterpolateHTMLPlugin(process.env),
        // @ts-expect-error
        reportLintErrors && usage === 'build' && new ESLintPlugin(eslintOptions),
        reportLintErrors && usage === 'build' && new StyleLintPlugin(styleLintOptions),
    ];

    return {
        mode,
        context: cwd,
        entry: entries.reduce(
            (webpackEntry, appEntry) => {
                const currentWebpackEntry = convertToWebpackEntry(appEntry);
                webpackEntry[appEntry.name] = currentWebpackEntry;
                return webpackEntry;
            },
            {} as EntryObject
        ),
        output: {
            path: path.join(cwd, 'dist', 'assets'),
            filename: '[name].[chunkhash].js',
            publicPath: publicPath || '/assets/',
        },
        module: {
            rules: moduleRules,
        },
        resolve: {
            extensions: ['.js', '.jsx', '.ts', '.tsx'],
            mainFields: ['browser', 'module', 'main'],
            alias: {
                '@': path.join(cwd, srcDirectory),
                ...hostPackageName ? {[hostPackageName]: path.join(cwd, 'src')} : {},
                'regenerator-runtime': path.dirname(regeneratorRuntimePath),
            },
            plugins: [
                new ResolveTypeScriptPlugin(),
            ],
        },
        cache: cache === 'off'
            ? false
            : (
                cache === 'persist'
                    ? {
                        type: 'filesystem',
                        version: cacheKey,
                        cacheDirectory: cacheDirectory ? path.join(cwd, cacheDirectory) : undefined,
                        name: `${paramCase(entry.usage)}-${paramCase(entry.mode)}`,
                    }
                    : {type: 'memory'}
            ),
        snapshot: {
            module: {
                timestamp: usage !== 'build',
                hash: usage === 'build',
            },
            resolve: {
                timestamp: usage !== 'build',
                hash: usage === 'build',
            },
        },
        plugins: compact(plugins),
        optimization: {},
    };
}
Example #12
Source File: run.ts    From design-systems-cli with MIT License 4 votes vote down vote up
/** A plugin to create a completely new system or a new package in a system. */
export default async function run(args: CreateArgs) {
  const command = getCommand(args);

  if (args.listTemplates) {
    logger.info(listTemplates(command, args.template, args.templates));
    return;
  }

  const template = await getTemplatePath(args);
  const skipUnnecessaryPrompts = Boolean(args.name);
  const name = args.name || (await askName(command, args.force));
  const config: TemplateOptions = {
    name,
    authorName:
      (skipUnnecessaryPrompts && defaultAuthorName()) || (await askAuthor()),
    authorEmail:
      (skipUnnecessaryPrompts && defaultAuthorEmail()) || (await askEmail()),
    version: (skipUnnecessaryPrompts && defaultVersion) || (await askVersion()),
    repoUrl:
      ('repo' in args && args.repo) ||
      (skipUnnecessaryPrompts && repo()) ||
      repo() ||
      (await askRepo()),
    monorepoName: monorepoName()
  };
  const pascal = pascalCase(config.name);
  const kebab = paramCase(config.name);
  let destinationDirectory = getDestDirectory(
    command,
    config.name,
    'destination' in args ? args.destination : undefined
  );

  if ('cwd' in args && args.cwd) {
    logger.debug('Creating repo in current working directory...');
    destinationDirectory = '.';
  }

  if ('force' in args && args.force) {
    await fs.remove(destinationDirectory);
  } else if (fs.existsSync(destinationDirectory)) {
    logger.error(
      `Destination directory already exists! '${destinationDirectory}'\n\nRun with --force to ignore`
    );
    process.exit(1);
  }

  logger.debug('Creating templated directory...');
  await copy(template, destinationDirectory, {
    ...config,
    cliVersion,
    title: titleCase(config.name),
    kebab,
    pascal,
    camel: camelCase(config.name)
  });
  logger.debug('Created templated directory!');

  if (command === 'component') {
    logger.success(dedent`\n
      ✨   You made a component  ✨

      ?️   Start developing:

      yarn
      cd ${destinationDirectory}
      yarn dev
    `);
  } else if (command === 'package') {
    logger.success(dedent`\n
      ✨   You made a package  ✨

      ?   Start developing:

      yarn
      cd ${destinationDirectory}
      yarn start
    `);
  } else {
    if ('cwd' in args && !args.cwd) {
      logger.info('Initializing git repo');

      execSync(`cd ${config.name} && git init`);
      execSync(`cd ${config.name} && git remote add origin ${config.repoUrl}`);

      logger.await('Running yarn. This may take a bit...');

      await estimator(
        new Promise<void>((res, rej) => {
          try {
            const isVerbose =
              getLogLevel() === 'debug' || getLogLevel() === 'trace';
            execSync(`cd ${config.name} && yarn`, {
              stdio: isVerbose ? 'inherit' : 'ignore'
            });
            res();
          } catch (error) {
            rej(error);
          }
        }),
        'Installing dependencies',
        72 * 1000 as LogOption
      );
      execSync(
        `cd ${config.name} && git add . && git commit --no-verify -m "Create new design system"`
      );
    }

    logger.success(dedent`\n
      ✨  You made a design system  ✨
        
      ?   Create your first component:
      ${destinationDirectory === '.' ? '' : `\ncd ${destinationDirectory}`}
      yarn run create
    `);
  }
}