@weme-ui/weme-ui 0.2.4 → 0.2.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @weme-ui/weme-ui
2
2
 
3
+ ## 0.2.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [`3c83500`](https://github.com/weme-ui/weme-ui/commit/3c83500f06723b464c6afac2f9c0ea4baa46abd0) Thanks [@moujinet](https://github.com/moujinet)! - 用 oxfmt / oxlint 统一源码格式,不改变运行时行为。
8
+ - Updated dependencies [[`3c83500`](https://github.com/weme-ui/weme-ui/commit/3c83500f06723b464c6afac2f9c0ea4baa46abd0)]:
9
+ - @weme-ui/schema@5.0.1
10
+ - @weme-ui/unocss-preset@0.3.2
11
+
3
12
  ## 0.2.4
4
13
 
5
14
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { n as callWhen, o as randomColor, s as unwrapError, t as Project } from "./project-BZkWl9YJ.js";
1
+ import { n as callWhen, o as randomColor, s as unwrapError, t as Project } from "./project-DgAuYtns.js";
2
2
  import { defineCommand } from "citty";
3
3
  import { resolve } from "node:path/posix";
4
4
  import { cwd, exit } from "node:process";
@@ -32,10 +32,10 @@ var add_default = defineCommand({
32
32
  const kinds = args.kinds.split(",").map((kind) => kind.trim()) || ["file", "doc"];
33
33
  try {
34
34
  const project = new Project(cwd);
35
- if (await project.isInitialized() === false) throw new Error("Project is not initialized");
35
+ if (!await project.isInitialized()) throw new Error("Project is not initialized");
36
36
  let count = 0;
37
37
  const spinner = ora({ text: "Adding items..." }).start();
38
- for (const item of items) await callWhen(await project.hasAddedItem(item) === false, async () => {
38
+ for (const item of items) await callWhen(!await project.hasAddedItem(item), async () => {
39
39
  spinner.text = `Adding ${item}...`;
40
40
  spinner.color = randomColor();
41
41
  if (await project.addItem(item, kinds)) count++;
@@ -53,4 +53,4 @@ var add_default = defineCommand({
53
53
  });
54
54
 
55
55
  export { add_default as default };
56
- //# sourceMappingURL=add-DESSspHh.js.map
56
+ //# sourceMappingURL=add-Cq6lHTUW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-Cq6lHTUW.js","names":[],"sources":["../src/commands/add/index.ts"],"sourcesContent":["// oxlint-disable no-await-in-loop\nimport type { RegistryItemFileKind } from '../../types'\nimport { defineCommand } from 'citty'\nimport { resolve } from 'node:path/posix'\nimport { cwd, exit } from 'node:process'\nimport ora from 'ora'\nimport { callWhen, Project, randomColor, unwrapError } from '../../utils'\n\n/**\n * 添加组件\n */\nexport default defineCommand({\n meta: {\n name: 'add',\n description: 'Add items to your project',\n },\n\n args: {\n cwd: {\n type: 'string',\n description: 'Change working directory to the project root.',\n default: cwd(),\n },\n kinds: {\n type: 'string',\n description: 'The kinds of items to add. Available values: file, doc, example, test',\n default: 'file,doc',\n },\n },\n\n async run({ args }) {\n const items = args._\n\n if (items.length === 0) {\n throw new Error('No items to add')\n }\n\n const cwd = resolve(args.cwd)\n const kinds = (args.kinds.split(',').map((kind) => kind.trim()) || [\n 'file',\n 'doc',\n ]) as RegistryItemFileKind[]\n\n try {\n const project = new Project(cwd)\n\n if (!(await project.isInitialized())) {\n throw new Error('Project is not initialized')\n }\n\n let count = 0\n const spinner = ora({ text: 'Adding items...' }).start()\n\n for (const item of items) {\n await callWhen(!(await project.hasAddedItem(item)), async () => {\n spinner.text = `Adding ${item}...`\n spinner.color = randomColor()\n\n if (await project.addItem(item, kinds)) {\n count++\n }\n })\n }\n\n if (count === 0) {\n spinner.fail('No items added')\n exit(1)\n }\n\n spinner.succeed('Items added successfully')\n } catch (err) {\n console.error(unwrapError(err))\n exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;;;;AAWA,kBAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CAEA,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,SAAS,IAAI;EACf;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,SAAS;EACX;CACF;CAEA,MAAM,IAAI,EAAE,QAAQ;EAClB,MAAM,QAAQ,KAAK;EAEnB,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,MAAM,iBAAiB;EAGnC,MAAM,MAAM,QAAQ,KAAK,GAAG;EAC5B,MAAM,QAAS,KAAK,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,SAAS,KAAK,KAAK,CAAC,KAAK,CACjE,QACA,KACF;EAEA,IAAI;GACF,MAAM,UAAU,IAAI,QAAQ,GAAG;GAE/B,IAAI,CAAE,MAAM,QAAQ,cAAc,GAChC,MAAM,IAAI,MAAM,4BAA4B;GAG9C,IAAI,QAAQ;GACZ,MAAM,UAAU,IAAI,EAAE,MAAM,kBAAkB,CAAC,CAAC,CAAC,MAAM;GAEvD,KAAK,MAAM,QAAQ,OACjB,MAAM,SAAS,CAAE,MAAM,QAAQ,aAAa,IAAI,GAAI,YAAY;IAC9D,QAAQ,OAAO,UAAU,KAAK;IAC9B,QAAQ,QAAQ,YAAY;IAE5B,IAAI,MAAM,QAAQ,QAAQ,MAAM,KAAK,GACnC;GAEJ,CAAC;GAGH,IAAI,UAAU,GAAG;IACf,QAAQ,KAAK,gBAAgB;IAC7B,KAAK,CAAC;GACR;GAEA,QAAQ,QAAQ,0BAA0B;EAC5C,SAAS,KAAK;GACZ,QAAQ,MAAM,YAAY,GAAG,CAAC;GAC9B,KAAK,CAAC;EACR;CACF;AACF,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { defineCommand, runMain } from "citty";
3
3
 
4
4
  // package.json
5
- var version = "0.2.4";
5
+ var version = "0.2.5";
6
6
  var description = "A CLI to manage Weme UI projects.";
7
7
 
8
8
  // src/constants.ts
@@ -17,13 +17,13 @@ const DEFAULT_REGISTRY_BRANCH = "main";
17
17
  const DEFAULT_REGISTRIES = [{ registry: DEFAULT_REGISTRY_NAME }];
18
18
  const DEFAULT_PATHS = {
19
19
  "~": "src",
20
- "component": "~/components",
21
- "composable": "~/composables",
22
- "block": "~/blocks",
23
- "layout": "~/layouts",
24
- "page": "~/pages",
25
- "util": "~/utils",
26
- "theme": "~/themes"
20
+ component: "~/components",
21
+ composable: "~/composables",
22
+ block: "~/blocks",
23
+ layout: "~/layouts",
24
+ page: "~/pages",
25
+ util: "~/utils",
26
+ theme: "~/themes"
27
27
  };
28
28
 
29
29
  // src/cli.ts
@@ -40,14 +40,14 @@ const cli = defineCommand({
40
40
  * @example
41
41
  * ```bunx @weme-ui/weme-ui init```
42
42
  */
43
- init: () => import("./init-DZjeMuf3.js").then((r) => r.default),
43
+ init: () => import("./init-DXWOjwh_.js").then((r) => r.default),
44
44
  /**
45
45
  * 添加组件
46
46
  *
47
47
  * @example
48
48
  * ```bunx @weme-ui/weme-ui add weme-ui/slim/button```
49
49
  */
50
- add: () => import("./add-DESSspHh.js").then((r) => r.default)
50
+ add: () => import("./add-Cq6lHTUW.js").then((r) => r.default)
51
51
  }
52
52
  });
53
53
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../package.json","../src/constants.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["","import type { ProjectAddedRegistry } from './types'\nimport { description, version } from '../package.json'\n\nexport const CLI_NAME = 'weme-cli'\nexport const CLI_VERSION = version\nexport const CLI_DESCRIPTION = description\n\nexport const CLI_TMP_DIR = '.weme'\n\nexport const PROJECT_CONFIG_FILENAME = 'weme.config.json'\nexport const PROJECT_LOCKFILE_FILENAME = 'weme.lock.json'\n\nexport const DEFAULT_REGISTRY_NAME = 'weme-ui/slim'\nexport const DEFAULT_REGISTRY_BRANCH = 'main'\n\nexport const DEFAULT_REGISTRIES: ProjectAddedRegistry[] = [\n { registry: DEFAULT_REGISTRY_NAME },\n]\n\nexport const DEFAULT_PATHS = {\n '~': 'src',\n 'component': '~/components',\n 'composable': '~/composables',\n 'block': '~/blocks',\n 'layout': '~/layouts',\n 'page': '~/pages',\n 'util': '~/utils',\n 'theme': '~/themes',\n} as const\n","import { defineCommand } from 'citty'\nimport { CLI_DESCRIPTION, CLI_NAME, CLI_VERSION } from './constants'\n\nconst cli = defineCommand({\n meta: {\n name: CLI_NAME,\n version: CLI_VERSION,\n description: CLI_DESCRIPTION,\n },\n\n subCommands: {\n /**\n * 初始化项目\n *\n * @example\n * ```bunx @weme-ui/weme-ui init```\n */\n init: () => import('./commands/init').then(r => r.default),\n\n /**\n * 添加组件\n *\n * @example\n * ```bunx @weme-ui/weme-ui add weme-ui/slim/button```\n */\n add: () => import('./commands/add').then(r => r.default),\n },\n})\n\nexport {\n cli,\n}\n","#!/usr/bin/env node\nimport { runMain } from 'citty'\nimport { cli } from './cli'\n\nrunMain(cli)\n"],"mappings":";;;;;;;;ACGA,MAAa,WAAW;AACxB,MAAa,cAAc;AAC3B,MAAa,kBAAkB;AAE/B,MAAa,cAAc;AAE3B,MAAa,0BAA0B;AACvC,MAAa,4BAA4B;AAEzC,MAAa,wBAAwB;AACrC,MAAa,0BAA0B;AAEvC,MAAa,qBAA6C,CACxD,EAAE,UAAU,sBAAsB,CACpC;AAEA,MAAa,gBAAgB;CAC3B,KAAK;CACL,aAAa;CACb,cAAc;CACd,SAAS;CACT,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,SAAS;AACX;;;ACzBA,MAAM,MAAM,cAAc;CACxB,MAAM;EACJ,MAAM;EACN,SAAS;EACT,aAAa;CACf;CAEA,aAAa;;;;;;;EAOX,YAAY,OAAO,qBAAkB,CAAC,MAAK,MAAK,EAAE,OAAO;;;;;;;EAQzD,WAAW,OAAO,oBAAiB,CAAC,MAAK,MAAK,EAAE,OAAO;CACzD;AACF,CAAC;;;ACvBD,QAAQ,GAAG"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../package.json","../src/constants.ts","../src/cli.ts","../src/index.ts"],"sourcesContent":["","import type { ProjectAddedRegistry } from './types'\nimport { description, version } from '../package.json'\n\nexport const CLI_NAME = 'weme-cli'\nexport const CLI_VERSION = version\nexport const CLI_DESCRIPTION = description\n\nexport const CLI_TMP_DIR = '.weme'\n\nexport const PROJECT_CONFIG_FILENAME = 'weme.config.json'\nexport const PROJECT_LOCKFILE_FILENAME = 'weme.lock.json'\n\nexport const DEFAULT_REGISTRY_NAME = 'weme-ui/slim'\nexport const DEFAULT_REGISTRY_BRANCH = 'main'\n\nexport const DEFAULT_REGISTRIES: ProjectAddedRegistry[] = [{ registry: DEFAULT_REGISTRY_NAME }]\n\nexport const DEFAULT_PATHS = {\n '~': 'src',\n component: '~/components',\n composable: '~/composables',\n block: '~/blocks',\n layout: '~/layouts',\n page: '~/pages',\n util: '~/utils',\n theme: '~/themes',\n} as const\n","import { defineCommand } from 'citty'\nimport { CLI_DESCRIPTION, CLI_NAME, CLI_VERSION } from './constants'\n\nconst cli = defineCommand({\n meta: {\n name: CLI_NAME,\n version: CLI_VERSION,\n description: CLI_DESCRIPTION,\n },\n\n subCommands: {\n /**\n * 初始化项目\n *\n * @example\n * ```bunx @weme-ui/weme-ui init```\n */\n init: () => import('./commands/init').then((r) => r.default),\n\n /**\n * 添加组件\n *\n * @example\n * ```bunx @weme-ui/weme-ui add weme-ui/slim/button```\n */\n add: () => import('./commands/add').then((r) => r.default),\n },\n})\n\nexport { cli }\n","#!/usr/bin/env node\nimport { runMain } from 'citty'\nimport { cli } from './cli'\n\nrunMain(cli)\n"],"mappings":";;;;;;;;ACGA,MAAa,WAAW;AACxB,MAAa,cAAc;AAC3B,MAAa,kBAAkB;AAE/B,MAAa,cAAc;AAE3B,MAAa,0BAA0B;AACvC,MAAa,4BAA4B;AAEzC,MAAa,wBAAwB;AACrC,MAAa,0BAA0B;AAEvC,MAAa,qBAA6C,CAAC,EAAE,UAAU,sBAAsB,CAAC;AAE9F,MAAa,gBAAgB;CAC3B,KAAK;CACL,WAAW;CACX,YAAY;CACZ,OAAO;CACP,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;AACT;;;ACvBA,MAAM,MAAM,cAAc;CACxB,MAAM;EACJ,MAAM;EACN,SAAS;EACT,aAAa;CACf;CAEA,aAAa;;;;;;;EAOX,YAAY,OAAO,qBAAkB,CAAC,MAAM,MAAM,EAAE,OAAO;;;;;;;EAQ3D,WAAW,OAAO,oBAAiB,CAAC,MAAM,MAAM,EAAE,OAAO;CAC3D;AACF,CAAC;;;ACvBD,QAAQ,GAAG"}
@@ -1,5 +1,5 @@
1
1
  import { n as DEFAULT_PATHS, o as PROJECT_CONFIG_FILENAME, r as DEFAULT_REGISTRIES, t as CLI_TMP_DIR } from "./index.js";
2
- import { a as parseRepoURL, c as writeFile, i as existsFile, l as useRegistry, n as callWhen, o as randomColor, r as ensureDir, s as unwrapError, t as Project } from "./project-BZkWl9YJ.js";
2
+ import { a as parseRepoURL, c as writeFile, i as existsFile, l as useRegistry, n as callWhen, o as randomColor, r as ensureDir, s as unwrapError, t as Project } from "./project-DgAuYtns.js";
3
3
  import { defineCommand } from "citty";
4
4
  import { dirname, join, resolve } from "node:path/posix";
5
5
  import { cwd, exit } from "node:process";
@@ -204,7 +204,7 @@ var init_default = defineCommand({
204
204
  const onInitItems = await registry.getItems((item) => item.when === "on-init");
205
205
  if (onInitItems.length > 0) for (const item of onInitItems) {
206
206
  const itemName = `${name}/${item.name}`;
207
- if (await project.hasAddedItem(itemName) === false) await project.addItem(itemName);
207
+ if (!await project.hasAddedItem(itemName)) await project.addItem(itemName);
208
208
  }
209
209
  });
210
210
  spinner.succeed("Project initialized successfully");
@@ -216,4 +216,4 @@ var init_default = defineCommand({
216
216
  });
217
217
 
218
218
  export { init_default as default };
219
- //# sourceMappingURL=init-DZjeMuf3.js.map
219
+ //# sourceMappingURL=init-DXWOjwh_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-DXWOjwh_.js","names":[],"sources":["../src/commands/init/config.ts","../src/commands/init/template.ts","../src/commands/init/unocss.ts","../src/commands/init/index.ts"],"sourcesContent":["import { CONFIG_SCHEMA_URL, ProjectConfigSchema } from '@weme-ui/schema'\nimport * as v from 'valibot'\nimport { DEFAULT_PATHS, DEFAULT_REGISTRIES, PROJECT_CONFIG_FILENAME } from '../../constants'\nimport { parseRepoURL, writeFile } from '../../utils'\n\n/**\n * Generate the default config for the project.\n *\n * @param root - The root directory of the project.\n * @returns Whether the default config was generated successfully.\n * @throws If the default config fails to generate.\n */\nexport async function generateDefaultConfig(root: string, repo?: string) {\n const { name } = parseRepoURL(repo)\n\n const registries = repo ? [{ registry: name, repo }] : DEFAULT_REGISTRIES\n\n const schema = v.safeParse(ProjectConfigSchema, {\n $schema: CONFIG_SCHEMA_URL,\n registries,\n paths: DEFAULT_PATHS,\n })\n\n if (!schema.success) {\n throw new Error('Failed to generate default config')\n }\n\n return await writeFile(root, PROJECT_CONFIG_FILENAME, JSON.stringify(schema.output, null, 2))\n}\n","// oxlint-disable no-await-in-loop\nimport { existsSync } from 'node:fs'\nimport { copyFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path/posix'\nimport { x } from 'tinyexec'\nimport { glob } from 'tinyglobby'\nimport { CLI_TMP_DIR } from '../../constants'\nimport { ensureDir, existsFile } from '../../utils'\n\n/**\n * Initialize the project template.\n *\n * @param cwd - The current working directory.\n * @param template - The template to initialize.\n * @throws If the template is not found.\n */\nexport async function initProjectTemplate(cwd: string, template: string = 'vite') {\n const templatePath = join(cwd, CLI_TMP_DIR, 'repository', 'templates', template)\n\n if (!existsSync(templatePath)) {\n throw new Error(`Template ${template} not found`)\n }\n\n const files = await glob('**', { cwd: templatePath, onlyFiles: true })\n\n for (const file of files) {\n const filePath = join(cwd, file)\n const fileDir = dirname(filePath)\n\n if (!existsSync(fileDir)) {\n ensureDir(fileDir)\n }\n\n if (!(await existsFile(cwd, file))) {\n await copyFile(join(templatePath, file), filePath)\n }\n }\n\n // Clean the template repository finally.\n await cleanTemplateRepository(cwd)\n}\n\n/**\n * Clone the template repository.\n *\n * @returns The result of the clone operation.\n * @throws If the clone operation fails.\n */\nexport async function cloneTemplateRepository(cwd: string) {\n const repositoryPath = join(cwd, CLI_TMP_DIR, 'repository')\n\n await cleanTemplateRepository(cwd)\n\n const result = await x('git', [\n 'clone',\n '--depth',\n '1',\n 'https://github.com/weme-ui/weme-ui.git',\n repositoryPath,\n ])\n\n if (result.exitCode !== 0) {\n throw new Error(`Failed to clone template repository: ${result.stderr}`)\n }\n\n return result.stdout\n}\n\n/**\n * Clean the template repository.\n *\n * @param cwd - The current working directory.\n * @returns The result of the clean operation.\n * @throws If the clean operation fails.\n */\nexport async function cleanTemplateRepository(cwd: string) {\n const repositoryPath = join(cwd, CLI_TMP_DIR, 'repository')\n\n if (existsSync(repositoryPath)) {\n await x('rm', ['-rf', repositoryPath])\n }\n}\n","import { join } from 'node:path/posix'\nimport { CLI_TMP_DIR, PROJECT_CONFIG_FILENAME } from '../../constants'\nimport { writeFile } from '../../utils'\n\nconst baseUnoConfig = `import type { Theme } from '@weme-ui/unocss-preset/types'\nimport { defineConfig } from 'unocss'\n\nexport default defineConfig<Theme>({\n // Configure the content pipeline to include *.style.ts files in the project.\n content: {\n pipeline: {\n include: [\n /\\\\.(vue|[jt]sx|style\\\\.[jt]s|vine\\\\.[jt]s|mdx?|astro|elm|php|phtml|html)($|\\\\?)/,\n ],\n },\n },\n})\n`\nconst unoConfig = `import type { ProjectConfigSchema } from '@weme-ui/schema'\nimport type { Theme } from '@weme-ui/unocss-preset/types'\nimport type { InferInput } from 'valibot'\nimport { presetWemeUI } from '@weme-ui/unocss-preset'\nimport { mergeConfigs } from 'unocss'\nimport baseConfig from './${CLI_TMP_DIR}/uno.config'\nimport wemeConfigJson from './${PROJECT_CONFIG_FILENAME}' with { type: 'json' }\n\nconst wemeConfig = wemeConfigJson as InferInput<typeof ProjectConfigSchema>\n\nexport default mergeConfigs<Theme>([\n baseConfig,\n {\n presets: [\n presetWemeUI({\n colors: wemeConfig.unocss?.colors || {},\n cssVars: wemeConfig.unocss?.cssVars || {},\n }),\n ],\n },\n])\n`\n\nexport async function generateDefaultUnoCSSConfigs(root: string) {\n const createdBaseConfig = await writeFile(\n join(root, CLI_TMP_DIR),\n 'uno.config.ts',\n baseUnoConfig.trim(),\n )\n const createdUnoConfig = await writeFile(root, 'uno.config.ts', unoConfig.trim())\n\n return createdBaseConfig && createdUnoConfig\n}\n","// oxlint-disable no-await-in-loop\nimport { defineCommand } from 'citty'\nimport { resolve } from 'node:path/posix'\nimport { cwd, exit } from 'node:process'\nimport { installDependencies } from 'nypm'\nimport ora from 'ora'\nimport { callWhen, parseRepoURL, Project, randomColor, unwrapError, useRegistry } from '../../utils'\nimport { generateDefaultConfig } from './config'\nimport { cloneTemplateRepository, initProjectTemplate } from './template'\nimport { generateDefaultUnoCSSConfigs } from './unocss'\n\n/**\n * 初始化项目\n */\nexport default defineCommand({\n meta: {\n name: 'init',\n description: 'Initialize a new Weme UI project',\n },\n\n args: {\n cwd: {\n type: 'positional',\n description: 'Change working directory to the project root.',\n default: cwd(),\n },\n repo: {\n type: 'string',\n description: 'Specify the registry repository of the project.',\n valueHint: 'weme-ui/slim',\n },\n },\n\n async run({ args }) {\n const cwd = resolve(args.cwd)\n\n try {\n const project = new Project(cwd)\n\n if (await project.isInitialized()) {\n throw new Error('Project already initialized')\n }\n\n const spinner = ora({ text: 'Initializing project...' }).start()\n\n const { name, branch } = parseRepoURL(args.repo)\n\n // 1. Initialize project from clone template repository\n await callWhen(!(await project.hasPackageJson()), async () => {\n spinner.color = randomColor()\n spinner.text = 'Cloning template repository...'\n await cloneTemplateRepository(cwd)\n\n spinner.text = 'Initializing project structure...'\n spinner.color = randomColor()\n await initProjectTemplate(cwd)\n })\n\n // 2. Generate the default project config file\n await callWhen(!(await project.hasProjectConfig()), async () => {\n spinner.text = 'Generating project config file...'\n spinner.color = randomColor()\n await generateDefaultConfig(cwd, args.repo)\n })\n\n // 3. Generate the default UnoCSS config file\n await callWhen(!(await project.hasUnoConfig()), async () => {\n spinner.color = randomColor()\n spinner.text = 'Generating UnoCSS config file...'\n await generateDefaultUnoCSSConfigs(cwd)\n })\n\n // 4. Install dependencies\n await callWhen(await project.hasPackageJson(), async () => {\n spinner.text = 'Install dependencies...'\n spinner.color = randomColor()\n await installDependencies({\n cwd,\n silent: true,\n })\n })\n\n // 5. Add dependencies to the project\n await callWhen(await project.hasPackageJson(), async () => {\n const registry = useRegistry(name, branch)\n\n spinner.text = 'Adding dependencies to the project...'\n spinner.color = randomColor()\n const dependencies = await registry.dependencies()\n if (dependencies.length > 0) {\n await project.addDependencies(dependencies)\n }\n\n spinner.text = 'Adding dev dependencies to the project...'\n spinner.color = randomColor()\n const devDependencies = await registry.devDependencies()\n if (devDependencies.length > 0) {\n await project.addDevDependencies(devDependencies)\n }\n })\n\n // 6. Add `on-init` items to the project\n await callWhen(await project.hasPackageJson(), async () => {\n const registry = useRegistry(name, branch)\n\n spinner.text = 'Adding `on-init` items to the project...'\n spinner.color = randomColor()\n const onInitItems = await registry.getItems((item) => item.when === 'on-init')\n if (onInitItems.length > 0) {\n for (const item of onInitItems) {\n const itemName = `${name}/${item.name}`\n if (!(await project.hasAddedItem(itemName))) {\n await project.addItem(itemName)\n }\n }\n }\n })\n\n spinner.succeed('Project initialized successfully')\n } catch (err) {\n console.error(unwrapError(err))\n exit(1)\n }\n },\n})\n"],"mappings":"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"}
@@ -425,8 +425,8 @@ var Project = class {
425
425
  };
426
426
  lockfile.items.push(...addedItems);
427
427
  const written = await writeFile(join(this.root, CLI_TMP_DIR), PROJECT_LOCKFILE_FILENAME, JSON.stringify(lockfile, null, 2));
428
- const dependencies = items.map((item) => item.dependencies ?? []).flat();
429
- const devDependencies = items.map((item) => item.devDependencies ?? []).flat();
428
+ const dependencies = items.flatMap((item) => item.dependencies ?? []);
429
+ const devDependencies = items.flatMap((item) => item.devDependencies ?? []);
430
430
  if (dependencies.length > 0) await this.addDependencies(dependencies);
431
431
  if (devDependencies.length > 0) await this.addDevDependencies(devDependencies);
432
432
  const cssVariables = items.map((item) => item.cssVars ?? {}).reduce((acc, curr) => defu(acc, curr), {});
@@ -682,4 +682,4 @@ var Project = class {
682
682
  };
683
683
 
684
684
  export { parseRepoURL as a, writeFile as c, existsFile as i, useRegistry as l, callWhen as n, randomColor as o, ensureDir as r, unwrapError as s, Project as t };
685
- //# sourceMappingURL=project-BZkWl9YJ.js.map
685
+ //# sourceMappingURL=project-DgAuYtns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-DgAuYtns.js","names":[],"sources":["../src/utils/fetcher.ts","../src/utils/registry.ts","../src/utils/utilities.ts","../src/utils/project.ts"],"sourcesContent":["import makeFetch from 'make-fetch-happen'\nimport { CLI_TMP_DIR } from '../constants'\n\nconst fetch = makeFetch.defaults({\n cachePath: CLI_TMP_DIR,\n noProxy: ['raw.githubusercontent.com'],\n})\n\n/**\n * Fetch a URL.\n *\n * @param url - The URL to fetch.\n * @returns The text response.\n */\nexport async function fetchURL(url: string) {\n const res = await fetch(url)\n return res.text()\n}\n\n/**\n * Fetch a JSON file.\n *\n * @param url - The URL to fetch.\n * @returns The JSON response.\n */\nexport async function fetchJSON<T>(url: string) {\n const res = await fetch(url)\n return res.json() as Promise<T>\n}\n","import type {\n HashableContent,\n Prettify,\n RegistryConfig,\n RegistryItem,\n RegistryItemFile,\n} from '../types'\nimport { RegistryConfigSchema } from '@weme-ui/schema'\nimport { hash } from 'hasha'\nimport * as v from 'valibot'\nimport { DEFAULT_REGISTRY_BRANCH } from '../constants'\nimport { fetchJSON, fetchURL } from './fetcher'\n\ninterface RegistryMetadata {\n name: RegistryConfig['name']\n description: RegistryConfig['description']\n version: RegistryConfig['version']\n homepage: RegistryConfig['homepage']\n repository: RegistryConfig['repository']\n issues: RegistryConfig['issues']\n contributors: RegistryConfig['contributors']\n access: RegistryConfig['access']\n}\n\ntype ResolvedRegistryItemFile = Prettify<RegistryItemFile & HashableContent>\n\ninterface RegistryCache {\n config: RegistryConfig\n index: ReadonlyMap<string, RegistryItem>\n}\n\nclass Registry {\n /**\n * The name of the registry.\n */\n private name: string\n /**\n * The branch of the registry.\n */\n private branch: string\n /**\n * The cache of the registry.\n */\n private cache: Promise<RegistryCache> | null = null\n\n constructor(name: string, branch: string) {\n this.name = name\n this.branch = branch\n }\n\n /**\n * Get the registry metadata.\n *\n * @returns The registry metadata.\n */\n async metadata(): Promise<RegistryMetadata> {\n const { config } = await this.load()\n\n return {\n name: config.name,\n description: config.description,\n version: config.version,\n homepage: config.homepage,\n repository: config.repository,\n issues: config.issues,\n contributors: config.contributors,\n access: config.access,\n }\n }\n\n /**\n * Get the registry dependencies.\n *\n * @returns The registry dependencies.\n */\n async dependencies(): Promise<string[]> {\n return (await this.load()).config.dependencies ?? []\n }\n\n /**\n * Get the registry dev dependencies.\n *\n * @returns The registry dev dependencies.\n */\n async devDependencies(): Promise<string[]> {\n return (await this.load()).config.devDependencies ?? []\n }\n\n /**\n * Find the items in the registry.\n *\n * @param filter - The filter function.\n * @returns The items that match the filter.\n */\n async getItems(filter?: (item: RegistryItem) => boolean): Promise<RegistryItem[]> {\n const { config, index } = await this.load()\n\n const items = filter ? config.items.filter(filter) : config.items\n const visited = new Set<string>()\n const result: RegistryItem[] = []\n\n const visit = (item: RegistryItem) => {\n if (visited.has(item.name)) return\n visited.add(item.name)\n\n for (const name of item.registryDependencies ?? []) {\n const dep = index.get(name)\n if (!dep) {\n continue\n }\n visit(dep)\n }\n result.push(item)\n }\n\n items.forEach(visit)\n return result\n }\n\n /**\n * Get the files of an item.\n *\n * @param item - The item to get the files from.\n * @returns The resolved files of the item.\n */\n async getItemFiles(item: RegistryItem): Promise<ResolvedRegistryItemFile[]> {\n return await Promise.all(\n item.files.map(async (file) => {\n const result = await this.getItemFileContent(file.path)\n\n return {\n type: file.type,\n kind: file.kind,\n path: file.path,\n target: file.target,\n content: result.content,\n hash: result.hash,\n }\n }),\n )\n }\n\n /**\n * Get the content of a file.\n *\n * @param source - The source of the file.\n * @returns The content of the file.\n */\n async getItemFileContent(source: string): Promise<HashableContent> {\n const url = this.joinURL(source)\n const content = await fetchURL(url)\n const hashStr = await hash(content)\n\n return {\n content,\n hash: hashStr,\n }\n }\n\n /**\n * Load the registry cache.\n *\n * @throws If the registry cache fails to load.\n * @returns The registry cache.\n */\n private async load(): Promise<RegistryCache> {\n this.cache ??= this.fetchRegistryJson().catch((err) => {\n this.cache = null\n throw err\n })\n return this.cache\n }\n\n /**\n * Fetch the registry JSON.\n *\n * @throws If the registry JSON fails to parse.\n * @returns The registry cache.\n */\n private async fetchRegistryJson(): Promise<RegistryCache> {\n const url = this.joinURL('registry.json')\n const raw = await fetchJSON<unknown>(url)\n const parsed = v.safeParse(RegistryConfigSchema, raw)\n\n if (!parsed.success) {\n throw new Error('Failed to parse registry config', { cause: parsed.issues })\n }\n\n const config = parsed.output\n const index = new Map<string, RegistryItem>()\n for (const item of config.items) {\n if (index.has(item.name)) {\n throw new Error(`Duplicate item name: ${item.name}`)\n }\n index.set(item.name, item)\n }\n\n return { config, index }\n }\n\n /**\n * Join the URL with the name and branch.\n *\n * @param path The path to join.\n * @returns The joined URL.\n */\n private joinURL(path: string): string {\n return `https://raw.githubusercontent.com/${this.name}/refs/heads/${this.branch}/${path}`\n }\n}\n\n/**\n * Use the registry.\n *\n * @param name The name of the registry.\n * @param branch The branch of the registry.\n * @returns The registry instance.\n */\nexport function useRegistry(name: string, branch: string = DEFAULT_REGISTRY_BRANCH): Registry {\n return new Registry(name, branch)\n}\n","import { existsSync, mkdirSync } from 'node:fs'\nimport fs from 'node:fs/promises'\nimport { join, resolve } from 'node:path/posix'\nimport { cwd, exit } from 'node:process'\nimport { parseURL } from 'ufo'\nimport { DEFAULT_REGISTRY_BRANCH, DEFAULT_REGISTRY_NAME } from '../constants'\n\n/**\n * Ensure the working directory.\n *\n * @param path - The working directory to ensure.\n * @returns The ensured working directory. If the directory does not exist, it will be created.\n */\nexport function ensureDir(path: string) {\n if (path === cwd()) {\n return path\n }\n\n const resolved = resolve(path)\n\n if (!existsSync(resolved)) {\n mkdirSync(resolved, { recursive: true })\n }\n\n return resolved\n}\n\n/**\n * Check if a file exists.\n *\n * @param root - The root directory of the project.\n * @param filename - The name of the file.\n * @returns Whether the file exists.\n */\nexport async function existsFile(root: string, filename: string) {\n const filePath = resolve(root, filename)\n const exists = existsSync(filePath)\n\n if (!exists) return false\n\n const content = await fs.readFile(filePath, 'utf-8')\n\n return exists && content !== null && content.trim() !== ''\n}\n\n/**\n * Read a file.\n *\n * @param root - The root directory of the project.\n * @param filename - The name of the file.\n * @returns The content of the file. If the file does not exist, it will return `null`.\n */\nexport async function readFile(root: string, filename: string) {\n try {\n if (!(await existsFile(root, filename))) return null\n\n const content = await fs.readFile(join(ensureDir(root), filename), 'utf-8')\n\n if (!content) return null\n\n return content\n } catch {\n return null\n }\n}\n\n/**\n * Write a file.\n *\n * @param root - The root directory of the project.\n * @param filename - The name of the file.\n * @param content - The content of the file.\n * @returns Whether the file was written successfully.\n */\nexport async function writeFile(root: string, filename: string, content: string) {\n try {\n const path = join(ensureDir(root), filename)\n await fs.writeFile(path, `${content}\\n`, { encoding: 'utf-8', flag: 'w' })\n } catch {\n return false\n }\n\n return true\n}\n\n/**\n * Parse a repository URL.\n *\n * @param url - The URL to parse.\n * @returns The parsed repository URL.\n */\nexport function parseRepoURL(url?: string) {\n if (!url) {\n return {\n name: DEFAULT_REGISTRY_NAME,\n branch: DEFAULT_REGISTRY_BRANCH,\n }\n }\n\n const { host, pathname, hash } = parseURL(url)\n if ((host && host !== 'github.com') || !pathname) {\n throw new Error(`Invalid repository URL: ${url}`)\n }\n\n let branch = hash ? hash.replace(/^#/, '') : DEFAULT_REGISTRY_BRANCH\n let name = removeLeadingSlash(pathname)\n if (name.split('/').length !== 2 && name.includes('/tree/')) {\n branch = name.split('/tree/')[1]\n name = name.split('/tree/')[0]\n }\n\n return {\n name,\n branch,\n }\n}\n\n/**\n * Remove the leading slash from a path.\n *\n * @param path - The path to remove the leading slash from.\n * @returns The path without the leading slash.\n */\nexport function removeLeadingSlash(path: string) {\n return path.replace(/^\\//, '')\n}\n\n/**\n * Remove the trailing slash from a path.\n *\n * @param path - The path to remove the trailing slash from.\n * @returns The path without the trailing slash.\n */\nexport function removeTrailingSlash(path: string) {\n return path.replace(/\\/$/, '')\n}\n\n/**\n * Unwrap an error.\n *\n * @param error - The error to unwrap.\n * @returns The unwrapped error.\n */\nexport function unwrapError(error: unknown) {\n return error instanceof Error ? error.message : 'Unknown error'\n}\n\n/**\n * Call a callback when a condition is met.\n *\n * @param condition - The condition to check.\n * @param callback - The callback to call.\n * @param finalizer - The finalizer to call.\n * @returns Whether the callback was called successfully.\n */\nexport async function callWhen<T>(\n condition: boolean,\n callback: () => Promise<T>,\n finalizer?: () => Promise<void>,\n) {\n if (condition) {\n try {\n await callback()\n } catch (e) {\n console.error(unwrapError(e))\n exit(1)\n } finally {\n if (finalizer) {\n await finalizer()\n }\n }\n }\n}\n\ntype RandomColor =\n | 'black'\n | 'red'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'magenta'\n | 'cyan'\n | 'white'\n | 'gray'\n\n/**\n * Generate a random color.\n *\n * @returns The random color.\n */\nexport function randomColor(): RandomColor {\n const colors: RandomColor[] = [\n 'black',\n 'red',\n 'green',\n 'yellow',\n 'blue',\n 'magenta',\n 'cyan',\n 'white',\n 'gray',\n ]\n return colors[Math.floor(Math.random() * colors.length)]\n}\n","// oxlint-disable no-await-in-loop\nimport type {\n CssVariables,\n HashableContent,\n Prettify,\n ProjectAddedItem,\n ProjectAddedItemFile,\n ProjectAddedRegistry,\n ProjectConfig,\n ProjectLockFile,\n ProjectPaths,\n RegistryItemFileKind,\n} from '../types'\nimport { LOCKFILE_SCHEMA_URL, ProjectConfigSchema, ProjectLockFileSchema } from '@weme-ui/schema'\nimport { defu } from 'defu'\nimport { hash } from 'hasha'\nimport { basename, isAbsolute, join, relative, resolve } from 'node:path/posix'\nimport { addDependency } from 'nypm'\nimport * as v from 'valibot'\nimport {\n CLI_TMP_DIR,\n DEFAULT_PATHS,\n DEFAULT_REGISTRIES,\n PROJECT_CONFIG_FILENAME,\n PROJECT_LOCKFILE_FILENAME,\n} from '../constants'\nimport { useRegistry } from './registry'\nimport { existsFile, readFile, removeLeadingSlash, writeFile } from './utilities'\n\ntype ProjectAddedItemMeta = Pick<ProjectAddedItem, 'type' | 'registry' | 'repo' | 'prefix'>\ntype ResolvedProjectAddedItemFile = Prettify<\n ProjectAddedItemMeta & ProjectAddedItemFile & HashableContent\n>\n\ninterface ProjectInfo {\n root: string\n paths: ProjectPaths\n registries: NonNullable<ProjectConfig['registries']>\n defaultRegistry: ProjectAddedRegistry\n}\n\n/**\n * Project management class.\n *\n * @example\n * ```ts\n * const project = new Project(cwd)\n * ```\n *\n * @param root - The root directory of the project.\n * @returns The project instance.\n */\nexport class Project {\n /**\n * The root directory of the project.\n */\n private root: string\n\n constructor(root: string) {\n this.root = root\n }\n\n /**\n * Get the project info.\n *\n * @returns The project info.\n */\n async info(): Promise<ProjectInfo> {\n const config = (await this.hasProjectConfig()) ? await this.loadProjectConfig() : null\n\n return {\n root: this.root,\n paths: this.resolvePaths(config?.paths),\n registries: config?.registries ?? DEFAULT_REGISTRIES,\n defaultRegistry: config?.registries?.[0] ?? DEFAULT_REGISTRIES[0],\n }\n }\n\n /**\n * Add an item to the project.\n *\n * @param name - The name of the item to add.\n * @returns Whether the item was added.\n */\n async addItem(name: string, kinds: RegistryItemFileKind[] = ['file']): Promise<boolean> {\n if (await this.hasAddedItem(name)) {\n return await this.updateItem(name)\n }\n\n const parsed = await this.parseItemName(name)\n const registry = useRegistry(parsed.registry)\n\n const items = await registry.getItems((item) => item.name === parsed.name)\n if (items.length === 0) {\n throw new Error(`Item ${parsed.name} not found in the registry ${parsed.registry}`)\n }\n\n const { paths, registries, defaultRegistry } = await this.info()\n const itemRegistry =\n registries.find((registry) => registry.registry === parsed.registry) ?? defaultRegistry\n\n // #region Add items\n const addedItems: ProjectAddedItem[] = []\n for (const item of items) {\n const files = await registry.getItemFiles(item)\n const addedItem: ProjectAddedItem = {\n name: item.name,\n type: item.type,\n registry: itemRegistry.registry,\n repo: itemRegistry.repo,\n prefix: itemRegistry.prefix,\n files: [],\n }\n\n for (const file of files) {\n if (!kinds.includes(file.kind)) {\n continue\n }\n\n const fileName = basename(file.path)\n const fileDir = paths[file.type] ?? paths['~']\n\n let filePath = fileDir\n\n if (file.type === 'component') {\n filePath = itemRegistry.prefix\n ? join(fileDir, itemRegistry.prefix, item.name)\n : join(fileDir, item.name)\n }\n\n await writeFile(this.joinPath(filePath), fileName, file.content)\n\n addedItem.files.push({\n kind: file.kind,\n source: file.path,\n dest: join(filePath, fileName),\n })\n }\n\n if (addedItem.files.length > 0) {\n addedItems.push(addedItem)\n }\n }\n\n if (addedItems.length === 0) {\n return false\n }\n\n const lockfile = (await this.loadLockfile()) ?? {\n $schema: LOCKFILE_SCHEMA_URL,\n items: [],\n }\n\n lockfile.items.push(...addedItems)\n\n const written = await writeFile(\n join(this.root, CLI_TMP_DIR),\n PROJECT_LOCKFILE_FILENAME,\n JSON.stringify(lockfile, null, 2),\n )\n // #endregion\n\n // #region Add dependencies\n const dependencies = items.flatMap((item) => item.dependencies ?? [])\n const devDependencies = items.flatMap((item) => item.devDependencies ?? [])\n\n if (dependencies.length > 0) {\n await this.addDependencies(dependencies)\n }\n\n if (devDependencies.length > 0) {\n await this.addDevDependencies(devDependencies)\n }\n // #endregion\n\n // #region Add Css Variables\n const cssVariables = items\n .map((item) => item.cssVars ?? {})\n .reduce((acc, curr) => defu(acc, curr), {})\n if (Object.keys(cssVariables).length > 0) {\n await this.addCssVariables(cssVariables)\n }\n // #endregion\n\n return written\n }\n\n /**\n * Update an added item by name in the project.\n *\n * @param name - The name of the item to update.\n * @returns Whether the item was updated.\n */\n async updateItem(name: string): Promise<boolean> {\n void name\n return false\n }\n\n /**\n * Add css variables to the project.\n *\n * @param cssVariables - The css variables to add.\n * @throws If the project config is not found.\n * @throws If the project config is not writable.\n */\n async addCssVariables(cssVariables: CssVariables): Promise<void> {\n const projectConfig = await this.loadProjectConfig()\n\n if (!projectConfig) {\n throw new Error('Project config not found')\n }\n\n projectConfig.unocss = projectConfig.unocss ?? {}\n projectConfig.unocss.cssVars = defu(projectConfig.unocss.cssVars ?? {}, cssVariables)\n\n await writeFile(this.root, PROJECT_CONFIG_FILENAME, JSON.stringify(projectConfig, null, 2))\n }\n\n /**\n * Check if an item was added to the project.\n *\n * @param name - The name of the item to check.\n * @returns Whether the item was added.\n */\n async hasAddedItem(name: string): Promise<boolean> {\n const lockfile = await this.loadLockfile()\n\n if (lockfile) {\n const parsed = await this.parseItemName(name)\n return lockfile.items.some(\n (item) => item.name === parsed.name && item.registry === parsed.registry,\n )\n }\n\n return false\n }\n\n /**\n * Get the files of an added item.\n *\n * @param itemName - The name of the item to get the files from.\n * @returns The resolved files of the item.\n * @throws If the item is not found in the lockfile.\n * @throws If the file is not found in the project.\n */\n async getAddedItemFiles(itemName: string): Promise<ResolvedProjectAddedItemFile[]> {\n const lockfile = await this.loadLockfile()\n\n if (lockfile) {\n const addedItem = lockfile.items.find((item) => item.name === itemName)\n\n if (!addedItem) {\n throw new Error(`Item ${itemName} not found in the lockfile`)\n }\n\n return await Promise.all(\n addedItem.files.map(async (file) => {\n const result = await this.getAddedItemFileContent(file.dest)\n\n return {\n type: addedItem.type,\n registry: addedItem.registry,\n repo: addedItem.repo,\n prefix: addedItem.prefix,\n kind: file.kind,\n source: file.source,\n dest: file.dest,\n content: result.content,\n hash: result.hash,\n }\n }),\n )\n }\n\n return []\n }\n\n /**\n * Get the content of an added item file by filepath.\n *\n * @param filepath - The filepath of the file.\n * @returns The content of the file.\n * @throws If the file is not found in the project.\n */\n async getAddedItemFileContent(filepath: string): Promise<HashableContent> {\n const content = await readFile(this.root, filepath)\n\n if (!content) {\n throw new Error(`File ${filepath} not found in the project`)\n }\n\n const hashStr = await hash(content)\n\n return {\n content,\n hash: hashStr,\n }\n }\n\n /**\n * Add dependencies to the project.\n *\n * @param dependencies - The dependencies to add.\n */\n async addDependencies(dependencies: string[]): Promise<void> {\n await addDependency(dependencies, {\n cwd: this.root,\n silent: true,\n })\n }\n\n /**\n * Add dev dependencies to the project.\n *\n * @param dependencies - The dev dependencies to add.\n */\n async addDevDependencies(dependencies: string[]): Promise<void> {\n await addDependency(dependencies, {\n cwd: this.root,\n silent: true,\n dev: true,\n })\n }\n\n /**\n * Check if the project is initialized.\n *\n * @returns Whether the project is initialized.\n */\n async isInitialized(): Promise<boolean> {\n const checkList = [\n this.joinPath('uno.config.ts'),\n this.joinPath(PROJECT_CONFIG_FILENAME),\n this.joinPath(CLI_TMP_DIR, PROJECT_LOCKFILE_FILENAME),\n this.joinPath('package.json'),\n this.joinPath(CLI_TMP_DIR, 'uno.config.ts'),\n ]\n\n const progress = await Promise.all(\n checkList.map(async (path) => await existsFile(this.root, path)),\n )\n\n return progress.every(Boolean)\n }\n\n /**\n * Check if the project has a package.json file.\n *\n * @returns Whether the project has a package.json file.\n */\n async hasPackageJson(): Promise<boolean> {\n return await existsFile(this.root, 'package.json')\n }\n\n /**\n * Check if the project has a project config file.\n *\n * @returns Whether the project has a project config file.\n */\n async hasProjectConfig(): Promise<boolean> {\n return await existsFile(this.root, PROJECT_CONFIG_FILENAME)\n }\n\n /**\n * Check if the project has a lockfile.\n *\n * @returns Whether the project has a lockfile.\n */\n async hasLockfile(): Promise<boolean> {\n return await existsFile(this.root, join(CLI_TMP_DIR, PROJECT_LOCKFILE_FILENAME))\n }\n\n /**\n * Check if the project has a uno config file.\n *\n * @returns Whether the project has a uno config file.\n */\n async hasUnoConfig(): Promise<boolean> {\n return await existsFile(this.root, join(CLI_TMP_DIR, 'uno.config.ts'))\n }\n\n /**\n * Load the project config file.\n *\n * @returns The loaded project config if it exists, otherwise null.\n */\n private async loadProjectConfig(): Promise<ProjectConfig | null> {\n const content = await readFile(this.root, PROJECT_CONFIG_FILENAME)\n\n if (content) {\n try {\n const configJson = JSON.parse(content)\n const parsed = v.safeParse(ProjectConfigSchema, configJson)\n\n if (parsed.success) {\n return parsed.output\n }\n\n return null\n } catch {}\n }\n\n return null\n }\n\n /**\n * Load the lockfile.\n *\n * @returns The loaded lockfile if it exists, otherwise null.\n */\n private async loadLockfile(): Promise<ProjectLockFile | null> {\n const content = await readFile(join(this.root, CLI_TMP_DIR), PROJECT_LOCKFILE_FILENAME)\n\n if (content) {\n try {\n const lockfileJson = JSON.parse(content)\n const parsed = v.safeParse(ProjectLockFileSchema, lockfileJson)\n\n if (parsed.success) {\n return parsed.output\n }\n } catch {}\n }\n\n return null\n }\n\n /**\n * Resolve project config paths to locations relative to the project root.\n *\n * @param paths - The paths from project config.\n * @returns The resolved paths.\n */\n private resolvePaths(paths?: Partial<ProjectPaths> | null): ProjectPaths {\n const merged = defu(paths ?? {}, DEFAULT_PATHS)\n const alias = this.toProjectRelative(this.root, merged['~'])\n\n return Object.fromEntries(\n Object.entries(merged).map(([key, value]) => [\n key,\n key === '~'\n ? alias\n : this.toProjectRelative(this.root, this.expandTildeAlias(value, alias)),\n ]),\n ) as ProjectPaths\n }\n\n /**\n * Expand a tilde alias.\n *\n * @param value - The value to expand.\n * @param alias - The alias to expand.\n * @returns The expanded value.\n */\n private expandTildeAlias(value: string, alias: string) {\n if (value === '~') {\n return alias\n }\n\n if (value.startsWith('~/')) {\n const rest = value.slice(2)\n return rest ? join(alias, rest) : alias\n }\n\n return value\n }\n\n /**\n * Convert a path to a project relative path.\n *\n * @param root - The project root directory.\n * @param path - The path to convert.\n * @returns The project relative path.\n */\n private toProjectRelative(root: string, path: string) {\n const abs = isAbsolute(path) ? resolve(path) : resolve(root, path)\n\n if (abs === root || abs.startsWith(`${root}/`)) {\n return relative(root, abs) || '.'\n }\n\n return abs\n }\n\n /**\n * Parse the item name.\n *\n * @param input - The item name to parse, format: `<registry>/<item-name>`.\n * @returns The parsed item name.\n */\n private async parseItemName(input: string): Promise<{ registry: string; name: string }> {\n const s = input.trim().replace(/\\/+$/, '')\n const i = s.lastIndexOf('/')\n\n if (i === -1) {\n return {\n registry: (await this.info()).defaultRegistry.registry,\n name: s,\n }\n }\n return {\n registry: s.slice(0, i),\n name: s.slice(i + 1),\n }\n }\n\n /**\n * Join a path to the workplace directory.\n *\n * @param paths - The paths to join.\n * @returns The joined path.\n */\n private joinPath(...paths: string[]) {\n return join(this.root, ...paths.map(removeLeadingSlash))\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,34 +1,35 @@
1
1
  {
2
2
  "name": "@weme-ui/weme-ui",
3
- "type": "module",
4
- "version": "0.2.4",
5
- "packageManager": "bun@1.4.4",
3
+ "version": "0.2.5",
6
4
  "description": "A CLI to manage Weme UI projects.",
7
- "author": "Allen Luo <luoyi@mouji.net>",
8
- "license": "MIT",
5
+ "keywords": [
6
+ "component",
7
+ "nuxt",
8
+ "registry",
9
+ "typescript",
10
+ "vue"
11
+ ],
9
12
  "homepage": "https://mouji.net/weme-ui",
13
+ "bugs": {
14
+ "url": "https://github.com/weme-ui/weme-ui/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "Allen Luo <luoyi@mouji.net>",
10
18
  "repository": {
11
19
  "type": "git",
12
20
  "url": "git+https://github.com/weme-ui/weme-ui.git",
13
21
  "directory": "packages/cli"
14
22
  },
15
- "bugs": {
16
- "url": "https://github.com/weme-ui/weme-ui/issues"
23
+ "bin": {
24
+ "weme-ui": "./dist/index.js"
17
25
  },
18
- "keywords": [
19
- "component",
20
- "registry",
21
- "typescript",
22
- "vue",
23
- "nuxt"
26
+ "files": [
27
+ "!dist/**/*.map",
28
+ "CHANGELOG.md",
29
+ "dist/**/*"
24
30
  ],
31
+ "type": "module",
25
32
  "sideEffects": false,
26
- "exports": {
27
- ".": {
28
- "types": "./dist/index.d.ts",
29
- "import": "./dist/index.js"
30
- }
31
- },
32
33
  "main": "./dist/index.js",
33
34
  "module": "./dist/index.js",
34
35
  "types": "./dist/index.d.ts",
@@ -40,22 +41,16 @@
40
41
  ]
41
42
  }
42
43
  },
43
- "bin": {
44
- "weme-ui": "./dist/index.js"
44
+ "exports": {
45
+ ".": {
46
+ "types": "./dist/index.d.ts",
47
+ "import": "./dist/index.js"
48
+ }
45
49
  },
46
- "files": [
47
- "!dist/**/*.map",
48
- "CHANGELOG.md",
49
- "dist/**/*"
50
- ],
51
50
  "publishConfig": {
52
51
  "access": "public",
53
52
  "provenance": true
54
53
  },
55
- "engines": {
56
- "node": ">=22.14.0",
57
- "bun": ">=1.3.12"
58
- },
59
54
  "scripts": {
60
55
  "build": "NODE_ENV=deploy tsdown",
61
56
  "dev": "NODE_ENV=development tsdown --watch",
@@ -64,22 +59,9 @@
64
59
  "playground": "bun run src/index.ts",
65
60
  "prepack": "bun ../../scripts/materialize-catalog.ts"
66
61
  },
67
- "peerDependencies": {
68
- "nuxt": "^4.0.0",
69
- "valibot": "^1.5.0",
70
- "vue": "^3.0.0"
71
- },
72
- "peerDependenciesMeta": {
73
- "nuxt": {
74
- "optional": true
75
- },
76
- "vue": {
77
- "optional": true
78
- }
79
- },
80
62
  "dependencies": {
81
- "@weme-ui/schema": "^5.0.0",
82
- "@weme-ui/unocss-preset": "^0.3.1",
63
+ "@weme-ui/schema": "^5.0.1",
64
+ "@weme-ui/unocss-preset": "^0.3.2",
83
65
  "citty": "^0.2.2",
84
66
  "defu": "^6.1.7",
85
67
  "diff": "^9.0.0",
@@ -102,5 +84,23 @@
102
84
  "typescript": "6.0.3",
103
85
  "unocss": "66.10.5",
104
86
  "vitest": "^4.1.8"
105
- }
87
+ },
88
+ "peerDependencies": {
89
+ "nuxt": "^4.0.0",
90
+ "valibot": "^1.5.0",
91
+ "vue": "^3.0.0"
92
+ },
93
+ "peerDependenciesMeta": {
94
+ "nuxt": {
95
+ "optional": true
96
+ },
97
+ "vue": {
98
+ "optional": true
99
+ }
100
+ },
101
+ "engines": {
102
+ "bun": ">=1.3.12",
103
+ "node": ">=22.14.0"
104
+ },
105
+ "packageManager": "bun@1.4.4"
106
106
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-DESSspHh.js","names":[],"sources":["../src/commands/add/index.ts"],"sourcesContent":["import type { RegistryItemFileKind } from '../../types'\nimport { resolve } from 'node:path/posix'\nimport { cwd, exit } from 'node:process'\nimport { defineCommand } from 'citty'\nimport ora from 'ora'\nimport { callWhen, Project, randomColor, unwrapError } from '../../utils'\n\n/**\n * 添加组件\n */\nexport default defineCommand({\n meta: {\n name: 'add',\n description: 'Add items to your project',\n },\n\n args: {\n cwd: {\n type: 'string',\n description: 'Change working directory to the project root.',\n default: cwd(),\n },\n kinds: {\n type: 'string',\n description: 'The kinds of items to add. Available values: file, doc, example, test',\n default: 'file,doc',\n },\n },\n\n async run({ args }) {\n const items = args._\n\n if (items.length === 0) {\n throw new Error('No items to add')\n }\n\n const cwd = resolve(args.cwd)\n const kinds = (args.kinds.split(',').map(kind => kind.trim()) || ['file', 'doc']) as RegistryItemFileKind[]\n\n try {\n const project = new Project(cwd)\n\n if (await project.isInitialized() === false) {\n throw new Error('Project is not initialized')\n }\n\n let count = 0\n const spinner = ora({ text: 'Adding items...' }).start()\n\n for (const item of items) {\n await callWhen(\n await project.hasAddedItem(item) === false,\n async () => {\n spinner.text = `Adding ${item}...`\n spinner.color = randomColor()\n\n if (await project.addItem(item, kinds)) {\n count++\n }\n },\n )\n }\n\n if (count === 0) {\n spinner.fail('No items added')\n exit(1)\n }\n\n spinner.succeed('Items added successfully')\n }\n catch (err) {\n console.error(unwrapError(err))\n exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;;;;AAUA,kBAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CAEA,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,SAAS,IAAI;EACf;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,SAAS;EACX;CACF;CAEA,MAAM,IAAI,EAAE,QAAQ;EAClB,MAAM,QAAQ,KAAK;EAEnB,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,MAAM,iBAAiB;EAGnC,MAAM,MAAM,QAAQ,KAAK,GAAG;EAC5B,MAAM,QAAS,KAAK,MAAM,MAAM,GAAG,CAAC,CAAC,KAAI,SAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK;EAE/E,IAAI;GACF,MAAM,UAAU,IAAI,QAAQ,GAAG;GAE/B,IAAI,MAAM,QAAQ,cAAc,MAAM,OACpC,MAAM,IAAI,MAAM,4BAA4B;GAG9C,IAAI,QAAQ;GACZ,MAAM,UAAU,IAAI,EAAE,MAAM,kBAAkB,CAAC,CAAC,CAAC,MAAM;GAEvD,KAAK,MAAM,QAAQ,OACjB,MAAM,SACJ,MAAM,QAAQ,aAAa,IAAI,MAAM,OACrC,YAAY;IACV,QAAQ,OAAO,UAAU,KAAK;IAC9B,QAAQ,QAAQ,YAAY;IAE5B,IAAI,MAAM,QAAQ,QAAQ,MAAM,KAAK,GACnC;GAEJ,CACF;GAGF,IAAI,UAAU,GAAG;IACf,QAAQ,KAAK,gBAAgB;IAC7B,KAAK,CAAC;GACR;GAEA,QAAQ,QAAQ,0BAA0B;EAC5C,SACO,KAAK;GACV,QAAQ,MAAM,YAAY,GAAG,CAAC;GAC9B,KAAK,CAAC;EACR;CACF;AACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"init-DZjeMuf3.js","names":[],"sources":["../src/commands/init/config.ts","../src/commands/init/template.ts","../src/commands/init/unocss.ts","../src/commands/init/index.ts"],"sourcesContent":["import { CONFIG_SCHEMA_URL, ProjectConfigSchema } from '@weme-ui/schema'\nimport * as v from 'valibot'\nimport { DEFAULT_PATHS, DEFAULT_REGISTRIES, PROJECT_CONFIG_FILENAME } from '../../constants'\nimport { parseRepoURL, writeFile } from '../../utils'\n\n/**\n * Generate the default config for the project.\n *\n * @param root - The root directory of the project.\n * @returns Whether the default config was generated successfully.\n * @throws If the default config fails to generate.\n */\nexport async function generateDefaultConfig(root: string, repo?: string) {\n const { name } = parseRepoURL(repo)\n\n const registries = repo\n ? [{ registry: name, repo }]\n : DEFAULT_REGISTRIES\n\n const schema = v.safeParse(ProjectConfigSchema, {\n $schema: CONFIG_SCHEMA_URL,\n registries,\n paths: DEFAULT_PATHS,\n })\n\n if (!schema.success) {\n throw new Error('Failed to generate default config')\n }\n\n return await writeFile(\n root,\n PROJECT_CONFIG_FILENAME,\n JSON.stringify(schema.output, null, 2),\n )\n}\n","import { existsSync } from 'node:fs'\nimport { copyFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path/posix'\nimport { x } from 'tinyexec'\nimport { glob } from 'tinyglobby'\nimport { CLI_TMP_DIR } from '../../constants'\nimport { ensureDir, existsFile } from '../../utils'\n\n/**\n * Initialize the project template.\n *\n * @param cwd - The current working directory.\n * @param template - The template to initialize.\n * @throws If the template is not found.\n */\nexport async function initProjectTemplate(cwd: string, template: string = 'vite') {\n const templatePath = join(cwd, CLI_TMP_DIR, 'repository', 'templates', template)\n\n if (!existsSync(templatePath)) {\n throw new Error(`Template ${template} not found`)\n }\n\n const files = await glob('**', { cwd: templatePath, onlyFiles: true })\n\n for (const file of files) {\n const filePath = join(cwd, file)\n const fileDir = dirname(filePath)\n\n if (!existsSync(fileDir)) {\n ensureDir(fileDir)\n }\n\n if (!await existsFile(cwd, file)) {\n await copyFile(join(templatePath, file), filePath)\n }\n }\n\n // Clean the template repository finally.\n await cleanTemplateRepository(cwd)\n}\n\n/**\n * Clone the template repository.\n *\n * @returns The result of the clone operation.\n * @throws If the clone operation fails.\n */\nexport async function cloneTemplateRepository(cwd: string) {\n const repositoryPath = join(cwd, CLI_TMP_DIR, 'repository')\n\n await cleanTemplateRepository(cwd)\n\n const result = await x('git', ['clone', '--depth', '1', 'https://github.com/weme-ui/weme-ui.git', repositoryPath])\n\n if (result.exitCode !== 0) {\n throw new Error(`Failed to clone template repository: ${result.stderr}`)\n }\n\n return result.stdout\n}\n\n/**\n * Clean the template repository.\n *\n * @param cwd - The current working directory.\n * @returns The result of the clean operation.\n * @throws If the clean operation fails.\n */\nexport async function cleanTemplateRepository(cwd: string) {\n const repositoryPath = join(cwd, CLI_TMP_DIR, 'repository')\n\n if (existsSync(repositoryPath)) {\n await x('rm', ['-rf', repositoryPath])\n }\n}\n","import { join } from 'node:path/posix'\nimport { CLI_TMP_DIR, PROJECT_CONFIG_FILENAME } from '../../constants'\nimport { writeFile } from '../../utils'\n\nconst baseUnoConfig = `import type { Theme } from '@weme-ui/unocss-preset/types'\nimport { defineConfig } from 'unocss'\n\nexport default defineConfig<Theme>({\n // Configure the content pipeline to include *.style.ts files in the project.\n content: {\n pipeline: {\n include: [\n /\\\\.(vue|[jt]sx|style\\\\.[jt]s|vine\\\\.[jt]s|mdx?|astro|elm|php|phtml|html)($|\\\\?)/,\n ],\n },\n },\n})\n`\nconst unoConfig = `import type { ProjectConfigSchema } from '@weme-ui/schema'\nimport type { Theme } from '@weme-ui/unocss-preset/types'\nimport type { InferInput } from 'valibot'\nimport { presetWemeUI } from '@weme-ui/unocss-preset'\nimport { mergeConfigs } from 'unocss'\nimport baseConfig from './${CLI_TMP_DIR}/uno.config'\nimport wemeConfigJson from './${PROJECT_CONFIG_FILENAME}' with { type: 'json' }\n\nconst wemeConfig = wemeConfigJson as InferInput<typeof ProjectConfigSchema>\n\nexport default mergeConfigs<Theme>([\n baseConfig,\n {\n presets: [\n presetWemeUI({\n colors: wemeConfig.unocss?.colors || {},\n cssVars: wemeConfig.unocss?.cssVars || {},\n }),\n ],\n },\n])\n`\n\nexport async function generateDefaultUnoCSSConfigs(root: string) {\n const createdBaseConfig = await writeFile(join(root, CLI_TMP_DIR), 'uno.config.ts', baseUnoConfig.trim())\n const createdUnoConfig = await writeFile(root, 'uno.config.ts', unoConfig.trim())\n\n return createdBaseConfig && createdUnoConfig\n}\n","import { resolve } from 'node:path/posix'\nimport { cwd, exit } from 'node:process'\nimport { defineCommand } from 'citty'\nimport { installDependencies } from 'nypm'\nimport ora from 'ora'\nimport { callWhen, parseRepoURL, Project, randomColor, unwrapError, useRegistry } from '../../utils'\nimport { generateDefaultConfig } from './config'\nimport { cloneTemplateRepository, initProjectTemplate } from './template'\nimport { generateDefaultUnoCSSConfigs } from './unocss'\n\n/**\n * 初始化项目\n */\nexport default defineCommand({\n meta: {\n name: 'init',\n description: 'Initialize a new Weme UI project',\n },\n\n args: {\n cwd: {\n type: 'positional',\n description: 'Change working directory to the project root.',\n default: cwd(),\n },\n repo: {\n type: 'string',\n description: 'Specify the registry repository of the project.',\n valueHint: 'weme-ui/slim',\n },\n },\n\n async run({ args }) {\n const cwd = resolve(args.cwd)\n\n try {\n const project = new Project(cwd)\n\n if (await project.isInitialized()) {\n throw new Error('Project already initialized')\n }\n\n const spinner = ora({ text: 'Initializing project...' }).start()\n\n const {\n name,\n branch,\n } = parseRepoURL(args.repo)\n\n // 1. Initialize project from clone template repository\n await callWhen(\n !(await project.hasPackageJson()),\n async () => {\n spinner.color = randomColor()\n spinner.text = 'Cloning template repository...'\n await cloneTemplateRepository(cwd)\n\n spinner.text = 'Initializing project structure...'\n spinner.color = randomColor()\n await initProjectTemplate(cwd)\n },\n )\n\n // 2. Generate the default project config file\n await callWhen(\n !(await project.hasProjectConfig()),\n async () => {\n spinner.text = 'Generating project config file...'\n spinner.color = randomColor()\n await generateDefaultConfig(cwd, args.repo)\n },\n )\n\n // 3. Generate the default UnoCSS config file\n await callWhen(\n !(await project.hasUnoConfig()),\n async () => {\n spinner.color = randomColor()\n spinner.text = 'Generating UnoCSS config file...'\n await generateDefaultUnoCSSConfigs(cwd)\n },\n )\n\n // 4. Install dependencies\n await callWhen(\n await project.hasPackageJson(),\n async () => {\n spinner.text = 'Install dependencies...'\n spinner.color = randomColor()\n await installDependencies({\n cwd,\n silent: true,\n })\n },\n )\n\n // 5. Add dependencies to the project\n await callWhen(\n await project.hasPackageJson(),\n async () => {\n const registry = useRegistry(name, branch)\n\n spinner.text = 'Adding dependencies to the project...'\n spinner.color = randomColor()\n const dependencies = await registry.dependencies()\n if (dependencies.length > 0) {\n await project.addDependencies(dependencies)\n }\n\n spinner.text = 'Adding dev dependencies to the project...'\n spinner.color = randomColor()\n const devDependencies = await registry.devDependencies()\n if (devDependencies.length > 0) {\n await project.addDevDependencies(devDependencies)\n }\n },\n )\n\n // 6. Add `on-init` items to the project\n await callWhen(\n await project.hasPackageJson(),\n async () => {\n const registry = useRegistry(name, branch)\n\n spinner.text = 'Adding `on-init` items to the project...'\n spinner.color = randomColor()\n const onInitItems = await registry.getItems(item => item.when === 'on-init')\n if (onInitItems.length > 0) {\n for (const item of onInitItems) {\n const itemName = `${name}/${item.name}`\n if (await project.hasAddedItem(itemName) === false) {\n await project.addItem(itemName)\n }\n }\n }\n },\n )\n\n spinner.succeed('Project initialized successfully')\n }\n catch (err) {\n console.error(unwrapError(err))\n exit(1)\n }\n },\n})\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"project-BZkWl9YJ.js","names":[],"sources":["../src/utils/fetcher.ts","../src/utils/registry.ts","../src/utils/utilities.ts","../src/utils/project.ts"],"sourcesContent":["import makeFetch from 'make-fetch-happen'\nimport { CLI_TMP_DIR } from '../constants'\n\nconst fetch = makeFetch.defaults({\n cachePath: CLI_TMP_DIR,\n noProxy: ['raw.githubusercontent.com'],\n})\n\n/**\n * Fetch a URL.\n *\n * @param url - The URL to fetch.\n * @returns The text response.\n */\nexport async function fetchURL(url: string) {\n const res = await fetch(url)\n return res.text()\n}\n\n/**\n * Fetch a JSON file.\n *\n * @param url - The URL to fetch.\n * @returns The JSON response.\n */\nexport async function fetchJSON<T>(url: string) {\n const res = await fetch(url)\n return res.json() as Promise<T>\n}\n","import type { HashableContent, Prettify, RegistryConfig, RegistryItem, RegistryItemFile } from '../types'\nimport { RegistryConfigSchema } from '@weme-ui/schema'\nimport { hash } from 'hasha'\nimport * as v from 'valibot'\nimport { DEFAULT_REGISTRY_BRANCH } from '../constants'\nimport { fetchJSON, fetchURL } from './fetcher'\n\ninterface RegistryMetadata {\n name: RegistryConfig['name']\n description: RegistryConfig['description']\n version: RegistryConfig['version']\n homepage: RegistryConfig['homepage']\n repository: RegistryConfig['repository']\n issues: RegistryConfig['issues']\n contributors: RegistryConfig['contributors']\n access: RegistryConfig['access']\n}\n\ntype ResolvedRegistryItemFile = Prettify<RegistryItemFile & HashableContent>\n\ninterface RegistryCache {\n config: RegistryConfig\n index: ReadonlyMap<string, RegistryItem>\n}\n\nclass Registry {\n /**\n * The name of the registry.\n */\n private name: string\n /**\n * The branch of the registry.\n */\n private branch: string\n /**\n * The cache of the registry.\n */\n private cache: Promise<RegistryCache> | null = null\n\n constructor(name: string, branch: string) {\n this.name = name\n this.branch = branch\n }\n\n /**\n * Get the registry metadata.\n *\n * @returns The registry metadata.\n */\n async metadata(): Promise<RegistryMetadata> {\n const { config } = await this.load()\n\n return {\n name: config.name,\n description: config.description,\n version: config.version,\n homepage: config.homepage,\n repository: config.repository,\n issues: config.issues,\n contributors: config.contributors,\n access: config.access,\n }\n }\n\n /**\n * Get the registry dependencies.\n *\n * @returns The registry dependencies.\n */\n async dependencies(): Promise<string[]> {\n return (await this.load()).config.dependencies ?? []\n }\n\n /**\n * Get the registry dev dependencies.\n *\n * @returns The registry dev dependencies.\n */\n async devDependencies(): Promise<string[]> {\n return (await this.load()).config.devDependencies ?? []\n }\n\n /**\n * Find the items in the registry.\n *\n * @param filter - The filter function.\n * @returns The items that match the filter.\n */\n async getItems(filter?: (item: RegistryItem) => boolean): Promise<RegistryItem[]> {\n const { config, index } = await this.load()\n\n const items = filter ? config.items.filter(filter) : config.items\n const visited = new Set<string>()\n const result: RegistryItem[] = []\n\n const visit = (item: RegistryItem) => {\n if (visited.has(item.name))\n return\n visited.add(item.name)\n\n for (const name of item.registryDependencies ?? []) {\n const dep = index.get(name)\n if (!dep) {\n continue\n }\n visit(dep)\n }\n result.push(item)\n }\n\n items.forEach(visit)\n return result\n }\n\n /**\n * Get the files of an item.\n *\n * @param item - The item to get the files from.\n * @returns The resolved files of the item.\n */\n async getItemFiles(item: RegistryItem): Promise<ResolvedRegistryItemFile[]> {\n return await Promise.all(item.files.map(\n async (file) => {\n const result = await this.getItemFileContent(file.path)\n\n return {\n type: file.type,\n kind: file.kind,\n path: file.path,\n target: file.target,\n content: result.content,\n hash: result.hash,\n }\n },\n ))\n }\n\n /**\n * Get the content of a file.\n *\n * @param source - The source of the file.\n * @returns The content of the file.\n */\n async getItemFileContent(source: string): Promise<HashableContent> {\n const url = this.joinURL(source)\n const content = await fetchURL(url)\n const hashStr = await hash(content)\n\n return {\n content,\n hash: hashStr,\n }\n }\n\n /**\n * Load the registry cache.\n *\n * @throws If the registry cache fails to load.\n * @returns The registry cache.\n */\n private async load(): Promise<RegistryCache> {\n this.cache ??= this.fetchRegistryJson().catch((err) => {\n this.cache = null\n throw err\n })\n return this.cache\n }\n\n /**\n * Fetch the registry JSON.\n *\n * @throws If the registry JSON fails to parse.\n * @returns The registry cache.\n */\n private async fetchRegistryJson(): Promise<RegistryCache> {\n const url = this.joinURL('registry.json')\n const raw = await fetchJSON<unknown>(url)\n const parsed = v.safeParse(RegistryConfigSchema, raw)\n\n if (!parsed.success) {\n throw new Error('Failed to parse registry config', { cause: parsed.issues })\n }\n\n const config = parsed.output\n const index = new Map<string, RegistryItem>()\n for (const item of config.items) {\n if (index.has(item.name)) {\n throw new Error(`Duplicate item name: ${item.name}`)\n }\n index.set(item.name, item)\n }\n\n return { config, index }\n }\n\n /**\n * Join the URL with the name and branch.\n *\n * @param path The path to join.\n * @returns The joined URL.\n */\n private joinURL(path: string): string {\n return `https://raw.githubusercontent.com/${this.name}/refs/heads/${this.branch}/${path}`\n }\n}\n\n/**\n * Use the registry.\n *\n * @param name The name of the registry.\n * @param branch The branch of the registry.\n * @returns The registry instance.\n */\nexport function useRegistry(name: string, branch: string = DEFAULT_REGISTRY_BRANCH): Registry {\n return new Registry(name, branch)\n}\n","import { existsSync, mkdirSync } from 'node:fs'\nimport fs from 'node:fs/promises'\nimport { join, resolve } from 'node:path/posix'\nimport { cwd, exit } from 'node:process'\nimport { parseURL } from 'ufo'\nimport { DEFAULT_REGISTRY_BRANCH, DEFAULT_REGISTRY_NAME } from '../constants'\n\n/**\n * Ensure the working directory.\n *\n * @param path - The working directory to ensure.\n * @returns The ensured working directory. If the directory does not exist, it will be created.\n */\nexport function ensureDir(path: string) {\n if (path === cwd()) {\n return path\n }\n\n const resolved = resolve(path)\n\n if (!existsSync(resolved)) {\n mkdirSync(resolved, { recursive: true })\n }\n\n return resolved\n}\n\n/**\n * Check if a file exists.\n *\n * @param root - The root directory of the project.\n * @param filename - The name of the file.\n * @returns Whether the file exists.\n */\nexport async function existsFile(root: string, filename: string) {\n const filePath = resolve(root, filename)\n const exists = existsSync(filePath)\n\n if (!exists)\n return false\n\n const content = await fs.readFile(filePath, 'utf-8')\n\n return exists && content !== null && content.trim() !== ''\n}\n\n/**\n * Read a file.\n *\n * @param root - The root directory of the project.\n * @param filename - The name of the file.\n * @returns The content of the file. If the file does not exist, it will return `null`.\n */\nexport async function readFile(root: string, filename: string) {\n try {\n if (!(await existsFile(root, filename)))\n return null\n\n const content = await fs.readFile(join(ensureDir(root), filename), 'utf-8')\n\n if (!content)\n return null\n\n return content\n }\n catch {\n return null\n }\n}\n\n/**\n * Write a file.\n *\n * @param root - The root directory of the project.\n * @param filename - The name of the file.\n * @param content - The content of the file.\n * @returns Whether the file was written successfully.\n */\nexport async function writeFile(root: string, filename: string, content: string) {\n try {\n const path = join(ensureDir(root), filename)\n await fs.writeFile(path, `${content}\\n`, { encoding: 'utf-8', flag: 'w' })\n }\n catch {\n return false\n }\n\n return true\n}\n\n/**\n * Parse a repository URL.\n *\n * @param url - The URL to parse.\n * @returns The parsed repository URL.\n */\nexport function parseRepoURL(url?: string) {\n if (!url) {\n return {\n name: DEFAULT_REGISTRY_NAME,\n branch: DEFAULT_REGISTRY_BRANCH,\n }\n }\n\n const { host, pathname, hash } = parseURL(url)\n if ((host && host !== 'github.com') || !pathname) {\n throw new Error(`Invalid repository URL: ${url}`)\n }\n\n let branch = hash ? hash.replace(/^#/, '') : DEFAULT_REGISTRY_BRANCH\n let name = removeLeadingSlash(pathname)\n if (name.split('/').length !== 2 && name.includes('/tree/')) {\n branch = name.split('/tree/')[1]\n name = name.split('/tree/')[0]\n }\n\n return {\n name,\n branch,\n }\n}\n\n/**\n * Remove the leading slash from a path.\n *\n * @param path - The path to remove the leading slash from.\n * @returns The path without the leading slash.\n */\nexport function removeLeadingSlash(path: string) {\n return path.replace(/^\\//, '')\n}\n\n/**\n * Remove the trailing slash from a path.\n *\n * @param path - The path to remove the trailing slash from.\n * @returns The path without the trailing slash.\n */\nexport function removeTrailingSlash(path: string) {\n return path.replace(/\\/$/, '')\n}\n\n/**\n * Unwrap an error.\n *\n * @param error - The error to unwrap.\n * @returns The unwrapped error.\n */\nexport function unwrapError(error: unknown) {\n return error instanceof Error ? error.message : 'Unknown error'\n}\n\n/**\n * Call a callback when a condition is met.\n *\n * @param condition - The condition to check.\n * @param callback - The callback to call.\n * @param finalizer - The finalizer to call.\n * @returns Whether the callback was called successfully.\n */\nexport async function callWhen<T>(\n condition: boolean,\n callback: () => Promise<T>,\n finalizer?: () => Promise<void>,\n) {\n if (condition) {\n try {\n await callback()\n }\n catch (e) {\n console.error(unwrapError(e))\n exit(1)\n }\n finally {\n if (finalizer) {\n await finalizer()\n }\n }\n }\n}\n\ntype RandomColor = 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray'\n\n/**\n * Generate a random color.\n *\n * @returns The random color.\n */\nexport function randomColor(): RandomColor {\n const colors: RandomColor[] = [\n 'black',\n 'red',\n 'green',\n 'yellow',\n 'blue',\n 'magenta',\n 'cyan',\n 'white',\n 'gray',\n ]\n return colors[Math.floor(Math.random() * colors.length)]\n}\n","import type { CssVariables, HashableContent, Prettify, ProjectAddedItem, ProjectAddedItemFile, ProjectAddedRegistry, ProjectConfig, ProjectLockFile, ProjectPaths, RegistryItemFileKind } from '../types'\nimport { basename, isAbsolute, join, relative, resolve } from 'node:path/posix'\nimport { LOCKFILE_SCHEMA_URL, ProjectConfigSchema, ProjectLockFileSchema } from '@weme-ui/schema'\nimport { defu } from 'defu'\nimport { hash } from 'hasha'\nimport { addDependency } from 'nypm'\nimport * as v from 'valibot'\nimport { CLI_TMP_DIR, DEFAULT_PATHS, DEFAULT_REGISTRIES, PROJECT_CONFIG_FILENAME, PROJECT_LOCKFILE_FILENAME } from '../constants'\nimport { useRegistry } from './registry'\nimport { existsFile, readFile, removeLeadingSlash, writeFile } from './utilities'\n\ntype ProjectAddedItemMeta = Pick<ProjectAddedItem, 'type' | 'registry' | 'repo' | 'prefix'>\ntype ResolvedProjectAddedItemFile = Prettify<ProjectAddedItemMeta & ProjectAddedItemFile & HashableContent>\n\ninterface ProjectInfo {\n root: string\n paths: ProjectPaths\n registries: NonNullable<ProjectConfig['registries']>\n defaultRegistry: ProjectAddedRegistry\n}\n\n/**\n * Project management class.\n *\n * @example\n * ```ts\n * const project = new Project(cwd)\n * ```\n *\n * @param root - The root directory of the project.\n * @returns The project instance.\n */\nexport class Project {\n /**\n * The root directory of the project.\n */\n private root: string\n\n constructor(root: string) {\n this.root = root\n }\n\n /**\n * Get the project info.\n *\n * @returns The project info.\n */\n async info(): Promise<ProjectInfo> {\n const config = await this.hasProjectConfig() ? await this.loadProjectConfig() : null\n\n return {\n root: this.root,\n paths: this.resolvePaths(config?.paths),\n registries: config?.registries ?? DEFAULT_REGISTRIES,\n defaultRegistry: config?.registries?.[0] ?? DEFAULT_REGISTRIES[0],\n }\n }\n\n /**\n * Add an item to the project.\n *\n * @param name - The name of the item to add.\n * @returns Whether the item was added.\n */\n async addItem(name: string, kinds: RegistryItemFileKind[] = ['file']): Promise<boolean> {\n if (await this.hasAddedItem(name)) {\n return await this.updateItem(name)\n }\n\n const parsed = await this.parseItemName(name)\n const registry = useRegistry(parsed.registry)\n\n const items = await registry.getItems(item => item.name === parsed.name)\n if (items.length === 0) {\n throw new Error(`Item ${parsed.name} not found in the registry ${parsed.registry}`)\n }\n\n const { paths, registries, defaultRegistry } = await this.info()\n const itemRegistry = registries.find(registry => registry.registry === parsed.registry) ?? defaultRegistry\n\n // #region Add items\n const addedItems: ProjectAddedItem[] = []\n for (const item of items) {\n const files = await registry.getItemFiles(item)\n const addedItem: ProjectAddedItem = {\n name: item.name,\n type: item.type,\n registry: itemRegistry.registry,\n repo: itemRegistry.repo,\n prefix: itemRegistry.prefix,\n files: [],\n }\n\n for (const file of files) {\n if (!kinds.includes(file.kind)) {\n continue\n }\n\n const fileName = basename(file.path)\n const fileDir = paths[file.type] ?? paths['~']\n\n let filePath = fileDir\n\n if (file.type === 'component') {\n filePath = itemRegistry.prefix\n ? join(fileDir, itemRegistry.prefix, item.name)\n : join(fileDir, item.name)\n }\n\n await writeFile(\n this.joinPath(filePath),\n fileName,\n file.content,\n )\n\n addedItem.files.push({\n kind: file.kind,\n source: file.path,\n dest: join(filePath, fileName),\n })\n }\n\n if (addedItem.files.length > 0) {\n addedItems.push(addedItem)\n }\n }\n\n if (addedItems.length === 0) {\n return false\n }\n\n const lockfile = await this.loadLockfile() ?? {\n $schema: LOCKFILE_SCHEMA_URL,\n items: [],\n }\n\n lockfile.items.push(...addedItems)\n\n const written = await writeFile(\n join(this.root, CLI_TMP_DIR),\n PROJECT_LOCKFILE_FILENAME,\n JSON.stringify(lockfile, null, 2),\n )\n // #endregion\n\n // #region Add dependencies\n const dependencies = items.map(item => item.dependencies ?? []).flat()\n const devDependencies = items.map(item => item.devDependencies ?? []).flat()\n\n if (dependencies.length > 0) {\n await this.addDependencies(dependencies)\n }\n\n if (devDependencies.length > 0) {\n await this.addDevDependencies(devDependencies)\n }\n // #endregion\n\n // #region Add Css Variables\n const cssVariables = items.map(item => item.cssVars ?? {}).reduce((acc, curr) => defu(acc, curr), {})\n if (Object.keys(cssVariables).length > 0) {\n await this.addCssVariables(cssVariables)\n }\n // #endregion\n\n return written\n }\n\n /**\n * Update an added item by name in the project.\n *\n * @param name - The name of the item to update.\n * @returns Whether the item was updated.\n */\n async updateItem(name: string): Promise<boolean> {\n void name\n return false\n }\n\n /**\n * Add css variables to the project.\n *\n * @param cssVariables - The css variables to add.\n * @throws If the project config is not found.\n * @throws If the project config is not writable.\n */\n async addCssVariables(cssVariables: CssVariables): Promise<void> {\n const projectConfig = await this.loadProjectConfig()\n\n if (!projectConfig) {\n throw new Error('Project config not found')\n }\n\n projectConfig.unocss = projectConfig.unocss ?? {}\n projectConfig.unocss.cssVars = defu(projectConfig.unocss.cssVars ?? {}, cssVariables)\n\n await writeFile(this.root, PROJECT_CONFIG_FILENAME, JSON.stringify(projectConfig, null, 2))\n }\n\n /**\n * Check if an item was added to the project.\n *\n * @param name - The name of the item to check.\n * @returns Whether the item was added.\n */\n async hasAddedItem(name: string): Promise<boolean> {\n const lockfile = await this.loadLockfile()\n\n if (lockfile) {\n const parsed = await this.parseItemName(name)\n return lockfile.items.some(\n item => item.name === parsed.name && item.registry === parsed.registry,\n )\n }\n\n return false\n }\n\n /**\n * Get the files of an added item.\n *\n * @param itemName - The name of the item to get the files from.\n * @returns The resolved files of the item.\n * @throws If the item is not found in the lockfile.\n * @throws If the file is not found in the project.\n */\n async getAddedItemFiles(itemName: string): Promise<ResolvedProjectAddedItemFile[]> {\n const lockfile = await this.loadLockfile()\n\n if (lockfile) {\n const addedItem = lockfile.items.find(item => item.name === itemName)\n\n if (!addedItem) {\n throw new Error(`Item ${itemName} not found in the lockfile`)\n }\n\n return await Promise.all(addedItem.files.map(\n async (file) => {\n const result = await this.getAddedItemFileContent(file.dest)\n\n return {\n type: addedItem.type,\n registry: addedItem.registry,\n repo: addedItem.repo,\n prefix: addedItem.prefix,\n kind: file.kind,\n source: file.source,\n dest: file.dest,\n content: result.content,\n hash: result.hash,\n }\n },\n ))\n }\n\n return []\n }\n\n /**\n * Get the content of an added item file by filepath.\n *\n * @param filepath - The filepath of the file.\n * @returns The content of the file.\n * @throws If the file is not found in the project.\n */\n async getAddedItemFileContent(filepath: string): Promise<HashableContent> {\n const content = await readFile(this.root, filepath)\n\n if (!content) {\n throw new Error(`File ${filepath} not found in the project`)\n }\n\n const hashStr = await hash(content)\n\n return {\n content,\n hash: hashStr,\n }\n }\n\n /**\n * Add dependencies to the project.\n *\n * @param dependencies - The dependencies to add.\n */\n async addDependencies(dependencies: string[]): Promise<void> {\n await addDependency(dependencies, {\n cwd: this.root,\n silent: true,\n })\n }\n\n /**\n * Add dev dependencies to the project.\n *\n * @param dependencies - The dev dependencies to add.\n */\n async addDevDependencies(dependencies: string[]): Promise<void> {\n await addDependency(dependencies, {\n cwd: this.root,\n silent: true,\n dev: true,\n })\n }\n\n /**\n * Check if the project is initialized.\n *\n * @returns Whether the project is initialized.\n */\n async isInitialized(): Promise<boolean> {\n const checkList = [\n this.joinPath('uno.config.ts'),\n this.joinPath(PROJECT_CONFIG_FILENAME),\n this.joinPath(CLI_TMP_DIR, PROJECT_LOCKFILE_FILENAME),\n this.joinPath('package.json'),\n this.joinPath(CLI_TMP_DIR, 'uno.config.ts'),\n ]\n\n const progress = await Promise.all(checkList.map(\n async path => await existsFile(this.root, path),\n ))\n\n return progress.every(Boolean)\n }\n\n /**\n * Check if the project has a package.json file.\n *\n * @returns Whether the project has a package.json file.\n */\n async hasPackageJson(): Promise<boolean> {\n return await existsFile(this.root, 'package.json')\n }\n\n /**\n * Check if the project has a project config file.\n *\n * @returns Whether the project has a project config file.\n */\n async hasProjectConfig(): Promise<boolean> {\n return await existsFile(this.root, PROJECT_CONFIG_FILENAME)\n }\n\n /**\n * Check if the project has a lockfile.\n *\n * @returns Whether the project has a lockfile.\n */\n async hasLockfile(): Promise<boolean> {\n return await existsFile(this.root, join(CLI_TMP_DIR, PROJECT_LOCKFILE_FILENAME))\n }\n\n /**\n * Check if the project has a uno config file.\n *\n * @returns Whether the project has a uno config file.\n */\n async hasUnoConfig(): Promise<boolean> {\n return await existsFile(this.root, join(CLI_TMP_DIR, 'uno.config.ts'))\n }\n\n /**\n * Load the project config file.\n *\n * @returns The loaded project config if it exists, otherwise null.\n */\n private async loadProjectConfig(): Promise<ProjectConfig | null> {\n const content = await readFile(this.root, PROJECT_CONFIG_FILENAME)\n\n if (content) {\n try {\n const configJson = JSON.parse(content)\n const parsed = v.safeParse(ProjectConfigSchema, configJson)\n\n if (parsed.success) {\n return parsed.output\n }\n\n return null\n }\n catch {}\n }\n\n return null\n }\n\n /**\n * Load the lockfile.\n *\n * @returns The loaded lockfile if it exists, otherwise null.\n */\n private async loadLockfile(): Promise<ProjectLockFile | null> {\n const content = await readFile(join(this.root, CLI_TMP_DIR), PROJECT_LOCKFILE_FILENAME)\n\n if (content) {\n try {\n const lockfileJson = JSON.parse(content)\n const parsed = v.safeParse(ProjectLockFileSchema, lockfileJson)\n\n if (parsed.success) {\n return parsed.output\n }\n }\n catch {}\n }\n\n return null\n }\n\n /**\n * Resolve project config paths to locations relative to the project root.\n *\n * @param paths - The paths from project config.\n * @returns The resolved paths.\n */\n private resolvePaths(paths?: Partial<ProjectPaths> | null): ProjectPaths {\n const merged = defu(paths ?? {}, DEFAULT_PATHS)\n const alias = this.toProjectRelative(this.root, merged['~'])\n\n return Object.fromEntries(\n Object.entries(merged).map(([key, value]) => [\n key,\n key === '~'\n ? alias\n : this.toProjectRelative(this.root, this.expandTildeAlias(value, alias)),\n ]),\n ) as ProjectPaths\n }\n\n /**\n * Expand a tilde alias.\n *\n * @param value - The value to expand.\n * @param alias - The alias to expand.\n * @returns The expanded value.\n */\n private expandTildeAlias(value: string, alias: string) {\n if (value === '~') {\n return alias\n }\n\n if (value.startsWith('~/')) {\n const rest = value.slice(2)\n return rest ? join(alias, rest) : alias\n }\n\n return value\n }\n\n /**\n * Convert a path to a project relative path.\n *\n * @param root - The project root directory.\n * @param path - The path to convert.\n * @returns The project relative path.\n */\n private toProjectRelative(root: string, path: string) {\n const abs = isAbsolute(path) ? resolve(path) : resolve(root, path)\n\n if (abs === root || abs.startsWith(`${root}/`)) {\n return relative(root, abs) || '.'\n }\n\n return abs\n }\n\n /**\n * Parse the item name.\n *\n * @param input - The item name to parse, format: `<registry>/<item-name>`.\n * @returns The parsed item name.\n */\n private async parseItemName(input: string): Promise<{ registry: string, name: string }> {\n const s = input.trim().replace(/\\/+$/, '')\n const i = s.lastIndexOf('/')\n\n if (i === -1) {\n return {\n registry: (await this.info()).defaultRegistry.registry,\n name: s,\n }\n }\n return {\n registry: s.slice(0, i),\n name: s.slice(i + 1),\n }\n }\n\n /**\n * Join a path to the workplace directory.\n *\n * @param paths - The paths to join.\n * @returns The joined path.\n */\n private joinPath(...paths: string[]) {\n return join(this.root, ...paths.map(removeLeadingSlash))\n }\n}\n"],"mappings":"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"}