ds-01 1.0.13 → 1.1.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/.turbo/turbo-build.log +3 -2
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +16 -61
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -45
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +20 -60
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +0 -2
- package/dist/native/macos-key-helper.swift +34 -71
- package/dist/utils/secureKeyStore.d.ts +0 -5
- package/dist/utils/secureKeyStore.d.ts.map +1 -1
- package/dist/utils/secureKeyStore.js +13 -28
- package/package.json +2 -2
- package/scripts/build-macos-helper.js +52 -0
- package/src/commands/add.ts +66 -210
- package/src/commands/init.ts +26 -51
- package/src/commands/login.ts +71 -244
- package/src/commands/logout.ts +0 -2
- package/src/native/macos-key-helper.swift +34 -71
- package/src/utils/secureKeyStore.ts +41 -88
- package/src/test-key.ts +0 -20
- package/src/utils/deviceKey.ts +0 -19
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ---------------------------------------------------------
|
|
3
|
-
* PUBLIC API
|
|
4
|
-
* ---------------------------------------------------------
|
|
5
|
-
*/
|
|
6
1
|
export declare function createDeviceKey(): Promise<void>;
|
|
7
2
|
export declare function getDevicePublicKey(): Promise<string>;
|
|
8
3
|
export declare function signWithDeviceKey(data: Uint8Array): Promise<Uint8Array>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secureKeyStore.d.ts","sourceRoot":"","sources":["../../src/utils/secureKeyStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secureKeyStore.d.ts","sourceRoot":"","sources":["../../src/utils/secureKeyStore.ts"],"names":[],"mappings":"AAoUA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CASrD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ1D;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ7E;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CASrD"}
|
|
@@ -7,7 +7,11 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
const execFileAsync = promisify(execFile);
|
|
8
8
|
const KEY_NAME = "DS01-CLI-Device-Key";
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
// import.meta.ur -- current module ka location URL form mein deta hai
|
|
10
11
|
const __dirname = path.dirname(__filename);
|
|
12
|
+
//C:\Projects\DS01\cli\dist\utils
|
|
13
|
+
// __filename = where is THIS FILE?
|
|
14
|
+
// __dirname = which folder contains THIS FILE?
|
|
11
15
|
function getMacHelperPath() {
|
|
12
16
|
return path.resolve(__dirname, "../native/macos-key-helper.swift");
|
|
13
17
|
}
|
|
@@ -17,11 +21,7 @@ function ensureSupportedOS() {
|
|
|
17
21
|
throw new Error("DS01 secure device keys currently support Windows and macOS.");
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
|
-
|
|
21
|
-
* ---------------------------------------------------------
|
|
22
|
-
* WINDOWS
|
|
23
|
-
* ---------------------------------------------------------
|
|
24
|
-
*/
|
|
24
|
+
// for windows
|
|
25
25
|
async function createWindowsDeviceKey() {
|
|
26
26
|
const script = `
|
|
27
27
|
$ErrorActionPreference = "Stop"
|
|
@@ -84,15 +84,6 @@ Write-Output "CREATED"
|
|
|
84
84
|
throw new Error("Failed to create Windows DS01 device key.");
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Find exactly one valid DS01 certificate.
|
|
89
|
-
*
|
|
90
|
-
* We intentionally do not use Select-Object -First 1.
|
|
91
|
-
*
|
|
92
|
-
* 0 certificates -> error
|
|
93
|
-
* 1 certificate -> use it
|
|
94
|
-
* 2+ certificates -> error
|
|
95
|
-
*/
|
|
96
87
|
function getWindowsCertificateLookup() {
|
|
97
88
|
return `
|
|
98
89
|
$certificates = @(Get-ChildItem Cert:\\CurrentUser\\My |
|
|
@@ -113,6 +104,10 @@ if ($certificates.Count -gt 1) {
|
|
|
113
104
|
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]$certificates[0]
|
|
114
105
|
`;
|
|
115
106
|
}
|
|
107
|
+
// cert - just a variable holding the certificate object
|
|
108
|
+
// X509Certificate2 is a Windows/.NET certificate object
|
|
109
|
+
// that gives the code a standard way to work with the certificate and its associated key information
|
|
110
|
+
// X509Certificate2 a class/type, rather than simply a "format"
|
|
116
111
|
async function getWindowsPublicKey() {
|
|
117
112
|
const script = `
|
|
118
113
|
$ErrorActionPreference = "Stop"
|
|
@@ -218,11 +213,7 @@ Write-Output "DELETED"
|
|
|
218
213
|
windowsHide: true,
|
|
219
214
|
});
|
|
220
215
|
}
|
|
221
|
-
|
|
222
|
-
* ---------------------------------------------------------
|
|
223
|
-
* MACOS
|
|
224
|
-
* ---------------------------------------------------------
|
|
225
|
-
*/
|
|
216
|
+
// for Mac
|
|
226
217
|
async function runMacHelper(operation, data) {
|
|
227
218
|
const helper = getMacHelperPath();
|
|
228
219
|
const args = [helper, operation];
|
|
@@ -236,10 +227,8 @@ async function runMacHelper(operation, data) {
|
|
|
236
227
|
}
|
|
237
228
|
async function createMacDeviceKey() {
|
|
238
229
|
const result = await runMacHelper("create");
|
|
239
|
-
if (result !== "CREATED" &&
|
|
240
|
-
result
|
|
241
|
-
throw new Error(result ||
|
|
242
|
-
"Failed to create macOS Secure Enclave device key.");
|
|
230
|
+
if (result !== "CREATED" && result !== "EXISTS") {
|
|
231
|
+
throw new Error(result || "Failed to create macOS Secure Enclave device key.");
|
|
243
232
|
}
|
|
244
233
|
}
|
|
245
234
|
async function getMacPublicKey() {
|
|
@@ -259,11 +248,7 @@ async function signMacDeviceKey(data) {
|
|
|
259
248
|
async function deleteMacDeviceKey() {
|
|
260
249
|
await runMacHelper("delete");
|
|
261
250
|
}
|
|
262
|
-
|
|
263
|
-
* ---------------------------------------------------------
|
|
264
|
-
* PUBLIC API
|
|
265
|
-
* ---------------------------------------------------------
|
|
266
|
-
*/
|
|
251
|
+
// Public APIs which we use this for creating keys and certificate
|
|
267
252
|
export async function createDeviceKey() {
|
|
268
253
|
ensureSupportedOS();
|
|
269
254
|
if (os.platform() === "win32") {
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ds-01",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.01",
|
|
4
4
|
"description": "Make your site best with DS01",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"ds01": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "tsc && node scripts/copy-native.js"
|
|
10
|
+
"build": "tsc && node scripts/copy-native.js && node scripts/build-macos-helper.js"
|
|
11
11
|
},
|
|
12
12
|
"publishConfig": {
|
|
13
13
|
"access": "public"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
if (process.platform !== "darwin") {
|
|
6
|
+
console.log("Skipping macOS native helper build.");
|
|
7
|
+
process.exit(0);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const root = process.cwd();
|
|
11
|
+
|
|
12
|
+
const source = path.join(
|
|
13
|
+
root,
|
|
14
|
+
"src",
|
|
15
|
+
"native",
|
|
16
|
+
"macos-key-helper.swift",
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const nativeDir = path.join(
|
|
20
|
+
root,
|
|
21
|
+
"dist",
|
|
22
|
+
"native",
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const output = path.join(
|
|
26
|
+
nativeDir,
|
|
27
|
+
"macos-key-helper",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(source)) {
|
|
31
|
+
throw new Error(`Swift helper not found: ${source}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fs.mkdirSync(nativeDir, {
|
|
35
|
+
recursive: true,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log("Building macOS native helper...");
|
|
39
|
+
|
|
40
|
+
execFileSync(
|
|
41
|
+
"swiftc",
|
|
42
|
+
[
|
|
43
|
+
source,
|
|
44
|
+
"-o",
|
|
45
|
+
output,
|
|
46
|
+
],
|
|
47
|
+
{
|
|
48
|
+
stdio: "inherit",
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
console.log("macOS native helper built successfully.");
|
package/src/commands/add.ts
CHANGED
|
@@ -12,12 +12,9 @@ import machineIdPkg from "node-machine-id";
|
|
|
12
12
|
|
|
13
13
|
const { machineIdSync } = machineIdPkg;
|
|
14
14
|
|
|
15
|
-
const API_BASE_URL =
|
|
16
|
-
process.env.DS01_API_URL || "https://ds-01.vercel.app";
|
|
15
|
+
const API_BASE_URL = process.env.DS01_API_URL || "https://ds-01.vercel.app";
|
|
17
16
|
|
|
18
|
-
//
|
|
19
|
-
// Helper: Verify Tailwind exists
|
|
20
|
-
// ---------------------------------------------------------
|
|
17
|
+
// function for tailwind dependency check
|
|
21
18
|
|
|
22
19
|
function checkTailwindInstallation() {
|
|
23
20
|
const targetDir = process.cwd();
|
|
@@ -33,9 +30,7 @@ function checkTailwindInstallation() {
|
|
|
33
30
|
process.exit(1);
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
const pkgJson = JSON.parse(
|
|
37
|
-
fs.readFileSync(pkgJsonPath, "utf-8"),
|
|
38
|
-
);
|
|
33
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
39
34
|
|
|
40
35
|
const allDeps = {
|
|
41
36
|
...pkgJson.dependencies,
|
|
@@ -44,47 +39,33 @@ function checkTailwindInstallation() {
|
|
|
44
39
|
|
|
45
40
|
if (!allDeps["tailwindcss"]) {
|
|
46
41
|
cancel(
|
|
47
|
-
pc.red(
|
|
48
|
-
"Tailwind CSS is missing from your project dependencies.\n",
|
|
49
|
-
) +
|
|
42
|
+
pc.red("Tailwind CSS is missing from your project dependencies.\n") +
|
|
50
43
|
pc.gray(
|
|
51
44
|
"DS01 components rely strictly on Tailwind CSS for styling.\n\n",
|
|
52
45
|
) +
|
|
53
46
|
pc.white(
|
|
54
47
|
"Kindly install it and configure your project, then retry:\n",
|
|
55
48
|
) +
|
|
56
|
-
pc.cyan(
|
|
57
|
-
" npm install tailwindcss @tailwindcss/postcss postcss\n\n",
|
|
58
|
-
) +
|
|
49
|
+
pc.cyan(" npm install tailwindcss @tailwindcss/postcss postcss\n\n") +
|
|
59
50
|
pc.gray("Official Setup Guide: ") +
|
|
60
|
-
pc.underline(
|
|
61
|
-
"https://tailwindcss.com/docs/installation",
|
|
62
|
-
),
|
|
51
|
+
pc.underline("https://tailwindcss.com/docs/installation"),
|
|
63
52
|
);
|
|
64
53
|
|
|
65
54
|
process.exit(1);
|
|
66
55
|
}
|
|
67
56
|
}
|
|
68
57
|
|
|
69
|
-
//
|
|
70
|
-
// Helper: Find dependencies that are actually missing
|
|
71
|
-
// ---------------------------------------------------------
|
|
58
|
+
// function to Find dependencies that are actually missing
|
|
72
59
|
|
|
73
|
-
function getMissingDependencies(
|
|
74
|
-
|
|
75
|
-
): string[] {
|
|
76
|
-
const packageJsonPath = path.join(
|
|
77
|
-
process.cwd(),
|
|
78
|
-
"package.json",
|
|
79
|
-
);
|
|
60
|
+
function getMissingDependencies(dependencies: string[]): string[] {
|
|
61
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
80
62
|
|
|
63
|
+
// I cannot check what is installed, so treat all required dependencies as missing
|
|
81
64
|
if (!fs.existsSync(packageJsonPath)) {
|
|
82
65
|
return dependencies;
|
|
83
66
|
}
|
|
84
67
|
|
|
85
|
-
const packageJson = JSON.parse(
|
|
86
|
-
fs.readFileSync(packageJsonPath, "utf-8"),
|
|
87
|
-
);
|
|
68
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
88
69
|
|
|
89
70
|
const installedDependencies = {
|
|
90
71
|
...(packageJson.dependencies || {}),
|
|
@@ -96,17 +77,10 @@ function getMissingDependencies(
|
|
|
96
77
|
);
|
|
97
78
|
}
|
|
98
79
|
|
|
99
|
-
// ---------------------------------------------------------
|
|
100
|
-
// ADD COMMAND
|
|
101
|
-
// ---------------------------------------------------------
|
|
102
|
-
|
|
103
80
|
export const add = new Command()
|
|
104
81
|
.name("add")
|
|
105
82
|
.description("Add a component from DS01 to your project")
|
|
106
|
-
.argument(
|
|
107
|
-
"<component>",
|
|
108
|
-
"The name of the component (e.g., premium-section)",
|
|
109
|
-
)
|
|
83
|
+
.argument("<component>", "The name of the component (e.g., premium-section)")
|
|
110
84
|
.action(async (componentName: string) => {
|
|
111
85
|
console.log();
|
|
112
86
|
|
|
@@ -116,62 +90,39 @@ export const add = new Command()
|
|
|
116
90
|
)}`,
|
|
117
91
|
);
|
|
118
92
|
|
|
119
|
-
//
|
|
120
|
-
// 1. Validate project
|
|
121
|
-
// -----------------------------------------------------
|
|
93
|
+
// validatin
|
|
122
94
|
|
|
123
95
|
checkTailwindInstallation();
|
|
124
96
|
|
|
125
97
|
const cwd = process.cwd();
|
|
126
98
|
|
|
127
|
-
const configPath = path.join(
|
|
128
|
-
cwd,
|
|
129
|
-
"ds01.config.json",
|
|
130
|
-
);
|
|
99
|
+
const configPath = path.join(cwd, "ds01.config.json");
|
|
131
100
|
|
|
132
101
|
if (!fs.existsSync(configPath)) {
|
|
133
|
-
cancel(
|
|
134
|
-
pc.red(
|
|
135
|
-
"ds01.config.json not found. Run 'npx ds-01 init' first.",
|
|
136
|
-
),
|
|
137
|
-
);
|
|
102
|
+
cancel(pc.red("ds01.config.json not found. Run 'npx ds-01 init' first."));
|
|
138
103
|
|
|
139
104
|
process.exit(1);
|
|
140
105
|
}
|
|
141
106
|
|
|
142
|
-
const config = JSON.parse(
|
|
143
|
-
fs.readFileSync(configPath, "utf-8"),
|
|
144
|
-
);
|
|
107
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
145
108
|
|
|
146
|
-
//
|
|
147
|
-
// 2. Authentication
|
|
148
|
-
// -----------------------------------------------------
|
|
109
|
+
// for auth
|
|
149
110
|
|
|
150
111
|
const token = getToken();
|
|
151
112
|
const machineId = machineIdSync();
|
|
152
113
|
|
|
153
114
|
if (!token || !machineId) {
|
|
154
|
-
cancel(
|
|
155
|
-
pc.red(
|
|
156
|
-
"You are not authenticated. Run 'npx ds-01 login' first.",
|
|
157
|
-
),
|
|
158
|
-
);
|
|
115
|
+
cancel(pc.red("You are not authenticated. Run 'npx ds-01 login' first."));
|
|
159
116
|
|
|
160
117
|
process.exit(1);
|
|
161
118
|
}
|
|
162
119
|
|
|
163
120
|
const s = spinner();
|
|
164
121
|
|
|
165
|
-
s.start(
|
|
166
|
-
`Fetching ${pc.cyan(
|
|
167
|
-
`<${componentName} />`,
|
|
168
|
-
)} from registry...`,
|
|
169
|
-
);
|
|
122
|
+
s.start(`Fetching ${pc.cyan(`<${componentName} />`)} from registry...`);
|
|
170
123
|
|
|
171
124
|
try {
|
|
172
|
-
//
|
|
173
|
-
// 3. Create request-specific signed message
|
|
174
|
-
// --------------------------------------------------
|
|
125
|
+
// Creating request-specific signed message
|
|
175
126
|
|
|
176
127
|
const timestamp = Date.now().toString();
|
|
177
128
|
|
|
@@ -182,70 +133,43 @@ export const add = new Command()
|
|
|
182
133
|
machineId,
|
|
183
134
|
].join("\n");
|
|
184
135
|
|
|
185
|
-
//
|
|
186
|
-
// 4. Sign request with secure device private key
|
|
187
|
-
// --------------------------------------------------
|
|
136
|
+
// Sign request with secure device private key
|
|
188
137
|
|
|
189
138
|
const signature = await signWithDeviceKey(
|
|
190
139
|
new TextEncoder().encode(message),
|
|
191
140
|
);
|
|
192
141
|
|
|
193
|
-
const signatureBase64 =
|
|
194
|
-
Buffer.from(signature).toString("base64");
|
|
142
|
+
const signatureBase64 = Buffer.from(signature).toString("base64");
|
|
195
143
|
|
|
196
|
-
//
|
|
197
|
-
// 5. Request component from registry
|
|
198
|
-
// --------------------------------------------------
|
|
144
|
+
// Request component from registry
|
|
199
145
|
|
|
200
146
|
const response = await fetch(
|
|
201
147
|
`${API_BASE_URL}/api/registry/${componentName}`,
|
|
202
148
|
{
|
|
203
149
|
method: "GET",
|
|
204
|
-
|
|
205
150
|
headers: {
|
|
206
151
|
Authorization: `Bearer ${token}`,
|
|
207
|
-
|
|
208
152
|
"X-Machine-ID": machineId,
|
|
209
|
-
|
|
210
153
|
"X-DS01-Timestamp": timestamp,
|
|
211
|
-
|
|
212
154
|
"X-DS01-Signature": signatureBase64,
|
|
213
155
|
},
|
|
214
156
|
},
|
|
215
157
|
);
|
|
216
158
|
|
|
217
|
-
//
|
|
218
|
-
// 6. Handle registry errors
|
|
219
|
-
// --------------------------------------------------
|
|
159
|
+
// Handle registry errors
|
|
220
160
|
|
|
221
161
|
if (!response.ok) {
|
|
222
|
-
const errorData =
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
s.stop(
|
|
226
|
-
pc.red("Component fetch failed."),
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
cancel(
|
|
230
|
-
errorData?.error ||
|
|
231
|
-
`Server returned HTTP ${response.status}`,
|
|
232
|
-
);
|
|
233
|
-
|
|
162
|
+
const errorData = await response.json().catch(() => null);
|
|
163
|
+
s.stop(pc.red("Component fetch failed."));
|
|
164
|
+
cancel(errorData?.error || `Server returned HTTP ${response.status}`);
|
|
234
165
|
process.exit(1);
|
|
235
166
|
}
|
|
236
167
|
|
|
237
|
-
const componentData =
|
|
238
|
-
await response.json();
|
|
168
|
+
const componentData = await response.json();
|
|
239
169
|
|
|
240
|
-
//
|
|
241
|
-
// 7. Create component directory
|
|
242
|
-
// --------------------------------------------------
|
|
170
|
+
// Create component directory
|
|
243
171
|
|
|
244
|
-
const targetDir = path.join(
|
|
245
|
-
cwd,
|
|
246
|
-
config.componentsPath,
|
|
247
|
-
componentName,
|
|
248
|
-
);
|
|
172
|
+
const targetDir = path.join(cwd, config.componentsPath, componentName);
|
|
249
173
|
|
|
250
174
|
if (!fs.existsSync(targetDir)) {
|
|
251
175
|
fs.mkdirSync(targetDir, {
|
|
@@ -253,49 +177,29 @@ export const add = new Command()
|
|
|
253
177
|
});
|
|
254
178
|
}
|
|
255
179
|
|
|
256
|
-
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
componentData.files.map(
|
|
262
|
-
(file: any) =>
|
|
263
|
-
file.name.replace(
|
|
264
|
-
/\.[^/.]+$/,
|
|
265
|
-
"",
|
|
266
|
-
),
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
// --------------------------------------------------
|
|
270
|
-
// 9. Write component files
|
|
271
|
-
// --------------------------------------------------
|
|
180
|
+
|
|
181
|
+
// Extract bundled file names
|
|
182
|
+
const bundledFileNames = componentData.files.map((file: any) =>
|
|
183
|
+
file.name.replace(/\.[^/.]+$/, ""),
|
|
184
|
+
);
|
|
272
185
|
|
|
186
|
+
|
|
187
|
+
// Write component files
|
|
273
188
|
for (const file of componentData.files) {
|
|
274
|
-
const filePath = path.join(
|
|
275
|
-
targetDir,
|
|
276
|
-
file.name,
|
|
277
|
-
);
|
|
189
|
+
const filePath = path.join(targetDir, file.name);
|
|
278
190
|
|
|
279
191
|
let content = file.content;
|
|
280
192
|
|
|
281
|
-
bundledFileNames.forEach(
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
content = content.replace(
|
|
289
|
-
regex,
|
|
290
|
-
`from "./${fileName}"`,
|
|
291
|
-
);
|
|
292
|
-
},
|
|
293
|
-
);
|
|
193
|
+
bundledFileNames.forEach((fileName: string) => {
|
|
194
|
+
const regex = new RegExp(
|
|
195
|
+
`from\\s+["']\\.[^"']*?\\/${fileName}["']`,
|
|
196
|
+
"g",
|
|
197
|
+
);
|
|
294
198
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
);
|
|
199
|
+
content = content.replace(regex, `from "./${fileName}"`);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
fs.writeFileSync(filePath, content);
|
|
299
203
|
}
|
|
300
204
|
|
|
301
205
|
s.stop(
|
|
@@ -306,85 +210,46 @@ export const add = new Command()
|
|
|
306
210
|
),
|
|
307
211
|
);
|
|
308
212
|
|
|
309
|
-
|
|
310
|
-
//
|
|
311
|
-
|
|
213
|
+
|
|
214
|
+
// Install ONLY missing dependencies
|
|
215
|
+
const registryDependencies = Array.isArray(componentData.dependencies)
|
|
216
|
+
? componentData.dependencies
|
|
217
|
+
: [];
|
|
312
218
|
|
|
313
|
-
const
|
|
314
|
-
Array.isArray(componentData.dependencies)
|
|
315
|
-
? componentData.dependencies
|
|
316
|
-
: [];
|
|
317
|
-
|
|
318
|
-
const missingDependencies =
|
|
319
|
-
getMissingDependencies(
|
|
320
|
-
registryDependencies,
|
|
321
|
-
);
|
|
219
|
+
const missingDependencies = getMissingDependencies(registryDependencies);
|
|
322
220
|
|
|
323
221
|
if (missingDependencies.length > 0) {
|
|
324
|
-
const depsToInstall =
|
|
325
|
-
missingDependencies.join(" ");
|
|
222
|
+
const depsToInstall = missingDependencies.join(" ");
|
|
326
223
|
|
|
327
224
|
s.start(
|
|
328
|
-
`Installing missing dependencies: ${pc.cyan(
|
|
329
|
-
depsToInstall,
|
|
330
|
-
)}...`,
|
|
225
|
+
`Installing missing dependencies: ${pc.cyan(depsToInstall)}...`,
|
|
331
226
|
);
|
|
332
227
|
|
|
333
228
|
try {
|
|
334
|
-
execSync(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
stdio: "ignore",
|
|
338
|
-
},
|
|
339
|
-
);
|
|
229
|
+
execSync(`npm install ${depsToInstall}`, {
|
|
230
|
+
stdio: "ignore",
|
|
231
|
+
});
|
|
340
232
|
|
|
341
233
|
s.stop(
|
|
342
234
|
pc.green(
|
|
343
|
-
`Dependencies installed successfully: ${pc.gray(
|
|
344
|
-
depsToInstall,
|
|
345
|
-
)}`,
|
|
235
|
+
`Dependencies installed successfully: ${pc.gray(depsToInstall)}`,
|
|
346
236
|
),
|
|
347
237
|
);
|
|
348
238
|
} catch {
|
|
349
|
-
s.stop(
|
|
350
|
-
pc.red(
|
|
351
|
-
"Failed to auto-install dependencies.",
|
|
352
|
-
),
|
|
353
|
-
);
|
|
239
|
+
s.stop(pc.red("Failed to auto-install dependencies."));
|
|
354
240
|
|
|
355
241
|
note(
|
|
356
|
-
`Please run: ${pc.cyan(
|
|
357
|
-
`npm install ${depsToInstall}`,
|
|
358
|
-
)} manually.`,
|
|
242
|
+
`Please run: ${pc.cyan(`npm install ${depsToInstall}`)} manually.`,
|
|
359
243
|
"Manual Action Required",
|
|
360
244
|
);
|
|
361
245
|
}
|
|
362
246
|
}
|
|
363
247
|
|
|
364
|
-
|
|
365
|
-
// 11. No dependencies needed
|
|
366
|
-
// --------------------------------------------------
|
|
367
|
-
|
|
368
|
-
// We intentionally don't show a spinner here.
|
|
369
|
-
//
|
|
370
|
-
// Example:
|
|
371
|
-
//
|
|
372
|
-
// DS01 requires ["motion"]
|
|
373
|
-
// package.json already contains "motion"
|
|
374
|
-
//
|
|
375
|
-
// → Nothing happens.
|
|
376
|
-
// → No npm install.
|
|
377
|
-
// → No unnecessary package changes.
|
|
378
|
-
|
|
379
|
-
// --------------------------------------------------
|
|
380
|
-
// 12. Success
|
|
381
|
-
// --------------------------------------------------
|
|
248
|
+
|
|
382
249
|
|
|
383
250
|
const mainFile =
|
|
384
251
|
bundledFileNames.find(
|
|
385
|
-
(name: string) =>
|
|
386
|
-
name.toLowerCase() ===
|
|
387
|
-
componentName.toLowerCase(),
|
|
252
|
+
(name: string) => name.toLowerCase() === componentName.toLowerCase(),
|
|
388
253
|
) || bundledFileNames[0];
|
|
389
254
|
|
|
390
255
|
outro(
|
|
@@ -397,19 +262,10 @@ export const add = new Command()
|
|
|
397
262
|
),
|
|
398
263
|
);
|
|
399
264
|
} catch (error: any) {
|
|
400
|
-
s.stop(
|
|
401
|
-
pc.red(
|
|
402
|
-
"An error occurred during injection.",
|
|
403
|
-
),
|
|
404
|
-
);
|
|
265
|
+
s.stop(pc.red("An error occurred during injection."));
|
|
405
266
|
|
|
406
|
-
cancel(
|
|
407
|
-
pc.gray(
|
|
408
|
-
error?.message ||
|
|
409
|
-
"Unknown CLI Error",
|
|
410
|
-
),
|
|
411
|
-
);
|
|
267
|
+
cancel(pc.gray(error?.message || "Unknown CLI Error"));
|
|
412
268
|
|
|
413
269
|
process.exit(1);
|
|
414
270
|
}
|
|
415
|
-
});
|
|
271
|
+
});
|