@idealyst/mcp-server 1.0.87 → 1.0.88

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 (205) hide show
  1. package/ARCHITECTURE.md +313 -0
  2. package/README.md +292 -104
  3. package/TYPE-SYSTEM.md +397 -0
  4. package/dist/index.js +170 -1
  5. package/examples/components/Accordion.examples.tsx +147 -0
  6. package/examples/components/ActivityIndicator.examples.tsx +350 -0
  7. package/examples/components/Alert.examples.tsx +335 -0
  8. package/examples/components/Avatar.examples.tsx +188 -0
  9. package/examples/components/Badge.examples.tsx +242 -0
  10. package/examples/components/Breadcrumb.examples.tsx +303 -0
  11. package/examples/components/Button.examples.tsx +113 -0
  12. package/examples/components/Card.examples.tsx +131 -0
  13. package/examples/components/Checkbox.examples.tsx +195 -0
  14. package/examples/components/Chip.examples.tsx +87 -0
  15. package/examples/components/Dialog.examples.tsx +344 -0
  16. package/examples/components/Divider.examples.tsx +258 -0
  17. package/examples/components/Icon.examples.tsx +202 -0
  18. package/examples/components/Input.examples.tsx +205 -0
  19. package/examples/components/Menu.examples.tsx +321 -0
  20. package/examples/components/Popover.examples.tsx +439 -0
  21. package/examples/components/Progress.examples.tsx +340 -0
  22. package/examples/components/RadioButton.examples.tsx +443 -0
  23. package/examples/components/Screen.examples.tsx +347 -0
  24. package/examples/components/Select.examples.tsx +279 -0
  25. package/examples/components/Skeleton.examples.tsx +278 -0
  26. package/examples/components/Slider.examples.tsx +249 -0
  27. package/examples/components/Switch.examples.tsx +94 -0
  28. package/examples/components/TabBar.examples.tsx +356 -0
  29. package/examples/components/Text.examples.tsx +177 -0
  30. package/examples/components/TextArea.examples.tsx +203 -0
  31. package/examples/components/Tooltip.examples.tsx +318 -0
  32. package/examples/components/View.examples.tsx +307 -0
  33. package/package.json +15 -2
  34. package/scripts/extract-types.ts +71 -0
  35. package/scripts/type-extractor.ts +286 -0
  36. package/scripts/validate-examples.ts +142 -0
  37. package/src/data/components/Icon.ts +1 -1
  38. package/src/data/components/index.ts +2 -0
  39. package/src/index.ts +181 -1
  40. package/src/tools/get-types.ts +169 -0
  41. package/tsconfig.examples.json +14 -0
  42. package/dist/data/cli-commands.d.ts +0 -2
  43. package/dist/data/cli-commands.d.ts.map +0 -1
  44. package/dist/data/cli-commands.js +0 -100
  45. package/dist/data/cli-commands.js.map +0 -1
  46. package/dist/data/components/Accordion.d.ts +0 -15
  47. package/dist/data/components/Accordion.d.ts.map +0 -1
  48. package/dist/data/components/Accordion.js +0 -112
  49. package/dist/data/components/Accordion.js.map +0 -1
  50. package/dist/data/components/ActivityIndicator.d.ts +0 -15
  51. package/dist/data/components/ActivityIndicator.d.ts.map +0 -1
  52. package/dist/data/components/ActivityIndicator.js +0 -82
  53. package/dist/data/components/ActivityIndicator.js.map +0 -1
  54. package/dist/data/components/Alert.d.ts +0 -15
  55. package/dist/data/components/Alert.d.ts.map +0 -1
  56. package/dist/data/components/Alert.js +0 -132
  57. package/dist/data/components/Alert.js.map +0 -1
  58. package/dist/data/components/Avatar.d.ts +0 -15
  59. package/dist/data/components/Avatar.d.ts.map +0 -1
  60. package/dist/data/components/Avatar.js +0 -93
  61. package/dist/data/components/Avatar.js.map +0 -1
  62. package/dist/data/components/Badge.d.ts +0 -15
  63. package/dist/data/components/Badge.d.ts.map +0 -1
  64. package/dist/data/components/Badge.js +0 -64
  65. package/dist/data/components/Badge.js.map +0 -1
  66. package/dist/data/components/Breadcrumb.d.ts +0 -15
  67. package/dist/data/components/Breadcrumb.d.ts.map +0 -1
  68. package/dist/data/components/Breadcrumb.js +0 -96
  69. package/dist/data/components/Breadcrumb.js.map +0 -1
  70. package/dist/data/components/Button.d.ts +0 -15
  71. package/dist/data/components/Button.d.ts.map +0 -1
  72. package/dist/data/components/Button.js +0 -87
  73. package/dist/data/components/Button.js.map +0 -1
  74. package/dist/data/components/Card.d.ts +0 -15
  75. package/dist/data/components/Card.d.ts.map +0 -1
  76. package/dist/data/components/Card.js +0 -67
  77. package/dist/data/components/Card.js.map +0 -1
  78. package/dist/data/components/Checkbox.d.ts +0 -15
  79. package/dist/data/components/Checkbox.d.ts.map +0 -1
  80. package/dist/data/components/Checkbox.js +0 -118
  81. package/dist/data/components/Checkbox.js.map +0 -1
  82. package/dist/data/components/Chip.d.ts +0 -15
  83. package/dist/data/components/Chip.d.ts.map +0 -1
  84. package/dist/data/components/Chip.js +0 -76
  85. package/dist/data/components/Chip.js.map +0 -1
  86. package/dist/data/components/Dialog.d.ts +0 -15
  87. package/dist/data/components/Dialog.d.ts.map +0 -1
  88. package/dist/data/components/Dialog.js +0 -137
  89. package/dist/data/components/Dialog.js.map +0 -1
  90. package/dist/data/components/Divider.d.ts +0 -15
  91. package/dist/data/components/Divider.d.ts.map +0 -1
  92. package/dist/data/components/Divider.js +0 -71
  93. package/dist/data/components/Divider.js.map +0 -1
  94. package/dist/data/components/Icon.d.ts +0 -15
  95. package/dist/data/components/Icon.d.ts.map +0 -1
  96. package/dist/data/components/Icon.js +0 -70
  97. package/dist/data/components/Icon.js.map +0 -1
  98. package/dist/data/components/Image.d.ts +0 -15
  99. package/dist/data/components/Image.d.ts.map +0 -1
  100. package/dist/data/components/Image.js +0 -122
  101. package/dist/data/components/Image.js.map +0 -1
  102. package/dist/data/components/Input.d.ts +0 -15
  103. package/dist/data/components/Input.d.ts.map +0 -1
  104. package/dist/data/components/Input.js +0 -109
  105. package/dist/data/components/Input.js.map +0 -1
  106. package/dist/data/components/List.d.ts +0 -15
  107. package/dist/data/components/List.d.ts.map +0 -1
  108. package/dist/data/components/List.js +0 -113
  109. package/dist/data/components/List.js.map +0 -1
  110. package/dist/data/components/Menu.d.ts +0 -15
  111. package/dist/data/components/Menu.d.ts.map +0 -1
  112. package/dist/data/components/Menu.js +0 -132
  113. package/dist/data/components/Menu.js.map +0 -1
  114. package/dist/data/components/Popover.d.ts +0 -15
  115. package/dist/data/components/Popover.d.ts.map +0 -1
  116. package/dist/data/components/Popover.js +0 -159
  117. package/dist/data/components/Popover.js.map +0 -1
  118. package/dist/data/components/Pressable.d.ts +0 -15
  119. package/dist/data/components/Pressable.d.ts.map +0 -1
  120. package/dist/data/components/Pressable.js +0 -125
  121. package/dist/data/components/Pressable.js.map +0 -1
  122. package/dist/data/components/Progress.d.ts +0 -15
  123. package/dist/data/components/Progress.d.ts.map +0 -1
  124. package/dist/data/components/Progress.js +0 -95
  125. package/dist/data/components/Progress.js.map +0 -1
  126. package/dist/data/components/RadioButton.d.ts +0 -15
  127. package/dist/data/components/RadioButton.d.ts.map +0 -1
  128. package/dist/data/components/RadioButton.js +0 -140
  129. package/dist/data/components/RadioButton.js.map +0 -1
  130. package/dist/data/components/SVGImage.d.ts +0 -15
  131. package/dist/data/components/SVGImage.d.ts.map +0 -1
  132. package/dist/data/components/SVGImage.js +0 -112
  133. package/dist/data/components/SVGImage.js.map +0 -1
  134. package/dist/data/components/Screen.d.ts +0 -15
  135. package/dist/data/components/Screen.d.ts.map +0 -1
  136. package/dist/data/components/Screen.js +0 -99
  137. package/dist/data/components/Screen.js.map +0 -1
  138. package/dist/data/components/Select.d.ts +0 -15
  139. package/dist/data/components/Select.d.ts.map +0 -1
  140. package/dist/data/components/Select.js +0 -146
  141. package/dist/data/components/Select.js.map +0 -1
  142. package/dist/data/components/Skeleton.d.ts +0 -15
  143. package/dist/data/components/Skeleton.d.ts.map +0 -1
  144. package/dist/data/components/Skeleton.js +0 -110
  145. package/dist/data/components/Skeleton.js.map +0 -1
  146. package/dist/data/components/Slider.d.ts +0 -15
  147. package/dist/data/components/Slider.d.ts.map +0 -1
  148. package/dist/data/components/Slider.js +0 -129
  149. package/dist/data/components/Slider.js.map +0 -1
  150. package/dist/data/components/Switch.d.ts +0 -15
  151. package/dist/data/components/Switch.d.ts.map +0 -1
  152. package/dist/data/components/Switch.js +0 -127
  153. package/dist/data/components/Switch.js.map +0 -1
  154. package/dist/data/components/TabBar.d.ts +0 -15
  155. package/dist/data/components/TabBar.d.ts.map +0 -1
  156. package/dist/data/components/TabBar.js +0 -145
  157. package/dist/data/components/TabBar.js.map +0 -1
  158. package/dist/data/components/Table.d.ts +0 -15
  159. package/dist/data/components/Table.d.ts.map +0 -1
  160. package/dist/data/components/Table.js +0 -151
  161. package/dist/data/components/Table.js.map +0 -1
  162. package/dist/data/components/Tabs.d.ts +0 -15
  163. package/dist/data/components/Tabs.d.ts.map +0 -1
  164. package/dist/data/components/Tabs.js +0 -150
  165. package/dist/data/components/Tabs.js.map +0 -1
  166. package/dist/data/components/Text.d.ts +0 -15
  167. package/dist/data/components/Text.d.ts.map +0 -1
  168. package/dist/data/components/Text.js +0 -85
  169. package/dist/data/components/Text.js.map +0 -1
  170. package/dist/data/components/TextArea.d.ts +0 -15
  171. package/dist/data/components/TextArea.d.ts.map +0 -1
  172. package/dist/data/components/TextArea.js +0 -155
  173. package/dist/data/components/TextArea.js.map +0 -1
  174. package/dist/data/components/Tooltip.d.ts +0 -15
  175. package/dist/data/components/Tooltip.d.ts.map +0 -1
  176. package/dist/data/components/Tooltip.js +0 -105
  177. package/dist/data/components/Tooltip.js.map +0 -1
  178. package/dist/data/components/Video.d.ts +0 -15
  179. package/dist/data/components/Video.d.ts.map +0 -1
  180. package/dist/data/components/Video.js +0 -168
  181. package/dist/data/components/Video.js.map +0 -1
  182. package/dist/data/components/View.d.ts +0 -15
  183. package/dist/data/components/View.d.ts.map +0 -1
  184. package/dist/data/components/View.js +0 -126
  185. package/dist/data/components/View.js.map +0 -1
  186. package/dist/data/components/index.d.ts +0 -37
  187. package/dist/data/components/index.d.ts.map +0 -1
  188. package/dist/data/components/index.js +0 -110
  189. package/dist/data/components/index.js.map +0 -1
  190. package/dist/data/framework-guides.d.ts +0 -2
  191. package/dist/data/framework-guides.d.ts.map +0 -1
  192. package/dist/data/framework-guides.js +0 -589
  193. package/dist/data/framework-guides.js.map +0 -1
  194. package/dist/data/icon-guide.d.ts +0 -2
  195. package/dist/data/icon-guide.d.ts.map +0 -1
  196. package/dist/data/icon-guide.js +0 -285
  197. package/dist/data/icon-guide.js.map +0 -1
  198. package/dist/data/icons.json +0 -7452
  199. package/dist/data/navigation-guides.d.ts +0 -2
  200. package/dist/data/navigation-guides.d.ts.map +0 -1
  201. package/dist/data/navigation-guides.js +0 -1196
  202. package/dist/data/navigation-guides.js.map +0 -1
  203. package/dist/index.d.ts +0 -3
  204. package/dist/index.d.ts.map +0 -1
  205. package/dist/index.js.map +0 -1
