create-tsdown 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025-present VoidZero Inc. & Contributors
4
+ Copyright (c) 2024 三咲智子 Kevin Deng (https://github.com/sxzz)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # create-tsdown [![npm](https://img.shields.io/npm/v/tsdown.svg)](https://npmjs.com/package/tsdown) [![Unit Test](https://github.com/rolldown/tsdown/actions/workflows/tests.yml/badge.svg)](https://github.com/rolldown/tsdown/actions/workflows/tests.yml) [![JSR](https://jsr.io/badges/@sxzz/tsdown)](https://jsr.io/@sxzz/tsdown) [![tsdown-starter-stackblitz](https://developer.stackblitz.com/img/open_in_stackblitz_small.svg)](https://stackblitz.com/github/rolldown/tsdown-starter-stackblitz)
2
+
3
+ **create-tsdown** is the cli tool to create a new project using [tsdown](https://tsdown.dev). It provides a simple and efficient way to set up a TypeScript project with all the necessary configurations and dependencies.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npm create tsdown
9
+ ```
10
+
11
+ ## Migrate from tsup
12
+
13
+ ```bash
14
+ npx create-tsdown migrate
15
+ ```
16
+
17
+ Please make sure to commit your changes before migrating. For more details, see the [Migration Guide](https://tsdown.dev/guide/migrate-from-tsup).
18
+
19
+ ## Sponsors
20
+
21
+ <p align="center">
22
+ <a href="https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg">
23
+ <img src='https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg'/>
24
+ </a>
25
+ </p>
26
+
27
+ ## Licenses
28
+
29
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,48 @@
1
+ //#region src/utils/types.d.ts
2
+ type Overwrite<T, U> = Omit<T, keyof U> & U;
3
+
4
+ //#endregion
5
+ //#region src/options/types.d.ts
6
+ /**
7
+ * Options for tsdown.
8
+ */
9
+ interface Options {
10
+ /**
11
+ * The name of the package.
12
+ * @default 'my-package'
13
+ */
14
+ name?: string;
15
+ /**
16
+ * The template to use.
17
+ * @default 'default'
18
+ */
19
+ template?: "default" | "vue" | "react";
20
+ /** @default false */
21
+ silent?: boolean;
22
+ /** @default false */
23
+ debug?: boolean;
24
+ }
25
+ type ResolvedOptions = Overwrite<Options, {
26
+ /**
27
+ * The name of the package.
28
+ * @default 'my-package'
29
+ */
30
+ name: string;
31
+ /**
32
+ * The template to use.
33
+ * @default 'default'
34
+ */
35
+ template: "default" | "vue" | "react";
36
+ /** @default false */
37
+ silent: boolean;
38
+ /** @default false */
39
+ debug: boolean;
40
+ }>; //#endregion
41
+ //#region src/index.d.ts
42
+ /**
43
+ * Create a tsdown project.
44
+ */
45
+ declare function create(options: ResolvedOptions): Promise<void>;
46
+
47
+ //#endregion
48
+ export { create };
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import { logger } from "./logger-0-2qD2tL.js";
2
+ import { downloadTemplate } from "giget";
3
+
4
+ //#region src/index.ts
5
+ /**
6
+ * Create a tsdown project.
7
+ */
8
+ async function create(options) {
9
+ if (typeof options.silent === "boolean") logger.setSilent(options.silent);
10
+ await downloadTemplate(`gh:gugustinette/create-tsdown/templates/${options.template}`, { dir: options.name });
11
+ }
12
+
13
+ //#endregion
14
+ export { create };
@@ -0,0 +1,41 @@
1
+ import { bgRed, bgYellow, blue, green } from "ansis";
2
+
3
+ //#region src/utils/general.ts
4
+ function toArray(val, defaultValue) {
5
+ if (Array.isArray(val)) return val;
6
+ else if (val == null) {
7
+ if (defaultValue) return [defaultValue];
8
+ return [];
9
+ } else return [val];
10
+ }
11
+ function resolveComma(arr) {
12
+ return arr.flatMap((format) => format.split(","));
13
+ }
14
+
15
+ //#endregion
16
+ //#region src/utils/logger.ts
17
+ var Logger = class {
18
+ silent = false;
19
+ setSilent(value) {
20
+ this.silent = value;
21
+ }
22
+ filter(...args) {
23
+ return args.filter((arg) => arg !== void 0 && arg !== false);
24
+ }
25
+ info(...args) {
26
+ if (!this.silent) console.info(blue`ℹ`, ...this.filter(...args));
27
+ }
28
+ warn(...args) {
29
+ if (!this.silent) console.warn("\n", bgYellow` WARN `, ...this.filter(...args), "\n");
30
+ }
31
+ error(...args) {
32
+ if (!this.silent) console.error("\n", bgRed` ERROR `, ...this.filter(...args), "\n");
33
+ }
34
+ success(...args) {
35
+ if (!this.silent) console.info(green`✔`, ...this.filter(...args));
36
+ }
37
+ };
38
+ const logger = new Logger();
39
+
40
+ //#endregion
41
+ export { logger, resolveComma, toArray };
@@ -0,0 +1,104 @@
1
+ import { logger } from "./logger-0-2qD2tL.js";
2
+ import { version } from "./package-DN7qLXAi.js";
3
+ import process from "node:process";
4
+ import { existsSync } from "node:fs";
5
+ import { readFile, unlink, writeFile } from "node:fs/promises";
6
+
7
+ //#region src/migrate.ts
8
+ async function migrate({ cwd, dryRun }) {
9
+ if (dryRun) logger.info("Dry run enabled. No changes were made.");
10
+ if (cwd) process.chdir(cwd);
11
+ await migratePackageJson(dryRun);
12
+ await migrateTsupConfig(dryRun);
13
+ }
14
+ async function migratePackageJson(dryRun) {
15
+ if (!existsSync("package.json")) {
16
+ logger.error("No package.json found");
17
+ return false;
18
+ }
19
+ const pkgRaw = await readFile("package.json", "utf-8");
20
+ let pkg = JSON.parse(pkgRaw);
21
+ const semver = `^${version}`;
22
+ let found = false;
23
+ if (pkg.dependencies?.tsup) {
24
+ logger.info("Migrating `dependencies` to tsdown.");
25
+ found = true;
26
+ pkg.dependencies = renameKey(pkg.dependencies, "tsup", "tsdown", semver);
27
+ }
28
+ if (pkg.devDependencies?.tsup) {
29
+ logger.info("Migrating `devDependencies` to tsdown.");
30
+ found = true;
31
+ pkg.devDependencies = renameKey(pkg.devDependencies, "tsup", "tsdown", semver);
32
+ }
33
+ if (pkg.peerDependencies?.tsup) {
34
+ logger.info("Migrating `peerDependencies` to tsdown.");
35
+ found = true;
36
+ pkg.peerDependencies = renameKey(pkg.peerDependencies, "tsup", "tsdown", "*");
37
+ }
38
+ if (pkg.scripts) {
39
+ for (const key of Object.keys(pkg.scripts)) if (pkg.scripts[key].includes("tsup")) {
40
+ logger.info(`Migrating \`${key}\` script to tsdown`);
41
+ found = true;
42
+ pkg.scripts[key] = pkg.scripts[key].replaceAll(/tsup(?:-node)?/g, "tsdown");
43
+ }
44
+ }
45
+ if (pkg.tsup) {
46
+ logger.info("Migrating `tsup` field in package.json to `tsdown`.");
47
+ found = true;
48
+ pkg = renameKey(pkg, "tsup", "tsdown");
49
+ }
50
+ if (!found) {
51
+ logger.warn("No tsup-related fields found in package.json");
52
+ return false;
53
+ }
54
+ const pkgStr = `${JSON.stringify(pkg, null, 2)}\n`;
55
+ if (dryRun) {
56
+ const { createPatch } = await import("diff");
57
+ logger.info("[dry-run] package.json:");
58
+ console.info(createPatch("package.json", pkgRaw, pkgStr));
59
+ } else {
60
+ await writeFile("package.json", pkgStr);
61
+ logger.success("Migrated `package.json`");
62
+ }
63
+ return true;
64
+ }
65
+ const TSUP_FILES = [
66
+ "tsup.config.ts",
67
+ "tsup.config.cts",
68
+ "tsup.config.mts",
69
+ "tsup.config.js",
70
+ "tsup.config.cjs",
71
+ "tsup.config.mjs",
72
+ "tsup.config.json"
73
+ ];
74
+ async function migrateTsupConfig(dryRun) {
75
+ let found = false;
76
+ for (const file of TSUP_FILES) {
77
+ if (!existsSync(file)) continue;
78
+ logger.info(`Found \`${file}\``);
79
+ found = true;
80
+ const tsupConfigRaw = await readFile(file, "utf-8");
81
+ const tsupConfig = tsupConfigRaw.replaceAll(/\btsup\b/g, "tsdown").replaceAll(/\bTSUP\b/g, "TSDOWN");
82
+ const renamed = file.replaceAll("tsup", "tsdown");
83
+ if (dryRun) {
84
+ const { createTwoFilesPatch } = await import("diff");
85
+ logger.info(`[dry-run] ${file} -> ${renamed}:`);
86
+ console.info(createTwoFilesPatch(file, renamed, tsupConfigRaw, tsupConfig));
87
+ } else {
88
+ await writeFile(renamed, tsupConfig, "utf8");
89
+ await unlink(file);
90
+ logger.success(`Migrated \`${file}\` to \`${renamed}\``);
91
+ }
92
+ }
93
+ if (!found) logger.warn("No tsup config found");
94
+ return found;
95
+ }
96
+ function renameKey(obj, oldKey, newKey, newValue) {
97
+ const newObj = {};
98
+ for (const key of Object.keys(obj)) if (key === oldKey) newObj[newKey] = newValue || obj[oldKey];
99
+ else newObj[key] = obj[key];
100
+ return newObj;
101
+ }
102
+
103
+ //#endregion
104
+ export { migrate };
@@ -0,0 +1,5 @@
1
+ //#region package.json
2
+ var version = "0.0.1";
3
+
4
+ //#endregion
5
+ export { version };
package/dist/run.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/run.js ADDED
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ import { logger, resolveComma, toArray } from "./logger-0-2qD2tL.js";
3
+ import { version } from "./package-DN7qLXAi.js";
4
+ import module from "node:module";
5
+ import { green, underline } from "ansis";
6
+ import process$1 from "node:process";
7
+ import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
8
+ import { cac } from "cac";
9
+ import debug from "debug";
10
+
11
+ //#region src/options/index.ts
12
+ const debug$1 = debug("create-tsdown:options");
13
+ /**
14
+ * Resolve the user options and configs
15
+ * @param options The user options
16
+ * @returns The resolved options
17
+ */
18
+ async function resolveOptions(options) {
19
+ debug$1("options %O", options);
20
+ let resolvedName;
21
+ if (options.name !== void 0) resolvedName = options.name;
22
+ else resolvedName = await text({
23
+ message: "What is the name of your package?",
24
+ placeholder: "./my-package",
25
+ initialValue: "./my-package"
26
+ });
27
+ if (isCancel(resolvedName)) {
28
+ cancel("Operation cancelled.");
29
+ process.exit(0);
30
+ }
31
+ let resolvedTemplate;
32
+ if (options.template !== void 0) {
33
+ resolvedTemplate = options.template;
34
+ if (![
35
+ "default",
36
+ "vue",
37
+ "react"
38
+ ].includes(resolvedTemplate)) throw new Error(`Invalid template "${resolvedTemplate}". Available templates: default, vue, react`);
39
+ } else resolvedTemplate = await select({
40
+ message: "Which template do you want to use?",
41
+ options: [
42
+ {
43
+ value: "default",
44
+ label: "Default"
45
+ },
46
+ {
47
+ value: "vue",
48
+ label: "Vue"
49
+ },
50
+ {
51
+ value: "react",
52
+ label: "React"
53
+ }
54
+ ],
55
+ initialValue: "default"
56
+ });
57
+ if (isCancel(resolvedTemplate)) {
58
+ cancel("Operation cancelled.");
59
+ process.exit(0);
60
+ }
61
+ const resolvedOptions = {
62
+ name: resolvedName,
63
+ template: resolvedTemplate,
64
+ silent: !!options.silent,
65
+ debug: !!options.debug
66
+ };
67
+ debug$1("resolved configs %O", resolvedOptions);
68
+ return resolvedOptions;
69
+ }
70
+
71
+ //#endregion
72
+ //#region src/cli.ts
73
+ const cli = cac("create-tsdown");
74
+ cli.help().version(version);
75
+ cli.command("[...files]", "Create a tsdown project", {
76
+ ignoreOptionDefaultValue: true,
77
+ allowUnknownOptions: true
78
+ }).option("-n, --name <name>", "Name of the package to create", { default: "./my-package" }).option("-t, --template <template>", "Available templates: default, vue, react", { default: "default" }).option("--debug", "Show debug logs").option("--silent", "Suppress non-error logs").action(async (input, options) => {
79
+ intro(`tsdown - The Elegant Library Bundler`);
80
+ logger.setSilent(!!options.silent);
81
+ const resolvedOptions = await resolveOptions(options);
82
+ const s = spinner();
83
+ s.start("Cloning the template...");
84
+ const { create } = await import("./index.js");
85
+ if (input.length > 0) options.name = input[0];
86
+ await create(resolvedOptions);
87
+ s.stop("Template cloned");
88
+ outro(`Done! Now run:\n ${green`cd ${resolvedOptions.name}`}\n ${green`npm install`}\n ${green`npm run build`}\n\nFor more information, visit: ${underline`https://tsdown.dev/`}`);
89
+ });
90
+ cli.command("migrate", "Migrate from tsup to tsdown").option("-c, --cwd <dir>", "Working directory").option("-d, --dry-run", "Dry run").action(async (args) => {
91
+ intro(`Starting migration from tsup to tsdown`);
92
+ const shouldContinue = await confirm({ message: `Before proceeding, review the migration guide at ${underline`https://tsdown.dev/guide/migrate-from-tsup`}, as this process will modify your files.\nUncommitted changes will be lost. Use the ${green`--dry-run`} flag to preview changes without applying them.` });
93
+ if (isCancel(shouldContinue)) {
94
+ cancel("Migration cancelled.");
95
+ process$1.exit(0);
96
+ }
97
+ if (!shouldContinue) {
98
+ outro("Migration cancelled.");
99
+ process$1.exit(0);
100
+ }
101
+ const s = spinner();
102
+ s.start("Migrating from tsup to tsdown...");
103
+ const { migrate } = await import("./migrate-C-3eL652.js");
104
+ await migrate({
105
+ cwd: args.cwd,
106
+ dryRun: !!args.dryRun
107
+ });
108
+ s.stop();
109
+ outro(`Migration completed!`);
110
+ });
111
+ async function runCLI() {
112
+ cli.parse(process$1.argv, { run: false });
113
+ if (cli.options.debug) {
114
+ let namespace;
115
+ if (cli.options.debug === true) namespace = "tsdown:*";
116
+ else namespace = resolveComma(toArray(cli.options.debug)).map((v) => `tsdown:${v}`).join(",");
117
+ const enabled = debug.disable();
118
+ if (enabled) namespace += `,${enabled}`;
119
+ debug.enable(namespace);
120
+ debug("tsdown:debug")("Debugging enabled", namespace);
121
+ }
122
+ try {
123
+ await cli.runMatchedCommand();
124
+ } catch (error) {
125
+ logger.error(error);
126
+ process$1.exit(1);
127
+ }
128
+ }
129
+
130
+ //#endregion
131
+ //#region src/run.ts
132
+ try {
133
+ module.enableCompileCache?.();
134
+ } catch {}
135
+ runCLI();
136
+
137
+ //#endregion
package/esm-shims.js ADDED
@@ -0,0 +1,9 @@
1
+ // Shim globals in esm bundle
2
+ import path from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+
5
+ const getFilename = () => fileURLToPath(import.meta.url)
6
+ const getDirname = () => path.dirname(getFilename())
7
+
8
+ export const __dirname = /* @__PURE__ */ getDirname()
9
+ export const __filename = /* @__PURE__ */ getFilename()
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "create-tsdown",
3
+ "version": "0.0.1",
4
+ "description": "The Elegant Bundler for Libraries",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/rolldown/tsdown#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/rolldown/tsdown/issues"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/rolldown/tsdown.git"
14
+ },
15
+ "author": "三咲智子 Kevin Deng <sxzz@sxzz.moe>",
16
+ "funding": "https://github.com/sponsors/sxzz",
17
+ "files": [
18
+ "dist",
19
+ "esm-shims.js"
20
+ ],
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "exports": {
25
+ ".": "./dist/index.js",
26
+ "./run": "./dist/run.js",
27
+ "./package.json": "./package.json"
28
+ },
29
+ "typesVersions": {
30
+ "*": {
31
+ "*": [
32
+ "./dist/*",
33
+ "./*"
34
+ ]
35
+ }
36
+ },
37
+ "bin": {
38
+ "create-tsdown": "./dist/run.js"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "peerDependencies": {
44
+ "typescript": "^5.0.0"
45
+ },
46
+ "peerDependenciesMeta": {
47
+ "typescript": {
48
+ "optional": true
49
+ }
50
+ },
51
+ "dependencies": {
52
+ "@clack/prompts": "^0.11.0",
53
+ "ansis": "^4.0.0",
54
+ "cac": "^6.7.14",
55
+ "debug": "^4.4.1",
56
+ "diff": "^8.0.1",
57
+ "giget": "^2.0.0",
58
+ "rolldown": "1.0.0-beta.9-commit.51df2b7"
59
+ },
60
+ "devDependencies": {
61
+ "@oxc-node/core": "^0.0.27",
62
+ "@sxzz/eslint-config": "^7.0.1",
63
+ "@sxzz/prettier-config": "^2.2.1",
64
+ "@sxzz/test-utils": "^0.5.6",
65
+ "@types/debug": "^4.1.12",
66
+ "@types/node": "^22.15.21",
67
+ "bumpp": "^10.1.1",
68
+ "eslint": "^9.27.0",
69
+ "prettier": "^3.5.3",
70
+ "tsdown": "^0.12.2",
71
+ "typescript": "~5.8.3",
72
+ "unplugin-unused": "^0.5.0",
73
+ "vitest": "^3.1.4"
74
+ },
75
+ "engines": {
76
+ "node": ">=18.0.0"
77
+ },
78
+ "prettier": "@sxzz/prettier-config",
79
+ "scripts": {
80
+ "lint": "eslint --cache --max-warnings 0 .",
81
+ "lint:fix": "pnpm run lint --fix",
82
+ "build": "tsdown",
83
+ "dev": "node --import @oxc-node/core/register ./src/run.ts",
84
+ "dev:migrate": "node --import @oxc-node/core/register ./src/run.ts migrate --dry-run",
85
+ "test": "vitest",
86
+ "typecheck": "tsc --noEmit",
87
+ "format": "prettier --cache --write .",
88
+ "release": "bumpp && pnpm publish"
89
+ }
90
+ }