@dxos/plugin-script 0.8.1-staging.391c573 → 0.8.1-staging.97aedb1
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/lib/browser/DeploymentDialog-AEPYJKPO.mjs +12 -0
- package/dist/lib/browser/DeploymentDialog-AEPYJKPO.mjs.map +7 -0
- package/dist/lib/browser/{ScriptContainer-4FIJVITA.mjs → ScriptContainer-R25PRK2D.mjs} +26 -39
- package/dist/lib/browser/ScriptContainer-R25PRK2D.mjs.map +7 -0
- package/dist/lib/browser/app-graph-builder-RRLY67QC.mjs +64 -0
- package/dist/lib/browser/app-graph-builder-RRLY67QC.mjs.map +7 -0
- package/dist/lib/browser/{artifact-definition-GTL3ZSF2.mjs → artifact-definition-WXFYD2V5.mjs} +10 -9
- package/dist/lib/browser/artifact-definition-WXFYD2V5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-SFG422OU.mjs → chunk-2CGZFDCR.mjs} +290 -277
- package/dist/lib/browser/chunk-2CGZFDCR.mjs.map +7 -0
- package/dist/lib/browser/chunk-4VD3K3PY.mjs +15 -0
- package/dist/lib/browser/{chunk-6MOQ4BP3.mjs.map → chunk-4VD3K3PY.mjs.map} +3 -3
- package/dist/lib/browser/chunk-CSZXPLYY.mjs +147 -0
- package/dist/lib/browser/chunk-CSZXPLYY.mjs.map +7 -0
- package/dist/lib/browser/chunk-KLEOGVXY.mjs +352 -0
- package/dist/lib/browser/chunk-KLEOGVXY.mjs.map +7 -0
- package/dist/lib/browser/chunk-MQZQB5VD.mjs +233 -0
- package/dist/lib/browser/chunk-MQZQB5VD.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JL34HAEL.mjs → chunk-R2CHVWJ2.mjs} +5 -4
- package/dist/lib/browser/chunk-R2CHVWJ2.mjs.map +7 -0
- package/dist/lib/browser/chunk-SUCBNCEQ.mjs +87 -0
- package/dist/lib/browser/chunk-SUCBNCEQ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FVVCAWNP.mjs → chunk-WSK3YQXI.mjs} +9 -3
- package/dist/lib/browser/chunk-WSK3YQXI.mjs.map +7 -0
- package/dist/lib/browser/{compiler-YY2XSKHQ.mjs → compiler-56LTBEQB.mjs} +7 -7
- package/dist/lib/browser/index.mjs +65 -61
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-WCVXKRBR.mjs +90 -0
- package/dist/lib/browser/intent-resolver-WCVXKRBR.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-surface-WXZVPNGI.mjs +117 -0
- package/dist/lib/browser/react-surface-WXZVPNGI.mjs.map +7 -0
- package/dist/lib/browser/{settings-HIWURVAS.mjs → settings-Z7B37V2I.mjs} +6 -6
- package/dist/lib/browser/{settings-HIWURVAS.mjs.map → settings-Z7B37V2I.mjs.map} +3 -3
- package/dist/lib/browser/types.mjs +5 -2
- package/dist/lib/node/DeploymentDialog-O4MU4OMF.cjs +33 -0
- package/dist/lib/node/DeploymentDialog-O4MU4OMF.cjs.map +7 -0
- package/dist/lib/node/{ScriptContainer-54GQSZCU.cjs → ScriptContainer-5KY6ZOQD.cjs} +29 -40
- package/dist/lib/node/ScriptContainer-5KY6ZOQD.cjs.map +7 -0
- package/dist/lib/node/app-graph-builder-6I2BWD46.cjs +80 -0
- package/dist/lib/node/app-graph-builder-6I2BWD46.cjs.map +7 -0
- package/dist/lib/node/{artifact-definition-64KZC4UT.cjs → artifact-definition-6NVXEHJD.cjs} +16 -15
- package/dist/lib/node/artifact-definition-6NVXEHJD.cjs.map +7 -0
- package/dist/lib/node/chunk-65MIJR3Q.cjs +173 -0
- package/dist/lib/node/chunk-65MIJR3Q.cjs.map +7 -0
- package/dist/lib/node/chunk-F4DP7WON.cjs +372 -0
- package/dist/lib/node/chunk-F4DP7WON.cjs.map +7 -0
- package/dist/lib/node/{chunk-ALY3N6PW.cjs → chunk-JICWAOWZ.cjs} +6 -6
- package/dist/lib/node/{chunk-ALY3N6PW.cjs.map → chunk-JICWAOWZ.cjs.map} +3 -3
- package/dist/lib/node/{chunk-45OE3V5M.cjs → chunk-SLDJM45C.cjs} +286 -272
- package/dist/lib/node/chunk-SLDJM45C.cjs.map +7 -0
- package/dist/lib/node/chunk-VYBEBLDO.cjs +251 -0
- package/dist/lib/node/chunk-VYBEBLDO.cjs.map +7 -0
- package/dist/lib/node/chunk-X7MHLHHS.cjs +91 -0
- package/dist/lib/node/chunk-X7MHLHHS.cjs.map +7 -0
- package/dist/lib/node/{chunk-VJ73IG7P.cjs → chunk-XFZPWFEG.cjs} +8 -7
- package/dist/lib/node/chunk-XFZPWFEG.cjs.map +7 -0
- package/dist/lib/node/{chunk-5UH3F7TA.cjs → chunk-YJQZHKKA.cjs} +11 -4
- package/dist/lib/node/chunk-YJQZHKKA.cjs.map +7 -0
- package/dist/lib/node/{compiler-UIBLKJKG.cjs → compiler-W2RU3M7U.cjs} +8 -8
- package/dist/lib/node/index.cjs +75 -71
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/intent-resolver-J4NBDNFH.cjs +100 -0
- package/dist/lib/node/intent-resolver-J4NBDNFH.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/react-surface-27KTUBIZ.cjs +129 -0
- package/dist/lib/node/react-surface-27KTUBIZ.cjs.map +7 -0
- package/dist/lib/node/{settings-ZASSNBKR.cjs → settings-EI6VPNKN.cjs} +9 -9
- package/dist/lib/node/{settings-ZASSNBKR.cjs.map → settings-EI6VPNKN.cjs.map} +3 -3
- package/dist/lib/node/types.cjs +6 -4
- package/dist/lib/node/types.cjs.map +2 -2
- package/dist/lib/node-esm/DeploymentDialog-SSQSWLHX.mjs +13 -0
- package/dist/lib/node-esm/DeploymentDialog-SSQSWLHX.mjs.map +7 -0
- package/dist/lib/node-esm/{ScriptContainer-JAQY5F3X.mjs → ScriptContainer-W2F4FGDV.mjs} +26 -39
- package/dist/lib/node-esm/ScriptContainer-W2F4FGDV.mjs.map +7 -0
- package/dist/lib/node-esm/app-graph-builder-H5XLRVX3.mjs +65 -0
- package/dist/lib/node-esm/app-graph-builder-H5XLRVX3.mjs.map +7 -0
- package/dist/lib/node-esm/{artifact-definition-SF46QOO7.mjs → artifact-definition-KQ64AYBP.mjs} +10 -9
- package/dist/lib/node-esm/artifact-definition-KQ64AYBP.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-LBFWIT3Y.mjs → chunk-4MTPYMV2.mjs} +290 -277
- package/dist/lib/node-esm/chunk-4MTPYMV2.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CP5LXTK5.mjs → chunk-EB5DSAD4.mjs} +5 -5
- package/dist/lib/node-esm/{chunk-CP5LXTK5.mjs.map → chunk-EB5DSAD4.mjs.map} +3 -3
- package/dist/lib/node-esm/chunk-F4HA5C34.mjs +234 -0
- package/dist/lib/node-esm/chunk-F4HA5C34.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-P2V2Y5LV.mjs → chunk-FDEAVT67.mjs} +9 -3
- package/dist/lib/node-esm/chunk-FDEAVT67.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-MU3JKVL2.mjs +148 -0
- package/dist/lib/node-esm/chunk-MU3JKVL2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-PBGVTGL2.mjs +353 -0
- package/dist/lib/node-esm/chunk-PBGVTGL2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-QDYGTY4L.mjs +89 -0
- package/dist/lib/node-esm/chunk-QDYGTY4L.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FHQKFLM7.mjs → chunk-RW2APVMV.mjs} +5 -4
- package/dist/lib/node-esm/chunk-RW2APVMV.mjs.map +7 -0
- package/dist/lib/node-esm/{compiler-XTXFGZJM.mjs → compiler-VT5C2Z3T.mjs} +7 -7
- package/dist/lib/node-esm/index.mjs +65 -61
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-PDZ2A26X.mjs +91 -0
- package/dist/lib/node-esm/intent-resolver-PDZ2A26X.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/react-surface-UCUVDVSH.mjs +118 -0
- package/dist/lib/node-esm/react-surface-UCUVDVSH.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-FDGLXN4I.mjs → settings-HU5UEFRF.mjs} +6 -6
- package/dist/lib/node-esm/{settings-FDGLXN4I.mjs.map → settings-HU5UEFRF.mjs.map} +3 -3
- package/dist/lib/node-esm/types.mjs +5 -2
- package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +178 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts +11 -0
- package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts.map +1 -0
- package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts +18 -0
- package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts.map +1 -0
- package/dist/types/src/components/DeploymentDialog/index.d.ts +4 -0
- package/dist/types/src/components/DeploymentDialog/index.d.ts.map +1 -0
- package/dist/types/src/components/ScriptContainer.d.ts +3 -3
- package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
- package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
- package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts +8 -0
- package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts.map +1 -0
- package/dist/types/src/components/{ScriptSettings/ScriptSettings.d.ts → Settings/ScriptPluginSettings.d.ts} +2 -2
- package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +3 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -0
- package/dist/types/src/components/TestPanel/TestPanel.d.ts +7 -0
- package/dist/types/src/components/TestPanel/TestPanel.d.ts.map +1 -0
- package/dist/types/src/components/TestPanel/index.d.ts +2 -0
- package/dist/types/src/components/TestPanel/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +8 -5
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/deploy.d.ts +16 -12
- package/dist/types/src/hooks/deploy.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useCreateAndDeployScriptTemplates.d.ts +17 -0
- package/dist/types/src/hooks/useCreateAndDeployScriptTemplates.d.ts.map +1 -0
- package/dist/types/src/hooks/useToolbarAction.d.ts +2 -3
- package/dist/types/src/hooks/useToolbarAction.d.ts.map +1 -1
- package/dist/types/src/hooks/useToolbarState.d.ts +2 -8
- package/dist/types/src/hooks/useToolbarState.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +3 -9
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/templates/chess.d.ts.map +1 -1
- package/dist/types/src/templates/data-generator.d.ts +10 -0
- package/dist/types/src/templates/data-generator.d.ts.map +1 -0
- package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
- package/dist/types/src/templates/gmail.d.ts +3 -0
- package/dist/types/src/templates/gmail.d.ts.map +1 -0
- package/dist/types/src/templates/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +68 -21
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +12 -2
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/deploy.d.ts +25 -0
- package/dist/types/src/util/deploy.d.ts.map +1 -0
- package/dist/types/src/util/functions.d.ts +11 -0
- package/dist/types/src/util/functions.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +3 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/package.json +51 -49
- package/src/ScriptPlugin.tsx +12 -17
- package/src/capabilities/app-graph-builder.ts +47 -0
- package/src/capabilities/artifact-definition.ts +2 -1
- package/src/capabilities/capabilities.ts +2 -2
- package/src/capabilities/index.ts +2 -1
- package/src/capabilities/intent-resolver.ts +39 -5
- package/src/capabilities/react-surface.tsx +64 -25
- package/src/capabilities/settings.ts +2 -2
- package/src/components/DeploymentDialog/DeploymentDialog.stories.tsx +39 -0
- package/src/components/DeploymentDialog/DeploymentDialog.tsx +112 -0
- package/src/components/DeploymentDialog/index.ts +9 -0
- package/src/components/ScriptContainer.tsx +21 -32
- package/src/components/ScriptToolbar/ScriptToolbar.tsx +3 -4
- package/src/components/{ScriptSettingsPanel.tsx → Settings/ScriptObjectSettings.tsx} +120 -102
- package/src/components/{ScriptSettings/ScriptSettings.tsx → Settings/ScriptPluginSettings.tsx} +3 -3
- package/src/components/Settings/index.ts +6 -0
- package/src/components/{DebugPanel/DebugPanel.tsx → TestPanel/TestPanel.tsx} +8 -14
- package/src/components/{LogsPanel → TestPanel}/index.ts +1 -1
- package/src/components/index.ts +4 -4
- package/src/hooks/deploy.ts +31 -80
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useCreateAndDeployScriptTemplates.ts +59 -0
- package/src/hooks/useToolbarAction.ts +9 -13
- package/src/hooks/useToolbarState.ts +1 -2
- package/src/meta.ts +7 -2
- package/src/templates/chess.ts +4 -0
- package/src/templates/data-generator.ts +73 -0
- package/src/templates/discord.ts +1 -1
- package/src/templates/forex-effect.ts +2 -1
- package/src/templates/gmail.ts +244 -0
- package/src/templates/index.ts +14 -0
- package/src/translations.ts +28 -10
- package/src/types.ts +4 -0
- package/src/util/deploy.ts +126 -0
- package/src/util/functions.ts +53 -0
- package/src/util/index.ts +6 -0
- package/dist/lib/browser/ScriptContainer-4FIJVITA.mjs.map +0 -7
- package/dist/lib/browser/artifact-definition-GTL3ZSF2.mjs.map +0 -7
- package/dist/lib/browser/chunk-4SSKJNMZ.mjs +0 -69
- package/dist/lib/browser/chunk-4SSKJNMZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-6MOQ4BP3.mjs +0 -15
- package/dist/lib/browser/chunk-7TZYIGBS.mjs +0 -541
- package/dist/lib/browser/chunk-7TZYIGBS.mjs.map +0 -7
- package/dist/lib/browser/chunk-FVVCAWNP.mjs.map +0 -7
- package/dist/lib/browser/chunk-JL34HAEL.mjs.map +0 -7
- package/dist/lib/browser/chunk-SFG422OU.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-BJ76DBGE.mjs +0 -45
- package/dist/lib/browser/intent-resolver-BJ76DBGE.mjs.map +0 -7
- package/dist/lib/browser/react-surface-HXCDELEA.mjs +0 -79
- package/dist/lib/browser/react-surface-HXCDELEA.mjs.map +0 -7
- package/dist/lib/node/ScriptContainer-54GQSZCU.cjs.map +0 -7
- package/dist/lib/node/artifact-definition-64KZC4UT.cjs.map +0 -7
- package/dist/lib/node/chunk-45OE3V5M.cjs.map +0 -7
- package/dist/lib/node/chunk-5UH3F7TA.cjs.map +0 -7
- package/dist/lib/node/chunk-CJ45RBS4.cjs +0 -563
- package/dist/lib/node/chunk-CJ45RBS4.cjs.map +0 -7
- package/dist/lib/node/chunk-VJ73IG7P.cjs.map +0 -7
- package/dist/lib/node/chunk-XCQNFRZ6.cjs +0 -77
- package/dist/lib/node/chunk-XCQNFRZ6.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-HQ3FGK2K.cjs +0 -59
- package/dist/lib/node/intent-resolver-HQ3FGK2K.cjs.map +0 -7
- package/dist/lib/node/react-surface-QQL4EDUS.cjs +0 -95
- package/dist/lib/node/react-surface-QQL4EDUS.cjs.map +0 -7
- package/dist/lib/node-esm/ScriptContainer-JAQY5F3X.mjs.map +0 -7
- package/dist/lib/node-esm/artifact-definition-SF46QOO7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4YUSGXJ2.mjs +0 -71
- package/dist/lib/node-esm/chunk-4YUSGXJ2.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FHQKFLM7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LBFWIT3Y.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-P2V2Y5LV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RI35DJSW.mjs +0 -542
- package/dist/lib/node-esm/chunk-RI35DJSW.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-CDTQKQD4.mjs +0 -46
- package/dist/lib/node-esm/intent-resolver-CDTQKQD4.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-PCW5HN3B.mjs +0 -80
- package/dist/lib/node-esm/react-surface-PCW5HN3B.mjs.map +0 -7
- package/dist/types/src/components/DebugPanel/DebugPanel.d.ts +0 -7
- package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +0 -1
- package/dist/types/src/components/DebugPanel/index.d.ts +0 -2
- package/dist/types/src/components/DebugPanel/index.d.ts.map +0 -1
- package/dist/types/src/components/LogsPanel/LogsPanel.d.ts +0 -8
- package/dist/types/src/components/LogsPanel/LogsPanel.d.ts.map +0 -1
- package/dist/types/src/components/LogsPanel/index.d.ts +0 -2
- package/dist/types/src/components/LogsPanel/index.d.ts.map +0 -1
- package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +0 -1
- package/dist/types/src/components/ScriptSettings/index.d.ts +0 -2
- package/dist/types/src/components/ScriptSettings/index.d.ts.map +0 -1
- package/dist/types/src/components/ScriptSettingsPanel.d.ts +0 -7
- package/dist/types/src/components/ScriptSettingsPanel.d.ts.map +0 -1
- package/dist/types/src/hooks/view.d.ts +0 -33
- package/dist/types/src/hooks/view.d.ts.map +0 -1
- package/src/components/DebugPanel/index.ts +0 -5
- package/src/components/LogsPanel/LogsPanel.tsx +0 -111
- package/src/components/ScriptSettings/index.ts +0 -5
- package/src/hooks/view.ts +0 -52
- /package/dist/lib/browser/{compiler-YY2XSKHQ.mjs.map → compiler-56LTBEQB.mjs.map} +0 -0
- /package/dist/lib/node/{compiler-UIBLKJKG.cjs.map → compiler-W2RU3M7U.cjs.map} +0 -0
- /package/dist/lib/node-esm/{compiler-XTXFGZJM.mjs.map → compiler-VT5C2Z3T.mjs.map} +0 -0
package/src/meta.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type PluginMeta } from '@dxos/app-framework';
|
|
|
6
6
|
|
|
7
7
|
export const SCRIPT_PLUGIN = 'dxos.org/plugin/script';
|
|
8
8
|
|
|
9
|
-
export const meta = {
|
|
9
|
+
export const meta: PluginMeta = {
|
|
10
10
|
id: SCRIPT_PLUGIN,
|
|
11
11
|
name: 'Scripts',
|
|
12
12
|
description:
|
|
@@ -15,4 +15,9 @@ export const meta = {
|
|
|
15
15
|
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/experimental/plugin-explorer',
|
|
16
16
|
tags: ['experimental'],
|
|
17
17
|
screenshots: ['https://dxos.network/plugin-details-scripts-dark.png'],
|
|
18
|
-
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// TODO(ZaymonFC): Configure by scopes?
|
|
21
|
+
export const defaultScriptsForIntegration: Record<string, string[]> = {
|
|
22
|
+
'gmail.com': ['dxos.org/script/gmail'],
|
|
23
|
+
};
|
package/src/templates/chess.ts
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
EchoObject,
|
|
7
|
+
defineFunction,
|
|
8
|
+
S,
|
|
9
|
+
createStatic,
|
|
10
|
+
Expando,
|
|
11
|
+
TypedObject,
|
|
12
|
+
Ref,
|
|
13
|
+
LabelAnnotationId,
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
} from 'dxos:functions';
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import { randParagraph } from 'https://esm.sh/@ngneat/falso@7.1.1';
|
|
18
|
+
|
|
19
|
+
export class TextType extends TypedObject({ typename: 'dxos.org/type/Text', version: '0.1.0' })({
|
|
20
|
+
content: S.String,
|
|
21
|
+
}) {}
|
|
22
|
+
|
|
23
|
+
export const DocumentSchema = S.Struct({
|
|
24
|
+
name: S.optional(S.String),
|
|
25
|
+
fallbackName: S.optional(S.String),
|
|
26
|
+
content: Ref(TextType),
|
|
27
|
+
threads: S.mutable(S.Array(Ref(Expando))),
|
|
28
|
+
}).annotations({
|
|
29
|
+
[LabelAnnotationId]: ['name', 'fallbackName'],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const DocumentType = DocumentSchema.pipe(EchoObject('dxos.org/type/Document', '0.1.0'));
|
|
33
|
+
export type DocumentType = S.Schema.Type<typeof DocumentType>;
|
|
34
|
+
|
|
35
|
+
export default defineFunction({
|
|
36
|
+
inputSchema: S.Struct({
|
|
37
|
+
documentAmount: S.optional(S.Number),
|
|
38
|
+
textSize: S.optional(S.Number),
|
|
39
|
+
mutationAmount: S.optional(S.Number),
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
outputSchema: S.Struct({}),
|
|
43
|
+
|
|
44
|
+
handler: async ({ event: { documentAmount = 10, textSize = 10, mutationAmount = 0 }, context: { space } }: any) => {
|
|
45
|
+
await space.db.graph.schemaRegistry.addSchema([Expando]);
|
|
46
|
+
|
|
47
|
+
const objects = [];
|
|
48
|
+
// const rootCollection = await space.properties[COLLECTION_TYPENAME]?.load();
|
|
49
|
+
for (let i = 0; i < documentAmount; i++) {
|
|
50
|
+
const obj = space.db.add(
|
|
51
|
+
createStatic(Expando, {
|
|
52
|
+
name: 'scriptGenerated',
|
|
53
|
+
content: randParagraph({ length: textSize }),
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
// rootCollection.objects.push(obj);
|
|
57
|
+
objects.push(obj);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < mutationAmount; i++) {
|
|
61
|
+
const obj = objects[Math.floor(Math.random() * objects.length)];
|
|
62
|
+
obj.content = randParagraph({ length: textSize });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
await space.db.flush();
|
|
66
|
+
// TODO(mykola): This seems to halp with propagating data to space.
|
|
67
|
+
for (const obj of objects) {
|
|
68
|
+
await space.db.query({ id: obj.id }).first();
|
|
69
|
+
console.log('obj', obj.id);
|
|
70
|
+
}
|
|
71
|
+
return 'OK';
|
|
72
|
+
},
|
|
73
|
+
});
|
package/src/templates/discord.ts
CHANGED
|
@@ -19,7 +19,7 @@ const MessageSchema = S.Struct({
|
|
|
19
19
|
from: S.String,
|
|
20
20
|
created: S.String,
|
|
21
21
|
content: S.String,
|
|
22
|
-
}).pipe(EchoObject('example.com/type/Message', '0.1.0'));
|
|
22
|
+
}).pipe(EchoObject({ typename: 'example.com/type/Message', version: '0.1.0' }));
|
|
23
23
|
|
|
24
24
|
const DEFAULT_AFTER = 1704067200; // 2024-01-01
|
|
25
25
|
|
|
@@ -33,9 +33,10 @@ export default defineFunction({
|
|
|
33
33
|
HttpClient.execute,
|
|
34
34
|
Effect.flatMap((res: any) => res.json),
|
|
35
35
|
Effect.timeout('1 second'),
|
|
36
|
-
Effect.retry(Schedule.exponential(
|
|
36
|
+
Effect.retry(Schedule.exponential(1_000).pipe(Schedule.compose(Schedule.recurs(3)))),
|
|
37
37
|
Effect.scoped,
|
|
38
38
|
);
|
|
39
|
+
|
|
39
40
|
return res.data.rates[to].toString();
|
|
40
41
|
}).pipe(Effect.provide(FetchHttpClient.layer)),
|
|
41
42
|
});
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import { createStatic, defineFunction, EchoObject, Filter, ObjectId, S } from 'dxos:functions';
|
|
7
|
+
import {
|
|
8
|
+
HttpClient,
|
|
9
|
+
HttpClientRequest,
|
|
10
|
+
FetchHttpClient,
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
} from 'https://esm.sh/@effect/platform@0.77.2?deps=effect@3.13.3';
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
import { pipe, Chunk, Effect, Ref, Schedule, Stream } from 'https://esm.sh/effect@3.13.3';
|
|
15
|
+
|
|
16
|
+
// TODO(ZaymonFC): Calculate this dynamically and expose a parameter.
|
|
17
|
+
const DEFAULT_AFTER = '2025-01-01';
|
|
18
|
+
|
|
19
|
+
export default defineFunction({
|
|
20
|
+
inputSchema: S.Struct({
|
|
21
|
+
// TODO(wittjosiah): Remove. This is used to provide a terminal for a cron trigger.
|
|
22
|
+
tick: S.optional(S.String),
|
|
23
|
+
userId: S.optional(S.String),
|
|
24
|
+
after: S.optional(S.Union(S.Number, S.String)),
|
|
25
|
+
pageSize: S.optional(S.Number),
|
|
26
|
+
mailboxId: S.String,
|
|
27
|
+
}),
|
|
28
|
+
|
|
29
|
+
outputSchema: S.Struct({
|
|
30
|
+
newMessages: S.Number,
|
|
31
|
+
}),
|
|
32
|
+
|
|
33
|
+
handler: ({
|
|
34
|
+
event: {
|
|
35
|
+
data: { mailboxId, userId = 'me', after = DEFAULT_AFTER, pageSize = 100 },
|
|
36
|
+
},
|
|
37
|
+
context: { space },
|
|
38
|
+
}: any) =>
|
|
39
|
+
Effect.gen(function* () {
|
|
40
|
+
const { token } = yield* Effect.tryPromise({
|
|
41
|
+
try: () => space.db.query(Filter.typename('dxos.org/type/AccessToken', { source: 'gmail.com' })).first(),
|
|
42
|
+
catch: (e: any) => e,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const makeRequest = (path: string) =>
|
|
46
|
+
pipe(
|
|
47
|
+
path,
|
|
48
|
+
HttpClientRequest.get,
|
|
49
|
+
HttpClientRequest.setHeaders({ Authorization: `Bearer ${token}`, Accept: 'application/json' }),
|
|
50
|
+
HttpClient.execute,
|
|
51
|
+
Effect.flatMap((res: any) => res.json),
|
|
52
|
+
Effect.timeout('1 second'),
|
|
53
|
+
Effect.retry(Schedule.exponential(1000).pipe(Schedule.compose(Schedule.recurs(3)))),
|
|
54
|
+
Effect.scoped,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const listMessages = (userId: string, q: string, pageSize: number, pageToken: string | null) => {
|
|
58
|
+
const url = `https://gmail.googleapis.com/gmail/v1/users/${userId}/messages?maxResults=${pageSize}&q=${q}`;
|
|
59
|
+
return makeRequest(pageToken ? `${url}&pageToken=${pageToken}` : url);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const getMessage = (userId: string, id: string) =>
|
|
63
|
+
makeRequest(`https://gmail.googleapis.com/gmail/v1/users/${userId}/messages/${id}`);
|
|
64
|
+
|
|
65
|
+
const mailbox = yield* Effect.tryPromise({
|
|
66
|
+
try: () => space.db.query({ id: mailboxId }).first(),
|
|
67
|
+
catch: (e: any) => e,
|
|
68
|
+
});
|
|
69
|
+
const { objects } = yield* Effect.tryPromise({
|
|
70
|
+
try: () => space.queues.queryQueue(mailbox.queue.dxn),
|
|
71
|
+
catch: (e: any) => e,
|
|
72
|
+
});
|
|
73
|
+
const newMessages = yield* Ref.make([]);
|
|
74
|
+
const nextPage = yield* Ref.make(null);
|
|
75
|
+
|
|
76
|
+
do {
|
|
77
|
+
const last = objects.at(-1);
|
|
78
|
+
const q = last
|
|
79
|
+
? `in:inbox after:${Math.floor(new Date(last.created).getTime() / 1000)}`
|
|
80
|
+
: `in:inbox after:${after}`;
|
|
81
|
+
const pageToken = yield* Ref.get(nextPage);
|
|
82
|
+
const { messages, nextPageToken } = yield* listMessages(userId, q, pageSize, pageToken);
|
|
83
|
+
yield* Ref.update(nextPage, () => nextPageToken);
|
|
84
|
+
for (const message of messages) {
|
|
85
|
+
const messageDetails = yield* getMessage(userId, message.id);
|
|
86
|
+
const created = new Date(parseInt(messageDetails.internalDate)).toISOString();
|
|
87
|
+
const from = messageDetails.payload.headers.find((h: any) => h.name === 'From');
|
|
88
|
+
const sender = from && parseEmailString(from.value);
|
|
89
|
+
// TODO(wittjosiah): Improve parsing of email contents.
|
|
90
|
+
const content =
|
|
91
|
+
messageDetails.payload.body?.data ??
|
|
92
|
+
messageDetails.payload.parts?.find((p: any) => p.mimeType === 'text/plain')?.body.data;
|
|
93
|
+
// Skip the message if content or sender is missing.
|
|
94
|
+
// Skip the message if it's the same as the last message.
|
|
95
|
+
// TODO(wittjosiah): This comparison should be done via foreignId probably.
|
|
96
|
+
if (!content || !sender || created === last?.created) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const subject = messageDetails.payload.headers.find((h: any) => h.name === 'Subject')?.value;
|
|
100
|
+
const object = createStatic(MessageType, {
|
|
101
|
+
id: ObjectId.random(),
|
|
102
|
+
created,
|
|
103
|
+
sender,
|
|
104
|
+
blocks: [
|
|
105
|
+
{
|
|
106
|
+
type: 'text',
|
|
107
|
+
text: Buffer.from(content, 'base64').toString('utf-8'),
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
properties: {
|
|
111
|
+
subject,
|
|
112
|
+
threadId: message.threadId,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
// TODO(wittjosiah): Set foreignId in object meta.
|
|
116
|
+
yield* Ref.update(newMessages, (n: any) => [object, ...n]);
|
|
117
|
+
}
|
|
118
|
+
} while (yield* Ref.get(nextPage));
|
|
119
|
+
|
|
120
|
+
const queueMessages = yield* Ref.get(newMessages);
|
|
121
|
+
if (queueMessages.length > 0) {
|
|
122
|
+
yield* pipe(
|
|
123
|
+
queueMessages,
|
|
124
|
+
Stream.fromIterable,
|
|
125
|
+
Stream.grouped(10),
|
|
126
|
+
Stream.flatMap((batch: any) =>
|
|
127
|
+
Effect.tryPromise({
|
|
128
|
+
try: () => space.queues.insertIntoQueue(mailbox.queue.dxn, Chunk.toReadonlyArray(batch)),
|
|
129
|
+
catch: (e: any) => e,
|
|
130
|
+
}),
|
|
131
|
+
),
|
|
132
|
+
Stream.runDrain,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { newMessages: queueMessages.length };
|
|
137
|
+
}).pipe(Effect.provide(FetchHttpClient.layer)),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Parses an email string in the format "Name <email@example.com>" into separate name and email components.
|
|
142
|
+
*/
|
|
143
|
+
const parseEmailString = (emailString: string): { name?: string; email: string } | undefined => {
|
|
144
|
+
const match = emailString.match(/^([^<]+?)\s*<([^>]+@[^>]+)>$/);
|
|
145
|
+
if (match) {
|
|
146
|
+
const [, name, email] = match;
|
|
147
|
+
return {
|
|
148
|
+
name: name.trim(),
|
|
149
|
+
email: email.trim(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return undefined;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// TODO(wittjosiah): These schemas should be imported from @dxos/schema.
|
|
157
|
+
|
|
158
|
+
//
|
|
159
|
+
// Schemas
|
|
160
|
+
//
|
|
161
|
+
|
|
162
|
+
const ActorRoles = ['user', 'assistant'] as const;
|
|
163
|
+
const ActorRole = S.Literal(...ActorRoles);
|
|
164
|
+
type ActorRole = S.Schema.Type<typeof ActorRole>;
|
|
165
|
+
|
|
166
|
+
const ActorSchema = S.Struct({
|
|
167
|
+
identityKey: S.optional(S.String),
|
|
168
|
+
email: S.optional(S.String),
|
|
169
|
+
name: S.optional(S.String),
|
|
170
|
+
role: S.optional(ActorRole),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const AbstractContentBlock = S.Struct({
|
|
174
|
+
pending: S.optional(S.Boolean),
|
|
175
|
+
});
|
|
176
|
+
type AbstractContentBlock = S.Schema.Type<typeof AbstractContentBlock>;
|
|
177
|
+
const TextContentBlock = S.extend(
|
|
178
|
+
AbstractContentBlock,
|
|
179
|
+
S.Struct({
|
|
180
|
+
type: S.Literal('text'),
|
|
181
|
+
disposition: S.optional(S.String),
|
|
182
|
+
text: S.String,
|
|
183
|
+
}),
|
|
184
|
+
).pipe(S.mutable);
|
|
185
|
+
type TextContentBlock = S.Schema.Type<typeof TextContentBlock>;
|
|
186
|
+
const JsonContentBlock = S.extend(
|
|
187
|
+
AbstractContentBlock,
|
|
188
|
+
S.Struct({
|
|
189
|
+
type: S.Literal('json'),
|
|
190
|
+
disposition: S.optional(S.String),
|
|
191
|
+
data: S.String,
|
|
192
|
+
}),
|
|
193
|
+
).pipe(S.mutable);
|
|
194
|
+
type JsonContentBlock = S.Schema.Type<typeof JsonContentBlock>;
|
|
195
|
+
const Base64ImageSource = S.Struct({
|
|
196
|
+
type: S.Literal('base64'),
|
|
197
|
+
mediaType: S.String,
|
|
198
|
+
data: S.String,
|
|
199
|
+
}).pipe(S.mutable);
|
|
200
|
+
const HttpImageSource = S.Struct({
|
|
201
|
+
type: S.Literal('http'),
|
|
202
|
+
url: S.String,
|
|
203
|
+
}).pipe(S.mutable);
|
|
204
|
+
const ImageSource = S.Union(Base64ImageSource, HttpImageSource);
|
|
205
|
+
type ImageSource = S.Schema.Type<typeof ImageSource>;
|
|
206
|
+
const ImageContentBlock = S.extend(
|
|
207
|
+
AbstractContentBlock,
|
|
208
|
+
S.Struct({
|
|
209
|
+
type: S.Literal('image'),
|
|
210
|
+
id: S.optional(S.String),
|
|
211
|
+
source: S.optional(ImageSource),
|
|
212
|
+
}),
|
|
213
|
+
).pipe(S.mutable);
|
|
214
|
+
type ImageContentBlock = S.Schema.Type<typeof ImageContentBlock>;
|
|
215
|
+
const ReferenceContentBlock = S.extend(
|
|
216
|
+
AbstractContentBlock,
|
|
217
|
+
S.Struct({
|
|
218
|
+
type: S.Literal('reference'),
|
|
219
|
+
reference: S.Any,
|
|
220
|
+
}),
|
|
221
|
+
).pipe(S.mutable);
|
|
222
|
+
type ReferenceContentBlock = S.Schema.Type<typeof ReferenceContentBlock>;
|
|
223
|
+
const MessageContentBlock = S.Union(TextContentBlock, JsonContentBlock, ImageContentBlock, ReferenceContentBlock);
|
|
224
|
+
|
|
225
|
+
const MessageType = S.Struct({
|
|
226
|
+
id: ObjectId,
|
|
227
|
+
created: S.String.annotations({
|
|
228
|
+
description: 'ISO date string when the message was sent.',
|
|
229
|
+
}),
|
|
230
|
+
sender: ActorSchema.annotations({
|
|
231
|
+
description: 'Identity of the message sender.',
|
|
232
|
+
}),
|
|
233
|
+
blocks: S.Array(MessageContentBlock).annotations({
|
|
234
|
+
description: 'Contents of the message.',
|
|
235
|
+
}),
|
|
236
|
+
properties: S.optional(
|
|
237
|
+
S.mutable(
|
|
238
|
+
S.Record({ key: S.String, value: S.Any }).annotations({
|
|
239
|
+
description: 'Custom properties for specific message types (e.g. attention context, email subject, etc.).',
|
|
240
|
+
}),
|
|
241
|
+
),
|
|
242
|
+
),
|
|
243
|
+
}).pipe(EchoObject({ typename: 'dxos.org/type/Message', version: '0.1.0' }));
|
|
244
|
+
type MessageType = S.Schema.Type<typeof MessageType>;
|
package/src/templates/index.ts
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import chat from './chat.ts?raw';
|
|
6
6
|
import chess from './chess.ts?raw';
|
|
7
|
+
import dataGenerator from './data-generator.ts?raw';
|
|
7
8
|
import discord from './discord.ts?raw';
|
|
8
9
|
import echo from './echo.ts?raw';
|
|
9
10
|
import email from './email.ts?raw';
|
|
10
11
|
import forexEffect from './forex-effect.ts?raw';
|
|
11
12
|
import forex from './forex.ts?raw';
|
|
13
|
+
import gmail from './gmail.ts?raw';
|
|
12
14
|
|
|
13
15
|
const removeHeader = (str: string) => str.split('\n').slice(4).join('\n');
|
|
14
16
|
|
|
@@ -59,4 +61,16 @@ export const templates: Template[] = [
|
|
|
59
61
|
source: removeHeader(discord),
|
|
60
62
|
presetId: 'dxos.org/function/discord',
|
|
61
63
|
},
|
|
64
|
+
{
|
|
65
|
+
id: 'dxos.org/script/gmail',
|
|
66
|
+
name: 'Gmail',
|
|
67
|
+
source: removeHeader(gmail),
|
|
68
|
+
presetId: 'dxos.org/function/gmail',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'dxos.org/script/data-generator',
|
|
72
|
+
name: 'Data Generator',
|
|
73
|
+
source: removeHeader(dataGenerator),
|
|
74
|
+
presetId: 'dxos.org/function/data-generator',
|
|
75
|
+
},
|
|
62
76
|
];
|
package/src/translations.ts
CHANGED
|
@@ -11,14 +11,12 @@ export default [
|
|
|
11
11
|
'en-US': {
|
|
12
12
|
[ScriptType.typename]: {
|
|
13
13
|
'typename label': 'Script',
|
|
14
|
+
'object name placeholder': 'New script',
|
|
14
15
|
},
|
|
15
16
|
[SCRIPT_PLUGIN]: {
|
|
16
17
|
'plugin name': 'Scripts',
|
|
17
|
-
'object title placeholder': 'New script',
|
|
18
|
-
'create object label': 'Create script',
|
|
19
|
-
'create stack section label': 'Create script',
|
|
20
18
|
'description label': 'Description',
|
|
21
|
-
'description placeholder': '
|
|
19
|
+
'description placeholder': 'Enter description',
|
|
22
20
|
'binding placeholder': 'Function name',
|
|
23
21
|
'function request placeholder': 'Function request',
|
|
24
22
|
'deploy label': 'Deploy',
|
|
@@ -33,10 +31,10 @@ export default [
|
|
|
33
31
|
'remote function settings heading': 'Remote Function',
|
|
34
32
|
'function url label': 'Invocation URL',
|
|
35
33
|
'function binding label': 'Function binding',
|
|
36
|
-
'function binding placeholder': '
|
|
34
|
+
'function binding placeholder': 'Enter binding name (e.g., NAME)',
|
|
37
35
|
'script publish settings label': 'Publishing',
|
|
38
36
|
'script publish settings description': 'Scripts can be shared publicly as Github gists.',
|
|
39
|
-
'no github token label': 'This space has no
|
|
37
|
+
'no github token label': 'This space has no GitHub access token available.',
|
|
40
38
|
'open token manager label': 'Open Token Manager',
|
|
41
39
|
'publish label': 'Publish',
|
|
42
40
|
'publishing label': 'Publishing',
|
|
@@ -45,12 +43,32 @@ export default [
|
|
|
45
43
|
'settings editor input mode default label': 'Default',
|
|
46
44
|
'settings editor input mode vim label': 'Vim',
|
|
47
45
|
'settings editor input mode vscode label': 'VS Code',
|
|
48
|
-
'view group label': 'View',
|
|
49
|
-
'view editor label': 'Editor',
|
|
50
|
-
'view split label': 'Split',
|
|
51
|
-
'view logs label': 'Logs',
|
|
52
46
|
'template select group label': 'Select template',
|
|
53
47
|
'function panel label': 'Debug Function',
|
|
48
|
+
'script test label': 'Test',
|
|
49
|
+
'script logs label': 'Logs',
|
|
50
|
+
'deployment dialog title': 'Default Scripts',
|
|
51
|
+
'deployment dialog scripts found message_one':
|
|
52
|
+
'We found the following script template for your new integration:',
|
|
53
|
+
'deployment dialog scripts found message_other':
|
|
54
|
+
'We found the following script templates for your new integration:',
|
|
55
|
+
'deployment dialog deploy functions button label_one': 'Create and deploy script',
|
|
56
|
+
'deployment dialog deploy functions button label_other': 'Create and deploy scripts',
|
|
57
|
+
'deployment dialog deploy functions pending button label_one': 'Deploying script',
|
|
58
|
+
'deployment dialog deploy functions pending button label_other': 'Deploying scripts',
|
|
59
|
+
'deployment dialog skip button label': 'Skip',
|
|
60
|
+
'script deployment toast label_one': 'Script deployed',
|
|
61
|
+
'script deployment toast label_other': 'Scripts deployed',
|
|
62
|
+
'script deployment toast description_one': 'Your script has been deployed successfully.',
|
|
63
|
+
'script deployment toast description_other': 'Your scripts have been deployed successfully.',
|
|
64
|
+
'script deployment toast close label_one': 'Close',
|
|
65
|
+
'script deployment toast close label_other': 'Close',
|
|
66
|
+
'script deployment error toast label_one': 'Script deployment failed',
|
|
67
|
+
'script deployment error toast label_other': 'Scripts deployment failed',
|
|
68
|
+
'script deployment error toast description_one': 'There was an error deploying your script.',
|
|
69
|
+
'script deployment error toast description_other': 'There was an error deploying your scripts.',
|
|
70
|
+
'script deployment error toast close label_one': 'Close',
|
|
71
|
+
'script deployment error toast close label_other': 'Close',
|
|
54
72
|
},
|
|
55
73
|
},
|
|
56
74
|
},
|
package/src/types.ts
CHANGED
|
@@ -11,6 +11,9 @@ import { EditorInputMode } from '@dxos/react-ui-editor';
|
|
|
11
11
|
|
|
12
12
|
import { SCRIPT_PLUGIN } from './meta';
|
|
13
13
|
|
|
14
|
+
// TODO(burdon): Standardize export (e.g., @dxos/plugin-script/meta)?
|
|
15
|
+
export { SCRIPT_PLUGIN };
|
|
16
|
+
|
|
14
17
|
export namespace ScriptAction {
|
|
15
18
|
const SCRIPT_ACTION = `${SCRIPT_PLUGIN}/action`;
|
|
16
19
|
|
|
@@ -18,6 +21,7 @@ export namespace ScriptAction {
|
|
|
18
21
|
name: S.optional(S.String),
|
|
19
22
|
// TODO(wittjosiah): Placeholder annotation?
|
|
20
23
|
gistUrl: S.optional(S.String.annotations({ [TitleAnnotationId]: 'Import from Gist (url)' })),
|
|
24
|
+
initialTemplateId: S.optional(S.String),
|
|
21
25
|
});
|
|
22
26
|
|
|
23
27
|
export type CreateScriptProps = S.Schema.Type<typeof CreateScriptSchema>;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Client } from '@dxos/client';
|
|
6
|
+
import {
|
|
7
|
+
FunctionType,
|
|
8
|
+
type ScriptType,
|
|
9
|
+
getUserFunctionUrlInMetadata,
|
|
10
|
+
incrementSemverPatch,
|
|
11
|
+
setUserFunctionUrlInMetadata,
|
|
12
|
+
uploadWorkerFunction,
|
|
13
|
+
} from '@dxos/functions';
|
|
14
|
+
import { Bundler } from '@dxos/functions/bundler';
|
|
15
|
+
import { log } from '@dxos/log';
|
|
16
|
+
import { create, getMeta, makeRef, type Space } from '@dxos/react-client/echo';
|
|
17
|
+
|
|
18
|
+
import { updateFunctionMetadata } from './functions';
|
|
19
|
+
|
|
20
|
+
export const isScriptDeployed = ({ script, fn }: { script: ScriptType; fn: any }): boolean => {
|
|
21
|
+
const existingFunctionUrl = fn && getUserFunctionUrlInMetadata(getMeta(fn));
|
|
22
|
+
return Boolean(existingFunctionUrl) && !script.changed;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type DeployScriptProps = {
|
|
26
|
+
script: ScriptType;
|
|
27
|
+
client: Client;
|
|
28
|
+
space: Space;
|
|
29
|
+
fn?: FunctionType;
|
|
30
|
+
existingFunctionUrl?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type DeployScriptResult = { success: boolean; error?: Error; functionUrl?: string };
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Deploy a script to a space, handling bundling and uploading to the FaaS infrastructure.
|
|
37
|
+
*/
|
|
38
|
+
export const deployScript = async ({
|
|
39
|
+
script,
|
|
40
|
+
client,
|
|
41
|
+
space,
|
|
42
|
+
fn,
|
|
43
|
+
existingFunctionUrl,
|
|
44
|
+
}: DeployScriptProps): Promise<DeployScriptResult> => {
|
|
45
|
+
const validationError = validateDeployInputs(script, space);
|
|
46
|
+
if (validationError) {
|
|
47
|
+
return { success: false, error: validationError };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const existingFunctionId = extractFunctionId(existingFunctionUrl);
|
|
52
|
+
|
|
53
|
+
const { bundle, error } = await bundleScript(script.source!.target!.content);
|
|
54
|
+
if (error || !bundle) {
|
|
55
|
+
throw error || new Error('Bundle creation failed');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const { functionId, version, meta } = await uploadWorkerFunction({
|
|
59
|
+
client,
|
|
60
|
+
spaceId: space.id,
|
|
61
|
+
version: fn ? incrementSemverPatch(fn.version) : '0.0.1',
|
|
62
|
+
functionId: existingFunctionId,
|
|
63
|
+
source: bundle,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (functionId === undefined || version === undefined) {
|
|
67
|
+
throw new Error(`Upload didn't return expected data: ${JSON.stringify({ functionId, version })}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const storedFunction = createOrUpdateFunctionInSpace(space, fn, script, functionId, version);
|
|
71
|
+
script.changed = false;
|
|
72
|
+
updateFunctionMetadata(script, storedFunction, meta, functionId);
|
|
73
|
+
|
|
74
|
+
const functionUrl = makeFunctionUrl(space.id, functionId);
|
|
75
|
+
setUserFunctionUrlInMetadata(getMeta(storedFunction), functionUrl);
|
|
76
|
+
|
|
77
|
+
return { success: true, functionUrl };
|
|
78
|
+
} catch (err: any) {
|
|
79
|
+
log.catch(err);
|
|
80
|
+
return { success: false, error: err };
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Validate inputs for script deployment.
|
|
86
|
+
*/
|
|
87
|
+
const validateDeployInputs = (script: ScriptType, space: Space): Error | null => {
|
|
88
|
+
if (!script.source || !space) {
|
|
89
|
+
return new Error('Script source or space not available');
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const extractFunctionId = (functionUrl?: string): string | undefined => {
|
|
95
|
+
return functionUrl?.split('/').at(-1);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const bundleScript = async (source: string): Promise<{ bundle?: string; error?: Error }> => {
|
|
99
|
+
const bundler = new Bundler({ platform: 'browser', sandboxedModules: [], remoteModules: {} });
|
|
100
|
+
const buildResult = await bundler.bundle({ source });
|
|
101
|
+
|
|
102
|
+
if (buildResult.error || !buildResult.bundle) {
|
|
103
|
+
return { error: buildResult.error || new Error('Bundle creation failed') };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { bundle: buildResult.bundle };
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const createOrUpdateFunctionInSpace = (
|
|
110
|
+
space: Space,
|
|
111
|
+
fn: FunctionType | undefined,
|
|
112
|
+
script: ScriptType,
|
|
113
|
+
functionId: string,
|
|
114
|
+
version: string,
|
|
115
|
+
): FunctionType => {
|
|
116
|
+
if (fn) {
|
|
117
|
+
fn.version = version;
|
|
118
|
+
return fn;
|
|
119
|
+
} else {
|
|
120
|
+
return space.db.add(create(FunctionType, { name: functionId, version, source: makeRef(script) }));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const makeFunctionUrl = (spaceId: string, functionId: string): string => {
|
|
125
|
+
return `/${spaceId}/${functionId}`;
|
|
126
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ScriptType, getInvocationUrl, getUserFunctionUrlInMetadata } from '@dxos/functions';
|
|
6
|
+
import { log } from '@dxos/log';
|
|
7
|
+
import { getMeta, getSpace } from '@dxos/react-client/echo';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get the function URL for a given script and client configuration
|
|
11
|
+
*/
|
|
12
|
+
export const getFunctionUrl = ({
|
|
13
|
+
script,
|
|
14
|
+
fn,
|
|
15
|
+
edgeUrl,
|
|
16
|
+
}: {
|
|
17
|
+
script: ScriptType;
|
|
18
|
+
fn: any;
|
|
19
|
+
edgeUrl: string;
|
|
20
|
+
}): string | undefined => {
|
|
21
|
+
const space = getSpace(script);
|
|
22
|
+
const existingFunctionUrl = fn && getUserFunctionUrlInMetadata(getMeta(fn));
|
|
23
|
+
|
|
24
|
+
if (!existingFunctionUrl) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return getInvocationUrl(existingFunctionUrl, edgeUrl, {
|
|
29
|
+
spaceId: space?.id,
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const updateFunctionMetadata = (script: ScriptType, storedFunction: any, meta: any, functionId: string) => {
|
|
34
|
+
if (script.description !== undefined && script.description.trim() !== '') {
|
|
35
|
+
storedFunction.description = script.description;
|
|
36
|
+
} else if (meta.description) {
|
|
37
|
+
storedFunction.description = meta.description;
|
|
38
|
+
} else {
|
|
39
|
+
log.verbose('no description in function metadata', { functionId });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (meta.inputSchema) {
|
|
43
|
+
storedFunction.inputSchema = meta.inputSchema;
|
|
44
|
+
} else {
|
|
45
|
+
log.verbose('no input schema in function metadata', { functionId });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (meta.outputSchema) {
|
|
49
|
+
storedFunction.outputSchema = meta.outputSchema;
|
|
50
|
+
} else {
|
|
51
|
+
log.verbose('no output schema in function metadata', { functionId });
|
|
52
|
+
}
|
|
53
|
+
};
|