@seed-design/figma 0.0.0-alpha-20260324091316

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 (181) hide show
  1. package/lib/codegen/index.cjs +23543 -0
  2. package/lib/codegen/index.d.ts +2957 -0
  3. package/lib/codegen/index.d.ts.map +1 -0
  4. package/lib/codegen/index.js +23514 -0
  5. package/lib/codegen/targets/react/index.cjs +31980 -0
  6. package/lib/codegen/targets/react/index.d.ts +308 -0
  7. package/lib/codegen/targets/react/index.d.ts.map +1 -0
  8. package/lib/codegen/targets/react/index.js +31961 -0
  9. package/lib/index.cjs +26905 -0
  10. package/lib/index.d.ts +221 -0
  11. package/lib/index.d.ts.map +1 -0
  12. package/lib/index.js +26884 -0
  13. package/package.json +56 -0
  14. package/src/codegen/component-properties.archive.ts +1019 -0
  15. package/src/codegen/component-properties.ts +369 -0
  16. package/src/codegen/core/codegen.ts +112 -0
  17. package/src/codegen/core/component-handler.ts +23 -0
  18. package/src/codegen/core/component-type-helper.ts +35 -0
  19. package/src/codegen/core/element-transformer.ts +13 -0
  20. package/src/codegen/core/index.ts +19 -0
  21. package/src/codegen/core/infer-layout.test.ts +286 -0
  22. package/src/codegen/core/infer-layout.ts +416 -0
  23. package/src/codegen/core/jsx.ts +174 -0
  24. package/src/codegen/core/props-converter.ts +78 -0
  25. package/src/codegen/core/value-resolver.ts +381 -0
  26. package/src/codegen/default-services.ts +44 -0
  27. package/src/codegen/index.ts +3 -0
  28. package/src/codegen/skip-components.ts +7 -0
  29. package/src/codegen/targets/figma/frame.ts +38 -0
  30. package/src/codegen/targets/figma/index.ts +6 -0
  31. package/src/codegen/targets/figma/instance.ts +36 -0
  32. package/src/codegen/targets/figma/pipeline.ts +106 -0
  33. package/src/codegen/targets/figma/props.ts +262 -0
  34. package/src/codegen/targets/figma/shape.ts +65 -0
  35. package/src/codegen/targets/figma/text.ts +30 -0
  36. package/src/codegen/targets/figma/value-resolver.ts +75 -0
  37. package/src/codegen/targets/index.ts +2 -0
  38. package/src/codegen/targets/react/component/deps.interface.ts +7 -0
  39. package/src/codegen/targets/react/component/handlers/action-button.ts +149 -0
  40. package/src/codegen/targets/react/component/handlers/alert-dialog.ts +120 -0
  41. package/src/codegen/targets/react/component/handlers/app-bar.ts +169 -0
  42. package/src/codegen/targets/react/component/handlers/archive/action-button.ts +144 -0
  43. package/src/codegen/targets/react/component/handlers/archive/alert-dialog.ts +122 -0
  44. package/src/codegen/targets/react/component/handlers/archive/app-bar.ts +149 -0
  45. package/src/codegen/targets/react/component/handlers/archive/avatar-stack.ts +35 -0
  46. package/src/codegen/targets/react/component/handlers/archive/avatar.ts +55 -0
  47. package/src/codegen/targets/react/component/handlers/archive/badge.ts +18 -0
  48. package/src/codegen/targets/react/component/handlers/archive/bottom-sheet.ts +70 -0
  49. package/src/codegen/targets/react/component/handlers/archive/callout.ts +88 -0
  50. package/src/codegen/targets/react/component/handlers/archive/checkbox.ts +43 -0
  51. package/src/codegen/targets/react/component/handlers/archive/checkmark.ts +29 -0
  52. package/src/codegen/targets/react/component/handlers/archive/chip.ts +90 -0
  53. package/src/codegen/targets/react/component/handlers/archive/contextual-floating-button.ts +52 -0
  54. package/src/codegen/targets/react/component/handlers/archive/divider.ts +25 -0
  55. package/src/codegen/targets/react/component/handlers/archive/field-button.ts +197 -0
  56. package/src/codegen/targets/react/component/handlers/archive/field.ts +167 -0
  57. package/src/codegen/targets/react/component/handlers/archive/floating-action-button.ts +48 -0
  58. package/src/codegen/targets/react/component/handlers/archive/help-bubble.ts +73 -0
  59. package/src/codegen/targets/react/component/handlers/archive/identity-placeholder.ts +21 -0
  60. package/src/codegen/targets/react/component/handlers/archive/index.ts +40 -0
  61. package/src/codegen/targets/react/component/handlers/archive/legacy-select-box.ts +89 -0
  62. package/src/codegen/targets/react/component/handlers/archive/legacy-text-field.ts +198 -0
  63. package/src/codegen/targets/react/component/handlers/archive/list-header.ts +20 -0
  64. package/src/codegen/targets/react/component/handlers/archive/list-item.ts +162 -0
  65. package/src/codegen/targets/react/component/handlers/archive/manner-temp-badge.ts +21 -0
  66. package/src/codegen/targets/react/component/handlers/archive/manner-temp.ts +18 -0
  67. package/src/codegen/targets/react/component/handlers/archive/menu-sheet.ts +108 -0
  68. package/src/codegen/targets/react/component/handlers/archive/page-banner.ts +101 -0
  69. package/src/codegen/targets/react/component/handlers/archive/progress-circle.ts +55 -0
  70. package/src/codegen/targets/react/component/handlers/archive/radio-group.ts +31 -0
  71. package/src/codegen/targets/react/component/handlers/archive/radiomark.ts +27 -0
  72. package/src/codegen/targets/react/component/handlers/archive/reaction-button.ts +37 -0
  73. package/src/codegen/targets/react/component/handlers/archive/result-section.ts +67 -0
  74. package/src/codegen/targets/react/component/handlers/archive/segmented-control.ts +64 -0
  75. package/src/codegen/targets/react/component/handlers/archive/skeleton.ts +26 -0
  76. package/src/codegen/targets/react/component/handlers/archive/slider.ts +114 -0
  77. package/src/codegen/targets/react/component/handlers/archive/snackbar.ts +25 -0
  78. package/src/codegen/targets/react/component/handlers/archive/switch.ts +39 -0
  79. package/src/codegen/targets/react/component/handlers/archive/switchmark.ts +26 -0
  80. package/src/codegen/targets/react/component/handlers/archive/tabs.ts +297 -0
  81. package/src/codegen/targets/react/component/handlers/archive/tag-group.ts +86 -0
  82. package/src/codegen/targets/react/component/handlers/archive/text-field.ts +264 -0
  83. package/src/codegen/targets/react/component/handlers/archive/toggle-button.ts +43 -0
  84. package/src/codegen/targets/react/component/handlers/avatar-stack.ts +38 -0
  85. package/src/codegen/targets/react/component/handlers/avatar.ts +58 -0
  86. package/src/codegen/targets/react/component/handlers/badge.ts +18 -0
  87. package/src/codegen/targets/react/component/handlers/bottom-sheet.ts +74 -0
  88. package/src/codegen/targets/react/component/handlers/callout.ts +88 -0
  89. package/src/codegen/targets/react/component/handlers/checkbox.ts +129 -0
  90. package/src/codegen/targets/react/component/handlers/checkmark.ts +29 -0
  91. package/src/codegen/targets/react/component/handlers/chip.ts +93 -0
  92. package/src/codegen/targets/react/component/handlers/content-placeholder.ts +20 -0
  93. package/src/codegen/targets/react/component/handlers/contextual-floating-button.ts +52 -0
  94. package/src/codegen/targets/react/component/handlers/divider.ts +25 -0
  95. package/src/codegen/targets/react/component/handlers/field-button.ts +192 -0
  96. package/src/codegen/targets/react/component/handlers/field.ts +164 -0
  97. package/src/codegen/targets/react/component/handlers/floating-action-button.ts +45 -0
  98. package/src/codegen/targets/react/component/handlers/help-bubble.ts +73 -0
  99. package/src/codegen/targets/react/component/handlers/identity-placeholder.ts +20 -0
  100. package/src/codegen/targets/react/component/handlers/image-frame.ts +147 -0
  101. package/src/codegen/targets/react/component/handlers/index.ts +43 -0
  102. package/src/codegen/targets/react/component/handlers/legacy-select-box.ts +87 -0
  103. package/src/codegen/targets/react/component/handlers/legacy-text-field.ts +196 -0
  104. package/src/codegen/targets/react/component/handlers/list-header.ts +20 -0
  105. package/src/codegen/targets/react/component/handlers/list-item.ts +163 -0
  106. package/src/codegen/targets/react/component/handlers/manner-temp-badge.ts +21 -0
  107. package/src/codegen/targets/react/component/handlers/manner-temp.ts +18 -0
  108. package/src/codegen/targets/react/component/handlers/menu-sheet.ts +111 -0
  109. package/src/codegen/targets/react/component/handlers/page-banner.ts +106 -0
  110. package/src/codegen/targets/react/component/handlers/progress-circle.ts +55 -0
  111. package/src/codegen/targets/react/component/handlers/radio-group.ts +109 -0
  112. package/src/codegen/targets/react/component/handlers/radiomark.ts +27 -0
  113. package/src/codegen/targets/react/component/handlers/reaction-button.ts +37 -0
  114. package/src/codegen/targets/react/component/handlers/result-section.ts +67 -0
  115. package/src/codegen/targets/react/component/handlers/segmented-control.ts +63 -0
  116. package/src/codegen/targets/react/component/handlers/select-box.ts +333 -0
  117. package/src/codegen/targets/react/component/handlers/skeleton.ts +26 -0
  118. package/src/codegen/targets/react/component/handlers/slider.ts +117 -0
  119. package/src/codegen/targets/react/component/handlers/snackbar.ts +25 -0
  120. package/src/codegen/targets/react/component/handlers/switch.ts +35 -0
  121. package/src/codegen/targets/react/component/handlers/switchmark.ts +26 -0
  122. package/src/codegen/targets/react/component/handlers/tabs.ts +298 -0
  123. package/src/codegen/targets/react/component/handlers/tag-group.ts +90 -0
  124. package/src/codegen/targets/react/component/handlers/text-field.ts +253 -0
  125. package/src/codegen/targets/react/component/handlers/toggle-button.ts +43 -0
  126. package/src/codegen/targets/react/component/index.ts +24 -0
  127. package/src/codegen/targets/react/component/size.ts +22 -0
  128. package/src/codegen/targets/react/element-factories.ts +59 -0
  129. package/src/codegen/targets/react/frame.ts +96 -0
  130. package/src/codegen/targets/react/icon.ts +55 -0
  131. package/src/codegen/targets/react/index.ts +7 -0
  132. package/src/codegen/targets/react/instance.ts +82 -0
  133. package/src/codegen/targets/react/pipeline.ts +133 -0
  134. package/src/codegen/targets/react/props.ts +417 -0
  135. package/src/codegen/targets/react/shape.ts +47 -0
  136. package/src/codegen/targets/react/text.ts +31 -0
  137. package/src/codegen/targets/react/value-resolver.ts +93 -0
  138. package/src/entities/component.interface.ts +7 -0
  139. package/src/entities/component.repository.ts +16 -0
  140. package/src/entities/data/__generated__/archive/component-sets/index.d.ts +2074 -0
  141. package/src/entities/data/__generated__/archive/component-sets/index.mjs +2074 -0
  142. package/src/entities/data/__generated__/archive/components/index.d.ts +116 -0
  143. package/src/entities/data/__generated__/archive/components/index.mjs +116 -0
  144. package/src/entities/data/__generated__/archive/styles/index.d.ts +3 -0
  145. package/src/entities/data/__generated__/archive/styles/index.mjs +429 -0
  146. package/src/entities/data/__generated__/archive/variable-collections/index.d.ts +3 -0
  147. package/src/entities/data/__generated__/archive/variable-collections/index.mjs +501 -0
  148. package/src/entities/data/__generated__/archive/variables/index.d.ts +3 -0
  149. package/src/entities/data/__generated__/archive/variables/index.mjs +7019 -0
  150. package/src/entities/data/__generated__/component-sets/index.d.ts +4325 -0
  151. package/src/entities/data/__generated__/component-sets/index.mjs +4325 -0
  152. package/src/entities/data/__generated__/components/index.d.ts +378 -0
  153. package/src/entities/data/__generated__/components/index.mjs +378 -0
  154. package/src/entities/data/__generated__/icons/index.d.ts +3 -0
  155. package/src/entities/data/__generated__/icons/index.mjs +3476 -0
  156. package/src/entities/data/__generated__/styles/index.d.ts +3 -0
  157. package/src/entities/data/__generated__/styles/index.mjs +436 -0
  158. package/src/entities/data/__generated__/variable-collections/index.d.ts +3 -0
  159. package/src/entities/data/__generated__/variable-collections/index.mjs +479 -0
  160. package/src/entities/data/__generated__/variables/index.d.ts +3 -0
  161. package/src/entities/data/__generated__/variables/index.mjs +6969 -0
  162. package/src/entities/icon.interface.ts +5 -0
  163. package/src/entities/icon.repository.ts +11 -0
  164. package/src/entities/icon.service.ts +26 -0
  165. package/src/entities/index.ts +60 -0
  166. package/src/entities/style.interface.ts +5 -0
  167. package/src/entities/style.repository.ts +27 -0
  168. package/src/entities/style.service.ts +36 -0
  169. package/src/entities/variable.interface.ts +18 -0
  170. package/src/entities/variable.repository.ts +57 -0
  171. package/src/entities/variable.service.ts +101 -0
  172. package/src/index.ts +3 -0
  173. package/src/normalizer/from-plugin.ts +602 -0
  174. package/src/normalizer/from-rest.ts +577 -0
  175. package/src/normalizer/index.ts +3 -0
  176. package/src/normalizer/types.ts +208 -0
  177. package/src/utils/common.ts +38 -0
  178. package/src/utils/css.ts +19 -0
  179. package/src/utils/figma-gradient.ts +72 -0
  180. package/src/utils/figma-node.ts +95 -0
  181. package/src/utils/figma-variable.ts +49 -0
