@master/create-css 2.0.0-rc.69 → 2.0.0-rc.79
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 +21 -0
- package/README.md +65 -56
- package/dist/bin/index.d.ts +1 -0
- package/dist/bin/index.js +6 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +36 -0
- package/dist/core.d.ts +28 -0
- package/dist/core.js +116 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +326 -0
- package/dist/transforms.d.ts +24 -0
- package/dist/transforms.js +232 -0
- package/package.json +51 -1
- package/dist/bin/index.mjs +0 -206
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Aoyue Design LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,56 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
1
|
+
# @master/create-css
|
|
2
|
+
|
|
3
|
+
Add Master CSS to an existing project.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm create @master/css@rc -- --yes
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or run the package directly:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @master/create-css@rc add --yes
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The recommended workflow adds Master CSS to the detected framework and includes the development guardrails Master CSS expects by default:
|
|
18
|
+
|
|
19
|
+
- `@master/eslint-config-css` and `eslint.config.js`
|
|
20
|
+
- `@master/css-mcp` with the stdio registration command in the summary
|
|
21
|
+
- Master CSS guidance in `AGENTS.md`
|
|
22
|
+
|
|
23
|
+
With `--yes`, recommended defaults are accepted and dependency installation runs with the detected package manager unless `--no-install` is passed.
|
|
24
|
+
|
|
25
|
+
Without `--yes`, TTY sessions ask about ESLint, MCP, AI guidance, and dependency installation. Each prompt defaults to yes. Non-TTY sessions apply recommended defaults without installing dependencies unless `--install <package-manager>` is passed.
|
|
26
|
+
|
|
27
|
+
Use `--minimal` for core framework setup only, or disable individual recommended integrations with `--no-eslint`, `--no-mcp`, or `--no-ai`.
|
|
28
|
+
|
|
29
|
+
If you do not have a project yet, create one first:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm create vite@latest my-app
|
|
33
|
+
cd my-app
|
|
34
|
+
npm create @master/css@rc -- --yes
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx @master/create-css@rc add --yes
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @master/create-css@rc add --minimal
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx @master/create-css@rc add --no-mcp --no-ai
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx @master/create-css@rc add --json --minimal --eslint
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Supported `--framework` values:
|
|
56
|
+
|
|
57
|
+
```txt
|
|
58
|
+
auto, vite, react, react-router, vue, nextjs, svelte, nuxt, astro, webpack, rspack, rsbuild, laravel, lit, angular, none
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
SvelteKit setup is delegated to the Svelte CLI add-on:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx sv add @master/css-sv
|
|
65
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/constants.d.ts
|
|
2
|
+
declare const MASTER_CSS_VERSION = "rc";
|
|
3
|
+
declare const MASTER_CSS_PACKAGES: {
|
|
4
|
+
readonly css: "@master/css";
|
|
5
|
+
readonly runtime: "@master/css-runtime";
|
|
6
|
+
readonly preset: "@master/css-preset";
|
|
7
|
+
readonly cli: "@master/css-cli";
|
|
8
|
+
readonly vite: "@master/css.vite";
|
|
9
|
+
readonly next: "@master/css.next";
|
|
10
|
+
readonly nuxt: "@master/css.nuxt";
|
|
11
|
+
readonly astro: "@master/css.astro";
|
|
12
|
+
readonly svelte: "@master/css.svelte";
|
|
13
|
+
readonly svelteAddon: "@master/css-sv";
|
|
14
|
+
readonly webpack: "@master/css.webpack";
|
|
15
|
+
readonly eslintConfig: "@master/eslint-config-css";
|
|
16
|
+
readonly mcp: "@master/css-mcp";
|
|
17
|
+
};
|
|
18
|
+
declare const CANONICAL_ESLINT_CONFIG = "import { defineConfig } from 'eslint/config'\nimport css from '@master/eslint-config-css'\n\nexport default defineConfig([\n ...css\n])\n";
|
|
19
|
+
declare const AGENT_RULES_BLOCK = "## Master CSS\n\n- Use https://rc.css.master.co as the source of truth.\n- Inspect the framework, package manager, CSS entry, rendering mode, theme tokens, component classes, utilities, custom variants, and validation commands before editing styles.\n- Prefer existing @theme tokens, @components, @utilities, and @custom-variant definitions.\n- Use the Master CSS MCP server when available.\n- Use ESLint for class policy diagnostics and the Master CSS Language Service for completion, hover, colors, highlighting, and directive formatting.\n- Do not invent Master CSS APIs, directives, package names, or Tailwind-style syntax.\n- Preserve semantic HTML, accessibility attributes, and behavior.\n";
|
|
20
|
+
//#endregion
|
|
21
|
+
export { AGENT_RULES_BLOCK, CANONICAL_ESLINT_CONFIG, MASTER_CSS_PACKAGES, MASTER_CSS_VERSION };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/constants.ts
|
|
2
|
+
const MASTER_CSS_VERSION = "rc";
|
|
3
|
+
const MASTER_CSS_PACKAGES = {
|
|
4
|
+
css: "@master/css",
|
|
5
|
+
runtime: "@master/css-runtime",
|
|
6
|
+
preset: "@master/css-preset",
|
|
7
|
+
cli: "@master/css-cli",
|
|
8
|
+
vite: "@master/css.vite",
|
|
9
|
+
next: "@master/css.next",
|
|
10
|
+
nuxt: "@master/css.nuxt",
|
|
11
|
+
astro: "@master/css.astro",
|
|
12
|
+
svelte: "@master/css.svelte",
|
|
13
|
+
svelteAddon: "@master/css-sv",
|
|
14
|
+
webpack: "@master/css.webpack",
|
|
15
|
+
eslintConfig: "@master/eslint-config-css",
|
|
16
|
+
mcp: "@master/css-mcp"
|
|
17
|
+
};
|
|
18
|
+
const CANONICAL_ESLINT_CONFIG = `import { defineConfig } from 'eslint/config'
|
|
19
|
+
import css from '@master/eslint-config-css'
|
|
20
|
+
|
|
21
|
+
export default defineConfig([
|
|
22
|
+
...css
|
|
23
|
+
])
|
|
24
|
+
`;
|
|
25
|
+
const AGENT_RULES_BLOCK = `## Master CSS
|
|
26
|
+
|
|
27
|
+
- Use https://rc.css.master.co as the source of truth.
|
|
28
|
+
- Inspect the framework, package manager, CSS entry, rendering mode, theme tokens, component classes, utilities, custom variants, and validation commands before editing styles.
|
|
29
|
+
- Prefer existing @theme tokens, @components, @utilities, and @custom-variant definitions.
|
|
30
|
+
- Use the Master CSS MCP server when available.
|
|
31
|
+
- Use ESLint for class policy diagnostics and the Master CSS Language Service for completion, hover, colors, highlighting, and directive formatting.
|
|
32
|
+
- Do not invent Master CSS APIs, directives, package names, or Tailwind-style syntax.
|
|
33
|
+
- Preserve semantic HTML, accessibility attributes, and behavior.
|
|
34
|
+
`;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { AGENT_RULES_BLOCK, CANONICAL_ESLINT_CONFIG, MASTER_CSS_PACKAGES, MASTER_CSS_VERSION };
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/core.d.ts
|
|
2
|
+
type CommandFramework = 'none' | 'vite' | 'react' | 'react-router' | 'vue' | 'nextjs' | 'svelte' | 'nuxt' | 'astro' | 'webpack' | 'rspack' | 'rsbuild' | 'laravel' | 'lit' | 'angular';
|
|
3
|
+
type CommandFrameworkOption = CommandFramework | 'auto';
|
|
4
|
+
type CommandPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
5
|
+
interface CommandOptions {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
framework?: CommandFrameworkOption;
|
|
8
|
+
eslint?: boolean;
|
|
9
|
+
mcp?: boolean;
|
|
10
|
+
ai?: boolean;
|
|
11
|
+
minimal?: boolean;
|
|
12
|
+
install?: CommandPackageManager | false;
|
|
13
|
+
dryRun?: boolean;
|
|
14
|
+
json?: boolean;
|
|
15
|
+
yes?: boolean;
|
|
16
|
+
}
|
|
17
|
+
type InstallResolution = CommandPackageManager | false | 'detected' | undefined;
|
|
18
|
+
type PromptQuestion = (question: string) => Promise<string>;
|
|
19
|
+
interface ResolvedCommandOptions {
|
|
20
|
+
eslint: boolean;
|
|
21
|
+
mcp: boolean;
|
|
22
|
+
ai: boolean;
|
|
23
|
+
install: InstallResolution;
|
|
24
|
+
}
|
|
25
|
+
declare function runProgram(argv?: string[]): Promise<void>;
|
|
26
|
+
declare function resolveCommandOptions(options: CommandOptions, prompt?: PromptQuestion): Promise<ResolvedCommandOptions>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { CommandOptions, InstallResolution, PromptQuestion, ResolvedCommandOptions, runProgram as default, resolveCommandOptions };
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { applySetupPlan, createSetupPlan } from "./index.js";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { createInterface } from "node:readline/promises";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
//#region src/core.ts
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, "../package.json"), "utf8"));
|
|
10
|
+
const newProjectCommands = [
|
|
11
|
+
"npm create vite@latest my-app",
|
|
12
|
+
"cd my-app",
|
|
13
|
+
"npm create @master/css@rc -- --yes"
|
|
14
|
+
];
|
|
15
|
+
async function runProgram(argv = process.argv) {
|
|
16
|
+
const program = new Command();
|
|
17
|
+
program.name("create-css").description(pkg.description).version(pkg.version || "0.0.0");
|
|
18
|
+
const configure = (command) => command.option("-C, --cwd <path>", "Project root to update.").option("--framework <framework>", "Framework: auto, vite, react, react-router, vue, nextjs, svelte, nuxt, astro, webpack, rspack, rsbuild, laravel, lit, angular, none.", "auto").option("--eslint", "Add the Master CSS recommended ESLint flat config.").option("--no-eslint", "Skip the Master CSS recommended ESLint flat config.").option("--mcp", "Add the Master CSS MCP package and print the stdio registration command.").option("--no-mcp", "Skip the Master CSS MCP package and registration command.").option("--ai", "Add Master CSS guidance to AGENTS.md.").option("--no-ai", "Skip Master CSS guidance for coding agents.").option("--minimal", "Only add core Master CSS framework setup.").option("--install <package-manager>", "Run dependency installation with npm, pnpm, yarn, or bun after edits.").option("--no-install", "Do not run dependency installation.").option("--dry-run", "Print the setup plan without writing files.").option("--json", "Print machine-readable JSON.").option("-y, --yes", "Accept recommended defaults and run package installation with the detected package manager.");
|
|
19
|
+
configure(program).argument("[project name]", "Deprecated. The installer now updates the current project; use --cwd for another root.").action(async (projectName, options) => {
|
|
20
|
+
if (projectName && projectName !== "add") program.error(`Project scaffolding is not provided by @master/create-css. Create a Vite project first, then run the installer from the project root:\n\n${formatNewProjectCommands()}`);
|
|
21
|
+
await runAdd(options);
|
|
22
|
+
});
|
|
23
|
+
configure(program.command("add").description("Add Master CSS to an existing project.")).action(runAdd);
|
|
24
|
+
await program.parseAsync(argv);
|
|
25
|
+
}
|
|
26
|
+
async function runAdd(options) {
|
|
27
|
+
const root = resolve(options.cwd || process.cwd());
|
|
28
|
+
if (!options.dryRun && !options.json && !existsSync(join(root, "package.json"))) {
|
|
29
|
+
printNonProjectGuidance(root);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const prompt = shouldPrompt(options) ? createTTYPrompt() : void 0;
|
|
33
|
+
let resolvedOptions;
|
|
34
|
+
try {
|
|
35
|
+
resolvedOptions = await resolveCommandOptions(options, prompt?.question);
|
|
36
|
+
} finally {
|
|
37
|
+
prompt?.close();
|
|
38
|
+
}
|
|
39
|
+
const planInstall = resolvedOptions.install === "detected" ? void 0 : resolvedOptions.install;
|
|
40
|
+
const plan = createSetupPlan({
|
|
41
|
+
root,
|
|
42
|
+
framework: options.framework,
|
|
43
|
+
eslint: resolvedOptions.eslint,
|
|
44
|
+
mcp: resolvedOptions.mcp,
|
|
45
|
+
ai: resolvedOptions.ai,
|
|
46
|
+
install: planInstall
|
|
47
|
+
});
|
|
48
|
+
if (options.dryRun || options.json) {
|
|
49
|
+
process.stdout.write(`${JSON.stringify(plan, null, 2)}\n`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
applySetupPlan(plan, { install: resolvedOptions.install === "detected" ? plan.packageManager : resolvedOptions.install });
|
|
53
|
+
if (!options.json) printSummary(plan);
|
|
54
|
+
}
|
|
55
|
+
async function resolveCommandOptions(options, prompt) {
|
|
56
|
+
const question = options.yes ? void 0 : prompt;
|
|
57
|
+
return {
|
|
58
|
+
eslint: await resolveRecommendedBoolean(options.eslint, options.minimal, "Add Master CSS ESLint diagnostics?", question),
|
|
59
|
+
mcp: await resolveRecommendedBoolean(options.mcp, options.minimal, "Add the Master CSS MCP package?", question),
|
|
60
|
+
ai: await resolveRecommendedBoolean(options.ai, options.minimal, "Add Master CSS AI agent guidance?", question),
|
|
61
|
+
install: await resolveInstall(options.install, options.yes, question)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function resolveRecommendedBoolean(value, minimal, question, prompt) {
|
|
65
|
+
if (value !== void 0) return value;
|
|
66
|
+
if (minimal) return false;
|
|
67
|
+
if (prompt) return confirm(question, prompt);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
async function resolveInstall(install, yes, prompt) {
|
|
71
|
+
if (install !== void 0) return install;
|
|
72
|
+
if (yes) return "detected";
|
|
73
|
+
if (prompt) return await confirm("Install dependencies now?", prompt) ? "detected" : false;
|
|
74
|
+
}
|
|
75
|
+
async function confirm(question, prompt) {
|
|
76
|
+
while (true) {
|
|
77
|
+
const answer = (await prompt(`${question} (Y/n) `)).trim().toLowerCase();
|
|
78
|
+
if (!answer || answer === "y" || answer === "yes") return true;
|
|
79
|
+
if (answer === "n" || answer === "no") return false;
|
|
80
|
+
process.stdout.write("Please answer yes or no.\n");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function shouldPrompt(options) {
|
|
84
|
+
return !options.yes && !options.json && !options.dryRun && Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
|
|
85
|
+
}
|
|
86
|
+
function createTTYPrompt() {
|
|
87
|
+
const input = process.stdin;
|
|
88
|
+
const output = process.stdout;
|
|
89
|
+
const rl = createInterface({
|
|
90
|
+
input,
|
|
91
|
+
output
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
question: (question) => rl.question(question),
|
|
95
|
+
close: () => rl.close()
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function printNonProjectGuidance(root) {
|
|
99
|
+
process.stdout.write(`No package.json was found in ${root}.\n`);
|
|
100
|
+
process.stdout.write("@master/create-css adds Master CSS to an existing project.\n\n");
|
|
101
|
+
process.stdout.write("Create a Vite project first, then run the installer from the project root:\n\n");
|
|
102
|
+
process.stdout.write(`${formatNewProjectCommands()}\n`);
|
|
103
|
+
}
|
|
104
|
+
function formatNewProjectCommands() {
|
|
105
|
+
return newProjectCommands.map((command) => ` ${command}`).join("\n");
|
|
106
|
+
}
|
|
107
|
+
function printSummary(plan) {
|
|
108
|
+
process.stdout.write(`Master CSS setup complete for ${plan.framework}.\n`);
|
|
109
|
+
process.stdout.write(`Dependencies planned: ${plan.summary.dependencies}\n`);
|
|
110
|
+
process.stdout.write(`Files created: ${plan.summary.filesToCreate}\n`);
|
|
111
|
+
process.stdout.write(`Files updated: ${plan.summary.filesToUpdate}\n`);
|
|
112
|
+
for (const warning of plan.warnings) process.stdout.write(`Warning: ${warning}\n`);
|
|
113
|
+
for (const command of plan.commands) process.stdout.write(`Next: ${command.command}\n`);
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { runProgram as default, resolveCommandOptions };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
type Framework = 'none' | 'vite' | 'react' | 'react-router' | 'vue' | 'nextjs' | 'svelte' | 'nuxt' | 'astro' | 'webpack' | 'rspack' | 'rsbuild' | 'laravel' | 'lit' | 'angular';
|
|
3
|
+
type FrameworkOption = Framework | 'auto';
|
|
4
|
+
type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
5
|
+
type FileAction = 'create' | 'update' | 'skip';
|
|
6
|
+
interface SetupOptions {
|
|
7
|
+
root?: string;
|
|
8
|
+
framework?: FrameworkOption;
|
|
9
|
+
eslint?: boolean;
|
|
10
|
+
mcp?: boolean;
|
|
11
|
+
ai?: boolean;
|
|
12
|
+
minimal?: boolean;
|
|
13
|
+
install?: PackageManager | false;
|
|
14
|
+
yes?: boolean;
|
|
15
|
+
packageTag?: string;
|
|
16
|
+
}
|
|
17
|
+
interface PlannedDependency {
|
|
18
|
+
name: string;
|
|
19
|
+
version: string;
|
|
20
|
+
dev: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface PlannedFileChange {
|
|
23
|
+
path: string;
|
|
24
|
+
action: FileAction;
|
|
25
|
+
content?: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
}
|
|
28
|
+
interface PlannedCommand {
|
|
29
|
+
command: string;
|
|
30
|
+
reason: string;
|
|
31
|
+
}
|
|
32
|
+
interface SetupPlan {
|
|
33
|
+
version: 1;
|
|
34
|
+
root: string;
|
|
35
|
+
framework: Framework;
|
|
36
|
+
packageManager: PackageManager;
|
|
37
|
+
dependencies: PlannedDependency[];
|
|
38
|
+
files: PlannedFileChange[];
|
|
39
|
+
commands: PlannedCommand[];
|
|
40
|
+
warnings: string[];
|
|
41
|
+
summary: {
|
|
42
|
+
dependencies: number;
|
|
43
|
+
filesToCreate: number;
|
|
44
|
+
filesToUpdate: number;
|
|
45
|
+
commands: number;
|
|
46
|
+
warnings: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
declare function createSetupPlan(options?: SetupOptions): SetupPlan;
|
|
50
|
+
declare function applySetupPlan(plan: SetupPlan, options?: SetupOptions): void;
|
|
51
|
+
declare function applySetup(options?: SetupOptions): SetupPlan;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { FileAction, Framework, FrameworkOption, PackageManager, PlannedCommand, PlannedDependency, PlannedFileChange, SetupOptions, SetupPlan, applySetup, applySetupPlan, createSetupPlan };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { AGENT_RULES_BLOCK, CANONICAL_ESLINT_CONFIG, MASTER_CSS_PACKAGES } from "./constants.js";
|
|
2
|
+
import { addAngularRuntimeSetup, addLitShadowRuntime, addMasterCSSAstroIntegration, addMasterCSSEslintConfig, addMasterCSSImportToStylesheet, addMasterCSSNextConfig, addMasterCSSNuxtModule, addMasterCSSRsbuildPlugin, addMasterCSSRspackPlugin, addMasterCSSStaticVitePlugin, addMasterCSSVitePlugin, addReactRouterRootCSSImport, addViteClientTypes, createAstroConfig, createMasterCSSStylesheet, createNextConfig, createNuxtConfig, createRsbuildConfig, createRspackConfig, createStaticViteConfig, createViteConfig } from "./transforms.js";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
const lockfiles = {
|
|
8
|
+
pnpm: "pnpm-lock.yaml",
|
|
9
|
+
npm: "package-lock.json",
|
|
10
|
+
yarn: "yarn.lock",
|
|
11
|
+
bun: "bun.lockb"
|
|
12
|
+
};
|
|
13
|
+
function createSetupPlan(options = {}) {
|
|
14
|
+
const root = resolve(options.root || process.cwd());
|
|
15
|
+
const packageJSON = readPackageJSON(root);
|
|
16
|
+
const packageManager = resolvePackageManager(root, packageJSON, options.install || void 0);
|
|
17
|
+
const framework = resolveFramework(root, packageJSON, options.framework || "auto");
|
|
18
|
+
const version = options.packageTag || "rc";
|
|
19
|
+
const eslint = resolveRecommendedOption(options.eslint, options.minimal);
|
|
20
|
+
const mcp = resolveRecommendedOption(options.mcp, options.minimal);
|
|
21
|
+
const ai = resolveRecommendedOption(options.ai, options.minimal);
|
|
22
|
+
const dependencies = [];
|
|
23
|
+
const files = [];
|
|
24
|
+
const commands = [];
|
|
25
|
+
const warnings = [];
|
|
26
|
+
if (framework === "svelte") commands.push({
|
|
27
|
+
command: packageManager === "pnpm" ? "pnpm dlx sv add @master/css-sv" : packageManager === "yarn" ? "yarn dlx sv add @master/css-sv" : packageManager === "bun" ? "bunx sv add @master/css-sv" : "npx sv add @master/css-sv",
|
|
28
|
+
reason: "SvelteKit file setup is delegated to the official Svelte CLI add-on."
|
|
29
|
+
});
|
|
30
|
+
else {
|
|
31
|
+
for (const dependency of dependenciesForFramework(framework, version)) pushDependency(dependencies, dependency.name, dependency.dev, dependency.version);
|
|
32
|
+
files.push(...filesForFramework(root, framework, warnings));
|
|
33
|
+
}
|
|
34
|
+
if (eslint) {
|
|
35
|
+
pushDependency(dependencies, MASTER_CSS_PACKAGES.eslintConfig, true, version);
|
|
36
|
+
pushDependency(dependencies, "eslint", true, "^9.0.0 || ^10.0.0");
|
|
37
|
+
files.push(planTextFile(root, "eslint.config.js", addMasterCSSEslintConfig, CANONICAL_ESLINT_CONFIG, "Add the Master CSS recommended ESLint flat config."));
|
|
38
|
+
}
|
|
39
|
+
if (mcp) {
|
|
40
|
+
pushDependency(dependencies, MASTER_CSS_PACKAGES.mcp, true, version);
|
|
41
|
+
commands.push({
|
|
42
|
+
command: `npx -y @master/css-mcp@${version} --root ${root}`,
|
|
43
|
+
reason: "Use this stdio command when registering the Master CSS MCP server in an MCP client."
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (ai) files.push(planTextFile(root, "AGENTS.md", appendAgentRules, AGENT_RULES_BLOCK, "Add Master CSS instructions for local coding agents."));
|
|
47
|
+
if (!existsSync(join(root, "package.json"))) warnings.push("No package.json was found. Dependency changes will be skipped until a package.json exists.");
|
|
48
|
+
if (framework === "none") warnings.push("No supported framework was detected. The plan adds base Master CSS packages and a standalone stylesheet entry only.");
|
|
49
|
+
return {
|
|
50
|
+
version: 1,
|
|
51
|
+
root,
|
|
52
|
+
framework,
|
|
53
|
+
packageManager,
|
|
54
|
+
dependencies,
|
|
55
|
+
files,
|
|
56
|
+
commands,
|
|
57
|
+
warnings,
|
|
58
|
+
summary: {
|
|
59
|
+
dependencies: dependencies.length,
|
|
60
|
+
filesToCreate: files.filter((file) => file.action === "create").length,
|
|
61
|
+
filesToUpdate: files.filter((file) => file.action === "update").length,
|
|
62
|
+
commands: commands.length,
|
|
63
|
+
warnings: warnings.length
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function applySetupPlan(plan, options = {}) {
|
|
68
|
+
applyDependencyChanges(plan.root, plan.dependencies);
|
|
69
|
+
for (const file of plan.files) {
|
|
70
|
+
if (file.action === "skip" || file.content === void 0) continue;
|
|
71
|
+
const filePath = join(plan.root, file.path);
|
|
72
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
73
|
+
writeFileSync(filePath, file.content, "utf8");
|
|
74
|
+
}
|
|
75
|
+
const install = options.install === false ? false : options.install || (options.yes ? plan.packageManager : void 0);
|
|
76
|
+
if (install) {
|
|
77
|
+
const result = spawnSync(install, ["install"], {
|
|
78
|
+
cwd: plan.root,
|
|
79
|
+
stdio: "inherit",
|
|
80
|
+
shell: process.platform === "win32"
|
|
81
|
+
});
|
|
82
|
+
if (result.status) throw new Error(`${install} install failed with exit code ${result.status}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function applySetup(options = {}) {
|
|
86
|
+
const plan = createSetupPlan(options);
|
|
87
|
+
applySetupPlan(plan, options);
|
|
88
|
+
return plan;
|
|
89
|
+
}
|
|
90
|
+
function filesForFramework(root, framework, warnings) {
|
|
91
|
+
switch (framework) {
|
|
92
|
+
case "vite": return [planTextFile(root, firstExistingPath(root, [
|
|
93
|
+
"vite.config.ts",
|
|
94
|
+
"vite.config.js",
|
|
95
|
+
"vite.config.mjs"
|
|
96
|
+
], "vite.config.js"), addMasterCSSVitePlugin, createViteConfig(), "Register the Master CSS Vite plugin."), planTextFile(root, firstExistingPath(root, [
|
|
97
|
+
"src/style.css",
|
|
98
|
+
"src/index.css",
|
|
99
|
+
"src/main.css"
|
|
100
|
+
], "src/style.css"), addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the project CSS entry.")];
|
|
101
|
+
case "react": return [planTextFile(root, firstExistingPath(root, [
|
|
102
|
+
"vite.config.ts",
|
|
103
|
+
"vite.config.js",
|
|
104
|
+
"vite.config.mjs"
|
|
105
|
+
], "vite.config.js"), addMasterCSSVitePlugin, createViteConfig(), "Register the Master CSS Vite plugin."), planTextFile(root, firstExistingPath(root, ["src/index.css", "src/style.css"], "src/index.css"), addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the React project CSS entry.")];
|
|
106
|
+
case "react-router": {
|
|
107
|
+
const files = [planTextFile(root, firstExistingPath(root, [
|
|
108
|
+
"vite.config.ts",
|
|
109
|
+
"vite.config.js",
|
|
110
|
+
"vite.config.mjs"
|
|
111
|
+
], "vite.config.ts"), addMasterCSSVitePlugin, createViteConfig(), "Register the Master CSS Vite plugin."), planTextFile(root, "app/app.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the React Router app stylesheet entry.")];
|
|
112
|
+
const rootEntryPath = findExistingPath(root, [
|
|
113
|
+
"app/root.tsx",
|
|
114
|
+
"app/root.jsx",
|
|
115
|
+
"app/root.ts",
|
|
116
|
+
"app/root.js"
|
|
117
|
+
]);
|
|
118
|
+
if (rootEntryPath) files.push(planTextFile(root, rootEntryPath, addReactRouterRootCSSImport, "", "Import the React Router app stylesheet from the root route."));
|
|
119
|
+
else warnings.push("No app/root.tsx, app/root.jsx, app/root.ts, or app/root.js file was found. Import ./app.css from the React Router root route manually after setup.");
|
|
120
|
+
return files;
|
|
121
|
+
}
|
|
122
|
+
case "vue": return [planTextFile(root, firstExistingPath(root, [
|
|
123
|
+
"vite.config.ts",
|
|
124
|
+
"vite.config.js",
|
|
125
|
+
"vite.config.mjs"
|
|
126
|
+
], "vite.config.ts"), addMasterCSSVitePlugin, createViteConfig(), "Register the Master CSS Vite plugin."), planTextFile(root, firstExistingPath(root, [
|
|
127
|
+
"src/assets/main.css",
|
|
128
|
+
"src/style.css",
|
|
129
|
+
"src/main.css"
|
|
130
|
+
], "src/assets/main.css"), addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the Vue project CSS entry.")];
|
|
131
|
+
case "nextjs": return [planTextFile(root, firstExistingPath(root, [
|
|
132
|
+
"next.config.ts",
|
|
133
|
+
"next.config.mjs",
|
|
134
|
+
"next.config.js"
|
|
135
|
+
], "next.config.js"), addMasterCSSNextConfig, createNextConfig(), "Register the Master CSS Next.js adapter."), planTextFile(root, "app/globals.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the Next.js global stylesheet entry.")];
|
|
136
|
+
case "nuxt": return [planTextFile(root, firstExistingPath(root, ["nuxt.config.ts", "nuxt.config.js"], "nuxt.config.ts"), addMasterCSSNuxtModule, createNuxtConfig(), "Register the Master CSS Nuxt module."), planTextFile(root, "assets/css/master.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create the Nuxt CSS entry referenced by nuxt.config.")];
|
|
137
|
+
case "astro": return [planTextFile(root, firstExistingPath(root, [
|
|
138
|
+
"astro.config.mjs",
|
|
139
|
+
"astro.config.js",
|
|
140
|
+
"astro.config.ts"
|
|
141
|
+
], "astro.config.mjs"), addMasterCSSAstroIntegration, createAstroConfig(), "Register the Master CSS Astro integration."), planTextFile(root, "src/styles/global.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create the Astro project CSS entry.")];
|
|
142
|
+
case "laravel": {
|
|
143
|
+
const viteConfigPath = findExistingPath(root, ["vite.config.ts", "vite.config.js"]);
|
|
144
|
+
const files = [planTextFile(root, "resources/css/app.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the Laravel Vite CSS entry.")];
|
|
145
|
+
if (viteConfigPath) files.unshift(planTextFile(root, viteConfigPath, addMasterCSSStaticVitePlugin, createStaticViteConfig(), "Register the Master CSS Vite plugin in static mode."));
|
|
146
|
+
else warnings.push("No vite.config.ts or vite.config.js was found. Add @master/css.vite to the Laravel Vite config manually after setup.");
|
|
147
|
+
return files;
|
|
148
|
+
}
|
|
149
|
+
case "lit": {
|
|
150
|
+
const files = [
|
|
151
|
+
planTextFile(root, firstExistingPath(root, [
|
|
152
|
+
"vite.config.ts",
|
|
153
|
+
"vite.config.js",
|
|
154
|
+
"vite.config.mjs"
|
|
155
|
+
], "vite.config.ts"), addMasterCSSVitePlugin, createViteConfig(), "Register the Master CSS Vite plugin."),
|
|
156
|
+
planTextFile(root, "src/index.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the Lit project CSS entry."),
|
|
157
|
+
planTextFile(root, "src/vite-env.d.ts", addViteClientTypes, `/// <reference types="vite/client" />
|
|
158
|
+
/// <reference types="@master/css-integration/client" />
|
|
159
|
+
`, "Add Vite and Master CSS integration client types.")
|
|
160
|
+
];
|
|
161
|
+
const elementPath = findExistingPath(root, ["src/my-element.ts", "src/my-element.js"]);
|
|
162
|
+
if (elementPath) files.push(planTextFile(root, elementPath, addLitShadowRuntime, "", "Initialize Master CSS Runtime for the Lit shadow root."));
|
|
163
|
+
else warnings.push("No standard src/my-element.ts or src/my-element.js file was found. Add @cssRuntime to Lit elements that render Master CSS classes inside shadow roots.");
|
|
164
|
+
return files;
|
|
165
|
+
}
|
|
166
|
+
case "angular": {
|
|
167
|
+
const files = [planTextFile(root, "src/styles.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the Angular global stylesheet entry.")];
|
|
168
|
+
const mainPath = findExistingPath(root, ["src/main.ts"]);
|
|
169
|
+
if (mainPath) files.unshift(planTextFile(root, mainPath, addAngularRuntimeSetup, "", "Initialize Master CSS Runtime in the Angular browser entry."));
|
|
170
|
+
else warnings.push("No src/main.ts file was found. Initialize CSSRuntime manually in the Angular browser entry after setup.");
|
|
171
|
+
return files;
|
|
172
|
+
}
|
|
173
|
+
case "rspack": return [planTextFile(root, firstExistingPath(root, [
|
|
174
|
+
"rspack.config.ts",
|
|
175
|
+
"rspack.config.mts",
|
|
176
|
+
"rspack.config.mjs",
|
|
177
|
+
"rspack.config.js",
|
|
178
|
+
"rspack.config.cjs"
|
|
179
|
+
], "rspack.config.mjs"), addMasterCSSRspackPlugin, createRspackConfig(), "Register the Master CSS Webpack-compatible plugin in the Rspack config."), planTextFile(root, "src/index.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the project CSS entry for Rspack.")];
|
|
180
|
+
case "rsbuild": return [planTextFile(root, firstExistingPath(root, [
|
|
181
|
+
"rsbuild.config.ts",
|
|
182
|
+
"rsbuild.config.mts",
|
|
183
|
+
"rsbuild.config.mjs",
|
|
184
|
+
"rsbuild.config.js"
|
|
185
|
+
], "rsbuild.config.ts"), addMasterCSSRsbuildPlugin, createRsbuildConfig(), "Register the Master CSS Webpack-compatible plugin through Rsbuild tools.rspack."), planTextFile(root, "src/index.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the project CSS entry for Rsbuild.")];
|
|
186
|
+
case "webpack": return [planTextFile(root, "src/index.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create or update the project CSS entry for Webpack.")];
|
|
187
|
+
default: return [planTextFile(root, "src/master.css", addMasterCSSImportToStylesheet, createMasterCSSStylesheet(), "Create a standalone Master CSS stylesheet entry.")];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function dependenciesForFramework(framework, version) {
|
|
191
|
+
const dependencies = [{
|
|
192
|
+
name: MASTER_CSS_PACKAGES.css,
|
|
193
|
+
version,
|
|
194
|
+
dev: false
|
|
195
|
+
}];
|
|
196
|
+
if (framework === "vite" || framework === "react" || framework === "react-router" || framework === "vue" || framework === "laravel" || framework === "lit") dependencies.push({
|
|
197
|
+
name: MASTER_CSS_PACKAGES.vite,
|
|
198
|
+
version,
|
|
199
|
+
dev: false
|
|
200
|
+
});
|
|
201
|
+
if (framework === "nextjs") dependencies.push({
|
|
202
|
+
name: MASTER_CSS_PACKAGES.next,
|
|
203
|
+
version,
|
|
204
|
+
dev: false
|
|
205
|
+
});
|
|
206
|
+
if (framework === "nuxt") dependencies.push({
|
|
207
|
+
name: MASTER_CSS_PACKAGES.nuxt,
|
|
208
|
+
version,
|
|
209
|
+
dev: false
|
|
210
|
+
});
|
|
211
|
+
if (framework === "astro") dependencies.push({
|
|
212
|
+
name: MASTER_CSS_PACKAGES.astro,
|
|
213
|
+
version,
|
|
214
|
+
dev: false
|
|
215
|
+
});
|
|
216
|
+
if (framework === "webpack" || framework === "rspack" || framework === "rsbuild") dependencies.push({
|
|
217
|
+
name: MASTER_CSS_PACKAGES.webpack,
|
|
218
|
+
version,
|
|
219
|
+
dev: false
|
|
220
|
+
});
|
|
221
|
+
if (framework === "none" || framework === "lit" || framework === "angular") dependencies.push({
|
|
222
|
+
name: MASTER_CSS_PACKAGES.runtime,
|
|
223
|
+
version,
|
|
224
|
+
dev: false
|
|
225
|
+
});
|
|
226
|
+
if (framework === "angular") dependencies.push({
|
|
227
|
+
name: MASTER_CSS_PACKAGES.preset,
|
|
228
|
+
version,
|
|
229
|
+
dev: false
|
|
230
|
+
});
|
|
231
|
+
return dependencies;
|
|
232
|
+
}
|
|
233
|
+
function planTextFile(root, path, transform, createContent, reason) {
|
|
234
|
+
const filePath = join(root, path);
|
|
235
|
+
if (!existsSync(filePath)) return {
|
|
236
|
+
path,
|
|
237
|
+
action: "create",
|
|
238
|
+
content: createContent,
|
|
239
|
+
reason
|
|
240
|
+
};
|
|
241
|
+
const content = readFileSync(filePath, "utf8");
|
|
242
|
+
const nextContent = transform(content);
|
|
243
|
+
return {
|
|
244
|
+
path,
|
|
245
|
+
action: nextContent === content ? "skip" : "update",
|
|
246
|
+
...nextContent === content ? {} : { content: nextContent },
|
|
247
|
+
reason
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function applyDependencyChanges(root, dependencies) {
|
|
251
|
+
if (!dependencies.length) return;
|
|
252
|
+
const packageJSONPath = join(root, "package.json");
|
|
253
|
+
if (!existsSync(packageJSONPath)) return;
|
|
254
|
+
const packageJSON = JSON.parse(readFileSync(packageJSONPath, "utf8"));
|
|
255
|
+
packageJSON.dependencies ||= {};
|
|
256
|
+
packageJSON.devDependencies ||= {};
|
|
257
|
+
for (const dependency of dependencies) {
|
|
258
|
+
const target = dependency.dev ? packageJSON.devDependencies : packageJSON.dependencies;
|
|
259
|
+
if ((dependency.dev ? packageJSON.dependencies : packageJSON.devDependencies)?.[dependency.name]) continue;
|
|
260
|
+
if (!target?.[dependency.name]) target[dependency.name] = dependency.version;
|
|
261
|
+
}
|
|
262
|
+
writeFileSync(packageJSONPath, `${JSON.stringify(packageJSON, null, 4)}\n`, "utf8");
|
|
263
|
+
}
|
|
264
|
+
function pushDependency(dependencies, name, dev, version) {
|
|
265
|
+
if (dependencies.some((dependency) => dependency.name === name)) return;
|
|
266
|
+
dependencies.push({
|
|
267
|
+
name,
|
|
268
|
+
dev,
|
|
269
|
+
version
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
function firstExistingPath(root, paths, fallback) {
|
|
273
|
+
return findExistingPath(root, paths) || fallback;
|
|
274
|
+
}
|
|
275
|
+
function findExistingPath(root, paths) {
|
|
276
|
+
return paths.find((path) => existsSync(join(root, path)));
|
|
277
|
+
}
|
|
278
|
+
function readPackageJSON(root) {
|
|
279
|
+
try {
|
|
280
|
+
return JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
281
|
+
} catch {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function resolvePackageManager(root, packageJSON, explicit) {
|
|
286
|
+
if (isPackageManager(explicit)) return explicit;
|
|
287
|
+
const declared = packageJSON?.packageManager?.split("@")[0];
|
|
288
|
+
if (isPackageManager(declared)) return declared;
|
|
289
|
+
for (const [name, lockfile] of Object.entries(lockfiles)) if (existsSync(join(root, lockfile))) return name;
|
|
290
|
+
return "npm";
|
|
291
|
+
}
|
|
292
|
+
function resolveFramework(root, packageJSON, framework) {
|
|
293
|
+
if (framework !== "auto") return framework;
|
|
294
|
+
const dependencies = {
|
|
295
|
+
...packageJSON?.dependencies,
|
|
296
|
+
...packageJSON?.devDependencies
|
|
297
|
+
};
|
|
298
|
+
if (existsSync(join(root, "next.config.js")) || existsSync(join(root, "next.config.mjs")) || existsSync(join(root, "next.config.ts")) || dependencies.next) return "nextjs";
|
|
299
|
+
if (existsSync(join(root, "svelte.config.js")) || existsSync(join(root, "svelte.config.mjs")) || dependencies["@sveltejs/kit"]) return "svelte";
|
|
300
|
+
if (existsSync(join(root, "nuxt.config.ts")) || existsSync(join(root, "nuxt.config.js")) || dependencies.nuxt) return "nuxt";
|
|
301
|
+
if (existsSync(join(root, "astro.config.mjs")) || existsSync(join(root, "astro.config.js")) || dependencies.astro) return "astro";
|
|
302
|
+
if (existsSync(join(root, "angular.json")) || dependencies["@angular/core"]) return "angular";
|
|
303
|
+
if (dependencies["laravel-vite-plugin"] || existsSync(join(root, "artisan"))) return "laravel";
|
|
304
|
+
if (existsSync(join(root, "rsbuild.config.ts")) || existsSync(join(root, "rsbuild.config.mts")) || existsSync(join(root, "rsbuild.config.mjs")) || existsSync(join(root, "rsbuild.config.js")) || dependencies["@rsbuild/core"]) return "rsbuild";
|
|
305
|
+
if (existsSync(join(root, "rspack.config.ts")) || existsSync(join(root, "rspack.config.mts")) || existsSync(join(root, "rspack.config.mjs")) || existsSync(join(root, "rspack.config.js")) || existsSync(join(root, "rspack.config.cjs")) || dependencies["@rspack/core"] || dependencies["@rspack/cli"]) return "rspack";
|
|
306
|
+
if (existsSync(join(root, "react-router.config.ts")) || existsSync(join(root, "react-router.config.js")) || existsSync(join(root, "react-router.config.mjs")) || existsSync(join(root, "react-router.config.mts")) || dependencies["@react-router/dev"]) return "react-router";
|
|
307
|
+
if (dependencies.vue || dependencies["@vitejs/plugin-vue"] || existsSync(join(root, "src/App.vue"))) return "vue";
|
|
308
|
+
if (dependencies.lit) return "lit";
|
|
309
|
+
if (dependencies.react || dependencies["react-dom"]) return "react";
|
|
310
|
+
if (existsSync(join(root, "webpack.config.js")) || existsSync(join(root, "webpack.config.mjs")) || dependencies.webpack) return "webpack";
|
|
311
|
+
if (existsSync(join(root, "vite.config.ts")) || existsSync(join(root, "vite.config.js")) || dependencies.vite) return "vite";
|
|
312
|
+
return "none";
|
|
313
|
+
}
|
|
314
|
+
function isPackageManager(value) {
|
|
315
|
+
return value === "npm" || value === "pnpm" || value === "yarn" || value === "bun";
|
|
316
|
+
}
|
|
317
|
+
function resolveRecommendedOption(value, minimal) {
|
|
318
|
+
if (value !== void 0) return value;
|
|
319
|
+
return !minimal;
|
|
320
|
+
}
|
|
321
|
+
function appendAgentRules(content) {
|
|
322
|
+
if (content.includes("## Master CSS")) return content;
|
|
323
|
+
return `${content.trimEnd()}${content.trim() ? "\n\n" : ""}${AGENT_RULES_BLOCK}`;
|
|
324
|
+
}
|
|
325
|
+
//#endregion
|
|
326
|
+
export { applySetup, applySetupPlan, createSetupPlan };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/transforms.d.ts
|
|
2
|
+
declare function addMasterCSSImportToStylesheet(content: string): string;
|
|
3
|
+
declare function createMasterCSSStylesheet(): string;
|
|
4
|
+
declare function addMasterCSSVitePlugin(content: string): string;
|
|
5
|
+
declare function addReactRouterRootCSSImport(content: string): string;
|
|
6
|
+
declare function addMasterCSSStaticVitePlugin(content: string): string;
|
|
7
|
+
declare function addMasterCSSRspackPlugin(content: string): string;
|
|
8
|
+
declare function addMasterCSSRsbuildPlugin(content: string): string;
|
|
9
|
+
declare function createViteConfig(): string;
|
|
10
|
+
declare function createStaticViteConfig(): string;
|
|
11
|
+
declare function createRspackConfig(): string;
|
|
12
|
+
declare function createRsbuildConfig(): string;
|
|
13
|
+
declare function createNextConfig(): string;
|
|
14
|
+
declare function addMasterCSSNextConfig(content: string): string;
|
|
15
|
+
declare function addMasterCSSNuxtModule(content: string): string;
|
|
16
|
+
declare function createNuxtConfig(): string;
|
|
17
|
+
declare function addMasterCSSAstroIntegration(content: string): string;
|
|
18
|
+
declare function createAstroConfig(): string;
|
|
19
|
+
declare function addViteClientTypes(content: string): string;
|
|
20
|
+
declare function addLitShadowRuntime(content: string): string;
|
|
21
|
+
declare function addAngularRuntimeSetup(content: string): string;
|
|
22
|
+
declare function addMasterCSSEslintConfig(content: string): string;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { addAngularRuntimeSetup, addLitShadowRuntime, addMasterCSSAstroIntegration, addMasterCSSEslintConfig, addMasterCSSImportToStylesheet, addMasterCSSNextConfig, addMasterCSSNuxtModule, addMasterCSSRsbuildPlugin, addMasterCSSRspackPlugin, addMasterCSSStaticVitePlugin, addMasterCSSVitePlugin, addReactRouterRootCSSImport, addViteClientTypes, createAstroConfig, createMasterCSSStylesheet, createNextConfig, createNuxtConfig, createRsbuildConfig, createRspackConfig, createStaticViteConfig, createViteConfig };
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { CANONICAL_ESLINT_CONFIG } from "./constants.js";
|
|
2
|
+
//#region src/transforms.ts
|
|
3
|
+
function addImport(content, statement) {
|
|
4
|
+
if (content.includes(statement)) return content;
|
|
5
|
+
const lines = content.split("\n");
|
|
6
|
+
let insertIndex = 0;
|
|
7
|
+
while (insertIndex < lines.length && /^import\s/.test(lines[insertIndex])) insertIndex++;
|
|
8
|
+
lines.splice(insertIndex, 0, statement);
|
|
9
|
+
return lines.join("\n").replace(/\n{3,}/, "\n\n");
|
|
10
|
+
}
|
|
11
|
+
function ensureCSSImport(content) {
|
|
12
|
+
if (/^\s*@import\s+['"]@master\/css['"]\s*;/m.test(content)) return content;
|
|
13
|
+
return `@import '@master/css';\n${content ? `\n${content}` : ""}`;
|
|
14
|
+
}
|
|
15
|
+
function replaceFirst(content, pattern, replacement) {
|
|
16
|
+
return pattern.test(content) ? content.replace(pattern, replacement) : content;
|
|
17
|
+
}
|
|
18
|
+
function addMasterCSSImportToStylesheet(content) {
|
|
19
|
+
return ensureCSSImport(content);
|
|
20
|
+
}
|
|
21
|
+
function createMasterCSSStylesheet() {
|
|
22
|
+
return "@import '@master/css';\n";
|
|
23
|
+
}
|
|
24
|
+
function addMasterCSSVitePlugin(content) {
|
|
25
|
+
return addMasterCSSVitePluginCall(content, "masterCSS()");
|
|
26
|
+
}
|
|
27
|
+
function addReactRouterRootCSSImport(content) {
|
|
28
|
+
if (/^\s*import\s+['"]\.\/app\.css['"]\s*;?/m.test(content)) return content;
|
|
29
|
+
return addImport(content, "import './app.css'");
|
|
30
|
+
}
|
|
31
|
+
function addMasterCSSStaticVitePlugin(content) {
|
|
32
|
+
return addMasterCSSVitePluginCall(content, "masterCSS({ mode: 'static' })");
|
|
33
|
+
}
|
|
34
|
+
function addMasterCSSRspackPlugin(content) {
|
|
35
|
+
if (content.includes("@master/css.webpack")) return content;
|
|
36
|
+
let next = addImport(content, "import MasterCSSPlugin from '@master/css.webpack'");
|
|
37
|
+
if (/plugins\s*:\s*\[/.test(next)) return replaceFirst(next, /plugins\s*:\s*\[/, "plugins: [\n new MasterCSSPlugin(),");
|
|
38
|
+
if (/export\s+default\s+\{/.test(next)) return replaceFirst(next, /export\s+default\s+\{/, "export default {\n plugins: [new MasterCSSPlugin()],");
|
|
39
|
+
return next;
|
|
40
|
+
}
|
|
41
|
+
function addMasterCSSRsbuildPlugin(content) {
|
|
42
|
+
if (content.includes("@master/css.webpack")) return content;
|
|
43
|
+
let next = addImport(content, "import MasterCSSPlugin from '@master/css.webpack'");
|
|
44
|
+
const rspackSetupBody = ` config.plugins ||= []
|
|
45
|
+
config.plugins.push(new MasterCSSPlugin())
|
|
46
|
+
return config`;
|
|
47
|
+
const rspackSetup = `rspack(config) {
|
|
48
|
+
${rspackSetupBody}
|
|
49
|
+
}`;
|
|
50
|
+
if (/rspack\s*\(\s*config\s*\)\s*\{/.test(next)) return replaceFirst(next, /rspack\s*\(\s*config\s*\)\s*\{/, `rspack(config) {
|
|
51
|
+
${rspackSetupBody}`);
|
|
52
|
+
if (/tools\s*:\s*\{/.test(next)) return replaceFirst(next, /tools\s*:\s*\{/, `tools: {
|
|
53
|
+
${rspackSetup},`);
|
|
54
|
+
if (/defineConfig\(\s*\{/.test(next)) return replaceFirst(next, /defineConfig\(\s*\{/, `defineConfig({
|
|
55
|
+
tools: {
|
|
56
|
+
${rspackSetup}
|
|
57
|
+
},`);
|
|
58
|
+
if (/export\s+default\s+\{/.test(next)) return replaceFirst(next, /export\s+default\s+\{/, `export default {
|
|
59
|
+
tools: {
|
|
60
|
+
${rspackSetup}
|
|
61
|
+
},`);
|
|
62
|
+
return next;
|
|
63
|
+
}
|
|
64
|
+
function addMasterCSSVitePluginCall(content, pluginCall) {
|
|
65
|
+
if (content.includes("@master/css.vite")) return content;
|
|
66
|
+
let next = addImport(content, "import masterCSS from '@master/css.vite'");
|
|
67
|
+
if (/plugins\s*:\s*\[/.test(next)) return replaceFirst(next, /plugins\s*:\s*\[/, `plugins: [\n ${pluginCall},`);
|
|
68
|
+
if (/defineConfig\(\s*\{/.test(next)) return replaceFirst(next, /defineConfig\(\s*\{/, `defineConfig({\n plugins: [${pluginCall}],`);
|
|
69
|
+
return next;
|
|
70
|
+
}
|
|
71
|
+
function createViteConfig() {
|
|
72
|
+
return `import { defineConfig } from 'vite'
|
|
73
|
+
import masterCSS from '@master/css.vite'
|
|
74
|
+
|
|
75
|
+
export default defineConfig({
|
|
76
|
+
plugins: [
|
|
77
|
+
masterCSS()
|
|
78
|
+
]
|
|
79
|
+
})
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
function createStaticViteConfig() {
|
|
83
|
+
return `import { defineConfig } from 'vite'
|
|
84
|
+
import masterCSS from '@master/css.vite'
|
|
85
|
+
|
|
86
|
+
export default defineConfig({
|
|
87
|
+
plugins: [
|
|
88
|
+
masterCSS({ mode: 'static' })
|
|
89
|
+
]
|
|
90
|
+
})
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
function createRspackConfig() {
|
|
94
|
+
return `import MasterCSSPlugin from '@master/css.webpack'
|
|
95
|
+
|
|
96
|
+
export default {
|
|
97
|
+
module: {
|
|
98
|
+
rules: [
|
|
99
|
+
{
|
|
100
|
+
test: /\\.css$/i,
|
|
101
|
+
type: 'css/auto'
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
plugins: [
|
|
106
|
+
new MasterCSSPlugin()
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
function createRsbuildConfig() {
|
|
112
|
+
return `import { defineConfig } from '@rsbuild/core'
|
|
113
|
+
import MasterCSSPlugin from '@master/css.webpack'
|
|
114
|
+
|
|
115
|
+
export default defineConfig({
|
|
116
|
+
tools: {
|
|
117
|
+
rspack(config) {
|
|
118
|
+
config.plugins ||= []
|
|
119
|
+
config.plugins.push(new MasterCSSPlugin())
|
|
120
|
+
return config
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
function createNextConfig() {
|
|
127
|
+
return `import { withMasterCSS } from '@master/css.next'
|
|
128
|
+
|
|
129
|
+
const nextConfig = withMasterCSS({})
|
|
130
|
+
|
|
131
|
+
export default nextConfig
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
function addMasterCSSNextConfig(content) {
|
|
135
|
+
if (content.includes("@master/css.next")) return content;
|
|
136
|
+
const next = addImport(content, "import { withMasterCSS } from '@master/css.next'");
|
|
137
|
+
if (/export\s+default\s+/.test(next)) return next.replace(/export\s+default\s+([^;\n]+)(;?)(\n|$)/, "export default withMasterCSS($1)$2$3");
|
|
138
|
+
return `${next.trimEnd()}
|
|
139
|
+
|
|
140
|
+
export default withMasterCSS({})
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
function addMasterCSSNuxtModule(content) {
|
|
144
|
+
if (content.includes("@master/css.nuxt")) return content;
|
|
145
|
+
if (/modules\s*:\s*\[/.test(content)) return replaceFirst(content, /modules\s*:\s*\[/, "modules: [\n '@master/css.nuxt',");
|
|
146
|
+
if (/defineNuxtConfig\(\s*\{/.test(content)) return replaceFirst(content, /defineNuxtConfig\(\s*\{/, "defineNuxtConfig({\n modules: ['@master/css.nuxt'],");
|
|
147
|
+
return content;
|
|
148
|
+
}
|
|
149
|
+
function createNuxtConfig() {
|
|
150
|
+
return `export default defineNuxtConfig({
|
|
151
|
+
modules: ['@master/css.nuxt'],
|
|
152
|
+
css: ['~/assets/css/master.css']
|
|
153
|
+
})
|
|
154
|
+
`;
|
|
155
|
+
}
|
|
156
|
+
function addMasterCSSAstroIntegration(content) {
|
|
157
|
+
if (content.includes("@master/css.astro")) return content;
|
|
158
|
+
let next = addImport(content, "import masterCSS from '@master/css.astro'");
|
|
159
|
+
if (/integrations\s*:\s*\[/.test(next)) return replaceFirst(next, /integrations\s*:\s*\[/, "integrations: [\n masterCSS(),");
|
|
160
|
+
if (/defineConfig\(\s*\{/.test(next)) return replaceFirst(next, /defineConfig\(\s*\{/, "defineConfig({\n integrations: [masterCSS()],");
|
|
161
|
+
return next;
|
|
162
|
+
}
|
|
163
|
+
function createAstroConfig() {
|
|
164
|
+
return `import { defineConfig } from 'astro/config'
|
|
165
|
+
import masterCSS from '@master/css.astro'
|
|
166
|
+
|
|
167
|
+
export default defineConfig({
|
|
168
|
+
integrations: [
|
|
169
|
+
masterCSS()
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
function addViteClientTypes(content) {
|
|
175
|
+
let next = content;
|
|
176
|
+
if (!next.includes("/// <reference types=\"vite/client\" />")) next = `/// <reference types="vite/client" />\n${next}`;
|
|
177
|
+
if (!next.includes("/// <reference types=\"@master/css-integration/client\" />")) {
|
|
178
|
+
const lines = next.split("\n");
|
|
179
|
+
const viteReferenceIndex = lines.findIndex((line) => line.includes("/// <reference types=\"vite/client\" />"));
|
|
180
|
+
lines.splice(viteReferenceIndex + 1, 0, "/// <reference types=\"@master/css-integration/client\" />");
|
|
181
|
+
next = lines.join("\n");
|
|
182
|
+
}
|
|
183
|
+
return next;
|
|
184
|
+
}
|
|
185
|
+
function addLitShadowRuntime(content) {
|
|
186
|
+
if (content.includes("@master/css-runtime") && content.includes("virtual:master-css-manifest") && content.includes("@cssRuntime({ manifest, emittedGlobals })") && content.includes("cssRuntime?: CSSRuntime")) return content;
|
|
187
|
+
let next = addImport(content, "import { cssRuntime } from '@master/css-runtime'");
|
|
188
|
+
next = addImport(next, "import type { CSSRuntime } from '@master/css-runtime'");
|
|
189
|
+
next = addImport(next, "import manifest from 'virtual:master-css-manifest'");
|
|
190
|
+
next = addImport(next, "import emittedGlobals from 'virtual:master-css-emitted-globals'");
|
|
191
|
+
if (!next.includes("@cssRuntime({ manifest, emittedGlobals })")) if (/@customElement\([^\n]+\)\nexport\s+class\s/.test(next)) next = next.replace(/(@customElement\([^\n]+\)\n)(export\s+class\s)/, "$1@cssRuntime({ manifest, emittedGlobals })\n$2");
|
|
192
|
+
else next = next.replace(/export\s+class\s/, "@cssRuntime({ manifest, emittedGlobals })\nexport class ");
|
|
193
|
+
if (!next.includes("cssRuntime?: CSSRuntime")) next = next.replace(/(export\s+class\s+\w+[^{]*\{)/, "$1\n\n cssRuntime?: CSSRuntime");
|
|
194
|
+
return next;
|
|
195
|
+
}
|
|
196
|
+
function addAngularRuntimeSetup(content) {
|
|
197
|
+
if (content.includes("@master/css-runtime")) return content;
|
|
198
|
+
let next = addImport(content, "import defaultManifestJSON from '@master/css-preset/default-manifest.json'");
|
|
199
|
+
next = addImport(next, "import { CSSRuntime } from '@master/css-runtime'");
|
|
200
|
+
next = addImport(next, "import type { MasterCSSManifest } from '@master/css-runtime'");
|
|
201
|
+
const setup = `const defaultManifest = defaultManifestJSON as unknown as MasterCSSManifest
|
|
202
|
+
|
|
203
|
+
CSSRuntime.create({ manifest: defaultManifest }).observe()
|
|
204
|
+
|
|
205
|
+
`;
|
|
206
|
+
if (/bootstrapApplication\s*\(/.test(next)) return next.replace(/bootstrapApplication\s*\(/, `${setup}bootstrapApplication(`);
|
|
207
|
+
if (/platformBrowserDynamic\s*\(/.test(next)) return next.replace(/platformBrowserDynamic\s*\(/, `${setup}platformBrowserDynamic(`);
|
|
208
|
+
return `${next.trimEnd()}
|
|
209
|
+
|
|
210
|
+
${setup}`;
|
|
211
|
+
}
|
|
212
|
+
function addMasterCSSEslintConfig(content) {
|
|
213
|
+
if (content.includes("@master/eslint-config-css")) return content;
|
|
214
|
+
if (!content.trim()) return CANONICAL_ESLINT_CONFIG;
|
|
215
|
+
let next = addImport(content, "import { defineConfig } from 'eslint/config'");
|
|
216
|
+
next = addImport(next, "import css from '@master/eslint-config-css'");
|
|
217
|
+
if (/export\s+default\s+defineConfig\(\s*\[/.test(next)) return replaceFirst(next, /export\s+default\s+defineConfig\(\s*\[/, "export default defineConfig([\n ...css,");
|
|
218
|
+
if (/export\s+default\s+\[/.test(next)) {
|
|
219
|
+
next = replaceFirst(next, /export\s+default\s+\[/, "export default defineConfig([\n ...css,");
|
|
220
|
+
const closeIndex = next.lastIndexOf("]");
|
|
221
|
+
return closeIndex === -1 ? next : `${next.slice(0, closeIndex + 1)})${next.slice(closeIndex + 1)}`;
|
|
222
|
+
}
|
|
223
|
+
return `${next.trimEnd()}
|
|
224
|
+
|
|
225
|
+
// Master CSS recommended config:
|
|
226
|
+
// export default defineConfig([
|
|
227
|
+
// ...css
|
|
228
|
+
// ])
|
|
229
|
+
`;
|
|
230
|
+
}
|
|
231
|
+
//#endregion
|
|
232
|
+
export { addAngularRuntimeSetup, addLitShadowRuntime, addMasterCSSAstroIntegration, addMasterCSSEslintConfig, addMasterCSSImportToStylesheet, addMasterCSSNextConfig, addMasterCSSNuxtModule, addMasterCSSRsbuildPlugin, addMasterCSSRspackPlugin, addMasterCSSStaticVitePlugin, addMasterCSSVitePlugin, addReactRouterRootCSSImport, addViteClientTypes, createAstroConfig, createMasterCSSStylesheet, createNextConfig, createNuxtConfig, createRsbuildConfig, createRspackConfig, createStaticViteConfig, createViteConfig };
|
package/package.json
CHANGED
|
@@ -1 +1,51 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@master/create-css",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Add Master CSS to an existing project.",
|
|
6
|
+
"author": "Aoyue Design LLC.",
|
|
7
|
+
"funding": "https://rc.css.master.co/sponsor",
|
|
8
|
+
"homepage": "https://css.master.co",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/master-co/css/issues"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/master-co/css.git",
|
|
15
|
+
"directory": "packages/create"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"cli",
|
|
19
|
+
"create",
|
|
20
|
+
"init",
|
|
21
|
+
"css",
|
|
22
|
+
"mastercss"
|
|
23
|
+
],
|
|
24
|
+
"bin": {
|
|
25
|
+
"create-css": "./dist/bin/index.js"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public",
|
|
39
|
+
"provenance": true
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"commander": "^14.0.3"
|
|
43
|
+
},
|
|
44
|
+
"version": "2.0.0-rc.79",
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsdown --config ../../shared/tsdown-package.config.ts",
|
|
47
|
+
"dev": "tsdown --config ../../shared/tsdown-package.config.ts --watch",
|
|
48
|
+
"lint": "eslint",
|
|
49
|
+
"test": "vitest"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/dist/bin/index.mjs
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { readJSONFileSync } from '@techor/fs';
|
|
5
|
-
import log from '@techor/log';
|
|
6
|
-
import { detect } from 'detect-package-manager';
|
|
7
|
-
import { existsSync } from 'fs';
|
|
8
|
-
import { downloadTemplate } from 'giget';
|
|
9
|
-
import { execSync } from 'node:child_process';
|
|
10
|
-
import { writeFileSync, existsSync as existsSync$1 } from 'node:fs';
|
|
11
|
-
import ora from 'ora';
|
|
12
|
-
import { dirname } from 'path';
|
|
13
|
-
import { fileURLToPath } from 'url';
|
|
14
|
-
import { exit } from 'node:process';
|
|
15
|
-
|
|
16
|
-
var detectAppExt = (()=>{
|
|
17
|
-
// automatically detect the format
|
|
18
|
-
if (existsSync('tsconfig.json')) {
|
|
19
|
-
log.i`Detected **tsconfig.json**`;
|
|
20
|
-
return 'ts';
|
|
21
|
-
} else {
|
|
22
|
-
const { type } = readJSONFileSync('./package.json') || {};
|
|
23
|
-
if (type === 'module') {
|
|
24
|
-
log.i`package.json has **type="module"** set`;
|
|
25
|
-
return 'mjs';
|
|
26
|
-
} else {
|
|
27
|
-
return 'js';
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
var detectAppTech = (()=>{
|
|
33
|
-
if (existsSync('next.config.js') || existsSync('next.config.cjs') || existsSync('next.config.mjs') || existsSync('next.config.ts')) {
|
|
34
|
-
return 'nextjs';
|
|
35
|
-
}
|
|
36
|
-
if (existsSync('nuxt.config.js') || existsSync('nuxt.config.cjs') || existsSync('nuxt.config.mjs') || existsSync('nuxt.config.ts')) {
|
|
37
|
-
return 'nuxtjs';
|
|
38
|
-
}
|
|
39
|
-
if (existsSync('svelte.config.js') || existsSync('svelte.config.cjs') || existsSync('svelte.config.mjs') || existsSync('svelte.config.ts')) {
|
|
40
|
-
return 'svelte';
|
|
41
|
-
}
|
|
42
|
-
if (existsSync('astro.config.js') || existsSync('astro.config.cjs') || existsSync('astro.config.mjs') || existsSync('astro.config.ts')) {
|
|
43
|
-
return 'astro';
|
|
44
|
-
}
|
|
45
|
-
if (existsSync('composer.json')) {
|
|
46
|
-
return 'laravel';
|
|
47
|
-
}
|
|
48
|
-
if (existsSync('angular.json')) {
|
|
49
|
-
return 'angular';
|
|
50
|
-
}
|
|
51
|
-
const pkg = readJSONFileSync('package.json');
|
|
52
|
-
if (pkg?.dependencies?.['@sveltejs/kit'] || pkg?.devDependencies?.['@sveltejs/kit']) {
|
|
53
|
-
return 'svelte';
|
|
54
|
-
}
|
|
55
|
-
if (pkg?.dependencies?.['astro'] || pkg?.devDependencies?.['astro']) {
|
|
56
|
-
return 'astro';
|
|
57
|
-
}
|
|
58
|
-
if (pkg?.dependencies?.['next'] || pkg?.devDependencies?.['next']) {
|
|
59
|
-
return 'nextjs';
|
|
60
|
-
}
|
|
61
|
-
if (pkg?.dependencies?.['nuxt'] || pkg?.devDependencies?.['nuxt']) {
|
|
62
|
-
return 'nuxtjs';
|
|
63
|
-
}
|
|
64
|
-
if (pkg?.dependencies?.['@angular/core'] || pkg?.devDependencies?.['@angular/core']) {
|
|
65
|
-
return 'angular';
|
|
66
|
-
}
|
|
67
|
-
if (pkg?.dependencies?.['react'] || pkg?.devDependencies?.['react']) {
|
|
68
|
-
return 'react';
|
|
69
|
-
}
|
|
70
|
-
if (pkg?.dependencies?.['vue'] || pkg?.devDependencies?.['vue']) {
|
|
71
|
-
return 'vuejs';
|
|
72
|
-
}
|
|
73
|
-
if (existsSync('vite.config.js') || existsSync('vite.config.cjs') || existsSync('vite.config.mjs') || existsSync('vite.config.ts')) {
|
|
74
|
-
return 'vite';
|
|
75
|
-
}
|
|
76
|
-
if (existsSync('webpack.config.js') || existsSync('webpack.config.cjs') || existsSync('webpack.config.mjs') || existsSync('webpack.config.ts')) {
|
|
77
|
-
return 'webpack';
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
var CONFIG_ESM_TEXT = `/** @type {import('@master/css').Config} */
|
|
82
|
-
export default {
|
|
83
|
-
|
|
84
|
-
}`;
|
|
85
|
-
|
|
86
|
-
var CONFIG_TS_TEXT = `import type { Config } from '@master/css'
|
|
87
|
-
|
|
88
|
-
export default {
|
|
89
|
-
|
|
90
|
-
} as Config`;
|
|
91
|
-
|
|
92
|
-
var CONFIG_TEXT = `/** @type {import('@master/css').Config} */
|
|
93
|
-
module.exports = {
|
|
94
|
-
|
|
95
|
-
}`;
|
|
96
|
-
|
|
97
|
-
const BRANCH = 'rc';
|
|
98
|
-
const CURRENT_VERSION = 'rc' // ^2.0.0
|
|
99
|
-
;
|
|
100
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
101
|
-
const __dirname = dirname(__filename);
|
|
102
|
-
const pkg = readJSONFileSync(resolve(__dirname, '../../package.json'));
|
|
103
|
-
const program = new Command();
|
|
104
|
-
program.name(pkg.name).description(pkg.description).version(pkg.version || 'workspace:^').argument('[project name]', 'The project name is used to create the folder').option('-o, --override', 'Override existing definition file').option('--ext <ext>', 'Specify the extension mjs, ts, js').option('--pm <package manager>', 'Specify the package manager npm, yarn, pnpm, bun').option('--example <folder name>', 'Specify the example folder name', 'blank').action(async function(appName, options) {
|
|
105
|
-
if (!options.pm) {
|
|
106
|
-
options.pm = await detect();
|
|
107
|
-
}
|
|
108
|
-
// Create a new app with the example
|
|
109
|
-
if (appName) {
|
|
110
|
-
log.i(`Detected **${options.pm}**`);
|
|
111
|
-
const spinner = ora(`Initializing Master CSS`).start();
|
|
112
|
-
const examplePath = `github:master-co/css/examples/${options.example}#${BRANCH}`;
|
|
113
|
-
spinner.start(`Cloning example from "${examplePath}"`);
|
|
114
|
-
try {
|
|
115
|
-
await downloadTemplate(examplePath, {
|
|
116
|
-
dir: appName
|
|
117
|
-
});
|
|
118
|
-
} catch (error) {
|
|
119
|
-
spinner.fail(error.message);
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
process.chdir(appName);
|
|
123
|
-
const appPkg = readJSONFileSync('package.json');
|
|
124
|
-
if (!appPkg) {
|
|
125
|
-
spinner.stop();
|
|
126
|
-
log.i`View all examples at **https://github.com/master-co/css/tree/${BRANCH}/examples**`;
|
|
127
|
-
log.x(`Cannot found "${examplePath}"`);
|
|
128
|
-
exit(1);
|
|
129
|
-
}
|
|
130
|
-
appPkg.name = appName;
|
|
131
|
-
for(const key in appPkg.dependencies){
|
|
132
|
-
if (appPkg.dependencies[key] === 'workspace:^') {
|
|
133
|
-
appPkg.dependencies[key] = CURRENT_VERSION;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
for(const key in appPkg.devDependencies){
|
|
137
|
-
if (appPkg.devDependencies[key] === 'workspace:^') {
|
|
138
|
-
appPkg.devDependencies[key] = CURRENT_VERSION;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
writeFileSync('package.json', JSON.stringify(appPkg, null, 4), {
|
|
142
|
-
flag: 'w'
|
|
143
|
-
});
|
|
144
|
-
spinner.stop();
|
|
145
|
-
log.ok`Cloned example from "${examplePath}"`;
|
|
146
|
-
log``;
|
|
147
|
-
try {
|
|
148
|
-
execSync(`${options.pm} install`, {
|
|
149
|
-
stdio: 'inherit'
|
|
150
|
-
});
|
|
151
|
-
log``;
|
|
152
|
-
log.ok`Created **${appName}**`;
|
|
153
|
-
if (appPkg.scripts) {
|
|
154
|
-
log.i`Commands in this app:`;
|
|
155
|
-
console.table(appPkg.scripts);
|
|
156
|
-
}
|
|
157
|
-
log.i`Start by running "cd ${appName} && ${options.pm} run ${appPkg.scripts?.dev ? 'dev' : 'start'}"`;
|
|
158
|
-
} catch (error) {
|
|
159
|
-
spinner.fail();
|
|
160
|
-
throw error;
|
|
161
|
-
}
|
|
162
|
-
} else {
|
|
163
|
-
const appPkg = readJSONFileSync('package.json');
|
|
164
|
-
options.ext = options.ext || detectAppExt();
|
|
165
|
-
const create = (fileName, text)=>{
|
|
166
|
-
const configExists = existsSync$1(fileName);
|
|
167
|
-
if (!configExists) {
|
|
168
|
-
writeFileSync(fileName, text);
|
|
169
|
-
log.ok`Created **${fileName}**`;
|
|
170
|
-
} else if (configExists && options.override) {
|
|
171
|
-
writeFileSync(fileName, text);
|
|
172
|
-
log.ok`**${fileName}** is overridden`;
|
|
173
|
-
} else {
|
|
174
|
-
log.x`**${fileName}** already exists`;
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
// create master.css.* file
|
|
178
|
-
switch(options.ext){
|
|
179
|
-
case 'js':
|
|
180
|
-
create('master.css.js', CONFIG_TEXT);
|
|
181
|
-
break;
|
|
182
|
-
case 'mjs':
|
|
183
|
-
create('master.css.mjs', CONFIG_ESM_TEXT);
|
|
184
|
-
break;
|
|
185
|
-
case 'ts':
|
|
186
|
-
create('master.css.ts', CONFIG_TS_TEXT);
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
if (!appPkg?.dependencies?.['@master/css']) {
|
|
190
|
-
log.i(`Detected **${options.pm}**`);
|
|
191
|
-
log.i`Start "${options.pm} add @master/css@${BRANCH}"`;
|
|
192
|
-
log``;
|
|
193
|
-
execSync(`${options.pm} add @master/css@rc`, {
|
|
194
|
-
stdio: 'inherit'
|
|
195
|
-
});
|
|
196
|
-
log``;
|
|
197
|
-
}
|
|
198
|
-
const tech = detectAppTech();
|
|
199
|
-
if (tech) {
|
|
200
|
-
log.i(`Detected **${tech}** (https://${BRANCH}.css.master.co/docs/installation/${tech})`);
|
|
201
|
-
} else {
|
|
202
|
-
log.i(`To integrate with your framework, check out the guides at **https://${BRANCH}.css.master.co/docs/installation**`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
program.parse(process.argv);
|