ds-01 1.0.14 → 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.
@@ -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
+ });
@@ -17,83 +17,58 @@ export const init = new Command()
17
17
  const packageJsonPath = path.join(cwd, "package.json");
18
18
  const tsconfigPath = path.join(cwd, "tsconfig.json");
19
19
 
20
- // 1. Check for package.json
20
+ // runs only if package file missing
21
21
  if (!fs.existsSync(packageJsonPath)) {
22
22
  s.stop("Environment check failed.");
23
- cancel("No package.json found. Please run this command in the root of your project.");
23
+ cancel(
24
+ "No package.json found. Please run this command in the root of your project.",
25
+ );
24
26
  process.exit(1);
25
27
  }
26
28
 
27
29
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
28
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
30
+ const deps = {
31
+ ...packageJson.dependencies,
32
+ ...packageJson.devDependencies,
33
+ };
29
34
 
30
- // 2. Check strictly for React or Next.js
35
+ // Check strictly for React or Next.js
31
36
  if (!deps.react && !deps.next) {
32
37
  s.stop("Environment check failed.");
33
- cancel("DS01 strictly supports React and Next.js environments. Please run this in a supported project.");
38
+ cancel(
39
+ "DS01 strictly supports React and Next.js environments. Please run this in a supported project.",
40
+ );
34
41
  process.exit(1);
35
42
  }
36
43
 
37
- // 3. Check strictly for TypeScript
44
+ // Check strictly for TypeScript
38
45
  if (!fs.existsSync(tsconfigPath)) {
39
46
  s.stop("Environment check failed.");
40
- cancel("DS01 requires TypeScript. No tsconfig.json found in the project root.");
47
+ cancel(
48
+ "DS01 requires TypeScript. No tsconfig.json found in the project root.",
49
+ );
41
50
  process.exit(1);
42
51
  }
43
52
 
44
53
  s.stop(chalk.green("✔ React and TypeScript detected!"));
45
54
 
46
- // 4. Ask the user where their global CSS is located
47
- const cssPath = await text({
48
- message: "Where is your global CSS file?",
49
- placeholder: "app/globals.css",
50
- initialValue: "app/globals.css",
51
- });
52
-
53
- if (isCancel(cssPath)) {
54
- cancel("Setup cancelled.");
55
- process.exit(0);
56
- }
57
-
58
- // 5. Inject Dark Mode / Glassmorphic CSS variables
59
- const fullCssPath = path.join(cwd, cssPath as string);
60
- if (fs.existsSync(fullCssPath)) {
61
- const cssContent = fs.readFileSync(fullCssPath, "utf-8");
62
-
63
- if (!cssContent.includes("/* ds01-theme-start */")) {
64
- const variables = `
65
- /* ds01-theme-start */
66
- @layer base {
67
- :root {
68
- --ds-background: #0a0a0a; /* Deep charcoal */
69
- --ds-foreground: #ffffff;
70
- --ds-glass-border: rgba(255, 255, 255, 0.08);
71
- --ds-glass-blur: blur(16px);
72
- }
73
- }
74
- /* ds01-theme-end */
75
- `;
76
- fs.appendFileSync(fullCssPath, variables);
77
- console.log(chalk.green(`✔ Injected design tokens into ${cssPath}`));
78
- } else {
79
- console.log(chalk.gray(`- Design tokens already exist in ${cssPath}`));
80
- }
81
- } else {
82
- console.log(chalk.yellow(`⚠ Could not find ${cssPath}. You may need to add the CSS variables manually.`));
83
- }
55
+ // Create the local configuration file so the CLI remembers this project
56
+ //! Need to be understand
84
57
 
85
- // 6. Create the local configuration file so the CLI remembers this project
86
58
  const configPath = path.join(cwd, "ds01.config.json");
87
59
  const configData = {
88
60
  $schema: "https://ds-01.vercel.app/schema.json",
89
61
  style: "default",
90
62
  typescript: true,
91
- cssPath: cssPath,
92
- componentsPath: "components/ui" // This is where we will inject components later
63
+ componentsPath: "components/ui", // This is where we will inject components later
93
64
  };
94
-
65
+
95
66
  fs.writeFileSync(configPath, JSON.stringify(configData, null, 2));
96
67
  console.log(chalk.green(`✔ Created ds01.config.json`));
97
68
 
98
- outro(chalk.green.bold("DS01 successfully initialized! Ready to add components."));
99
- });
69
+ outro(
70
+ chalk.green.bold(
71
+ "DS01 successfully initialized! Ready to add components.",
72
+ ),
73
+ );
74
+ });