@dsai-io/tools 0.0.1 → 1.1.0

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.
Files changed (44) hide show
  1. package/README.md +438 -186
  2. package/bin/dsai-tools.mjs +13 -13
  3. package/dist/cli/index.cjs +8192 -2757
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.d.cts +4 -0
  6. package/dist/cli/index.d.ts +4 -0
  7. package/dist/cli/index.js +8190 -2757
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/config/index.cjs +264 -63
  10. package/dist/config/index.cjs.map +1 -1
  11. package/dist/config/index.d.cts +537 -1759
  12. package/dist/config/index.d.ts +537 -1759
  13. package/dist/config/index.js +259 -63
  14. package/dist/config/index.js.map +1 -1
  15. package/dist/icons/index.cjs +1 -1
  16. package/dist/icons/index.cjs.map +1 -1
  17. package/dist/icons/index.d.cts +1 -1
  18. package/dist/icons/index.d.ts +1 -1
  19. package/dist/icons/index.js +1 -1
  20. package/dist/icons/index.js.map +1 -1
  21. package/dist/index.cjs +8093 -3024
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +214 -5
  24. package/dist/index.d.ts +214 -5
  25. package/dist/index.js +8033 -3012
  26. package/dist/index.js.map +1 -1
  27. package/dist/tokens/index.cjs +4457 -737
  28. package/dist/tokens/index.cjs.map +1 -1
  29. package/dist/tokens/index.d.cts +1258 -17
  30. package/dist/tokens/index.d.ts +1258 -17
  31. package/dist/tokens/index.js +4368 -683
  32. package/dist/tokens/index.js.map +1 -1
  33. package/dist/{types-Idj08nad.d.cts → types-CtE9f0G0.d.cts} +293 -3
  34. package/dist/{types-Idj08nad.d.ts → types-CtE9f0G0.d.ts} +293 -3
  35. package/dist/utils/circuit-breaker.cjs +173 -0
  36. package/dist/utils/circuit-breaker.cjs.map +1 -0
  37. package/dist/utils/circuit-breaker.d.cts +123 -0
  38. package/dist/utils/circuit-breaker.d.ts +123 -0
  39. package/dist/utils/circuit-breaker.js +169 -0
  40. package/dist/utils/circuit-breaker.js.map +1 -0
  41. package/package.json +102 -97
  42. package/templates/.dsairc.json +37 -37
  43. package/templates/dsai-config.schema.json +618 -554
  44. package/templates/dsai.config.mjs +281 -221
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @fileoverview Circuit Breaker pattern implementation
3
+ * Prevents cascade failures by tracking error rates and temporarily blocking requests
4
+ */
5
+ /**
6
+ * Circuit breaker states
7
+ */
8
+ declare enum CircuitState {
9
+ /** Normal operation - requests are allowed */
10
+ CLOSED = "CLOSED",
11
+ /** Failing - all requests are rejected immediately */
12
+ OPEN = "OPEN",
13
+ /** Testing recovery - limited requests are allowed */
14
+ HALF_OPEN = "HALF_OPEN"
15
+ }
16
+ /**
17
+ * Circuit breaker configuration
18
+ */
19
+ interface CircuitBreakerConfig {
20
+ /** Number of failures before opening circuit */
21
+ failureThreshold?: number;
22
+ /** Time in ms before attempting to close circuit */
23
+ cooldownMs?: number;
24
+ /** Request timeout in ms */
25
+ timeout?: number;
26
+ /** Name for logging */
27
+ name?: string;
28
+ }
29
+ /**
30
+ * Circuit breaker statistics
31
+ */
32
+ interface CircuitBreakerStats {
33
+ /** Current state */
34
+ state: CircuitState;
35
+ /** Total failures */
36
+ failures: number;
37
+ /** Total successes */
38
+ successes: number;
39
+ /** Total calls */
40
+ totalCalls: number;
41
+ /** Time circuit opened (if open) */
42
+ openedAt?: Date;
43
+ /** Time circuit will attempt to close */
44
+ resetAt?: Date;
45
+ /** Last error */
46
+ lastError?: string;
47
+ }
48
+ /**
49
+ * Circuit breaker error thrown when circuit is open
50
+ */
51
+ declare class CircuitBreakerOpenError extends Error {
52
+ readonly circuitName: string;
53
+ readonly resetAt: Date;
54
+ constructor(circuitName: string, resetAt: Date);
55
+ }
56
+ /**
57
+ * Circuit breaker implementation
58
+ * Tracks failures and opens circuit to prevent cascade failures
59
+ */
60
+ declare class CircuitBreaker {
61
+ private state;
62
+ private failures;
63
+ private successes;
64
+ private totalCalls;
65
+ private openedAt?;
66
+ private resetAt?;
67
+ private lastError?;
68
+ private readonly failureThreshold;
69
+ private readonly cooldownMs;
70
+ private readonly timeout;
71
+ private readonly name;
72
+ constructor(config?: CircuitBreakerConfig);
73
+ /**
74
+ * Execute a function with circuit breaker protection
75
+ */
76
+ execute<T>(fn: () => Promise<T>): Promise<T>;
77
+ /**
78
+ * Execute function with timeout
79
+ */
80
+ private executeWithTimeout;
81
+ /**
82
+ * Handle successful execution
83
+ */
84
+ private onSuccess;
85
+ /**
86
+ * Handle failed execution
87
+ */
88
+ private onFailure;
89
+ /**
90
+ * Open the circuit
91
+ */
92
+ private openCircuit;
93
+ /**
94
+ * Check if circuit can attempt reset
95
+ */
96
+ private canAttemptReset;
97
+ /**
98
+ * Get current circuit breaker state
99
+ */
100
+ getState(): CircuitState;
101
+ /**
102
+ * Get circuit breaker statistics
103
+ */
104
+ getStats(): CircuitBreakerStats;
105
+ /**
106
+ * Manually reset circuit breaker
107
+ */
108
+ reset(): void;
109
+ /**
110
+ * Check if circuit is open
111
+ */
112
+ isOpen(): boolean;
113
+ /**
114
+ * Check if circuit is closed
115
+ */
116
+ isClosed(): boolean;
117
+ /**
118
+ * Check if circuit is half-open
119
+ */
120
+ isHalfOpen(): boolean;
121
+ }
122
+
123
+ export { CircuitBreaker, type CircuitBreakerConfig, CircuitBreakerOpenError, type CircuitBreakerStats, CircuitState };
@@ -0,0 +1,169 @@
1
+ /* @dsai-io/tools - DSAi Design System Build Tools */
2
+
3
+ // src/utils/circuit-breaker.ts
4
+ var CircuitState = /* @__PURE__ */ ((CircuitState2) => {
5
+ CircuitState2["CLOSED"] = "CLOSED";
6
+ CircuitState2["OPEN"] = "OPEN";
7
+ CircuitState2["HALF_OPEN"] = "HALF_OPEN";
8
+ return CircuitState2;
9
+ })(CircuitState || {});
10
+ var CircuitBreakerOpenError = class extends Error {
11
+ constructor(circuitName, resetAt) {
12
+ super(`Circuit breaker "${circuitName}" is open. Will retry at ${resetAt.toISOString()}`);
13
+ this.circuitName = circuitName;
14
+ this.resetAt = resetAt;
15
+ this.name = "CircuitBreakerOpenError";
16
+ }
17
+ };
18
+ var CircuitBreaker = class {
19
+ state = "CLOSED" /* CLOSED */;
20
+ failures = 0;
21
+ successes = 0;
22
+ totalCalls = 0;
23
+ openedAt;
24
+ resetAt;
25
+ lastError;
26
+ failureThreshold;
27
+ cooldownMs;
28
+ timeout;
29
+ name;
30
+ constructor(config = {}) {
31
+ this.failureThreshold = config.failureThreshold ?? 5;
32
+ this.cooldownMs = config.cooldownMs ?? 3e4;
33
+ this.timeout = config.timeout ?? 1e4;
34
+ this.name = config.name ?? "CircuitBreaker";
35
+ }
36
+ /**
37
+ * Execute a function with circuit breaker protection
38
+ */
39
+ async execute(fn) {
40
+ this.totalCalls++;
41
+ if (this.state === "OPEN" /* OPEN */ && this.canAttemptReset()) {
42
+ this.state = "HALF_OPEN" /* HALF_OPEN */;
43
+ this.failures = 0;
44
+ }
45
+ if (this.state === "OPEN" /* OPEN */) {
46
+ if (!this.resetAt) {
47
+ throw new Error(`Circuit breaker "${this.name}" is open but has no reset time`);
48
+ }
49
+ throw new CircuitBreakerOpenError(this.name, this.resetAt);
50
+ }
51
+ try {
52
+ const result = await this.executeWithTimeout(fn);
53
+ this.onSuccess();
54
+ return result;
55
+ } catch (error) {
56
+ this.onFailure(error);
57
+ throw error;
58
+ }
59
+ }
60
+ /**
61
+ * Execute function with timeout
62
+ */
63
+ async executeWithTimeout(fn) {
64
+ return Promise.race([
65
+ fn(),
66
+ new Promise((_, reject) => {
67
+ setTimeout(() => {
68
+ reject(new Error(`Circuit breaker timeout after ${this.timeout}ms`));
69
+ }, this.timeout);
70
+ })
71
+ ]);
72
+ }
73
+ /**
74
+ * Handle successful execution
75
+ */
76
+ onSuccess() {
77
+ this.successes++;
78
+ if (this.state === "HALF_OPEN" /* HALF_OPEN */) {
79
+ this.state = "CLOSED" /* CLOSED */;
80
+ this.failures = 0;
81
+ this.openedAt = void 0;
82
+ this.resetAt = void 0;
83
+ this.lastError = void 0;
84
+ }
85
+ }
86
+ /**
87
+ * Handle failed execution
88
+ */
89
+ onFailure(error) {
90
+ this.failures++;
91
+ this.lastError = error instanceof Error ? error.message : String(error);
92
+ if (this.state === "HALF_OPEN" /* HALF_OPEN */) {
93
+ this.openCircuit();
94
+ } else if (this.failures >= this.failureThreshold) {
95
+ this.openCircuit();
96
+ }
97
+ }
98
+ /**
99
+ * Open the circuit
100
+ */
101
+ openCircuit() {
102
+ this.state = "OPEN" /* OPEN */;
103
+ this.openedAt = /* @__PURE__ */ new Date();
104
+ this.resetAt = new Date(Date.now() + this.cooldownMs);
105
+ }
106
+ /**
107
+ * Check if circuit can attempt reset
108
+ */
109
+ canAttemptReset() {
110
+ if (!this.resetAt) {
111
+ return false;
112
+ }
113
+ return Date.now() >= this.resetAt.getTime();
114
+ }
115
+ /**
116
+ * Get current circuit breaker state
117
+ */
118
+ getState() {
119
+ return this.state;
120
+ }
121
+ /**
122
+ * Get circuit breaker statistics
123
+ */
124
+ getStats() {
125
+ return {
126
+ state: this.state,
127
+ failures: this.failures,
128
+ successes: this.successes,
129
+ totalCalls: this.totalCalls,
130
+ openedAt: this.openedAt,
131
+ resetAt: this.resetAt,
132
+ lastError: this.lastError
133
+ };
134
+ }
135
+ /**
136
+ * Manually reset circuit breaker
137
+ */
138
+ reset() {
139
+ this.state = "CLOSED" /* CLOSED */;
140
+ this.failures = 0;
141
+ this.successes = 0;
142
+ this.totalCalls = 0;
143
+ this.openedAt = void 0;
144
+ this.resetAt = void 0;
145
+ this.lastError = void 0;
146
+ }
147
+ /**
148
+ * Check if circuit is open
149
+ */
150
+ isOpen() {
151
+ return this.state === "OPEN" /* OPEN */;
152
+ }
153
+ /**
154
+ * Check if circuit is closed
155
+ */
156
+ isClosed() {
157
+ return this.state === "CLOSED" /* CLOSED */;
158
+ }
159
+ /**
160
+ * Check if circuit is half-open
161
+ */
162
+ isHalfOpen() {
163
+ return this.state === "HALF_OPEN" /* HALF_OPEN */;
164
+ }
165
+ };
166
+
167
+ export { CircuitBreaker, CircuitBreakerOpenError, CircuitState };
168
+ //# sourceMappingURL=circuit-breaker.js.map
169
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/circuit-breaker.ts"],"names":["CircuitState"],"mappings":"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","file":"circuit-breaker.js","sourcesContent":["/**\r\n * @fileoverview Circuit Breaker pattern implementation\r\n * Prevents cascade failures by tracking error rates and temporarily blocking requests\r\n */\r\n\r\n/**\r\n * Circuit breaker states\r\n */\r\nexport enum CircuitState {\r\n /** Normal operation - requests are allowed */\r\n CLOSED = 'CLOSED',\r\n /** Failing - all requests are rejected immediately */\r\n OPEN = 'OPEN',\r\n /** Testing recovery - limited requests are allowed */\r\n HALF_OPEN = 'HALF_OPEN',\r\n}\r\n\r\n/**\r\n * Circuit breaker configuration\r\n */\r\nexport interface CircuitBreakerConfig {\r\n /** Number of failures before opening circuit */\r\n failureThreshold?: number;\r\n /** Time in ms before attempting to close circuit */\r\n cooldownMs?: number;\r\n /** Request timeout in ms */\r\n timeout?: number;\r\n /** Name for logging */\r\n name?: string;\r\n}\r\n\r\n/**\r\n * Circuit breaker statistics\r\n */\r\nexport interface CircuitBreakerStats {\r\n /** Current state */\r\n state: CircuitState;\r\n /** Total failures */\r\n failures: number;\r\n /** Total successes */\r\n successes: number;\r\n /** Total calls */\r\n totalCalls: number;\r\n /** Time circuit opened (if open) */\r\n openedAt?: Date;\r\n /** Time circuit will attempt to close */\r\n resetAt?: Date;\r\n /** Last error */\r\n lastError?: string;\r\n}\r\n\r\n/**\r\n * Circuit breaker error thrown when circuit is open\r\n */\r\nexport class CircuitBreakerOpenError extends Error {\r\n constructor(\r\n public readonly circuitName: string,\r\n public readonly resetAt: Date\r\n ) {\r\n super(`Circuit breaker \"${circuitName}\" is open. Will retry at ${resetAt.toISOString()}`);\r\n this.name = 'CircuitBreakerOpenError';\r\n }\r\n}\r\n\r\n/**\r\n * Circuit breaker implementation\r\n * Tracks failures and opens circuit to prevent cascade failures\r\n */\r\nexport class CircuitBreaker {\r\n private state: CircuitState = CircuitState.CLOSED;\r\n private failures = 0;\r\n private successes = 0;\r\n private totalCalls = 0;\r\n private openedAt?: Date;\r\n private resetAt?: Date;\r\n private lastError?: string;\r\n\r\n private readonly failureThreshold: number;\r\n private readonly cooldownMs: number;\r\n private readonly timeout: number;\r\n private readonly name: string;\r\n\r\n constructor(config: CircuitBreakerConfig = {}) {\r\n this.failureThreshold = config.failureThreshold ?? 5;\r\n this.cooldownMs = config.cooldownMs ?? 30000; // 30 seconds\r\n this.timeout = config.timeout ?? 10000; // 10 seconds\r\n this.name = config.name ?? 'CircuitBreaker';\r\n }\r\n\r\n /**\r\n * Execute a function with circuit breaker protection\r\n */\r\n async execute<T>(fn: () => Promise<T>): Promise<T> {\r\n this.totalCalls++;\r\n\r\n // Check if circuit should transition from OPEN to HALF_OPEN\r\n if (this.state === CircuitState.OPEN && this.canAttemptReset()) {\r\n this.state = CircuitState.HALF_OPEN;\r\n this.failures = 0; // Reset failure count for half-open state\r\n }\r\n\r\n // Reject immediately if circuit is open\r\n if (this.state === CircuitState.OPEN) {\r\n if (!this.resetAt) {\r\n throw new Error(`Circuit breaker \"${this.name}\" is open but has no reset time`);\r\n }\r\n throw new CircuitBreakerOpenError(this.name, this.resetAt);\r\n }\r\n\r\n try {\r\n // Execute with timeout\r\n const result = await this.executeWithTimeout(fn);\r\n\r\n // Record success\r\n this.onSuccess();\r\n\r\n return result;\r\n } catch (error) {\r\n // Record failure\r\n this.onFailure(error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute function with timeout\r\n */\r\n private async executeWithTimeout<T>(fn: () => Promise<T>): Promise<T> {\r\n return Promise.race([\r\n fn(),\r\n new Promise<T>((_, reject) => {\r\n setTimeout(() => {\r\n reject(new Error(`Circuit breaker timeout after ${this.timeout}ms`));\r\n }, this.timeout);\r\n }),\r\n ]);\r\n }\r\n\r\n /**\r\n * Handle successful execution\r\n */\r\n private onSuccess(): void {\r\n this.successes++;\r\n\r\n if (this.state === CircuitState.HALF_OPEN) {\r\n // Successful call in HALF_OPEN state closes the circuit\r\n this.state = CircuitState.CLOSED;\r\n this.failures = 0;\r\n this.openedAt = undefined;\r\n this.resetAt = undefined;\r\n this.lastError = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Handle failed execution\r\n */\r\n private onFailure(error: unknown): void {\r\n this.failures++;\r\n this.lastError = error instanceof Error ? error.message : String(error);\r\n\r\n if (this.state === CircuitState.HALF_OPEN) {\r\n // Failure in HALF_OPEN state immediately reopens circuit\r\n this.openCircuit();\r\n } else if (this.failures >= this.failureThreshold) {\r\n // Threshold reached, open circuit\r\n this.openCircuit();\r\n }\r\n }\r\n\r\n /**\r\n * Open the circuit\r\n */\r\n private openCircuit(): void {\r\n this.state = CircuitState.OPEN;\r\n this.openedAt = new Date();\r\n this.resetAt = new Date(Date.now() + this.cooldownMs);\r\n }\r\n\r\n /**\r\n * Check if circuit can attempt reset\r\n */\r\n private canAttemptReset(): boolean {\r\n if (!this.resetAt) {\r\n return false;\r\n }\r\n return Date.now() >= this.resetAt.getTime();\r\n }\r\n\r\n /**\r\n * Get current circuit breaker state\r\n */\r\n getState(): CircuitState {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * Get circuit breaker statistics\r\n */\r\n getStats(): CircuitBreakerStats {\r\n return {\r\n state: this.state,\r\n failures: this.failures,\r\n successes: this.successes,\r\n totalCalls: this.totalCalls,\r\n openedAt: this.openedAt,\r\n resetAt: this.resetAt,\r\n lastError: this.lastError,\r\n };\r\n }\r\n\r\n /**\r\n * Manually reset circuit breaker\r\n */\r\n reset(): void {\r\n this.state = CircuitState.CLOSED;\r\n this.failures = 0;\r\n this.successes = 0;\r\n this.totalCalls = 0;\r\n this.openedAt = undefined;\r\n this.resetAt = undefined;\r\n this.lastError = undefined;\r\n }\r\n\r\n /**\r\n * Check if circuit is open\r\n */\r\n isOpen(): boolean {\r\n return this.state === CircuitState.OPEN;\r\n }\r\n\r\n /**\r\n * Check if circuit is closed\r\n */\r\n isClosed(): boolean {\r\n return this.state === CircuitState.CLOSED;\r\n }\r\n\r\n /**\r\n * Check if circuit is half-open\r\n */\r\n isHalfOpen(): boolean {\r\n return this.state === CircuitState.HALF_OPEN;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,97 +1,102 @@
1
- {
2
- "name": "@dsai-io/tools",
3
- "version": "0.0.1",
4
- "description": "Build tooling and CLI for DSAi Design System",
5
- "type": "module",
6
- "main": "dist/index.cjs",
7
- "module": "dist/index.js",
8
- "types": "dist/index.d.ts",
9
- "bin": {
10
- "dsai": "./bin/dsai-tools.mjs",
11
- "dsai-tools": "./bin/dsai-tools.mjs"
12
- },
13
- "exports": {
14
- ".": {
15
- "types": "./dist/index.d.ts",
16
- "import": "./dist/index.js",
17
- "require": "./dist/index.cjs"
18
- },
19
- "./config": {
20
- "types": "./dist/config/index.d.ts",
21
- "import": "./dist/config/index.js",
22
- "require": "./dist/config/index.cjs"
23
- },
24
- "./tokens": {
25
- "types": "./dist/tokens/index.d.ts",
26
- "import": "./dist/tokens/index.js",
27
- "require": "./dist/tokens/index.cjs"
28
- },
29
- "./icons": {
30
- "types": "./dist/icons/index.d.ts",
31
- "import": "./dist/icons/index.js",
32
- "require": "./dist/icons/index.cjs"
33
- },
34
- "./cli": {
35
- "types": "./dist/cli/index.d.ts",
36
- "import": "./dist/cli/index.js",
37
- "require": "./dist/cli/index.cjs"
38
- }
39
- },
40
- "files": [
41
- "dist",
42
- "bin",
43
- "templates"
44
- ],
45
- "scripts": {
46
- "build": "tsup",
47
- "build:watch": "tsup --watch",
48
- "dev": "tsup --watch",
49
- "test": "jest",
50
- "lint": "eslint src --ext .ts",
51
- "lint:fix": "eslint src --ext .ts --fix",
52
- "typecheck": "tsc --noEmit",
53
- "generate-schema": "node scripts/generate-schema.mjs"
54
- },
55
- "keywords": [
56
- "design-tokens",
57
- "design-system",
58
- "cli",
59
- "style-dictionary",
60
- "build-tools",
61
- "dsai"
62
- ],
63
- "license": "UNLICENSED",
64
- "engines": {
65
- "node": ">=22.0.0"
66
- },
67
- "dependencies": {
68
- "commander": "^14.0.2",
69
- "cosmiconfig": "^9.0.0",
70
- "deepmerge": "^4.3.1",
71
- "fast-glob": "^3.3.3",
72
- "ora": "^9.0.0",
73
- "picocolors": "^1.1.1",
74
- "svgo": "^4.0.0",
75
- "zod": "^3.25.0"
76
- },
77
- "devDependencies": {
78
- "@clack/prompts": "^0.11.0",
79
- "@types/node": "^22.15.30",
80
- "@types/prompts": "^2.4.9",
81
- "style-dictionary": "^5.1.1",
82
- "tsup": "^8.5.1",
83
- "typescript": "^5.9.3",
84
- "zod-to-json-schema": "^3.25.0"
85
- },
86
- "peerDependencies": {
87
- "style-dictionary": "^5.1.1"
88
- },
89
- "peerDependenciesMeta": {
90
- "style-dictionary": {
91
- "optional": true
92
- }
93
- },
94
- "publishConfig": {
95
- "access": "restricted"
96
- }
97
- }
1
+ {
2
+ "name": "@dsai-io/tools",
3
+ "version": "1.1.0",
4
+ "description": "Build tooling and CLI for DSAi Design System",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "dsai": "./bin/dsai-tools.mjs",
11
+ "dsai-tools": "./bin/dsai-tools.mjs"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/index.cjs"
18
+ },
19
+ "./config": {
20
+ "types": "./dist/config/index.d.ts",
21
+ "import": "./dist/config/index.js",
22
+ "require": "./dist/config/index.cjs"
23
+ },
24
+ "./tokens": {
25
+ "types": "./dist/tokens/index.d.ts",
26
+ "import": "./dist/tokens/index.js",
27
+ "require": "./dist/tokens/index.cjs"
28
+ },
29
+ "./icons": {
30
+ "types": "./dist/icons/index.d.ts",
31
+ "import": "./dist/icons/index.js",
32
+ "require": "./dist/icons/index.cjs"
33
+ },
34
+ "./cli": {
35
+ "types": "./dist/cli/index.d.ts",
36
+ "import": "./dist/cli/index.js",
37
+ "require": "./dist/cli/index.cjs"
38
+ },
39
+ "./utils/circuit-breaker": {
40
+ "types": "./dist/utils/circuit-breaker.d.ts",
41
+ "import": "./dist/utils/circuit-breaker.js",
42
+ "require": "./dist/utils/circuit-breaker.cjs"
43
+ }
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "bin",
48
+ "templates"
49
+ ],
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "build:watch": "tsup --watch",
53
+ "dev": "tsup --watch",
54
+ "test": "jest",
55
+ "lint": "eslint src --ext .ts",
56
+ "lint:fix": "eslint src --ext .ts --fix",
57
+ "typecheck": "tsc --noEmit",
58
+ "generate-schema": "node scripts/generate-schema.mjs"
59
+ },
60
+ "keywords": [
61
+ "design-tokens",
62
+ "design-system",
63
+ "cli",
64
+ "style-dictionary",
65
+ "build-tools",
66
+ "dsai"
67
+ ],
68
+ "license": "AGPL-3.0-or-later",
69
+ "engines": {
70
+ "node": ">=22.0.0"
71
+ },
72
+ "dependencies": {
73
+ "commander": "^14.0.2",
74
+ "cosmiconfig": "^9.0.0",
75
+ "deepmerge": "^4.3.1",
76
+ "fast-glob": "^3.3.3",
77
+ "ora": "^9.0.0",
78
+ "picocolors": "^1.1.1",
79
+ "svgo": "^4.0.0",
80
+ "zod": "^4.3.5"
81
+ },
82
+ "devDependencies": {
83
+ "@clack/prompts": "^0.11.0",
84
+ "@types/node": "^22.15.30",
85
+ "@types/prompts": "^2.4.9",
86
+ "style-dictionary": "^5.1.4",
87
+ "tsup": "^8.5.1",
88
+ "typescript": "^5.9.3",
89
+ "zod-to-json-schema": "^3.25.1"
90
+ },
91
+ "peerDependencies": {
92
+ "style-dictionary": "^5.1.4"
93
+ },
94
+ "peerDependenciesMeta": {
95
+ "style-dictionary": {
96
+ "optional": true
97
+ }
98
+ },
99
+ "publishConfig": {
100
+ "access": "public"
101
+ }
102
+ }
@@ -1,37 +1,37 @@
1
- {
2
- "$schema": "./dsai-config.schema.json",
3
- "tokens": {
4
- "source": "theme",
5
- "sourceDir": "figma-exports",
6
- "sourcePatterns": ["theme.json", "tokens.json", "*.tokens.json"],
7
- "outputDir": "dist",
8
- "formats": ["css", "scss", "js", "ts", "json"],
9
- "prefix": "--dsai-",
10
- "themes": {
11
- "autoDetect": true,
12
- "default": "Light",
13
- "selectorPattern": {
14
- "default": ":root",
15
- "others": "[data-dsai-theme=\"{mode}\"]"
16
- }
17
- },
18
- "outputReferences": true,
19
- "baseFontSize": 16,
20
- "separateThemeFiles": false,
21
- "watch": false
22
- },
23
- "icons": {
24
- "sourceDir": "icons",
25
- "outputDir": "src/components/icons",
26
- "framework": "react",
27
- "typescript": true,
28
- "optimize": true,
29
- "prefix": "Icon",
30
- "exportIndex": true,
31
- "generateSprite": false
32
- },
33
- "global": {
34
- "debug": false,
35
- "logLevel": "info"
36
- }
37
- }
1
+ {
2
+ "$schema": "./dsai-config.schema.json",
3
+ "tokens": {
4
+ "source": "theme",
5
+ "sourceDir": "figma-exports",
6
+ "sourcePatterns": ["theme.json", "tokens.json", "*.tokens.json"],
7
+ "outputDir": "dist",
8
+ "formats": ["css", "scss", "js", "ts", "json"],
9
+ "prefix": "--dsai-",
10
+ "themes": {
11
+ "autoDetect": true,
12
+ "default": "Light",
13
+ "selectorPattern": {
14
+ "default": ":root",
15
+ "others": "[data-dsai-theme=\"{mode}\"]"
16
+ }
17
+ },
18
+ "outputReferences": true,
19
+ "baseFontSize": 16,
20
+ "separateThemeFiles": false,
21
+ "watch": false
22
+ },
23
+ "icons": {
24
+ "sourceDir": "icons",
25
+ "outputDir": "src/components/icons",
26
+ "framework": "react",
27
+ "typescript": true,
28
+ "optimize": true,
29
+ "prefix": "Icon",
30
+ "exportIndex": true,
31
+ "generateSprite": false
32
+ },
33
+ "global": {
34
+ "debug": false,
35
+ "logLevel": "info"
36
+ }
37
+ }