@motiadev/workbench 0.14.0-beta.165-516298 → 0.14.0-beta.165-285707
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.
- package/dist/index.d.ts +10 -189
- package/dist/index.html +1 -1
- package/dist/index.js +7 -1065
- package/dist/middleware.d.ts +8 -66
- package/dist/middleware.js +86 -694
- package/dist/motia-plugin/__tests__/generator.test.d.ts +1 -0
- package/dist/motia-plugin/__tests__/generator.test.js +97 -0
- package/dist/motia-plugin/__tests__/resolver.test.d.ts +1 -0
- package/dist/motia-plugin/__tests__/resolver.test.js +64 -0
- package/dist/motia-plugin/__tests__/validator.test.d.ts +1 -0
- package/dist/motia-plugin/__tests__/validator.test.js +59 -0
- package/dist/motia-plugin/generator.d.ts +78 -0
- package/dist/motia-plugin/{generator.ts → generator.js} +35 -37
- package/dist/motia-plugin/hmr.d.ts +22 -0
- package/dist/motia-plugin/hmr.js +100 -0
- package/dist/motia-plugin/index.d.ts +3 -0
- package/dist/motia-plugin/index.js +153 -0
- package/dist/motia-plugin/{resolver.ts → resolver.d.ts} +5 -38
- package/dist/motia-plugin/resolver.js +92 -0
- package/dist/motia-plugin/types.d.ts +169 -0
- package/dist/motia-plugin/types.js +36 -0
- package/dist/motia-plugin/{utils.ts → utils.d.ts} +4 -17
- package/dist/motia-plugin/utils.js +75 -0
- package/dist/motia-plugin/validator.d.ts +19 -0
- package/dist/motia-plugin/validator.js +163 -0
- package/dist/src/App.d.ts +2 -0
- package/dist/src/App.js +35 -0
- package/dist/src/components/NotFoundPage.d.ts +1 -0
- package/dist/src/components/NotFoundPage.js +3 -0
- package/dist/src/components/bottom-panel.d.ts +1 -0
- package/dist/src/components/bottom-panel.js +15 -0
- package/dist/src/components/flow/base-edge.d.ts +3 -0
- package/dist/src/components/flow/base-edge.js +39 -0
- package/dist/src/components/flow/flow-loader.d.ts +1 -0
- package/dist/src/components/flow/flow-loader.js +4 -0
- package/dist/src/components/flow/flow-page.d.ts +1 -0
- package/dist/src/components/flow/flow-page.js +25 -0
- package/dist/src/components/flow/flow-tab-menu-item.d.ts +1 -0
- package/dist/src/components/flow/flow-tab-menu-item.js +18 -0
- package/dist/src/components/flow/flow-view.d.ts +12 -0
- package/dist/src/components/flow/flow-view.js +22 -0
- package/dist/src/components/flow/hooks/use-get-flow-state.d.ts +10 -0
- package/dist/src/components/flow/hooks/use-get-flow-state.js +133 -0
- package/dist/src/components/flow/hooks/use-save-workflow-config.d.ts +2 -0
- package/dist/src/components/flow/hooks/use-save-workflow-config.js +22 -0
- package/dist/src/components/flow/node-organizer.d.ts +10 -0
- package/dist/src/components/flow/node-organizer.js +82 -0
- package/dist/src/components/flow/nodes/api-flow-node.d.ts +2 -0
- package/dist/src/components/flow/nodes/api-flow-node.js +5 -0
- package/dist/src/components/flow/nodes/cron-flow-node.d.ts +2 -0
- package/dist/src/components/flow/nodes/cron-flow-node.js +5 -0
- package/dist/src/components/flow/nodes/event-flow-node.d.ts +2 -0
- package/dist/src/components/flow/nodes/event-flow-node.js +5 -0
- package/dist/src/components/flow/nodes/noop-flow-node.d.ts +2 -0
- package/dist/src/components/flow/nodes/noop-flow-node.js +5 -0
- package/dist/src/components/header/deploy-button.d.ts +1 -0
- package/dist/src/components/header/deploy-button.js +28 -0
- package/dist/src/components/header/header.d.ts +2 -0
- package/dist/src/components/header/header.js +23 -0
- package/dist/src/components/root-motia.d.ts +2 -0
- package/dist/src/components/root-motia.js +7 -0
- package/dist/src/components/top-panel.d.ts +1 -0
- package/dist/src/components/top-panel.js +15 -0
- package/dist/src/components/tutorial/engine/tutorial-engine.d.ts +12 -0
- package/dist/src/components/tutorial/engine/tutorial-engine.js +36 -0
- package/dist/src/components/tutorial/engine/tutorial-types.d.ts +22 -0
- package/dist/src/components/tutorial/engine/tutorial-types.js +1 -0
- package/dist/src/components/tutorial/engine/workbench-xpath.d.ts +45 -0
- package/dist/src/components/tutorial/engine/workbench-xpath.js +45 -0
- package/dist/src/components/tutorial/hooks/tutorial-utils.d.ts +1 -0
- package/dist/src/components/tutorial/hooks/tutorial-utils.js +17 -0
- package/dist/src/components/tutorial/hooks/use-tutorial-engine.d.ts +15 -0
- package/dist/src/components/tutorial/hooks/use-tutorial-engine.js +183 -0
- package/dist/src/components/tutorial/hooks/use-tutorial.d.ts +5 -0
- package/dist/src/components/tutorial/hooks/use-tutorial.js +10 -0
- package/dist/src/components/tutorial/tutorial-button.d.ts +2 -0
- package/dist/src/components/tutorial/tutorial-button.js +21 -0
- package/dist/src/components/tutorial/tutorial-step.d.ts +14 -0
- package/dist/src/components/tutorial/tutorial-step.js +19 -0
- package/dist/src/components/tutorial/tutorial.d.ts +2 -0
- package/dist/src/components/tutorial/tutorial.js +32 -0
- package/dist/src/components/ui/json-editor.d.ts +12 -0
- package/dist/src/components/ui/json-editor.js +35 -0
- package/dist/src/components/ui/table.d.ts +10 -0
- package/dist/src/components/ui/table.js +20 -0
- package/dist/src/components/ui/theme-toggle.d.ts +2 -0
- package/dist/src/components/ui/theme-toggle.js +19 -0
- package/dist/src/components/ui/tooltip.d.ts +6 -0
- package/dist/src/components/ui/tooltip.js +3 -0
- package/dist/src/hooks/use-debounced.d.ts +1 -0
- package/dist/src/hooks/use-debounced.js +18 -0
- package/dist/src/hooks/use-fetch-flows.d.ts +1 -0
- package/dist/src/hooks/use-fetch-flows.js +26 -0
- package/dist/src/hooks/use-mobile.d.ts +1 -0
- package/dist/src/hooks/use-mobile.js +15 -0
- package/dist/src/hooks/use-update-handle-positions.d.ts +10 -0
- package/dist/src/hooks/use-update-handle-positions.js +35 -0
- package/dist/src/index.css +5 -5
- package/dist/src/lib/__tests__/utils.test.d.ts +1 -0
- package/dist/src/lib/__tests__/utils.test.js +94 -0
- package/dist/src/lib/motia-analytics.d.ts +38 -0
- package/dist/src/lib/motia-analytics.js +132 -0
- package/dist/src/lib/plugins.d.ts +2 -0
- package/dist/src/lib/plugins.js +105 -0
- package/dist/src/lib/utils.d.ts +7 -0
- package/dist/src/lib/utils.js +34 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.js +17 -0
- package/dist/src/project-view-mode.d.ts +1 -0
- package/dist/src/project-view-mode.js +20 -0
- package/dist/src/publicComponents/api-node.d.ts +5 -0
- package/dist/src/publicComponents/api-node.js +5 -0
- package/dist/src/publicComponents/base-node/base-handle.d.ts +9 -0
- package/dist/src/publicComponents/base-node/base-handle.js +8 -0
- package/dist/src/publicComponents/base-node/base-node.d.ts +15 -0
- package/dist/src/publicComponents/base-node/base-node.js +30 -0
- package/dist/src/publicComponents/base-node/code-display.d.ts +9 -0
- package/dist/src/publicComponents/base-node/code-display.js +64 -0
- package/dist/src/publicComponents/base-node/emits.d.ts +5 -0
- package/dist/src/publicComponents/base-node/emits.js +5 -0
- package/dist/src/publicComponents/base-node/feature-card.d.ts +10 -0
- package/dist/src/publicComponents/base-node/feature-card.js +5 -0
- package/dist/src/publicComponents/base-node/language-indicator.d.ts +10 -0
- package/dist/src/publicComponents/base-node/language-indicator.js +29 -0
- package/dist/src/publicComponents/base-node/node-header.d.ts +13 -0
- package/dist/src/publicComponents/base-node/node-header.js +30 -0
- package/dist/src/publicComponents/base-node/node-sidebar.d.ts +14 -0
- package/dist/src/publicComponents/base-node/node-sidebar.js +9 -0
- package/dist/src/publicComponents/base-node/subscribe.d.ts +4 -0
- package/dist/src/publicComponents/base-node/subscribe.js +4 -0
- package/dist/src/publicComponents/cron-node.d.ts +4 -0
- package/dist/src/publicComponents/cron-node.js +6 -0
- package/dist/src/publicComponents/event-node.d.ts +4 -0
- package/dist/src/publicComponents/event-node.js +5 -0
- package/dist/src/publicComponents/node-props.d.ts +21 -0
- package/dist/src/publicComponents/node-props.js +1 -0
- package/dist/src/publicComponents/noop-node.d.ts +4 -0
- package/dist/src/publicComponents/noop-node.js +5 -0
- package/dist/src/setupTests.d.ts +1 -0
- package/dist/src/setupTests.js +1 -0
- package/dist/src/stores/use-app-tabs-store.d.ts +16 -0
- package/dist/src/stores/use-app-tabs-store.js +31 -0
- package/dist/src/stores/use-flow-store.d.ts +21 -0
- package/dist/src/stores/use-flow-store.js +16 -0
- package/dist/src/stores/use-global-store.d.ts +18 -0
- package/dist/src/stores/use-global-store.js +12 -0
- package/dist/src/stores/use-motia-config-store.d.ts +12 -0
- package/dist/src/stores/use-motia-config-store.js +24 -0
- package/dist/src/stores/use-tabs-store.d.ts +19 -0
- package/dist/src/stores/use-tabs-store.js +22 -0
- package/dist/src/system-view-mode.d.ts +1 -0
- package/dist/src/system-view-mode.js +10 -0
- package/dist/src/types/endpoint.d.ts +14 -0
- package/dist/src/types/endpoint.js +1 -0
- package/dist/src/types/file.d.ts +7 -0
- package/dist/src/types/file.js +1 -0
- package/dist/src/types/flow.d.ts +115 -0
- package/dist/src/types/flow.js +1 -0
- package/dist/tsconfig.app.tsbuildinfo +1 -0
- package/dist/tsconfig.node.tsbuildinfo +1 -0
- package/package.json +51 -53
- package/dist/motia-plugin/__tests__/generator.test.ts +0 -129
- package/dist/motia-plugin/__tests__/resolver.test.ts +0 -82
- package/dist/motia-plugin/__tests__/validator.test.ts +0 -71
- package/dist/motia-plugin/hmr.ts +0 -123
- package/dist/motia-plugin/index.ts +0 -183
- package/dist/motia-plugin/types.ts +0 -198
- package/dist/motia-plugin/validator.ts +0 -197
- package/dist/src/App.tsx +0 -41
- package/dist/src/components/NotFoundPage.tsx +0 -11
- package/dist/src/components/bottom-panel.tsx +0 -39
- package/dist/src/components/flow/base-edge.tsx +0 -61
- package/dist/src/components/flow/flow-loader.tsx +0 -3
- package/dist/src/components/flow/flow-page.tsx +0 -75
- package/dist/src/components/flow/flow-tab-menu-item.tsx +0 -52
- package/dist/src/components/flow/flow-view.tsx +0 -66
- package/dist/src/components/flow/hooks/use-get-flow-state.tsx +0 -171
- package/dist/src/components/flow/hooks/use-save-workflow-config.ts +0 -25
- package/dist/src/components/flow/node-organizer.tsx +0 -103
- package/dist/src/components/flow/nodes/api-flow-node.tsx +0 -6
- package/dist/src/components/flow/nodes/cron-flow-node.tsx +0 -6
- package/dist/src/components/flow/nodes/event-flow-node.tsx +0 -6
- package/dist/src/components/flow/nodes/noop-flow-node.tsx +0 -6
- package/dist/src/components/header/deploy-button.tsx +0 -110
- package/dist/src/components/header/header.tsx +0 -39
- package/dist/src/components/root-motia.tsx +0 -10
- package/dist/src/components/top-panel.tsx +0 -40
- package/dist/src/components/tutorial/engine/tutorial-engine.ts +0 -26
- package/dist/src/components/tutorial/engine/tutorial-types.ts +0 -26
- package/dist/src/components/tutorial/engine/workbench-xpath.ts +0 -53
- package/dist/src/components/tutorial/hooks/tutorial-utils.ts +0 -26
- package/dist/src/components/tutorial/hooks/use-tutorial-engine.ts +0 -213
- package/dist/src/components/tutorial/hooks/use-tutorial.ts +0 -14
- package/dist/src/components/tutorial/tutorial-button.tsx +0 -46
- package/dist/src/components/tutorial/tutorial-step.tsx +0 -82
- package/dist/src/components/tutorial/tutorial.tsx +0 -59
- package/dist/src/components/ui/json-editor.tsx +0 -68
- package/dist/src/components/ui/table.tsx +0 -75
- package/dist/src/components/ui/theme-toggle.tsx +0 -54
- package/dist/src/components/ui/tooltip.tsx +0 -26
- package/dist/src/hooks/use-debounced.ts +0 -22
- package/dist/src/hooks/use-fetch-flows.ts +0 -33
- package/dist/src/hooks/use-mobile.ts +0 -19
- package/dist/src/hooks/use-update-handle-positions.ts +0 -42
- package/dist/src/lib/__tests__/utils.test.ts +0 -110
- package/dist/src/lib/motia-analytics.ts +0 -140
- package/dist/src/lib/plugins.tsx +0 -132
- package/dist/src/lib/utils.ts +0 -37
- package/dist/src/main.tsx +0 -30
- package/dist/src/project-view-mode.tsx +0 -32
- package/dist/src/publicComponents/api-node.tsx +0 -26
- package/dist/src/publicComponents/base-node/base-handle.tsx +0 -50
- package/dist/src/publicComponents/base-node/base-node.tsx +0 -114
- package/dist/src/publicComponents/base-node/code-display.tsx +0 -119
- package/dist/src/publicComponents/base-node/emits.tsx +0 -17
- package/dist/src/publicComponents/base-node/feature-card.tsx +0 -32
- package/dist/src/publicComponents/base-node/language-indicator.tsx +0 -131
- package/dist/src/publicComponents/base-node/node-header.tsx +0 -49
- package/dist/src/publicComponents/base-node/node-sidebar.tsx +0 -41
- package/dist/src/publicComponents/base-node/subscribe.tsx +0 -13
- package/dist/src/publicComponents/cron-node.tsx +0 -24
- package/dist/src/publicComponents/event-node.tsx +0 -20
- package/dist/src/publicComponents/node-props.tsx +0 -15
- package/dist/src/publicComponents/noop-node.tsx +0 -19
- package/dist/src/setupTests.ts +0 -1
- package/dist/src/stores/use-app-tabs-store.ts +0 -49
- package/dist/src/stores/use-flow-store.ts +0 -31
- package/dist/src/stores/use-global-store.ts +0 -24
- package/dist/src/stores/use-motia-config-store.ts +0 -36
- package/dist/src/stores/use-tabs-store.ts +0 -34
- package/dist/src/system-view-mode.tsx +0 -28
- package/dist/src/types/endpoint.ts +0 -12
- package/dist/src/types/file.ts +0 -7
- package/dist/src/types/flow.ts +0 -103
- package/eslint.config.cjs +0 -22
- package/jest.config.cjs +0 -68
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateCssImports,
|
|
3
|
-
generateImports,
|
|
4
|
-
generatePackageMap,
|
|
5
|
-
generatePluginCode,
|
|
6
|
-
generatePluginLogic,
|
|
7
|
-
isValidCode,
|
|
8
|
-
} from '../generator'
|
|
9
|
-
import type { WorkbenchPlugin } from '../types'
|
|
10
|
-
|
|
11
|
-
describe('Generator', () => {
|
|
12
|
-
describe('generateImports', () => {
|
|
13
|
-
it('should generate import statements', () => {
|
|
14
|
-
const packages = ['@test/plugin-1', '@test/plugin-2']
|
|
15
|
-
const imports = generateImports(packages)
|
|
16
|
-
|
|
17
|
-
expect(imports).toContain("import * as plugin_0 from '@test/plugin-1'")
|
|
18
|
-
expect(imports).toContain("import * as plugin_1 from '@test/plugin-2'")
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should handle empty package array', () => {
|
|
22
|
-
const imports = generateImports([])
|
|
23
|
-
|
|
24
|
-
expect(imports).toBe('')
|
|
25
|
-
})
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
describe('generatePackageMap', () => {
|
|
29
|
-
it('should generate package map', () => {
|
|
30
|
-
const packages = ['@test/plugin-1', '@test/plugin-2']
|
|
31
|
-
const map = generatePackageMap(packages)
|
|
32
|
-
|
|
33
|
-
expect(map).toContain('const packageMap')
|
|
34
|
-
expect(map).toContain("'@test/plugin-1': plugin_0")
|
|
35
|
-
expect(map).toContain("'@test/plugin-2': plugin_1")
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
describe('generatePluginLogic', () => {
|
|
40
|
-
it('should generate plugin processing logic', () => {
|
|
41
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin', label: 'Test' }]
|
|
42
|
-
const logic = generatePluginLogic(plugins)
|
|
43
|
-
|
|
44
|
-
expect(logic).toContain('const motiaPlugins')
|
|
45
|
-
expect(logic).toContain('export const plugins')
|
|
46
|
-
expect(logic).toContain('packageMap[plugin.packageName]')
|
|
47
|
-
})
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
describe('generatePluginCode', () => {
|
|
51
|
-
it('should generate complete module code', () => {
|
|
52
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin', label: 'Test' }]
|
|
53
|
-
const code = generatePluginCode(plugins)
|
|
54
|
-
|
|
55
|
-
expect(code).toContain('import * as plugin_0')
|
|
56
|
-
expect(code).toContain('const packageMap')
|
|
57
|
-
expect(code).toContain('export const plugins')
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('should handle empty plugins array', () => {
|
|
61
|
-
const code = generatePluginCode([])
|
|
62
|
-
|
|
63
|
-
expect(code).toBe('export const plugins = []')
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('should handle multiple plugins', () => {
|
|
67
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin-1' }, { packageName: '@test/plugin-2' }]
|
|
68
|
-
const code = generatePluginCode(plugins)
|
|
69
|
-
|
|
70
|
-
expect(code).toContain("'@test/plugin-1'")
|
|
71
|
-
expect(code).toContain("'@test/plugin-2'")
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
describe('generateCssImports', () => {
|
|
76
|
-
it('should generate CSS import statements', () => {
|
|
77
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin', cssImports: ['styles.css', 'theme.css'] }]
|
|
78
|
-
const css = generateCssImports(plugins)
|
|
79
|
-
|
|
80
|
-
expect(css).toContain("@import 'styles.css';")
|
|
81
|
-
expect(css).toContain("@import 'theme.css';")
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('should filter empty CSS imports', () => {
|
|
85
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin', cssImports: ['styles.css', '', ' '] }]
|
|
86
|
-
const css = generateCssImports(plugins)
|
|
87
|
-
|
|
88
|
-
expect(css).toContain("@import 'styles.css';")
|
|
89
|
-
expect(css).not.toContain("@import '';")
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('should return empty string for plugins without CSS imports', () => {
|
|
93
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin' }]
|
|
94
|
-
const css = generateCssImports(plugins)
|
|
95
|
-
|
|
96
|
-
expect(css).toBe('')
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it('should flatten CSS imports from multiple plugins', () => {
|
|
100
|
-
const plugins: WorkbenchPlugin[] = [
|
|
101
|
-
{ packageName: '@test/plugin-1', cssImports: ['a.css'] },
|
|
102
|
-
{ packageName: '@test/plugin-2', cssImports: ['b.css'] },
|
|
103
|
-
]
|
|
104
|
-
const css = generateCssImports(plugins)
|
|
105
|
-
|
|
106
|
-
expect(css).toContain("@import 'a.css';")
|
|
107
|
-
expect(css).toContain("@import 'b.css';")
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
describe('isValidCode', () => {
|
|
112
|
-
it('should return true for valid code', () => {
|
|
113
|
-
expect(isValidCode('export const plugins = []')).toBe(true)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('should return false for empty string', () => {
|
|
117
|
-
expect(isValidCode('')).toBe(false)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('should return false for whitespace only', () => {
|
|
121
|
-
expect(isValidCode(' \n\t ')).toBe(false)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('should return false for non-string', () => {
|
|
125
|
-
expect(isValidCode(null as any)).toBe(false)
|
|
126
|
-
expect(isValidCode(undefined as any)).toBe(false)
|
|
127
|
-
})
|
|
128
|
-
})
|
|
129
|
-
})
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { createAliasConfig, getUniquePackageNames, resolvePluginPackage } from '../resolver'
|
|
2
|
-
import type { WorkbenchPlugin } from '../types'
|
|
3
|
-
|
|
4
|
-
describe('Resolver', () => {
|
|
5
|
-
describe('resolvePluginPackage', () => {
|
|
6
|
-
it('should resolve local plugin', () => {
|
|
7
|
-
const plugin: WorkbenchPlugin = { packageName: '~/plugins/local' }
|
|
8
|
-
const resolved = resolvePluginPackage(plugin)
|
|
9
|
-
|
|
10
|
-
expect(resolved.packageName).toBe('~/plugins/local')
|
|
11
|
-
expect(resolved.isLocal).toBe(true)
|
|
12
|
-
expect(resolved.resolvedPath).toContain('plugins/local')
|
|
13
|
-
expect(resolved.alias).toBe('~/plugins/local')
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('should resolve npm package', () => {
|
|
17
|
-
const plugin: WorkbenchPlugin = { packageName: '@test/plugin' }
|
|
18
|
-
const resolved = resolvePluginPackage(plugin)
|
|
19
|
-
|
|
20
|
-
expect(resolved.packageName).toBe('@test/plugin')
|
|
21
|
-
expect(resolved.isLocal).toBe(false)
|
|
22
|
-
expect(resolved.resolvedPath).toContain('node_modules')
|
|
23
|
-
expect(resolved.resolvedPath).toContain('@test/plugin')
|
|
24
|
-
expect(resolved.alias).toBe('@test/plugin')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should normalize paths', () => {
|
|
28
|
-
const plugin: WorkbenchPlugin = { packageName: 'simple-plugin' }
|
|
29
|
-
const resolved = resolvePluginPackage(plugin)
|
|
30
|
-
|
|
31
|
-
expect(resolved.resolvedPath).not.toContain('\\')
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
describe('createAliasConfig', () => {
|
|
36
|
-
it('should create aliases for all plugins', () => {
|
|
37
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '~/plugins/local' }, { packageName: '@test/npm' }]
|
|
38
|
-
|
|
39
|
-
const aliases = createAliasConfig(plugins)
|
|
40
|
-
|
|
41
|
-
expect(aliases['~/plugins/local']).toBeDefined()
|
|
42
|
-
expect(aliases['@test/npm']).toBeDefined()
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('should handle duplicate package names', () => {
|
|
46
|
-
const plugins: WorkbenchPlugin[] = [{ packageName: '@test/plugin' }, { packageName: '@test/plugin' }]
|
|
47
|
-
|
|
48
|
-
const aliases = createAliasConfig(plugins)
|
|
49
|
-
|
|
50
|
-
expect(Object.keys(aliases)).toHaveLength(1)
|
|
51
|
-
expect(aliases['@test/plugin']).toBeDefined()
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('should return empty object for empty plugins array', () => {
|
|
55
|
-
const aliases = createAliasConfig([])
|
|
56
|
-
|
|
57
|
-
expect(aliases).toEqual({})
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
describe('getUniquePackageNames', () => {
|
|
62
|
-
it('should return unique package names', () => {
|
|
63
|
-
const plugins: WorkbenchPlugin[] = [
|
|
64
|
-
{ packageName: '@test/a' },
|
|
65
|
-
{ packageName: '@test/b' },
|
|
66
|
-
{ packageName: '@test/a' },
|
|
67
|
-
]
|
|
68
|
-
|
|
69
|
-
const unique = getUniquePackageNames(plugins)
|
|
70
|
-
|
|
71
|
-
expect(unique).toHaveLength(2)
|
|
72
|
-
expect(unique).toContain('@test/a')
|
|
73
|
-
expect(unique).toContain('@test/b')
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('should return empty array for no plugins', () => {
|
|
77
|
-
const unique = getUniquePackageNames([])
|
|
78
|
-
|
|
79
|
-
expect(unique).toEqual([])
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
})
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { validatePlugins } from '../validator'
|
|
2
|
-
|
|
3
|
-
describe('Validator', () => {
|
|
4
|
-
describe('validatePlugins', () => {
|
|
5
|
-
it('should validate array of valid plugins', () => {
|
|
6
|
-
const plugins = [
|
|
7
|
-
{ packageName: '@test/plugin-1', label: 'Plugin 1' },
|
|
8
|
-
{ packageName: '@test/plugin-2', label: 'Plugin 2' },
|
|
9
|
-
]
|
|
10
|
-
const result = validatePlugins(plugins)
|
|
11
|
-
|
|
12
|
-
expect(result.valid).toBe(true)
|
|
13
|
-
expect(result.errors).toHaveLength(0)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('should reject non-array input', () => {
|
|
17
|
-
const result = validatePlugins('not-an-array' as any)
|
|
18
|
-
|
|
19
|
-
expect(result.valid).toBe(false)
|
|
20
|
-
expect(result.errors.some((err) => err.includes('array'))).toBe(true)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('should handle empty array', () => {
|
|
24
|
-
const result = validatePlugins([])
|
|
25
|
-
|
|
26
|
-
expect(result.valid).toBe(true)
|
|
27
|
-
expect(result.warnings.some((w) => w.includes('No plugins'))).toBe(true)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('should collect all errors from multiple plugins', () => {
|
|
31
|
-
const plugins = [{ packageName: '' }, { packageName: '' }, { packageName: 'valid' }]
|
|
32
|
-
const result = validatePlugins(plugins)
|
|
33
|
-
|
|
34
|
-
expect(result.valid).toBe(false)
|
|
35
|
-
expect(result.errors.length).toBeGreaterThanOrEqual(2)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('should warn about duplicate package names', () => {
|
|
39
|
-
const plugins = [
|
|
40
|
-
{ packageName: '@test/plugin', label: 'Plugin 1' },
|
|
41
|
-
{ packageName: '@test/plugin', label: 'Plugin 2' },
|
|
42
|
-
]
|
|
43
|
-
const result = validatePlugins(plugins)
|
|
44
|
-
|
|
45
|
-
expect(result.valid).toBe(true)
|
|
46
|
-
expect(result.warnings.some((w) => w.includes('Duplicate'))).toBe(true)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('should support failFast option', () => {
|
|
50
|
-
const plugins = [{ packageName: '' }, { packageName: '' }]
|
|
51
|
-
const result = validatePlugins(plugins, { failFast: true })
|
|
52
|
-
|
|
53
|
-
expect(result.valid).toBe(false)
|
|
54
|
-
// With failFast, should stop after first plugin validation fails
|
|
55
|
-
// Each plugin with empty packageName generates 2 errors (min length + invalid format)
|
|
56
|
-
// So failFast should result in only the first plugin's errors
|
|
57
|
-
expect(result.errors.length).toBeLessThanOrEqual(2)
|
|
58
|
-
// Verify it didn't process second plugin by checking error messages don't mention index 1
|
|
59
|
-
const hasIndex1Error = result.errors.some((err) => err.includes('index 1'))
|
|
60
|
-
expect(hasIndex1Error).toBe(false)
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('should handle mixed valid and invalid plugins', () => {
|
|
64
|
-
const plugins = [{ packageName: '@test/valid' }, { packageName: '' }, { packageName: '@test/another-valid' }]
|
|
65
|
-
const result = validatePlugins(plugins)
|
|
66
|
-
|
|
67
|
-
expect(result.valid).toBe(false)
|
|
68
|
-
expect(result.errors.length).toBeGreaterThan(0)
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
})
|
package/dist/motia-plugin/hmr.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import type { Printer } from '@motiadev/core'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import type { HmrContext, ModuleNode } from 'vite'
|
|
4
|
-
import { resolvePluginPackage } from './resolver'
|
|
5
|
-
import type { WorkbenchPlugin } from './types'
|
|
6
|
-
import { CONSTANTS } from './types'
|
|
7
|
-
import { isLocalPlugin, normalizePath } from './utils'
|
|
8
|
-
|
|
9
|
-
const WATCHED_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.css', '.scss', '.less']
|
|
10
|
-
|
|
11
|
-
export function isConfigFile(file: string): boolean {
|
|
12
|
-
const normalizedFile = normalizePath(file)
|
|
13
|
-
return normalizedFile.endsWith('motia.config.ts') || normalizedFile.endsWith('motia.config.js')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Checks if a file change should trigger HMR for plugins.
|
|
18
|
-
*
|
|
19
|
-
* @param file - The file path that changed
|
|
20
|
-
* @param plugins - Current plugin configurations
|
|
21
|
-
* @returns True if the change affects plugins
|
|
22
|
-
*/
|
|
23
|
-
export function shouldInvalidatePlugins(file: string, plugins: WorkbenchPlugin[]): boolean {
|
|
24
|
-
const normalizedFile = normalizePath(file)
|
|
25
|
-
const absoluteFile = path.isAbsolute(normalizedFile) ? normalizedFile : path.resolve(process.cwd(), normalizedFile)
|
|
26
|
-
|
|
27
|
-
if (isConfigFile(file)) {
|
|
28
|
-
return true
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const hasWatchedExtension = WATCHED_EXTENSIONS.some((ext) => absoluteFile.endsWith(ext))
|
|
32
|
-
if (!hasWatchedExtension) {
|
|
33
|
-
return false
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
for (const plugin of plugins) {
|
|
37
|
-
if (isLocalPlugin(plugin.packageName)) {
|
|
38
|
-
const resolved = resolvePluginPackage(plugin)
|
|
39
|
-
const pluginAbsolutePath = path.isAbsolute(resolved.resolvedPath)
|
|
40
|
-
? resolved.resolvedPath
|
|
41
|
-
: path.resolve(process.cwd(), resolved.resolvedPath)
|
|
42
|
-
|
|
43
|
-
const normalizedPluginPath = pluginAbsolutePath.endsWith(path.sep)
|
|
44
|
-
? pluginAbsolutePath
|
|
45
|
-
: `${pluginAbsolutePath}${path.sep}`
|
|
46
|
-
|
|
47
|
-
if (absoluteFile.startsWith(normalizedPluginPath) || absoluteFile === pluginAbsolutePath) {
|
|
48
|
-
return true
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return false
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Handles hot updates for the plugin system.
|
|
58
|
-
* This function is called by Vite's handleHotUpdate hook.
|
|
59
|
-
*
|
|
60
|
-
* @param ctx - Vite's HMR context
|
|
61
|
-
* @param plugins - Current plugin configurations
|
|
62
|
-
* @param printer - Printer instance for logging
|
|
63
|
-
* @returns Array of modules to update, or undefined to continue with default behavior
|
|
64
|
-
*/
|
|
65
|
-
export function handlePluginHotUpdate(
|
|
66
|
-
ctx: HmrContext,
|
|
67
|
-
plugins: WorkbenchPlugin[],
|
|
68
|
-
printer: Printer,
|
|
69
|
-
): ModuleNode[] | undefined {
|
|
70
|
-
const { file, server, timestamp } = ctx
|
|
71
|
-
|
|
72
|
-
printer.printPluginLog(`HMR: File changed: ${normalizePath(file)}`)
|
|
73
|
-
|
|
74
|
-
if (isConfigFile(file)) {
|
|
75
|
-
printer.printPluginLog('HMR: Config file changed, triggering full page reload')
|
|
76
|
-
printer.printPluginWarn(
|
|
77
|
-
'Configuration changes require a server restart for full effect. Please restart the dev server to apply all changes.',
|
|
78
|
-
)
|
|
79
|
-
server.ws.send({
|
|
80
|
-
type: 'full-reload',
|
|
81
|
-
path: '*',
|
|
82
|
-
})
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (!shouldInvalidatePlugins(file, plugins)) {
|
|
87
|
-
printer.printPluginLog('HMR: Change outside plugin scope, delegating to Vite default handling')
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
printer.printPluginLog('HMR: Plugin change detected, invalidating virtual module')
|
|
92
|
-
|
|
93
|
-
const virtualModule = server.moduleGraph.getModuleById(CONSTANTS.RESOLVED_VIRTUAL_MODULE_ID)
|
|
94
|
-
|
|
95
|
-
if (!virtualModule) {
|
|
96
|
-
printer.printPluginWarn('HMR: Virtual module not found, triggering full reload as fallback')
|
|
97
|
-
server.ws.send({
|
|
98
|
-
type: 'full-reload',
|
|
99
|
-
path: '*',
|
|
100
|
-
})
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
server.moduleGraph.invalidateModule(virtualModule, new Set(), timestamp)
|
|
105
|
-
printer.printPluginLog('HMR: Virtual module invalidated')
|
|
106
|
-
|
|
107
|
-
const modulesToUpdateSet = new Set<ModuleNode>([virtualModule])
|
|
108
|
-
const processedModules = new Set<ModuleNode>([virtualModule])
|
|
109
|
-
|
|
110
|
-
for (const importer of virtualModule.importers) {
|
|
111
|
-
if (!processedModules.has(importer)) {
|
|
112
|
-
processedModules.add(importer)
|
|
113
|
-
modulesToUpdateSet.add(importer)
|
|
114
|
-
server.moduleGraph.invalidateModule(importer, new Set(), timestamp)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const modulesToUpdate = Array.from(modulesToUpdateSet)
|
|
119
|
-
|
|
120
|
-
printer.printPluginLog(`HMR: Updated ${modulesToUpdate.length} module(s)`)
|
|
121
|
-
|
|
122
|
-
return modulesToUpdate
|
|
123
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { Printer } from '@motiadev/core'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import type { Plugin, ViteDevServer } from 'vite'
|
|
4
|
-
import { generateCssImports, generatePluginCode, isValidCode } from './generator'
|
|
5
|
-
import { handlePluginHotUpdate } from './hmr'
|
|
6
|
-
import { createAliasConfig, resolvePluginPackage } from './resolver'
|
|
7
|
-
import type { WorkbenchPlugin } from './types'
|
|
8
|
-
import { CONSTANTS } from './types'
|
|
9
|
-
import { isLocalPlugin, normalizePath } from './utils'
|
|
10
|
-
import { validatePlugins } from './validator'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Vite plugin for loading and managing Motia workbench plugins.
|
|
14
|
-
*
|
|
15
|
-
* Features:
|
|
16
|
-
* - Hot Module Replacement (HMR) support
|
|
17
|
-
* - Runtime validation with detailed error messages
|
|
18
|
-
* - Verbose logging for debugging
|
|
19
|
-
* - CSS injection for plugin styles
|
|
20
|
-
*
|
|
21
|
-
* @param plugins - Array of plugin configurations
|
|
22
|
-
* @param options - Optional loader configuration
|
|
23
|
-
* @returns Vite plugin instance
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* export default defineConfig({
|
|
28
|
-
* plugins: [
|
|
29
|
-
* motiaPluginsPlugin([
|
|
30
|
-
* { packageName: '@my-org/plugin', label: 'My Plugin' }
|
|
31
|
-
* ])
|
|
32
|
-
* ]
|
|
33
|
-
* })
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
const printer = new Printer(process.cwd())
|
|
37
|
-
|
|
38
|
-
export default function motiaPluginsPlugin(plugins: WorkbenchPlugin[]): Plugin {
|
|
39
|
-
let devServer: ViteDevServer | null = null
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
const validationResult = validatePlugins(plugins, {
|
|
43
|
-
failFast: false,
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
if (!validationResult.valid) {
|
|
47
|
-
printer.printPluginError('Plugin configuration validation failed:')
|
|
48
|
-
for (const err of validationResult.errors) {
|
|
49
|
-
printer.printPluginError(` ${err}`)
|
|
50
|
-
}
|
|
51
|
-
throw new Error('Invalid plugin configuration. See errors above.')
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (validationResult.warnings.length > 0) {
|
|
55
|
-
for (const warning of validationResult.warnings) {
|
|
56
|
-
printer.printPluginWarn(warning)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
} catch (error) {
|
|
60
|
-
printer.printPluginError(`Failed to validate plugins: ${error}`)
|
|
61
|
-
throw error
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const alias = createAliasConfig(plugins)
|
|
65
|
-
|
|
66
|
-
printer.printPluginLog(`Initialized with ${plugins.length} plugin(s)`)
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
name: 'vite-plugin-motia-plugins',
|
|
70
|
-
enforce: 'pre',
|
|
71
|
-
|
|
72
|
-
buildStart() {
|
|
73
|
-
printer.printPluginLog('Build started')
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
config: () => ({
|
|
77
|
-
resolve: {
|
|
78
|
-
alias,
|
|
79
|
-
},
|
|
80
|
-
}),
|
|
81
|
-
|
|
82
|
-
configureServer(server) {
|
|
83
|
-
devServer = server
|
|
84
|
-
printer.printPluginLog('Dev server configured, HMR enabled')
|
|
85
|
-
|
|
86
|
-
const configPaths = [path.join(process.cwd(), 'motia.config.ts'), path.join(process.cwd(), 'motia.config.js')]
|
|
87
|
-
|
|
88
|
-
for (const configPath of configPaths) {
|
|
89
|
-
server.watcher.add(configPath)
|
|
90
|
-
}
|
|
91
|
-
printer.printPluginLog('Watching for config file changes')
|
|
92
|
-
|
|
93
|
-
const localPlugins = plugins.filter((p) => isLocalPlugin(p.packageName))
|
|
94
|
-
if (localPlugins.length > 0) {
|
|
95
|
-
printer.printPluginLog(`Watching ${localPlugins.length} local plugin(s)`)
|
|
96
|
-
|
|
97
|
-
for (const plugin of localPlugins) {
|
|
98
|
-
const resolved = resolvePluginPackage(plugin)
|
|
99
|
-
const watchPath = resolved.resolvedPath
|
|
100
|
-
|
|
101
|
-
server.watcher.add(watchPath)
|
|
102
|
-
printer.printPluginLog(`Watching: ${watchPath}`)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
server.watcher.on('change', (file) => {
|
|
106
|
-
const normalizedFile = normalizePath(file)
|
|
107
|
-
printer.printPluginLog(`File watcher detected change: ${normalizedFile}`)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
server.watcher.on('add', (file) => {
|
|
111
|
-
const normalizedFile = normalizePath(file)
|
|
112
|
-
printer.printPluginLog(`File watcher detected new file: ${normalizedFile}`)
|
|
113
|
-
})
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
resolveId(id) {
|
|
118
|
-
if (id === CONSTANTS.VIRTUAL_MODULE_ID) {
|
|
119
|
-
return CONSTANTS.RESOLVED_VIRTUAL_MODULE_ID
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
load(id) {
|
|
124
|
-
if (id !== CONSTANTS.RESOLVED_VIRTUAL_MODULE_ID) {
|
|
125
|
-
return null
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
printer.printPluginLog('Loading plugins virtual module')
|
|
129
|
-
printer.printPluginLog('Generating plugin code...')
|
|
130
|
-
|
|
131
|
-
const code = generatePluginCode(plugins)
|
|
132
|
-
|
|
133
|
-
if (!isValidCode(code)) {
|
|
134
|
-
printer.printPluginError('Generated code is invalid or empty')
|
|
135
|
-
return 'export const plugins = []'
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
printer.printPluginLog('Plugin code generated successfully')
|
|
139
|
-
|
|
140
|
-
return code
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
async transform(code, id) {
|
|
144
|
-
const normalizedId = normalizePath(id)
|
|
145
|
-
|
|
146
|
-
if (!normalizedId.endsWith('src/index.css')) {
|
|
147
|
-
return null
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
printer.printPluginLog('Injecting plugin CSS imports')
|
|
151
|
-
|
|
152
|
-
const cssImports = generateCssImports(plugins)
|
|
153
|
-
|
|
154
|
-
if (!cssImports) {
|
|
155
|
-
return null
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return {
|
|
159
|
-
code: `${cssImports}\n${code}`,
|
|
160
|
-
map: null,
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
|
|
164
|
-
handleHotUpdate(ctx) {
|
|
165
|
-
if (!devServer) {
|
|
166
|
-
printer.printPluginWarn('HMR: Dev server not available')
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const modulesToUpdate = handlePluginHotUpdate(ctx, plugins, printer)
|
|
171
|
-
|
|
172
|
-
if (modulesToUpdate && modulesToUpdate.length > 0) {
|
|
173
|
-
const merged = Array.from(new Set([...(ctx.modules || []), ...modulesToUpdate]))
|
|
174
|
-
printer.printPluginLog(`HMR: Successfully updated ${merged.length} module(s)`)
|
|
175
|
-
return merged
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
buildEnd() {
|
|
180
|
-
printer.printPluginLog('Build ended')
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
}
|