termcast 1.4.1 → 1.6.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 (180) hide show
  1. package/dist/build.d.ts.map +1 -1
  2. package/dist/build.js +30 -12
  3. package/dist/build.js.map +1 -1
  4. package/dist/cli.js +0 -40
  5. package/dist/cli.js.map +1 -1
  6. package/dist/compile.d.ts.map +1 -1
  7. package/dist/compile.js +7 -1
  8. package/dist/compile.js.map +1 -1
  9. package/dist/components/bar-graph.d.ts +23 -8
  10. package/dist/components/bar-graph.d.ts.map +1 -1
  11. package/dist/components/bar-graph.js +84 -40
  12. package/dist/components/bar-graph.js.map +1 -1
  13. package/dist/components/dotted-line-graph.d.ts +86 -0
  14. package/dist/components/dotted-line-graph.d.ts.map +1 -0
  15. package/dist/components/dotted-line-graph.js +260 -0
  16. package/dist/components/dotted-line-graph.js.map +1 -0
  17. package/dist/components/extension-preferences.d.ts.map +1 -1
  18. package/dist/components/extension-preferences.js +1 -10
  19. package/dist/components/extension-preferences.js.map +1 -1
  20. package/dist/components/graph.d.ts.map +1 -1
  21. package/dist/components/graph.js +7 -1
  22. package/dist/components/graph.js.map +1 -1
  23. package/dist/components/histogram.d.ts +42 -0
  24. package/dist/components/histogram.d.ts.map +1 -0
  25. package/dist/components/histogram.js +115 -0
  26. package/dist/components/histogram.js.map +1 -0
  27. package/dist/components/horizontal-bar-graph.d.ts +47 -0
  28. package/dist/components/horizontal-bar-graph.d.ts.map +1 -0
  29. package/dist/components/horizontal-bar-graph.js +137 -0
  30. package/dist/components/horizontal-bar-graph.js.map +1 -0
  31. package/dist/components/list.d.ts +9 -0
  32. package/dist/components/list.d.ts.map +1 -1
  33. package/dist/components/list.js +84 -21
  34. package/dist/components/list.js.map +1 -1
  35. package/dist/examples/bar-graph-weekly.js +2 -2
  36. package/dist/examples/bar-graph-weekly.js.map +1 -1
  37. package/dist/examples/charts-showcase-barchart.d.ts +2 -0
  38. package/dist/examples/charts-showcase-barchart.d.ts.map +1 -0
  39. package/dist/examples/charts-showcase-barchart.js +10 -0
  40. package/dist/examples/charts-showcase-barchart.js.map +1 -0
  41. package/dist/examples/charts-showcase-bargraph.d.ts +2 -0
  42. package/dist/examples/charts-showcase-bargraph.d.ts.map +1 -0
  43. package/dist/examples/charts-showcase-bargraph.js +60 -0
  44. package/dist/examples/charts-showcase-bargraph.js.map +1 -0
  45. package/dist/examples/charts-showcase-candle.d.ts +2 -0
  46. package/dist/examples/charts-showcase-candle.d.ts.map +1 -0
  47. package/dist/examples/charts-showcase-candle.js +30 -0
  48. package/dist/examples/charts-showcase-candle.js.map +1 -0
  49. package/dist/examples/charts-showcase-graph.d.ts +2 -0
  50. package/dist/examples/charts-showcase-graph.d.ts.map +1 -0
  51. package/dist/examples/charts-showcase-graph.js +33 -0
  52. package/dist/examples/charts-showcase-graph.js.map +1 -0
  53. package/dist/examples/charts-showcase-heatmap.d.ts +2 -0
  54. package/dist/examples/charts-showcase-heatmap.d.ts.map +1 -0
  55. package/dist/examples/charts-showcase-heatmap.js +36 -0
  56. package/dist/examples/charts-showcase-heatmap.js.map +1 -0
  57. package/dist/examples/charts-showcase-mixed.d.ts +2 -0
  58. package/dist/examples/charts-showcase-mixed.d.ts.map +1 -0
  59. package/dist/examples/charts-showcase-mixed.js +30 -0
  60. package/dist/examples/charts-showcase-mixed.js.map +1 -0
  61. package/dist/examples/charts-showcase-progress.d.ts +2 -0
  62. package/dist/examples/charts-showcase-progress.d.ts.map +1 -0
  63. package/dist/examples/charts-showcase-progress.js +10 -0
  64. package/dist/examples/charts-showcase-progress.js.map +1 -0
  65. package/dist/examples/graph-multi-series.js +1 -1
  66. package/dist/examples/graph-multi-series.js.map +1 -1
  67. package/dist/examples/horizontal-bar-graph-weekly.d.ts +2 -0
  68. package/dist/examples/horizontal-bar-graph-weekly.d.ts.map +1 -0
  69. package/dist/examples/horizontal-bar-graph-weekly.js +67 -0
  70. package/dist/examples/horizontal-bar-graph-weekly.js.map +1 -0
  71. package/dist/examples/list-detail-height-ratchet.d.ts +2 -0
  72. package/dist/examples/list-detail-height-ratchet.d.ts.map +1 -0
  73. package/dist/examples/list-detail-height-ratchet.js +26 -0
  74. package/dist/examples/list-detail-height-ratchet.js.map +1 -0
  75. package/dist/examples/simple-dotted-line-graph.d.ts +2 -0
  76. package/dist/examples/simple-dotted-line-graph.d.ts.map +1 -0
  77. package/dist/examples/simple-dotted-line-graph.js +39 -0
  78. package/dist/examples/simple-dotted-line-graph.js.map +1 -0
  79. package/dist/examples/simple-histogram.d.ts +2 -0
  80. package/dist/examples/simple-histogram.d.ts.map +1 -0
  81. package/dist/examples/simple-histogram.js +47 -0
  82. package/dist/examples/simple-histogram.js.map +1 -0
  83. package/dist/extensions/dev.d.ts.map +1 -1
  84. package/dist/extensions/dev.js +1 -0
  85. package/dist/extensions/dev.js.map +1 -1
  86. package/dist/globals.js +8 -0
  87. package/dist/globals.js.map +1 -1
  88. package/dist/index.d.ts +6 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +6 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/package-json.d.ts +2 -0
  93. package/dist/package-json.d.ts.map +1 -1
  94. package/dist/package-json.js +20 -17
  95. package/dist/package-json.js.map +1 -1
  96. package/dist/platform/node/sqlite.d.ts +6 -5
  97. package/dist/platform/node/sqlite.d.ts.map +1 -1
  98. package/dist/platform/node/sqlite.js +30 -14
  99. package/dist/platform/node/sqlite.js.map +1 -1
  100. package/dist/profiler.d.ts +2 -0
  101. package/dist/profiler.d.ts.map +1 -0
  102. package/dist/profiler.js +390 -0
  103. package/dist/profiler.js.map +1 -0
  104. package/dist/theme.d.ts.map +1 -1
  105. package/dist/theme.js +11 -9
  106. package/dist/theme.js.map +1 -1
  107. package/dist/utils/run-command.d.ts.map +1 -1
  108. package/dist/utils/run-command.js +8 -19
  109. package/dist/utils/run-command.js.map +1 -1
  110. package/dist/utils.d.ts +1 -19
  111. package/dist/utils.d.ts.map +1 -1
  112. package/dist/utils.js +1 -100
  113. package/dist/utils.js.map +1 -1
  114. package/package.json +18 -21
  115. package/src/build.tsx +38 -15
  116. package/src/cli.tsx +3 -40
  117. package/src/compile.tsx +9 -1
  118. package/src/compile.vitest.tsx +8 -8
  119. package/src/components/bar-graph.tsx +217 -111
  120. package/src/components/dotted-line-graph.tsx +407 -0
  121. package/src/components/extension-preferences.tsx +2 -12
  122. package/src/components/graph.tsx +5 -1
  123. package/src/components/histogram.tsx +228 -0
  124. package/src/components/horizontal-bar-graph.tsx +279 -0
  125. package/src/components/list.tsx +112 -26
  126. package/src/examples/action-shortcut.vitest.tsx +20 -20
  127. package/src/examples/actions-context.vitest.tsx +2 -2
  128. package/src/examples/bar-graph-weekly.tsx +2 -2
  129. package/src/examples/bar-graph-weekly.vitest.tsx +103 -102
  130. package/src/examples/charts-showcase-bargraph.tsx +103 -0
  131. package/src/examples/detail-metadata-showcase.vitest.tsx +12 -12
  132. package/src/examples/form-basic.vitest.tsx +11 -11
  133. package/src/examples/form-dropdown.vitest.tsx +11 -11
  134. package/src/examples/form-scroll.vitest.tsx +1 -1
  135. package/src/examples/form-tagpicker.vitest.tsx +11 -11
  136. package/src/examples/github.vitest.tsx +22 -31
  137. package/src/examples/graph-bar-chart.vitest.tsx +36 -36
  138. package/src/examples/graph-multi-series.tsx +1 -1
  139. package/src/examples/graph-polymarket.vitest.tsx +24 -24
  140. package/src/examples/graph-row.vitest.tsx +14 -14
  141. package/src/examples/graph-styles.vitest.tsx +77 -77
  142. package/src/examples/horizontal-bar-graph-weekly.tsx +138 -0
  143. package/src/examples/horizontal-bar-graph-weekly.vitest.tsx +164 -0
  144. package/src/examples/list-detail-height-ratchet.tsx +48 -0
  145. package/src/examples/list-detail-height-ratchet.vitest.tsx +161 -0
  146. package/src/examples/list-detail-metadata.vitest.tsx +51 -51
  147. package/src/examples/list-dropdown-default.vitest.tsx +27 -27
  148. package/src/examples/list-fetch-data.vitest.tsx +3 -3
  149. package/src/examples/list-loading-empty-view.vitest.tsx +1 -1
  150. package/src/examples/list-no-actions.vitest.tsx +3 -3
  151. package/src/examples/list-scrollbox.vitest.tsx +6 -6
  152. package/src/examples/list-spacing-mode.vitest.tsx +1 -1
  153. package/src/examples/list-with-detail.vitest.tsx +55 -55
  154. package/src/examples/list-with-dropdown.vitest.tsx +6 -6
  155. package/src/examples/list-with-sections.vitest.tsx +20 -20
  156. package/src/examples/list-with-toast.vitest.tsx +4 -4
  157. package/src/examples/simple-candle-chart.vitest.tsx +61 -59
  158. package/src/examples/simple-dotted-line-graph.tsx +53 -0
  159. package/src/examples/simple-dotted-line-graph.vitest.tsx +62 -0
  160. package/src/examples/simple-grid.vitest.tsx +4 -4
  161. package/src/examples/simple-heatmap.vitest.tsx +9 -9
  162. package/src/examples/simple-histogram.tsx +90 -0
  163. package/src/examples/simple-navigation.vitest.tsx +25 -25
  164. package/src/examples/simple-progress-bar.vitest.tsx +7 -7
  165. package/src/examples/swift-extension.vitest.tsx +5 -5
  166. package/src/examples/toast-action.vitest.tsx +4 -4
  167. package/src/extensions/dev.tsx +2 -1
  168. package/src/extensions/dev.vitest.tsx +17 -17
  169. package/src/globals.ts +9 -0
  170. package/src/index.tsx +21 -0
  171. package/src/package-json.tsx +24 -23
  172. package/src/platform/node/sqlite.ts +29 -13
  173. package/src/profiler.tsx +487 -0
  174. package/src/theme.tsx +11 -10
  175. package/src/utils/run-command.tsx +10 -19
  176. package/src/utils.tsx +0 -163
  177. package/src/examples/store.tsx +0 -4
  178. package/src/examples/store.vitest.tsx +0 -78
  179. package/src/extensions/home.tsx +0 -227
  180. package/src/extensions/store.tsx +0 -375
