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.
@@ -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":"AA2WA;;;;GAIG;AAEH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CASrD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ1D;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,UAAU,CAAC,CAQrB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CASrD"}
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 !== "EXISTS") {
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.0.13",
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.");
@@ -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
- dependencies: string[],
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
- await response.json().catch(() => null);
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
- // 8. Extract bundled file names
258
- // --------------------------------------------------
259
-
260
- const bundledFileNames =
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
- (fileName: string) => {
283
- const regex = new RegExp(
284
- `from\\s+["']\\.[^"']*?\\/${fileName}["']`,
285
- "g",
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
- fs.writeFileSync(
296
- filePath,
297
- content,
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
- // 10. Install ONLY missing dependencies
311
- // --------------------------------------------------
213
+
214
+ // Install ONLY missing dependencies
215
+ const registryDependencies = Array.isArray(componentData.dependencies)
216
+ ? componentData.dependencies
217
+ : [];
312
218
 
313
- const registryDependencies =
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
- `npm install ${depsToInstall}`,
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
+ });