@@ -0,0 +1,5 @@
1
+ export interface IconData {
2
+ name: string;
3
+ type: "monochrome" | "multicolor";
4
+ weight?: string;
5
+ }
@@ -0,0 +1,11 @@
1
+ import type { IconData } from "./icon.interface";
2
+
3
+ export interface IconRepository {
4
+ getOne(key: string): IconData;
5
+ }
6
+
7
+ export function createStaticIconRepository(iconRecord: Record<string, IconData>) {
8
+ return {
9
+ getOne: (key: string) => iconRecord[key],
10
+ };
11
+ }
@@ -0,0 +1,26 @@
1
+ import type { IconData } from "./icon.interface";
2
+ import type { IconRepository } from "./icon.repository";
3
+
4
+ export interface IconService {
5
+ isAvailable: (componentKey: string) => boolean;
6
+ getOne: (componentKey: string) => IconData;
7
+ }
8
+
9
+ export function createIconService({
10
+ iconRepository,
11
+ }: {
12
+ iconRepository: IconRepository;
13
+ }): IconService {
14
+ function isAvailable(componentKey: string) {
15
+ return iconRepository.getOne(componentKey) !== undefined;
16
+ }
17
+
18
+ function getOne(componentKey: string) {
19
+ return iconRepository.getOne(componentKey);
20
+ }
21
+
22
+ return {
23
+ isAvailable,
24
+ getOne,
25
+ };
26
+ }
@@ -0,0 +1,60 @@
1
+ import { createStaticIconRepository } from "./icon.repository";
2
+ import { createStaticStyleRepository } from "./style.repository";
3
+ import { createStaticVariableRepository } from "./variable.repository";
4
+ import { createStaticComponentRepository } from "./component.repository";
5
+ import { FIGMA_ICONS } from "./data/__generated__/icons";
6
+
7
+ // Archive
8
+ import { FIGMA_STYLES as FIGMA_STYLES_ARCHIVE } from "./data/__generated__/archive/styles";
9
+ import { FIGMA_VARIABLE_COLLECTIONS as FIGMA_VARIABLE_COLLECTIONS_ARCHIVE } from "./data/__generated__/archive/variable-collections";
10
+ import { FIGMA_VARIABLES as FIGMA_VARIABLES_ARCHIVE } from "./data/__generated__/archive/variables";
11
+ import * as FIGMA_COMPONENTS_ARCHIVE from "./data/__generated__/archive/component-sets";
12
+
13
+ // Current
14
+ import { FIGMA_STYLES } from "./data/__generated__/styles";
15
+ import { FIGMA_VARIABLE_COLLECTIONS } from "./data/__generated__/variable-collections";
16
+ import { FIGMA_VARIABLES } from "./data/__generated__/variables";
17
+ import * as FIGMA_COMPONENTS from "./data/__generated__/component-sets";
18
+
19
+ export * from "./icon.interface";
20
+ export * from "./icon.repository";
21
+ export * from "./icon.service";
22
+ export * from "./style.interface";
23
+ export * from "./style.repository";
24
+ export * from "./style.service";
25
+ export * from "./variable.interface";
26
+ export * from "./variable.repository";
27
+ export * from "./variable.service";
28
+ export * from "./component.interface";
29
+ export * from "./component.repository";
30
+
31
+ export const styleRepository = createStaticStyleRepository([
32
+ ...FIGMA_STYLES_ARCHIVE,
33
+ ...FIGMA_STYLES,
34
+ ]);
35
+ export const variableRepository = createStaticVariableRepository({
36
+ variables: { ...FIGMA_VARIABLES_ARCHIVE, ...FIGMA_VARIABLES },
37
+ variableCollections: { ...FIGMA_VARIABLE_COLLECTIONS_ARCHIVE, ...FIGMA_VARIABLE_COLLECTIONS },
38
+ });
39
+ export const iconRepository = createStaticIconRepository(FIGMA_ICONS);
40
+ export const componentRepository = createStaticComponentRepository({
41
+ ...FIGMA_COMPONENTS_ARCHIVE,
42
+ ...FIGMA_COMPONENTS,
43
+ });
44
+
45
+ export function getFigmaVariableKey(name: string) {
46
+ return variableRepository.findVariableByName(name)?.key;
47
+ }
48
+
49
+ export function getFigmaStyleKey(name: string) {
50
+ return styleRepository.findOneByName(name)?.key;
51
+ }
52
+
53
+ export function getFigmaColorVariableNames(scopes: Array<"fg" | "bg" | "stroke" | "palette">) {
54
+ const variables = variableRepository.getVariableList();
55
+ return variables
56
+ .filter((variable) =>
57
+ scopes.includes(variable.name.split("/")[0] as "fg" | "bg" | "stroke" | "palette"),
58
+ )
59
+ .map((variable) => variable.name);
60
+ }
@@ -0,0 +1,5 @@
1
+ import type { Style as FigmaStyle, StyleType as FigmaStyleType } from "@figma/rest-api-spec";
2
+
3
+ export type Style = FigmaStyle;
4
+
5
+ export type StyleType = FigmaStyleType;
@@ -0,0 +1,27 @@
1
+ import type { Style } from "./style.interface";
2
+
3
+ export interface StyleRepository {
4
+ getAll(): Style[];
5
+ getTextStyles(): Style[];
6
+ getColorStyles(): Style[];
7
+ findOneByKey(key: string): Style | undefined;
8
+ findOneByName(name: string): Style | undefined;
9
+ }
10
+
11
+ export function createStaticStyleRepository(styles: Style[]): StyleRepository {
12
+ const stylesMap = new Map<string, Style>();
13
+ const stylesNameMap = new Map<string, Style>();
14
+
15
+ for (const style of styles) {
16
+ stylesMap.set(style.key, style);
17
+ stylesNameMap.set(style.name, style);
18
+ }
19
+
20
+ return {
21
+ getAll: () => styles,
22
+ getTextStyles: () => styles.filter((style) => style.styleType === "TEXT"),
23
+ getColorStyles: () => styles.filter((style) => style.styleType === "FILL"),
24
+ findOneByKey: (key) => stylesMap.get(key),
25
+ findOneByName: (name) => stylesNameMap.get(name),
26
+ };
27
+ }
@@ -0,0 +1,36 @@
1
+ import type { StyleRepository } from "./style.repository";
2
+
3
+ export interface StyleService {
4
+ getSlug: (id: string) => string[] | undefined;
5
+ }
6
+
7
+ // TODO: inferStyleName 추가해야 함, rest api에서 style value가 제공되지 않고 있어 보류
8
+ export function createStyleService({
9
+ styleRepository,
10
+ }: {
11
+ styleRepository: StyleRepository;
12
+ }): StyleService {
13
+ function getName(id: string) {
14
+ const style = styleRepository.findOneByKey(id);
15
+
16
+ if (!style) {
17
+ return undefined;
18
+ }
19
+
20
+ return style.name;
21
+ }
22
+
23
+ function getSlug(id: string): string[] | undefined {
24
+ const name = getName(id);
25
+
26
+ if (!name) {
27
+ return undefined;
28
+ }
29
+
30
+ return name.split("/");
31
+ }
32
+
33
+ return {
34
+ getSlug,
35
+ };
36
+ }
@@ -0,0 +1,18 @@
1
+ import type {
2
+ LocalVariable,
3
+ LocalVariableCollection,
4
+ VariableAlias,
5
+ VariableResolvedDataType,
6
+ } from "@figma/rest-api-spec";
7
+
8
+ export type Variable = LocalVariable;
9
+
10
+ export type VariableCollection = LocalVariableCollection;
11
+
12
+ export type VariableType = VariableResolvedDataType;
13
+
14
+ export type VariableValue = Variable["valuesByMode"][string];
15
+
16
+ export type VariableValueResolved = Exclude<VariableValue, VariableAlias>;
17
+
18
+ export type { VariableScope } from "@figma/rest-api-spec";
@@ -0,0 +1,57 @@
1
+ import type { Variable, VariableCollection } from "./variable.interface";
2
+
3
+ export interface VariableRepository {
4
+ getVariableList(): Variable[];
5
+ getVariableCollectionList(): VariableCollection[];
6
+ findVariableByKey(key: string): Variable | undefined;
7
+ findVariableById(id: string): Variable | undefined;
8
+ findVariableByName(name: string): Variable | undefined;
9
+ findVariableCollectionByKey(key: string): VariableCollection | undefined;
10
+ findVariableCollectionById(id: string): VariableCollection | undefined;
11
+ }
12
+
13
+ export function createStaticVariableRepository({
14
+ variables,
15
+ variableCollections,
16
+ }: {
17
+ variables: Record<string, Variable>;
18
+ variableCollections: Record<string, VariableCollection>;
19
+ }): VariableRepository {
20
+ const variablesKeyMap = new Map<string, Variable>();
21
+ const variablesIdMap = new Map<string, Variable>();
22
+ const variablesNameMap = new Map<string, Variable>();
23
+ const variableCollectionsKeyMap = new Map<string, VariableCollection>();
24
+ const variableCollectionsIdMap = new Map<string, VariableCollection>();
25
+
26
+ for (const variable of Object.values(variables)) {
27
+ if (variable.remote) {
28
+ continue;
29
+ }
30
+
31
+ variablesKeyMap.set(variable.key, variable);
32
+ variablesIdMap.set(variable.id, variable);
33
+ variablesNameMap.set(variable.name, variable);
34
+ }
35
+
36
+ for (const variableCollection of Object.values(variableCollections)) {
37
+ if (variableCollection.remote) {
38
+ continue;
39
+ }
40
+
41
+ variableCollectionsKeyMap.set(variableCollection.key, variableCollection);
42
+ variableCollectionsIdMap.set(variableCollection.id, variableCollection);
43
+ }
44
+
45
+ const variablesList = [...variablesKeyMap.values()];
46
+ const variableCollectionsList = [...variableCollectionsKeyMap.values()];
47
+
48
+ return {
49
+ getVariableList: () => variablesList,
50
+ getVariableCollectionList: () => variableCollectionsList,
51
+ findVariableByName: (name: string) => variablesNameMap.get(name),
52
+ findVariableByKey: (key: string) => variablesKeyMap.get(key),
53
+ findVariableById: (id: string) => variablesIdMap.get(id),
54
+ findVariableCollectionByKey: (key: string) => variableCollectionsKeyMap.get(key),
55
+ findVariableCollectionById: (id: string) => variableCollectionsIdMap.get(id),
56
+ };
57
+ }
@@ -0,0 +1,101 @@
1
+ import {
2
+ isIdenticalVariableValue,
3
+ isInsideScope,
4
+ isVariableAlias,
5
+ sanitizeVariableId,
6
+ } from "@/utils/figma-variable";
7
+ import type { Variable, VariableScope, VariableValueResolved } from "./variable.interface";
8
+ import type { VariableRepository } from "./variable.repository";
9
+
10
+ export interface VariableService {
11
+ getSlug: (id: string) => string[] | undefined;
12
+ resolveValue: (variable: Variable, mode: string) => VariableValueResolved;
13
+ infer: (value: VariableValueResolved, scope: VariableScope) => Variable | undefined;
14
+ }
15
+
16
+ export interface VariableServiceDeps {
17
+ variableRepository: VariableRepository;
18
+ inferCompareFunction: (a: Variable, b: Variable) => number;
19
+ }
20
+
21
+ export function createVariableService({
22
+ variableRepository,
23
+ inferCompareFunction,
24
+ }: VariableServiceDeps): VariableService {
25
+ const variables = variableRepository.getVariableList();
26
+
27
+ // private
28
+ function getName(key: string) {
29
+ const sanitizedId = sanitizeVariableId(key);
30
+ const variable = variableRepository.findVariableByKey(sanitizedId);
31
+
32
+ if (!variable) {
33
+ return undefined;
34
+ }
35
+
36
+ return variable.name;
37
+ }
38
+
39
+ function getDefaultModeId(variable: Variable) {
40
+ const variableCollection = variableRepository.findVariableCollectionById(
41
+ variable.variableCollectionId,
42
+ );
43
+
44
+ if (!variableCollection) {
45
+ // Variable collection not found: ${variable.variableCollectionId}, falling back to variable.valuesByMode key
46
+ return Object.keys(variable.valuesByMode)[0]!;
47
+ }
48
+
49
+ return variableCollection.defaultModeId;
50
+ }
51
+
52
+ // public
53
+ function getSlug(key: string): string[] | undefined {
54
+ const name = getName(key);
55
+
56
+ if (!name) {
57
+ return undefined;
58
+ }
59
+
60
+ return name.split("/");
61
+ }
62
+
63
+ function resolveValue(variable: Variable, mode: string): VariableValueResolved {
64
+ const value = variable.valuesByMode[mode];
65
+
66
+ if (value === undefined) {
67
+ throw new Error(`Variable value not found: ${variable.id} ${mode}`);
68
+ }
69
+
70
+ if (isVariableAlias(value)) {
71
+ const resolvedVariable = variableRepository.findVariableById(value.id);
72
+
73
+ if (!resolvedVariable) {
74
+ throw new Error(`Variable not found: ${value.id}`);
75
+ }
76
+
77
+ return resolveValue(resolvedVariable, mode);
78
+ }
79
+
80
+ return value;
81
+ }
82
+
83
+ function infer(value: VariableValueResolved, scope: VariableScope) {
84
+ // NOTE: We assume that the variable is in the default mode or value is equal between all modes for simplicity.
85
+ const inferredVariables = variables.filter(
86
+ (variable) =>
87
+ isInsideScope(variable, scope) &&
88
+ isIdenticalVariableValue(resolveValue(variable, getDefaultModeId(variable)), value),
89
+ );
90
+
91
+ const sortedVariables = inferredVariables.sort(inferCompareFunction);
92
+
93
+ return sortedVariables[0];
94
+ }
95
+
96
+ return {
97
+ getSlug,
98
+ resolveValue,
99
+ infer,
100
+ };
101
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./normalizer";
2
+ export * from "./codegen";
3
+ export * from "./entities";