@nebutra/design-sync 0.1.0 → 0.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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function run(argv?: string[]): Promise<number>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAoGA,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDxE"}
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env node
2
+ // =============================================================================
3
+ // design-sync CLI
4
+ // =============================================================================
5
+ // Commands:
6
+ // design-sync detect Print the resolved provider + env diagnostics
7
+ // design-sync healthcheck Run the provider's healthcheck()
8
+ // design-sync pull Pull design-tool → repo (DTCG JSON)
9
+ // design-sync push Push repo → design-tool (defaults to dry-run)
10
+ //
11
+ // Flags:
12
+ // --dry-run Force dry-run on push
13
+ // --themes a,b Restrict to specific token sets / themes
14
+ // --provider X Override DESIGN_SYNC_PROVIDER for this invocation
15
+ // --json Emit machine-readable JSON instead of human text
16
+ // =============================================================================
17
+ import { describeEnv } from "../detect";
18
+ import { createDesignSync } from "../factory";
19
+ function parseArgs(argv) {
20
+ const [, , command = "help", ...rest] = argv;
21
+ let dryRun = false;
22
+ let json = false;
23
+ const themes = [];
24
+ let provider;
25
+ for (let i = 0; i < rest.length; i++) {
26
+ const arg = rest[i];
27
+ if (arg === "--dry-run")
28
+ dryRun = true;
29
+ else if (arg === "--json")
30
+ json = true;
31
+ else if (arg === "--themes") {
32
+ const next = rest[i + 1];
33
+ if (next) {
34
+ for (const t of next.split(",")) {
35
+ const trimmed = t.trim();
36
+ if (trimmed)
37
+ themes.push(trimmed);
38
+ }
39
+ i++;
40
+ }
41
+ }
42
+ else if (arg === "--provider") {
43
+ const next = rest[i + 1];
44
+ if (next) {
45
+ provider = next.trim();
46
+ i++;
47
+ }
48
+ }
49
+ }
50
+ return { command, dryRun, json, themes, provider };
51
+ }
52
+ function emit(payload, json) {
53
+ if (json) {
54
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
55
+ return;
56
+ }
57
+ if (typeof payload === "string") {
58
+ process.stdout.write(`${payload}\n`);
59
+ return;
60
+ }
61
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
62
+ }
63
+ function emitError(message, json) {
64
+ if (json) {
65
+ process.stderr.write(`${JSON.stringify({ ok: false, error: message })}\n`);
66
+ }
67
+ else {
68
+ process.stderr.write(`error: ${message}\n`);
69
+ }
70
+ }
71
+ const HELP_TEXT = `design-sync — provider-agnostic design-tool sync
72
+
73
+ Usage:
74
+ design-sync <command> [options]
75
+
76
+ Commands:
77
+ detect Print the resolved provider + env diagnostics
78
+ healthcheck Run the provider's healthcheck()
79
+ pull Pull design-tool → repo (DTCG JSON)
80
+ push Push repo → design-tool (defaults to dry-run on figma/penpot)
81
+ help Show this message
82
+
83
+ Options:
84
+ --provider <X> Override provider (figma|penpot|git-only|memory)
85
+ --themes a,b Restrict to specific token sets
86
+ --dry-run Force dry-run on push
87
+ --json Emit machine-readable JSON
88
+ `;
89
+ export async function run(argv = process.argv) {
90
+ const args = parseArgs(argv);
91
+ if (args.command === "help" || args.command === "--help" || args.command === "-h") {
92
+ process.stdout.write(HELP_TEXT);
93
+ return 0;
94
+ }
95
+ if (args.command === "detect") {
96
+ const env = describeEnv();
97
+ emit(env, args.json);
98
+ return 0;
99
+ }
100
+ try {
101
+ const provider = await createDesignSync(args.provider ? { provider: args.provider } : undefined);
102
+ if (args.command === "healthcheck") {
103
+ const status = await provider.healthcheck();
104
+ emit(status, args.json);
105
+ return status.ok ? 0 : 1;
106
+ }
107
+ if (args.command === "pull") {
108
+ const themes = args.themes.length > 0 ? { themes: args.themes } : {};
109
+ const result = await provider.pull(themes);
110
+ emit(args.json
111
+ ? result
112
+ : `${result.summary} (provider=${result.provider}, sets=${result.sets.length})`, args.json);
113
+ return 0;
114
+ }
115
+ if (args.command === "push") {
116
+ const opts = {};
117
+ if (args.themes.length > 0)
118
+ opts.themes = args.themes;
119
+ if (args.dryRun)
120
+ opts.dryRun = true;
121
+ const result = await provider.push(opts);
122
+ emit(args.json
123
+ ? result
124
+ : `${result.summary} (provider=${result.provider}, dryRun=${result.dryRun})`, args.json);
125
+ return 0;
126
+ }
127
+ emitError(`unknown command: ${args.command}\n\n${HELP_TEXT}`, args.json);
128
+ return 2;
129
+ }
130
+ catch (error) {
131
+ emitError(error.message, args.json);
132
+ return 1;
133
+ }
134
+ }
135
+ // Run when invoked directly (not when imported in tests).
136
+ //
137
+ // We treat any of the following as "invoked as CLI":
138
+ // - argv[1] basename matches `design-sync` (the bin entry)
139
+ // - argv[1] basename matches the source/dist filename (`index.ts`, `index.js`)
140
+ // - argv[1] is missing (e.g. `node --eval` style runners)
141
+ // - DESIGN_SYNC_CLI env flag is set (escape hatch for unusual runners)
142
+ const invokedFromCli = (() => {
143
+ if (typeof process === "undefined")
144
+ return false;
145
+ if (process.env?.DESIGN_SYNC_CLI === "1")
146
+ return true;
147
+ const entry = Array.isArray(process.argv) ? process.argv[1] : undefined;
148
+ if (!entry)
149
+ return false;
150
+ const base = entry.split("/").pop() ?? entry;
151
+ return /^(design-sync|index\.(c|m)?[jt]sx?)$/u.test(base);
152
+ })();
153
+ if (invokedFromCli) {
154
+ run().then((code) => {
155
+ process.exit(code);
156
+ }, (error) => {
157
+ process.stderr.write(`fatal: ${error.message}\n`);
158
+ process.exit(1);
159
+ });
160
+ }
@@ -0,0 +1,21 @@
1
+ import type { DesignSyncProviderType } from "./types";
2
+ /**
3
+ * Read `DESIGN_SYNC_PROVIDER` from the environment, validate it, and return
4
+ * the typed value if it matches a known provider.
5
+ */
6
+ export declare function readConfiguredProvider(env?: NodeJS.ProcessEnv): DesignSyncProviderType | undefined;
7
+ /**
8
+ * Detect the provider from a snapshot of environment variables.
9
+ * Pure function — does NOT touch `process.env` directly so it is unit-testable.
10
+ */
11
+ export declare function detectProvider(env?: NodeJS.ProcessEnv): DesignSyncProviderType;
12
+ /**
13
+ * For diagnostics: return which env vars were detected and which are missing
14
+ * for each provider. Used by `healthcheck()` and the `detect` CLI command.
15
+ */
16
+ export declare function describeEnv(env?: NodeJS.ProcessEnv): {
17
+ detected: string[];
18
+ missing: string[];
19
+ resolved: DesignSyncProviderType;
20
+ };
21
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAsBtD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,sBAAsB,GAAG,SAAS,CAOpC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,sBAAsB,CAa3F;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,sBAAsB,CAAC;CAClC,CA0BA"}
package/dist/detect.js ADDED
@@ -0,0 +1,79 @@
1
+ // =============================================================================
2
+ // Provider Auto-Detection
3
+ // =============================================================================
4
+ // Resolution order (highest priority first):
5
+ // 1. DESIGN_SYNC_PROVIDER env var (explicit)
6
+ // 2. FIGMA_PERSONAL_ACCESS_TOKEN + FIGMA_FILE_ID → "figma"
7
+ // 3. PENPOT_API_URL + PENPOT_TOKEN → "penpot"
8
+ // 4. fallback → "git-only"
9
+ //
10
+ // `memory` is never auto-detected; it must be requested explicitly via the
11
+ // DESIGN_SYNC_PROVIDER env var or a config object (used in tests).
12
+ // =============================================================================
13
+ const VALID_PROVIDERS = new Set([
14
+ "figma",
15
+ "penpot",
16
+ "git-only",
17
+ "memory",
18
+ ]);
19
+ /**
20
+ * Read `DESIGN_SYNC_PROVIDER` from the environment, validate it, and return
21
+ * the typed value if it matches a known provider.
22
+ */
23
+ export function readConfiguredProvider(env = process.env) {
24
+ const raw = env.DESIGN_SYNC_PROVIDER?.trim();
25
+ if (!raw)
26
+ return undefined;
27
+ if (!VALID_PROVIDERS.has(raw)) {
28
+ return undefined;
29
+ }
30
+ return raw;
31
+ }
32
+ /**
33
+ * Detect the provider from a snapshot of environment variables.
34
+ * Pure function — does NOT touch `process.env` directly so it is unit-testable.
35
+ */
36
+ export function detectProvider(env = process.env) {
37
+ const explicit = readConfiguredProvider(env);
38
+ if (explicit)
39
+ return explicit;
40
+ const figmaToken = env.FIGMA_PERSONAL_ACCESS_TOKEN?.trim();
41
+ const figmaFileId = env.FIGMA_FILE_ID?.trim();
42
+ if (figmaToken && figmaFileId)
43
+ return "figma";
44
+ const penpotUrl = env.PENPOT_API_URL?.trim();
45
+ const penpotToken = env.PENPOT_TOKEN?.trim();
46
+ if (penpotUrl && penpotToken)
47
+ return "penpot";
48
+ return "git-only";
49
+ }
50
+ /**
51
+ * For diagnostics: return which env vars were detected and which are missing
52
+ * for each provider. Used by `healthcheck()` and the `detect` CLI command.
53
+ */
54
+ export function describeEnv(env = process.env) {
55
+ const detected = [];
56
+ const missing = [];
57
+ const known = [
58
+ "DESIGN_SYNC_PROVIDER",
59
+ "FIGMA_PERSONAL_ACCESS_TOKEN",
60
+ "FIGMA_FILE_ID",
61
+ "FIGMA_GITHUB_REPO",
62
+ "FIGMA_GITHUB_BRANCH",
63
+ "PENPOT_API_URL",
64
+ "PENPOT_TOKEN",
65
+ "PENPOT_FILE_ID",
66
+ "PENPOT_TEAM_ID",
67
+ ];
68
+ for (const key of known) {
69
+ if (env[key]?.trim())
70
+ detected.push(key);
71
+ else
72
+ missing.push(key);
73
+ }
74
+ return {
75
+ detected,
76
+ missing,
77
+ resolved: detectProvider(env),
78
+ };
79
+ }
@@ -0,0 +1,42 @@
1
+ import type { DesignSyncConfig, DesignSyncProvider } from "./types";
2
+ /**
3
+ * Create a design-sync provider instance.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * // Auto-detect from environment
8
+ * const sync = await createDesignSync();
9
+ *
10
+ * // Explicit Figma
11
+ * const sync = await createDesignSync({
12
+ * provider: "figma",
13
+ * personalAccessToken: process.env.FIGMA_PERSONAL_ACCESS_TOKEN,
14
+ * fileId: "abc123",
15
+ * });
16
+ *
17
+ * // Explicit Penpot
18
+ * const sync = await createDesignSync({
19
+ * provider: "penpot",
20
+ * apiUrl: "https://design.penpot.app/api",
21
+ * token: process.env.PENPOT_TOKEN,
22
+ * });
23
+ *
24
+ * // Explicit git-only (zero config)
25
+ * const sync = await createDesignSync({ provider: "git-only" });
26
+ * ```
27
+ */
28
+ export declare function createDesignSync(config?: DesignSyncConfig): Promise<DesignSyncProvider>;
29
+ /**
30
+ * Get or create the default (singleton) design-sync provider.
31
+ * Lazy initialisation avoids import-time side effects.
32
+ */
33
+ export declare function getDesignSync(): Promise<DesignSyncProvider>;
34
+ /**
35
+ * Replace the default design-sync provider (useful in tests).
36
+ */
37
+ export declare function setDesignSync(provider: DesignSyncProvider): void;
38
+ /**
39
+ * Reset the singleton — primarily for test isolation.
40
+ */
41
+ export declare function resetDesignSync(): void;
42
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAA0B,MAAM,SAAS,CAAC;AAe5F;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiC7F;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAKjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAEhE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,89 @@
1
+ import { logger } from "@nebutra/logger";
2
+ import { detectProvider } from "./detect";
3
+ // =============================================================================
4
+ // Design-Sync Factory — Provider-agnostic creation
5
+ // =============================================================================
6
+ // The factory resolves the correct provider at runtime based on:
7
+ // 1. Explicit config passed to `createDesignSync()`
8
+ // 2. `DESIGN_SYNC_PROVIDER` environment variable
9
+ // 3. Auto-detection from FIGMA_* / PENPOT_* env vars
10
+ //
11
+ // This lets customers switch design tools without changing application code.
12
+ // =============================================================================
13
+ let defaultProvider = null;
14
+ /**
15
+ * Create a design-sync provider instance.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * // Auto-detect from environment
20
+ * const sync = await createDesignSync();
21
+ *
22
+ * // Explicit Figma
23
+ * const sync = await createDesignSync({
24
+ * provider: "figma",
25
+ * personalAccessToken: process.env.FIGMA_PERSONAL_ACCESS_TOKEN,
26
+ * fileId: "abc123",
27
+ * });
28
+ *
29
+ * // Explicit Penpot
30
+ * const sync = await createDesignSync({
31
+ * provider: "penpot",
32
+ * apiUrl: "https://design.penpot.app/api",
33
+ * token: process.env.PENPOT_TOKEN,
34
+ * });
35
+ *
36
+ * // Explicit git-only (zero config)
37
+ * const sync = await createDesignSync({ provider: "git-only" });
38
+ * ```
39
+ */
40
+ export async function createDesignSync(config) {
41
+ const providerType = config?.provider ?? detectProvider();
42
+ logger.info("[design-sync] Creating provider", { provider: providerType });
43
+ switch (providerType) {
44
+ case "figma": {
45
+ const { FigmaProvider } = await import("./providers/figma");
46
+ const figmaConfig = config?.provider === "figma" ? config : undefined;
47
+ return new FigmaProvider(figmaConfig ?? { provider: "figma" });
48
+ }
49
+ case "penpot": {
50
+ const { PenpotProvider } = await import("./providers/penpot");
51
+ const penpotConfig = config?.provider === "penpot" ? config : undefined;
52
+ return new PenpotProvider(penpotConfig ?? { provider: "penpot" });
53
+ }
54
+ case "git-only": {
55
+ const { GitOnlyProvider } = await import("./providers/git-only");
56
+ const gitConfig = config?.provider === "git-only" ? config : undefined;
57
+ return new GitOnlyProvider(gitConfig ?? { provider: "git-only" });
58
+ }
59
+ case "memory": {
60
+ const { MemoryProvider } = await import("./providers/memory");
61
+ const memConfig = config?.provider === "memory" ? config : undefined;
62
+ return new MemoryProvider(memConfig ?? { provider: "memory" });
63
+ }
64
+ default:
65
+ throw new Error(`Unknown design-sync provider: ${providerType}`);
66
+ }
67
+ }
68
+ /**
69
+ * Get or create the default (singleton) design-sync provider.
70
+ * Lazy initialisation avoids import-time side effects.
71
+ */
72
+ export async function getDesignSync() {
73
+ if (!defaultProvider) {
74
+ defaultProvider = await createDesignSync();
75
+ }
76
+ return defaultProvider;
77
+ }
78
+ /**
79
+ * Replace the default design-sync provider (useful in tests).
80
+ */
81
+ export function setDesignSync(provider) {
82
+ defaultProvider = provider;
83
+ }
84
+ /**
85
+ * Reset the singleton — primarily for test isolation.
86
+ */
87
+ export function resetDesignSync() {
88
+ defaultProvider = null;
89
+ }
@@ -0,0 +1,37 @@
1
+ import figmaPluginConfig from "./tokens-studio.config.json";
2
+ export declare const FIGMA_TOKENS_STUDIO_CONFIG: {
3
+ $schema: string;
4
+ name: string;
5
+ version: string;
6
+ description: string;
7
+ syncProvider: string;
8
+ git: {
9
+ repository: string;
10
+ defaultBranch: string;
11
+ syncBranchPrefix: string;
12
+ tokenPath: string;
13
+ themesPath: string;
14
+ metadataPath: string;
15
+ };
16
+ format: {
17
+ spec: string;
18
+ indent: number;
19
+ trailingNewline: boolean;
20
+ useUiCompatibleTypes: boolean;
21
+ };
22
+ storage: {
23
+ multiFile: boolean;
24
+ tokenSetSeparator: string;
25
+ };
26
+ permissions: {
27
+ allowDestructiveSync: boolean;
28
+ requirePullRequest: boolean;
29
+ protectedSets: string[];
30
+ };
31
+ ui: {
32
+ language: string;
33
+ showThemeMatrix: boolean;
34
+ };
35
+ };
36
+ export type FigmaTokensStudioConfig = typeof figmaPluginConfig;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/figma-config/index.ts"],"names":[],"mappings":"AAWA,OAAO,iBAAiB,MAAM,6BAA6B,CAAuB;AAElF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAoB,CAAC;AAE5D,MAAM,MAAM,uBAAuB,GAAG,OAAO,iBAAiB,CAAC"}
@@ -0,0 +1,12 @@
1
+ // =============================================================================
2
+ // Tokens Studio config — canonical copy owned by @nebutra/design-sync
3
+ // =============================================================================
4
+ // The original `.tokens-studio/config.json` lives at the repo root because the
5
+ // Tokens Studio plugin pins its config-discovery path. We keep an in-package
6
+ // canonical copy here so the figma provider can self-document and so a sync
7
+ // CLI can scaffold the file when initialising a fresh repo.
8
+ //
9
+ // If the plugin's config schema changes, update both files in lock-step.
10
+ // =============================================================================
11
+ import figmaPluginConfig from "./tokens-studio.config.json" with { type: "json" };
12
+ export const FIGMA_TOKENS_STUDIO_CONFIG = figmaPluginConfig;
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/tokens-studio/figma-plugin/main/schemas/tokens-studio-config.schema.json",
3
+ "name": "Nebutra Design Tokens",
4
+ "version": "0.1.0",
5
+ "description": "Bidirectional sync between Tokens Studio for Figma and packages/design-tokens (W3C DTCG). Owned by @nebutra/design-sync's figma provider.",
6
+ "syncProvider": "github",
7
+ "git": {
8
+ "repository": "Nebutra/Nebutra-Sailor",
9
+ "defaultBranch": "main",
10
+ "syncBranchPrefix": "tokens-studio/",
11
+ "tokenPath": "packages/design/design-tokens/tokens",
12
+ "themesPath": ".tokens-studio/themes.json",
13
+ "metadataPath": ".tokens-studio/metadata.json"
14
+ },
15
+ "format": {
16
+ "spec": "dtcg",
17
+ "indent": 2,
18
+ "trailingNewline": true,
19
+ "useUiCompatibleTypes": true
20
+ },
21
+ "storage": {
22
+ "multiFile": true,
23
+ "tokenSetSeparator": "/"
24
+ },
25
+ "permissions": {
26
+ "allowDestructiveSync": false,
27
+ "requirePullRequest": true,
28
+ "protectedSets": ["core", "semantic"]
29
+ },
30
+ "ui": {
31
+ "language": "en",
32
+ "showThemeMatrix": true
33
+ }
34
+ }
@@ -0,0 +1,12 @@
1
+ export { describeEnv, detectProvider, readConfiguredProvider } from "./detect";
2
+ export { createDesignSync, getDesignSync, resetDesignSync, setDesignSync, } from "./factory";
3
+ export type { FigmaTokensStudioConfig } from "./figma-config/index";
4
+ export { FIGMA_TOKENS_STUDIO_CONFIG } from "./figma-config/index";
5
+ export { defaultTokensDir, defaultTokensStudioDir, readTokenSets, validateDtcgTree, writeTokenSet, } from "./io";
6
+ export { FigmaProvider } from "./providers/figma";
7
+ export { GitOnlyProvider } from "./providers/git-only";
8
+ export { MemoryProvider } from "./providers/memory";
9
+ export { PenpotProvider } from "./providers/penpot";
10
+ export type { BaseProviderConfig, DesignSyncConfig, DesignSyncProvider, DesignSyncProviderType, DesignTokenLeaf, DesignTokenSet, DesignTokenTree, FigmaProviderConfig, GitOnlyProviderConfig, HealthStatus, MemoryProviderConfig, PenpotProviderConfig, PullOptions, PullResult, PushOptions, PushResult, } from "./types";
11
+ export { DesignTokenLeafSchema } from "./types";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAE/E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,aAAa,GACd,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ // =============================================================================
2
+ // @nebutra/design-sync — Provider-agnostic design-tool sync
3
+ // =============================================================================
4
+ // Supports:
5
+ // - Figma + Tokens Studio (DTCG via GitHub, plugin owns the transport)
6
+ // - Penpot (REST API, self-hostable, China-friendly)
7
+ // - git-only (zero-config default — DTCG files only)
8
+ // - memory (test fixture)
9
+ //
10
+ // Usage:
11
+ // import { getDesignSync } from "@nebutra/design-sync";
12
+ //
13
+ // const sync = await getDesignSync(); // auto-detect provider
14
+ // const result = await sync.pull(); // design-tool → repo
15
+ // await sync.push({ dryRun: true }); // repo → design-tool
16
+ // await sync.healthcheck();
17
+ // =============================================================================
18
+ // ── Detection helpers ───────────────────────────────────────────────────────
19
+ export { describeEnv, detectProvider, readConfiguredProvider } from "./detect";
20
+ // ── Factory ─────────────────────────────────────────────────────────────────
21
+ export { createDesignSync, getDesignSync, resetDesignSync, setDesignSync, } from "./factory";
22
+ // ── Figma config snapshot ───────────────────────────────────────────────────
23
+ export { FIGMA_TOKENS_STUDIO_CONFIG } from "./figma-config/index";
24
+ // ── DTCG I/O helpers (re-exported for advanced consumers) ───────────────────
25
+ export { defaultTokensDir, defaultTokensStudioDir, readTokenSets, validateDtcgTree, writeTokenSet, } from "./io";
26
+ // ── Providers (tree-shakable direct imports) ────────────────────────────────
27
+ export { FigmaProvider } from "./providers/figma";
28
+ export { GitOnlyProvider } from "./providers/git-only";
29
+ export { MemoryProvider } from "./providers/memory";
30
+ export { PenpotProvider } from "./providers/penpot";
31
+ // ── Types ───────────────────────────────────────────────────────────────────
32
+ export { DesignTokenLeafSchema } from "./types";
package/dist/io.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { type DesignTokenSet } from "./types";
2
+ /**
3
+ * Validate that every leaf in a DTCG tree carries `$value` and `$type`.
4
+ * Returns a list of dot-paths that violate the contract.
5
+ */
6
+ export declare function validateDtcgTree(tree: unknown, pathPrefix?: string): string[];
7
+ /**
8
+ * Read all DTCG token files under `tokensDir` into memory.
9
+ * Each file becomes one `DesignTokenSet`.
10
+ */
11
+ export declare function readTokenSets(tokensDir: string): Promise<DesignTokenSet[]>;
12
+ /**
13
+ * Write a `DesignTokenSet` back to disk under `tokensDir`. Creates
14
+ * parent directories as needed and uses 2-space indentation with a
15
+ * trailing newline (matches `.tokens-studio/config.json#format`).
16
+ */
17
+ export declare function writeTokenSet(tokensDir: string, set: DesignTokenSet): Promise<void>;
18
+ /**
19
+ * Default tokens directory for the Nebutra-Sailor monorepo.
20
+ */
21
+ export declare function defaultTokensDir(cwd?: string): string;
22
+ /**
23
+ * Default Tokens Studio metadata directory for the Nebutra-Sailor monorepo.
24
+ */
25
+ export declare function defaultTokensStudioDir(cwd?: string): string;
26
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../src/io.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,cAAc,EAAwB,MAAM,SAAS,CAAC;AAyC3F;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,SAAK,GAAG,MAAM,EAAE,CA0BzE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA8BhF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAE1E"}