@trypattern/sdk 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/README.md +127 -2
  2. package/dist/access.d.ts +31 -0
  3. package/dist/access.js +72 -0
  4. package/dist/actions.d.ts +57 -0
  5. package/dist/actions.js +198 -0
  6. package/dist/api.d.ts +20 -0
  7. package/dist/api.js +34 -0
  8. package/dist/app.d.ts +106 -0
  9. package/dist/app.js +224 -0
  10. package/dist/appearance.d.ts +7 -0
  11. package/dist/appearance.js +2 -0
  12. package/dist/auth/sessionApi.d.ts +41 -0
  13. package/dist/auth/sessionApi.js +158 -0
  14. package/dist/auth/sessionStore.d.ts +20 -0
  15. package/dist/auth/sessionStore.js +40 -0
  16. package/dist/auth/user.d.ts +11 -0
  17. package/dist/auth/user.js +9 -0
  18. package/dist/builtins/Account.d.ts +25 -0
  19. package/dist/builtins/Account.js +15 -0
  20. package/dist/builtins/Palette.d.ts +29 -0
  21. package/dist/builtins/Palette.js +63 -0
  22. package/dist/builtins/SignIn.d.ts +28 -0
  23. package/dist/builtins/SignIn.js +60 -0
  24. package/dist/builtins/Toasts.d.ts +32 -0
  25. package/dist/builtins/Toasts.js +24 -0
  26. package/dist/builtins/actions.d.ts +2 -0
  27. package/dist/builtins/actions.js +45 -0
  28. package/dist/cache.d.ts +24 -0
  29. package/dist/cache.js +112 -0
  30. package/dist/cli/app.d.ts +2 -0
  31. package/dist/cli/app.js +1329 -0
  32. package/dist/cli/screenshot.d.ts +1 -0
  33. package/dist/cli/screenshot.js +96 -0
  34. package/dist/cli/tools.d.ts +12 -0
  35. package/dist/cli/tools.js +35 -0
  36. package/dist/components/AppFrame.d.ts +14 -0
  37. package/dist/components/AppFrame.js +64 -0
  38. package/dist/components/AppearancePicker.d.ts +1 -0
  39. package/dist/components/AppearancePicker.js +12 -0
  40. package/dist/components/Avatar.d.ts +9 -0
  41. package/dist/components/Avatar.js +63 -0
  42. package/dist/components/Badge.d.ts +11 -0
  43. package/dist/components/Badge.js +87 -0
  44. package/dist/components/Button.d.ts +23 -0
  45. package/dist/components/Button.js +249 -0
  46. package/dist/components/Card.d.ts +12 -0
  47. package/dist/components/Card.js +38 -0
  48. package/dist/components/CommandMenu.d.ts +23 -0
  49. package/dist/components/CommandMenu.js +214 -0
  50. package/dist/components/CommandPalette.d.ts +1 -0
  51. package/dist/components/CommandPalette.js +7 -0
  52. package/dist/components/Content.d.ts +7 -0
  53. package/dist/components/Content.js +24 -0
  54. package/dist/components/ContextMenu.d.ts +8 -0
  55. package/dist/components/ContextMenu.js +23 -0
  56. package/dist/components/Dialog.d.ts +11 -0
  57. package/dist/components/Dialog.js +81 -0
  58. package/dist/components/Divider.d.ts +6 -0
  59. package/dist/components/Divider.js +15 -0
  60. package/dist/components/EmptyState.d.ts +8 -0
  61. package/dist/components/EmptyState.js +24 -0
  62. package/dist/components/Form.d.ts +9 -0
  63. package/dist/components/Form.js +23 -0
  64. package/dist/components/Icon.d.ts +10 -0
  65. package/dist/components/Icon.js +22 -0
  66. package/dist/components/IconButton.d.ts +14 -0
  67. package/dist/components/IconButton.js +53 -0
  68. package/dist/components/Kbd.d.ts +6 -0
  69. package/dist/components/Kbd.js +67 -0
  70. package/dist/components/Link.d.ts +9 -0
  71. package/dist/components/Link.js +35 -0
  72. package/dist/components/ListRow.d.ts +12 -0
  73. package/dist/components/ListRow.js +62 -0
  74. package/dist/components/LoadingRows.d.ts +5 -0
  75. package/dist/components/LoadingRows.js +6 -0
  76. package/dist/components/Menu.d.ts +12 -0
  77. package/dist/components/Menu.js +33 -0
  78. package/dist/components/MenuItems.d.ts +21 -0
  79. package/dist/components/MenuItems.js +32 -0
  80. package/dist/components/Placement.d.ts +21 -0
  81. package/dist/components/Placement.js +1 -0
  82. package/dist/components/Popup.d.ts +8 -0
  83. package/dist/components/Popup.js +43 -0
  84. package/dist/components/PopupItem.d.ts +8 -0
  85. package/dist/components/PopupItem.js +51 -0
  86. package/dist/components/PropertyRow.d.ts +7 -0
  87. package/dist/components/PropertyRow.js +23 -0
  88. package/dist/components/Row.d.ts +16 -0
  89. package/dist/components/Row.js +27 -0
  90. package/dist/components/Screen.d.ts +13 -0
  91. package/dist/components/Screen.js +56 -0
  92. package/dist/components/Scrim.d.ts +8 -0
  93. package/dist/components/Scrim.js +40 -0
  94. package/dist/components/ScrollArea.d.ts +15 -0
  95. package/dist/components/ScrollArea.js +13 -0
  96. package/dist/components/SegmentedControl.d.ts +17 -0
  97. package/dist/components/SegmentedControl.js +68 -0
  98. package/dist/components/Select.d.ts +17 -0
  99. package/dist/components/Select.js +107 -0
  100. package/dist/components/SettingsRow.d.ts +8 -0
  101. package/dist/components/SettingsRow.js +32 -0
  102. package/dist/components/Sidebar.d.ts +20 -0
  103. package/dist/components/Sidebar.js +138 -0
  104. package/dist/components/SignInScreen.d.ts +1 -0
  105. package/dist/components/SignInScreen.js +40 -0
  106. package/dist/components/Size.d.ts +1 -0
  107. package/dist/components/Size.js +1 -0
  108. package/dist/components/Skeleton.d.ts +8 -0
  109. package/dist/components/Skeleton.js +48 -0
  110. package/dist/components/Spinner.d.ts +6 -0
  111. package/dist/components/Spinner.js +54 -0
  112. package/dist/components/Stack.d.ts +14 -0
  113. package/dist/components/Stack.js +19 -0
  114. package/dist/components/Switch.d.ts +10 -0
  115. package/dist/components/Switch.js +71 -0
  116. package/dist/components/Text.d.ts +21 -0
  117. package/dist/components/Text.js +77 -0
  118. package/dist/components/TextField.d.ts +25 -0
  119. package/dist/components/TextField.js +68 -0
  120. package/dist/components/Toaster.d.ts +1 -0
  121. package/dist/components/Toaster.js +83 -0
  122. package/dist/components/Tooltip.d.ts +8 -0
  123. package/dist/components/Tooltip.js +43 -0
  124. package/dist/components/controlLook.d.ts +60 -0
  125. package/dist/components/controlLook.js +67 -0
  126. package/dist/components/frame.d.ts +4 -0
  127. package/dist/components/frame.js +2 -0
  128. package/dist/components/icons.d.ts +58 -0
  129. package/dist/components/icons.js +105 -0
  130. package/dist/components/interaction.d.ts +12 -0
  131. package/dist/components/interaction.js +22 -0
  132. package/dist/components/spacing.d.ts +118 -0
  133. package/dist/components/spacing.js +46 -0
  134. package/dist/components/tones.d.ts +28 -0
  135. package/dist/components/tones.js +12 -0
  136. package/dist/entityStore.d.ts +46 -0
  137. package/dist/entityStore.js +160 -0
  138. package/dist/flows/accessFlows.d.ts +9 -0
  139. package/dist/flows/accessFlows.js +151 -0
  140. package/dist/flows/browser.d.ts +32 -0
  141. package/dist/flows/browser.js +164 -0
  142. package/dist/flows/contactSheet.d.ts +1 -0
  143. package/dist/flows/contactSheet.js +63 -0
  144. package/dist/flows/flowBrowser.d.ts +23 -0
  145. package/dist/flows/flowBrowser.js +21 -0
  146. package/dist/flows/flowSetup.d.ts +3 -0
  147. package/dist/flows/flowSetup.js +35 -0
  148. package/dist/flows/flows.d.ts +41 -0
  149. package/dist/flows/flows.js +148 -0
  150. package/dist/flows/screenshotName.d.ts +1 -0
  151. package/dist/flows/screenshotName.js +6 -0
  152. package/dist/gate.d.ts +8 -0
  153. package/dist/gate.js +52 -0
  154. package/dist/hooks/appContext.d.ts +14 -0
  155. package/dist/hooks/appContext.js +5 -0
  156. package/dist/hooks/appHooks.d.ts +21 -0
  157. package/dist/hooks/appHooks.js +24 -0
  158. package/dist/hooks/useAnimatesOnChange.d.ts +1 -0
  159. package/dist/hooks/useAnimatesOnChange.js +14 -0
  160. package/dist/hooks/useStoreState.d.ts +6 -0
  161. package/dist/hooks/useStoreState.js +5 -0
  162. package/dist/index.d.ts +40 -0
  163. package/dist/index.js +19 -0
  164. package/dist/memoryApi.d.ts +19 -0
  165. package/dist/memoryApi.js +42 -0
  166. package/dist/model.d.ts +94 -0
  167. package/dist/model.js +243 -0
  168. package/dist/page.d.ts +11 -0
  169. package/dist/page.js +9 -0
  170. package/dist/platform.d.ts +1 -0
  171. package/dist/platform.js +5 -0
  172. package/dist/react.d.ts +46 -0
  173. package/dist/react.js +38 -0
  174. package/dist/registered.d.ts +54 -0
  175. package/dist/registered.js +17 -0
  176. package/dist/routes.d.ts +38 -0
  177. package/dist/routes.js +21 -0
  178. package/dist/rules/checkAllFiles.d.ts +1 -0
  179. package/dist/rules/checkAllFiles.js +741 -0
  180. package/dist/rules/checkApiRouting.d.ts +1 -0
  181. package/dist/rules/checkApiRouting.js +112 -0
  182. package/dist/rules/lintPlugin.d.ts +252 -0
  183. package/dist/rules/lintPlugin.js +1157 -0
  184. package/dist/rules/messages.d.ts +48 -0
  185. package/dist/rules/messages.js +48 -0
  186. package/dist/rules/themeTokens.d.ts +6 -0
  187. package/dist/rules/themeTokens.js +64 -0
  188. package/dist/schema.d.ts +2 -0
  189. package/dist/schema.js +1 -0
  190. package/dist/server/auth.d.ts +115 -0
  191. package/dist/server/auth.js +131 -0
  192. package/dist/server/authService.d.ts +9 -0
  193. package/dist/server/authService.js +50 -0
  194. package/dist/server/createServer.d.ts +357 -0
  195. package/dist/server/createServer.js +62 -0
  196. package/dist/server/env.d.ts +15 -0
  197. package/dist/server/env.js +1 -0
  198. package/dist/server/index.d.ts +8 -0
  199. package/dist/server/index.js +5 -0
  200. package/dist/server/session.d.ts +28 -0
  201. package/dist/server/session.js +54 -0
  202. package/dist/server/sessions.d.ts +92 -0
  203. package/dist/server/sessions.js +47 -0
  204. package/dist/server/signInWire.d.ts +52 -0
  205. package/dist/server/signInWire.js +22 -0
  206. package/dist/server/tables.d.ts +242 -0
  207. package/dist/server/tables.js +246 -0
  208. package/dist/server/users.d.ts +189 -0
  209. package/dist/server/users.js +49 -0
  210. package/dist/shortcuts.d.ts +3 -0
  211. package/dist/shortcuts.js +40 -0
  212. package/dist/start.d.ts +20 -0
  213. package/dist/start.js +121 -0
  214. package/dist/state.d.ts +14 -0
  215. package/dist/state.js +17 -0
  216. package/dist/store.d.ts +43 -0
  217. package/dist/store.js +198 -0
  218. package/dist/subscribers.d.ts +5 -0
  219. package/dist/subscribers.js +13 -0
  220. package/dist/table.d.ts +143 -0
  221. package/dist/table.js +91 -0
  222. package/dist/tables.d.ts +77 -0
  223. package/dist/tables.js +216 -0
  224. package/dist/theme/reset.css +84 -0
  225. package/dist/theme/scales.d.ts +76 -0
  226. package/dist/theme/scales.js +82 -0
  227. package/dist/theme/tokens.stylex.d.ts +218 -0
  228. package/dist/theme/tokens.stylex.js +233 -0
  229. package/dist/vite/commandBridge.d.ts +2 -0
  230. package/dist/vite/commandBridge.js +46 -0
  231. package/dist/vite/designManifest.d.ts +25 -0
  232. package/dist/vite/designManifest.js +191 -0
  233. package/dist/vite/localWorker.d.ts +4 -0
  234. package/dist/vite/localWorker.js +59 -0
  235. package/dist/vite/rootAlias.d.ts +2 -0
  236. package/dist/vite/rootAlias.js +15 -0
  237. package/dist/vite/vite.d.ts +7 -0
  238. package/dist/vite/vite.js +88 -0
  239. package/dist/wire.d.ts +7 -0
  240. package/dist/wire.js +1 -0
  241. package/package.json +99 -3
  242. package/presets/lintPlugin.js +7 -0
  243. package/presets/oxlint.json +167 -0
  244. package/presets/register.d.ts +19 -0
  245. package/presets/server.d.ts +2 -0
  246. package/presets/tsconfig.app.json +29 -0
  247. package/presets/tsconfig.server.json +27 -0
