@greensight/gts 1.0.0-alpha.10

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 (55) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +68 -0
  3. package/bin/generate.cjs +12 -0
  4. package/bin/generate.js +21 -0
  5. package/bin/generate.mjs +10 -0
  6. package/bin/init.cjs +11 -0
  7. package/bin/init.js +19 -0
  8. package/bin/init.mjs +8 -0
  9. package/classes/Config/index.d.ts +13 -0
  10. package/classes/Config/index.d.ts.map +1 -0
  11. package/classes/FigmaApi/index.d.ts +16 -0
  12. package/classes/FigmaApi/index.d.ts.map +1 -0
  13. package/classes/FigmaApi/types.d.ts +7 -0
  14. package/classes/FigmaApi/types.d.ts.map +1 -0
  15. package/classes/FigmaApi/utils.d.ts +3 -0
  16. package/classes/FigmaApi/utils.d.ts.map +1 -0
  17. package/classes/FileStorage/index.d.ts +19 -0
  18. package/classes/FileStorage/index.d.ts.map +1 -0
  19. package/classes/TokenManager/index.d.ts +71 -0
  20. package/classes/TokenManager/index.d.ts.map +1 -0
  21. package/classes/TokenManager/types/ds.d.ts +25 -0
  22. package/classes/TokenManager/types/ds.d.ts.map +1 -0
  23. package/classes/TokenManager/types/figma.d.ts +82 -0
  24. package/classes/TokenManager/types/figma.d.ts.map +1 -0
  25. package/classes/TokenManager/types/index.d.ts +3 -0
  26. package/classes/TokenManager/types/index.d.ts.map +1 -0
  27. package/commands/generate/index.d.ts +2 -0
  28. package/commands/generate/index.d.ts.map +1 -0
  29. package/commands/init/index.d.ts +2 -0
  30. package/commands/init/index.d.ts.map +1 -0
  31. package/common/console.d.ts +3 -0
  32. package/common/console.d.ts.map +1 -0
  33. package/common/types.d.ts +29 -0
  34. package/common/types.d.ts.map +1 -0
  35. package/index.cjs +8 -0
  36. package/index.d.ts +6 -0
  37. package/index.d.ts.map +1 -0
  38. package/index.mjs +732 -0
  39. package/modules/colors/colorsFromStyles.d.ts +16 -0
  40. package/modules/colors/colorsFromStyles.d.ts.map +1 -0
  41. package/modules/colors/colorsFromTokenManager.d.ts +17 -0
  42. package/modules/colors/colorsFromTokenManager.d.ts.map +1 -0
  43. package/modules/colors/colorsFromVariables.d.ts +16 -0
  44. package/modules/colors/colorsFromVariables.d.ts.map +1 -0
  45. package/modules/colors/index.d.ts +4 -0
  46. package/modules/colors/index.d.ts.map +1 -0
  47. package/modules/colors/types.d.ts +6 -0
  48. package/modules/colors/types.d.ts.map +1 -0
  49. package/modules/colors/utils.d.ts +45 -0
  50. package/modules/colors/utils.d.ts.map +1 -0
  51. package/modules/index.d.ts +2 -0
  52. package/modules/index.d.ts.map +1 -0
  53. package/modules/types.d.ts +10 -0
  54. package/modules/types.d.ts.map +1 -0
  55. package/package.json +44 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Greensight
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Greensight Token System
2
+
3
+ Generate design tokens from Figma.
4
+
5
+ ## Installation
6
+
7
+ Install as a development dependency:
8
+
9
+ ```bash
10
+ npm install --save-dev @greensight/gts
11
+ # or
12
+ pnpm add -D @greensight/gts
13
+ # or
14
+ yarn add --dev @greensight/gts
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Initialize configuration
20
+
21
+ ```bash
22
+ npx gts-init
23
+ ```
24
+
25
+ This will create a `gts.config.ts` file in your project root.
26
+
27
+ ### Generate tokens
28
+
29
+ ```bash
30
+ npx gts-generate
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ Create a `gts.config.ts` file in your project root:
36
+
37
+ ```typescript
38
+ import { colorsFromStyles, colorsFromVariables } from '@greensight/gts';
39
+
40
+ export default {
41
+ figmaToken: 'your-figma-token',
42
+ fileId: 'your-figma-file-id',
43
+ modules: [
44
+ colorsFromStyles({
45
+ input: { variablePaths: ['./dark.tokens.json', './light.tokens.json'] },
46
+ output: { jsonDir: './dist', stylesDir: './dist' },
47
+ }),
48
+ colorsFromVariables({
49
+ input: { variablePaths: ['./dark.tokens.json', './light.tokens.json'] },
50
+ output: { jsonDir: './dist', stylesDir: './dist' },
51
+ }),
52
+ ],
53
+ };
54
+ ```
55
+
56
+ ## Modules
57
+
58
+ ### colorsFromStyles
59
+
60
+ Generates color tokens from Figma styles. Fetches styles from Figma API and processes them.
61
+
62
+ ### colorsFromVariables
63
+
64
+ Generates color tokens directly from variable files (JSON format).
65
+
66
+ ## License
67
+
68
+ MIT
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+
3
+ (async () => {
4
+ try {
5
+ const { generate } = require('../index.cjs');
6
+ const modules = process.argv.slice(2);
7
+ await generate(modules);
8
+ } catch (error) {
9
+ console.error('Failed to generate:', error);
10
+ process.exit(1);
11
+ }
12
+ })();
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Universal bin file - works with both CJS and ESM via dynamic import
4
+ (async () => {
5
+ const modules = process.argv.slice(2);
6
+
7
+ try {
8
+ // Dynamic import works in both CJS (Node 12.20+) and ESM
9
+ const module = await import('../index.mjs');
10
+ await module.generate(modules);
11
+ } catch (error) {
12
+ // Fallback to CJS if ESM fails
13
+ try {
14
+ const module = require('../index.cjs');
15
+ await module.generate(modules);
16
+ } catch (cjsError) {
17
+ console.error('Failed to generate:', error.message || error);
18
+ process.exit(1);
19
+ }
20
+ }
21
+ })();
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { generate } from '../index.mjs';
4
+
5
+ const modules = process.argv.slice(2);
6
+
7
+ generate(modules).catch(error => {
8
+ console.error('Failed to generate:', error);
9
+ process.exit(1);
10
+ });
package/bin/init.cjs ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ (async () => {
4
+ try {
5
+ const { init } = require('../index.cjs');
6
+ await init();
7
+ } catch (error) {
8
+ console.error('Failed to initialize:', error);
9
+ process.exit(1);
10
+ }
11
+ })();
package/bin/init.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Universal bin file - works with both CJS and ESM via dynamic import
4
+ (async () => {
5
+ try {
6
+ // Dynamic import works in both CJS (Node 12.20+) and ESM
7
+ const module = await import('../index.mjs');
8
+ await module.init();
9
+ } catch (error) {
10
+ // Fallback to CJS if ESM fails
11
+ try {
12
+ const module = require('../index.cjs');
13
+ await module.init();
14
+ } catch (cjsError) {
15
+ console.error('Failed to initialize:', error.message || error);
16
+ process.exit(1);
17
+ }
18
+ }
19
+ })();
package/bin/init.mjs ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { init } from '../index.mjs';
4
+
5
+ init().catch(error => {
6
+ console.error('Failed to initialize:', error);
7
+ process.exit(1);
8
+ });
@@ -0,0 +1,13 @@
1
+ import { IModule } from '../../modules/types';
2
+ export interface IGtsConfig {
3
+ figmaToken?: string;
4
+ fileId?: string;
5
+ manifest?: string;
6
+ modules: IModule[];
7
+ }
8
+ export declare class Config {
9
+ private static readonly configFileName;
10
+ static create(): Promise<void>;
11
+ load(): Promise<IGtsConfig | undefined>;
12
+ }
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/classes/Config/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,MAAM,WAAW,UAAU;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,EAAE,CAAC;CACtB;AAED,qBAAa,MAAM;IACf,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAmB;WAE5C,MAAM;IAQN,IAAI,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;CAYvD"}
@@ -0,0 +1,16 @@
1
+ import { GetFileComponentsResponse, GetFileNodesResponse, GetFileStylesResponse } from '@figma/rest-api-spec';
2
+ import { OnTimeMeasureHandlerType } from './types';
3
+ export declare class FigmaAPI {
4
+ figmaToken: string | undefined;
5
+ fileId: string | undefined;
6
+ constructor(figmaToken?: string, fileId?: string);
7
+ private onTimeMeasureHandler?;
8
+ setOnTimeMeasureHandler(handler: OnTimeMeasureHandlerType): void;
9
+ static returnJSON<T = unknown>(response: Response): Promise<T>;
10
+ private performControlledRequest;
11
+ private request;
12
+ getComponents(): Promise<GetFileComponentsResponse>;
13
+ getStyles(): Promise<GetFileStylesResponse>;
14
+ getNodes(ids: string[]): Promise<GetFileNodesResponse>;
15
+ }
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/classes/FigmaApi/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAEnH,OAAO,KAAK,EAAW,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAGjE,qBAAa,QAAQ;IACjB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBACf,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAKhD,OAAO,CAAC,oBAAoB,CAAC,CAA2B;IAExD,uBAAuB,CAAC,OAAO,EAAE,wBAAwB;WAI5C,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ;YAYzC,wBAAwB;YAsCxB,OAAO;IAUR,aAAa;IAIb,SAAS;IAIT,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE;CActC"}
@@ -0,0 +1,7 @@
1
+ export interface IConfig<TParams = any> {
2
+ params?: TParams;
3
+ timeout?: number;
4
+ abortController?: AbortController;
5
+ }
6
+ export type OnTimeMeasureHandlerType = (endpoint: string, headers: Record<string, unknown>, deltaTimeMs: number) => void;
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/classes/FigmaApi/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO,CAAC,OAAO,GAAG,GAAG;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,eAAe,CAAC;CACrC;AAED,MAAM,MAAM,wBAAwB,GAAG,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,WAAW,EAAE,MAAM,KAClB,IAAI,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const preparedParams: (params: Record<string, any>) => URLSearchParams;
2
+ export declare const chunkIds: (ids: string[], step?: number) => string[][];
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/classes/FigmaApi/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,oBAYzD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,EAAE,aAAS,eAQhD,CAAC"}
@@ -0,0 +1,19 @@
1
+ interface IWriteOptions {
2
+ directory?: string;
3
+ overwrite?: boolean;
4
+ }
5
+ export declare class FileStorage {
6
+ private static readonly baseDir;
7
+ private static resolveReadPath;
8
+ private static resolveWritePath;
9
+ private static handleReadError;
10
+ static read(filePath: string, encoding?: BufferEncoding): Promise<string>;
11
+ static readBuffer(filePath: string): Promise<Buffer<ArrayBufferLike>>;
12
+ static readJson<T = unknown>(filePath: string): Promise<T>;
13
+ static write(fileName: string, content?: string, options?: IWriteOptions): Promise<string>;
14
+ static writeWithExtension(name: string, extension: string, content?: string, options?: IWriteOptions): Promise<string>;
15
+ static exists(filePath: string): boolean;
16
+ static delete(fileName: string, directory?: string): Promise<void>;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/classes/FileStorage/index.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAyB;IAExD,OAAO,CAAC,MAAM,CAAC,eAAe;IAQ9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAQ/B,OAAO,CAAC,MAAM,CAAC,eAAe;WAUjB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,cAAuB;WAUxD,UAAU,CAAC,QAAQ,EAAE,MAAM;WAU3B,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;WAgBnD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAK,EAAE,OAAO,GAAE,aAAkB;WAcjE,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,SAAK,EAAE,OAAO,CAAC,EAAE,aAAa;IAOtG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;WAK3B,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAS3D"}
@@ -0,0 +1,71 @@
1
+ import { IDSStyles, IDSTokenVariable, IDSTokens } from './types';
2
+ export declare class TokenManager {
3
+ private tokensDir;
4
+ private manifestPath;
5
+ private variables?;
6
+ private styles?;
7
+ private loaded;
8
+ constructor(tokensDir?: string);
9
+ isLoaded(): boolean;
10
+ /** to camelCase */
11
+ private normalizeKey;
12
+ /**
13
+ * Parses variable string references like "{Line heights.h1}" and normalizes the content
14
+ */
15
+ private parseVariableString;
16
+ /**
17
+ * Creates a flat list of variable files to process from manifest collections
18
+ */
19
+ private createVariableFileList;
20
+ private parseValue;
21
+ private getTokensFromFile;
22
+ private processTokensFile;
23
+ /**
24
+ * Loads all variable files in parallel and returns processed results
25
+ */
26
+ private loadVariableFiles;
27
+ private mergeVariables;
28
+ /**
29
+ * Loads and processes all token variables from manifest collections
30
+ */
31
+ private loadTokenVariables;
32
+ /**
33
+ * Creates a flat list of style files to process from manifest styles
34
+ */
35
+ private createStyleFileList;
36
+ /**
37
+ * Loads all style files in parallel and returns results
38
+ */
39
+ private loadStyleFiles;
40
+ /**
41
+ * Loads and processes all style tokens from manifest
42
+ */
43
+ private loadStyles;
44
+ load(): Promise<void>;
45
+ /**
46
+ * Get all variables (flattened tokens from collections)
47
+ */
48
+ getVariables(): IDSTokens;
49
+ /**
50
+ * Get resolved styles
51
+ */
52
+ getStyles(): IDSStyles;
53
+ /**
54
+ * Checks if a value is a variable reference path
55
+ * @param value - Value to check
56
+ * @returns true if value is a string wrapped in curly braces like {variable.path}
57
+ */
58
+ isVariableReference(value: any): value is string;
59
+ /**
60
+ * Extracts variable path from variable reference string after checking if it's a reference
61
+ * @param value - Value to extract path from
62
+ * @returns variable path if value is a valid reference, undefined otherwise
63
+ */
64
+ getVariablePath(value: string): string;
65
+ /**
66
+ * Gets a nested token value by path, similar to lodash.get
67
+ * @param variablePath - Dot-separated string path or array of path segments
68
+ */
69
+ getToken(variablePath: string | string[]): IDSTokenVariable | undefined;
70
+ }
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/classes/TokenManager/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAER,SAAS,EACT,gBAAgB,EAChB,SAAS,EAIZ,MAAM,SAAS,CAAC;AAajB,qBAAa,YAAY;IAErB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;IAG7B,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAY;IAG3B,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,CAAC,EAAE,MAAM;IAKvB,QAAQ,IAAI,OAAO;IAI1B,mBAAmB;IACnB,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;YACW,iBAAiB;IAe/B,OAAO,CAAC,cAAc;IAItB;;OAEG;YACW,kBAAkB;IAYhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;YACW,cAAc;IAmB5B;;OAEG;YACW,UAAU;IAQX,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAalC;;OAEG;IACI,YAAY,IAAI,SAAS;IAOhC;;OAEG;IACI,SAAS,IAAI,SAAS;IAO7B;;;;OAIG;IACI,mBAAmB,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,MAAM;IAKvD;;;;OAIG;IACI,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI7C;;;OAGG;IACI,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS;CAgBjF"}
@@ -0,0 +1,25 @@
1
+ import { TFigmaToken, TFigmaTokenType } from './figma';
2
+ export type TDSTokenValue<T extends TFigmaTokenType> = Extract<TFigmaToken, {
3
+ $type: T;
4
+ }>['$value'];
5
+ export type TDSTokenValueWithModes = Record<string, TDSTokenValue<TFigmaTokenType>>;
6
+ export interface IDSTokenVariable {
7
+ type: TFigmaTokenType;
8
+ value: TDSTokenValueWithModes | TDSTokenValue<TFigmaTokenType>;
9
+ description?: string;
10
+ }
11
+ export type TDSTokenVariablesValue = Record<string, IDSTokenVariable> | IDSTokenVariable;
12
+ export interface IDSTokens {
13
+ [group: string]: TDSTokenVariablesValue | IDSTokens;
14
+ }
15
+ export interface IDSStyles {
16
+ text?: IDSTokens;
17
+ effect?: IDSTokens;
18
+ color?: IDSTokens;
19
+ grid?: IDSTokens;
20
+ }
21
+ export interface IDSTokenFile {
22
+ variables: IDSTokens;
23
+ styles: IDSStyles;
24
+ }
25
+ //# sourceMappingURL=ds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ds.d.ts","sourceRoot":"","sources":["../../../../src/classes/TokenManager/types/ds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE5D,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;AACpG,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;AAEpF,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,sBAAsB,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;AACzF,MAAM,WAAW,SAAS;IACtB,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAAC;CACvD;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;CACrB"}
@@ -0,0 +1,82 @@
1
+ export type TFigmaTokenType = 'color' | 'dimension' | 'typography' | 'shadow' | 'grid' | 'string';
2
+ export interface IBaseFigmaToken {
3
+ $type: TFigmaTokenType;
4
+ $value: unknown;
5
+ $description?: string;
6
+ }
7
+ export interface IColorFigmaToken extends IBaseFigmaToken {
8
+ $type: 'color';
9
+ $value: string;
10
+ }
11
+ export interface IDimensionFigmaToken extends IBaseFigmaToken {
12
+ $type: 'dimension';
13
+ $value: string;
14
+ }
15
+ export interface IStringFigmaToken extends IBaseFigmaToken {
16
+ $type: 'string';
17
+ $value: string;
18
+ }
19
+ export interface ITypographyValue {
20
+ fontFamily: string;
21
+ fontSize: string;
22
+ fontWeight: number;
23
+ letterSpacing: string;
24
+ lineHeight: string;
25
+ textTransform: 'none' | 'uppercase' | 'lowercase' | 'capitalize';
26
+ textDecoration: 'none' | 'underline' | 'line-through';
27
+ }
28
+ export interface TypographyFigmaToken extends IBaseFigmaToken {
29
+ $type: 'typography';
30
+ $value: ITypographyValue;
31
+ }
32
+ export interface IShadowValue {
33
+ offsetX: string;
34
+ offsetY: string;
35
+ blur: string;
36
+ spread: string;
37
+ color: string;
38
+ inset?: boolean;
39
+ }
40
+ export interface IShadowFigmaToken extends IBaseFigmaToken {
41
+ $type: 'shadow';
42
+ $value: IShadowValue[];
43
+ }
44
+ export interface IGridValue {
45
+ pattern: 'columns' | 'rows';
46
+ visible: boolean;
47
+ alignment: 'stretch' | 'center' | 'start' | 'end';
48
+ color: string;
49
+ gutterSize: string;
50
+ count: number;
51
+ offset: string;
52
+ }
53
+ export interface IGridFigmaToken extends IBaseFigmaToken {
54
+ $type: 'grid';
55
+ $value: IGridValue[];
56
+ }
57
+ export type TFigmaTokenValue = string | ITokenFile | TFigmaToken | ITypographyValue | IShadowValue[] | IGridValue[];
58
+ export type TFigmaToken = IColorFigmaToken | IDimensionFigmaToken | TypographyFigmaToken | IShadowFigmaToken | IGridFigmaToken | IStringFigmaToken;
59
+ export interface IModeFiles {
60
+ [modeName: string]: string[];
61
+ }
62
+ export interface ICollection {
63
+ modes: IModeFiles;
64
+ }
65
+ export interface ICollections {
66
+ [collectionName: string]: ICollection;
67
+ }
68
+ export interface IFigmaStyles {
69
+ text?: string[];
70
+ effect?: string[];
71
+ color?: string[];
72
+ grid?: string[];
73
+ }
74
+ export interface IManifest {
75
+ name: string;
76
+ collections: ICollections;
77
+ styles?: IFigmaStyles;
78
+ }
79
+ export interface ITokenFile {
80
+ [key: string]: TFigmaToken | ITokenFile;
81
+ }
82
+ //# sourceMappingURL=figma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma.d.ts","sourceRoot":"","sources":["../../../../src/classes/TokenManager/types/figma.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './figma';
2
+ export * from './ds';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/classes/TokenManager/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const generate: () => Promise<void>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/generate/index.ts"],"names":[],"mappings":"AA+DA,eAAO,MAAM,QAAQ,qBAmCpB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const init: () => Promise<void>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,qBAIhB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const consoleError: (message: string) => void;
2
+ export declare const consoleWarn: (message: string) => void;
3
+ //# sourceMappingURL=console.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/common/console.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,SAA8C,CAAC;AAC3F,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,SAA6C,CAAC"}
@@ -0,0 +1,29 @@
1
+ export declare enum ExtensionEnum {
2
+ CSS = "css",
3
+ SCSS = "scss",
4
+ SASS = "sass"
5
+ }
6
+ export interface IColorComponents {
7
+ colorSpace: string;
8
+ components: [number, number, number];
9
+ alpha: number;
10
+ hex: string;
11
+ }
12
+ export interface IFigmaVariable<T = unknown> {
13
+ $type: string;
14
+ $value: T;
15
+ $extensions: {
16
+ 'com.figma.variableId': string;
17
+ 'com.figma.scopes': string[];
18
+ };
19
+ }
20
+ export interface IFigmaVariablesBase {
21
+ $extensions: {
22
+ 'com.figma.modeName': string;
23
+ };
24
+ }
25
+ export interface IFigmaVariablesMap {
26
+ [key: string]: IFigmaVariable<IColorComponents>;
27
+ }
28
+ export type IFigmaColorVariables = IFigmaVariablesBase & IFigmaVariablesMap;
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAAA,oBAAY,aAAa;IACrB,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,IAAI,SAAS;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,CAAC;IACV,WAAW,EAAE;QACT,sBAAsB,EAAE,MAAM,CAAC;QAC/B,kBAAkB,EAAE,MAAM,EAAE,CAAC;KAChC,CAAC;CACL;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE;QACT,oBAAoB,EAAE,MAAM,CAAC;KAChC,CAAC;CACL;AAED,MAAM,WAAW,kBAAkB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAAC;CACnD;AAED,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG,kBAAkB,CAAC"}
package/index.cjs ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";var _=Object.defineProperty;var ee=(s,e,r)=>e in s?_(s,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[e]=r;var b=(s,e,r)=>ee(s,typeof e!="symbol"?e+"":e,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("path"),re=require("ts-import"),P=require("node:fs"),$=require("node:fs/promises"),x=require("node:path"),O=require("lodash-es"),h=class h{static resolveReadPath(e){if(!e||!e.trim())throw new Error("File path must be a non-empty string");return x.resolve(h.baseDir,e)}static resolveWritePath(e,r){const t=x.resolve(h.baseDir,r??"");return{targetDir:t,targetPath:x.resolve(t,e)}}static handleReadError(e,r){throw e.code==="ENOENT"?new Error(`File not found: ${r}`):new Error(`Failed to read file "${r}": ${e.message??String(e)}`)}static async read(e,r="utf8"){const t=h.resolveReadPath(e);try{return await $.readFile(t,{encoding:r})}catch(o){h.handleReadError(o,t)}}static async readBuffer(e){const r=h.resolveReadPath(e);try{return await $.readFile(r)}catch(t){h.handleReadError(t,r)}}static async readJson(e){const r=h.resolveReadPath(e);try{const t=await $.readFile(r,{encoding:"utf8"});try{return JSON.parse(t)}catch(o){throw new Error(`Failed to parse JSON from "${r}": ${o.message}`)}}catch(t){h.handleReadError(t,r)}}static async write(e,r="",t={}){const{directory:o,overwrite:n=!0}=t,{targetDir:a,targetPath:i}=h.resolveWritePath(e,o);if(!n&&P.existsSync(i))throw new Error(`File ${i} already exists`);return await $.mkdir(a,{recursive:!0}),await $.writeFile(i,r,{encoding:"utf8"}),i}static async writeWithExtension(e,r,t="",o){const n=r.startsWith(".")?r:`.${r}`,a=`${e}${n}`;return h.write(a,t,o)}static exists(e){const r=h.resolveReadPath(e);return P.existsSync(r)}static async delete(e,r){const{targetPath:t}=h.resolveWritePath(e,r);P.existsSync(t)&&await $.rm(t,{force:!0})}};b(h,"baseDir",process.cwd());let m=h;const F=class F{static async create(){if(m.exists(F.configFileName))throw new Error("The file already exists");await m.write(F.configFileName,"",{overwrite:!1})}async load(){try{const e=await re.tsImport.compile(`${v.resolve(process.cwd(),F.configFileName)}`);if(!e)throw new Error;return e.default}catch(e){console.error("Cannot find module gts.config.ts",e)}}};b(F,"configFileName","gts.config.ts");let E=F;const te=s=>{const e=new URLSearchParams;return Object.keys(s).forEach(r=>{Array.isArray(s[r])?s[r].forEach(t=>e.append(`${r}[]`,t)):e.append(r,s[r])}),e},oe=(s,e=50)=>{const r=[];for(let t=0;t<s.length;t+=e)r.push(s.slice(t,t+e));return r};class M{constructor(e,r){b(this,"figmaToken");b(this,"fileId");b(this,"onTimeMeasureHandler");this.figmaToken=e,this.fileId=r}setOnTimeMeasureHandler(e){this.onTimeMeasureHandler=e}static async returnJSON(e){const r=await e.json();if(!e.ok){let t="Request failed";throw new Error(t)}return r}async performControlledRequest(e,{params:r={},timeout:t=3e4,abortController:o=new AbortController}={}){var f;if(!this.figmaToken||!this.fileId)throw new Error("Добавьте figmaToken и figmaId");const n=Object.entries(r).reduce((u,[p,w])=>typeof w<"u"?{...u,[p]:w}:u,{}),a=`https://api.figma.com/v1${e}${n&&Object.keys(n).length?`?${te(n)}`:""}`;console.log("endpoinWithParams=",a);const i=setTimeout(()=>o.abort(),t),l={"Content-Type":"application/json",...this.figmaToken&&{"X-Figma-Token":this.figmaToken}},c={method:"GET",headers:l,signal:o.signal},g=performance.now(),d=await fetch(`${a}`,c);clearTimeout(i);const y=performance.now()-g;return(f=this.onTimeMeasureHandler)==null||f.call(this,a,l,y),d}async request(e,r){var o;const t=await this.performControlledRequest(e,{...r});return(o=t.headers.get("content-type"))!=null&&o.includes("application/json")?M.returnJSON(t):t}async getComponents(){return this.request(`/files/${this.fileId}/components`)}async getStyles(){return this.request(`/files/${this.fileId}/styles`)}async getNodes(e){const r=oe(e).map(n=>this.request(`/files/${this.fileId}/nodes`,{params:{ids:n.join(",")}})),t=await Promise.all(r);return{...t[0],nodes:t.reduce((n,a)=>({...n,...a.nodes}),{})}}}class X{constructor(e){b(this,"tokensDir");b(this,"manifestPath");b(this,"variables");b(this,"styles");b(this,"loaded",!1);this.tokensDir=e||"",this.manifestPath=v.join(this.tokensDir,"manifest.json")}isLoaded(){return this.loaded&&!!this.variables&&!!this.styles}normalizeKey(e){const r=e.trim();return r&&r.replace(/[-_\s]+/g," ").split(" ").filter(t=>t.length).map((t,o)=>{const n=t.charAt(0),a=t.slice(1);return o===0?t:n.toUpperCase()+a}).join("")}parseVariableString(e){if(typeof e!="string")return e;const r=/^\{(.+)\}$/,t=e.match(r);if(t){const o=t[1].trim();return`{${this.normalizeKey(o)}}`}return e}createVariableFileList(e){return Object.entries(e).flatMap(([r,t])=>Object.entries(t.modes).flatMap(([o,n])=>n.map(a=>({fileName:a,modeName:this.normalizeKey(o.trim()),collectionName:r}))))}parseValue(e){return e&&(typeof e=="string"?this.parseVariableString(e):typeof e!="object"?e:(Array.isArray(e)&&e.map(r=>this.parseValue(r)),Object.entries(e).reduce((r,[t,o])=>({...r,[t]:this.parseValue(o)}),{})))}getTokensFromFile(e,r){return Object.entries(e).reduce((t,[o,n])=>"$type"in n&&"$value"in n?{...t,[this.normalizeKey(o)]:{type:n.$type,description:n.$description,value:r?{[this.normalizeKey(r)]:this.parseValue(n.$value)}:this.parseValue(n.$value)}}:{...t,[this.normalizeKey(o)]:this.getTokensFromFile(n,r)},{})}processTokensFile(e,r,t){const o=this.normalizeKey(t),n=this.getTokensFromFile(e,r);return{[o]:n}}async loadVariableFiles(e){return Promise.all(e.map(async({fileName:r,modeName:t,collectionName:o})=>{try{const n=v.join(this.tokensDir,r),a=await m.readJson(n);return this.processTokensFile(a,t,o)}catch(n){return console.warn(`Failed to load variable file: ${v.join(this.tokensDir,r)}`,n),{}}}))}mergeVariables(e){return e.reduce((r,t)=>O.merge(r,t),{})}async loadTokenVariables(e){try{const r=this.createVariableFileList(e),t=await this.loadVariableFiles(r);return this.mergeVariables(t)}catch(r){throw new Error(`Failed to load token variables from ${this.tokensDir}: ${r}`)}}createStyleFileList(e){return Object.entries(e).flatMap(([r,t])=>(t==null?void 0:t.map(o=>({styleType:r,fileName:o})))||[])}async loadStyleFiles(e){return(await Promise.all(e.map(async({styleType:t,fileName:o})=>{try{const n=v.join(this.tokensDir,o),a=await m.readJson(n);return{styleType:t,styleTokens:a}}catch(n){return console.warn(`Failed to load style file: ${v.join(this.tokensDir,o)}`,n),{styleType:t,styleTokens:{}}}}))).reduce((t,o)=>({...t,[o.styleType]:this.getTokensFromFile(o.styleTokens,"")}),{})}async loadStyles(e){if(!e)return{};const r=this.createStyleFileList(e);return await this.loadStyleFiles(r)}async load(){if(this.loaded)return;const e=await m.readJson(this.manifestPath);if(!e)throw new Error(`Failed to load manifest file from: ${this.manifestPath}`);this.variables=await this.loadTokenVariables(e.collections),this.styles=await this.loadStyles(e.styles),this.loaded=!0}getVariables(){if(!this.loaded||!this.variables)throw new Error("Tokens not loaded. Call load() first.");return this.variables}getStyles(){if(!this.loaded||!this.styles)throw new Error("Tokens not loaded. Call load() first.");return this.styles}isVariableReference(e){return typeof e!="string"?!1:/^\{.+\}$/.test(e)}getVariablePath(e){return e.slice(1,-1)}getToken(e){if(!this.loaded||!this.variables)throw new Error("Tokens not loaded. Call load() first.");const r=O.get(this.variables,e);if(r&&typeof r=="object")return r;for(const[,t]of Object.entries(this.variables)){const o=O.get(t,e);if(o!=null&&o.value)return o}}}const se=async()=>{const e=await new E().load();if(!e)throw new Error("Заполнить ошибку через нейронку");const{figmaToken:r,fileId:t,modules:o,manifest:n}=e,a=new M(r,t),i=new X(n);n&&m.exists(n)&&await i.load(),await Promise.all(o.map(l=>l.executor({figmaApiClient:a,tokenManagerClient:i})))},ne=async()=>{await E.create(),console.log("\x1B[32m%s\x1B[0m","✔️ Configuration file created gts.config.ts")},ae=({r:s,g:e,b:r})=>{const t=o=>`0${o.toString(16)}`.slice(-2);return`#${t(s)}${t(e)}${t(r)}`},j=({opacity:s,r:e,g:r,b:t})=>{const o=[e,r,t].map(n=>Math.round(n*255));return s<1?`rgba(${o[0]}, ${o[1]}, ${o[2]}, ${s})`:ae({r:o[0],g:o[1],b:o[2]})},Y=(s,e=0)=>{const r=Math.atan2(s[1].y-s[0].y,s[1].x-s[0].x);return Math.round(r*180/Math.PI)+e},R=s=>s.reduce((e,r)=>{const t=Number((r.position*100).toFixed(1));return[...e,`${j({opacity:r.color.a,r:r.color.r,g:r.color.g,b:r.color.b})}${t>0&&t<100?` ${t}%`:""}`]},[]).join(", "),K=s=>{const e=s[0].x,r=s[0].y,t=(e*100).toFixed(2),o=(r*100).toFixed(2);return{centerX:t,centerY:o}},ie=s=>{const{gradientHandlePositions:e,gradientStops:r}=s,t=Y(e,90),o=R(r);return`linear-gradient(${t}deg, ${o})`},le=s=>{const e=s[0].x,r=s[0].y,t=s[1].x,o=s[1].y,n=s[2].x,a=s[2].y,i=(Math.sqrt((n-e)**2+(a-r)**2)*100).toFixed(2),l=(Math.sqrt((t-e)**2+(o-r)**2)*100).toFixed(2);return{radiusX:i,radiusY:l}},ce=s=>{const{gradientHandlePositions:e,gradientStops:r}=s,{centerX:t,centerY:o}=K(e),{radiusX:n,radiusY:a}=le(e),i=R(r);return`radial-gradient(${n}% ${a}% at ${t}% ${o}%, ${i})`},de=s=>{const{gradientHandlePositions:e,gradientStops:r}=s,t=Y(e,30),{centerX:o,centerY:n}=K(e),a=R(r);return`conic-gradient(from ${t}deg at ${o}% ${n}%, ${a})`},ue=s=>{const e=s.type;return e==="SOLID"?j({opacity:s.color.a,r:s.color.r,g:s.color.g,b:s.color.b}):e==="GRADIENT_LINEAR"?ie(s):e==="GRADIENT_RADIAL"?ce(s):e==="GRADIENT_ANGULAR"?de(s):""},B=(s,e)=>{if(!e.length)return"";const r=e.map(t=>` ${t}`).join(`
2
+ `);return`${s} {
3
+ ${r}
4
+ }`},ge=s=>`.${s.replace(/\s+/g,"-").toLowerCase()}`,fe=s=>s.replaceAll(/ /g,"").split("/").at(-1),he=s=>`--${s}`,me=s=>s.reduce((e,r)=>{const t=he(r.name);return typeof r.value=="object"?Object.entries(r.value).forEach(([o,n])=>{e[o]||(e[o]=[]),e[o].push(`${t}: ${n};`)}):e.root.push(`${t}: ${r.value};`),e},{root:[]}),ye=s=>{const e=B(":root",s.root),r=Object.entries(s).reduce((t,[o,n])=>{if(o==="root"||!n.length)return t;const a=B(ge(o),n);return a&&t.push(a),t},[]).join(`
5
+
6
+ `);return[e,r].filter(Boolean).join(`
7
+
8
+ `)},be=s=>{const e=s.reduce((r,t)=>({...r,[t.name]:t.value}),{});return JSON.stringify(e)},pe=async(s,e,r,t,o,n)=>{await Promise.all([m.delete(o,r),m.delete(n,t)]);const a=m.write(o,s,{directory:r}),i=m.write(n,e,{directory:t});await Promise.all([a,i])},N=async({colorTokens:s,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:o})=>{const n=me(s),a=ye(n),i=be(s);await pe(i,a,e,r,t,o)},we=({input:s,output:{jsonDir:e,stylesDir:r,jsonFileName:t="colors.json",cssFileName:o="colors.css"}})=>({name:"styles/colors",executor:async({figmaApiClient:n})=>{try{console.log("[styles/colors] Fetching styles from Figma...");const i=(await n.getStyles()).meta.styles,l=(s==null?void 0:s.variablePaths)||[],c=i.filter(u=>u.style_type==="FILL");if(console.log(`[styles/colors] Found ${c.length} color styles`),c.length===0){console.warn("[styles/colors] No color styles found in Figma file");return}console.log(`[styles/colors] Fetching ${c.length} color nodes from Figma...`);const g=await n.getNodes(c.map(u=>u.node_id)),d=Object.entries(g.nodes);let y=[];if(l.length>1){console.log(`[styles/colors] Reading ${l.length} variable files...`);try{y=await Promise.all(l.map(async u=>{try{return await m.readJson(u)}catch(p){throw console.error(`[styles/colors] Failed to read variable file: ${u}`,p),p}}))}catch(u){throw console.error("[styles/colors] Error reading variable files:",u),new Error(`Failed to read variable files: ${u.message}`)}}console.log(`[styles/colors] Processing ${d.length} color nodes...`);const f=d.reduce((u,[,p])=>{var w,C,I;try{const{document:k}=p,A=fe(k.name);if(k.type!=="RECTANGLE")return u;const S=(w=k.fills)==null?void 0:w[0];if(!S)return u;if(S.type==="SOLID"&&y.length>1){const D=(I=(C=S.boundVariables)==null?void 0:C.color)==null?void 0:I.id;if(D){const q=y.reduce((G,J)=>{var z;const W=(z=Object.entries(J).find(([,T])=>T.$extensions["com.figma.variableId"]===D))==null?void 0:z[1];if(W){const{components:T,alpha:Q}=W.$value,Z=j({opacity:Q,r:T[0],g:T[1],b:T[2]});return{...G,[J.$extensions["com.figma.modeName"]]:Z}}return G},{});if(Object.keys(q).length>1)return[...u,{name:A,value:q}]}}const L=ue(S);return L?[...u,{name:A,value:L}]:u}catch(k){return console.warn("[styles/colors] Error processing color node:",k),u}},[]);if(console.log(`[styles/colors] Generated ${f.length} color tokens`),f.length===0){console.warn("[styles/colors] No color tokens generated. Check your Figma styles configuration.");return}console.log(`[styles/colors] Writing files to ${e} and ${r}...`),await N({colorTokens:f,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:o}),console.log("[styles/colors] ✅ Successfully generated color files")}catch(a){const i=a instanceof Error?a.message:String(a);throw console.error("[styles/colors] ❌ Failed to generate colors from styles:",i),a instanceof Error&&a.stack&&console.error("[styles/colors] Stack trace:",a.stack),a}}}),$e=({input:{variablePaths:s},output:{jsonDir:e,stylesDir:r,jsonFileName:t="colors.json",cssFileName:o="colors.css"}})=>({name:"variables/colors",executor:async()=>{try{if(!s.length)throw new Error("At least one variable file path is required");console.log(`[variables/colors] Reading ${s.length} variable files...`);const n=await Promise.all(s.map(async l=>{try{return console.log(`[variables/colors] Reading file: ${l}`),await m.readJson(l)}catch(c){throw console.error(`[variables/colors] Failed to read variable file: ${l}`,c),new Error(`Failed to read variable file "${l}": ${c.message}`)}}));console.log(`[variables/colors] Processing ${n.length} variable files...`);const a=new Map;n.forEach((l,c)=>{try{if(!l.$extensions||!l.$extensions["com.figma.modeName"]){console.warn(`[variables/colors] File ${s[c]} is missing modeName in extensions`);return}const g=l.$extensions["com.figma.modeName"];Object.entries(l).forEach(([d,y])=>{if(d!=="$extensions")try{const f=y;if(!f||f.$type!=="color")return;if(!f.$value||!f.$value.components){console.warn(`[variables/colors] Variable "${d}" in mode "${g}" has invalid structure`);return}const{components:u,alpha:p}=f.$value,w=j({opacity:p??1,r:u[0],g:u[1],b:u[2]});a.has(d)||a.set(d,{}),a.get(d)[g]=w}catch(f){console.warn(`[variables/colors] Error processing variable "${d}" in mode "${g}":`,f)}})}catch(g){console.error(`[variables/colors] Error processing file ${s[c]}:`,g)}});const i=Array.from(a.entries()).map(([l,c])=>({name:l,value:Object.keys(c).length>1?c:Object.values(c)[0]}));if(console.log(`[variables/colors] Generated ${i.length} color tokens`),i.length===0){console.warn("[variables/colors] No color tokens generated. Check your variable files structure.");return}console.log(`[variables/colors] Writing files to ${e} and ${r}...`),await N({colorTokens:i,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:o}),console.log("[variables/colors] ✅ Successfully generated color files")}catch(n){const a=n instanceof Error?n.message:String(n);throw console.error("[variables/colors] ❌ Failed to generate colors from variables:",a),n instanceof Error&&n.stack&&console.error("[variables/colors] Stack trace:",n.stack),n}}}),U=(s,e)=>Object.keys(s).reduce((r,t)=>{const o=s[t],n=e?`${e}-${t}`:t;if(o&&typeof o=="object"&&"type"in o&&"value"in o){const i=Object.keys(o.value),l=i.length>1?o.value:o.value[i[0]],c={[n]:l};return{...r,...c}}const a=U(o,n);return{...r,...a}},{}),ve=s=>`cl-${s}`,V=(s,e,r)=>{const{type:t,value:o}=s;if(t!=="color")return;if(typeof o=="string"){if(!e.isVariableReference(o))return{...s,value:o};const i=e.getToken(e.getVariablePath(o)),l=i?V(i,e,r):void 0;return l!=null&&l.value?{...s,...i}:void 0}const a=Object.keys(o).reduce((i,l)=>{if(r&&l!==r)return i;const c=o[l];if(typeof c!="string")return i;if(!e.isVariableReference(c))return{...i,[l]:c};const g=e.getToken(e.getVariablePath(c)),d=g?V(g,e,l):void 0;return d!=null&&d.value?{...i,...d.value}:i},{});if(Object.keys(a).length)return{...s,value:a}},H=(s,e)=>Object.keys(s).reduce((r,t)=>{const o=s[t];if(o.type&&o.value){const a=V(o,e);return a?{...r,[t]:a}:r}const n=H(o,e);return n?{...r,[t]:n}:r},{}),Fe=({input:s={},output:{jsonDir:e,stylesDir:r,jsonFileName:t="colors.json",cssFileName:o="colors.css"}})=>({name:"colors/tokenManager",executor:async({tokenManagerClient:n})=>{try{console.log("[colors/tokenManager] Generating colors from TokenManager...");const{includeVariables:a,includeStyles:i=!0}=s;if(!(a!=null&&a.length)&&!i)throw new Error("Either includeVariables or includeStyles must be enabled");if(!n.isLoaded())throw new Error("TokenManager is not loaded. Tokens must be loaded before using this module.");const l=[],c=n.getVariables();if(i){const d=n.getStyles();console.log("[colors/tokenManager] Processing styles for colors..."),d.color&&l.push(d.color)}if(a!=null&&a.length){console.log(`[colors/tokenManager] Processing ${a.length} variable groups...`);const d=a.map(y=>c[y]).filter(Boolean);l.push(...d)}const g=l.map(d=>H(d,n)).flatMap(d=>Object.entries(U(d,"")).reduce((y,[f,u])=>[...y,{name:ve(f),value:u}],[]));if(g.length===0){console.warn("[colors/tokenManager] No color tokens generated");return}console.log(`[colors/tokenManager] Generated ${g.length} color tokens`),console.log(`[colors/tokenManager] Writing files to ${e} and ${r}...`),await N({colorTokens:g,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:o}),console.log("[colors/tokenManager] ✅ Successfully generated color files")}catch(a){const i=a instanceof Error?a.message:String(a);throw console.error("[colors/tokenManager] ❌ Failed to generate colors:",i),a instanceof Error&&a.stack&&console.error("[colors/tokenManager] Stack trace:",a.stack),a}}});exports.TokenManager=X;exports.colorsFromStyles=we;exports.colorsFromTokenManager=Fe;exports.colorsFromVariables=$e;exports.generate=se;exports.init=ne;
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { generate } from './commands/generate';
2
+ export { init } from './commands/init';
3
+ export { TokenManager } from './classes/TokenManager';
4
+ export type { IGtsConfig } from './classes/Config';
5
+ export * from './modules';
6
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,cAAc,WAAW,CAAC"}