@dsai-io/tools 0.0.1 → 1.0.7
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 +282 -30
- package/dist/cli/index.cjs +6271 -2233
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +4 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +6232 -2195
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.cjs +198 -61
- package/dist/config/index.cjs.map +1 -1
- package/dist/config/index.d.cts +490 -1759
- package/dist/config/index.d.ts +490 -1759
- package/dist/config/index.js +197 -61
- package/dist/config/index.js.map +1 -1
- package/dist/icons/index.cjs +1 -1
- package/dist/icons/index.cjs.map +1 -1
- package/dist/icons/index.d.cts +1 -1
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/index.js +1 -1
- package/dist/icons/index.js.map +1 -1
- package/dist/index.cjs +6733 -2888
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +6774 -2963
- package/dist/index.js.map +1 -1
- package/dist/tokens/index.cjs +4457 -737
- package/dist/tokens/index.cjs.map +1 -1
- package/dist/tokens/index.d.cts +1258 -17
- package/dist/tokens/index.d.ts +1258 -17
- package/dist/tokens/index.js +4368 -683
- package/dist/tokens/index.js.map +1 -1
- package/dist/{types-Idj08nad.d.cts → types-DabOzcsj.d.cts} +236 -3
- package/dist/{types-Idj08nad.d.ts → types-DabOzcsj.d.ts} +236 -3
- package/dist/utils/circuit-breaker.cjs +173 -0
- package/dist/utils/circuit-breaker.cjs.map +1 -0
- package/dist/utils/circuit-breaker.d.cts +123 -0
- package/dist/utils/circuit-breaker.d.ts +123 -0
- package/dist/utils/circuit-breaker.js +169 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -1,19 +1,61 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @dsai-io/tools
|
|
2
2
|
|
|
3
|
-
> Enterprise-grade
|
|
3
|
+
> Enterprise-grade design token tooling with incremental builds, automatic changelog generation, and production-ready error recovery
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@dsai-io/tools)
|
|
6
|
+
[](../../docs/coverage.md)
|
|
7
|
+
[](../../BUILD.md)
|
|
4
8
|
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
7
11
|
```bash
|
|
8
12
|
pnpm add @dsai-io/tools
|
|
13
|
+
|
|
14
|
+
# or
|
|
15
|
+
npm install @dsai-io/tools
|
|
16
|
+
|
|
17
|
+
# or
|
|
18
|
+
yarn add @dsai-io/tools
|
|
9
19
|
```
|
|
10
20
|
|
|
11
21
|
## Features
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
23
|
+
### 🚀 **Incremental Builds**
|
|
24
|
+
|
|
25
|
+
- SHA-256 content hashing for instant change detection
|
|
26
|
+
- Smart decision logic (10-100x faster than full rebuilds)
|
|
27
|
+
- Dependency graph analysis for minimal rebuilds
|
|
28
|
+
- Persistent caching in `.dsai-cache/`
|
|
29
|
+
|
|
30
|
+
### 📝 **Automatic Changelog Generation**
|
|
31
|
+
|
|
32
|
+
- Detects added, removed, modified, and type-changed tokens
|
|
33
|
+
- Breaking change identification and warnings
|
|
34
|
+
- Professional Markdown output with before/after values
|
|
35
|
+
- DTCG and legacy token format support
|
|
36
|
+
|
|
37
|
+
### 🛡️ **Production-Grade Error Recovery**
|
|
38
|
+
|
|
39
|
+
- Circuit breaker pattern prevents cascading failures
|
|
40
|
+
- Rate limiter protects external APIs (Figma)
|
|
41
|
+
- Snapshot service for version rollback
|
|
42
|
+
- Exponential backoff with jitter for retries
|
|
43
|
+
- Health monitoring and metrics
|
|
44
|
+
|
|
45
|
+
### 🎨 **Token Management**
|
|
46
|
+
|
|
47
|
+
- DTCG-compliant token format with legacy support
|
|
48
|
+
- Style Dictionary v5 integration
|
|
49
|
+
- Schema validation (Zod-based)
|
|
50
|
+
- Figma Variables API sync
|
|
51
|
+
- Multi-mode token support
|
|
52
|
+
|
|
53
|
+
### 🔧 **Developer Tools**
|
|
54
|
+
|
|
55
|
+
- Type-safe configuration with `dsai.config.ts`
|
|
56
|
+
- Comprehensive CLI with rich output
|
|
57
|
+
- Programmatic API for automation
|
|
58
|
+
- Icon component generation from SVGs
|
|
17
59
|
|
|
18
60
|
## Quick Start
|
|
19
61
|
|
|
@@ -42,27 +84,72 @@ export default defineConfig({
|
|
|
42
84
|
|
|
43
85
|
### CLI Usage
|
|
44
86
|
|
|
87
|
+
#### Token Building
|
|
88
|
+
|
|
45
89
|
```bash
|
|
46
|
-
#
|
|
47
|
-
npx dsai-tools build
|
|
90
|
+
# Full build
|
|
91
|
+
npx dsai-tools tokens build tokens/
|
|
92
|
+
|
|
93
|
+
# Incremental build (10-100x faster)
|
|
94
|
+
npx dsai-tools tokens build tokens/ --incremental
|
|
48
95
|
|
|
49
|
-
#
|
|
50
|
-
npx dsai-tools build --
|
|
96
|
+
# Force full rebuild
|
|
97
|
+
npx dsai-tools tokens build tokens/ --force
|
|
51
98
|
|
|
52
|
-
#
|
|
99
|
+
# Custom cache directory
|
|
100
|
+
npx dsai-tools tokens build tokens/ --incremental --cache-dir .cache
|
|
101
|
+
|
|
102
|
+
# Clean outputs before build
|
|
53
103
|
npx dsai-tools tokens build --clean
|
|
104
|
+
```
|
|
54
105
|
|
|
55
|
-
|
|
56
|
-
npx dsai-tools build --icons
|
|
106
|
+
#### Changelog Generation
|
|
57
107
|
|
|
58
|
-
|
|
59
|
-
|
|
108
|
+
```bash
|
|
109
|
+
# Generate changelog from token changes
|
|
110
|
+
npx dsai-tools tokens changelog old-tokens.json new-tokens.json
|
|
60
111
|
|
|
61
|
-
#
|
|
112
|
+
# With version number
|
|
113
|
+
npx dsai-tools tokens changelog old.json new.json --version 1.2.0
|
|
114
|
+
|
|
115
|
+
# Custom output file
|
|
116
|
+
npx dsai-tools tokens changelog old.json new.json --output CHANGES.md
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Token Validation & Transformation
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Validate tokens against DTCG spec
|
|
123
|
+
npx dsai-tools tokens validate tokens/**/*.json
|
|
124
|
+
|
|
125
|
+
# Transform Figma exports to Style Dictionary format
|
|
62
126
|
npx dsai-tools tokens transform
|
|
63
127
|
|
|
64
|
-
# Sync tokens flat file
|
|
128
|
+
# Sync tokens to flat TypeScript file
|
|
65
129
|
npx dsai-tools tokens sync
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Figma Integration
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Sync from Figma Variables API
|
|
136
|
+
npx dsai-tools tokens sync --figma-file YOUR_FILE_ID
|
|
137
|
+
|
|
138
|
+
# Validate Figma export
|
|
139
|
+
npx dsai-tools tokens validate-figma export.json
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Utilities
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Clean output directories
|
|
146
|
+
npx dsai-tools tokens clean
|
|
147
|
+
|
|
148
|
+
# Post-process CSS theme files
|
|
149
|
+
npx dsai-tools tokens postprocess
|
|
150
|
+
|
|
151
|
+
# Generate icons from SVGs
|
|
152
|
+
npx dsai-tools build --icons
|
|
66
153
|
|
|
67
154
|
# Initialize configuration
|
|
68
155
|
npx dsai-tools init
|
|
@@ -70,8 +157,92 @@ npx dsai-tools init
|
|
|
70
157
|
|
|
71
158
|
### Programmatic Usage
|
|
72
159
|
|
|
160
|
+
#### Incremental Builds
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { buildTokens, CacheService } from '@dsai-io/tools/tokens';
|
|
164
|
+
|
|
165
|
+
// Incremental build with caching
|
|
166
|
+
const result = await buildTokens('tokens/', {
|
|
167
|
+
incremental: true,
|
|
168
|
+
cacheDir: '.dsai-cache',
|
|
169
|
+
force: false,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
console.log(`Built ${result.tokenCount} tokens`);
|
|
173
|
+
console.log(`Build time: ${result.duration}ms`);
|
|
174
|
+
console.log(`Cache hit rate: ${result.cacheStats?.hitRate}%`);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Changelog Generation
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { diffTokens, generateChangelog, writeChangelog } from '@dsai-io/tools/tokens';
|
|
181
|
+
|
|
182
|
+
// Load tokens
|
|
183
|
+
const oldTokens = JSON.parse(fs.readFileSync('old.json', 'utf-8'));
|
|
184
|
+
const newTokens = JSON.parse(fs.readFileSync('new.json', 'utf-8'));
|
|
185
|
+
|
|
186
|
+
// Compute diff
|
|
187
|
+
const diff = diffTokens(oldTokens, newTokens);
|
|
188
|
+
|
|
189
|
+
if (diff.hasBreaking) {
|
|
190
|
+
console.warn('⚠️ Breaking changes detected!');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Generate and write changelog
|
|
194
|
+
const result = generateChangelog(diff, {
|
|
195
|
+
version: '1.2.0',
|
|
196
|
+
includeDescriptions: true,
|
|
197
|
+
includeValues: true,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
await writeChangelog(result.content, 'TOKENS-CHANGELOG.md');
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### Error Recovery
|
|
204
|
+
|
|
73
205
|
```typescript
|
|
74
|
-
import {
|
|
206
|
+
import {
|
|
207
|
+
CircuitBreaker,
|
|
208
|
+
RateLimiter,
|
|
209
|
+
SnapshotService
|
|
210
|
+
} from '@dsai-io/tools/tokens';
|
|
211
|
+
|
|
212
|
+
// Circuit breaker for external APIs
|
|
213
|
+
const breaker = new CircuitBreaker({
|
|
214
|
+
threshold: 5,
|
|
215
|
+
timeout: 30000,
|
|
216
|
+
resetTimeout: 60000,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const data = await breaker.execute(async () => {
|
|
220
|
+
return await fetchFromFigmaAPI();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Rate limiter for API protection
|
|
224
|
+
const limiter = new RateLimiter({
|
|
225
|
+
maxRequests: 10,
|
|
226
|
+
windowMs: 60000,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
await limiter.acquire();
|
|
230
|
+
|
|
231
|
+
// Snapshot for rollback
|
|
232
|
+
const snapshotService = new SnapshotService('.snapshots');
|
|
233
|
+
const snapshot = await snapshotService.createSnapshot(
|
|
234
|
+
'tokens/',
|
|
235
|
+
'Before v2.0.0 migration'
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// Restore if needed
|
|
239
|
+
await snapshotService.restoreSnapshot(snapshot.id, 'tokens/');
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### Configuration & Build
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { loadConfig, buildTokens, generateIcons } from '@dsai-io/tools';
|
|
75
246
|
|
|
76
247
|
// Load configuration
|
|
77
248
|
const config = await loadConfig();
|
|
@@ -93,27 +264,108 @@ console.log('Generated:', iconResult.files);
|
|
|
93
264
|
- `loadConfig(searchFrom?)` - Load configuration from filesystem
|
|
94
265
|
- `validateConfig(config)` - Validate configuration against schema
|
|
95
266
|
|
|
96
|
-
### Token
|
|
97
|
-
|
|
98
|
-
- `
|
|
99
|
-
- `
|
|
100
|
-
- `
|
|
101
|
-
|
|
102
|
-
|
|
267
|
+
### Token Building
|
|
268
|
+
|
|
269
|
+
- `buildTokens(tokensDir, options)` - Build tokens with optional incremental mode
|
|
270
|
+
- `buildTokensCLI(args)` - CLI wrapper for token builds
|
|
271
|
+
- `runBuildCLI(args)` - Execute build from command line
|
|
272
|
+
|
|
273
|
+
**Options:**
|
|
274
|
+
|
|
275
|
+
- `incremental: boolean` - Enable incremental builds
|
|
276
|
+
- `force: boolean` - Force full rebuild
|
|
277
|
+
- `cacheDir: string` - Custom cache directory
|
|
278
|
+
- `clean: boolean` - Clean outputs before build
|
|
279
|
+
|
|
280
|
+
### Incremental Build System
|
|
281
|
+
|
|
282
|
+
- `CacheService` - SHA-256 content hashing and cache management
|
|
283
|
+
- `hashFile(filePath)` - Generate content hash
|
|
284
|
+
- `hasFileChanged(filePath, baseDir)` - Check if file changed
|
|
285
|
+
- `getChangedFiles(directory, pattern)` - Get all changed files
|
|
286
|
+
- `updateCacheEntry(filePath, baseDir)` - Update cache
|
|
287
|
+
- `getCacheStats()` - Get cache metrics
|
|
288
|
+
|
|
289
|
+
- `analyzeChanges(options)` - Analyze token changes
|
|
290
|
+
- `buildDependencyGraph(collections)` - Build dependency graph
|
|
291
|
+
- `getAffectedCollections(changed, graph)` - Get affected collections
|
|
292
|
+
- `generateIncrementalReport(result)` - Generate build report
|
|
293
|
+
|
|
294
|
+
### Changelog Generation
|
|
295
|
+
|
|
296
|
+
- `diffTokens(oldTokens, newTokens)` - Compare token collections
|
|
297
|
+
- `generateChangelog(diff, options)` - Generate Markdown changelog
|
|
298
|
+
- `writeChangelog(content, filePath)` - Write changelog to file
|
|
299
|
+
- `generateAndWriteChangelog(diff, filePath, options)` - Combined operation
|
|
300
|
+
- `generateChangelogCLI(oldPath, newPath, output, version)` - CLI wrapper
|
|
301
|
+
|
|
302
|
+
**Diff Result:**
|
|
303
|
+
|
|
304
|
+
- `added: TokenChange[]` - Added tokens
|
|
305
|
+
- `removed: TokenChange[]` - Removed tokens (breaking)
|
|
306
|
+
- `modified: TokenChange[]` - Modified tokens
|
|
307
|
+
- `typeChanged: TokenChange[]` - Type-changed tokens (breaking)
|
|
308
|
+
- `deprecated: TokenChange[]` - Deprecated tokens
|
|
309
|
+
- `totalChanges: number` - Total count
|
|
310
|
+
- `hasBreaking: boolean` - Breaking change flag
|
|
311
|
+
|
|
312
|
+
**Helper Functions:**
|
|
313
|
+
|
|
314
|
+
- `summarizeDiff(diff)` - Text summary of changes
|
|
315
|
+
- `filterDiff(diff, types)` - Filter by change types
|
|
316
|
+
- `getBreakingChanges(diff)` - Get only breaking changes
|
|
317
|
+
|
|
318
|
+
### Error Recovery
|
|
319
|
+
|
|
320
|
+
- `CircuitBreaker` - Prevent cascading failures
|
|
321
|
+
- `execute(fn)` - Execute with circuit breaker protection
|
|
322
|
+
- `getState()` - Get current state (CLOSED, OPEN, HALF_OPEN)
|
|
323
|
+
- `getMetrics()` - Get failure/success metrics
|
|
324
|
+
- `reset()` - Manually reset circuit
|
|
325
|
+
|
|
326
|
+
- `RateLimiter` - API rate limiting
|
|
327
|
+
- `acquire()` - Acquire rate limit slot
|
|
328
|
+
- `getMetrics()` - Get request metrics
|
|
329
|
+
- `reset()` - Reset rate limiter
|
|
330
|
+
|
|
331
|
+
- `SnapshotService` - Version snapshots for rollback
|
|
332
|
+
- `createSnapshot(dir, description)` - Create snapshot
|
|
333
|
+
- `listSnapshots()` - List all snapshots
|
|
334
|
+
- `getSnapshot(id)` - Get snapshot by ID
|
|
335
|
+
- `restoreSnapshot(id, targetDir)` - Restore snapshot
|
|
336
|
+
- `deleteSnapshot(id)` - Delete snapshot
|
|
337
|
+
- `cleanup(keepCount)` - Clean old snapshots
|
|
338
|
+
|
|
339
|
+
### Token Validation & Transformation
|
|
340
|
+
|
|
341
|
+
- `validateTokens(config, options)` - Validate against DTCG spec
|
|
342
|
+
- `validateFigmaExports(data)` - Validate Figma exports
|
|
343
|
+
- `transformTokens(options)` - Transform Figma to Style Dictionary
|
|
344
|
+
- `syncTokens(options)` - Sync to flat TypeScript file
|
|
345
|
+
- `cleanTokenOutputs(options)` - Clean output directories
|
|
103
346
|
- `postprocessCss(options)` - Post-process CSS theme files
|
|
104
347
|
|
|
348
|
+
### Schema Validation
|
|
349
|
+
|
|
350
|
+
- `validateDTCGFile(data)` - Validate DTCG file structure
|
|
351
|
+
- `validateDTCGTokens(tokens)` - Validate token collection
|
|
352
|
+
- `validateFigmaExport(data)` - Validate Figma export
|
|
353
|
+
- `validateStyleDictionaryInput(data)` - Validate SD input
|
|
354
|
+
|
|
105
355
|
### Icon Tools
|
|
106
356
|
|
|
107
357
|
- `generateIcons(config)` - Generate icon components from SVGs
|
|
108
358
|
- `optimizeSvg(source, options)` - Optimize SVG files
|
|
109
359
|
- `extractIconMetadata(svgPath)` - Extract metadata from SVG
|
|
110
360
|
|
|
111
|
-
### Utilities
|
|
361
|
+
### Type Guards & Utilities
|
|
112
362
|
|
|
113
|
-
- `
|
|
114
|
-
- `
|
|
115
|
-
- `
|
|
116
|
-
- `
|
|
363
|
+
- `isDTCGToken(obj)` - Check if DTCG format
|
|
364
|
+
- `isLegacyToken(obj)` - Check if legacy format
|
|
365
|
+
- `isToken(obj)` - Check if any token format
|
|
366
|
+
- `getTokenValue(token)` - Get value from any format
|
|
367
|
+
- `getTokenType(token)` - Get type from any format
|
|
368
|
+
- `toDTCGToken(legacy)` - Convert legacy to DTCG
|
|
117
369
|
|
|
118
370
|
## Configuration Options
|
|
119
371
|
|