@@ -0,0 +1,233 @@
1
+ import * as stylex from '@stylexjs/stylex';
2
+ export const breakpoints = stylex.defineConsts({
3
+ compact: '@media (max-width: 767px)',
4
+ reducedMotion: '@media (prefers-reduced-motion: reduce)',
5
+ coarsePointer: '@media (pointer: coarse)'
6
+ });
7
+ export const colors = stylex.defineVars({
8
+ blackFill: '#000',
9
+ blackTransparent: '#0000',
10
+ borderDefault: 'light-dark(#0000000f, #ffffff12)',
11
+ borderInverted: 'light-dark(#000, #fff)',
12
+ borderOnStandout: 'light-dark(#ffffff1a, #ffffff0d)',
13
+ borderStrong: 'light-dark(#00000026, #ffffff2c)',
14
+ borderStrongSolid: 'light-dark(#d9d9d9, #3a3a3a)',
15
+ borderSubtle: 'light-dark(#00000006, #ffffff09)',
16
+ brandBorderDefault: 'light-dark(#0088f653, #0f89fd7f)',
17
+ brandBorderFocus: 'light-dark(#0084e6a1, #0090ff)',
18
+ brandBorderSubtle: 'light-dark(#0093ff3d, #0081fd6b)',
19
+ brandGradientSubtle: 'linear-gradient(90deg, #ef5f0033 20%, #c2007a28 40%, #53009e25 60%, #0086f032 80%)',
20
+ brandForeground: 'light-dark(#0086f0fa, #3b9eff)',
21
+ brandSolid: '#0090ff',
22
+ brandSolidActive: 'light-dark(#0d74ce, #70b8ff)',
23
+ brandSolidHover: 'light-dark(#0588f0, #3b9eff)',
24
+ brandSubtle: 'light-dark(#008ff519, #0077ff3a)',
25
+ brandSubtleHover: 'light-dark(#009eff2a, #0075ff57)',
26
+ card: 'light-dark(#00000006, #ffffff09)',
27
+ component: 'light-dark(#0000000f, #ffffff12)',
28
+ componentActive: 'light-dark(#0000001f, #fff2)',
29
+ componentHover: 'light-dark(#00000017, #ffffff1b)',
30
+ componentOnContainerStrong: 'light-dark(#fff, #ffffff12)',
31
+ componentOnContainerStrongHover: 'light-dark(#f9f9f9, #ffffff1b)',
32
+ componentOnContainerSubtle: 'light-dark(#fff, #ffffff09)',
33
+ componentOnContainerSubtleHover: 'light-dark(#fff, #ffffff12)',
34
+ componentOnInverted: 'light-dark(#ffffff1a, #0000001a)',
35
+ componentOnSunken: 'light-dark(#fff, #2a2a2a)',
36
+ container: 'light-dark(#fff, #111)',
37
+ containerRecessed: 'light-dark(#fcfcfc, #111)',
38
+ dangerBorderDefault: 'light-dark(#f92d0050, #ff4f3864)',
39
+ dangerBorderSubtle: 'light-dark(#ff35002c, #fd201142)',
40
+ dangerForeground: 'light-dark(#d72400da, #ff6847eb)',
41
+ dangerSolid: '#e54d2e',
42
+ dangerSolidActive: 'light-dark(#d13415, #ff977d)',
43
+ dangerSolidHover: 'light-dark(#dd4425, #ec6142)',
44
+ dangerSubtle: 'light-dark(#ff200008, #ff55330f)',
45
+ dangerSubtleActive: 'light-dark(#ff2e003d, #fe332153)',
46
+ dangerSubtleHover: 'light-dark(#f52b0018, #ff35232b)',
47
+ disabled: 'light-dark(#0000000f, #ffffff09)',
48
+ divider: 'light-dark(#0000000f, #ffffff1f)',
49
+ disabledForeground: 'light-dark(#0004, #fff5)',
50
+ invertedSolid: 'light-dark(#000000f2, #fffffff2)',
51
+ invertedSolidActive: 'light-dark(#000000b3, #ffffffb3)',
52
+ invertedSolidHover: 'light-dark(#000c, #fffc)',
53
+ modal: 'light-dark(oklch(100% 0 0), oklch(25.2% 0 0))',
54
+ onBrandSolidForeground: '#fff',
55
+ onBrandSubtleForeground: 'light-dark(#0090ff, #70b8ff)',
56
+ onDangerSolidForeground: 'light-dark(#fffcfc, #fff)',
57
+ onDangerSubtleForeground: 'light-dark(#df2600d1, #ff977d)',
58
+ onInvertedForeground: 'light-dark(#fff, #000)',
59
+ onPositiveSolidForeground: 'light-dark(#fbfefc, #fff)',
60
+ onPositiveSubtleForeground: 'light-dark(#008f4acf, #46fea5d4)',
61
+ onStandoutPrimaryForeground: 'light-dark(#fff, #ffffffed)',
62
+ onStandoutSecondaryForeground: '#ffffff80',
63
+ onWarningSolidForeground: 'light-dark(#fefcfb, #fff)',
64
+ onWarningSubtleForeground: 'light-dark(#cc4e00, #ffa057)',
65
+ page: 'light-dark(#fff, oklch(15% 0 0))',
66
+ positiveBorderDefault: 'light-dark(#00963c52, #44ffaa4b)',
67
+ positiveForeground: 'light-dark(#008647d4, #43fea4ab)',
68
+ positiveSolid: '#30a46c',
69
+ positiveSolidHover: 'light-dark(#2b9a66, #33b074)',
70
+ positiveSubtle: 'light-dark(#00a43319, #22ff991e)',
71
+ positiveSubtleHover: 'light-dark(#00a83829, #11ff992d)',
72
+ primaryForeground: 'light-dark(#000000df, #ffffffed)',
73
+ secondaryForeground: 'light-dark(#0000009b, #ffffffaf)',
74
+ secondaryForegroundSolid: 'light-dark(#646464, #b4b4b4)',
75
+ shell: 'light-dark(oklch(97.3% 0 0), #000)',
76
+ standout: 'light-dark(#202020, #222)',
77
+ sunken: 'light-dark(#0000000d, #0006)',
78
+ tertiaryForeground: 'light-dark(#00000072, #ffffff64)',
79
+ transparent: '#0000',
80
+ transparentActive: 'light-dark(#0000000f, #ffffff12)',
81
+ transparentHover: 'light-dark(#0000000f, #ffffff1b)',
82
+ warningBorderDefault: 'light-dark(#ff81007d, #fd75045c)',
83
+ warningForeground: 'light-dark(#ef5f00, #ff801f)',
84
+ warningSolid: '#f76b15',
85
+ warningSolidHover: 'light-dark(#ef5f00, #ff801f)',
86
+ warningSubtle: 'light-dark(#ff9c0029, #fb6a0025)',
87
+ warningSubtleHover: 'light-dark(#ff91014a, #ff590039)',
88
+ whiteFill: '#fff',
89
+ dangerText: 'light-dark(#cd2200ea, #ff977d)',
90
+ indicatorBorder: 'light-dark(#d9d9d9, #484848)',
91
+ overlay: 'light-dark(#0006, #0009)'
92
+ });
93
+ export const space = stylex.defineVars({
94
+ xxs: '2px',
95
+ xs: '4px',
96
+ sm: '8px',
97
+ md: '12px',
98
+ lg: '16px',
99
+ xl: '24px',
100
+ xxl: '32px',
101
+ xxxl: '48px'
102
+ });
103
+ export const controls = stylex.defineVars({
104
+ heightXs: '20px',
105
+ heightSm: '24px',
106
+ heightMd: '28px',
107
+ heightLg: '32px',
108
+ heightXl: '40px',
109
+ paddingXs: '6px',
110
+ paddingSm: '8px',
111
+ paddingMd: '10px',
112
+ paddingLg: '12px',
113
+ paddingXl: '14px',
114
+ gapXs: '4px',
115
+ gapSm: '4px',
116
+ gapMd: '6px',
117
+ gapLg: '6px',
118
+ gapXl: '8px'
119
+ });
120
+ export const iconSizes = stylex.defineVars({
121
+ xs: '12px',
122
+ sm: '14px',
123
+ md: '16px',
124
+ lg: '16px',
125
+ xl: '20px'
126
+ });
127
+ export const borders = stylex.defineVars({
128
+ hairline: '0.5px',
129
+ thin: '1px'
130
+ });
131
+ export const widths = stylex.defineVars({
132
+ contentXs: '280px',
133
+ contentSm: '480px',
134
+ contentMd: '640px',
135
+ contentLg: '720px',
136
+ sidebar: '280px',
137
+ toast: '356px'
138
+ });
139
+ export const layers = stylex.defineConsts({
140
+ scrim: '15',
141
+ sidebar: '20',
142
+ menu: '20',
143
+ tooltip: '30',
144
+ dialog: '40',
145
+ toast: '40'
146
+ });
147
+ export const radii = stylex.defineVars({
148
+ xs: '2px',
149
+ sm: '4px',
150
+ md: '6px',
151
+ lg: '8px',
152
+ xl: '10px',
153
+ xxl: '12px',
154
+ xxxl: '16px',
155
+ xxxxl: '20px',
156
+ full: '9999px'
157
+ });
158
+ export const fontSizes = stylex.defineVars({
159
+ captionXs: '8px',
160
+ captionSm: '10px',
161
+ captionBase: '11px',
162
+ captionLg: '12px',
163
+ bodySm: '13px',
164
+ bodyBase: '15px',
165
+ bodyLg: '18px',
166
+ heading6: '20px',
167
+ heading5: '24px',
168
+ heading4: '28px',
169
+ heading3: '36px',
170
+ heading2: '44px',
171
+ heading1: '56px'
172
+ });
173
+ export const lineHeights = stylex.defineVars({
174
+ captionXs: '12px',
175
+ caption: '16px',
176
+ title: '18px',
177
+ bodySm: '20px',
178
+ body: '24px',
179
+ heading6: '24px',
180
+ heading5: '32px',
181
+ heading4: '36px',
182
+ heading3: '44px',
183
+ heading2: '56px',
184
+ heading1: '56px'
185
+ });
186
+ export const fonts = stylex.defineVars({
187
+ sans: '"Inter Variable", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif',
188
+ mono: 'ui-monospace, SFMono-Regular, Menlo, monospace'
189
+ });
190
+ export const fontFeatures = stylex.defineVars({
191
+ sans: '"ss03"',
192
+ kbd: '"ss02"'
193
+ });
194
+ export const fontWeights = stylex.defineVars({
195
+ normal: '400',
196
+ semimedium: '450',
197
+ medium: '500',
198
+ semibold: '600',
199
+ bold: '700'
200
+ });
201
+ export const shadows = stylex.defineVars({
202
+ border: '0 0 0 1px light-dark(#00000012, #ffffff12)',
203
+ default: '0 0 0 .5px light-dark(#0000, #ffffff12) inset, 0 0 0 .5px light-dark(#0000000f, #0000), 0 1px 1px -1px light-dark(#0000001a, #0000), 0 1px 2px 0px light-dark(#0000000d, #0000)',
204
+ large: '0 0 0 .5px light-dark(color-mix(in oklab, #0000000f, #f0f0f0 25%), #0000), 0 0 0 1px light-dark(#0000, color-mix(in oklab, #ffffff12, #3a3a3a 25%)), 0 2px 3px -2px light-dark(#0000000f, #00000026), 0 3px 12px -4px light-dark(#0000001a, #0000), 0 4px 16px -8px light-dark(#0000000d, #0000), 0 3px 8px -2px light-dark(#0000, #0006), 0 4px 12px -4px light-dark(#0000, #00000080)',
205
+ extraLarge: '0 0 0 .5px light-dark(#0000, #ffffff12) inset, 0 0 0 .5px light-dark(#0000000f, #0000), 0 8px 40px 0px #0000000d, 0 12px 32px -16px #00000026'
206
+ });
207
+ export const motion = stylex.defineVars({
208
+ easeOut: 'cubic-bezier(0, 0, .2, 1)',
209
+ easeInOut: 'cubic-bezier(.4, 0, .2, 1)',
210
+ slideEasing: 'cubic-bezier(0.32, 0.72, 0, 1)',
211
+ instant: {
212
+ default: '75ms',
213
+ '@media (prefers-reduced-motion: reduce)': '0ms'
214
+ },
215
+ exit: {
216
+ default: '120ms',
217
+ '@media (prefers-reduced-motion: reduce)': '0ms'
218
+ },
219
+ fast: {
220
+ default: '150ms',
221
+ '@media (prefers-reduced-motion: reduce)': '0ms'
222
+ },
223
+ base: {
224
+ default: '200ms',
225
+ '@media (prefers-reduced-motion: reduce)': '0ms'
226
+ },
227
+ slide: {
228
+ default: '300ms',
229
+ '@media (prefers-reduced-motion: reduce)': '0ms'
230
+ },
231
+ pulse: '2s',
232
+ spin: '1200ms'
233
+ });
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from 'vite';
2
+ export declare function commandBridge(): Plugin;
@@ -0,0 +1,46 @@
1
+ const COMMAND_EVENT = 'pattern:command';
2
+ const REPLY_EVENT = 'pattern:reply';
3
+ const REPLY_TIMEOUT_MS = 3000;
4
+ const NO_APP_OPEN = 'No Pattern app is open in a browser. Open the dev server URL (app start opens it), then send again.';
5
+ export function commandBridge() {
6
+ return {
7
+ name: 'pattern-command-bridge',
8
+ apply: 'serve',
9
+ configureServer(server) {
10
+ const waiting = new Map();
11
+ server.ws.on(REPLY_EVENT, (reply) => {
12
+ waiting.get(reply.id)?.(reply);
13
+ waiting.delete(reply.id);
14
+ });
15
+ server.middlewares.use('/__pattern/send', (request, response) => {
16
+ let body = '';
17
+ request.on('data', (chunk) => (body += chunk.toString()));
18
+ request.on('end', () => {
19
+ const id = crypto.randomUUID();
20
+ const respond = (status, payload) => {
21
+ response.statusCode = status;
22
+ response.setHeader('content-type', 'application/json');
23
+ response.end(JSON.stringify(payload));
24
+ };
25
+ let command;
26
+ try {
27
+ command = JSON.parse(body);
28
+ }
29
+ catch {
30
+ respond(400, { error: `Command is not valid JSON: ${body}` });
31
+ return;
32
+ }
33
+ const timer = setTimeout(() => {
34
+ waiting.delete(id);
35
+ respond(503, { error: NO_APP_OPEN });
36
+ }, REPLY_TIMEOUT_MS);
37
+ waiting.set(id, (reply) => {
38
+ clearTimeout(timer);
39
+ respond(200, reply);
40
+ });
41
+ server.ws.send(COMMAND_EVENT, { id, command });
42
+ });
43
+ });
44
+ }
45
+ };
46
+ }
@@ -0,0 +1,25 @@
1
+ type Counts = Record<string, number>;
2
+ type PrimitiveUse = {
3
+ uses: number;
4
+ props: Record<string, Counts>;
5
+ };
6
+ type TokenEntry = {
7
+ value: string;
8
+ isOverridden: boolean;
9
+ };
10
+ export type DesignManifest = {
11
+ sdk: string;
12
+ tokens: Record<string, Record<string, TokenEntry>>;
13
+ primitives: Record<string, PrimitiveUse>;
14
+ customPieces: {
15
+ name: string;
16
+ file: string;
17
+ tokens: string[];
18
+ }[];
19
+ icons: {
20
+ builtIn: string[];
21
+ app: string[];
22
+ };
23
+ };
24
+ export declare function designManifest(root: string): DesignManifest;
25
+ export {};
@@ -0,0 +1,191 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { basename, extname, join, relative } from 'node:path';
3
+ import ts from 'typescript';
4
+ import { builtInIconNames } from "../components/icons.js";
5
+ import { themeTokens } from "../rules/themeTokens.js";
6
+ const PRIMITIVES_MODULE = '@trypattern/sdk/react';
7
+ const TOKENS_MODULE = '@trypattern/sdk/tokens.stylex';
8
+ const LOOK_PROPS = new Set([
9
+ 'variant',
10
+ 'tone',
11
+ 'size',
12
+ 'surface',
13
+ 'padding',
14
+ 'paddingBlock',
15
+ 'paddingInline',
16
+ 'gap',
17
+ 'align',
18
+ 'justify',
19
+ 'width',
20
+ 'as',
21
+ 'name',
22
+ 'icon',
23
+ 'trailingIcon',
24
+ 'placement'
25
+ ]);
26
+ const DYNAMIC = 'dynamic';
27
+ const SDK_PACKAGE = new URL('../../package.json', import.meta.url);
28
+ function sourceFiles(folder) {
29
+ if (!existsSync(folder))
30
+ return [];
31
+ return readdirSync(folder, { withFileTypes: true }).flatMap((entry) => {
32
+ const path = join(folder, entry.name);
33
+ if (entry.isDirectory())
34
+ return sourceFiles(path);
35
+ return /\.tsx?$/.test(entry.name) ? [path] : [];
36
+ });
37
+ }
38
+ function parse(path) {
39
+ return ts.createSourceFile(path, readFileSync(path, 'utf8'), ts.ScriptTarget.Latest, true, path.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
40
+ }
41
+ function importsFrom(source, module) {
42
+ const names = new Map();
43
+ for (const statement of source.statements) {
44
+ if (!ts.isImportDeclaration(statement) ||
45
+ !ts.isStringLiteral(statement.moduleSpecifier) ||
46
+ statement.moduleSpecifier.text !== module) {
47
+ continue;
48
+ }
49
+ const bindings = statement.importClause?.namedBindings;
50
+ if (bindings === undefined || !ts.isNamedImports(bindings))
51
+ continue;
52
+ for (const element of bindings.elements) {
53
+ names.set(element.name.text, element.propertyName?.text ?? element.name.text);
54
+ }
55
+ }
56
+ return names;
57
+ }
58
+ function literalValues(expression) {
59
+ if (ts.isStringLiteralLike(expression))
60
+ return [expression.text];
61
+ if (ts.isParenthesizedExpression(expression)) {
62
+ return literalValues(expression.expression);
63
+ }
64
+ if (ts.isConditionalExpression(expression)) {
65
+ return [
66
+ ...literalValues(expression.whenTrue),
67
+ ...literalValues(expression.whenFalse)
68
+ ];
69
+ }
70
+ return [DYNAMIC];
71
+ }
72
+ function attributeValues(attribute) {
73
+ const initializer = attribute.initializer;
74
+ if (initializer === undefined)
75
+ return ['true'];
76
+ if (ts.isStringLiteral(initializer))
77
+ return [initializer.text];
78
+ if (ts.isJsxExpression(initializer) && initializer.expression !== undefined) {
79
+ return literalValues(initializer.expression);
80
+ }
81
+ return [DYNAMIC];
82
+ }
83
+ function countPrimitives(source, primitives) {
84
+ const imported = importsFrom(source, PRIMITIVES_MODULE);
85
+ const visit = (node) => {
86
+ const element = ts.isJsxSelfClosingElement(node) || ts.isJsxOpeningElement(node)
87
+ ? node
88
+ : undefined;
89
+ const name = element !== undefined && ts.isIdentifier(element.tagName)
90
+ ? imported.get(element.tagName.text)
91
+ : undefined;
92
+ if (element !== undefined && name !== undefined) {
93
+ const use = (primitives[name] ??= { uses: 0, props: {} });
94
+ use.uses += 1;
95
+ for (const attribute of element.attributes.properties) {
96
+ if (!ts.isJsxAttribute(attribute))
97
+ continue;
98
+ const prop = attribute.name.getText(source);
99
+ if (!LOOK_PROPS.has(prop))
100
+ continue;
101
+ if (prop === 'name' && name !== 'Icon')
102
+ continue;
103
+ const counts = (use.props[prop] ??= {});
104
+ for (const value of new Set(attributeValues(attribute))) {
105
+ counts[value] = (counts[value] ?? 0) + 1;
106
+ }
107
+ }
108
+ }
109
+ ts.forEachChild(node, visit);
110
+ };
111
+ visit(source);
112
+ }
113
+ function customPiece(root, path, source) {
114
+ const tokenGroups = new Set(importsFrom(source, TOKENS_MODULE).keys());
115
+ const tokens = new Set();
116
+ let draws = false;
117
+ const visit = (node) => {
118
+ if (ts.isCallExpression(node) &&
119
+ node.expression.getText(source) === 'stylex.create') {
120
+ draws = true;
121
+ }
122
+ if (ts.isPropertyAccessExpression(node) &&
123
+ ts.isIdentifier(node.expression) &&
124
+ tokenGroups.has(node.expression.text)) {
125
+ tokens.add(`${node.expression.text}.${node.name.text}`);
126
+ }
127
+ ts.forEachChild(node, visit);
128
+ };
129
+ visit(source);
130
+ return draws
131
+ ? [
132
+ {
133
+ name: basename(path, extname(path)),
134
+ file: relative(root, path),
135
+ tokens: [...tokens].toSorted()
136
+ }
137
+ ]
138
+ : [];
139
+ }
140
+ function appIcons(root) {
141
+ const path = join(root, 'src', 'theme', 'icons.ts');
142
+ if (!existsSync(path))
143
+ return [];
144
+ const names = [];
145
+ const visit = (node) => {
146
+ if (ts.isCallExpression(node) &&
147
+ node.expression.getText() === 'defineIcons' &&
148
+ node.arguments[0] !== undefined &&
149
+ ts.isObjectLiteralExpression(node.arguments[0])) {
150
+ for (const property of node.arguments[0].properties) {
151
+ if (property.name !== undefined)
152
+ names.push(property.name.getText());
153
+ }
154
+ }
155
+ ts.forEachChild(node, visit);
156
+ };
157
+ visit(parse(path));
158
+ return names;
159
+ }
160
+ function tokensOf(root) {
161
+ const tokens = {};
162
+ for (const [name, { value, offset }] of themeTokens(root)) {
163
+ const [group = '', key = ''] = name.split('.');
164
+ tokens[group] = {
165
+ ...tokens[group],
166
+ [key]: { value, isOverridden: offset !== undefined }
167
+ };
168
+ }
169
+ return tokens;
170
+ }
171
+ export function designManifest(root) {
172
+ const primitives = {};
173
+ const customPieces = [];
174
+ for (const path of sourceFiles(join(root, 'src'))) {
175
+ const source = parse(path);
176
+ countPrimitives(source, primitives);
177
+ if (path.startsWith(join(root, 'src', 'components'))) {
178
+ customPieces.push(...customPiece(root, path, source));
179
+ }
180
+ }
181
+ const sdk = JSON.parse(readFileSync(SDK_PACKAGE, 'utf8'));
182
+ return {
183
+ sdk: typeof sdk === 'object' && sdk !== null && 'version' in sdk
184
+ ? String(sdk.version)
185
+ : 'unknown',
186
+ tokens: tokensOf(root),
187
+ primitives: Object.fromEntries(Object.entries(primitives).toSorted(([a], [b]) => a.localeCompare(b))),
188
+ customPieces,
189
+ icons: { builtIn: builtInIconNames, app: appIcons(root) }
190
+ };
191
+ }
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from 'vite';
2
+ import type { Seed, Tables } from '../table.ts';
3
+ export declare function resetLocalDatabase(root: string, tables: Tables, seed: Seed<Tables>): void;
4
+ export declare function localWorker<Group extends Tables>(tables: Group, seed: Seed<Group>): Plugin;
@@ -0,0 +1,59 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { appendFileSync, existsSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { seedSql } from "../server/tables.js";
6
+ import { snakeCase } from "../table.js";
7
+ import { toolBin } from "../cli/tools.js";
8
+ function ensureLocalSessionSecret(root) {
9
+ const DEV_VARS = join(root, '.dev.vars');
10
+ const current = existsSync(DEV_VARS) ? readFileSync(DEV_VARS, 'utf8') : '';
11
+ if (/^SESSION_SECRET=/m.test(current))
12
+ return;
13
+ const separator = current === '' || current.endsWith('\n') ? '' : '\n';
14
+ appendFileSync(DEV_VARS, `${separator}SESSION_SECRET=${randomBytes(32).toString('hex')}\n`);
15
+ }
16
+ function wrangler(root, args) {
17
+ execFileSync(process.execPath, [toolBin('wrangler'), ...args], {
18
+ cwd: root,
19
+ stdio: 'pipe',
20
+ env: { ...process.env, CI: '1' }
21
+ });
22
+ }
23
+ export function resetLocalDatabase(root, tables, seed) {
24
+ wrangler(root, ['d1', 'migrations', 'apply', 'DB', '--local']);
25
+ wrangler(root, [
26
+ 'd1',
27
+ 'execute',
28
+ 'DB',
29
+ '--local',
30
+ '--command',
31
+ [
32
+ ...Object.values(tables).map((table) => `DELETE FROM ${snakeCase(table.name)};`),
33
+ seedSql(tables, seed)
34
+ ].join('\n')
35
+ ]);
36
+ }
37
+ function prepareLocalDatabase(root, tables, seed) {
38
+ wrangler(root, ['d1', 'migrations', 'apply', 'DB', '--local']);
39
+ wrangler(root, [
40
+ 'd1',
41
+ 'execute',
42
+ 'DB',
43
+ '--local',
44
+ '--command',
45
+ seedSql(tables, seed)
46
+ ]);
47
+ }
48
+ export function localWorker(tables, seed) {
49
+ return {
50
+ name: 'pattern-local-worker',
51
+ config(config, { command }) {
52
+ if (command !== 'serve')
53
+ return;
54
+ const root = config.root ?? process.cwd();
55
+ ensureLocalSessionSecret(root);
56
+ prepareLocalDatabase(root, tables, seed);
57
+ }
58
+ };
59
+ }
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from 'vite';
2
+ export declare function rootAlias(): Plugin;
@@ -0,0 +1,15 @@
1
+ import { resolve } from 'node:path';
2
+ export function rootAlias() {
3
+ return {
4
+ name: 'pattern-root-alias',
5
+ config(config) {
6
+ const root = resolve(config.root ?? process.cwd());
7
+ return {
8
+ resolve: {
9
+ alias: [{ find: /^@\//, replacement: `${root}/` }],
10
+ dedupe: ['react', 'react-dom', 'react-router', 'zod']
11
+ }
12
+ };
13
+ }
14
+ };
15
+ }
@@ -0,0 +1,7 @@
1
+ import type { Seed, Tables } from '../table.ts';
2
+ export type PatternOptions<Group extends Tables> = {
3
+ tables: Group;
4
+ admins: readonly string[];
5
+ seed?: Seed<Group>;
6
+ };
7
+ export declare function pattern<Group extends Tables>({ tables, admins, seed }: PatternOptions<Group>): import("vite").UserConfig;
@@ -0,0 +1,88 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { extname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { cloudflare } from '@cloudflare/vite-plugin';
5
+ import stylex from '@stylexjs/unplugin';
6
+ import react from '@vitejs/plugin-react';
7
+ import { defineConfig } from 'vitest/config';
8
+ import { commandBridge } from "./commandBridge.js";
9
+ import { designManifest } from "./designManifest.js";
10
+ import { localWorker } from "./localWorker.js";
11
+ import { rootAlias } from "./rootAlias.js";
12
+ const DEV_SERVER_PORT = 5173;
13
+ const VISUAL_FLOW_TIMEOUT_MS = 30_000;
14
+ const CSS_LAYERS_BEFORE_STYLEX = ['reset'];
15
+ const browsersWithNativeLightDark = {
16
+ chrome: 123 << 16,
17
+ firefox: 120 << 16,
18
+ safari: (17 << 16) | (5 << 8)
19
+ };
20
+ const minifyStylexCssAppendedAfterViteMinifies = {
21
+ minify: true,
22
+ targets: browsersWithNativeLightDark
23
+ };
24
+ const reactCompilerSkippingUnchangedRendersAndLoggingWhereItCannot = {
25
+ compiler: { logDiagnostics: true }
26
+ };
27
+ const FLOW_SETUP = fileURLToPath(new URL(`../flows/flowSetup${extname(import.meta.filename)}`, import.meta.url));
28
+ export function pattern({ tables, admins, seed = {} }) {
29
+ const isVitest = process.env['VITEST'] !== undefined;
30
+ const isVisualFlowRun = process.env['PATTERN_VISUAL_URL'] !== undefined;
31
+ const stylexPlugin = stylex.vite({
32
+ useCSSLayers: { before: CSS_LAYERS_BEFORE_STYLEX },
33
+ aliases: { '@/*': [join(process.cwd(), '*')] },
34
+ sxPropName: false,
35
+ lightningcssOptions: minifyStylexCssAppendedAfterViteMinifies
36
+ });
37
+ const stylexWithoutDevCssPollerThatKeepsVitestFromExiting = {
38
+ ...stylexPlugin,
39
+ configureServer: undefined
40
+ };
41
+ const stylexBeforeReactToKeepFastRefresh = [
42
+ isVitest
43
+ ? stylexWithoutDevCssPollerThatKeepsVitestFromExiting
44
+ : stylexPlugin,
45
+ react(reactCompilerSkippingUnchangedRendersAndLoggingWhereItCannot)
46
+ ];
47
+ const workerServingApiInDevAndBuild = isVitest
48
+ ? []
49
+ : [localWorker(tables, seed), cloudflare()];
50
+ return defineConfig({
51
+ plugins: [
52
+ ...stylexBeforeReactToKeepFastRefresh,
53
+ ...workerServingApiInDevAndBuild,
54
+ commandBridge(),
55
+ rootAlias(),
56
+ designFile()
57
+ ],
58
+ clearScreen: false,
59
+ optimizeDeps: { exclude: ['@trypattern/sdk'] },
60
+ build: {
61
+ cssTarget: ['chrome123', 'firefox120', 'safari17.5']
62
+ },
63
+ server: {
64
+ port: DEV_SERVER_PORT,
65
+ strictPort: true
66
+ },
67
+ test: {
68
+ include: ['flows/**/*.flow.ts'],
69
+ server: { deps: { inline: ['@trypattern/sdk'] } },
70
+ provide: { patternSeed: seed, patternAdmins: admins },
71
+ ...(isVisualFlowRun && {
72
+ globalSetup: [FLOW_SETUP],
73
+ testTimeout: VISUAL_FLOW_TIMEOUT_MS
74
+ })
75
+ }
76
+ });
77
+ }
78
+ function designFile() {
79
+ return {
80
+ name: 'pattern:design',
81
+ apply: 'build',
82
+ closeBundle() {
83
+ const root = process.cwd();
84
+ mkdirSync(join(root, 'dist'), { recursive: true });
85
+ writeFileSync(join(root, 'dist', 'design.json'), `${JSON.stringify(designManifest(root), null, 2)}\n`);
86
+ }
87
+ };
88
+ }