@@ -0,0 +1,307 @@
1
+ /**
2
+ * View Component Examples
3
+ *
4
+ * These examples are type-checked against the actual ViewProps interface
5
+ * to ensure accuracy and correctness.
6
+ */
7
+
8
+ import React from 'react';
9
+ import { View, Text } from '@idealyst/components';
10
+
11
+ // Example 1: Basic View
12
+ export function BasicView() {
13
+ return (
14
+ <View>
15
+ <Text>This is a basic view container</Text>
16
+ </View>
17
+ );
18
+ }
19
+
20
+ // Example 2: View with Spacing
21
+ export function ViewWithSpacing() {
22
+ return (
23
+ <View spacing="none">
24
+ <Text>No spacing</Text>
25
+ <View spacing="xs">
26
+ <Text>Extra small spacing</Text>
27
+ </View>
28
+ <View spacing="sm">
29
+ <Text>Small spacing</Text>
30
+ </View>
31
+ <View spacing="md">
32
+ <Text>Medium spacing</Text>
33
+ </View>
34
+ <View spacing="lg">
35
+ <Text>Large spacing</Text>
36
+ </View>
37
+ <View spacing="xl">
38
+ <Text>Extra large spacing</Text>
39
+ </View>
40
+ </View>
41
+ );
42
+ }
43
+
44
+ // Example 3: View with Background
45
+ export function ViewWithBackground() {
46
+ return (
47
+ <View spacing="md">
48
+ <View background="primary" spacing="md">
49
+ <Text>Primary surface</Text>
50
+ </View>
51
+ <View background="secondary" spacing="md">
52
+ <Text>Secondary surface</Text>
53
+ </View>
54
+ <View background="tertiary" spacing="md">
55
+ <Text>Tertiary surface</Text>
56
+ </View>
57
+ <View background="transparent" spacing="md">
58
+ <Text>Transparent background</Text>
59
+ </View>
60
+ </View>
61
+ );
62
+ }
63
+
64
+ // Example 4: View with Border Radius
65
+ export function ViewWithRadius() {
66
+ return (
67
+ <View spacing="md">
68
+ <View background="primary" radius="none" spacing="md">
69
+ <Text>No radius</Text>
70
+ </View>
71
+ <View background="primary" radius="xs" spacing="md">
72
+ <Text>XS radius</Text>
73
+ </View>
74
+ <View background="primary" radius="sm" spacing="md">
75
+ <Text>Small radius</Text>
76
+ </View>
77
+ <View background="primary" radius="md" spacing="md">
78
+ <Text>Medium radius</Text>
79
+ </View>
80
+ <View background="primary" radius="lg" spacing="md">
81
+ <Text>Large radius</Text>
82
+ </View>
83
+ <View background="primary" radius="xl" spacing="md">
84
+ <Text>XL radius</Text>
85
+ </View>
86
+ </View>
87
+ );
88
+ }
89
+
90
+ // Example 5: View with Borders
91
+ export function ViewWithBorders() {
92
+ return (
93
+ <View spacing="md">
94
+ <View border="none" spacing="md">
95
+ <Text>No border</Text>
96
+ </View>
97
+ <View border="thin" spacing="md">
98
+ <Text>Thin border</Text>
99
+ </View>
100
+ <View border="thick" spacing="md">
101
+ <Text>Thick border</Text>
102
+ </View>
103
+ </View>
104
+ );
105
+ }
106
+
107
+ // Example 6: View with Custom Colors
108
+ export function ViewWithCustomColors() {
109
+ return (
110
+ <View spacing="md">
111
+ <View backgroundColor="blue" spacing="md" radius="md">
112
+ <Text >Blue background</Text>
113
+ </View>
114
+ <View backgroundColor="green" spacing="md" radius="md">
115
+ <Text >Green background</Text>
116
+ </View>
117
+ <View backgroundColor="red" spacing="md" radius="md">
118
+ <Text >Red background</Text>
119
+ </View>
120
+ <View
121
+ border="thin"
122
+ borderColor="purple"
123
+ spacing="md"
124
+ radius="md"
125
+ >
126
+ <Text>Purple border</Text>
127
+ </View>
128
+ </View>
129
+ );
130
+ }
131
+
132
+ // Example 7: View with Custom Sizes
133
+ export function ViewWithCustomSizes() {
134
+ return (
135
+ <View spacing="md">
136
+ <View padding={8} borderRadius={4} backgroundColor="gray.100">
137
+ <Text>Custom padding: 8</Text>
138
+ </View>
139
+ <View padding={16} borderRadius={8} backgroundColor="gray.100">
140
+ <Text>Custom padding: 16</Text>
141
+ </View>
142
+ <View padding={24} borderRadius={12} backgroundColor="gray.100">
143
+ <Text>Custom padding: 24</Text>
144
+ </View>
145
+ </View>
146
+ );
147
+ }
148
+
149
+ // Example 8: Nested Views
150
+ export function NestedViews() {
151
+ return (
152
+ <View spacing="lg" background="primary" radius="lg">
153
+ <Text weight="bold" size="lg">
154
+ Outer View
155
+ </Text>
156
+ <View spacing="md" background="secondary" radius="md">
157
+ <Text weight="semibold">Middle View</Text>
158
+ <View spacing="sm" background="tertiary" radius="sm">
159
+ <Text>Inner View</Text>
160
+ </View>
161
+ </View>
162
+ </View>
163
+ );
164
+ }
165
+
166
+ // Example 9: Card-like Layout
167
+ export function CardLayout() {
168
+ return (
169
+ <View spacing="md">
170
+ <View
171
+ background="primary"
172
+ spacing="lg"
173
+ radius="lg"
174
+ border="thin"
175
+ >
176
+ <Text size="lg" weight="bold">
177
+ Card Title
178
+ </Text>
179
+ <Text size="md" >
180
+ This is a card-like layout created using the View component with background, spacing,
181
+ radius, and border properties.
182
+ </Text>
183
+ </View>
184
+ </View>
185
+ );
186
+ }
187
+
188
+ // Example 10: View with Margin
189
+ export function ViewWithMargin() {
190
+ return (
191
+ <View spacing="md">
192
+ <View
193
+ background="primary"
194
+ spacing="md"
195
+ marginVariant="none"
196
+ >
197
+ <Text>No margin</Text>
198
+ </View>
199
+ <View
200
+ background="primary"
201
+ spacing="md"
202
+ marginVariant="sm"
203
+ >
204
+ <Text>Small margin</Text>
205
+ </View>
206
+ <View
207
+ background="primary"
208
+ spacing="md"
209
+ marginVariant="md"
210
+ >
211
+ <Text>Medium margin</Text>
212
+ </View>
213
+ <View
214
+ background="primary"
215
+ spacing="md"
216
+ marginVariant="lg"
217
+ >
218
+ <Text>Large margin</Text>
219
+ </View>
220
+ </View>
221
+ );
222
+ }
223
+
224
+ // Example 11: Profile Card
225
+ export function ProfileCard() {
226
+ return (
227
+ <View
228
+ background="primary"
229
+ spacing="lg"
230
+ radius="lg"
231
+ border="thin"
232
+ >
233
+ <View spacing="md">
234
+ <Text size="xl" weight="bold">
235
+ John Doe
236
+ </Text>
237
+ <Text size="md" >
238
+ Software Engineer
239
+ </Text>
240
+ </View>
241
+ <View spacing="sm">
242
+ <Text size="sm" >
243
+ Email: john.doe@example.com
244
+ </Text>
245
+ <Text size="sm" >
246
+ Location: San Francisco, CA
247
+ </Text>
248
+ </View>
249
+ </View>
250
+ );
251
+ }
252
+
253
+ // Example 12: Dashboard Grid
254
+ export function DashboardGrid() {
255
+ return (
256
+ <View spacing="md">
257
+ <View spacing="md">
258
+ <View
259
+ background="primary"
260
+ spacing="md"
261
+ radius="md"
262
+ border="thin"
263
+ >
264
+ <Text weight="semibold">Card 1</Text>
265
+ <Text size="sm" >
266
+ Content goes here
267
+ </Text>
268
+ </View>
269
+ <View
270
+ background="primary"
271
+ spacing="md"
272
+ radius="md"
273
+ border="thin"
274
+ >
275
+ <Text weight="semibold">Card 2</Text>
276
+ <Text size="sm" >
277
+ Content goes here
278
+ </Text>
279
+ </View>
280
+ </View>
281
+ <View spacing="md">
282
+ <View
283
+ background="primary"
284
+ spacing="md"
285
+ radius="md"
286
+ border="thin"
287
+ >
288
+ <Text weight="semibold">Card 3</Text>
289
+ <Text size="sm" >
290
+ Content goes here
291
+ </Text>
292
+ </View>
293
+ <View
294
+ background="primary"
295
+ spacing="md"
296
+ radius="md"
297
+ border="thin"
298
+ >
299
+ <Text weight="semibold">Card 4</Text>
300
+ <Text size="sm" >
301
+ Content goes here
302
+ </Text>
303
+ </View>
304
+ </View>
305
+ </View>
306
+ );
307
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/mcp-server",
3
- "version": "1.0.87",
3
+ "version": "1.0.88",
4
4
  "description": "MCP server providing documentation and examples for the Idealyst framework",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -8,7 +8,11 @@
8
8
  },
