@drupal-canvas/cli 0.6.0 → 0.6.2
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/README.md +42 -7
- package/dist/index.js +442 -271
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -40,7 +40,6 @@ to get started.
|
|
|
40
40
|
| `--client-id` | `CANVAS_CLIENT_ID` | OAuth client ID. |
|
|
41
41
|
| `--client-secret` | `CANVAS_CLIENT_SECRET` | OAuth client secret. |
|
|
42
42
|
| `--dir` | `CANVAS_COMPONENT_DIR` | Directory where code components are stored in the filesystem. |
|
|
43
|
-
| `--verbose` | `CANVAS_VERBOSE` | Verbose CLI output for troubleshooting. Defaults to `false`. |
|
|
44
43
|
| `--scope` | `CANVAS_SCOPE` | (Optional) Space-separated list of OAuth scopes to request. |
|
|
45
44
|
|
|
46
45
|
**Note:** The `--scope` parameter defaults to
|
|
@@ -66,8 +65,13 @@ npx canvas download [options]
|
|
|
66
65
|
- `--all`: Download all components
|
|
67
66
|
- `-y, --yes`: Skip all confirmation prompts (non-interactive mode)
|
|
68
67
|
- `--skip-overwrite`: Skip downloading components that already exist locally
|
|
68
|
+
- `--skip-css`: Skip global CSS download
|
|
69
|
+
- `--css-only`: Download only global CSS (skip components)
|
|
69
70
|
|
|
70
|
-
**
|
|
71
|
+
**Notes:**
|
|
72
|
+
|
|
73
|
+
- `--components` and `--all` cannot be used together
|
|
74
|
+
- `--skip-css` and `--css-only` cannot be used together
|
|
71
75
|
|
|
72
76
|
**About prompts:**
|
|
73
77
|
|
|
@@ -118,12 +122,25 @@ Fully non-interactive, only download new components:
|
|
|
118
122
|
npx canvas download --all --yes --skip-overwrite
|
|
119
123
|
```
|
|
120
124
|
|
|
125
|
+
Download components without global CSS:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npx canvas download --all --skip-css
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Download only global CSS (skip components):
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npx canvas download --css-only
|
|
135
|
+
```
|
|
136
|
+
|
|
121
137
|
Downloads one or more components from your site. You can select components
|
|
122
138
|
interactively, specify them with `--components`, or use `--all` to download
|
|
123
139
|
everything. By default, existing component directories will be overwritten after
|
|
124
140
|
confirmation. Use `--yes` for non-interactive mode (suitable for CI/CD), or
|
|
125
|
-
`--skip-overwrite` to preserve existing components.
|
|
126
|
-
|
|
141
|
+
`--skip-overwrite` to preserve existing components. Global CSS assets are
|
|
142
|
+
downloaded by default and can be controlled with `--skip-css` to exclude them or
|
|
143
|
+
`--css-only` to download only CSS without components.
|
|
127
144
|
|
|
128
145
|
---
|
|
129
146
|
|
|
@@ -227,8 +244,13 @@ npx canvas upload [options]
|
|
|
227
244
|
- `--all`: Upload all components in the directory
|
|
228
245
|
- `-y, --yes`: Skip confirmation prompts (non-interactive mode)
|
|
229
246
|
- `--no-tailwind`: Skip Tailwind CSS build and global asset upload
|
|
247
|
+
- `--skip-css`: Skip global CSS upload
|
|
248
|
+
- `--css-only`: Upload only global CSS (skip components)
|
|
230
249
|
|
|
231
|
-
**
|
|
250
|
+
**Notes:**
|
|
251
|
+
|
|
252
|
+
- `--components` and `--all` cannot be used together
|
|
253
|
+
- `--skip-css` and `--css-only` cannot be used together
|
|
232
254
|
|
|
233
255
|
**Examples:**
|
|
234
256
|
|
|
@@ -268,10 +290,23 @@ CI/CD without Tailwind:
|
|
|
268
290
|
npx canvas upload --all --yes --no-tailwind
|
|
269
291
|
```
|
|
270
292
|
|
|
293
|
+
Upload components without global CSS:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
npx canvas upload --all --skip-css
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Upload only global CSS (skip components):
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
npx canvas upload --css-only
|
|
303
|
+
```
|
|
304
|
+
|
|
271
305
|
Builds and uploads the selected (or all) local components to your site. Also
|
|
272
306
|
builds and uploads global Tailwind CSS assets unless `--no-tailwind` is
|
|
273
|
-
specified.
|
|
274
|
-
|
|
307
|
+
specified. Global CSS upload can be controlled with `--skip-css` to exclude it
|
|
308
|
+
or `--css-only` to upload only CSS without components. Existing components on
|
|
309
|
+
the site will be updated if they already exist.
|
|
275
310
|
|
|
276
311
|
---
|
|
277
312
|
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Command } from 'commander';
|
|
|
4
4
|
import * as p from '@clack/prompts';
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import fs__default, { realpathSync as realpathSync$1, readlinkSync, readdirSync, readdir as readdir$1, lstatSync, promises } from 'fs';
|
|
7
|
-
import
|
|
7
|
+
import path3, { win32, posix } from 'path';
|
|
8
8
|
import dotenv from 'dotenv';
|
|
9
9
|
import { transform, Features } from 'lightningcss';
|
|
10
10
|
import axios from 'axios';
|
|
@@ -25,16 +25,16 @@ import { parse } from '@babel/parser';
|
|
|
25
25
|
|
|
26
26
|
// package.json
|
|
27
27
|
var package_default = {
|
|
28
|
-
version: "0.6.
|
|
28
|
+
version: "0.6.2"};
|
|
29
29
|
function loadEnvFiles() {
|
|
30
30
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
31
31
|
if (homeDir) {
|
|
32
|
-
const homeEnvPath =
|
|
32
|
+
const homeEnvPath = path3.resolve(homeDir, ".canvasrc");
|
|
33
33
|
if (fs__default.existsSync(homeEnvPath)) {
|
|
34
34
|
dotenv.config({ path: homeEnvPath });
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
const localEnvPath =
|
|
37
|
+
const localEnvPath = path3.resolve(process.cwd(), ".env");
|
|
38
38
|
if (fs__default.existsSync(localEnvPath)) {
|
|
39
39
|
dotenv.config({ path: localEnvPath });
|
|
40
40
|
}
|
|
@@ -46,7 +46,6 @@ var config = {
|
|
|
46
46
|
clientSecret: process.env.CANVAS_CLIENT_SECRET || "",
|
|
47
47
|
scope: process.env.CANVAS_SCOPE || "canvas:js_component canvas:asset_library",
|
|
48
48
|
componentDir: process.env.CANVAS_COMPONENT_DIR || "./components",
|
|
49
|
-
verbose: process.env.CANVAS_VERBOSE === "true",
|
|
50
49
|
userAgent: process.env.CANVAS_USER_AGENT || ""
|
|
51
50
|
};
|
|
52
51
|
function getConfig() {
|
|
@@ -10672,107 +10671,138 @@ var ApiService = class _ApiService {
|
|
|
10672
10671
|
throw new Error("Failed to update global asset library");
|
|
10673
10672
|
}
|
|
10674
10673
|
}
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
if (
|
|
10683
|
-
|
|
10684
|
-
console.error(`- Status: ${status}`);
|
|
10685
|
-
console.error(`- URL: ${error.config?.url || "unknown"}`);
|
|
10686
|
-
console.error(
|
|
10687
|
-
`- Method: ${error.config?.method?.toUpperCase() || "unknown"}`
|
|
10688
|
-
);
|
|
10689
|
-
console.error("- Response data:", JSON.stringify(data, null, 2));
|
|
10690
|
-
const safeHeaders = { ...error.config?.headers };
|
|
10691
|
-
if (safeHeaders && safeHeaders.Authorization) {
|
|
10692
|
-
safeHeaders.Authorization = "Bearer ********";
|
|
10693
|
-
}
|
|
10694
|
-
console.error(
|
|
10695
|
-
"- Request headers:",
|
|
10696
|
-
JSON.stringify(safeHeaders, null, 2)
|
|
10697
|
-
);
|
|
10698
|
-
}
|
|
10699
|
-
if (status === 401) {
|
|
10700
|
-
throw new Error(
|
|
10701
|
-
"Authentication failed. Please check your client ID and secret."
|
|
10702
|
-
);
|
|
10703
|
-
} else if (status === 403) {
|
|
10704
|
-
throw new Error(
|
|
10705
|
-
"You do not have permission to perform this action. Check your configured scope."
|
|
10706
|
-
);
|
|
10707
|
-
} else if (data && (data.error || data.error_description || data.hint)) {
|
|
10708
|
-
throw new Error(
|
|
10709
|
-
`API Error (${status}): ${[
|
|
10710
|
-
data.error,
|
|
10711
|
-
data.error_description,
|
|
10712
|
-
data.hint
|
|
10713
|
-
].filter(Boolean).join(" | ")}`
|
|
10714
|
-
);
|
|
10715
|
-
} else {
|
|
10716
|
-
throw new Error(`API Error (${status}): ${error.message}`);
|
|
10674
|
+
/**
|
|
10675
|
+
* Parse Canvas API error responses into user-friendly messages.
|
|
10676
|
+
* Handles both structured validation errors and simple string errors.
|
|
10677
|
+
*/
|
|
10678
|
+
parseCanvasErrors(data) {
|
|
10679
|
+
if (data && typeof data === "object" && "errors" in data && Array.isArray(data.errors)) {
|
|
10680
|
+
return data.errors.map((err) => {
|
|
10681
|
+
if (typeof err === "string") {
|
|
10682
|
+
return err.trim();
|
|
10717
10683
|
}
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
console.error(
|
|
10724
|
-
`- Method: ${error.config?.method?.toUpperCase() || "unknown"}`
|
|
10725
|
-
);
|
|
10726
|
-
const safeHeaders = { ...error.config?.headers };
|
|
10727
|
-
if (safeHeaders && safeHeaders.Authorization) {
|
|
10728
|
-
safeHeaders.Authorization = "Bearer ********";
|
|
10684
|
+
if (err && typeof err === "object" && "detail" in err) {
|
|
10685
|
+
let message = typeof err.detail === "string" ? err.detail : String(err.detail);
|
|
10686
|
+
message = message.replace(/<[^>]*>/g, "").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").trim();
|
|
10687
|
+
if (!message) {
|
|
10688
|
+
return "";
|
|
10729
10689
|
}
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
JSON.stringify(safeHeaders, null, 2)
|
|
10733
|
-
);
|
|
10734
|
-
if (this.siteUrl.includes("ddev.site")) {
|
|
10735
|
-
console.error("\nDDEV Local Development Troubleshooting Tips:");
|
|
10736
|
-
console.error('1. Make sure DDEV is running: try "ddev status"');
|
|
10737
|
-
console.error(
|
|
10738
|
-
'2. Try using HTTP instead of HTTPS: use "http://drupal-dev.ddev.site" as URL'
|
|
10739
|
-
);
|
|
10740
|
-
console.error("3. Check if the site is accessible in your browser");
|
|
10741
|
-
console.error(
|
|
10742
|
-
'4. For HTTPS issues: Try "ddev auth ssl" to set up local SSL certificates'
|
|
10743
|
-
);
|
|
10690
|
+
if ("source" in err && err.source && typeof err.source === "object" && "pointer" in err.source && typeof err.source.pointer === "string" && err.source.pointer !== "") {
|
|
10691
|
+
message = `[${err.source.pointer}] ${message}`;
|
|
10744
10692
|
}
|
|
10693
|
+
return message;
|
|
10745
10694
|
}
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10695
|
+
return "";
|
|
10696
|
+
}).filter((msg) => msg !== "");
|
|
10697
|
+
}
|
|
10698
|
+
return [];
|
|
10699
|
+
}
|
|
10700
|
+
/**
|
|
10701
|
+
* Throws an appropriate error based on the API response.
|
|
10702
|
+
*/
|
|
10703
|
+
throwApiError(status, data, error, canvasErrors) {
|
|
10704
|
+
if (canvasErrors.length > 0) {
|
|
10705
|
+
const errorList = canvasErrors.join("\n\n").trim();
|
|
10706
|
+
if (errorList) {
|
|
10707
|
+
throw new Error(errorList);
|
|
10708
|
+
}
|
|
10709
|
+
}
|
|
10710
|
+
if (status === 401) {
|
|
10711
|
+
let message = "Authentication failed. Please check your client ID and secret.";
|
|
10712
|
+
if (data && typeof data === "object" && "error_description" in data && typeof data.error_description === "string") {
|
|
10713
|
+
message = `Authentication Error: ${data.error_description}
|
|
10714
|
+
|
|
10715
|
+
${message}`;
|
|
10716
|
+
}
|
|
10717
|
+
throw new Error(message);
|
|
10718
|
+
}
|
|
10719
|
+
if (status === 403) {
|
|
10720
|
+
throw new Error(
|
|
10721
|
+
"You do not have permission to perform this action. Check your configured scope."
|
|
10722
|
+
);
|
|
10723
|
+
}
|
|
10724
|
+
if (status === 404) {
|
|
10725
|
+
const url2 = error.config?.url || "unknown";
|
|
10726
|
+
let message = `API endpoint not found: ${url2}
|
|
10727
|
+
|
|
10728
|
+
`;
|
|
10729
|
+
if (this.siteUrl.includes("ddev.site")) {
|
|
10730
|
+
message += "Possible causes:\n";
|
|
10731
|
+
message += " \u2022 DDEV is not running (run: ddev start)\n";
|
|
10732
|
+
message += " \u2022 Canvas module is not enabled (run: ddev drush en canvas -y)\n";
|
|
10733
|
+
message += " \u2022 Site URL is incorrect";
|
|
10755
10734
|
} else {
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10735
|
+
message += "Possible causes:\n";
|
|
10736
|
+
message += " \u2022 Canvas module is not enabled\n";
|
|
10737
|
+
message += " \u2022 Site URL is incorrect\n";
|
|
10738
|
+
message += " \u2022 Server is not responding correctly";
|
|
10739
|
+
}
|
|
10740
|
+
throw new Error(message);
|
|
10741
|
+
}
|
|
10742
|
+
if (data && typeof data === "object" && "message" in data && typeof data.message === "string") {
|
|
10743
|
+
throw new Error(data.message);
|
|
10744
|
+
}
|
|
10745
|
+
if (data && typeof data === "object") {
|
|
10746
|
+
const errorParts = [];
|
|
10747
|
+
if ("error" in data && typeof data.error === "string") {
|
|
10748
|
+
errorParts.push(data.error);
|
|
10749
|
+
}
|
|
10750
|
+
if ("error_description" in data && typeof data.error_description === "string") {
|
|
10751
|
+
errorParts.push(data.error_description);
|
|
10752
|
+
}
|
|
10753
|
+
if ("hint" in data && typeof data.hint === "string") {
|
|
10754
|
+
errorParts.push(data.hint);
|
|
10762
10755
|
}
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
console.error("General Error:");
|
|
10766
|
-
console.error(`- Message: ${error.message}`);
|
|
10767
|
-
console.error("- Stack:", error.stack);
|
|
10756
|
+
if (errorParts.length > 0) {
|
|
10757
|
+
throw new Error(`API Error (${status}): ${errorParts.join(" | ")}`);
|
|
10768
10758
|
}
|
|
10769
|
-
|
|
10759
|
+
}
|
|
10760
|
+
const url = error.config?.url || "unknown";
|
|
10761
|
+
const method = error.config?.method?.toUpperCase() || "unknown";
|
|
10762
|
+
throw new Error(
|
|
10763
|
+
`API Error (${status}): ${error.message}
|
|
10764
|
+
|
|
10765
|
+
URL: ${url}
|
|
10766
|
+
Method: ${method}`
|
|
10767
|
+
);
|
|
10768
|
+
}
|
|
10769
|
+
/**
|
|
10770
|
+
* Handles network errors (no response from server).
|
|
10771
|
+
*/
|
|
10772
|
+
handleNetworkError() {
|
|
10773
|
+
let message = `No response from: ${this.siteUrl}
|
|
10774
|
+
|
|
10775
|
+
`;
|
|
10776
|
+
if (this.siteUrl.includes("ddev.site")) {
|
|
10777
|
+
message += "Troubleshooting tips:\n";
|
|
10778
|
+
message += " \u2022 Check if DDEV is running: ddev status\n";
|
|
10779
|
+
message += " \u2022 Try HTTP instead of HTTPS\n";
|
|
10780
|
+
message += " \u2022 Verify site is accessible in browser\n";
|
|
10781
|
+
message += " \u2022 For HTTPS issues, try: ddev auth ssl";
|
|
10770
10782
|
} else {
|
|
10771
|
-
|
|
10772
|
-
|
|
10783
|
+
message += "Check your site URL and internet connection.";
|
|
10784
|
+
}
|
|
10785
|
+
throw new Error(message);
|
|
10786
|
+
}
|
|
10787
|
+
/**
|
|
10788
|
+
* Main error handler for API requests.
|
|
10789
|
+
*/
|
|
10790
|
+
handleApiError(error) {
|
|
10791
|
+
if (!axios.isAxiosError(error)) {
|
|
10792
|
+
if (error instanceof Error) {
|
|
10793
|
+
throw error;
|
|
10773
10794
|
}
|
|
10774
10795
|
throw new Error("Unknown API error occurred");
|
|
10775
10796
|
}
|
|
10797
|
+
if (error.response) {
|
|
10798
|
+
const { status, data } = error.response;
|
|
10799
|
+
const canvasErrors = this.parseCanvasErrors(data);
|
|
10800
|
+
this.throwApiError(status, data, error, canvasErrors);
|
|
10801
|
+
}
|
|
10802
|
+
if (error.request) {
|
|
10803
|
+
this.handleNetworkError();
|
|
10804
|
+
}
|
|
10805
|
+
throw new Error(`Request setup error: ${error.message}`);
|
|
10776
10806
|
}
|
|
10777
10807
|
};
|
|
10778
10808
|
function createApiService() {
|
|
@@ -10805,17 +10835,17 @@ function createApiService() {
|
|
|
10805
10835
|
userAgent: config2.userAgent
|
|
10806
10836
|
});
|
|
10807
10837
|
}
|
|
10808
|
-
var CANVAS_CACHE_DIR =
|
|
10838
|
+
var CANVAS_CACHE_DIR = path3.join(os.homedir(), ".canvas");
|
|
10809
10839
|
async function downloadJsSourceFromCanvas(componentsToDownload) {
|
|
10810
10840
|
for (const key in componentsToDownload) {
|
|
10811
10841
|
const component = componentsToDownload[key];
|
|
10812
10842
|
try {
|
|
10813
|
-
const componentDir =
|
|
10843
|
+
const componentDir = path3.join(CANVAS_CACHE_DIR, component.machineName);
|
|
10814
10844
|
await fs2.rm(componentDir, { recursive: true, force: true });
|
|
10815
10845
|
await fs2.mkdir(componentDir, { recursive: true });
|
|
10816
10846
|
if (component.sourceCodeJs) {
|
|
10817
10847
|
await fs2.writeFile(
|
|
10818
|
-
|
|
10848
|
+
path3.join(componentDir, `index.jsx`),
|
|
10819
10849
|
component.sourceCodeJs,
|
|
10820
10850
|
"utf-8"
|
|
10821
10851
|
);
|
|
@@ -10833,14 +10863,14 @@ async function copyLocalJsSource(componentsToCopy) {
|
|
|
10833
10863
|
try {
|
|
10834
10864
|
await fs2.mkdir(CANVAS_CACHE_DIR, { recursive: true });
|
|
10835
10865
|
for (const componentPath of componentsToCopy) {
|
|
10836
|
-
const baseName =
|
|
10866
|
+
const baseName = path3.basename(componentPath);
|
|
10837
10867
|
const sourcePath = componentPath;
|
|
10838
|
-
const targetPath =
|
|
10868
|
+
const targetPath = path3.join(CANVAS_CACHE_DIR, baseName);
|
|
10839
10869
|
const stats = await fs2.stat(sourcePath);
|
|
10840
10870
|
if (stats.isDirectory()) {
|
|
10841
10871
|
await fs2.mkdir(targetPath, { recursive: true });
|
|
10842
|
-
const sourceFile =
|
|
10843
|
-
const targetFile =
|
|
10872
|
+
const sourceFile = path3.join(sourcePath, "index.jsx");
|
|
10873
|
+
const targetFile = path3.join(targetPath, "index.jsx");
|
|
10844
10874
|
await fs2.copyFile(sourceFile, targetFile);
|
|
10845
10875
|
}
|
|
10846
10876
|
}
|
|
@@ -10858,7 +10888,7 @@ async function cleanUpCacheDirectory() {
|
|
|
10858
10888
|
withFileTypes: true
|
|
10859
10889
|
});
|
|
10860
10890
|
for (const entry of cacheEntries) {
|
|
10861
|
-
const entryPath =
|
|
10891
|
+
const entryPath = path3.join(CANVAS_CACHE_DIR, entry.name);
|
|
10862
10892
|
if (entry.isDirectory()) {
|
|
10863
10893
|
await fs2.rm(entryPath, { recursive: true, force: true });
|
|
10864
10894
|
} else {
|
|
@@ -10873,8 +10903,32 @@ async function cleanUpCacheDirectory() {
|
|
|
10873
10903
|
);
|
|
10874
10904
|
}
|
|
10875
10905
|
}
|
|
10906
|
+
async function fileExists(filePath) {
|
|
10907
|
+
try {
|
|
10908
|
+
await fs2.access(filePath);
|
|
10909
|
+
return true;
|
|
10910
|
+
} catch {
|
|
10911
|
+
return false;
|
|
10912
|
+
}
|
|
10913
|
+
}
|
|
10914
|
+
async function directoryExists(dirPath) {
|
|
10915
|
+
return await fs2.stat(dirPath).then(() => true).catch(() => false);
|
|
10916
|
+
}
|
|
10876
10917
|
|
|
10877
10918
|
// src/utils/build-tailwind.ts
|
|
10919
|
+
async function downloadGlobalCssInBackground() {
|
|
10920
|
+
const apiService = await createApiService();
|
|
10921
|
+
const globalAssetLibrary = await apiService.getGlobalAssetLibrary();
|
|
10922
|
+
return globalAssetLibrary?.css?.original || "";
|
|
10923
|
+
}
|
|
10924
|
+
async function getGlobalCss(useLocal = true) {
|
|
10925
|
+
const config2 = getConfig();
|
|
10926
|
+
const localGlobalCssPath = path3.join(config2.componentDir, "global.css");
|
|
10927
|
+
if (useLocal && await fileExists(localGlobalCssPath)) {
|
|
10928
|
+
return await promises.readFile(localGlobalCssPath, "utf-8");
|
|
10929
|
+
}
|
|
10930
|
+
return await downloadGlobalCssInBackground();
|
|
10931
|
+
}
|
|
10878
10932
|
async function getAllClassNameCandidatesFromCacheDir(componentsToDownload, localComponentsToCopy) {
|
|
10879
10933
|
if (Object.keys(componentsToDownload).length > 0) {
|
|
10880
10934
|
await downloadJsSourceFromCanvas(componentsToDownload);
|
|
@@ -10883,7 +10937,7 @@ async function getAllClassNameCandidatesFromCacheDir(componentsToDownload, local
|
|
|
10883
10937
|
const cacheEntries = await promises.readdir(CANVAS_CACHE_DIR, {
|
|
10884
10938
|
withFileTypes: true
|
|
10885
10939
|
});
|
|
10886
|
-
const cacheDirs = cacheEntries.filter((entry) => entry.isDirectory()).map((dir) =>
|
|
10940
|
+
const cacheDirs = cacheEntries.filter((entry) => entry.isDirectory()).map((dir) => path3.join(CANVAS_CACHE_DIR, dir.name));
|
|
10887
10941
|
let allClassNameCandidates = [];
|
|
10888
10942
|
for (const cacheDir of cacheDirs) {
|
|
10889
10943
|
const componentClassNameCandidates = await getClassNameCandidatesForComponent(cacheDir);
|
|
@@ -10901,16 +10955,16 @@ async function buildTailwindCss(classNameCandidates, globalSourceCodeCss, distDi
|
|
|
10901
10955
|
globalSourceCodeCss
|
|
10902
10956
|
);
|
|
10903
10957
|
const transformedTwCss = await transformCss(compiledTwCss);
|
|
10904
|
-
await promises.writeFile(
|
|
10958
|
+
await promises.writeFile(path3.join(distDir, "index.css"), transformedTwCss);
|
|
10905
10959
|
}
|
|
10906
10960
|
async function getClassNameCandidatesForComponent(dir) {
|
|
10907
|
-
const componentName =
|
|
10961
|
+
const componentName = path3.basename(dir);
|
|
10908
10962
|
const config2 = getConfig();
|
|
10909
10963
|
const componentsDir = config2.componentDir;
|
|
10910
|
-
const distDir =
|
|
10911
|
-
const jsSource = await promises.readFile(
|
|
10964
|
+
const distDir = path3.join(componentsDir, "dist");
|
|
10965
|
+
const jsSource = await promises.readFile(path3.join(dir, "index.jsx"), "utf-8");
|
|
10912
10966
|
const currentGlobalSourceCodeJs = await promises.readFile(
|
|
10913
|
-
|
|
10967
|
+
path3.join(distDir, "index.js"),
|
|
10914
10968
|
"utf-8"
|
|
10915
10969
|
);
|
|
10916
10970
|
const classNameCandidates = OE(jsSource);
|
|
@@ -10919,20 +10973,20 @@ async function getClassNameCandidatesForComponent(dir) {
|
|
|
10919
10973
|
componentName,
|
|
10920
10974
|
classNameCandidates
|
|
10921
10975
|
);
|
|
10922
|
-
await promises.writeFile(
|
|
10976
|
+
await promises.writeFile(path3.join(distDir, "index.js"), globalJSClassNameIndex);
|
|
10923
10977
|
return nextClassNameCandidates;
|
|
10924
10978
|
}
|
|
10925
|
-
async function buildTailwindForComponents(selectedComponents) {
|
|
10979
|
+
async function buildTailwindForComponents(selectedComponents, useLocalGlobalCss = true) {
|
|
10926
10980
|
try {
|
|
10927
10981
|
const config2 = getConfig();
|
|
10928
10982
|
const apiService = await createApiService();
|
|
10929
10983
|
const onlineComponents = await apiService.listComponents();
|
|
10984
|
+
const globalSourceCodeCss = await getGlobalCss(useLocalGlobalCss);
|
|
10930
10985
|
const globalAssetLibrary = await apiService.getGlobalAssetLibrary();
|
|
10931
|
-
const globalSourceCodeJs = globalAssetLibrary
|
|
10932
|
-
const
|
|
10933
|
-
const distDir = path11.join(config2.componentDir, "dist");
|
|
10986
|
+
const globalSourceCodeJs = globalAssetLibrary?.js?.original || "";
|
|
10987
|
+
const distDir = path3.join(config2.componentDir, "dist");
|
|
10934
10988
|
await promises.mkdir(distDir, { recursive: true });
|
|
10935
|
-
const targetFile =
|
|
10989
|
+
const targetFile = path3.join(distDir, "index.js");
|
|
10936
10990
|
await promises.writeFile(targetFile, globalSourceCodeJs, "utf-8");
|
|
10937
10991
|
const allClassNameCandidates = await getAllClassNameCandidatesFromCacheDir(
|
|
10938
10992
|
onlineComponents,
|
|
@@ -10984,17 +11038,6 @@ function compileJS(source) {
|
|
|
10984
11038
|
const { code } = transformSync(source, SWC_OPTIONS);
|
|
10985
11039
|
return code;
|
|
10986
11040
|
}
|
|
10987
|
-
async function fileExists(filePath) {
|
|
10988
|
-
try {
|
|
10989
|
-
await fs2.access(filePath);
|
|
10990
|
-
return true;
|
|
10991
|
-
} catch {
|
|
10992
|
-
return false;
|
|
10993
|
-
}
|
|
10994
|
-
}
|
|
10995
|
-
async function directoryExists(dirPath) {
|
|
10996
|
-
return await fs2.stat(dirPath).then(() => true).catch(() => false);
|
|
10997
|
-
}
|
|
10998
11041
|
async function validateComponent(componentDir, fix = false) {
|
|
10999
11042
|
const eslint = new ESLint({
|
|
11000
11043
|
overrideConfigFile: true,
|
|
@@ -11012,7 +11055,7 @@ async function validateComponent(componentDir, fix = false) {
|
|
|
11012
11055
|
(msg) => `Line ${msg.line}, Column ${msg.column}: ` + msg.message + (msg.ruleId ? ` (${msg.ruleId})` : "")
|
|
11013
11056
|
);
|
|
11014
11057
|
details.push({
|
|
11015
|
-
heading:
|
|
11058
|
+
heading: path3.relative(process.cwd(), result.filePath),
|
|
11016
11059
|
content: messages.join("\n\n")
|
|
11017
11060
|
});
|
|
11018
11061
|
});
|
|
@@ -11024,8 +11067,8 @@ async function validateComponent(componentDir, fix = false) {
|
|
|
11024
11067
|
}
|
|
11025
11068
|
|
|
11026
11069
|
// src/utils/build.ts
|
|
11027
|
-
async function buildComponent(componentDir) {
|
|
11028
|
-
const componentName =
|
|
11070
|
+
async function buildComponent(componentDir, useLocalGlobalCss = true) {
|
|
11071
|
+
const componentName = path3.basename(componentDir);
|
|
11029
11072
|
const result = {
|
|
11030
11073
|
itemName: componentName,
|
|
11031
11074
|
success: true,
|
|
@@ -11037,7 +11080,7 @@ async function buildComponent(componentDir) {
|
|
|
11037
11080
|
result.details = validationResult.details;
|
|
11038
11081
|
return result;
|
|
11039
11082
|
}
|
|
11040
|
-
const distDir =
|
|
11083
|
+
const distDir = path3.join(componentDir, "dist");
|
|
11041
11084
|
try {
|
|
11042
11085
|
await promises.mkdir(distDir, { recursive: true });
|
|
11043
11086
|
} catch (error) {
|
|
@@ -11050,11 +11093,11 @@ async function buildComponent(componentDir) {
|
|
|
11050
11093
|
}
|
|
11051
11094
|
try {
|
|
11052
11095
|
const jsSource = await promises.readFile(
|
|
11053
|
-
|
|
11096
|
+
path3.join(componentDir, "index.jsx"),
|
|
11054
11097
|
"utf-8"
|
|
11055
11098
|
);
|
|
11056
11099
|
const jsCompiled = compileJS(jsSource);
|
|
11057
|
-
await promises.writeFile(
|
|
11100
|
+
await promises.writeFile(path3.join(distDir, "index.js"), jsCompiled);
|
|
11058
11101
|
} catch (error) {
|
|
11059
11102
|
result.success = false;
|
|
11060
11103
|
result.details?.push({
|
|
@@ -11062,11 +11105,9 @@ async function buildComponent(componentDir) {
|
|
|
11062
11105
|
content: String(error)
|
|
11063
11106
|
});
|
|
11064
11107
|
}
|
|
11065
|
-
const
|
|
11066
|
-
const globalAssetLibrary = await apiService.getGlobalAssetLibrary();
|
|
11067
|
-
const globalSourceCodeCss = globalAssetLibrary.css.original;
|
|
11108
|
+
const globalSourceCodeCss = await getGlobalCss(useLocalGlobalCss);
|
|
11068
11109
|
try {
|
|
11069
|
-
const cssPath =
|
|
11110
|
+
const cssPath = path3.join(componentDir, "index.css");
|
|
11070
11111
|
const cssFileExists = await fileExists(cssPath);
|
|
11071
11112
|
if (cssFileExists) {
|
|
11072
11113
|
const cssSource = await promises.readFile(cssPath, "utf-8");
|
|
@@ -11075,7 +11116,7 @@ async function buildComponent(componentDir) {
|
|
|
11075
11116
|
globalSourceCodeCss
|
|
11076
11117
|
);
|
|
11077
11118
|
const cssTranspiled = await transformCss(cssCompiled);
|
|
11078
|
-
await promises.writeFile(
|
|
11119
|
+
await promises.writeFile(path3.join(distDir, "index.css"), cssTranspiled);
|
|
11079
11120
|
}
|
|
11080
11121
|
} catch (error) {
|
|
11081
11122
|
result.success = false;
|
|
@@ -11103,7 +11144,6 @@ function updateConfigFromOptions(options) {
|
|
|
11103
11144
|
if (options.dir) setConfig({ componentDir: options.dir });
|
|
11104
11145
|
if (options.scope) setConfig({ scope: options.scope });
|
|
11105
11146
|
if (options.all) setConfig({ all: options.all });
|
|
11106
|
-
if (options.verbose) setConfig({ verbose: true });
|
|
11107
11147
|
}
|
|
11108
11148
|
function pluralizeComponent(count) {
|
|
11109
11149
|
return count === 1 ? "component" : "components";
|
|
@@ -17728,11 +17768,11 @@ async function findComponentDirectories(baseDir) {
|
|
|
17728
17768
|
const namedYmls = await glob(`${baseDir}/**/*.component.yml`);
|
|
17729
17769
|
const allComponentPaths = [...standardYmls, ...namedYmls];
|
|
17730
17770
|
const uniqueDirs = new Set(
|
|
17731
|
-
allComponentPaths.map((filePath) =>
|
|
17771
|
+
allComponentPaths.map((filePath) => path3.dirname(filePath))
|
|
17732
17772
|
);
|
|
17733
17773
|
let componentDirs = Array.from(uniqueDirs).sort();
|
|
17734
17774
|
let sdcs = await glob(`${baseDir}/**/*.twig`);
|
|
17735
|
-
sdcs = sdcs.map((sdc) =>
|
|
17775
|
+
sdcs = sdcs.map((sdc) => path3.dirname(sdc));
|
|
17736
17776
|
componentDirs = componentDirs.filter(
|
|
17737
17777
|
(componentDir) => !sdcs.includes(componentDir)
|
|
17738
17778
|
);
|
|
@@ -17744,9 +17784,29 @@ async function findComponentDirectories(baseDir) {
|
|
|
17744
17784
|
}
|
|
17745
17785
|
|
|
17746
17786
|
// src/utils/component-selector.ts
|
|
17787
|
+
var GLOBAL_CSS_SELECTOR = "__GLOBAL_CSS__";
|
|
17788
|
+
function determineGlobalCssSelection(options) {
|
|
17789
|
+
if (options.cssOnly) {
|
|
17790
|
+
return true;
|
|
17791
|
+
}
|
|
17792
|
+
if (options.skipCss) {
|
|
17793
|
+
return false;
|
|
17794
|
+
}
|
|
17795
|
+
if (!options.includeGlobalCss) {
|
|
17796
|
+
return void 0;
|
|
17797
|
+
}
|
|
17798
|
+
return options.globalCssDefault !== false;
|
|
17799
|
+
}
|
|
17747
17800
|
async function selectLocalComponents(options) {
|
|
17748
17801
|
const config2 = getConfig();
|
|
17749
17802
|
const componentDir = options.componentDir || config2.componentDir;
|
|
17803
|
+
const globalCssSelection = determineGlobalCssSelection(options);
|
|
17804
|
+
if (options.cssOnly) {
|
|
17805
|
+
return {
|
|
17806
|
+
directories: [],
|
|
17807
|
+
includeGlobalCss: true
|
|
17808
|
+
};
|
|
17809
|
+
}
|
|
17750
17810
|
const allLocalDirs = await findComponentDirectories(componentDir);
|
|
17751
17811
|
if (allLocalDirs.length === 0) {
|
|
17752
17812
|
throw new Error(`No local components were found in ${componentDir}`);
|
|
@@ -17755,7 +17815,8 @@ async function selectLocalComponents(options) {
|
|
|
17755
17815
|
return selectSpecificLocalComponents(
|
|
17756
17816
|
options.components,
|
|
17757
17817
|
allLocalDirs,
|
|
17758
|
-
options
|
|
17818
|
+
options,
|
|
17819
|
+
globalCssSelection
|
|
17759
17820
|
);
|
|
17760
17821
|
}
|
|
17761
17822
|
if (options.all) {
|
|
@@ -17769,16 +17830,23 @@ async function selectLocalComponents(options) {
|
|
|
17769
17830
|
}
|
|
17770
17831
|
}
|
|
17771
17832
|
p.log.info(`Selected all components`);
|
|
17772
|
-
return {
|
|
17833
|
+
return {
|
|
17834
|
+
directories: allLocalDirs,
|
|
17835
|
+
includeGlobalCss: globalCssSelection
|
|
17836
|
+
};
|
|
17773
17837
|
}
|
|
17774
|
-
return selectLocalComponentsInteractive(
|
|
17838
|
+
return selectLocalComponentsInteractive(
|
|
17839
|
+
allLocalDirs,
|
|
17840
|
+
options,
|
|
17841
|
+
globalCssSelection
|
|
17842
|
+
);
|
|
17775
17843
|
}
|
|
17776
|
-
async function selectSpecificLocalComponents(componentsInput, allLocalDirs, options) {
|
|
17844
|
+
async function selectSpecificLocalComponents(componentsInput, allLocalDirs, options, globalCssSelection) {
|
|
17777
17845
|
const requestedNames = componentsInput.split(",").map((name) => name.trim()).filter((name) => name.length > 0);
|
|
17778
17846
|
const notFound = [];
|
|
17779
17847
|
const foundDirs = [];
|
|
17780
17848
|
for (const requestedName of requestedNames) {
|
|
17781
|
-
const dir = allLocalDirs.find((d2) =>
|
|
17849
|
+
const dir = allLocalDirs.find((d2) => path3.basename(d2) === requestedName);
|
|
17782
17850
|
if (dir) {
|
|
17783
17851
|
foundDirs.push(dir);
|
|
17784
17852
|
} else {
|
|
@@ -17798,27 +17866,48 @@ async function selectSpecificLocalComponents(componentsInput, allLocalDirs, opti
|
|
|
17798
17866
|
throw new Error("Operation cancelled by user");
|
|
17799
17867
|
}
|
|
17800
17868
|
}
|
|
17801
|
-
return {
|
|
17869
|
+
return {
|
|
17870
|
+
directories: foundDirs,
|
|
17871
|
+
includeGlobalCss: globalCssSelection
|
|
17872
|
+
};
|
|
17802
17873
|
}
|
|
17803
|
-
async function selectLocalComponentsInteractive(allLocalDirs, options) {
|
|
17804
|
-
const
|
|
17805
|
-
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
17809
|
-
|
|
17810
|
-
|
|
17811
|
-
|
|
17812
|
-
|
|
17813
|
-
|
|
17814
|
-
|
|
17815
|
-
|
|
17874
|
+
async function selectLocalComponentsInteractive(allLocalDirs, options, globalCssSelection) {
|
|
17875
|
+
const multiSelectOptions = [
|
|
17876
|
+
{
|
|
17877
|
+
value: ALL_COMPONENTS_SELECTOR,
|
|
17878
|
+
label: "All components"
|
|
17879
|
+
}
|
|
17880
|
+
];
|
|
17881
|
+
if (options.includeGlobalCss) {
|
|
17882
|
+
multiSelectOptions.push({
|
|
17883
|
+
value: GLOBAL_CSS_SELECTOR,
|
|
17884
|
+
label: "Global CSS"
|
|
17885
|
+
});
|
|
17886
|
+
}
|
|
17887
|
+
multiSelectOptions.push(
|
|
17888
|
+
...allLocalDirs.map((dir) => ({
|
|
17889
|
+
value: dir,
|
|
17890
|
+
label: path3.basename(dir)
|
|
17891
|
+
}))
|
|
17892
|
+
);
|
|
17893
|
+
const selectedItems = await p.multiselect({
|
|
17894
|
+
message: options.selectMessage || "Select items",
|
|
17895
|
+
options: multiSelectOptions,
|
|
17896
|
+
initialValues: options.includeGlobalCss && options.globalCssDefault !== false ? [GLOBAL_CSS_SELECTOR] : [],
|
|
17816
17897
|
required: true
|
|
17817
17898
|
});
|
|
17818
|
-
if (p.isCancel(
|
|
17899
|
+
if (p.isCancel(selectedItems)) {
|
|
17819
17900
|
throw new Error("Operation cancelled by user");
|
|
17820
17901
|
}
|
|
17821
|
-
const
|
|
17902
|
+
const includesAllComponents = selectedItems.includes(
|
|
17903
|
+
ALL_COMPONENTS_SELECTOR
|
|
17904
|
+
);
|
|
17905
|
+
const includesGlobalCss = selectedItems.includes(
|
|
17906
|
+
GLOBAL_CSS_SELECTOR
|
|
17907
|
+
);
|
|
17908
|
+
const finalDirs = includesAllComponents ? allLocalDirs : selectedItems.filter(
|
|
17909
|
+
(item) => item !== ALL_COMPONENTS_SELECTOR && item !== GLOBAL_CSS_SELECTOR
|
|
17910
|
+
);
|
|
17822
17911
|
if (!options.skipConfirmation) {
|
|
17823
17912
|
const confirmed = await confirmSelection(
|
|
17824
17913
|
finalDirs.length,
|
|
@@ -17828,10 +17917,21 @@ async function selectLocalComponentsInteractive(allLocalDirs, options) {
|
|
|
17828
17917
|
throw new Error("Operation cancelled by user");
|
|
17829
17918
|
}
|
|
17830
17919
|
}
|
|
17831
|
-
|
|
17920
|
+
const finalGlobalCss = options.includeGlobalCss ? includesGlobalCss : globalCssSelection;
|
|
17921
|
+
return {
|
|
17922
|
+
directories: finalDirs,
|
|
17923
|
+
includeGlobalCss: finalGlobalCss
|
|
17924
|
+
};
|
|
17832
17925
|
}
|
|
17833
17926
|
async function selectRemoteComponents(allComponents, options) {
|
|
17834
17927
|
const componentCount = Object.keys(allComponents).length;
|
|
17928
|
+
const globalCssSelection = determineGlobalCssSelection(options);
|
|
17929
|
+
if (options.cssOnly) {
|
|
17930
|
+
return {
|
|
17931
|
+
components: {},
|
|
17932
|
+
includeGlobalCss: true
|
|
17933
|
+
};
|
|
17934
|
+
}
|
|
17835
17935
|
if (componentCount === 0) {
|
|
17836
17936
|
throw new Error("No components found");
|
|
17837
17937
|
}
|
|
@@ -17845,18 +17945,26 @@ async function selectRemoteComponents(allComponents, options) {
|
|
|
17845
17945
|
throw new Error("Operation cancelled by user");
|
|
17846
17946
|
}
|
|
17847
17947
|
}
|
|
17848
|
-
return {
|
|
17948
|
+
return {
|
|
17949
|
+
components: allComponents,
|
|
17950
|
+
includeGlobalCss: globalCssSelection
|
|
17951
|
+
};
|
|
17849
17952
|
}
|
|
17850
17953
|
if (options.components) {
|
|
17851
17954
|
return selectSpecificRemoteComponents(
|
|
17852
17955
|
options.components,
|
|
17853
17956
|
allComponents,
|
|
17854
|
-
options
|
|
17957
|
+
options,
|
|
17958
|
+
globalCssSelection
|
|
17855
17959
|
);
|
|
17856
17960
|
}
|
|
17857
|
-
return selectRemoteComponentsInteractive(
|
|
17961
|
+
return selectRemoteComponentsInteractive(
|
|
17962
|
+
allComponents,
|
|
17963
|
+
options,
|
|
17964
|
+
globalCssSelection
|
|
17965
|
+
);
|
|
17858
17966
|
}
|
|
17859
|
-
async function selectSpecificRemoteComponents(componentsInput, allComponents, options) {
|
|
17967
|
+
async function selectSpecificRemoteComponents(componentsInput, allComponents, options, globalCssSelection) {
|
|
17860
17968
|
const requestedNames = componentsInput.split(",").map((name) => name.trim()).filter((name) => name.length > 0);
|
|
17861
17969
|
const notFound = [];
|
|
17862
17970
|
const selected = {};
|
|
@@ -17881,31 +17989,48 @@ async function selectSpecificRemoteComponents(componentsInput, allComponents, op
|
|
|
17881
17989
|
throw new Error("Operation cancelled by user");
|
|
17882
17990
|
}
|
|
17883
17991
|
}
|
|
17884
|
-
return {
|
|
17992
|
+
return {
|
|
17993
|
+
components: selected,
|
|
17994
|
+
includeGlobalCss: globalCssSelection
|
|
17995
|
+
};
|
|
17885
17996
|
}
|
|
17886
|
-
async function selectRemoteComponentsInteractive(allComponents, options) {
|
|
17887
|
-
const
|
|
17888
|
-
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17997
|
+
async function selectRemoteComponentsInteractive(allComponents, options, globalCssSelection) {
|
|
17998
|
+
const multiSelectOptions = [
|
|
17999
|
+
{
|
|
18000
|
+
value: ALL_COMPONENTS_SELECTOR,
|
|
18001
|
+
label: "All components"
|
|
18002
|
+
}
|
|
18003
|
+
];
|
|
18004
|
+
if (options.includeGlobalCss) {
|
|
18005
|
+
multiSelectOptions.push({
|
|
18006
|
+
value: GLOBAL_CSS_SELECTOR,
|
|
18007
|
+
label: "Global CSS"
|
|
18008
|
+
});
|
|
18009
|
+
}
|
|
18010
|
+
multiSelectOptions.push(
|
|
18011
|
+
...Object.keys(allComponents).map((key) => ({
|
|
18012
|
+
value: allComponents[key].machineName,
|
|
18013
|
+
label: `${allComponents[key].name} (${allComponents[key].machineName})`
|
|
18014
|
+
}))
|
|
18015
|
+
);
|
|
18016
|
+
const selectedItems = await p.multiselect({
|
|
18017
|
+
message: options.selectMessage || "Select items to download",
|
|
18018
|
+
options: multiSelectOptions,
|
|
18019
|
+
initialValues: options.includeGlobalCss && options.globalCssDefault !== false ? [GLOBAL_CSS_SELECTOR] : [],
|
|
17899
18020
|
required: true
|
|
17900
18021
|
});
|
|
17901
|
-
if (p.isCancel(
|
|
18022
|
+
if (p.isCancel(selectedItems)) {
|
|
17902
18023
|
throw new Error("Operation cancelled by user");
|
|
17903
18024
|
}
|
|
17904
|
-
const
|
|
18025
|
+
const includesAllComponents = selectedItems.includes(
|
|
17905
18026
|
ALL_COMPONENTS_SELECTOR
|
|
17906
|
-
)
|
|
18027
|
+
);
|
|
18028
|
+
const includesGlobalCss = selectedItems.includes(
|
|
18029
|
+
GLOBAL_CSS_SELECTOR
|
|
18030
|
+
);
|
|
18031
|
+
const selected = includesAllComponents ? allComponents : Object.fromEntries(
|
|
17907
18032
|
Object.entries(allComponents).filter(
|
|
17908
|
-
([, component]) =>
|
|
18033
|
+
([, component]) => selectedItems.includes(component.machineName)
|
|
17909
18034
|
)
|
|
17910
18035
|
);
|
|
17911
18036
|
if (!options.skipConfirmation) {
|
|
@@ -17917,7 +18042,11 @@ async function selectRemoteComponentsInteractive(allComponents, options) {
|
|
|
17917
18042
|
throw new Error("Operation cancelled by user");
|
|
17918
18043
|
}
|
|
17919
18044
|
}
|
|
17920
|
-
|
|
18045
|
+
const finalGlobalCss = options.includeGlobalCss ? includesGlobalCss : globalCssSelection;
|
|
18046
|
+
return {
|
|
18047
|
+
components: selected,
|
|
18048
|
+
includeGlobalCss: finalGlobalCss
|
|
18049
|
+
};
|
|
17921
18050
|
}
|
|
17922
18051
|
async function confirmSelection(count, customMessage) {
|
|
17923
18052
|
const componentLabel = count === 1 ? "component" : "components";
|
|
@@ -17991,7 +18120,7 @@ function buildCommand(program2) {
|
|
|
17991
18120
|
).option("--all", "Build all components").option(
|
|
17992
18121
|
"-c, --components <names>",
|
|
17993
18122
|
"Specific component(s) to build (comma-separated)"
|
|
17994
|
-
).option("--no-tailwind", "Skip Tailwind CSS building").option("-y, --yes", "Skip confirmation prompts").option("--client-id <id>", "Client ID").option("--client-secret <secret>", "Client Secret").option("--site-url <url>", "Site URL").
|
|
18123
|
+
).option("--no-tailwind", "Skip Tailwind CSS building").option("-y, --yes", "Skip confirmation prompts").option("--client-id <id>", "Client ID").option("--client-secret <secret>", "Client Secret").option("--site-url <url>", "Site URL").action(async (options) => {
|
|
17995
18124
|
try {
|
|
17996
18125
|
p.intro(chalk2.bold("Drupal Canvas CLI: build"));
|
|
17997
18126
|
validateComponentOptions(options);
|
|
@@ -18061,10 +18190,15 @@ function downloadCommand(program2) {
|
|
|
18061
18190
|
).option("--all", "Download all components").option("-y, --yes", "Skip all confirmation prompts").option(
|
|
18062
18191
|
"--skip-overwrite",
|
|
18063
18192
|
"Skip downloading components that already exist locally"
|
|
18064
|
-
).option("--
|
|
18193
|
+
).option("--skip-css", "Skip downloading global CSS").option("--css-only", "Download only global CSS (skip components)").action(async (options) => {
|
|
18065
18194
|
p.intro(chalk2.bold("Drupal Canvas CLI: download"));
|
|
18066
18195
|
try {
|
|
18067
18196
|
validateComponentOptions(options);
|
|
18197
|
+
if (options.skipCss && options.cssOnly) {
|
|
18198
|
+
throw new Error(
|
|
18199
|
+
"Cannot use both --skip-css and --css-only flags together"
|
|
18200
|
+
);
|
|
18201
|
+
}
|
|
18068
18202
|
updateConfigFromOptions(options);
|
|
18069
18203
|
await ensureConfig([
|
|
18070
18204
|
"siteUrl",
|
|
@@ -18075,35 +18209,50 @@ function downloadCommand(program2) {
|
|
|
18075
18209
|
]);
|
|
18076
18210
|
const config2 = getConfig();
|
|
18077
18211
|
const apiService = await createApiService();
|
|
18212
|
+
let components = {};
|
|
18213
|
+
let globalCss;
|
|
18078
18214
|
const s = p.spinner();
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
s.
|
|
18086
|
-
|
|
18087
|
-
|
|
18215
|
+
if (options.cssOnly) {
|
|
18216
|
+
s.start("Fetching global CSS");
|
|
18217
|
+
const globalAssetLibrary = await apiService.getGlobalAssetLibrary();
|
|
18218
|
+
globalCss = globalAssetLibrary?.css?.original || "";
|
|
18219
|
+
s.stop("Global CSS fetched");
|
|
18220
|
+
} else {
|
|
18221
|
+
s.start("Fetching components and global CSS");
|
|
18222
|
+
const [fetchedComponents, globalAssetLibrary] = await Promise.all([
|
|
18223
|
+
apiService.listComponents(),
|
|
18224
|
+
apiService.getGlobalAssetLibrary()
|
|
18225
|
+
]);
|
|
18226
|
+
components = fetchedComponents;
|
|
18227
|
+
globalCss = globalAssetLibrary?.css?.original || "";
|
|
18228
|
+
if (Object.keys(components).length === 0) {
|
|
18229
|
+
s.stop("No components found");
|
|
18230
|
+
p.outro("Download cancelled - no components were found");
|
|
18231
|
+
return;
|
|
18232
|
+
}
|
|
18233
|
+
s.stop(`Found ${Object.keys(components).length} components`);
|
|
18088
18234
|
}
|
|
18089
|
-
s.stop(`Found ${Object.keys(components).length} components`);
|
|
18090
18235
|
const allFlag = options.all || options.yes && !options.components || false;
|
|
18091
|
-
const { components: componentsToDownload } = await selectRemoteComponents(components, {
|
|
18236
|
+
const { components: componentsToDownload, includeGlobalCss } = await selectRemoteComponents(components, {
|
|
18092
18237
|
all: allFlag,
|
|
18093
18238
|
components: options.components,
|
|
18094
18239
|
skipConfirmation: options.yes,
|
|
18095
|
-
|
|
18240
|
+
skipCss: options.skipCss,
|
|
18241
|
+
cssOnly: options.cssOnly,
|
|
18242
|
+
includeGlobalCss: !options.skipCss,
|
|
18243
|
+
globalCssDefault: true,
|
|
18244
|
+
selectMessage: "Select items to download",
|
|
18096
18245
|
confirmMessage: `Download to ${config2.componentDir}?`
|
|
18097
18246
|
});
|
|
18098
|
-
const
|
|
18099
|
-
|
|
18100
|
-
);
|
|
18247
|
+
const componentCount = Object.keys(componentsToDownload).length;
|
|
18248
|
+
const componentPluralized = pluralizeComponent(componentCount);
|
|
18101
18249
|
const results = [];
|
|
18102
|
-
|
|
18250
|
+
const downloadMessage = options.cssOnly ? "Downloading global CSS" : componentCount > 0 ? `Downloading ${componentPluralized}` : "Processing request";
|
|
18251
|
+
s.start(downloadMessage);
|
|
18103
18252
|
for (const key in componentsToDownload) {
|
|
18104
18253
|
const component = componentsToDownload[key];
|
|
18105
18254
|
try {
|
|
18106
|
-
const componentDir =
|
|
18255
|
+
const componentDir = path3.join(
|
|
18107
18256
|
config2.componentDir,
|
|
18108
18257
|
component.machineName
|
|
18109
18258
|
);
|
|
@@ -18148,20 +18297,20 @@ function downloadCommand(program2) {
|
|
|
18148
18297
|
slots: component.slots || {}
|
|
18149
18298
|
};
|
|
18150
18299
|
await fs2.writeFile(
|
|
18151
|
-
|
|
18300
|
+
path3.join(componentDir, `component.yml`),
|
|
18152
18301
|
yaml__default.dump(metadata),
|
|
18153
18302
|
"utf-8"
|
|
18154
18303
|
);
|
|
18155
18304
|
if (component.sourceCodeJs) {
|
|
18156
18305
|
await fs2.writeFile(
|
|
18157
|
-
|
|
18306
|
+
path3.join(componentDir, `index.jsx`),
|
|
18158
18307
|
component.sourceCodeJs,
|
|
18159
18308
|
"utf-8"
|
|
18160
18309
|
);
|
|
18161
18310
|
}
|
|
18162
18311
|
if (component.sourceCodeCss) {
|
|
18163
18312
|
await fs2.writeFile(
|
|
18164
|
-
|
|
18313
|
+
path3.join(componentDir, `index.css`),
|
|
18165
18314
|
component.sourceCodeCss,
|
|
18166
18315
|
"utf-8"
|
|
18167
18316
|
);
|
|
@@ -18182,16 +18331,15 @@ function downloadCommand(program2) {
|
|
|
18182
18331
|
});
|
|
18183
18332
|
}
|
|
18184
18333
|
}
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
)
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
if (globalCss) {
|
|
18334
|
+
const successMessage = options.cssOnly && componentCount === 0 ? "Global CSS download completed" : `Processed ${componentCount} ${componentPluralized}`;
|
|
18335
|
+
s.stop(chalk2.green(successMessage));
|
|
18336
|
+
if (componentCount > 0) {
|
|
18337
|
+
reportResults(results, "Downloaded components", "Component");
|
|
18338
|
+
}
|
|
18339
|
+
if (includeGlobalCss && typeof globalCss === "string") {
|
|
18192
18340
|
let globalCssResult;
|
|
18193
18341
|
try {
|
|
18194
|
-
const globalCssPath =
|
|
18342
|
+
const globalCssPath = path3.join(config2.componentDir, "global.css");
|
|
18195
18343
|
await fs2.writeFile(globalCssPath, globalCss, "utf-8");
|
|
18196
18344
|
globalCssResult = {
|
|
18197
18345
|
itemName: "global.css",
|
|
@@ -18211,7 +18359,8 @@ function downloadCommand(program2) {
|
|
|
18211
18359
|
}
|
|
18212
18360
|
reportResults([globalCssResult], "Downloaded assets", "Asset");
|
|
18213
18361
|
}
|
|
18214
|
-
|
|
18362
|
+
const outroMessage = options.cssOnly && componentCount === 0 ? "\u2B07\uFE0F Global CSS downloaded successfully" : includeGlobalCss && componentCount > 0 ? "\u2B07\uFE0F Components and global CSS downloaded successfully" : componentCount > 0 ? "\u2B07\uFE0F Components downloaded successfully" : "\u2B07\uFE0F Download command completed";
|
|
18363
|
+
p.outro(outroMessage);
|
|
18215
18364
|
} catch (error) {
|
|
18216
18365
|
if (error instanceof Error) {
|
|
18217
18366
|
p.note(chalk2.red(`Error: ${error.message}`));
|
|
@@ -18229,11 +18378,10 @@ function scaffoldCommand(program2) {
|
|
|
18229
18378
|
).option(
|
|
18230
18379
|
"-d, --dir <directory>",
|
|
18231
18380
|
"Component directory to create component in"
|
|
18232
|
-
).
|
|
18381
|
+
).action(async (options) => {
|
|
18233
18382
|
p.intro(chalk2.bold("Drupal Canvas CLI: scaffold"));
|
|
18234
18383
|
try {
|
|
18235
18384
|
if (options.dir) setConfig({ componentDir: options.dir });
|
|
18236
|
-
if (options.verbose) setConfig({ verbose: options.verbose });
|
|
18237
18385
|
const config2 = getConfig();
|
|
18238
18386
|
const baseDir = config2.componentDir;
|
|
18239
18387
|
let componentName = options.name;
|
|
@@ -18254,13 +18402,13 @@ function scaffoldCommand(program2) {
|
|
|
18254
18402
|
}
|
|
18255
18403
|
componentName = name;
|
|
18256
18404
|
}
|
|
18257
|
-
const componentDir =
|
|
18405
|
+
const componentDir = path3.join(baseDir, componentName);
|
|
18258
18406
|
const s = p.spinner();
|
|
18259
18407
|
s.start(`Creating component "${componentName}"`);
|
|
18260
18408
|
try {
|
|
18261
18409
|
await fs2.mkdir(componentDir, { recursive: true });
|
|
18262
|
-
const templateDir =
|
|
18263
|
-
|
|
18410
|
+
const templateDir = path3.join(
|
|
18411
|
+
path3.dirname(new URL(import.meta.url).pathname),
|
|
18264
18412
|
"templates/hello-world"
|
|
18265
18413
|
);
|
|
18266
18414
|
const files = await fs2.readdir(templateDir);
|
|
@@ -18276,8 +18424,8 @@ function scaffoldCommand(program2) {
|
|
|
18276
18424
|
}
|
|
18277
18425
|
}
|
|
18278
18426
|
for (const file of files) {
|
|
18279
|
-
const srcPath =
|
|
18280
|
-
const destPath =
|
|
18427
|
+
const srcPath = path3.join(templateDir, file);
|
|
18428
|
+
const destPath = path3.join(componentDir, file);
|
|
18281
18429
|
let content = await fs2.readFile(srcPath, "utf-8");
|
|
18282
18430
|
const { pascalCaseName, className, displayName, machineName } = generateComponentNameFormats(componentName);
|
|
18283
18431
|
content = content.replace(/HelloWorld/g, pascalCaseName).replace(/hello-world-component/g, className).replace(/Hello World/g, displayName).replace(/hello_world/g, machineName);
|
|
@@ -18286,9 +18434,9 @@ function scaffoldCommand(program2) {
|
|
|
18286
18434
|
s.stop(chalk2.green(`Created component "${componentName}"`));
|
|
18287
18435
|
p.note(`Component "${componentName}" has been created:
|
|
18288
18436
|
- Directory: ${componentDir}
|
|
18289
|
-
- Component metadata: ${
|
|
18290
|
-
- Source file: ${
|
|
18291
|
-
- CSS file: ${
|
|
18437
|
+
- Component metadata: ${path3.join(componentDir, `component.yml`)}
|
|
18438
|
+
- Source file: ${path3.join(componentDir, `index.jsx`)}
|
|
18439
|
+
- CSS file: ${path3.join(componentDir, `index.css`)}`);
|
|
18292
18440
|
p.outro("\u{1F3D7}\uFE0F Scaffold command completed");
|
|
18293
18441
|
} catch (error) {
|
|
18294
18442
|
s.stop(chalk2.red(`Failed to create component "${componentName}"`));
|
|
@@ -18366,20 +18514,20 @@ var getDataDependenciesFromAst = (ast) => ast.program.body.filter((d2) => d2.typ
|
|
|
18366
18514
|
async function processComponentFiles(componentDir) {
|
|
18367
18515
|
const metadataPath = await findMetadataPath(componentDir);
|
|
18368
18516
|
const metadata = await readComponentMetadata(metadataPath);
|
|
18369
|
-
const distDir =
|
|
18517
|
+
const distDir = path3.join(componentDir, "dist");
|
|
18370
18518
|
const sourceCodeJs = await promises.readFile(
|
|
18371
|
-
|
|
18519
|
+
path3.join(componentDir, "index.jsx"),
|
|
18372
18520
|
"utf-8"
|
|
18373
18521
|
);
|
|
18374
|
-
const compiledJs = await promises.readFile(
|
|
18522
|
+
const compiledJs = await promises.readFile(path3.join(distDir, "index.js"), "utf-8");
|
|
18375
18523
|
let sourceCodeCss = "";
|
|
18376
18524
|
let compiledCss = "";
|
|
18377
18525
|
try {
|
|
18378
18526
|
sourceCodeCss = await promises.readFile(
|
|
18379
|
-
|
|
18527
|
+
path3.join(componentDir, "index.css"),
|
|
18380
18528
|
"utf-8"
|
|
18381
18529
|
);
|
|
18382
|
-
compiledCss = await promises.readFile(
|
|
18530
|
+
compiledCss = await promises.readFile(path3.join(distDir, "index.css"), "utf-8");
|
|
18383
18531
|
} catch {
|
|
18384
18532
|
}
|
|
18385
18533
|
return {
|
|
@@ -18391,7 +18539,7 @@ async function processComponentFiles(componentDir) {
|
|
|
18391
18539
|
};
|
|
18392
18540
|
}
|
|
18393
18541
|
async function findMetadataPath(componentDir) {
|
|
18394
|
-
const metadataPath =
|
|
18542
|
+
const metadataPath = path3.join(componentDir, "component.yml");
|
|
18395
18543
|
try {
|
|
18396
18544
|
await promises.access(metadataPath);
|
|
18397
18545
|
return metadataPath;
|
|
@@ -18412,10 +18560,10 @@ async function readComponentMetadata(filePath) {
|
|
|
18412
18560
|
}
|
|
18413
18561
|
const metadata = rawMetadata;
|
|
18414
18562
|
if (!metadata.name) {
|
|
18415
|
-
metadata.name =
|
|
18563
|
+
metadata.name = path3.basename(path3.dirname(filePath));
|
|
18416
18564
|
}
|
|
18417
18565
|
if (!metadata.machineName) {
|
|
18418
|
-
metadata.machineName =
|
|
18566
|
+
metadata.machineName = path3.basename(path3.dirname(filePath));
|
|
18419
18567
|
}
|
|
18420
18568
|
if (!metadata.slots || typeof metadata.slots !== "object") {
|
|
18421
18569
|
metadata.slots = {};
|
|
@@ -18585,12 +18733,17 @@ function uploadCommand(program2) {
|
|
|
18585
18733
|
program2.command("upload").description("build and upload local components and global CSS assets").option("--client-id <id>", "Client ID").option("--client-secret <secret>", "Client Secret").option("--site-url <url>", "Site URL").option("--scope <scope>", "Scope").option("-d, --dir <directory>", "Component directory").option(
|
|
18586
18734
|
"-c, --components <names>",
|
|
18587
18735
|
"Specific component(s) to upload (comma-separated)"
|
|
18588
|
-
).option("--all", "Upload all components").option("-y, --yes", "Skip confirmation prompts").option("--
|
|
18736
|
+
).option("--all", "Upload all components").option("-y, --yes", "Skip confirmation prompts").option("--no-tailwind", "Skip Tailwind CSS building").option("--skip-css", "Skip global CSS upload").option("--css-only", "Upload only global CSS (skip components)").action(async (options) => {
|
|
18589
18737
|
const allFlag = options.all || options.yes && !options.components || false;
|
|
18590
18738
|
const skipTailwind = !options.tailwind;
|
|
18591
18739
|
try {
|
|
18592
18740
|
p.intro(chalk2.bold("Drupal Canvas CLI: upload"));
|
|
18593
18741
|
validateComponentOptions(options);
|
|
18742
|
+
if (options.skipCss && options.cssOnly) {
|
|
18743
|
+
throw new Error(
|
|
18744
|
+
"Cannot use both --skip-css and --css-only flags together"
|
|
18745
|
+
);
|
|
18746
|
+
}
|
|
18594
18747
|
updateConfigFromOptions(options);
|
|
18595
18748
|
await ensureConfig([
|
|
18596
18749
|
"siteUrl",
|
|
@@ -18600,22 +18753,29 @@ function uploadCommand(program2) {
|
|
|
18600
18753
|
"componentDir"
|
|
18601
18754
|
]);
|
|
18602
18755
|
const config2 = getConfig();
|
|
18603
|
-
const { directories: componentsToUpload } = await selectLocalComponents(
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18756
|
+
const { directories: componentsToUpload, includeGlobalCss } = await selectLocalComponents({
|
|
18757
|
+
all: allFlag,
|
|
18758
|
+
components: options.components,
|
|
18759
|
+
skipConfirmation: options.yes,
|
|
18760
|
+
skipCss: options.skipCss,
|
|
18761
|
+
cssOnly: options.cssOnly,
|
|
18762
|
+
includeGlobalCss: !options.skipCss,
|
|
18763
|
+
globalCssDefault: true,
|
|
18764
|
+
selectMessage: "Select items to upload"
|
|
18765
|
+
});
|
|
18611
18766
|
const apiService = await createApiService();
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18767
|
+
await apiService.listComponents();
|
|
18768
|
+
let componentResults = [];
|
|
18769
|
+
if (!options.cssOnly && componentsToUpload.length > 0) {
|
|
18770
|
+
componentResults = await getBuildAndUploadResults(
|
|
18771
|
+
componentsToUpload,
|
|
18772
|
+
apiService,
|
|
18773
|
+
includeGlobalCss ?? false
|
|
18774
|
+
);
|
|
18775
|
+
reportResults(componentResults, "Uploaded components", "Component");
|
|
18776
|
+
if (componentResults.some((result) => !result.success)) {
|
|
18777
|
+
process.exit(1);
|
|
18778
|
+
}
|
|
18619
18779
|
}
|
|
18620
18780
|
if (skipTailwind) {
|
|
18621
18781
|
p.log.info("Skipping Tailwind CSS build");
|
|
@@ -18623,7 +18783,9 @@ function uploadCommand(program2) {
|
|
|
18623
18783
|
const s2 = p.spinner();
|
|
18624
18784
|
s2.start("Building Tailwind CSS");
|
|
18625
18785
|
const tailwindResult = await buildTailwindForComponents(
|
|
18626
|
-
componentsToUpload
|
|
18786
|
+
componentsToUpload,
|
|
18787
|
+
includeGlobalCss
|
|
18788
|
+
// Use local CSS if includeGlobalCss is true
|
|
18627
18789
|
);
|
|
18628
18790
|
const componentLabelPluralized = pluralizeComponent(
|
|
18629
18791
|
componentsToUpload.length
|
|
@@ -18639,14 +18801,20 @@ function uploadCommand(program2) {
|
|
|
18639
18801
|
chalk2.red(`Tailwind build failed, global assets upload aborted.`)
|
|
18640
18802
|
);
|
|
18641
18803
|
} else {
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18645
|
-
|
|
18646
|
-
|
|
18804
|
+
if (includeGlobalCss) {
|
|
18805
|
+
const globalCssResult = await uploadGlobalAssetLibrary(
|
|
18806
|
+
apiService,
|
|
18807
|
+
config2.componentDir
|
|
18808
|
+
);
|
|
18809
|
+
reportResults([globalCssResult], "Uploaded assets", "Asset");
|
|
18810
|
+
} else {
|
|
18811
|
+
p.log.info("Skipping global CSS upload");
|
|
18812
|
+
}
|
|
18647
18813
|
}
|
|
18648
18814
|
}
|
|
18649
|
-
|
|
18815
|
+
const componentCount = componentsToUpload.length;
|
|
18816
|
+
const outroMessage = options.cssOnly && componentCount === 0 ? "\u2B06\uFE0F Global CSS uploaded successfully" : includeGlobalCss && componentCount > 0 ? "\u2B06\uFE0F Components and global CSS uploaded successfully" : componentCount > 0 ? "\u2B06\uFE0F Components uploaded successfully" : "\u2B06\uFE0F Upload command completed";
|
|
18817
|
+
p.outro(outroMessage);
|
|
18650
18818
|
} catch (error) {
|
|
18651
18819
|
if (error instanceof Error) {
|
|
18652
18820
|
p.note(chalk2.red(`Error: ${error.message}`));
|
|
@@ -18662,11 +18830,11 @@ async function prepareComponentsForUpload(successfulBuilds, componentsToUpload)
|
|
|
18662
18830
|
const failed = [];
|
|
18663
18831
|
for (const buildResult of successfulBuilds) {
|
|
18664
18832
|
const dir = buildResult.itemName ? componentsToUpload.find(
|
|
18665
|
-
(d2) =>
|
|
18833
|
+
(d2) => path3.basename(d2) === buildResult.itemName
|
|
18666
18834
|
) : void 0;
|
|
18667
18835
|
if (!dir) continue;
|
|
18668
18836
|
try {
|
|
18669
|
-
const componentName =
|
|
18837
|
+
const componentName = path3.basename(dir);
|
|
18670
18838
|
const { sourceCodeJs, compiledJs, sourceCodeCss, compiledCss, metadata } = await processComponentFiles(dir);
|
|
18671
18839
|
if (!metadata) {
|
|
18672
18840
|
throw new Error("Invalid metadata file");
|
|
@@ -18719,11 +18887,14 @@ async function prepareComponentsForUpload(successfulBuilds, componentsToUpload)
|
|
|
18719
18887
|
}
|
|
18720
18888
|
return { prepared, failed };
|
|
18721
18889
|
}
|
|
18722
|
-
async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
18890
|
+
async function getBuildAndUploadResults(componentsToUpload, apiService, includeGlobalCss) {
|
|
18723
18891
|
const results = [];
|
|
18724
18892
|
const spinner6 = p.spinner();
|
|
18725
18893
|
spinner6.start("Building components");
|
|
18726
|
-
const buildResults = await buildSelectedComponents(
|
|
18894
|
+
const buildResults = await buildSelectedComponents(
|
|
18895
|
+
componentsToUpload,
|
|
18896
|
+
includeGlobalCss
|
|
18897
|
+
);
|
|
18727
18898
|
const successfulBuilds = buildResults.filter((build) => build.success);
|
|
18728
18899
|
const failedBuilds = buildResults.filter((build) => !build.success);
|
|
18729
18900
|
if (successfulBuilds.length === 0) {
|
|
@@ -18780,12 +18951,13 @@ async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
|
18780
18951
|
]
|
|
18781
18952
|
});
|
|
18782
18953
|
} else {
|
|
18954
|
+
const errorMessage = uploadResult.error?.message || "Unknown upload error";
|
|
18783
18955
|
results.push({
|
|
18784
18956
|
itemName: component.componentName,
|
|
18785
18957
|
success: false,
|
|
18786
18958
|
details: [
|
|
18787
18959
|
{
|
|
18788
|
-
content:
|
|
18960
|
+
content: errorMessage.trim() || "Unknown upload error"
|
|
18789
18961
|
}
|
|
18790
18962
|
]
|
|
18791
18963
|
});
|
|
@@ -18798,29 +18970,28 @@ async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
|
18798
18970
|
);
|
|
18799
18971
|
return results;
|
|
18800
18972
|
}
|
|
18801
|
-
async function buildSelectedComponents(componentDirs) {
|
|
18973
|
+
async function buildSelectedComponents(componentDirs, useLocalGlobalCss = true) {
|
|
18802
18974
|
const buildResults = [];
|
|
18803
18975
|
for (const dir of componentDirs) {
|
|
18804
|
-
buildResults.push(await buildComponent(dir));
|
|
18976
|
+
buildResults.push(await buildComponent(dir, useLocalGlobalCss));
|
|
18805
18977
|
}
|
|
18806
18978
|
return buildResults;
|
|
18807
18979
|
}
|
|
18808
18980
|
async function uploadGlobalAssetLibrary(apiService, componentDir) {
|
|
18809
18981
|
try {
|
|
18810
|
-
const distDir =
|
|
18811
|
-
const globalCompiledCssPath =
|
|
18982
|
+
const distDir = path3.join(componentDir, "dist");
|
|
18983
|
+
const globalCompiledCssPath = path3.join(distDir, "index.css");
|
|
18812
18984
|
const globalCompiledCssExists = await fileExists(globalCompiledCssPath);
|
|
18813
18985
|
if (globalCompiledCssExists) {
|
|
18814
18986
|
const globalCompiledCss = await fs2.readFile(
|
|
18815
|
-
|
|
18987
|
+
path3.join(distDir, "index.css"),
|
|
18816
18988
|
"utf-8"
|
|
18817
18989
|
);
|
|
18818
18990
|
const classNameCandidateIndexFile = await fs2.readFile(
|
|
18819
|
-
|
|
18991
|
+
path3.join(distDir, "index.js"),
|
|
18820
18992
|
"utf-8"
|
|
18821
18993
|
);
|
|
18822
|
-
const
|
|
18823
|
-
const originalCss = current.css.original;
|
|
18994
|
+
const originalCss = await getGlobalCss();
|
|
18824
18995
|
await apiService.updateGlobalAssetLibrary({
|
|
18825
18996
|
css: {
|
|
18826
18997
|
original: originalCss,
|
|
@@ -18866,7 +19037,7 @@ function validateCommand(program2) {
|
|
|
18866
19037
|
).option(
|
|
18867
19038
|
"-c, --components <names>",
|
|
18868
19039
|
"Specific component(s) to validate (comma-separated)"
|
|
18869
|
-
).option("--all", "Validate all components").option("-y, --yes", "Skip confirmation prompts").option(
|
|
19040
|
+
).option("--all", "Validate all components").option("-y, --yes", "Skip confirmation prompts").option(
|
|
18870
19041
|
"--fix",
|
|
18871
19042
|
"Apply available automatic fixes for linting issues",
|
|
18872
19043
|
false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drupal-canvas/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "CLI tool for managing Drupal Canvas code components",
|
|
5
5
|
"license": "GPL-2.0-or-later",
|
|
6
6
|
"repository": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@babel/parser": "^7.26.9",
|
|
53
53
|
"@clack/prompts": "^0.11.0",
|
|
54
|
-
"@drupal-canvas/eslint-config": "^0.0
|
|
54
|
+
"@drupal-canvas/eslint-config": "^0.1.0",
|
|
55
55
|
"@swc/wasm": "^1.12.1",
|
|
56
56
|
"axios": "^1.9.0",
|
|
57
57
|
"chalk": "^5.4.1",
|