@@ -1,375 +0,0 @@
1
- import React, { useState } from 'react'
2
- import fs from 'node:fs'
3
- import path from 'node:path'
4
- import dedent from 'string-dedent'
5
- import { useQuery } from '@tanstack/react-query'
6
- import {
7
- List,
8
- Detail,
9
- Action,
10
- ActionPanel,
11
- showToast,
12
- Toast,
13
- Icon,
14
- } from 'termcast'
15
- import { useNavigation } from 'termcast/src/internal/navigation'
16
- import { ExtensionPreferences } from '../components/extension-preferences'
17
- import { searchStoreListings } from '../store-api/search'
18
- import { fetchExtension } from '../store-api/extension'
19
- import { downloadExtension } from '../store-api/download'
20
- import { getStoreDirectory } from '../utils'
21
- import { buildExtensionCommands } from '../build'
22
- import { logger } from '../logger'
23
- import { parsePackageJson } from '../package-json'
24
- import Home from './home'
25
- import {
26
- checkExtensionPreferences,
27
- type ExtensionPreferencesInfo,
28
- } from '../utils'
29
-
30
- interface StoreListing {
31
- id: string
32
- name: string
33
- author: {
34
- name: string
35
- handle: string
36
- }
37
- owner: {
38
- name: string
39
- handle: string
40
- }
41
- title: string
42
- description: string
43
- download_count: number
44
- updated_at: number
45
- categories: string[]
46
- commands: Array<{
47
- title: string
48
- description: string
49
- mode: string
50
- }>
51
- }
52
-
53
- function StoreSearch(): any {
54
- const [searchQuery, setSearchQuery] = useState('')
55
- const { push } = useNavigation()
56
-
57
- const {
58
- isLoading,
59
- isPending,
60
- isFetching,
61
- data: extensions,
62
- error,
63
- } = useQuery({
64
- queryKey: ['store-search', searchQuery],
65
- queryFn: async () => {
66
- // If no query, use 'raycast' to get default popular extensions
67
- const query = searchQuery.trim() || 'raycast'
68
- logger.log(`Store searching for: "${query}"`)
69
- const response = await searchStoreListings({ query })
70
- logger.log(`Store search returned ${response.data?.length || 0} results`)
71
- return response.data
72
- },
73
- placeholderData: (previousData) => previousData, // Keep previous data while fetching
74
- })
75
-
76
- // Show error toast if query fails
77
- React.useEffect(() => {
78
- if (error) {
79
- showToast({
80
- style: Toast.Style.Failure,
81
- title: 'Search failed',
82
- message: (error as Error).message,
83
- })
84
- }
85
- }, [error])
86
-
87
- return (
88
- <List
89
- navigationTitle='Store - Install Extensions'
90
- searchBarPlaceholder='Search extensions...'
91
- filtering={false}
92
- onSearchTextChange={setSearchQuery}
93
- isLoading={isPending || isFetching}
94
- >
95
- {extensions?.map((ext) => (
96
- <List.Item
97
- key={ext.id}
98
- id={ext.id}
99
- title={ext.title}
100
- subtitle={ext.description}
101
- accessories={[]}
102
- keywords={ext.categories}
103
- actions={
104
- <ActionPanel>
105
- <Action
106
- title='View Details'
107
- onAction={() => {
108
- const Component = () => <ExtensionDetails extension={ext} />
109
- Component.displayName = `store-extension-${ext.name}`
110
- push(<Component />)
111
- }}
112
- />
113
- <Action.OpenInBrowser
114
- url={`https://raycast.com/${ext.owner.handle}/${ext.name}`}
115
- title='Open in Raycast Store'
116
- />
117
- </ActionPanel>
118
- }
119
- />
120
- ))}
121
- </List>
122
- )
123
- }
124
-
125
- function ExtensionDetails({ extension }: { extension: StoreListing }): any {
126
- const [isInstalling, setIsInstalling] = useState(false)
127
- const [isInstalled, setIsInstalled] = useState(false)
128
- const [extensionInfo, setExtensionInfo] = useState<ExtensionPreferencesInfo>({
129
- hasPreferences: false,
130
- hasRequiredPreferences: false,
131
- })
132
- const { pop, push } = useNavigation()
133
-
134
- // Check if extension is already installed and get preferences info
135
- React.useEffect(() => {
136
- const storeDir = getStoreDirectory()
137
- const extensionDir = path.join(storeDir, extension.name)
138
- const installed = fs.existsSync(extensionDir)
139
- setIsInstalled(installed)
140
-
141
- // Check preferences info if installed
142
- if (installed) {
143
- const prefsInfo = checkExtensionPreferences(extension.name)
144
- setExtensionInfo(prefsInfo)
145
- }
146
- }, [extension.name])
147
-
148
- const formatDate = (timestamp: number) => {
149
- return new Date(timestamp * 1000).toLocaleDateString('en-US', {
150
- year: 'numeric',
151
- month: 'long',
152
- day: 'numeric',
153
- })
154
- }
155
-
156
- const handleInstall = async () => {
157
- setIsInstalling(true)
158
- try {
159
- await showToast({
160
- style: Toast.Style.Animated,
161
- title: 'Downloading extension...',
162
- })
163
-
164
- const files = await downloadExtension({
165
- author: extension.owner.handle,
166
- extension: extension.name,
167
- })
168
-
169
- const storeDir = getStoreDirectory()
170
- const extensionDir = path.join(storeDir, extension.name)
171
-
172
- if (fs.existsSync(extensionDir)) {
173
- fs.rmSync(extensionDir, { recursive: true, force: true })
174
- }
175
-
176
- fs.mkdirSync(extensionDir, { recursive: true })
177
-
178
- // Write all files to the extension directory
179
- for (const file of files) {
180
- const filePath = path.join(extensionDir, file.filename)
181
- const fileDir = path.dirname(filePath)
182
-
183
- if (!fs.existsSync(fileDir)) {
184
- fs.mkdirSync(fileDir, { recursive: true })
185
- }
186
-
187
- fs.writeFileSync(filePath, file.buffer)
188
- }
189
-
190
- await showToast({
191
- style: Toast.Style.Animated,
192
- title: 'Building extension...',
193
- })
194
-
195
- // Build the extension commands to create bundles
196
- try {
197
- const buildResult = await buildExtensionCommands({
198
- extensionPath: extensionDir,
199
- format: 'cjs',
200
- target: 'node',
201
- })
202
- logger.log(
203
- `Built ${buildResult.commands.length} commands for ${extension.name}`,
204
- )
205
- } catch (buildError: any) {
206
- // Log build error but don't fail installation
207
- logger.error(
208
- `Failed to build extension commands: ${buildError.message}`,
209
- )
210
- await showToast({
211
- style: Toast.Style.Animated,
212
- title: 'Warning',
213
- message: buildError?.message,
214
- })
215
- return
216
- }
217
-
218
- await showToast({
219
- style: Toast.Style.Success,
220
- title: 'Extension installed',
221
- message: `${extension.title} has been installed successfully`,
222
- })
223
-
224
- logger.log(`Extension '${extension.name}' installed to ${extensionDir}`)
225
- setIsInstalled(true)
226
-
227
- // Update extension info after installation
228
- const prefsInfo = checkExtensionPreferences(extension.name)
229
- setExtensionInfo(prefsInfo)
230
-
231
- // Ask if user wants to configure preferences
232
- await showToast({
233
- style: Toast.Style.Success,
234
- title: 'Configure preferences?',
235
- message: 'Would you like to configure extension preferences now?',
236
- primaryAction: {
237
- title: 'Configure',
238
- onAction: () => {
239
- const Component = () => (
240
- <ExtensionPreferences extensionName={extension.name} />
241
- )
242
- Component.displayName = `store-preferences-${extension.name}`
243
- push(<Component />)
244
- },
245
- },
246
- })
247
- } catch (error: any) {
248
- await showToast({
249
- style: Toast.Style.Failure,
250
- title: 'Installation failed',
251
- message: error.message,
252
- })
253
- } finally {
254
- setIsInstalling(false)
255
- }
256
- }
257
-
258
- const markdownContent = dedent`
259
- # ${extension.title}
260
-
261
- ${extension.description}
262
-
263
- ## Commands
264
-
265
- ${extension.commands
266
- .map(
267
- (cmd) => dedent`
268
- ### ${cmd.title}
269
- ${cmd.description || 'No description available'}
270
- **Mode:** ${cmd.mode}
271
- `,
272
- )
273
- .join('\n\n')}
274
-
275
- ## Information
276
-
277
- - **Author:** ${extension.author.name} (@${extension.author.handle})
278
- - **Downloads:** ${extension.download_count.toLocaleString()}
279
- - **Last Updated:** ${formatDate(extension.updated_at)}
280
- - **Categories:** ${extension.categories.join(', ')}
281
- `
282
-
283
- return (
284
- <Detail
285
- navigationTitle={extension.title}
286
- markdown={markdownContent}
287
- metadata={
288
- <Detail.Metadata>
289
- <Detail.Metadata.Label title='Author' text={extension.author.name} />
290
- <Detail.Metadata.Label
291
- title='Downloads'
292
- text={extension.download_count.toLocaleString()}
293
- />
294
- <Detail.Metadata.Label
295
- title='Commands'
296
- text={extension.commands.length.toString()}
297
- />
298
- <Detail.Metadata.Separator />
299
- <Detail.Metadata.Label
300
- title='Updated'
301
- text={formatDate(extension.updated_at)}
302
- />
303
- <Detail.Metadata.TagList title='Categories'>
304
- {extension.categories.map((cat, index) => (
305
- <Detail.Metadata.TagList.Item text={cat} />
306
- ))}
307
- </Detail.Metadata.TagList>
308
- </Detail.Metadata>
309
- }
310
- actions={
311
- <ActionPanel>
312
- {!isInstalled ? (
313
- <Action
314
- title={isInstalling ? 'Installing...' : 'Install Extension'}
315
- onAction={handleInstall}
316
- />
317
- ) : (
318
- <>
319
- {extensionInfo.hasRequiredPreferences && (
320
- <Action
321
- title='Configure Extension'
322
- onAction={() => {
323
- const Component = () => (
324
- <ExtensionPreferences extensionName={extension.name} />
325
- )
326
- Component.displayName = `store-preferences-${extension.name}`
327
- push(<Component />)
328
- }}
329
- />
330
- )}
331
- <Action
332
- title='Use Extension'
333
- onAction={() => {
334
- const Component = () => (
335
- <Home
336
- key={extension.name}
337
- initialSearchQuery={extension.name}
338
- />
339
- )
340
- Component.displayName = `store-home-${extension.name}`
341
- push(<Component />)
342
- }}
343
- />
344
- {extensionInfo.hasPreferences &&
345
- !extensionInfo.hasRequiredPreferences && (
346
- <Action
347
- title='Configure Extension'
348
- onAction={() => {
349
- const Component = () => (
350
- <ExtensionPreferences extensionName={extension.name} />
351
- )
352
- Component.displayName = `store-preferences-${extension.name}`
353
- push(<Component />)
354
- }}
355
- />
356
- )}
357
- <Action title='Reinstall Extension' onAction={handleInstall} />
358
- </>
359
- )}
360
- <Action.OpenInBrowser
361
- url={`https://raycast.com/${extension.owner.handle}/${extension.name}`}
362
- title='View in Raycast Store'
363
- />
364
- </ActionPanel>
365
- }
366
- />
367
- )
368
- }
369
- ExtensionDetails.displayName = 'ExtensionDetails'
370
-
371
- StoreSearch.displayName = 'StoreSearch'
372
- export default function Store(): any {
373
- return <StoreSearch />
374
- }
375
- Store.displayName = 'Store'