9
9
  "type": "module",
10
10
  "scripts": {
11
- "build": "tsc && chmod +x dist/index.js",
11
+ "extract-types": "tsx scripts/extract-types.ts",
12
+ "validate-examples": "tsx scripts/validate-examples.ts",
13
+ "test": "tsx scripts/test-examples.ts",
14
+ "prebuild": "yarn extract-types && yarn validate-examples",
15
+ "build": "tsc && chmod +x dist/index.js && mkdir -p dist/generated && cp -r src/generated/* dist/generated/",
12
16
  "dev": "tsc --watch",
13
17
  "start": "node dist/index.js"
14
18
  },
@@ -25,10 +29,19 @@
25
29
  "author": "Idealyst",
26
30
  "license": "MIT",
27
31
  "dependencies": {
32
+ "@idealyst/components": "^1.0.88",
33
+ "@idealyst/navigation": "^1.0.88",
34
+ "@idealyst/theme": "^1.0.88",
28
35
  "@modelcontextprotocol/sdk": "^1.0.4"
29
36
  },
30
37
  "devDependencies": {
31
38
  "@types/node": "^20.0.0",
39
+ "@types/react": "^19.1.0",
40
+ "chalk": "^5.3.0",
41
+ "react": "^19.1.0",
42
+ "react-native": "^0.80.1",
43
+ "ts-morph": "^21.0.1",
44
+ "tsx": "^4.7.0",
32
45
  "typescript": "^5.0.0"
33
46
  }
