@drupal-canvas/cli 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -7
- package/dist/index.js +444 -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
|
-
|
|
28
|
+
};
|
|
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
10986
|
const globalSourceCodeJs = globalAssetLibrary.js.original;
|
|
10932
|
-
const
|
|
10933
|
-
const distDir = path11.join(config2.componentDir, "dist");
|
|
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,52 @@ 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.stop("
|
|
18086
|
-
|
|
18087
|
-
|
|
18215
|
+
if (options.cssOnly) {
|
|
18216
|
+
s.start("Fetching global CSS");
|
|
18217
|
+
const {
|
|
18218
|
+
css: { original }
|
|
18219
|
+
} = await apiService.getGlobalAssetLibrary();
|
|
18220
|
+
globalCss = original;
|
|
18221
|
+
s.stop("Global CSS fetched");
|
|
18222
|
+
} else {
|
|
18223
|
+
s.start("Fetching components and global CSS");
|
|
18224
|
+
const [fetchedComponents, globalAssetLibrary] = await Promise.all([
|
|
18225
|
+
apiService.listComponents(),
|
|
18226
|
+
apiService.getGlobalAssetLibrary()
|
|
18227
|
+
]);
|
|
18228
|
+
components = fetchedComponents;
|
|
18229
|
+
globalCss = globalAssetLibrary.css.original;
|
|
18230
|
+
if (Object.keys(components).length === 0) {
|
|
18231
|
+
s.stop("No components found");
|
|
18232
|
+
p.outro("Download cancelled - no components were found");
|
|
18233
|
+
return;
|
|
18234
|
+
}
|
|
18235
|
+
s.stop(`Found ${Object.keys(components).length} components`);
|
|
18088
18236
|
}
|
|
18089
|
-
s.stop(`Found ${Object.keys(components).length} components`);
|
|
18090
18237
|
const allFlag = options.all || options.yes && !options.components || false;
|
|
18091
|
-
const { components: componentsToDownload } = await selectRemoteComponents(components, {
|
|
18238
|
+
const { components: componentsToDownload, includeGlobalCss } = await selectRemoteComponents(components, {
|
|
18092
18239
|
all: allFlag,
|
|
18093
18240
|
components: options.components,
|
|
18094
18241
|
skipConfirmation: options.yes,
|
|
18095
|
-
|
|
18242
|
+
skipCss: options.skipCss,
|
|
18243
|
+
cssOnly: options.cssOnly,
|
|
18244
|
+
includeGlobalCss: !options.skipCss,
|
|
18245
|
+
globalCssDefault: true,
|
|
18246
|
+
selectMessage: "Select items to download",
|
|
18096
18247
|
confirmMessage: `Download to ${config2.componentDir}?`
|
|
18097
18248
|
});
|
|
18098
|
-
const
|
|
18099
|
-
|
|
18100
|
-
);
|
|
18249
|
+
const componentCount = Object.keys(componentsToDownload).length;
|
|
18250
|
+
const componentPluralized = pluralizeComponent(componentCount);
|
|
18101
18251
|
const results = [];
|
|
18102
|
-
|
|
18252
|
+
const downloadMessage = options.cssOnly ? "Downloading global CSS" : componentCount > 0 ? `Downloading ${componentPluralized}` : "Processing request";
|
|
18253
|
+
s.start(downloadMessage);
|
|
18103
18254
|
for (const key in componentsToDownload) {
|
|
18104
18255
|
const component = componentsToDownload[key];
|
|
18105
18256
|
try {
|
|
18106
|
-
const componentDir =
|
|
18257
|
+
const componentDir = path3.join(
|
|
18107
18258
|
config2.componentDir,
|
|
18108
18259
|
component.machineName
|
|
18109
18260
|
);
|
|
@@ -18148,20 +18299,20 @@ function downloadCommand(program2) {
|
|
|
18148
18299
|
slots: component.slots || {}
|
|
18149
18300
|
};
|
|
18150
18301
|
await fs2.writeFile(
|
|
18151
|
-
|
|
18302
|
+
path3.join(componentDir, `component.yml`),
|
|
18152
18303
|
yaml__default.dump(metadata),
|
|
18153
18304
|
"utf-8"
|
|
18154
18305
|
);
|
|
18155
18306
|
if (component.sourceCodeJs) {
|
|
18156
18307
|
await fs2.writeFile(
|
|
18157
|
-
|
|
18308
|
+
path3.join(componentDir, `index.jsx`),
|
|
18158
18309
|
component.sourceCodeJs,
|
|
18159
18310
|
"utf-8"
|
|
18160
18311
|
);
|
|
18161
18312
|
}
|
|
18162
18313
|
if (component.sourceCodeCss) {
|
|
18163
18314
|
await fs2.writeFile(
|
|
18164
|
-
|
|
18315
|
+
path3.join(componentDir, `index.css`),
|
|
18165
18316
|
component.sourceCodeCss,
|
|
18166
18317
|
"utf-8"
|
|
18167
18318
|
);
|
|
@@ -18182,16 +18333,15 @@ function downloadCommand(program2) {
|
|
|
18182
18333
|
});
|
|
18183
18334
|
}
|
|
18184
18335
|
}
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
)
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
if (globalCss) {
|
|
18336
|
+
const successMessage = options.cssOnly && componentCount === 0 ? "Global CSS download completed" : `Processed ${componentCount} ${componentPluralized}`;
|
|
18337
|
+
s.stop(chalk2.green(successMessage));
|
|
18338
|
+
if (componentCount > 0) {
|
|
18339
|
+
reportResults(results, "Downloaded components", "Component");
|
|
18340
|
+
}
|
|
18341
|
+
if (includeGlobalCss && typeof globalCss === "string") {
|
|
18192
18342
|
let globalCssResult;
|
|
18193
18343
|
try {
|
|
18194
|
-
const globalCssPath =
|
|
18344
|
+
const globalCssPath = path3.join(config2.componentDir, "global.css");
|
|
18195
18345
|
await fs2.writeFile(globalCssPath, globalCss, "utf-8");
|
|
18196
18346
|
globalCssResult = {
|
|
18197
18347
|
itemName: "global.css",
|
|
@@ -18211,7 +18361,8 @@ function downloadCommand(program2) {
|
|
|
18211
18361
|
}
|
|
18212
18362
|
reportResults([globalCssResult], "Downloaded assets", "Asset");
|
|
18213
18363
|
}
|
|
18214
|
-
|
|
18364
|
+
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";
|
|
18365
|
+
p.outro(outroMessage);
|
|
18215
18366
|
} catch (error) {
|
|
18216
18367
|
if (error instanceof Error) {
|
|
18217
18368
|
p.note(chalk2.red(`Error: ${error.message}`));
|
|
@@ -18229,11 +18380,10 @@ function scaffoldCommand(program2) {
|
|
|
18229
18380
|
).option(
|
|
18230
18381
|
"-d, --dir <directory>",
|
|
18231
18382
|
"Component directory to create component in"
|
|
18232
|
-
).
|
|
18383
|
+
).action(async (options) => {
|
|
18233
18384
|
p.intro(chalk2.bold("Drupal Canvas CLI: scaffold"));
|
|
18234
18385
|
try {
|
|
18235
18386
|
if (options.dir) setConfig({ componentDir: options.dir });
|
|
18236
|
-
if (options.verbose) setConfig({ verbose: options.verbose });
|
|
18237
18387
|
const config2 = getConfig();
|
|
18238
18388
|
const baseDir = config2.componentDir;
|
|
18239
18389
|
let componentName = options.name;
|
|
@@ -18254,13 +18404,13 @@ function scaffoldCommand(program2) {
|
|
|
18254
18404
|
}
|
|
18255
18405
|
componentName = name;
|
|
18256
18406
|
}
|
|
18257
|
-
const componentDir =
|
|
18407
|
+
const componentDir = path3.join(baseDir, componentName);
|
|
18258
18408
|
const s = p.spinner();
|
|
18259
18409
|
s.start(`Creating component "${componentName}"`);
|
|
18260
18410
|
try {
|
|
18261
18411
|
await fs2.mkdir(componentDir, { recursive: true });
|
|
18262
|
-
const templateDir =
|
|
18263
|
-
|
|
18412
|
+
const templateDir = path3.join(
|
|
18413
|
+
path3.dirname(new URL(import.meta.url).pathname),
|
|
18264
18414
|
"templates/hello-world"
|
|
18265
18415
|
);
|
|
18266
18416
|
const files = await fs2.readdir(templateDir);
|
|
@@ -18276,8 +18426,8 @@ function scaffoldCommand(program2) {
|
|
|
18276
18426
|
}
|
|
18277
18427
|
}
|
|
18278
18428
|
for (const file of files) {
|
|
18279
|
-
const srcPath =
|
|
18280
|
-
const destPath =
|
|
18429
|
+
const srcPath = path3.join(templateDir, file);
|
|
18430
|
+
const destPath = path3.join(componentDir, file);
|
|
18281
18431
|
let content = await fs2.readFile(srcPath, "utf-8");
|
|
18282
18432
|
const { pascalCaseName, className, displayName, machineName } = generateComponentNameFormats(componentName);
|
|
18283
18433
|
content = content.replace(/HelloWorld/g, pascalCaseName).replace(/hello-world-component/g, className).replace(/Hello World/g, displayName).replace(/hello_world/g, machineName);
|
|
@@ -18286,9 +18436,9 @@ function scaffoldCommand(program2) {
|
|
|
18286
18436
|
s.stop(chalk2.green(`Created component "${componentName}"`));
|
|
18287
18437
|
p.note(`Component "${componentName}" has been created:
|
|
18288
18438
|
- Directory: ${componentDir}
|
|
18289
|
-
- Component metadata: ${
|
|
18290
|
-
- Source file: ${
|
|
18291
|
-
- CSS file: ${
|
|
18439
|
+
- Component metadata: ${path3.join(componentDir, `component.yml`)}
|
|
18440
|
+
- Source file: ${path3.join(componentDir, `index.jsx`)}
|
|
18441
|
+
- CSS file: ${path3.join(componentDir, `index.css`)}`);
|
|
18292
18442
|
p.outro("\u{1F3D7}\uFE0F Scaffold command completed");
|
|
18293
18443
|
} catch (error) {
|
|
18294
18444
|
s.stop(chalk2.red(`Failed to create component "${componentName}"`));
|
|
@@ -18366,20 +18516,20 @@ var getDataDependenciesFromAst = (ast) => ast.program.body.filter((d2) => d2.typ
|
|
|
18366
18516
|
async function processComponentFiles(componentDir) {
|
|
18367
18517
|
const metadataPath = await findMetadataPath(componentDir);
|
|
18368
18518
|
const metadata = await readComponentMetadata(metadataPath);
|
|
18369
|
-
const distDir =
|
|
18519
|
+
const distDir = path3.join(componentDir, "dist");
|
|
18370
18520
|
const sourceCodeJs = await promises.readFile(
|
|
18371
|
-
|
|
18521
|
+
path3.join(componentDir, "index.jsx"),
|
|
18372
18522
|
"utf-8"
|
|
18373
18523
|
);
|
|
18374
|
-
const compiledJs = await promises.readFile(
|
|
18524
|
+
const compiledJs = await promises.readFile(path3.join(distDir, "index.js"), "utf-8");
|
|
18375
18525
|
let sourceCodeCss = "";
|
|
18376
18526
|
let compiledCss = "";
|
|
18377
18527
|
try {
|
|
18378
18528
|
sourceCodeCss = await promises.readFile(
|
|
18379
|
-
|
|
18529
|
+
path3.join(componentDir, "index.css"),
|
|
18380
18530
|
"utf-8"
|
|
18381
18531
|
);
|
|
18382
|
-
compiledCss = await promises.readFile(
|
|
18532
|
+
compiledCss = await promises.readFile(path3.join(distDir, "index.css"), "utf-8");
|
|
18383
18533
|
} catch {
|
|
18384
18534
|
}
|
|
18385
18535
|
return {
|
|
@@ -18391,7 +18541,7 @@ async function processComponentFiles(componentDir) {
|
|
|
18391
18541
|
};
|
|
18392
18542
|
}
|
|
18393
18543
|
async function findMetadataPath(componentDir) {
|
|
18394
|
-
const metadataPath =
|
|
18544
|
+
const metadataPath = path3.join(componentDir, "component.yml");
|
|
18395
18545
|
try {
|
|
18396
18546
|
await promises.access(metadataPath);
|
|
18397
18547
|
return metadataPath;
|
|
@@ -18412,10 +18562,10 @@ async function readComponentMetadata(filePath) {
|
|
|
18412
18562
|
}
|
|
18413
18563
|
const metadata = rawMetadata;
|
|
18414
18564
|
if (!metadata.name) {
|
|
18415
|
-
metadata.name =
|
|
18565
|
+
metadata.name = path3.basename(path3.dirname(filePath));
|
|
18416
18566
|
}
|
|
18417
18567
|
if (!metadata.machineName) {
|
|
18418
|
-
metadata.machineName =
|
|
18568
|
+
metadata.machineName = path3.basename(path3.dirname(filePath));
|
|
18419
18569
|
}
|
|
18420
18570
|
if (!metadata.slots || typeof metadata.slots !== "object") {
|
|
18421
18571
|
metadata.slots = {};
|
|
@@ -18585,12 +18735,17 @@ function uploadCommand(program2) {
|
|
|
18585
18735
|
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
18736
|
"-c, --components <names>",
|
|
18587
18737
|
"Specific component(s) to upload (comma-separated)"
|
|
18588
|
-
).option("--all", "Upload all components").option("-y, --yes", "Skip confirmation prompts").option("--
|
|
18738
|
+
).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
18739
|
const allFlag = options.all || options.yes && !options.components || false;
|
|
18590
18740
|
const skipTailwind = !options.tailwind;
|
|
18591
18741
|
try {
|
|
18592
18742
|
p.intro(chalk2.bold("Drupal Canvas CLI: upload"));
|
|
18593
18743
|
validateComponentOptions(options);
|
|
18744
|
+
if (options.skipCss && options.cssOnly) {
|
|
18745
|
+
throw new Error(
|
|
18746
|
+
"Cannot use both --skip-css and --css-only flags together"
|
|
18747
|
+
);
|
|
18748
|
+
}
|
|
18594
18749
|
updateConfigFromOptions(options);
|
|
18595
18750
|
await ensureConfig([
|
|
18596
18751
|
"siteUrl",
|
|
@@ -18600,22 +18755,29 @@ function uploadCommand(program2) {
|
|
|
18600
18755
|
"componentDir"
|
|
18601
18756
|
]);
|
|
18602
18757
|
const config2 = getConfig();
|
|
18603
|
-
const { directories: componentsToUpload } = await selectLocalComponents(
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18758
|
+
const { directories: componentsToUpload, includeGlobalCss } = await selectLocalComponents({
|
|
18759
|
+
all: allFlag,
|
|
18760
|
+
components: options.components,
|
|
18761
|
+
skipConfirmation: options.yes,
|
|
18762
|
+
skipCss: options.skipCss,
|
|
18763
|
+
cssOnly: options.cssOnly,
|
|
18764
|
+
includeGlobalCss: !options.skipCss,
|
|
18765
|
+
globalCssDefault: true,
|
|
18766
|
+
selectMessage: "Select items to upload"
|
|
18767
|
+
});
|
|
18611
18768
|
const apiService = await createApiService();
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18769
|
+
await apiService.listComponents();
|
|
18770
|
+
let componentResults = [];
|
|
18771
|
+
if (!options.cssOnly && componentsToUpload.length > 0) {
|
|
18772
|
+
componentResults = await getBuildAndUploadResults(
|
|
18773
|
+
componentsToUpload,
|
|
18774
|
+
apiService,
|
|
18775
|
+
includeGlobalCss ?? false
|
|
18776
|
+
);
|
|
18777
|
+
reportResults(componentResults, "Uploaded components", "Component");
|
|
18778
|
+
if (componentResults.some((result) => !result.success)) {
|
|
18779
|
+
process.exit(1);
|
|
18780
|
+
}
|
|
18619
18781
|
}
|
|
18620
18782
|
if (skipTailwind) {
|
|
18621
18783
|
p.log.info("Skipping Tailwind CSS build");
|
|
@@ -18623,7 +18785,9 @@ function uploadCommand(program2) {
|
|
|
18623
18785
|
const s2 = p.spinner();
|
|
18624
18786
|
s2.start("Building Tailwind CSS");
|
|
18625
18787
|
const tailwindResult = await buildTailwindForComponents(
|
|
18626
|
-
componentsToUpload
|
|
18788
|
+
componentsToUpload,
|
|
18789
|
+
includeGlobalCss
|
|
18790
|
+
// Use local CSS if includeGlobalCss is true
|
|
18627
18791
|
);
|
|
18628
18792
|
const componentLabelPluralized = pluralizeComponent(
|
|
18629
18793
|
componentsToUpload.length
|
|
@@ -18639,14 +18803,20 @@ function uploadCommand(program2) {
|
|
|
18639
18803
|
chalk2.red(`Tailwind build failed, global assets upload aborted.`)
|
|
18640
18804
|
);
|
|
18641
18805
|
} else {
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18645
|
-
|
|
18646
|
-
|
|
18806
|
+
if (includeGlobalCss) {
|
|
18807
|
+
const globalCssResult = await uploadGlobalAssetLibrary(
|
|
18808
|
+
apiService,
|
|
18809
|
+
config2.componentDir
|
|
18810
|
+
);
|
|
18811
|
+
reportResults([globalCssResult], "Uploaded assets", "Asset");
|
|
18812
|
+
} else {
|
|
18813
|
+
p.log.info("Skipping global CSS upload");
|
|
18814
|
+
}
|
|
18647
18815
|
}
|
|
18648
18816
|
}
|
|
18649
|
-
|
|
18817
|
+
const componentCount = componentsToUpload.length;
|
|
18818
|
+
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";
|
|
18819
|
+
p.outro(outroMessage);
|
|
18650
18820
|
} catch (error) {
|
|
18651
18821
|
if (error instanceof Error) {
|
|
18652
18822
|
p.note(chalk2.red(`Error: ${error.message}`));
|
|
@@ -18662,11 +18832,11 @@ async function prepareComponentsForUpload(successfulBuilds, componentsToUpload)
|
|
|
18662
18832
|
const failed = [];
|
|
18663
18833
|
for (const buildResult of successfulBuilds) {
|
|
18664
18834
|
const dir = buildResult.itemName ? componentsToUpload.find(
|
|
18665
|
-
(d2) =>
|
|
18835
|
+
(d2) => path3.basename(d2) === buildResult.itemName
|
|
18666
18836
|
) : void 0;
|
|
18667
18837
|
if (!dir) continue;
|
|
18668
18838
|
try {
|
|
18669
|
-
const componentName =
|
|
18839
|
+
const componentName = path3.basename(dir);
|
|
18670
18840
|
const { sourceCodeJs, compiledJs, sourceCodeCss, compiledCss, metadata } = await processComponentFiles(dir);
|
|
18671
18841
|
if (!metadata) {
|
|
18672
18842
|
throw new Error("Invalid metadata file");
|
|
@@ -18719,11 +18889,14 @@ async function prepareComponentsForUpload(successfulBuilds, componentsToUpload)
|
|
|
18719
18889
|
}
|
|
18720
18890
|
return { prepared, failed };
|
|
18721
18891
|
}
|
|
18722
|
-
async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
18892
|
+
async function getBuildAndUploadResults(componentsToUpload, apiService, includeGlobalCss) {
|
|
18723
18893
|
const results = [];
|
|
18724
18894
|
const spinner6 = p.spinner();
|
|
18725
18895
|
spinner6.start("Building components");
|
|
18726
|
-
const buildResults = await buildSelectedComponents(
|
|
18896
|
+
const buildResults = await buildSelectedComponents(
|
|
18897
|
+
componentsToUpload,
|
|
18898
|
+
includeGlobalCss
|
|
18899
|
+
);
|
|
18727
18900
|
const successfulBuilds = buildResults.filter((build) => build.success);
|
|
18728
18901
|
const failedBuilds = buildResults.filter((build) => !build.success);
|
|
18729
18902
|
if (successfulBuilds.length === 0) {
|
|
@@ -18780,12 +18953,13 @@ async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
|
18780
18953
|
]
|
|
18781
18954
|
});
|
|
18782
18955
|
} else {
|
|
18956
|
+
const errorMessage = uploadResult.error?.message || "Unknown upload error";
|
|
18783
18957
|
results.push({
|
|
18784
18958
|
itemName: component.componentName,
|
|
18785
18959
|
success: false,
|
|
18786
18960
|
details: [
|
|
18787
18961
|
{
|
|
18788
|
-
content:
|
|
18962
|
+
content: errorMessage.trim() || "Unknown upload error"
|
|
18789
18963
|
}
|
|
18790
18964
|
]
|
|
18791
18965
|
});
|
|
@@ -18798,29 +18972,28 @@ async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
|
18798
18972
|
);
|
|
18799
18973
|
return results;
|
|
18800
18974
|
}
|
|
18801
|
-
async function buildSelectedComponents(componentDirs) {
|
|
18975
|
+
async function buildSelectedComponents(componentDirs, useLocalGlobalCss = true) {
|
|
18802
18976
|
const buildResults = [];
|
|
18803
18977
|
for (const dir of componentDirs) {
|
|
18804
|
-
buildResults.push(await buildComponent(dir));
|
|
18978
|
+
buildResults.push(await buildComponent(dir, useLocalGlobalCss));
|
|
18805
18979
|
}
|
|
18806
18980
|
return buildResults;
|
|
18807
18981
|
}
|
|
18808
18982
|
async function uploadGlobalAssetLibrary(apiService, componentDir) {
|
|
18809
18983
|
try {
|
|
18810
|
-
const distDir =
|
|
18811
|
-
const globalCompiledCssPath =
|
|
18984
|
+
const distDir = path3.join(componentDir, "dist");
|
|
18985
|
+
const globalCompiledCssPath = path3.join(distDir, "index.css");
|
|
18812
18986
|
const globalCompiledCssExists = await fileExists(globalCompiledCssPath);
|
|
18813
18987
|
if (globalCompiledCssExists) {
|
|
18814
18988
|
const globalCompiledCss = await fs2.readFile(
|
|
18815
|
-
|
|
18989
|
+
path3.join(distDir, "index.css"),
|
|
18816
18990
|
"utf-8"
|
|
18817
18991
|
);
|
|
18818
18992
|
const classNameCandidateIndexFile = await fs2.readFile(
|
|
18819
|
-
|
|
18993
|
+
path3.join(distDir, "index.js"),
|
|
18820
18994
|
"utf-8"
|
|
18821
18995
|
);
|
|
18822
|
-
const
|
|
18823
|
-
const originalCss = current.css.original;
|
|
18996
|
+
const originalCss = await getGlobalCss();
|
|
18824
18997
|
await apiService.updateGlobalAssetLibrary({
|
|
18825
18998
|
css: {
|
|
18826
18999
|
original: originalCss,
|
|
@@ -18866,7 +19039,7 @@ function validateCommand(program2) {
|
|
|
18866
19039
|
).option(
|
|
18867
19040
|
"-c, --components <names>",
|
|
18868
19041
|
"Specific component(s) to validate (comma-separated)"
|
|
18869
|
-
).option("--all", "Validate all components").option("-y, --yes", "Skip confirmation prompts").option(
|
|
19042
|
+
).option("--all", "Validate all components").option("-y, --yes", "Skip confirmation prompts").option(
|
|
18870
19043
|
"--fix",
|
|
18871
19044
|
"Apply available automatic fixes for linting issues",
|
|
18872
19045
|
false
|
|
@@ -18917,7 +19090,7 @@ function validateCommand(program2) {
|
|
|
18917
19090
|
// src/index.ts
|
|
18918
19091
|
var version = package_default.version;
|
|
18919
19092
|
var program = new Command();
|
|
18920
|
-
program.name("canvas").description("CLI tool for managing Drupal Canvas code components").version(version);
|
|
19093
|
+
program.name("canvas").description("CLI tool for managing Drupal Canvas code components").version(version ?? "0.0.0");
|
|
18921
19094
|
downloadCommand(program);
|
|
18922
19095
|
scaffoldCommand(program);
|
|
18923
19096
|
uploadCommand(program);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drupal-canvas/cli",
|
|
3
|
-
"version": "0.6.0",
|
|
4
3
|
"description": "CLI tool for managing Drupal Canvas code components",
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"license": "GPL-2.0-or-later",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -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",
|