ply-ui-cli 1.1.118
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 +36 -0
- package/README.md +275 -0
- package/dist/commands/add.js +432 -0
- package/dist/commands/changelog.js +112 -0
- package/dist/commands/diff.js +174 -0
- package/dist/commands/doctor.js +332 -0
- package/dist/commands/init.js +367 -0
- package/dist/commands/list.js +99 -0
- package/dist/commands/update.js +378 -0
- package/dist/index.js +172 -0
- package/dist/registry.js +278 -0
- package/dist/sync.js +170 -0
- package/dist/vendor.js +31226 -0
- package/package.json +64 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/commands/diff.ts
|
|
31
|
+
var diff_exports = {};
|
|
32
|
+
__export(diff_exports, {
|
|
33
|
+
diff: () => diff
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(diff_exports);
|
|
36
|
+
var import_path3 = __toESM(require("path"));
|
|
37
|
+
var import_vendor = require("../vendor");
|
|
38
|
+
|
|
39
|
+
// src/config.ts
|
|
40
|
+
var import_fs = __toESM(require("fs"));
|
|
41
|
+
var import_path = __toESM(require("path"));
|
|
42
|
+
|
|
43
|
+
// src/brand.ts
|
|
44
|
+
var CLI_BIN = "ply-ui-cli";
|
|
45
|
+
var CLI_NPX = `npx ${CLI_BIN}`;
|
|
46
|
+
var MCP_PACKAGE = "ply-ui-mcp";
|
|
47
|
+
var MCP_NPX = `npx -y ${MCP_PACKAGE}`;
|
|
48
|
+
|
|
49
|
+
// src/config.ts
|
|
50
|
+
function readConfig() {
|
|
51
|
+
const configPath = import_path.default.resolve(process.cwd(), "base-ui.json");
|
|
52
|
+
if (!import_fs.default.existsSync(configPath)) {
|
|
53
|
+
console.error(`base-ui.json not found. Please run "${CLI_NPX} init" first.`);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const config = JSON.parse(import_fs.default.readFileSync(configPath, "utf8"));
|
|
58
|
+
if (!config || !config.aliases || !config.aliases.components) {
|
|
59
|
+
throw new Error("Missing aliases.components in base-ui.json");
|
|
60
|
+
}
|
|
61
|
+
return config;
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error(`Error reading base-ui.json: ${err.message}`);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/lockfile.ts
|
|
69
|
+
var import_fs2 = __toESM(require("fs"));
|
|
70
|
+
var import_path2 = __toESM(require("path"));
|
|
71
|
+
var LOCKFILE_NAME = "base-ui-lock.json";
|
|
72
|
+
var LOCKFILE_VERSION = 1;
|
|
73
|
+
function lockfilePath() {
|
|
74
|
+
return import_path2.default.resolve(process.cwd(), LOCKFILE_NAME);
|
|
75
|
+
}
|
|
76
|
+
function readLockFile() {
|
|
77
|
+
const p = lockfilePath();
|
|
78
|
+
if (!import_fs2.default.existsSync(p)) {
|
|
79
|
+
return { version: LOCKFILE_VERSION, components: {} };
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const parsed = JSON.parse(import_fs2.default.readFileSync(p, "utf8"));
|
|
83
|
+
if (parsed && typeof parsed === "object" && parsed.components) {
|
|
84
|
+
return { version: parsed.version ?? LOCKFILE_VERSION, components: parsed.components };
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
return { version: LOCKFILE_VERSION, components: {} };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/commands/diff.ts
|
|
92
|
+
var import_registry = require("../registry");
|
|
93
|
+
var import_sync = require("../sync");
|
|
94
|
+
async function diff(components) {
|
|
95
|
+
const config = readConfig();
|
|
96
|
+
if (!config) {
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const componentsRoot = import_path3.default.resolve(process.cwd(), config.aliases.components);
|
|
101
|
+
const lock = readLockFile();
|
|
102
|
+
const tracked = Object.keys(lock.components).sort();
|
|
103
|
+
if (!tracked.length) {
|
|
104
|
+
console.log('No components are tracked yet. Components installed with "add" (after this version of the CLI) are tracked automatically.');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const targets = components.length ? components : tracked;
|
|
108
|
+
const unknown = targets.filter((n) => !tracked.includes(n));
|
|
109
|
+
if (unknown.length) {
|
|
110
|
+
console.error(`\u2716 Not tracked: ${unknown.join(", ")}`);
|
|
111
|
+
console.error(` Tracked components: ${tracked.join(", ")}`);
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const spinner = (0, import_vendor.ora)(`Checking ${targets.length} component${targets.length === 1 ? "" : "s"} against upstream...`).start();
|
|
116
|
+
let index;
|
|
117
|
+
try {
|
|
118
|
+
index = await (0, import_registry.fetchIndex)();
|
|
119
|
+
} catch (err) {
|
|
120
|
+
spinner.fail(err.message);
|
|
121
|
+
process.exitCode = 1;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const results = [];
|
|
125
|
+
for (const name of targets) {
|
|
126
|
+
results.push(await (0, import_sync.computeComponentDiff)(name, componentsRoot, lock, index));
|
|
127
|
+
}
|
|
128
|
+
spinner.stop();
|
|
129
|
+
let anyChanges = false;
|
|
130
|
+
let anyConflicts = false;
|
|
131
|
+
const upToDate = [];
|
|
132
|
+
const errored = [];
|
|
133
|
+
for (const result of results) {
|
|
134
|
+
if (result.error) {
|
|
135
|
+
errored.push(result.name);
|
|
136
|
+
console.log(`
|
|
137
|
+
\u2716 ${result.name}: ${result.error}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (!(0, import_sync.hasChanges)(result)) {
|
|
141
|
+
upToDate.push(result.name);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
anyChanges = true;
|
|
145
|
+
if ((0, import_sync.hasConflicts)(result)) anyConflicts = true;
|
|
146
|
+
console.log(`
|
|
147
|
+
${result.name}${result.tier === "pro" ? " (pro)" : ""}`);
|
|
148
|
+
for (const file of result.files) {
|
|
149
|
+
if (file.status === "unchanged") continue;
|
|
150
|
+
console.log(` ${file.path} \u2014 ${(0, import_sync.statusLabel)(file.status)}`);
|
|
151
|
+
if (file.status === "upstream-changed" || file.status === "conflict" || file.status === "new-upstream") {
|
|
152
|
+
console.log((0, import_sync.renderDiff)(file.localContent, file.upstreamContent).split("\n").map((l) => ` ${l}`).join("\n"));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (upToDate.length) {
|
|
157
|
+
console.log(`
|
|
158
|
+
\u2714 Up to date: ${upToDate.join(", ")}`);
|
|
159
|
+
}
|
|
160
|
+
if (anyChanges) {
|
|
161
|
+
console.log(`
|
|
162
|
+
Run "${CLI_NPX} update${components.length ? " " + components.join(" ") : ""}" to apply upstream changes.`);
|
|
163
|
+
if (anyConflicts) {
|
|
164
|
+
console.log("Some files were edited both locally and upstream \u2014 update will ask how to resolve each one.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (errored.length) {
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
172
|
+
0 && (module.exports = {
|
|
173
|
+
diff
|
|
174
|
+
});
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/commands/doctor.ts
|
|
31
|
+
var doctor_exports = {};
|
|
32
|
+
__export(doctor_exports, {
|
|
33
|
+
doctor: () => doctor
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(doctor_exports);
|
|
36
|
+
var import_fs = __toESM(require("fs"));
|
|
37
|
+
var import_path = __toESM(require("path"));
|
|
38
|
+
var import_vendor = require("../vendor");
|
|
39
|
+
var import_registry = require("../registry");
|
|
40
|
+
|
|
41
|
+
// src/brand.ts
|
|
42
|
+
var CLI_BIN = "ply-ui-cli";
|
|
43
|
+
var CLI_NPX = `npx ${CLI_BIN}`;
|
|
44
|
+
var MCP_PACKAGE = "ply-ui-mcp";
|
|
45
|
+
var MCP_NPX = `npx -y ${MCP_PACKAGE}`;
|
|
46
|
+
|
|
47
|
+
// src/commands/doctor.ts
|
|
48
|
+
var ICON_SPRITES = ["icons.svg", "icons-filled.svg"];
|
|
49
|
+
function pickAngularProject(angularJson) {
|
|
50
|
+
const projects = angularJson?.projects || {};
|
|
51
|
+
const names = Object.keys(projects);
|
|
52
|
+
if (!names.length) return null;
|
|
53
|
+
const appName = names.find((n) => projects[n].projectType === "application" && projects[n].architect?.build) || names.find((n) => projects[n].architect?.build) || names[0];
|
|
54
|
+
return { name: appName, project: projects[appName] };
|
|
55
|
+
}
|
|
56
|
+
function resolveAssetsDir(cwd, angularJson) {
|
|
57
|
+
const picked = pickAngularProject(angularJson);
|
|
58
|
+
const buildOptions = picked?.project?.architect?.build?.options;
|
|
59
|
+
if (!buildOptions) return import_path.default.resolve(cwd, "src/assets");
|
|
60
|
+
const assets = buildOptions.assets || [];
|
|
61
|
+
const hasSrcAssets = assets.some(
|
|
62
|
+
(a) => a === "src/assets" || typeof a === "object" && a?.input === "src/assets"
|
|
63
|
+
);
|
|
64
|
+
const publicEntry = assets.find(
|
|
65
|
+
(a) => a === "public" || typeof a === "object" && a?.input === "public"
|
|
66
|
+
);
|
|
67
|
+
if (hasSrcAssets) return import_path.default.resolve(cwd, "src/assets");
|
|
68
|
+
if (publicEntry) return import_path.default.resolve(cwd, "public/assets");
|
|
69
|
+
return import_path.default.resolve(cwd, "src/assets");
|
|
70
|
+
}
|
|
71
|
+
function readJsonSafe(filePath) {
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(import_fs.default.readFileSync(filePath, "utf8"));
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function readTextSafe(filePath) {
|
|
79
|
+
try {
|
|
80
|
+
return import_fs.default.readFileSync(filePath, "utf8");
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function sourceCovers(source, tailwindDir, targetDir) {
|
|
86
|
+
const raw = source.replace(/[*?[\]{}].*$/, "");
|
|
87
|
+
const resolved = import_path.default.resolve(tailwindDir, raw);
|
|
88
|
+
const resolvedDir = raw.endsWith("/") || raw.endsWith("\\") || import_path.default.extname(raw) === "" ? resolved : import_path.default.dirname(resolved);
|
|
89
|
+
return targetDir === resolvedDir || targetDir.startsWith(resolvedDir + import_path.default.sep);
|
|
90
|
+
}
|
|
91
|
+
async function doctor(options = {}) {
|
|
92
|
+
const cwd = options.cwd || process.cwd();
|
|
93
|
+
const relative = (filePath) => import_path.default.relative(cwd, filePath) || ".";
|
|
94
|
+
const spinner = (0, import_vendor.ora)("Checking Ply setup...").start();
|
|
95
|
+
const checks = [];
|
|
96
|
+
const configPath = import_path.default.resolve(cwd, "base-ui.json");
|
|
97
|
+
let config = null;
|
|
98
|
+
if (!import_fs.default.existsSync(configPath)) {
|
|
99
|
+
checks.push({
|
|
100
|
+
name: "base-ui.json",
|
|
101
|
+
status: "error",
|
|
102
|
+
message: `Not found. Run "${CLI_NPX} init" first.`
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
config = readJsonSafe(configPath);
|
|
106
|
+
if (!config) {
|
|
107
|
+
checks.push({
|
|
108
|
+
name: "base-ui.json",
|
|
109
|
+
status: "error",
|
|
110
|
+
message: `${relative(configPath)} exists but is not valid JSON.`
|
|
111
|
+
});
|
|
112
|
+
} else if (!config.aliases?.components) {
|
|
113
|
+
checks.push({
|
|
114
|
+
name: "base-ui.json",
|
|
115
|
+
status: "error",
|
|
116
|
+
message: `${relative(configPath)} is missing aliases.components.`
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
checks.push({
|
|
120
|
+
name: "base-ui.json",
|
|
121
|
+
status: "ok",
|
|
122
|
+
message: `${relative(configPath)} exists and aliases.components is set.`
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const angularJsonPath = import_path.default.resolve(cwd, "angular.json");
|
|
127
|
+
let angularJson = null;
|
|
128
|
+
if (!import_fs.default.existsSync(angularJsonPath)) {
|
|
129
|
+
checks.push({
|
|
130
|
+
name: "Angular workspace",
|
|
131
|
+
status: "warn",
|
|
132
|
+
message: "No angular.json found. Is this an Angular workspace?"
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
angularJson = readJsonSafe(angularJsonPath);
|
|
136
|
+
const picked = angularJson ? pickAngularProject(angularJson) : null;
|
|
137
|
+
if (!picked) {
|
|
138
|
+
checks.push({
|
|
139
|
+
name: "Angular workspace",
|
|
140
|
+
status: "error",
|
|
141
|
+
message: `${relative(angularJsonPath)} has no buildable project.`
|
|
142
|
+
});
|
|
143
|
+
} else {
|
|
144
|
+
checks.push({
|
|
145
|
+
name: "Angular workspace",
|
|
146
|
+
status: "ok",
|
|
147
|
+
message: `Buildable project "${picked.name}" found.`
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const packageJsonPath = import_path.default.resolve(cwd, "package.json");
|
|
152
|
+
const packageJson = readJsonSafe(packageJsonPath);
|
|
153
|
+
if (!packageJson) {
|
|
154
|
+
checks.push({
|
|
155
|
+
name: "package.json",
|
|
156
|
+
status: "error",
|
|
157
|
+
message: `${relative(packageJsonPath)} not found or invalid.`
|
|
158
|
+
});
|
|
159
|
+
} else {
|
|
160
|
+
const deps = {
|
|
161
|
+
...packageJson.dependencies,
|
|
162
|
+
...packageJson.devDependencies
|
|
163
|
+
};
|
|
164
|
+
if (!deps["@angular/cdk"]) {
|
|
165
|
+
checks.push({
|
|
166
|
+
name: "Angular CDK",
|
|
167
|
+
status: "error",
|
|
168
|
+
message: "@angular/cdk is not installed. Most components need it for overlays."
|
|
169
|
+
});
|
|
170
|
+
} else {
|
|
171
|
+
checks.push({
|
|
172
|
+
name: "Angular CDK",
|
|
173
|
+
status: "ok",
|
|
174
|
+
message: `@angular/cdk ${deps["@angular/cdk"]} installed.`
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const tailwindPath = import_path.default.resolve(cwd, config?.tailwind?.config || "src/tailwind.css");
|
|
179
|
+
const tailwindContent = readTextSafe(tailwindPath);
|
|
180
|
+
if (!tailwindContent) {
|
|
181
|
+
checks.push({
|
|
182
|
+
name: "Tailwind entry",
|
|
183
|
+
status: "error",
|
|
184
|
+
message: `${relative(tailwindPath)} not found. Set tailwind.config in base-ui.json or create it.`
|
|
185
|
+
});
|
|
186
|
+
} else {
|
|
187
|
+
checks.push({
|
|
188
|
+
name: "Tailwind entry",
|
|
189
|
+
status: "ok",
|
|
190
|
+
message: `${relative(tailwindPath)} exists.`
|
|
191
|
+
});
|
|
192
|
+
if (!tailwindContent.includes('@import "tailwindcss"') && !tailwindContent.includes("@import 'tailwindcss'")) {
|
|
193
|
+
checks.push({
|
|
194
|
+
name: "Tailwind v4",
|
|
195
|
+
status: "warn",
|
|
196
|
+
message: `${relative(tailwindPath)} does not import "tailwindcss". Tailwind v4 is required.`
|
|
197
|
+
});
|
|
198
|
+
} else {
|
|
199
|
+
checks.push({
|
|
200
|
+
name: "Tailwind v4",
|
|
201
|
+
status: "ok",
|
|
202
|
+
message: `${relative(tailwindPath)} imports Tailwind v4.`
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
const sourceMatches = tailwindContent.match(/@source\s+["']([^"']+)["']/g) || [];
|
|
206
|
+
if (!sourceMatches.length) {
|
|
207
|
+
checks.push({
|
|
208
|
+
name: "@source paths",
|
|
209
|
+
status: "warn",
|
|
210
|
+
message: `No @source directives found in ${relative(tailwindPath)}. Components may not be scanned for classes.`
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
const componentsAlias2 = config?.aliases?.components || "src/app/components";
|
|
214
|
+
const componentsDir = import_path.default.resolve(cwd, componentsAlias2);
|
|
215
|
+
const tailwindDir = import_path.default.dirname(tailwindPath);
|
|
216
|
+
const hasComponentSource = sourceMatches.some((m) => {
|
|
217
|
+
const raw = m.match(/@source\s+["']([^"']+)["']/)?.[1];
|
|
218
|
+
if (!raw) return false;
|
|
219
|
+
return sourceCovers(raw, tailwindDir, componentsDir);
|
|
220
|
+
});
|
|
221
|
+
if (!hasComponentSource) {
|
|
222
|
+
checks.push({
|
|
223
|
+
name: "@source paths",
|
|
224
|
+
status: "warn",
|
|
225
|
+
message: `@source directives exist but none point to ${componentsAlias2}. Component classes may be missing.`
|
|
226
|
+
});
|
|
227
|
+
} else {
|
|
228
|
+
checks.push({
|
|
229
|
+
name: "@source paths",
|
|
230
|
+
status: "ok",
|
|
231
|
+
message: `@source covers ${componentsAlias2}.`
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const stylesPath = import_path.default.resolve(cwd, config?.tailwind?.css || "src/styles.scss");
|
|
237
|
+
const stylesContent = readTextSafe(stylesPath);
|
|
238
|
+
if (!stylesContent) {
|
|
239
|
+
checks.push({
|
|
240
|
+
name: "Global styles",
|
|
241
|
+
status: "error",
|
|
242
|
+
message: `${relative(stylesPath)} not found. Set tailwind.css in base-ui.json or create it.`
|
|
243
|
+
});
|
|
244
|
+
} else {
|
|
245
|
+
const baseCssImport = "@import './base-ui.css'";
|
|
246
|
+
if (!stylesContent.includes(baseCssImport)) {
|
|
247
|
+
checks.push({
|
|
248
|
+
name: "Global styles",
|
|
249
|
+
status: "warn",
|
|
250
|
+
message: `${relative(stylesPath)} does not import ${baseCssImport}. Ply global styles will be missing.`
|
|
251
|
+
});
|
|
252
|
+
} else {
|
|
253
|
+
checks.push({
|
|
254
|
+
name: "Global styles",
|
|
255
|
+
status: "ok",
|
|
256
|
+
message: `${relative(stylesPath)} imports base-ui.css.`
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const baseCssPath = import_path.default.join(import_path.default.dirname(stylesPath), "base-ui.css");
|
|
260
|
+
if (!import_fs.default.existsSync(baseCssPath)) {
|
|
261
|
+
checks.push({
|
|
262
|
+
name: "base-ui.css",
|
|
263
|
+
status: "error",
|
|
264
|
+
message: `${relative(baseCssPath)} not found. Run "${CLI_NPX} init" to create it.`
|
|
265
|
+
});
|
|
266
|
+
} else {
|
|
267
|
+
checks.push({
|
|
268
|
+
name: "base-ui.css",
|
|
269
|
+
status: "ok",
|
|
270
|
+
message: `${relative(baseCssPath)} exists.`
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const assetsDir = angularJson ? resolveAssetsDir(cwd, angularJson) : import_path.default.resolve(cwd, "src/assets");
|
|
275
|
+
const missingSprites = ICON_SPRITES.filter((s) => !import_fs.default.existsSync(import_path.default.join(assetsDir, s)));
|
|
276
|
+
if (missingSprites.length) {
|
|
277
|
+
checks.push({
|
|
278
|
+
name: "Icon sprites",
|
|
279
|
+
status: "error",
|
|
280
|
+
message: `Missing ${missingSprites.join(", ")} in ${relative(assetsDir)}. Run "${CLI_NPX} init" to download them.`
|
|
281
|
+
});
|
|
282
|
+
} else {
|
|
283
|
+
checks.push({
|
|
284
|
+
name: "Icon sprites",
|
|
285
|
+
status: "ok",
|
|
286
|
+
message: `${ICON_SPRITES.join(", ")} found in ${relative(assetsDir)}.`
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
const componentsAlias = config?.aliases?.components;
|
|
290
|
+
if (componentsAlias) {
|
|
291
|
+
const componentsDir = import_path.default.resolve(cwd, componentsAlias);
|
|
292
|
+
if (!import_fs.default.existsSync(componentsDir)) {
|
|
293
|
+
checks.push({
|
|
294
|
+
name: "Components directory",
|
|
295
|
+
status: "warn",
|
|
296
|
+
message: `${relative(componentsDir)} does not exist yet. It will be created when you add a component.`
|
|
297
|
+
});
|
|
298
|
+
} else {
|
|
299
|
+
checks.push({
|
|
300
|
+
name: "Components directory",
|
|
301
|
+
status: "ok",
|
|
302
|
+
message: `${relative(componentsDir)} exists.`
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
spinner.succeed("Check complete.");
|
|
307
|
+
printReport(checks);
|
|
308
|
+
}
|
|
309
|
+
function printReport(checks) {
|
|
310
|
+
console.log("");
|
|
311
|
+
for (const check of checks) {
|
|
312
|
+
const symbol = check.status === "ok" ? "\u2714" : check.status === "warn" ? "\u26A0" : "\u2716";
|
|
313
|
+
console.log(`${symbol} ${check.name}: ${check.message}`);
|
|
314
|
+
}
|
|
315
|
+
const errors = checks.filter((c) => c.status === "error").length;
|
|
316
|
+
const warnings = checks.filter((c) => c.status === "warn").length;
|
|
317
|
+
const ok = checks.filter((c) => c.status === "ok").length;
|
|
318
|
+
console.log("");
|
|
319
|
+
if (errors === 0 && warnings === 0) {
|
|
320
|
+
console.log(`\u2714 All ${ok} checks passed. Your project is ready for Ply.`);
|
|
321
|
+
} else if (errors === 0) {
|
|
322
|
+
console.log(`\u26A0 ${ok} passed, ${warnings} warning(s). Review the warnings above.`);
|
|
323
|
+
} else {
|
|
324
|
+
console.log(`\u2716 ${ok} passed, ${warnings} warning(s), ${errors} error(s). Fix errors before adding components.`);
|
|
325
|
+
console.log(` Need help? ${import_registry.SITE_URL}/getting-started/`);
|
|
326
|
+
process.exitCode = 1;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
330
|
+
0 && (module.exports = {
|
|
331
|
+
doctor
|
|
332
|
+
});
|