From c59c80007aef923d59fee991cbd919efb29c3527 Mon Sep 17 00:00:00 2001 From: p-sw Date: Thu, 6 Jun 2024 22:07:19 +0900 Subject: [PATCH] feat(cli): add configuration and path management functionality This commit introduces configuration and path management functionality in the CLI by adding the helper functions to load and validate configuration. It also provides the logic to retrieve available components from a given registry. Additionally, it exposes these functionalities in public API. --- packages/cli/src/const.ts | 53 ++++++++++++++++++++++++++++ packages/cli/src/helpers/config.ts | 18 ++++++++++ packages/cli/src/helpers/path.ts | 14 ++++++++ packages/cli/src/helpers/registry.ts | 13 +++++++ packages/cli/src/index.ts | 1 + packages/cli/src/public.ts | 7 ++++ 6 files changed, 106 insertions(+) create mode 100644 packages/cli/src/const.ts create mode 100644 packages/cli/src/helpers/config.ts create mode 100644 packages/cli/src/helpers/path.ts create mode 100644 packages/cli/src/helpers/registry.ts create mode 100644 packages/cli/src/public.ts diff --git a/packages/cli/src/const.ts b/packages/cli/src/const.ts new file mode 100644 index 0000000..241225e --- /dev/null +++ b/packages/cli/src/const.ts @@ -0,0 +1,53 @@ +import z from 'zod' + +export const REGISTRY_URL = 'https://ui.psw.kr/registry.json' +export const CONFIG_DEFAULT_PATH = 'pswui.config.js' + +export interface Registry { + base: string + components: Record +} + +export interface Config { + /** + * Path that cli will create a file. + */ + paths?: { + components?: 'src/pswui/components' | string + shared?: 'src/pswui/shared.ts' | string + } + /** + * Absolute path that will used for import in component + */ + import?: { + shared?: '@pswui-shared' | string + } +} +export type ResolvedConfig = { + [k in keyof T]-?: NonNullable extends object ? ResolvedConfig> : T[k] +} + +export const DEFAULT_CONFIG = { + paths: { + components: 'src/pswui/components', + shared: 'src/pswui/shared.ts', + }, + import: { + shared: '@pswui-shared', + }, +} +export const configZod = z.object({ + paths: z + .object({ + components: z.string().optional().default(DEFAULT_CONFIG.paths.components), + shared: z.string().optional().default(DEFAULT_CONFIG.paths.shared), + }) + .optional() + .default(DEFAULT_CONFIG.paths), + import: z + .object({ + shared: z.string().optional().default(DEFAULT_CONFIG.import.shared), + }) + .optional() + .default(DEFAULT_CONFIG.import), +}) diff --git a/packages/cli/src/helpers/config.ts b/packages/cli/src/helpers/config.ts new file mode 100644 index 0000000..8722d29 --- /dev/null +++ b/packages/cli/src/helpers/config.ts @@ -0,0 +1,18 @@ +import {CONFIG_DEFAULT_PATH, DEFAULT_CONFIG, ResolvedConfig} from '../const.js' +import {configZod} from '../const.js' +import {join} from 'node:path' +import {existsSync} from 'node:fs' + +export async function loadConfig(config?: string): Promise { + const configPath = join(process.cwd(), config ?? CONFIG_DEFAULT_PATH) + + if (existsSync(configPath)) { + return (await import(configPath)).default + } else { + return DEFAULT_CONFIG + } +} + +export async function validateConfig(config?: unknown): Promise { + return await configZod.parseAsync(config) +} diff --git a/packages/cli/src/helpers/path.ts b/packages/cli/src/helpers/path.ts new file mode 100644 index 0000000..af04070 --- /dev/null +++ b/packages/cli/src/helpers/path.ts @@ -0,0 +1,14 @@ +import {ResolvedConfig} from '../const.js' +import {readdir} from 'node:fs/promises' +import {existsSync} from 'node:fs' +import {join} from 'node:path' + +export async function getComponentsInstalled(components: string[], config: ResolvedConfig) { + const componentPath = join(process.cwd(), config.paths.components) + if (existsSync(componentPath)) { + const dir = await readdir(componentPath) + return dir.reduce((prev, current) => (components.includes(current) ? [...prev, current] : prev), [] as string[]) + } else { + return [] + } +} diff --git a/packages/cli/src/helpers/registry.ts b/packages/cli/src/helpers/registry.ts new file mode 100644 index 0000000..44cbe88 --- /dev/null +++ b/packages/cli/src/helpers/registry.ts @@ -0,0 +1,13 @@ +import {REGISTRY_URL, Registry} from '../const.js' + +export async function getRegistry(): Promise { + return (await (await fetch(REGISTRY_URL)).json()) as Registry +} + +export async function getAvailableComponentNames(registry: Registry): Promise { + return Object.keys(registry.components) +} + +export async function getComponentURL(registry: Registry, componentName: string): Promise { + return registry.base.replace('{componentName}', registry.components[componentName]) +} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index e32b0b2..9725459 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1 +1,2 @@ export {run} from '@oclif/core' +export * from './public.js' diff --git a/packages/cli/src/public.ts b/packages/cli/src/public.ts new file mode 100644 index 0000000..b63f759 --- /dev/null +++ b/packages/cli/src/public.ts @@ -0,0 +1,7 @@ +import {Config} from './const.js' + +function buildConfig(config: Config): Config { + return config +} + +export {Config, buildConfig}