34
47
  }
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * Extract Types Script
5
+ *
6
+ * Extracts TypeScript type information from @idealyst packages
7
+ * and generates a JSON file for use by the MCP server.
8
+ */
9
+
10
+ import { TypeExtractor } from './type-extractor.js';
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { fileURLToPath } from 'url';
14
+
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = path.dirname(__filename);
17
+
18
+ async function main() {
19
+ console.log('🔍 Extracting types from Idealyst packages...\n');
20
+
21
+ const extractor = new TypeExtractor();
22
+
23
+ // Extract all component types
24
+ console.log('📦 Extracting component types...');
25
+ const components = extractor.extractAllComponents();
26
+ console.log(` Found ${Object.keys(components).length} components\n`);
27
+
28
+ // Extract theme types
29
+ console.log('🎨 Extracting theme types...');
30
+ const themeTypes = extractor.extractThemeTypes();
31
+ console.log(` Found ${Object.keys(themeTypes).length} theme types\n`);
32
+
33
+ // Extract navigation types
34
+ console.log('🧭 Extracting navigation types...');
35
+ const navigationTypes = extractor.extractNavigationTypes();
36
+ console.log(` Found ${Object.keys(navigationTypes).length} navigation types\n`);
37
+
38
+ // Create output structure
39
+ const output = {
40
+ version: '1.0.88',
41
+ extractedAt: new Date().toISOString(),
42
+ components,
43
+ theme: themeTypes,
44
+ navigation: navigationTypes,
45
+ };
46
+
47
+ // Ensure output directory exists
48
+ const outputDir = path.join(__dirname, '../src/generated');
49
+ if (!fs.existsSync(outputDir)) {
50
+ fs.mkdirSync(outputDir, { recursive: true });
51
+ }
52
+
53
+ // Write JSON file
54
+ const outputPath = path.join(outputDir, 'types.json');
55
+ fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
56
+
57
+ console.log(`✅ Type extraction complete!`);
58
+ console.log(` Output: ${outputPath}\n`);
59
+
60
+ // Print summary
61
+ console.log('📊 Summary:');
62
+ console.log(` Components: ${Object.keys(components).length}`);
63
+ console.log(` Theme Types: ${Object.keys(themeTypes).length}`);
64
+ console.log(` Navigation Types: ${Object.keys(navigationTypes).length}`);
65
+ console.log(` Total Props: ${Object.values(components).reduce((sum, c) => sum + c.props.length, 0)}`);
66
+ }
67
+
68
+ main().catch(error => {
69
+ console.error('❌ Type extraction failed:', error);
70
+ process.exit(1);
71
+ });
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Type Extractor Utility
3
+ *
4
+ * Uses TypeScript Compiler API (via ts-morph) to extract type information
5
+ * from @idealyst packages at build time.
6
+ */
7
+
8
+ import { Project, SourceFile, InterfaceDeclaration, TypeAliasDeclaration, EnumDeclaration } from 'ts-morph';
9
+ import * as path from 'path';
10
+ import * as fs from 'fs';
11
+ import { fileURLToPath } from 'url';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+
16
+ export interface PropInfo {
17
+ name: string;
18
+ type: string;
19
+ required: boolean;
20
+ description?: string;
21
+ default?: string;
22
+ }
23
+
24
+ export interface ComponentTypeInfo {
25
+ name: string;
26
+ propsInterface: string;
27
+ props: PropInfo[];
28
+ typeDefinition: string;
29
+ relatedTypes: Record<string, string>;
30
+ }
31
+
32
+ export interface ThemeTypeInfo {
33
+ name: string;
34
+ definition: string;
35
+ values?: string[];
36
+ }
37
+
38
+ export class TypeExtractor {
39
+ private project: Project;
40
+ private componentsPath: string;
41
+ private themePath: string;
42
+ private navigationPath: string;
43
+
44
+ constructor() {
45
+ this.project = new Project({
46
+ tsConfigFilePath: path.join(__dirname, '../tsconfig.json'),
47
+ skipAddingFilesFromTsConfig: true,
48
+ });
49
+
50
+ // Resolve paths to the actual packages in the monorepo
51
+ const monorepoRoot = path.resolve(__dirname, '../../..');
52
+ this.componentsPath = path.join(monorepoRoot, 'packages/components/src');
53
+ this.themePath = path.join(monorepoRoot, 'packages/theme/src');
54
+ this.navigationPath = path.join(monorepoRoot, 'packages/navigation/src');
55
+ }
56
+
57
+ /**
58
+ * Extract component type information
59
+ */
60
+ extractComponentTypes(componentName: string): ComponentTypeInfo | null {
61
+ const typesFilePath = path.join(
62
+ this.componentsPath,
63
+ componentName,
64
+ 'types.ts'
65
+ );
66
+
67
+ if (!fs.existsSync(typesFilePath)) {
68
+ console.warn(`Types file not found for ${componentName}: ${typesFilePath}`);
69
+ return null;
70
+ }
71
+
72
+ const sourceFile = this.project.addSourceFileAtPath(typesFilePath);
73
+
74
+ // Find the main props interface (e.g., ButtonProps)
75
+ const propsInterfaceName = `${componentName}Props`;
76
+ const propsInterface = sourceFile.getInterface(propsInterfaceName);
77
+
78
+ if (!propsInterface) {
79
+ console.warn(`Props interface not found: ${propsInterfaceName}`);
80
+ return null;
81
+ }
82
+
83
+ const props = this.extractPropsFromInterface(propsInterface);
84
+ const relatedTypes = this.extractRelatedTypes(sourceFile);
85
+
86
+ return {
87
+ name: componentName,
88
+ propsInterface: propsInterfaceName,
89
+ props,
90
+ typeDefinition: propsInterface.getText(),
91
+ relatedTypes,
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Extract props from an interface
97
+ */
98
+ private extractPropsFromInterface(interfaceDecl: InterfaceDeclaration): PropInfo[] {
99
+ const props: PropInfo[] = [];
100
+
101
+ for (const prop of interfaceDecl.getProperties()) {
102
+ const name = prop.getName();
103
+ const type = prop.getType().getText();
104
+ const required = !prop.hasQuestionToken();
105
+
106
+ // Extract JSDoc comments for description
107
+ const jsDocs = prop.getJsDocs();
108
+ const description = jsDocs.length > 0
109
+ ? jsDocs[0].getDescription().trim()
110
+ : undefined;
111
+
112
+ props.push({
113
+ name,
114
+ type,
115
+ required,
116
+ description,
117
+ });
118
+ }
119
+
120
+ return props;
121
+ }
122
+
123
+ /**
124
+ * Extract related type definitions from a source file
125
+ */
126
+ private extractRelatedTypes(sourceFile: SourceFile): Record<string, string> {
127
+ const types: Record<string, string> = {};
128
+
129
+ // Extract type aliases
130
+ for (const typeAlias of sourceFile.getTypeAliases()) {
131
+ const name = typeAlias.getName();
132
+ const definition = typeAlias.getText();
133
+ types[name] = definition;
134
+ }
135
+
136
+ // Extract enums
137
+ for (const enumDecl of sourceFile.getEnums()) {
138
+ const name = enumDecl.getName();
139
+ const definition = enumDecl.getText();
140
+ types[name] = definition;
141
+ }
142
+
143
+ // Extract other interfaces
144
+ for (const interfaceDecl of sourceFile.getInterfaces()) {
145
+ const name = interfaceDecl.getName();
146
+ if (!name.endsWith('Props')) {
147
+ const definition = interfaceDecl.getText();
148
+ types[name] = definition;
149
+ }
150
+ }
151
+
152
+ return types;
153
+ }
154
+
155
+ /**
156
+ * Extract theme types (Size, Intent, Color, etc.)
157
+ */
158
+ extractThemeTypes(): Record<string, ThemeTypeInfo> {
159
+ const themeTypes: Record<string, ThemeTypeInfo> = {};
160
+
161
+ // Extract Size type
162
+ const sizeFile = path.join(this.themePath, 'theme/size.ts');
163
+ if (fs.existsSync(sizeFile)) {
164
+ const sourceFile = this.project.addSourceFileAtPath(sizeFile);
165
+ const sizeType = sourceFile.getTypeAlias('Size');
166
+ if (sizeType) {
167
+ const definition = sizeType.getText();
168
+ const values = this.extractUnionValues(sizeType);
169
+ themeTypes.Size = { name: 'Size', definition, values };
170
+ }
171
+ }
172
+
173
+ // Extract Intent type
174
+ const intentFile = path.join(this.themePath, 'theme/intent.ts');
175
+ if (fs.existsSync(intentFile)) {
176
+ const sourceFile = this.project.addSourceFileAtPath(intentFile);
177
+ const intentType = sourceFile.getTypeAlias('Intent');
178
+ if (intentType) {
179
+ const definition = intentType.getText();
180
+ const values = this.extractUnionValues(intentType);
181
+ themeTypes.Intent = { name: 'Intent', definition, values };
182
+ }
183
+ }
184
+
185
+ // Extract Color types
186
+ const colorFile = path.join(this.themePath, 'theme/color.ts');
187
+ if (fs.existsSync(colorFile)) {
188
+ const sourceFile = this.project.addSourceFileAtPath(colorFile);
189
+
190
+ const palletType = sourceFile.getTypeAlias('Pallet');
191
+ if (palletType) {
192
+ const definition = palletType.getText();
193
+ const values = this.extractUnionValues(palletType);
194
+ themeTypes.Pallet = { name: 'Pallet', definition, values };
195
+ }
196
+
197
+ const shadeType = sourceFile.getTypeAlias('Shade');
198
+ if (shadeType) {
199
+ const definition = shadeType.getText();
200
+ const values = this.extractUnionValues(shadeType);
201
+ themeTypes.Shade = { name: 'Shade', definition, values };
202
+ }
203
+
204
+ const colorType = sourceFile.getTypeAlias('Color');
205
+ if (colorType) {
206
+ const definition = colorType.getText();
207
+ themeTypes.Color = { name: 'Color', definition };
208
+ }
209
+ }
210
+
211
+ return themeTypes;
212
+ }
213
+
214
+ /**
215
+ * Extract values from a union type
216
+ */
217
+ private extractUnionValues(typeAlias: TypeAliasDeclaration): string[] {
218
+ const type = typeAlias.getType();
219
+ if (type.isUnion()) {
220
+ return type.getUnionTypes().map(t => {
221
+ const text = t.getText();
222
+ // Remove quotes from string literals
223
+ return text.replace(/^["']|["']$/g, '');
224
+ });
225
+ }
226
+ return [];
227
+ }
228
+
229
+ /**
230
+ * Extract navigation types
231
+ */
232
+ extractNavigationTypes(): Record<string, string> {
233
+ const navTypes: Record<string, string> = {};
234
+
235
+ const typesFile = path.join(this.navigationPath, 'routing/types.ts');
236
+ if (fs.existsSync(typesFile)) {
237
+ const sourceFile = this.project.addSourceFileAtPath(typesFile);
238
+
239
+ // Extract all type aliases and interfaces
240
+ for (const typeAlias of sourceFile.getTypeAliases()) {
241
+ navTypes[typeAlias.getName()] = typeAlias.getText();
242
+ }
243
+
244
+ for (const interfaceDecl of sourceFile.getInterfaces()) {
245
+ navTypes[interfaceDecl.getName()] = interfaceDecl.getText();
246
+ }
247
+ }
248
+
249
+ return navTypes;
250
+ }
251
+
252
+ /**
253
+ * Get all available components
254
+ */
255
+ getAvailableComponents(): string[] {
256
+ if (!fs.existsSync(this.componentsPath)) {
257
+ return [];
258
+ }
259
+
260
+ const entries = fs.readdirSync(this.componentsPath, { withFileTypes: true });
261
+ return entries
262
+ .filter(entry => entry.isDirectory())
263
+ .filter(entry => {
264
+ const typesFile = path.join(this.componentsPath, entry.name, 'types.ts');
265
+ return fs.existsSync(typesFile);
266
+ })
267
+ .map(entry => entry.name);
268
+ }
269
+
270
+ /**
271
+ * Extract all component types
272
+ */
273
+ extractAllComponents(): Record<string, ComponentTypeInfo> {
274
+ const components = this.getAvailableComponents();
275
+ const result: Record<string, ComponentTypeInfo> = {};
276
+
277
+ for (const componentName of components) {
278
+ const typeInfo = this.extractComponentTypes(componentName);
279
+ if (typeInfo) {
280
+ result[componentName] = typeInfo;
281
+ }
282
+ }
283
+
284
+ return result;
285
+ }
286
+ }