@drupal-canvas/cli 0.3.0 → 0.4.0
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 +216 -5
- package/dist/index.js +457 -287
- package/dist/index.js.map +1 -1
- package/dist/templates/hello-world/component.yml +4 -4
- package/dist/templates/hello-world/index.jsx +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chalk2 from 'chalk';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
-
import * as
|
|
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
7
|
import path11, { win32, posix } from 'path';
|
|
@@ -14,18 +14,18 @@ import { transformSync } from '@swc/wasm';
|
|
|
14
14
|
import { basename } from 'path/win32';
|
|
15
15
|
import { ESLint } from 'eslint';
|
|
16
16
|
import { required } from '@drupal-canvas/eslint-config';
|
|
17
|
-
import { table } from 'table';
|
|
18
17
|
import { fileURLToPath } from 'url';
|
|
19
18
|
import { EventEmitter } from 'events';
|
|
20
19
|
import Stream from 'stream';
|
|
21
20
|
import { StringDecoder } from 'string_decoder';
|
|
21
|
+
import { table } from 'table';
|
|
22
22
|
import * as yaml from 'js-yaml';
|
|
23
23
|
import yaml__default from 'js-yaml';
|
|
24
24
|
import { parse } from '@babel/parser';
|
|
25
25
|
|
|
26
26
|
// package.json
|
|
27
27
|
var package_default = {
|
|
28
|
-
version: "0.
|
|
28
|
+
version: "0.4.0"};
|
|
29
29
|
function loadEnvFiles() {
|
|
30
30
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
31
31
|
if (homeDir) {
|
|
@@ -65,7 +65,7 @@ async function ensureConfig(requiredKeys) {
|
|
|
65
65
|
async function promptForConfig(key) {
|
|
66
66
|
switch (key) {
|
|
67
67
|
case "siteUrl": {
|
|
68
|
-
const value = await
|
|
68
|
+
const value = await p.text({
|
|
69
69
|
message: "Enter the site URL",
|
|
70
70
|
placeholder: "https://example.com",
|
|
71
71
|
validate: (value2) => {
|
|
@@ -75,45 +75,45 @@ async function promptForConfig(key) {
|
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
-
if (
|
|
79
|
-
|
|
78
|
+
if (p.isCancel(value)) {
|
|
79
|
+
p.cancel("Operation cancelled");
|
|
80
80
|
process.exit(0);
|
|
81
81
|
}
|
|
82
82
|
setConfig({ siteUrl: value });
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
85
85
|
case "clientId": {
|
|
86
|
-
const value = await
|
|
86
|
+
const value = await p.text({
|
|
87
87
|
message: "Enter your client ID",
|
|
88
88
|
validate: (value2) => {
|
|
89
89
|
if (!value2) return "Client ID is required";
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
-
if (
|
|
94
|
-
|
|
93
|
+
if (p.isCancel(value)) {
|
|
94
|
+
p.cancel("Operation cancelled");
|
|
95
95
|
process.exit(0);
|
|
96
96
|
}
|
|
97
97
|
setConfig({ clientId: value });
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
100
|
case "clientSecret": {
|
|
101
|
-
const value = await
|
|
101
|
+
const value = await p.password({
|
|
102
102
|
message: "Enter your client secret",
|
|
103
103
|
validate: (value2) => {
|
|
104
104
|
if (!value2) return "Client secret is required";
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
107
|
});
|
|
108
|
-
if (
|
|
109
|
-
|
|
108
|
+
if (p.isCancel(value)) {
|
|
109
|
+
p.cancel("Operation cancelled");
|
|
110
110
|
process.exit(0);
|
|
111
111
|
}
|
|
112
112
|
setConfig({ clientSecret: value });
|
|
113
113
|
break;
|
|
114
114
|
}
|
|
115
115
|
case "componentDir": {
|
|
116
|
-
const value = await
|
|
116
|
+
const value = await p.text({
|
|
117
117
|
message: "Enter the component directory",
|
|
118
118
|
placeholder: "./components",
|
|
119
119
|
validate: (value2) => {
|
|
@@ -121,8 +121,8 @@ async function promptForConfig(key) {
|
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
|
-
if (
|
|
125
|
-
|
|
124
|
+
if (p.isCancel(value)) {
|
|
125
|
+
p.cancel("Operation cancelled");
|
|
126
126
|
process.exit(0);
|
|
127
127
|
}
|
|
128
128
|
setConfig({ componentDir: value });
|
|
@@ -10822,9 +10822,9 @@ async function downloadJsSourceFromCanvas(componentsToDownload) {
|
|
|
10822
10822
|
}
|
|
10823
10823
|
} catch (error) {
|
|
10824
10824
|
if (error instanceof Error) {
|
|
10825
|
-
|
|
10825
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
10826
10826
|
} else {
|
|
10827
|
-
|
|
10827
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
10828
10828
|
}
|
|
10829
10829
|
}
|
|
10830
10830
|
}
|
|
@@ -10846,9 +10846,9 @@ async function copyLocalJsSource(componentsToCopy) {
|
|
|
10846
10846
|
}
|
|
10847
10847
|
} catch (error) {
|
|
10848
10848
|
if (error instanceof Error) {
|
|
10849
|
-
|
|
10849
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
10850
10850
|
} else {
|
|
10851
|
-
|
|
10851
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
10852
10852
|
}
|
|
10853
10853
|
}
|
|
10854
10854
|
}
|
|
@@ -10866,7 +10866,7 @@ async function cleanUpCacheDirectory() {
|
|
|
10866
10866
|
}
|
|
10867
10867
|
}
|
|
10868
10868
|
} catch (error) {
|
|
10869
|
-
|
|
10869
|
+
p.note(
|
|
10870
10870
|
chalk2.red(
|
|
10871
10871
|
`Failed to clean cache directory contents: ${error instanceof Error ? error.message : String(error)}`
|
|
10872
10872
|
)
|
|
@@ -11086,57 +11086,28 @@ async function buildComponent(componentDir) {
|
|
|
11086
11086
|
}
|
|
11087
11087
|
return result;
|
|
11088
11088
|
}
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
const summary = `${succeededText}, ${failedText}`;
|
|
11097
|
-
if (results.length > 0) {
|
|
11098
|
-
const tableData = [
|
|
11099
|
-
hasDetails ? [chalk2.bold(title), "", ""] : [chalk2.bold(title), ""],
|
|
11100
|
-
hasDetails ? [itemLabel, "Status", "Details"] : [itemLabel, "Status"],
|
|
11101
|
-
...results.map(
|
|
11102
|
-
(r) => hasDetails ? [
|
|
11103
|
-
r.itemName,
|
|
11104
|
-
r.success ? chalk2.green("Success") : chalk2.red("Failed"),
|
|
11105
|
-
r.details?.map(
|
|
11106
|
-
(d2) => d2.heading ? `${chalk2.underline(d2.heading)}:
|
|
11107
|
-
${d2.content}` : d2.content
|
|
11108
|
-
).join("\n\n")
|
|
11109
|
-
] : [
|
|
11110
|
-
r.itemName,
|
|
11111
|
-
r.success ? chalk2.green("Success") : chalk2.red("Failed")
|
|
11112
|
-
]
|
|
11113
|
-
),
|
|
11114
|
-
hasDetails ? ["SUMMARY", "", summary] : ["SUMMARY", summary]
|
|
11115
|
-
];
|
|
11116
|
-
p9.log.info(
|
|
11117
|
-
table(tableData, {
|
|
11118
|
-
spanningCells: [
|
|
11119
|
-
{
|
|
11120
|
-
row: 0,
|
|
11121
|
-
col: 0,
|
|
11122
|
-
colSpan: hasDetails ? 3 : 2,
|
|
11123
|
-
alignment: "center"
|
|
11124
|
-
},
|
|
11125
|
-
{
|
|
11126
|
-
row: results.length + 2,
|
|
11127
|
-
col: 0,
|
|
11128
|
-
colSpan: hasDetails ? 2 : 1,
|
|
11129
|
-
alignment: hasDetails ? "right" : "left"
|
|
11130
|
-
}
|
|
11131
|
-
],
|
|
11132
|
-
columns: {
|
|
11133
|
-
// Limit the width of the details column for improved readability of long details.
|
|
11134
|
-
2: { width: 100, wrapWord: true }
|
|
11135
|
-
}
|
|
11136
|
-
})
|
|
11089
|
+
|
|
11090
|
+
// src/utils/command-helpers.ts
|
|
11091
|
+
var ALL_COMPONENTS_SELECTOR = "_allComponents";
|
|
11092
|
+
function validateComponentOptions(options) {
|
|
11093
|
+
if (options.components && options.all) {
|
|
11094
|
+
throw new Error(
|
|
11095
|
+
"Cannot use --all and --components options together. Please use either:\n \u2022 --components to specify specific components, or\n \u2022 --all to process everything."
|
|
11137
11096
|
);
|
|
11138
11097
|
}
|
|
11139
11098
|
}
|
|
11099
|
+
function updateConfigFromOptions(options) {
|
|
11100
|
+
if (options.clientId) setConfig({ clientId: options.clientId });
|
|
11101
|
+
if (options.clientSecret) setConfig({ clientSecret: options.clientSecret });
|
|
11102
|
+
if (options.siteUrl) setConfig({ siteUrl: options.siteUrl });
|
|
11103
|
+
if (options.dir) setConfig({ componentDir: options.dir });
|
|
11104
|
+
if (options.scope) setConfig({ scope: options.scope });
|
|
11105
|
+
if (options.all) setConfig({ all: options.all });
|
|
11106
|
+
if (options.verbose) setConfig({ verbose: true });
|
|
11107
|
+
}
|
|
11108
|
+
function pluralizeComponent(count) {
|
|
11109
|
+
return count === 1 ? "component" : "components";
|
|
11110
|
+
}
|
|
11140
11111
|
|
|
11141
11112
|
// ../node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
11142
11113
|
var balanced = (a, b, str) => {
|
|
@@ -17772,50 +17743,244 @@ async function findComponentDirectories(baseDir) {
|
|
|
17772
17743
|
}
|
|
17773
17744
|
}
|
|
17774
17745
|
|
|
17775
|
-
// src/utils/
|
|
17776
|
-
async function selectLocalComponents(
|
|
17746
|
+
// src/utils/component-selector.ts
|
|
17747
|
+
async function selectLocalComponents(options) {
|
|
17777
17748
|
const config2 = getConfig();
|
|
17778
|
-
const
|
|
17779
|
-
const
|
|
17780
|
-
if (
|
|
17781
|
-
|
|
17782
|
-
|
|
17749
|
+
const componentDir = options.componentDir || config2.componentDir;
|
|
17750
|
+
const allLocalDirs = await findComponentDirectories(componentDir);
|
|
17751
|
+
if (allLocalDirs.length === 0) {
|
|
17752
|
+
throw new Error(`No local components were found in ${componentDir}`);
|
|
17753
|
+
}
|
|
17754
|
+
if (options.components) {
|
|
17755
|
+
return selectSpecificLocalComponents(
|
|
17756
|
+
options.components,
|
|
17757
|
+
allLocalDirs,
|
|
17758
|
+
options
|
|
17759
|
+
);
|
|
17783
17760
|
}
|
|
17784
|
-
if (
|
|
17785
|
-
|
|
17786
|
-
|
|
17761
|
+
if (options.all) {
|
|
17762
|
+
if (!options.skipConfirmation) {
|
|
17763
|
+
const confirmed = await confirmSelection(
|
|
17764
|
+
allLocalDirs.length,
|
|
17765
|
+
options.confirmMessage
|
|
17766
|
+
);
|
|
17767
|
+
if (!confirmed) {
|
|
17768
|
+
throw new Error("Operation cancelled by user");
|
|
17769
|
+
}
|
|
17770
|
+
}
|
|
17771
|
+
p.log.info(`Selected all components`);
|
|
17772
|
+
return { directories: allLocalDirs };
|
|
17787
17773
|
}
|
|
17788
|
-
|
|
17789
|
-
|
|
17774
|
+
return selectLocalComponentsInteractive(allLocalDirs, options);
|
|
17775
|
+
}
|
|
17776
|
+
async function selectSpecificLocalComponents(componentsInput, allLocalDirs, options) {
|
|
17777
|
+
const requestedNames = componentsInput.split(",").map((name) => name.trim()).filter((name) => name.length > 0);
|
|
17778
|
+
const notFound = [];
|
|
17779
|
+
const foundDirs = [];
|
|
17780
|
+
for (const requestedName of requestedNames) {
|
|
17781
|
+
const dir = allLocalDirs.find((d2) => path11.basename(d2) === requestedName);
|
|
17782
|
+
if (dir) {
|
|
17783
|
+
foundDirs.push(dir);
|
|
17784
|
+
} else {
|
|
17785
|
+
notFound.push(requestedName);
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
if (notFound.length > 0) {
|
|
17789
|
+
const message = options.notFoundMessage || `The following component(s) were not found locally: ${notFound.join(", ")}`;
|
|
17790
|
+
throw new Error(message);
|
|
17791
|
+
}
|
|
17792
|
+
if (!options.skipConfirmation) {
|
|
17793
|
+
const confirmed = await confirmSelection(
|
|
17794
|
+
foundDirs.length,
|
|
17795
|
+
options.confirmMessage
|
|
17796
|
+
);
|
|
17797
|
+
if (!confirmed) {
|
|
17798
|
+
throw new Error("Operation cancelled by user");
|
|
17799
|
+
}
|
|
17800
|
+
}
|
|
17801
|
+
return { directories: foundDirs };
|
|
17802
|
+
}
|
|
17803
|
+
async function selectLocalComponentsInteractive(allLocalDirs, options) {
|
|
17804
|
+
const selectedDirs = await p.multiselect({
|
|
17805
|
+
message: options.selectMessage || "Select components",
|
|
17790
17806
|
options: [
|
|
17791
17807
|
{
|
|
17792
|
-
value:
|
|
17808
|
+
value: ALL_COMPONENTS_SELECTOR,
|
|
17793
17809
|
label: "All components"
|
|
17794
17810
|
},
|
|
17795
|
-
...
|
|
17811
|
+
...allLocalDirs.map((dir) => ({
|
|
17796
17812
|
value: dir,
|
|
17797
17813
|
label: path11.basename(dir)
|
|
17798
17814
|
}))
|
|
17799
17815
|
],
|
|
17800
17816
|
required: true
|
|
17801
17817
|
});
|
|
17802
|
-
if (
|
|
17803
|
-
|
|
17804
|
-
|
|
17818
|
+
if (p.isCancel(selectedDirs)) {
|
|
17819
|
+
throw new Error("Operation cancelled by user");
|
|
17820
|
+
}
|
|
17821
|
+
const finalDirs = selectedDirs.includes(ALL_COMPONENTS_SELECTOR) ? allLocalDirs : selectedDirs;
|
|
17822
|
+
if (!options.skipConfirmation) {
|
|
17823
|
+
const confirmed = await confirmSelection(
|
|
17824
|
+
finalDirs.length,
|
|
17825
|
+
options.confirmMessage
|
|
17826
|
+
);
|
|
17827
|
+
if (!confirmed) {
|
|
17828
|
+
throw new Error("Operation cancelled by user");
|
|
17829
|
+
}
|
|
17830
|
+
}
|
|
17831
|
+
return { directories: finalDirs };
|
|
17832
|
+
}
|
|
17833
|
+
async function selectRemoteComponents(allComponents, options) {
|
|
17834
|
+
const componentCount = Object.keys(allComponents).length;
|
|
17835
|
+
if (componentCount === 0) {
|
|
17836
|
+
throw new Error("No components found");
|
|
17837
|
+
}
|
|
17838
|
+
if (options.all) {
|
|
17839
|
+
if (!options.skipConfirmation) {
|
|
17840
|
+
const confirmed = await confirmSelection(
|
|
17841
|
+
componentCount,
|
|
17842
|
+
options.confirmMessage
|
|
17843
|
+
);
|
|
17844
|
+
if (!confirmed) {
|
|
17845
|
+
throw new Error("Operation cancelled by user");
|
|
17846
|
+
}
|
|
17847
|
+
}
|
|
17848
|
+
return { components: allComponents };
|
|
17849
|
+
}
|
|
17850
|
+
if (options.components) {
|
|
17851
|
+
return selectSpecificRemoteComponents(
|
|
17852
|
+
options.components,
|
|
17853
|
+
allComponents,
|
|
17854
|
+
options
|
|
17855
|
+
);
|
|
17856
|
+
}
|
|
17857
|
+
return selectRemoteComponentsInteractive(allComponents, options);
|
|
17858
|
+
}
|
|
17859
|
+
async function selectSpecificRemoteComponents(componentsInput, allComponents, options) {
|
|
17860
|
+
const requestedNames = componentsInput.split(",").map((name) => name.trim()).filter((name) => name.length > 0);
|
|
17861
|
+
const notFound = [];
|
|
17862
|
+
const selected = {};
|
|
17863
|
+
for (const requestedName of requestedNames) {
|
|
17864
|
+
const component = allComponents[requestedName];
|
|
17865
|
+
if (component) {
|
|
17866
|
+
selected[requestedName] = component;
|
|
17867
|
+
} else {
|
|
17868
|
+
notFound.push(requestedName);
|
|
17869
|
+
}
|
|
17870
|
+
}
|
|
17871
|
+
if (notFound.length > 0) {
|
|
17872
|
+
const message = options.notFoundMessage || `The following component(s) were not found: ${notFound.join(", ")}`;
|
|
17873
|
+
throw new Error(message);
|
|
17874
|
+
}
|
|
17875
|
+
if (!options.skipConfirmation) {
|
|
17876
|
+
const confirmed = await confirmSelection(
|
|
17877
|
+
Object.keys(selected).length,
|
|
17878
|
+
options.confirmMessage
|
|
17879
|
+
);
|
|
17880
|
+
if (!confirmed) {
|
|
17881
|
+
throw new Error("Operation cancelled by user");
|
|
17882
|
+
}
|
|
17805
17883
|
}
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
17884
|
+
return { components: selected };
|
|
17885
|
+
}
|
|
17886
|
+
async function selectRemoteComponentsInteractive(allComponents, options) {
|
|
17887
|
+
const selectedMachineNames = await p.multiselect({
|
|
17888
|
+
message: options.selectMessage || "Select components to download",
|
|
17889
|
+
options: [
|
|
17890
|
+
{
|
|
17891
|
+
value: ALL_COMPONENTS_SELECTOR,
|
|
17892
|
+
label: "All components"
|
|
17893
|
+
},
|
|
17894
|
+
...Object.keys(allComponents).map((key) => ({
|
|
17895
|
+
value: allComponents[key].machineName,
|
|
17896
|
+
label: `${allComponents[key].name} (${allComponents[key].machineName})`
|
|
17897
|
+
}))
|
|
17898
|
+
],
|
|
17899
|
+
required: true
|
|
17900
|
+
});
|
|
17901
|
+
if (p.isCancel(selectedMachineNames)) {
|
|
17902
|
+
throw new Error("Operation cancelled by user");
|
|
17903
|
+
}
|
|
17904
|
+
const selected = selectedMachineNames.includes(
|
|
17905
|
+
ALL_COMPONENTS_SELECTOR
|
|
17906
|
+
) ? allComponents : Object.fromEntries(
|
|
17907
|
+
Object.entries(allComponents).filter(
|
|
17908
|
+
([, component]) => selectedMachineNames.includes(component.machineName)
|
|
17909
|
+
)
|
|
17910
|
+
);
|
|
17911
|
+
if (!options.skipConfirmation) {
|
|
17912
|
+
const confirmed = await confirmSelection(
|
|
17913
|
+
Object.keys(selected).length,
|
|
17914
|
+
options.confirmMessage
|
|
17915
|
+
);
|
|
17916
|
+
if (!confirmed) {
|
|
17917
|
+
throw new Error("Operation cancelled by user");
|
|
17918
|
+
}
|
|
17919
|
+
}
|
|
17920
|
+
return { components: selected };
|
|
17921
|
+
}
|
|
17922
|
+
async function confirmSelection(count, customMessage) {
|
|
17923
|
+
const componentLabel = count === 1 ? "component" : "components";
|
|
17924
|
+
const message = customMessage || `Process ${count} ${componentLabel}?`;
|
|
17925
|
+
const confirmed = await p.confirm({
|
|
17926
|
+
message,
|
|
17809
17927
|
initialValue: true
|
|
17810
17928
|
});
|
|
17811
|
-
if (
|
|
17812
|
-
|
|
17813
|
-
return null;
|
|
17929
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
17930
|
+
return false;
|
|
17814
17931
|
}
|
|
17815
|
-
|
|
17816
|
-
|
|
17932
|
+
return true;
|
|
17933
|
+
}
|
|
17934
|
+
function reportResults(results, title, itemLabel = "Component") {
|
|
17935
|
+
results.sort((a, b) => a.itemName.localeCompare(b.itemName));
|
|
17936
|
+
const successful = results.filter((r) => r.success).length;
|
|
17937
|
+
const failed = results.filter((r) => !r.success).length;
|
|
17938
|
+
const hasDetails = results.some((r) => (r.details?.length ?? 0) > 0);
|
|
17939
|
+
const succeededText = failed === 0 ? chalk2.green(`${successful} succeeded`) : `${successful} succeeded`;
|
|
17940
|
+
const failedText = failed > 0 ? chalk2.red(`${failed} failed`) : chalk2.dim(`${failed} failed`);
|
|
17941
|
+
const summary = `${succeededText}, ${failedText}`;
|
|
17942
|
+
if (results.length > 0) {
|
|
17943
|
+
const tableData = [
|
|
17944
|
+
hasDetails ? [chalk2.bold(title), "", ""] : [chalk2.bold(title), ""],
|
|
17945
|
+
hasDetails ? [itemLabel, "Status", "Details"] : [itemLabel, "Status"],
|
|
17946
|
+
...results.map(
|
|
17947
|
+
(r) => hasDetails ? [
|
|
17948
|
+
r.itemName,
|
|
17949
|
+
r.success ? chalk2.green("Success") : chalk2.red("Failed"),
|
|
17950
|
+
r.details?.map(
|
|
17951
|
+
(d2) => d2.heading ? `${chalk2.underline(d2.heading)}:
|
|
17952
|
+
${d2.content}` : d2.content
|
|
17953
|
+
).join("\n\n") ?? ""
|
|
17954
|
+
] : [
|
|
17955
|
+
r.itemName,
|
|
17956
|
+
r.success ? chalk2.green("Success") : chalk2.red("Failed")
|
|
17957
|
+
]
|
|
17958
|
+
),
|
|
17959
|
+
hasDetails ? ["SUMMARY", "", summary] : ["SUMMARY", summary]
|
|
17960
|
+
];
|
|
17961
|
+
p.log.info(
|
|
17962
|
+
table(tableData, {
|
|
17963
|
+
spanningCells: [
|
|
17964
|
+
{
|
|
17965
|
+
row: 0,
|
|
17966
|
+
col: 0,
|
|
17967
|
+
colSpan: hasDetails ? 3 : 2,
|
|
17968
|
+
alignment: "center"
|
|
17969
|
+
},
|
|
17970
|
+
{
|
|
17971
|
+
row: results.length + 2,
|
|
17972
|
+
col: 0,
|
|
17973
|
+
colSpan: hasDetails ? 2 : 1,
|
|
17974
|
+
alignment: hasDetails ? "right" : "left"
|
|
17975
|
+
}
|
|
17976
|
+
],
|
|
17977
|
+
columns: {
|
|
17978
|
+
// Limit the width of the details column for improved readability of long details.
|
|
17979
|
+
2: { width: 100, wrapWord: true }
|
|
17980
|
+
}
|
|
17981
|
+
})
|
|
17982
|
+
);
|
|
17817
17983
|
}
|
|
17818
|
-
return selectedDirs;
|
|
17819
17984
|
}
|
|
17820
17985
|
|
|
17821
17986
|
// src/commands/build.ts
|
|
@@ -17823,75 +17988,84 @@ function buildCommand(program2) {
|
|
|
17823
17988
|
program2.command("build").description("build local components and Tailwind CSS assets").option(
|
|
17824
17989
|
"-d, --dir <directory>",
|
|
17825
17990
|
"Component directory to build the components in"
|
|
17826
|
-
).option("--all", "Build all components").option(
|
|
17827
|
-
|
|
17828
|
-
|
|
17829
|
-
|
|
17830
|
-
|
|
17831
|
-
|
|
17832
|
-
|
|
17833
|
-
|
|
17834
|
-
|
|
17835
|
-
|
|
17836
|
-
|
|
17837
|
-
|
|
17838
|
-
|
|
17839
|
-
|
|
17840
|
-
|
|
17841
|
-
|
|
17842
|
-
|
|
17843
|
-
|
|
17844
|
-
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
const s1 = p9.spinner();
|
|
17848
|
-
s1.start(`Building ${componentLabelPluralized}`);
|
|
17849
|
-
const results = [];
|
|
17850
|
-
for (const componentDir of selectedComponents) {
|
|
17851
|
-
results.push(await buildComponent(componentDir));
|
|
17852
|
-
}
|
|
17853
|
-
s1.stop(
|
|
17854
|
-
chalk2.green(
|
|
17855
|
-
`Processed ${selectedComponents.length} ${componentLabelPluralized}`
|
|
17856
|
-
)
|
|
17857
|
-
);
|
|
17858
|
-
reportResults(results, "Built components", "Component");
|
|
17859
|
-
if (results.map((result) => result.success).includes(false)) {
|
|
17860
|
-
process.exit(1);
|
|
17861
|
-
}
|
|
17862
|
-
if (skipTailwind) {
|
|
17863
|
-
p9.log.info("Skipping Tailwind CSS build");
|
|
17864
|
-
} else {
|
|
17865
|
-
const s2 = p9.spinner();
|
|
17866
|
-
s2.start("Building Tailwind CSS");
|
|
17867
|
-
const tailwindResult = await buildTailwindForComponents(
|
|
17868
|
-
selectedComponents
|
|
17991
|
+
).option("--all", "Build all components").option(
|
|
17992
|
+
"-c, --components <names>",
|
|
17993
|
+
"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").option("--verbose", "Enable verbose output").action(async (options) => {
|
|
17995
|
+
try {
|
|
17996
|
+
p.intro(chalk2.bold("Drupal Canvas CLI: build"));
|
|
17997
|
+
validateComponentOptions(options);
|
|
17998
|
+
const allFlag = options.all || options.yes && !options.components || false;
|
|
17999
|
+
const skipTailwind = !options.tailwind;
|
|
18000
|
+
updateConfigFromOptions(options);
|
|
18001
|
+
if (!skipTailwind) {
|
|
18002
|
+
await ensureConfig(["siteUrl", "clientId", "clientSecret"]);
|
|
18003
|
+
}
|
|
18004
|
+
const { directories: componentsToBuild } = await selectLocalComponents({
|
|
18005
|
+
all: allFlag,
|
|
18006
|
+
components: options.components,
|
|
18007
|
+
skipConfirmation: options.yes,
|
|
18008
|
+
selectMessage: "Select components to build"
|
|
18009
|
+
});
|
|
18010
|
+
const componentLabelPluralized = pluralizeComponent(
|
|
18011
|
+
componentsToBuild.length
|
|
17869
18012
|
);
|
|
17870
|
-
|
|
18013
|
+
const s1 = p.spinner();
|
|
18014
|
+
s1.start(`Building ${componentLabelPluralized}`);
|
|
18015
|
+
const results = [];
|
|
18016
|
+
for (const componentDir of componentsToBuild) {
|
|
18017
|
+
results.push(await buildComponent(componentDir));
|
|
18018
|
+
}
|
|
18019
|
+
s1.stop(
|
|
17871
18020
|
chalk2.green(
|
|
17872
|
-
`Processed
|
|
18021
|
+
`Processed ${componentsToBuild.length} ${componentLabelPluralized}`
|
|
17873
18022
|
)
|
|
17874
18023
|
);
|
|
17875
|
-
reportResults(
|
|
17876
|
-
if (
|
|
17877
|
-
|
|
18024
|
+
reportResults(results, "Built components", "Component");
|
|
18025
|
+
if (results.map((result) => result.success).includes(false)) {
|
|
18026
|
+
process.exit(1);
|
|
18027
|
+
}
|
|
18028
|
+
if (skipTailwind) {
|
|
18029
|
+
p.log.info("Skipping Tailwind CSS build");
|
|
18030
|
+
} else {
|
|
18031
|
+
const s2 = p.spinner();
|
|
18032
|
+
s2.start("Building Tailwind CSS");
|
|
18033
|
+
const tailwindResult = await buildTailwindForComponents(
|
|
18034
|
+
componentsToBuild
|
|
18035
|
+
);
|
|
18036
|
+
s2.stop(
|
|
18037
|
+
chalk2.green(
|
|
18038
|
+
`Processed Tailwind CSS classes from ${componentsToBuild.length} selected local ${componentLabelPluralized} and all online components`
|
|
18039
|
+
)
|
|
18040
|
+
);
|
|
18041
|
+
reportResults([tailwindResult], "Built assets", "Asset");
|
|
18042
|
+
if (!tailwindResult.success) {
|
|
18043
|
+
return process.exit(1);
|
|
18044
|
+
}
|
|
17878
18045
|
}
|
|
18046
|
+
p.outro(`\u{1F4E6} Build completed`);
|
|
18047
|
+
} catch (error) {
|
|
18048
|
+
if (error instanceof Error) {
|
|
18049
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
18050
|
+
} else {
|
|
18051
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
18052
|
+
}
|
|
18053
|
+
process.exit(1);
|
|
17879
18054
|
}
|
|
17880
|
-
p9.outro(`\u{1F4E6} Build completed`);
|
|
17881
18055
|
});
|
|
17882
18056
|
}
|
|
17883
18057
|
function downloadCommand(program2) {
|
|
17884
|
-
program2.command("download").description("download components to your local filesystem").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(
|
|
17885
|
-
|
|
18058
|
+
program2.command("download").description("download components to your local filesystem").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(
|
|
18059
|
+
"-c, --components <names>",
|
|
18060
|
+
"Specific component(s) to download (comma-separated)"
|
|
18061
|
+
).option("--all", "Download all components").option("-y, --yes", "Skip all confirmation prompts").option(
|
|
18062
|
+
"--skip-overwrite",
|
|
18063
|
+
"Skip downloading components that already exist locally"
|
|
18064
|
+
).option("--verbose", "Enable verbose output").action(async (options) => {
|
|
18065
|
+
p.intro(chalk2.bold("Drupal Canvas CLI: download"));
|
|
17886
18066
|
try {
|
|
17887
|
-
|
|
17888
|
-
|
|
17889
|
-
setConfig({ clientSecret: options.clientSecret });
|
|
17890
|
-
if (options.siteUrl) setConfig({ siteUrl: options.siteUrl });
|
|
17891
|
-
if (options.dir) setConfig({ componentDir: options.dir });
|
|
17892
|
-
if (options.all) setConfig({ all: options.all });
|
|
17893
|
-
if (options.scope) setConfig({ scope: options.scope });
|
|
17894
|
-
if (options.verbose) setConfig({ verbose: true });
|
|
18067
|
+
validateComponentOptions(options);
|
|
18068
|
+
updateConfigFromOptions(options);
|
|
17895
18069
|
await ensureConfig([
|
|
17896
18070
|
"siteUrl",
|
|
17897
18071
|
"clientId",
|
|
@@ -17901,7 +18075,7 @@ function downloadCommand(program2) {
|
|
|
17901
18075
|
]);
|
|
17902
18076
|
const config2 = getConfig();
|
|
17903
18077
|
const apiService = await createApiService();
|
|
17904
|
-
const s =
|
|
18078
|
+
const s = p.spinner();
|
|
17905
18079
|
s.start("Fetching components");
|
|
17906
18080
|
const components = await apiService.listComponents();
|
|
17907
18081
|
const {
|
|
@@ -17909,63 +18083,21 @@ function downloadCommand(program2) {
|
|
|
17909
18083
|
} = await apiService.getGlobalAssetLibrary();
|
|
17910
18084
|
if (Object.keys(components).length === 0) {
|
|
17911
18085
|
s.stop("No components found");
|
|
17912
|
-
|
|
18086
|
+
p.outro("Download cancelled - no components were found");
|
|
17913
18087
|
return;
|
|
17914
18088
|
}
|
|
17915
18089
|
s.stop(`Found ${Object.keys(components).length} components`);
|
|
17916
|
-
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
|
|
17923
|
-
if (!component) {
|
|
17924
|
-
p9.note(chalk2.red(`Component "${options.component}" not found`));
|
|
17925
|
-
p9.outro("Download cancelled");
|
|
17926
|
-
return;
|
|
17927
|
-
}
|
|
17928
|
-
componentsToDownload = { component };
|
|
17929
|
-
} else {
|
|
17930
|
-
const selectedComponents = await p9.multiselect({
|
|
17931
|
-
message: "Select components to download",
|
|
17932
|
-
options: [
|
|
17933
|
-
{
|
|
17934
|
-
value: "_allComponents",
|
|
17935
|
-
label: "All components"
|
|
17936
|
-
},
|
|
17937
|
-
...Object.keys(components).map((key) => ({
|
|
17938
|
-
value: components[key].machineName,
|
|
17939
|
-
label: `${components[key].name} (${components[key].machineName})`
|
|
17940
|
-
}))
|
|
17941
|
-
],
|
|
17942
|
-
required: true
|
|
17943
|
-
});
|
|
17944
|
-
if (p9.isCancel(selectedComponents)) {
|
|
17945
|
-
p9.cancel("Operation cancelled");
|
|
17946
|
-
return;
|
|
17947
|
-
}
|
|
17948
|
-
if (selectedComponents.includes("_allComponents")) {
|
|
17949
|
-
componentsToDownload = components;
|
|
17950
|
-
} else {
|
|
17951
|
-
componentsToDownload = Object.fromEntries(
|
|
17952
|
-
Object.entries(components).filter(
|
|
17953
|
-
([, component]) => selectedComponents.includes(
|
|
17954
|
-
component.machineName
|
|
17955
|
-
)
|
|
17956
|
-
)
|
|
17957
|
-
);
|
|
17958
|
-
}
|
|
17959
|
-
}
|
|
17960
|
-
const componentPluralized = `component${Object.keys(componentsToDownload).length > 1 ? "s" : ""}`;
|
|
17961
|
-
const confirmDownload = await p9.confirm({
|
|
17962
|
-
message: `Download ${Object.keys(componentsToDownload).length} ${componentPluralized} to ${config2.componentDir}?`,
|
|
17963
|
-
initialValue: true
|
|
18090
|
+
const allFlag = options.all || options.yes && !options.components || false;
|
|
18091
|
+
const { components: componentsToDownload } = await selectRemoteComponents(components, {
|
|
18092
|
+
all: allFlag,
|
|
18093
|
+
components: options.components,
|
|
18094
|
+
skipConfirmation: options.yes,
|
|
18095
|
+
selectMessage: "Select components to download",
|
|
18096
|
+
confirmMessage: `Download to ${config2.componentDir}?`
|
|
17964
18097
|
});
|
|
17965
|
-
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
}
|
|
18098
|
+
const componentPluralized = pluralizeComponent(
|
|
18099
|
+
Object.keys(componentsToDownload).length
|
|
18100
|
+
);
|
|
17969
18101
|
const results = [];
|
|
17970
18102
|
s.start(`Downloading ${componentPluralized}`);
|
|
17971
18103
|
for (const key in componentsToDownload) {
|
|
@@ -17979,13 +18111,27 @@ function downloadCommand(program2) {
|
|
|
17979
18111
|
if (dirExists) {
|
|
17980
18112
|
const files = await fs2.readdir(componentDir);
|
|
17981
18113
|
if (files.length > 0) {
|
|
17982
|
-
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
|
|
17986
|
-
|
|
17987
|
-
|
|
17988
|
-
|
|
18114
|
+
if (options.skipOverwrite) {
|
|
18115
|
+
results.push({
|
|
18116
|
+
itemName: component.machineName,
|
|
18117
|
+
success: true,
|
|
18118
|
+
details: [
|
|
18119
|
+
{
|
|
18120
|
+
content: "Skipped (already exists)"
|
|
18121
|
+
}
|
|
18122
|
+
]
|
|
18123
|
+
});
|
|
18124
|
+
continue;
|
|
18125
|
+
}
|
|
18126
|
+
if (!options.yes) {
|
|
18127
|
+
const confirmDelete = await p.confirm({
|
|
18128
|
+
message: `The "${componentDir}" directory is not empty. Are you sure you want to delete and overwrite this directory?`,
|
|
18129
|
+
initialValue: true
|
|
18130
|
+
});
|
|
18131
|
+
if (p.isCancel(confirmDelete) || !confirmDelete) {
|
|
18132
|
+
p.cancel("Operation cancelled");
|
|
18133
|
+
process.exit(0);
|
|
18134
|
+
}
|
|
17989
18135
|
}
|
|
17990
18136
|
}
|
|
17991
18137
|
}
|
|
@@ -18065,12 +18211,12 @@ function downloadCommand(program2) {
|
|
|
18065
18211
|
}
|
|
18066
18212
|
reportResults([globalCssResult], "Downloaded assets", "Asset");
|
|
18067
18213
|
}
|
|
18068
|
-
|
|
18214
|
+
p.outro(`\u2B07\uFE0F Download command completed`);
|
|
18069
18215
|
} catch (error) {
|
|
18070
18216
|
if (error instanceof Error) {
|
|
18071
|
-
|
|
18217
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
18072
18218
|
} else {
|
|
18073
|
-
|
|
18219
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
18074
18220
|
}
|
|
18075
18221
|
process.exit(1);
|
|
18076
18222
|
}
|
|
@@ -18084,7 +18230,7 @@ function scaffoldCommand(program2) {
|
|
|
18084
18230
|
"-d, --dir <directory>",
|
|
18085
18231
|
"Component directory to create component in"
|
|
18086
18232
|
).option("--verbose", "Enable verbose output").action(async (options) => {
|
|
18087
|
-
|
|
18233
|
+
p.intro(chalk2.bold("Drupal Canvas CLI: scaffold"));
|
|
18088
18234
|
try {
|
|
18089
18235
|
if (options.dir) setConfig({ componentDir: options.dir });
|
|
18090
18236
|
if (options.verbose) setConfig({ verbose: options.verbose });
|
|
@@ -18092,7 +18238,7 @@ function scaffoldCommand(program2) {
|
|
|
18092
18238
|
const baseDir = config2.componentDir;
|
|
18093
18239
|
let componentName = options.name;
|
|
18094
18240
|
if (!componentName) {
|
|
18095
|
-
const name = await
|
|
18241
|
+
const name = await p.text({
|
|
18096
18242
|
message: "Enter the component name",
|
|
18097
18243
|
placeholder: "my-component",
|
|
18098
18244
|
validate: (value) => {
|
|
@@ -18102,14 +18248,14 @@ function scaffoldCommand(program2) {
|
|
|
18102
18248
|
return;
|
|
18103
18249
|
}
|
|
18104
18250
|
});
|
|
18105
|
-
if (
|
|
18106
|
-
|
|
18251
|
+
if (p.isCancel(name)) {
|
|
18252
|
+
p.cancel("Operation cancelled");
|
|
18107
18253
|
return;
|
|
18108
18254
|
}
|
|
18109
18255
|
componentName = name;
|
|
18110
18256
|
}
|
|
18111
18257
|
const componentDir = path11.join(baseDir, componentName);
|
|
18112
|
-
const s =
|
|
18258
|
+
const s = p.spinner();
|
|
18113
18259
|
s.start(`Creating component "${componentName}"`);
|
|
18114
18260
|
try {
|
|
18115
18261
|
await fs2.mkdir(componentDir, { recursive: true });
|
|
@@ -18120,12 +18266,12 @@ function scaffoldCommand(program2) {
|
|
|
18120
18266
|
const files = await fs2.readdir(templateDir);
|
|
18121
18267
|
const newDirFiles = await fs2.readdir(componentDir);
|
|
18122
18268
|
if (newDirFiles.length > 0) {
|
|
18123
|
-
const confirmDelete = await
|
|
18269
|
+
const confirmDelete = await p.confirm({
|
|
18124
18270
|
message: `The "${componentDir}" directory is not empty. Do you want to proceed and potentially overwrite existing files?`,
|
|
18125
18271
|
initialValue: true
|
|
18126
18272
|
});
|
|
18127
|
-
if (
|
|
18128
|
-
|
|
18273
|
+
if (p.isCancel(confirmDelete) || !confirmDelete) {
|
|
18274
|
+
p.cancel("Operation cancelled");
|
|
18129
18275
|
process.exit(0);
|
|
18130
18276
|
}
|
|
18131
18277
|
}
|
|
@@ -18138,21 +18284,21 @@ function scaffoldCommand(program2) {
|
|
|
18138
18284
|
await fs2.writeFile(destPath, content, "utf-8");
|
|
18139
18285
|
}
|
|
18140
18286
|
s.stop(chalk2.green(`Created component "${componentName}"`));
|
|
18141
|
-
|
|
18287
|
+
p.note(`Component "${componentName}" has been created:
|
|
18142
18288
|
- Directory: ${componentDir}
|
|
18143
18289
|
- Component metadata: ${path11.join(componentDir, `component.yml`)}
|
|
18144
18290
|
- Source file: ${path11.join(componentDir, `index.jsx`)}
|
|
18145
18291
|
- CSS file: ${path11.join(componentDir, `index.css`)}`);
|
|
18146
|
-
|
|
18292
|
+
p.outro("\u{1F3D7}\uFE0F Scaffold command completed");
|
|
18147
18293
|
} catch (error) {
|
|
18148
18294
|
s.stop(chalk2.red(`Failed to create component "${componentName}"`));
|
|
18149
18295
|
throw error;
|
|
18150
18296
|
}
|
|
18151
18297
|
} catch (error) {
|
|
18152
18298
|
if (error instanceof Error) {
|
|
18153
|
-
|
|
18299
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
18154
18300
|
} else {
|
|
18155
|
-
|
|
18301
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
18156
18302
|
}
|
|
18157
18303
|
process.exit(1);
|
|
18158
18304
|
}
|
|
@@ -18347,12 +18493,12 @@ async function processInPool(items, processor, concurrency = 10) {
|
|
|
18347
18493
|
}
|
|
18348
18494
|
return results.sort((a, b) => a.index - b.index);
|
|
18349
18495
|
}
|
|
18350
|
-
function createProgressCallback(
|
|
18496
|
+
function createProgressCallback(spinner6, operation, total) {
|
|
18351
18497
|
let completed = 0;
|
|
18352
18498
|
return () => {
|
|
18353
18499
|
completed++;
|
|
18354
18500
|
const percentage = Math.round(completed / total * 100);
|
|
18355
|
-
|
|
18501
|
+
spinner6.message(`${operation} (${completed}/${total} - ${percentage}%)`);
|
|
18356
18502
|
};
|
|
18357
18503
|
}
|
|
18358
18504
|
|
|
@@ -18436,19 +18582,16 @@ async function uploadComponents(uploadTasks, apiService, onProgress) {
|
|
|
18436
18582
|
});
|
|
18437
18583
|
}
|
|
18438
18584
|
function uploadCommand(program2) {
|
|
18439
|
-
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(
|
|
18440
|
-
|
|
18585
|
+
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
|
+
"-c, --components <names>",
|
|
18587
|
+
"Specific component(s) to upload (comma-separated)"
|
|
18588
|
+
).option("--all", "Upload all components").option("-y, --yes", "Skip confirmation prompts").option("--verbose", "Verbose output").option("--no-tailwind", "Skip Tailwind CSS building").action(async (options) => {
|
|
18589
|
+
const allFlag = options.all || options.yes && !options.components || false;
|
|
18441
18590
|
const skipTailwind = !options.tailwind;
|
|
18442
18591
|
try {
|
|
18443
|
-
|
|
18444
|
-
|
|
18445
|
-
|
|
18446
|
-
setConfig({ clientSecret: options.clientSecret });
|
|
18447
|
-
if (options.siteUrl) setConfig({ siteUrl: options.siteUrl });
|
|
18448
|
-
if (options.dir) setConfig({ componentDir: options.dir });
|
|
18449
|
-
if (options.scope) setConfig({ scope: options.scope });
|
|
18450
|
-
if (options.all) setConfig({ all: options.all });
|
|
18451
|
-
if (options.verbose) setConfig({ verbose: options.verbose });
|
|
18592
|
+
p.intro(chalk2.bold("Drupal Canvas CLI: upload"));
|
|
18593
|
+
validateComponentOptions(options);
|
|
18594
|
+
updateConfigFromOptions(options);
|
|
18452
18595
|
await ensureConfig([
|
|
18453
18596
|
"siteUrl",
|
|
18454
18597
|
"clientId",
|
|
@@ -18457,28 +18600,34 @@ function uploadCommand(program2) {
|
|
|
18457
18600
|
"componentDir"
|
|
18458
18601
|
]);
|
|
18459
18602
|
const config2 = getConfig();
|
|
18460
|
-
const componentsToUpload = await selectLocalComponents(
|
|
18461
|
-
|
|
18462
|
-
|
|
18603
|
+
const { directories: componentsToUpload } = await selectLocalComponents(
|
|
18604
|
+
{
|
|
18605
|
+
all: allFlag,
|
|
18606
|
+
components: options.components,
|
|
18607
|
+
skipConfirmation: options.yes,
|
|
18608
|
+
selectMessage: "Select components to upload"
|
|
18609
|
+
}
|
|
18463
18610
|
);
|
|
18464
|
-
if (!componentsToUpload || componentsToUpload.length === 0) {
|
|
18465
|
-
return;
|
|
18466
|
-
}
|
|
18467
18611
|
const apiService = await createApiService();
|
|
18468
18612
|
const componentResults = await getBuildAndUploadResults(
|
|
18469
18613
|
componentsToUpload,
|
|
18470
18614
|
apiService
|
|
18471
18615
|
);
|
|
18472
18616
|
reportResults(componentResults, "Uploaded components", "Component");
|
|
18617
|
+
if (componentResults.some((result) => !result.success)) {
|
|
18618
|
+
process.exit(1);
|
|
18619
|
+
}
|
|
18473
18620
|
if (skipTailwind) {
|
|
18474
|
-
|
|
18621
|
+
p.log.info("Skipping Tailwind CSS build");
|
|
18475
18622
|
} else {
|
|
18476
|
-
const s2 =
|
|
18623
|
+
const s2 = p.spinner();
|
|
18477
18624
|
s2.start("Building Tailwind CSS");
|
|
18478
18625
|
const tailwindResult = await buildTailwindForComponents(
|
|
18479
18626
|
componentsToUpload
|
|
18480
18627
|
);
|
|
18481
|
-
const componentLabelPluralized =
|
|
18628
|
+
const componentLabelPluralized = pluralizeComponent(
|
|
18629
|
+
componentsToUpload.length
|
|
18630
|
+
);
|
|
18482
18631
|
s2.stop(
|
|
18483
18632
|
chalk2.green(
|
|
18484
18633
|
`Processed Tailwind CSS classes from ${componentsToUpload.length} selected local ${componentLabelPluralized} and all online components`
|
|
@@ -18486,7 +18635,7 @@ function uploadCommand(program2) {
|
|
|
18486
18635
|
);
|
|
18487
18636
|
if (!tailwindResult.success && tailwindResult.details) {
|
|
18488
18637
|
reportResults([tailwindResult], "Built assets", "Asset");
|
|
18489
|
-
|
|
18638
|
+
p.note(
|
|
18490
18639
|
chalk2.red(`Tailwind build failed, global assets upload aborted.`)
|
|
18491
18640
|
);
|
|
18492
18641
|
} else {
|
|
@@ -18497,12 +18646,12 @@ function uploadCommand(program2) {
|
|
|
18497
18646
|
reportResults([globalCssResult], "Uploaded assets", "Asset");
|
|
18498
18647
|
}
|
|
18499
18648
|
}
|
|
18500
|
-
|
|
18649
|
+
p.outro("\u2B06\uFE0F Upload command completed");
|
|
18501
18650
|
} catch (error) {
|
|
18502
18651
|
if (error instanceof Error) {
|
|
18503
|
-
|
|
18652
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
18504
18653
|
} else {
|
|
18505
|
-
|
|
18654
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
18506
18655
|
}
|
|
18507
18656
|
process.exit(1);
|
|
18508
18657
|
}
|
|
@@ -18534,7 +18683,7 @@ async function prepareComponentsForUpload(successfulBuilds, componentsToUpload)
|
|
|
18534
18683
|
importedJsComponents = getImportsFromAst(ast, scope);
|
|
18535
18684
|
dataDependencies = getDataDependenciesFromAst(ast);
|
|
18536
18685
|
} catch (error) {
|
|
18537
|
-
|
|
18686
|
+
p.note(chalk2.red(`Error: ${error}`));
|
|
18538
18687
|
}
|
|
18539
18688
|
const componentPayloadArg = {
|
|
18540
18689
|
metadata,
|
|
@@ -18572,30 +18721,30 @@ async function prepareComponentsForUpload(successfulBuilds, componentsToUpload)
|
|
|
18572
18721
|
}
|
|
18573
18722
|
async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
18574
18723
|
const results = [];
|
|
18575
|
-
const
|
|
18576
|
-
|
|
18724
|
+
const spinner6 = p.spinner();
|
|
18725
|
+
spinner6.start("Building components");
|
|
18577
18726
|
const buildResults = await buildSelectedComponents(componentsToUpload);
|
|
18578
18727
|
const successfulBuilds = buildResults.filter((build) => build.success);
|
|
18579
18728
|
const failedBuilds = buildResults.filter((build) => !build.success);
|
|
18580
18729
|
if (successfulBuilds.length === 0) {
|
|
18581
18730
|
const message = "All component builds failed.";
|
|
18582
|
-
|
|
18731
|
+
spinner6.stop(chalk2.red(message));
|
|
18583
18732
|
return failedBuilds;
|
|
18584
18733
|
}
|
|
18585
|
-
|
|
18734
|
+
spinner6.message("Preparing components for upload");
|
|
18586
18735
|
const { prepared: preparedComponents, failed: preparationFailures } = await prepareComponentsForUpload(successfulBuilds, componentsToUpload);
|
|
18587
18736
|
results.push(...preparationFailures);
|
|
18588
18737
|
if (preparedComponents.length === 0) {
|
|
18589
|
-
|
|
18738
|
+
spinner6.stop(chalk2.red("All component preparations failed"));
|
|
18590
18739
|
return [...results, ...failedBuilds];
|
|
18591
18740
|
}
|
|
18592
18741
|
const machineNames = preparedComponents.map((c) => c.machineName);
|
|
18593
18742
|
const existenceProgress = createProgressCallback(
|
|
18594
|
-
|
|
18743
|
+
spinner6,
|
|
18595
18744
|
"Checking component existence",
|
|
18596
18745
|
machineNames.length
|
|
18597
18746
|
);
|
|
18598
|
-
|
|
18747
|
+
spinner6.message("Checking component existence");
|
|
18599
18748
|
const existenceResults = await checkComponentsExist(
|
|
18600
18749
|
machineNames,
|
|
18601
18750
|
apiService,
|
|
@@ -18607,11 +18756,11 @@ async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
|
18607
18756
|
shouldUpdate: existenceResults[index]?.exists || false
|
|
18608
18757
|
}));
|
|
18609
18758
|
const uploadProgress = createProgressCallback(
|
|
18610
|
-
|
|
18759
|
+
spinner6,
|
|
18611
18760
|
"Uploading components",
|
|
18612
18761
|
uploadTasks.length
|
|
18613
18762
|
);
|
|
18614
|
-
|
|
18763
|
+
spinner6.message("Uploading components");
|
|
18615
18764
|
const uploadResults = await uploadComponents(
|
|
18616
18765
|
uploadTasks,
|
|
18617
18766
|
apiService,
|
|
@@ -18644,7 +18793,7 @@ async function getBuildAndUploadResults(componentsToUpload, apiService) {
|
|
|
18644
18793
|
}
|
|
18645
18794
|
results.push(...failedBuilds);
|
|
18646
18795
|
const componentLabelPluralized = results.length === 1 ? "component" : "components";
|
|
18647
|
-
|
|
18796
|
+
spinner6.stop(
|
|
18648
18797
|
chalk2.green(`Processed ${results.length} ${componentLabelPluralized}`)
|
|
18649
18798
|
);
|
|
18650
18799
|
return results;
|
|
@@ -18714,33 +18863,54 @@ function validateCommand(program2) {
|
|
|
18714
18863
|
program2.command("validate").description("validate local components").option(
|
|
18715
18864
|
"-d, --dir <directory>",
|
|
18716
18865
|
"Component directory to validate the components in"
|
|
18717
|
-
).option(
|
|
18866
|
+
).option(
|
|
18867
|
+
"-c, --components <names>",
|
|
18868
|
+
"Specific component(s) to validate (comma-separated)"
|
|
18869
|
+
).option("--all", "Validate all components").option("-y, --yes", "Skip confirmation prompts").option("--verbose", "Enable verbose output").option(
|
|
18718
18870
|
"--fix",
|
|
18719
18871
|
"Apply available automatic fixes for linting issues",
|
|
18720
18872
|
false
|
|
18721
18873
|
).action(async (options) => {
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
18725
|
-
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
|
|
18732
|
-
|
|
18733
|
-
|
|
18734
|
-
|
|
18735
|
-
|
|
18736
|
-
|
|
18737
|
-
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18874
|
+
try {
|
|
18875
|
+
p.intro(chalk2.bold("Drupal Canvas CLI: validate"));
|
|
18876
|
+
validateComponentOptions(options);
|
|
18877
|
+
const allFlag = options.all || options.yes && !options.components || false;
|
|
18878
|
+
updateConfigFromOptions(options);
|
|
18879
|
+
const { directories: componentsToValidate } = await selectLocalComponents({
|
|
18880
|
+
all: allFlag,
|
|
18881
|
+
components: options.components,
|
|
18882
|
+
skipConfirmation: options.yes,
|
|
18883
|
+
selectMessage: "Select components to validate"
|
|
18884
|
+
});
|
|
18885
|
+
const componentPluralized = pluralizeComponent(
|
|
18886
|
+
componentsToValidate.length
|
|
18887
|
+
);
|
|
18888
|
+
const s = p.spinner();
|
|
18889
|
+
s.start(`Validating ${componentPluralized}`);
|
|
18890
|
+
const results = [];
|
|
18891
|
+
for (const componentDir of componentsToValidate) {
|
|
18892
|
+
results.push(await validateComponent(componentDir, options.fix));
|
|
18893
|
+
}
|
|
18894
|
+
s.stop(
|
|
18895
|
+
chalk2.green(
|
|
18896
|
+
`Processed ${componentsToValidate.length} ${componentPluralized}`
|
|
18897
|
+
)
|
|
18898
|
+
);
|
|
18899
|
+
reportResults(results, "Validation results", "Component");
|
|
18900
|
+
const hasErrors = results.some((r) => !r.success);
|
|
18901
|
+
if (hasErrors) {
|
|
18902
|
+
p.outro(`\u274C Validation completed with errors`);
|
|
18903
|
+
process.exit(1);
|
|
18904
|
+
}
|
|
18905
|
+
p.outro(`\u2705 Validation completed`);
|
|
18906
|
+
} catch (error) {
|
|
18907
|
+
if (error instanceof Error) {
|
|
18908
|
+
p.note(chalk2.red(`Error: ${error.message}`));
|
|
18909
|
+
} else {
|
|
18910
|
+
p.note(chalk2.red(`Unknown error: ${String(error)}`));
|
|
18911
|
+
}
|
|
18741
18912
|
process.exit(1);
|
|
18742
18913
|
}
|
|
18743
|
-
p9.outro(`\u2705 Validation completed`);
|
|
18744
18914
|
});
|
|
18745
18915
|
}
|
|
18746
18916
|
|