@catchdrift/cli 0.1.5 → 0.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catchdrift/cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "CLI for Drift — install, check, and manage design system coverage for any React app.",
5
5
  "keywords": [
6
6
  "design-system",
@@ -103,7 +103,7 @@ export async function init(argv) {
103
103
  const sources = Array.isArray(dsSources) ? dsSources : []
104
104
 
105
105
  // ── Step 3a: Figma ───────────────────────────────────────────────────────────
106
- let figmaFileKey, figmaWIPPage
106
+ let figmaFileKey, figmaToken, figmaWIPPages
107
107
  if (sources.includes('figma')) {
108
108
  figmaFileKey = await p.text({
109
109
  message: 'Figma file key',
@@ -113,13 +113,30 @@ export async function init(argv) {
113
113
  if (p.isCancel(figmaFileKey)) { p.cancel('Setup cancelled.'); process.exit(EXIT_CANCELED) }
114
114
  figmaFileKey = figmaFileKey?.trim() || undefined
115
115
 
116
- figmaWIPPage = await p.text({
117
- message: 'Which Figma page holds in-progress / not-yet-ready components?',
118
- placeholder: '🚧 In Progress (skip if you don\'t have one)',
119
- hint: 'Components on this page will be flagged as drafts, not added to your registry',
116
+ figmaToken = await p.text({
117
+ message: 'Figma personal access token',
118
+ placeholder: 'figd_... (figma.com Profile Settings → Security → Personal access tokens)',
119
+ hint: 'Used to fetch your real page list. Store in FIGMA_API_TOKEN env var — not committed to git.',
120
120
  })
121
- if (p.isCancel(figmaWIPPage)) { p.cancel('Setup cancelled.'); process.exit(EXIT_CANCELED) }
122
- figmaWIPPage = figmaWIPPage?.trim() || undefined
121
+ if (p.isCancel(figmaToken)) { p.cancel('Setup cancelled.'); process.exit(EXIT_CANCELED) }
122
+ figmaToken = figmaToken?.trim() || undefined
123
+
124
+ // Fetch actual pages from Figma so the user picks from real names
125
+ if (figmaToken && figmaFileKey) {
126
+ spinner.start('Fetching pages from Figma...')
127
+ const pages = await fetchFigmaPages(figmaFileKey, figmaToken)
128
+ spinner.stop(pages ? `Found ${pages.length} pages` : 'Could not reach Figma — skipping page selection')
129
+
130
+ if (pages?.length) {
131
+ const selected = await p.multiselect({
132
+ message: 'Which pages hold in-progress / not-yet-ready components? (drafts — won\'t be added to registry)',
133
+ options: pages.map(name => ({ value: name, label: name })),
134
+ required: false,
135
+ })
136
+ if (p.isCancel(selected)) { p.cancel('Setup cancelled.'); process.exit(EXIT_CANCELED) }
137
+ figmaWIPPages = Array.isArray(selected) && selected.length ? selected : undefined
138
+ }
139
+ }
123
140
  }
124
141
 
125
142
  // ── Step 3b: Storybook ───────────────────────────────────────────────────────
@@ -202,7 +219,7 @@ export async function init(argv) {
202
219
  storybookUrl: storybookUrl || (storybook.found ? storybook.url : undefined),
203
220
  chromaticUrl,
204
221
  figmaFileKey,
205
- figmaWIPPage,
222
+ figmaWIPPages,
206
223
  dsPackages,
207
224
  threshold: Number(threshold) || 80,
208
225
  components,
@@ -292,3 +309,18 @@ ${pc.dim('Docs: https://catchdrift.ai · Issues: https://github.com/dyoon92/de
292
309
  console.log('')
293
310
  }
294
311
  }
312
+
313
+ // ── Helpers ───────────────────────────────────────────────────────────────────
314
+
315
+ async function fetchFigmaPages(fileKey, token) {
316
+ try {
317
+ const res = await fetch(`https://api.figma.com/v1/files/${fileKey}?depth=1`, {
318
+ headers: { 'X-Figma-Token': token },
319
+ })
320
+ if (!res.ok) return null
321
+ const data = await res.json()
322
+ return data.document?.children?.map(page => page.name) ?? null
323
+ } catch {
324
+ return null
325
+ }
326
+ }
@@ -10,7 +10,7 @@ import { findAppEntry } from './detect.mjs'
10
10
 
11
11
  // ── drift.config.ts ───────────────────────────────────────────────────────────
12
12
 
13
- export function writeDriftConfig(cwd, { storybookUrl, chromaticUrl, figmaFileKey, figmaWIPPage, dsPackages, threshold, components }) {
13
+ export function writeDriftConfig(cwd, { storybookUrl, chromaticUrl, figmaFileKey, figmaWIPPages, dsPackages, threshold, components }) {
14
14
  const registry = buildComponentRegistry(components)
15
15
 
16
16
  const dsPackagesLine = dsPackages?.length
@@ -24,7 +24,7 @@ export function writeDriftConfig(cwd, { storybookUrl, chromaticUrl, figmaFileKey
24
24
  storybookUrl ? ` storybookUrl: '${storybookUrl}',` : null,
25
25
  chromaticUrl ? ` chromaticUrl: '${chromaticUrl}',` : null,
26
26
  figmaFileKey ? ` figmaFileKey: '${figmaFileKey}',` : null,
27
- figmaWIPPage ? ` figmaWIPPage: '${figmaWIPPage}', // components on this page are drafts — not added to registry` : null,
27
+ figmaWIPPages?.length ? ` figmaWIPPages: [${figmaWIPPages.map(p => `'${p}'`).join(', ')}], // components on these pages are drafts — not added to registry` : null,
28
28
  ` threshold: ${threshold},`,
29
29
  dsPackagesLine,
30
30
  ` components: {`,