@quenty/studio-bridge 0.21.0 → 0.22.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.
- package/CHANGELOG.md +12 -0
- package/README.md +109 -17
- package/build-scripts/transform-add-session-attribute.lua +1 -0
- package/deploy.nevermore.json +10 -0
- package/dist/src/bridge/bridge-connection.d.ts +26 -2
- package/dist/src/bridge/bridge-connection.d.ts.map +1 -1
- package/dist/src/bridge/bridge-connection.js +159 -14
- package/dist/src/bridge/bridge-connection.js.map +1 -1
- package/dist/src/bridge/bridge-connection.test.js +81 -0
- package/dist/src/bridge/bridge-connection.test.js.map +1 -1
- package/dist/src/bridge/bridge-session.d.ts +35 -2
- package/dist/src/bridge/bridge-session.d.ts.map +1 -1
- package/dist/src/bridge/bridge-session.js +185 -28
- package/dist/src/bridge/bridge-session.js.map +1 -1
- package/dist/src/bridge/bridge-session.test.js +6 -4
- package/dist/src/bridge/bridge-session.test.js.map +1 -1
- package/dist/src/bridge/index.d.ts +1 -1
- package/dist/src/bridge/index.d.ts.map +1 -1
- package/dist/src/bridge/index.js.map +1 -1
- package/dist/src/bridge/internal/bridge-client.d.ts +4 -0
- package/dist/src/bridge/internal/bridge-client.d.ts.map +1 -1
- package/dist/src/bridge/internal/bridge-client.js +20 -7
- package/dist/src/bridge/internal/bridge-client.js.map +1 -1
- package/dist/src/bridge/internal/bridge-client.test.js +18 -0
- package/dist/src/bridge/internal/bridge-client.test.js.map +1 -1
- package/dist/src/bridge/internal/bridge-host.d.ts +13 -1
- package/dist/src/bridge/internal/bridge-host.d.ts.map +1 -1
- package/dist/src/bridge/internal/bridge-host.js +35 -0
- package/dist/src/bridge/internal/bridge-host.js.map +1 -1
- package/dist/src/bridge/internal/bridge-host.test.js +31 -0
- package/dist/src/bridge/internal/bridge-host.test.js.map +1 -1
- package/dist/src/bridge/internal/hand-off.d.ts.map +1 -1
- package/dist/src/bridge/internal/hand-off.js +4 -1
- package/dist/src/bridge/internal/hand-off.js.map +1 -1
- package/dist/src/bridge/internal/host-protocol.d.ts +8 -0
- package/dist/src/bridge/internal/host-protocol.d.ts.map +1 -1
- package/dist/src/bridge/internal/host-protocol.js +120 -13
- package/dist/src/bridge/internal/host-protocol.js.map +1 -1
- package/dist/src/bridge/internal/host-protocol.test.js +13 -0
- package/dist/src/bridge/internal/host-protocol.test.js.map +1 -1
- package/dist/src/bridge/internal/instance-state.d.ts +9 -0
- package/dist/src/bridge/internal/instance-state.d.ts.map +1 -0
- package/dist/src/bridge/internal/instance-state.js +28 -0
- package/dist/src/bridge/internal/instance-state.js.map +1 -0
- package/dist/src/bridge/internal/transport-client.d.ts.map +1 -1
- package/dist/src/bridge/internal/transport-client.js +2 -1
- package/dist/src/bridge/internal/transport-client.js.map +1 -1
- package/dist/src/bridge/internal/transport-server.d.ts.map +1 -1
- package/dist/src/bridge/internal/transport-server.js +5 -1
- package/dist/src/bridge/internal/transport-server.js.map +1 -1
- package/dist/src/bridge/types.d.ts +43 -4
- package/dist/src/bridge/types.d.ts.map +1 -1
- package/dist/src/bridge/types.js.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js +24 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter.d.ts +6 -0
- package/dist/src/cli/adapters/cli-command-adapter.d.ts.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter.js +107 -11
- package/dist/src/cli/adapters/cli-command-adapter.js.map +1 -1
- package/dist/src/cli/adapters/group-builder.d.ts +3 -0
- package/dist/src/cli/adapters/group-builder.d.ts.map +1 -1
- package/dist/src/cli/adapters/group-builder.js +34 -15
- package/dist/src/cli/adapters/group-builder.js.map +1 -1
- package/dist/src/cli/adapters/group-builder.test.js +26 -2
- package/dist/src/cli/adapters/group-builder.test.js.map +1 -1
- package/dist/src/cli/adapters/help-formatter.d.ts.map +1 -1
- package/dist/src/cli/adapters/help-formatter.js +4 -3
- package/dist/src/cli/adapters/help-formatter.js.map +1 -1
- package/dist/src/cli/adapters/help-formatter.test.js +1 -1
- package/dist/src/cli/adapters/help-formatter.test.js.map +1 -1
- package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts +2 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.js +28 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.js.map +1 -0
- package/dist/src/cli/args/global-args.d.ts +1 -1
- package/dist/src/cli/args/global-args.d.ts.map +1 -1
- package/dist/src/cli/cli-output-context.d.ts +14 -0
- package/dist/src/cli/cli-output-context.d.ts.map +1 -0
- package/dist/src/cli/cli-output-context.js +39 -0
- package/dist/src/cli/cli-output-context.js.map +1 -0
- package/dist/src/cli/cli-output-context.test.d.ts +2 -0
- package/dist/src/cli/cli-output-context.test.d.ts.map +1 -0
- package/dist/src/cli/cli-output-context.test.js +38 -0
- package/dist/src/cli/cli-output-context.test.js.map +1 -0
- package/dist/src/cli/cli.js +40 -17
- package/dist/src/cli/cli.js.map +1 -1
- package/dist/src/cli/managed-studio-run.d.ts +21 -0
- package/dist/src/cli/managed-studio-run.d.ts.map +1 -0
- package/dist/src/cli/managed-studio-run.js +75 -0
- package/dist/src/cli/managed-studio-run.js.map +1 -0
- package/dist/src/cli/managed-studio-run.test.d.ts +2 -0
- package/dist/src/cli/managed-studio-run.test.d.ts.map +1 -0
- package/dist/src/cli/managed-studio-run.test.js +52 -0
- package/dist/src/cli/managed-studio-run.test.js.map +1 -0
- package/dist/src/cli/resolve-session.js +1 -1
- package/dist/src/cli/resolve-session.js.map +1 -1
- package/dist/src/cli/resolve-session.test.js +1 -1
- package/dist/src/cli/resolve-session.test.js.map +1 -1
- package/dist/src/cli/script-executor.d.ts +13 -1
- package/dist/src/cli/script-executor.d.ts.map +1 -1
- package/dist/src/cli/script-executor.js +77 -47
- package/dist/src/cli/script-executor.js.map +1 -1
- package/dist/src/commands/console/exec/exec.d.ts +17 -0
- package/dist/src/commands/console/exec/exec.d.ts.map +1 -1
- package/dist/src/commands/console/exec/exec.js +39 -7
- package/dist/src/commands/console/exec/exec.js.map +1 -1
- package/dist/src/commands/console/exec/exec.test.js +62 -3
- package/dist/src/commands/console/exec/exec.test.js.map +1 -1
- package/dist/src/commands/console/logs/logs.d.ts +30 -2
- package/dist/src/commands/console/logs/logs.d.ts.map +1 -1
- package/dist/src/commands/console/logs/logs.js +82 -7
- package/dist/src/commands/console/logs/logs.js.map +1 -1
- package/dist/src/commands/console/logs/logs.test.js +63 -4
- package/dist/src/commands/console/logs/logs.test.js.map +1 -1
- package/dist/src/commands/explorer/export/export.d.ts +19 -0
- package/dist/src/commands/explorer/export/export.d.ts.map +1 -0
- package/dist/src/commands/explorer/export/export.js +37 -0
- package/dist/src/commands/explorer/export/export.js.map +1 -0
- package/dist/src/commands/explorer/export/export.test.d.ts +2 -0
- package/dist/src/commands/explorer/export/export.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/export/export.test.js +25 -0
- package/dist/src/commands/explorer/export/export.test.js.map +1 -0
- package/dist/src/commands/explorer/find/find.d.ts +28 -0
- package/dist/src/commands/explorer/find/find.d.ts.map +1 -0
- package/dist/src/commands/explorer/find/find.js +75 -0
- package/dist/src/commands/explorer/find/find.js.map +1 -0
- package/dist/src/commands/explorer/find/find.test.d.ts +2 -0
- package/dist/src/commands/explorer/find/find.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/find/find.test.js +44 -0
- package/dist/src/commands/explorer/find/find.test.js.map +1 -0
- package/dist/src/commands/explorer/grep/grep.d.ts +24 -0
- package/dist/src/commands/explorer/grep/grep.d.ts.map +1 -0
- package/dist/src/commands/explorer/grep/grep.js +63 -0
- package/dist/src/commands/explorer/grep/grep.js.map +1 -0
- package/dist/src/commands/explorer/grep/grep.test.d.ts +2 -0
- package/dist/src/commands/explorer/grep/grep.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/grep/grep.test.js +42 -0
- package/dist/src/commands/explorer/grep/grep.test.js.map +1 -0
- package/dist/src/commands/explorer/import/import.d.ts +21 -0
- package/dist/src/commands/explorer/import/import.d.ts.map +1 -0
- package/dist/src/commands/explorer/import/import.js +37 -0
- package/dist/src/commands/explorer/import/import.js.map +1 -0
- package/dist/src/commands/explorer/import/import.test.d.ts +2 -0
- package/dist/src/commands/explorer/import/import.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/import/import.test.js +45 -0
- package/dist/src/commands/explorer/import/import.test.js.map +1 -0
- package/dist/src/commands/formatters.test.js +7 -1
- package/dist/src/commands/formatters.test.js.map +1 -1
- package/dist/src/commands/framework/action-loader.d.ts +5 -1
- package/dist/src/commands/framework/action-loader.d.ts.map +1 -1
- package/dist/src/commands/framework/action-loader.js +9 -2
- package/dist/src/commands/framework/action-loader.js.map +1 -1
- package/dist/src/commands/framework/action-loader.test.js +23 -0
- package/dist/src/commands/framework/action-loader.test.js.map +1 -1
- package/dist/src/commands/framework/arg-builder.d.ts +15 -2
- package/dist/src/commands/framework/arg-builder.d.ts.map +1 -1
- package/dist/src/commands/framework/arg-builder.js +22 -2
- package/dist/src/commands/framework/arg-builder.js.map +1 -1
- package/dist/src/commands/framework/define-command.d.ts +19 -3
- package/dist/src/commands/framework/define-command.d.ts.map +1 -1
- package/dist/src/commands/framework/define-command.js.map +1 -1
- package/dist/src/commands/framework/index.d.ts +1 -1
- package/dist/src/commands/framework/index.d.ts.map +1 -1
- package/dist/src/commands/framework/index.js.map +1 -1
- package/dist/src/commands/index.d.ts +11 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +11 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts.map +1 -1
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js +1 -3
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js.map +1 -1
- package/dist/src/commands/linux/setup/setup.d.ts.map +1 -1
- package/dist/src/commands/linux/setup/setup.js +1 -3
- package/dist/src/commands/linux/setup/setup.js.map +1 -1
- package/dist/src/commands/linux/status/status.d.ts +9 -1
- package/dist/src/commands/linux/status/status.d.ts.map +1 -1
- package/dist/src/commands/linux/status/status.js +66 -86
- package/dist/src/commands/linux/status/status.js.map +1 -1
- package/dist/src/commands/playtest/player/add/add.d.ts +17 -0
- package/dist/src/commands/playtest/player/add/add.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/add/add.js +45 -0
- package/dist/src/commands/playtest/player/add/add.js.map +1 -0
- package/dist/src/commands/playtest/player/list/list.d.ts +13 -0
- package/dist/src/commands/playtest/player/list/list.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/list/list.js +33 -0
- package/dist/src/commands/playtest/player/list/list.js.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.d.ts +36 -0
- package/dist/src/commands/playtest/player/playtest-players.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.js +187 -0
- package/dist/src/commands/playtest/player/playtest-players.js.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.test.d.ts +2 -0
- package/dist/src/commands/playtest/player/playtest-players.test.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.test.js +89 -0
- package/dist/src/commands/playtest/player/playtest-players.test.js.map +1 -0
- package/dist/src/commands/playtest/player/remove/remove.d.ts +17 -0
- package/dist/src/commands/playtest/player/remove/remove.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/remove/remove.js +42 -0
- package/dist/src/commands/playtest/player/remove/remove.js.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.d.ts +49 -0
- package/dist/src/commands/playtest/playtest-sessions.d.ts.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.js +283 -0
- package/dist/src/commands/playtest/playtest-sessions.js.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.test.d.ts +2 -0
- package/dist/src/commands/playtest/playtest-sessions.test.d.ts.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.test.js +87 -0
- package/dist/src/commands/playtest/playtest-sessions.test.js.map +1 -0
- package/dist/src/commands/playtest/restart/restart.d.ts +23 -0
- package/dist/src/commands/playtest/restart/restart.d.ts.map +1 -0
- package/dist/src/commands/playtest/restart/restart.js +105 -0
- package/dist/src/commands/playtest/restart/restart.js.map +1 -0
- package/dist/src/commands/playtest/run/run.d.ts +47 -0
- package/dist/src/commands/playtest/run/run.d.ts.map +1 -0
- package/dist/src/commands/playtest/run/run.js +137 -0
- package/dist/src/commands/playtest/run/run.js.map +1 -0
- package/dist/src/commands/playtest/start/start.d.ts +42 -0
- package/dist/src/commands/playtest/start/start.d.ts.map +1 -0
- package/dist/src/commands/playtest/start/start.js +70 -0
- package/dist/src/commands/playtest/start/start.js.map +1 -0
- package/dist/src/commands/playtest/stop/stop.d.ts +15 -0
- package/dist/src/commands/playtest/stop/stop.d.ts.map +1 -0
- package/dist/src/commands/playtest/stop/stop.js +24 -0
- package/dist/src/commands/playtest/stop/stop.js.map +1 -0
- package/dist/src/commands/process/close/close.d.ts +19 -10
- package/dist/src/commands/process/close/close.d.ts.map +1 -1
- package/dist/src/commands/process/close/close.js +118 -15
- package/dist/src/commands/process/close/close.js.map +1 -1
- package/dist/src/commands/process/close/close.test.d.ts +2 -0
- package/dist/src/commands/process/close/close.test.d.ts.map +1 -0
- package/dist/src/commands/process/close/close.test.js +190 -0
- package/dist/src/commands/process/close/close.test.js.map +1 -0
- package/dist/src/commands/process/info/info.d.ts +45 -5
- package/dist/src/commands/process/info/info.d.ts.map +1 -1
- package/dist/src/commands/process/info/info.js +117 -13
- package/dist/src/commands/process/info/info.js.map +1 -1
- package/dist/src/commands/process/info/info.test.js +140 -38
- package/dist/src/commands/process/info/info.test.js.map +1 -1
- package/dist/src/commands/process/launch/launch.d.ts +11 -1
- package/dist/src/commands/process/launch/launch.d.ts.map +1 -1
- package/dist/src/commands/process/launch/launch.js +37 -7
- package/dist/src/commands/process/launch/launch.js.map +1 -1
- package/dist/src/commands/process/launch/launch.test.js +99 -20
- package/dist/src/commands/process/launch/launch.test.js.map +1 -1
- package/dist/src/commands/process/list/list.d.ts +2 -1
- package/dist/src/commands/process/list/list.d.ts.map +1 -1
- package/dist/src/commands/process/list/list.js +9 -6
- package/dist/src/commands/process/list/list.js.map +1 -1
- package/dist/src/commands/process/list/list.test.js +1 -0
- package/dist/src/commands/process/list/list.test.js.map +1 -1
- package/dist/src/commands/process/run/run.d.ts +9 -0
- package/dist/src/commands/process/run/run.d.ts.map +1 -1
- package/dist/src/commands/process/run/run.js +15 -5
- package/dist/src/commands/process/run/run.js.map +1 -1
- package/dist/src/commands/serve/serve.d.ts +2 -0
- package/dist/src/commands/serve/serve.d.ts.map +1 -1
- package/dist/src/commands/serve/serve.js +17 -4
- package/dist/src/commands/serve/serve.js.map +1 -1
- package/dist/src/commands/serve/serve.test.js +9 -2
- package/dist/src/commands/serve/serve.test.js.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.d.ts.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.js +4 -1
- package/dist/src/commands/viewport/screenshot/screenshot.js.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.test.js +5 -9
- package/dist/src/commands/viewport/screenshot/screenshot.test.js.map +1 -1
- package/dist/src/deploy/deploy-places.d.ts +39 -0
- package/dist/src/deploy/deploy-places.d.ts.map +1 -0
- package/dist/src/deploy/deploy-places.js +162 -0
- package/dist/src/deploy/deploy-places.js.map +1 -0
- package/dist/src/deploy/deploy-places.test.d.ts +2 -0
- package/dist/src/deploy/deploy-places.test.d.ts.map +1 -0
- package/dist/src/deploy/deploy-places.test.js +96 -0
- package/dist/src/deploy/deploy-places.test.js.map +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/linux/linux-studio-launcher.d.ts.map +1 -1
- package/dist/src/linux/linux-studio-launcher.js +10 -0
- package/dist/src/linux/linux-studio-launcher.js.map +1 -1
- package/dist/src/linux/linux-studio-launcher.test.d.ts +2 -0
- package/dist/src/linux/linux-studio-launcher.test.d.ts.map +1 -0
- package/dist/src/linux/linux-studio-launcher.test.js +68 -0
- package/dist/src/linux/linux-studio-launcher.test.js.map +1 -0
- package/dist/src/plugin/persistent-plugin-installer.d.ts.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.js +2 -1
- package/dist/src/plugin/persistent-plugin-installer.js.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.test.js +3 -0
- package/dist/src/plugin/persistent-plugin-installer.test.js.map +1 -1
- package/dist/src/plugin/plugin-build-version.d.ts +7 -0
- package/dist/src/plugin/plugin-build-version.d.ts.map +1 -0
- package/dist/src/plugin/plugin-build-version.js +42 -0
- package/dist/src/plugin/plugin-build-version.js.map +1 -0
- package/dist/src/plugin/plugin-build-version.test.d.ts +2 -0
- package/dist/src/plugin/plugin-build-version.test.d.ts.map +1 -0
- package/dist/src/plugin/plugin-build-version.test.js +41 -0
- package/dist/src/plugin/plugin-build-version.test.js.map +1 -0
- package/dist/src/plugin/plugin-injector.d.ts.map +1 -1
- package/dist/src/plugin/plugin-injector.js +7 -1
- package/dist/src/plugin/plugin-injector.js.map +1 -1
- package/dist/src/process/studio-process-closer.d.ts +35 -0
- package/dist/src/process/studio-process-closer.d.ts.map +1 -0
- package/dist/src/process/studio-process-closer.js +129 -0
- package/dist/src/process/studio-process-closer.js.map +1 -0
- package/dist/src/process/studio-process-closer.test.d.ts +2 -0
- package/dist/src/process/studio-process-closer.test.d.ts.map +1 -0
- package/dist/src/process/studio-process-closer.test.js +80 -0
- package/dist/src/process/studio-process-closer.test.js.map +1 -0
- package/dist/src/process/studio-settings.d.ts +14 -0
- package/dist/src/process/studio-settings.d.ts.map +1 -0
- package/dist/src/process/studio-settings.js +50 -0
- package/dist/src/process/studio-settings.js.map +1 -0
- package/dist/src/process/studio-settings.test.d.ts +2 -0
- package/dist/src/process/studio-settings.test.d.ts.map +1 -0
- package/dist/src/process/studio-settings.test.js +16 -0
- package/dist/src/process/studio-settings.test.js.map +1 -0
- package/dist/src/process/studio-window-state.d.ts +13 -0
- package/dist/src/process/studio-window-state.d.ts.map +1 -0
- package/dist/src/process/studio-window-state.js +48 -0
- package/dist/src/process/studio-window-state.js.map +1 -0
- package/dist/src/server/studio-bridge-server.d.ts +3 -1
- package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
- package/dist/src/server/studio-bridge-server.js +12 -4
- package/dist/src/server/studio-bridge-server.js.map +1 -1
- package/dist/src/server/web-socket-protocol.d.ts +173 -6
- package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
- package/dist/src/server/web-socket-protocol.js +244 -1
- package/dist/src/server/web-socket-protocol.js.map +1 -1
- package/dist/src/server/web-socket-protocol.test.js +48 -0
- package/dist/src/server/web-socket-protocol.test.js.map +1 -1
- package/dist/src/test/e2e/persistent-session.test.js +121 -0
- package/dist/src/test/e2e/persistent-session.test.js.map +1 -1
- package/dist/src/test/e2e/split-server.test.d.ts +3 -5
- package/dist/src/test/e2e/split-server.test.d.ts.map +1 -1
- package/dist/src/test/e2e/split-server.test.js +3 -5
- package/dist/src/test/e2e/split-server.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docker/Dockerfile +3 -0
- package/package.json +8 -6
- package/src/bridge/bridge-connection.test.ts +126 -0
- package/src/bridge/bridge-connection.ts +217 -22
- package/src/bridge/bridge-session.test.ts +6 -4
- package/src/bridge/bridge-session.ts +273 -28
- package/src/bridge/index.ts +3 -0
- package/src/bridge/internal/bridge-client.test.ts +23 -0
- package/src/bridge/internal/bridge-client.ts +25 -7
- package/src/bridge/internal/bridge-host.test.ts +38 -0
- package/src/bridge/internal/bridge-host.ts +47 -0
- package/src/bridge/internal/hand-off.ts +4 -1
- package/src/bridge/internal/host-protocol.test.ts +15 -0
- package/src/bridge/internal/host-protocol.ts +148 -37
- package/src/bridge/internal/instance-state.ts +34 -0
- package/src/bridge/internal/transport-client.ts +2 -1
- package/src/bridge/internal/transport-server.ts +5 -1
- package/src/bridge/types.ts +47 -2
- package/src/cli/adapters/cli-command-adapter-handler.test.ts +28 -0
- package/src/cli/adapters/cli-command-adapter.ts +150 -18
- package/src/cli/adapters/group-builder.test.ts +34 -2
- package/src/cli/adapters/group-builder.ts +52 -20
- package/src/cli/adapters/help-formatter.test.ts +1 -1
- package/src/cli/adapters/help-formatter.ts +4 -3
- package/src/cli/adapters/playtest-edit-guard.test.ts +54 -0
- package/src/cli/args/global-args.ts +1 -1
- package/src/cli/cli-output-context.test.ts +55 -0
- package/src/cli/cli-output-context.ts +50 -0
- package/src/cli/cli.ts +49 -17
- package/src/cli/managed-studio-run.test.ts +71 -0
- package/src/cli/managed-studio-run.ts +135 -0
- package/src/cli/resolve-session.test.ts +1 -1
- package/src/cli/resolve-session.ts +1 -1
- package/src/cli/script-executor.ts +99 -51
- package/src/commands/console/exec/exec.test.ts +96 -3
- package/src/commands/console/exec/exec.ts +59 -6
- package/src/commands/console/exec/execute.lua +356 -240
- package/src/commands/console/exec/execute.spec.lua +286 -0
- package/src/commands/console/logs/logs.test.ts +76 -4
- package/src/commands/console/logs/logs.ts +132 -17
- package/src/commands/console/logs/query-logs.lua +85 -52
- package/src/commands/console/logs/query-logs.spec.lua +132 -0
- package/src/commands/explorer/export/export-instances.lua +108 -0
- package/src/commands/explorer/export/export-instances.spec.lua +87 -0
- package/src/commands/explorer/export/export.test.ts +27 -0
- package/src/commands/explorer/export/export.ts +60 -0
- package/src/commands/explorer/find/find-instances.lua +174 -0
- package/src/commands/explorer/find/find-instances.spec.lua +122 -0
- package/src/commands/explorer/find/find.test.ts +53 -0
- package/src/commands/explorer/find/find.ts +113 -0
- package/src/commands/explorer/grep/grep-scripts.lua +214 -0
- package/src/commands/explorer/grep/grep-scripts.spec.lua +130 -0
- package/src/commands/explorer/grep/grep.test.ts +45 -0
- package/src/commands/explorer/grep/grep.ts +93 -0
- package/src/commands/explorer/import/import-instances.lua +106 -0
- package/src/commands/explorer/import/import-instances.spec.lua +84 -0
- package/src/commands/explorer/import/import.test.ts +60 -0
- package/src/commands/explorer/import/import.ts +66 -0
- package/src/commands/explorer/query/query-data-model.lua +124 -152
- package/src/commands/explorer/query/query-data-model.spec.lua +150 -0
- package/src/commands/formatters.test.ts +7 -1
- package/src/commands/framework/action-loader.test.ts +28 -0
- package/src/commands/framework/action-loader.ts +10 -2
- package/src/commands/framework/arg-builder.ts +26 -3
- package/src/commands/framework/define-command.ts +32 -3
- package/src/commands/framework/index.ts +1 -0
- package/src/commands/index.ts +50 -0
- package/src/commands/linux/inject-credentials/inject-credentials.ts +1 -3
- package/src/commands/linux/setup/setup.ts +1 -3
- package/src/commands/linux/status/status.ts +105 -98
- package/src/commands/playtest/player/add/add.ts +85 -0
- package/src/commands/playtest/player/list/list.ts +57 -0
- package/src/commands/playtest/player/playtest-players.test.ts +146 -0
- package/src/commands/playtest/player/playtest-players.ts +270 -0
- package/src/commands/playtest/player/remove/remove.ts +78 -0
- package/src/commands/playtest/playtest-sessions.test.ts +143 -0
- package/src/commands/playtest/playtest-sessions.ts +417 -0
- package/src/commands/playtest/restart/restart.ts +199 -0
- package/src/commands/playtest/run/playtest-runner.luau +264 -0
- package/src/commands/playtest/run/playtest-runner.spec.lua +71 -0
- package/src/commands/playtest/run/run-playtest-script.lua +139 -0
- package/src/commands/playtest/run/run-playtest-script.spec.lua +43 -0
- package/src/commands/playtest/run/run.ts +239 -0
- package/src/commands/playtest/start/start-playtest.lua +108 -0
- package/src/commands/playtest/start/start.ts +138 -0
- package/src/commands/playtest/stop/end-playtest.lua +47 -0
- package/src/commands/playtest/stop/stop.ts +51 -0
- package/src/commands/process/close/close.test.ts +250 -0
- package/src/commands/process/close/close.ts +183 -17
- package/src/commands/process/info/info.test.ts +198 -44
- package/src/commands/process/info/info.ts +204 -15
- package/src/commands/process/info/query-state.lua +42 -29
- package/src/commands/process/info/query-state.spec.lua +39 -0
- package/src/commands/process/launch/launch.test.ts +138 -21
- package/src/commands/process/launch/launch.ts +69 -9
- package/src/commands/process/list/list.test.ts +1 -0
- package/src/commands/process/list/list.ts +14 -6
- package/src/commands/process/run/run.ts +26 -5
- package/src/commands/serve/serve.test.ts +17 -2
- package/src/commands/serve/serve.ts +25 -6
- package/src/commands/viewport/screenshot/capture-screenshot.lua +175 -182
- package/src/commands/viewport/screenshot/capture-screenshot.spec.lua +129 -0
- package/src/commands/viewport/screenshot/screenshot.test.ts +7 -10
- package/src/commands/viewport/screenshot/screenshot.ts +6 -1
- package/src/deploy/deploy-places.test.ts +127 -0
- package/src/deploy/deploy-places.ts +229 -0
- package/src/index.ts +11 -0
- package/src/linux/linux-studio-launcher.test.ts +89 -0
- package/src/linux/linux-studio-launcher.ts +11 -0
- package/src/plugin/persistent-plugin-installer.test.ts +4 -0
- package/src/plugin/persistent-plugin-installer.ts +2 -1
- package/src/plugin/plugin-build-version.test.ts +55 -0
- package/src/plugin/plugin-build-version.ts +53 -0
- package/src/plugin/plugin-injector.ts +7 -1
- package/src/process/studio-process-closer.test.ts +107 -0
- package/src/process/studio-process-closer.ts +187 -0
- package/src/process/studio-settings.test.ts +18 -0
- package/src/process/studio-settings.ts +61 -0
- package/src/process/studio-window-state.ts +65 -0
- package/src/server/studio-bridge-server.ts +15 -4
- package/src/server/web-socket-protocol.test.ts +55 -0
- package/src/server/web-socket-protocol.ts +468 -8
- package/src/test/e2e/persistent-session.test.ts +137 -0
- package/src/test/e2e/split-server.test.ts +3 -5
- package/templates/studio-bridge-plugin/default.project.json +3 -0
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.lua +208 -159
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.spec.lua +418 -0
- package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.lua +94 -0
- package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.spec.lua +166 -0
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.lua +118 -137
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.spec.lua +228 -0
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.lua +80 -109
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.spec.lua +116 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.lua +233 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.spec.lua +239 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.lua +53 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.spec.lua +27 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.lua +164 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.spec.lua +159 -0
- package/templates/studio-bridge-plugin/src/StudioBridgePlugin.server.lua +266 -368
- package/templates/studio-bridge-plugin/src/Vendor/png.lua +8 -2
- package/test/default.project.json +41 -0
- package/test/jest.config.lua +3 -0
- package/test/scripts/Server/ServerMain.server.lua +10 -0
- package/tsconfig.json +1 -0
- package/templates/studio-bridge-plugin/src/Shared/Protocol.lua +0 -132
- package/templates/studio-bridge-plugin-test/test/actions.test.lua +0 -580
- package/templates/studio-bridge-plugin-test/test/discovery.test.lua +0 -622
- package/templates/studio-bridge-plugin-test/test/execute-handler.test.lua +0 -517
- package/templates/studio-bridge-plugin-test/test/hash-lifecycle.test.lua +0 -814
- package/templates/studio-bridge-plugin-test/test/integration.test.lua +0 -1020
- package/templates/studio-bridge-plugin-test/test/new-actions.test.lua +0 -339
- package/templates/studio-bridge-plugin-test/test/plugin-entry.test.lua +0 -493
- package/templates/studio-bridge-plugin-test/test/protocol.test.lua +0 -506
- package/templates/studio-bridge-plugin-test/test/roblox-mocks.lua +0 -108
- package/templates/studio-bridge-plugin-test/test/test-runner.lua +0 -112
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[[
|
|
3
|
+
@class StudioBridgeConnection.spec.lua
|
|
4
|
+
]]
|
|
5
|
+
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
7
|
+
|
|
8
|
+
local HttpService = game:GetService("HttpService")
|
|
9
|
+
|
|
10
|
+
local ActionRouter = require("ActionRouter")
|
|
11
|
+
local Jest = require("Jest")
|
|
12
|
+
local StudioBridgeConnection = require("StudioBridgeConnection")
|
|
13
|
+
local StudioBridgeLogUtils = require("StudioBridgeLogUtils")
|
|
14
|
+
|
|
15
|
+
local describe = Jest.Globals.describe
|
|
16
|
+
local expect = Jest.Globals.expect
|
|
17
|
+
local it = Jest.Globals.it
|
|
18
|
+
|
|
19
|
+
local REGISTER_PAYLOAD = table.freeze({
|
|
20
|
+
pluginVersion = "test",
|
|
21
|
+
state = "Edit",
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
local function createFakeSignal(): any
|
|
25
|
+
local handlers: { (...any) -> () } = {}
|
|
26
|
+
return {
|
|
27
|
+
Connect = function(_self, handler)
|
|
28
|
+
table.insert(handlers, handler)
|
|
29
|
+
return {
|
|
30
|
+
Disconnect = function()
|
|
31
|
+
local index = table.find(handlers, handler)
|
|
32
|
+
if index then
|
|
33
|
+
table.remove(handlers, index)
|
|
34
|
+
end
|
|
35
|
+
end,
|
|
36
|
+
}
|
|
37
|
+
end,
|
|
38
|
+
Fire = function(_self, ...)
|
|
39
|
+
for _, handler in table.clone(handlers) do
|
|
40
|
+
handler(...)
|
|
41
|
+
end
|
|
42
|
+
end,
|
|
43
|
+
GetHandlerCount = function()
|
|
44
|
+
return #handlers
|
|
45
|
+
end,
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
local function setup(maxMessageBytes: number?): any
|
|
50
|
+
local sentData: { string } = {}
|
|
51
|
+
local webSocket: any = {
|
|
52
|
+
closeCount = 0,
|
|
53
|
+
MessageReceived = createFakeSignal(),
|
|
54
|
+
Closed = createFakeSignal(),
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function webSocket.Send(_self, data: string)
|
|
58
|
+
table.insert(sentData, data)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
function webSocket.Close(self)
|
|
62
|
+
self.closeCount += 1
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
local router = ActionRouter.new()
|
|
66
|
+
local connection = StudioBridgeConnection.new({
|
|
67
|
+
webSocket = webSocket :: any,
|
|
68
|
+
router = router,
|
|
69
|
+
sessionId = "session-1",
|
|
70
|
+
registerPayload = REGISTER_PAYLOAD,
|
|
71
|
+
maxMessageBytes = maxMessageBytes,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
local controller = {
|
|
75
|
+
webSocket = webSocket,
|
|
76
|
+
router = router,
|
|
77
|
+
connection = connection,
|
|
78
|
+
receive = function(message: { [string]: any })
|
|
79
|
+
webSocket.MessageReceived:Fire(HttpService:JSONEncode(message))
|
|
80
|
+
end,
|
|
81
|
+
getSent = function(): { any }
|
|
82
|
+
local messages = {}
|
|
83
|
+
for _, data in sentData do
|
|
84
|
+
table.insert(messages, HttpService:JSONDecode(data))
|
|
85
|
+
end
|
|
86
|
+
return messages
|
|
87
|
+
end,
|
|
88
|
+
clearSent = function()
|
|
89
|
+
table.clear(sentData)
|
|
90
|
+
end,
|
|
91
|
+
Destroy = function(_self)
|
|
92
|
+
connection:Destroy()
|
|
93
|
+
end,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return controller
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe("StudioBridgeConnection.new()", function()
|
|
100
|
+
it("should register, then send a heartbeat", function()
|
|
101
|
+
local controller = setup()
|
|
102
|
+
|
|
103
|
+
local sent = controller.getSent()
|
|
104
|
+
|
|
105
|
+
expect(#sent).toEqual(2)
|
|
106
|
+
expect(sent[1]).toEqual({
|
|
107
|
+
type = "register",
|
|
108
|
+
sessionId = "session-1",
|
|
109
|
+
payload = { pluginVersion = "test", state = "Edit" },
|
|
110
|
+
})
|
|
111
|
+
expect(sent[2].type).toEqual("heartbeat")
|
|
112
|
+
expect(sent[2].sessionId).toEqual("session-1")
|
|
113
|
+
expect(sent[2].payload.state).toEqual("Edit")
|
|
114
|
+
expect(sent[2].payload.pendingRequests).toEqual(0)
|
|
115
|
+
expect(type(sent[2].payload.uptimeMs)).toEqual("number")
|
|
116
|
+
expect(controller.connection:IsOpen()).toEqual(true)
|
|
117
|
+
|
|
118
|
+
controller:Destroy()
|
|
119
|
+
end)
|
|
120
|
+
end)
|
|
121
|
+
|
|
122
|
+
describe("StudioBridgeConnection message handling", function()
|
|
123
|
+
it("should dispatch a message and send back the response", function()
|
|
124
|
+
local controller = setup()
|
|
125
|
+
controller.router:register("ping", function(payload)
|
|
126
|
+
return { echo = payload.value }
|
|
127
|
+
end)
|
|
128
|
+
controller.clearSent()
|
|
129
|
+
|
|
130
|
+
controller.receive({ type = "ping", sessionId = "session-1", requestId = "req-1", payload = { value = 3 } })
|
|
131
|
+
|
|
132
|
+
expect(controller.getSent()).toEqual({
|
|
133
|
+
{
|
|
134
|
+
type = "pingResult",
|
|
135
|
+
sessionId = "session-1",
|
|
136
|
+
requestId = "req-1",
|
|
137
|
+
payload = { echo = 3 },
|
|
138
|
+
},
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
controller:Destroy()
|
|
142
|
+
end)
|
|
143
|
+
|
|
144
|
+
it("should answer a reply over the size limit with RESULT_TOO_LARGE instead", function()
|
|
145
|
+
local controller = setup(1000)
|
|
146
|
+
controller.router:register("dump", function()
|
|
147
|
+
return { data = string.rep("a", 2000) }
|
|
148
|
+
end)
|
|
149
|
+
controller.clearSent()
|
|
150
|
+
|
|
151
|
+
controller.receive({ type = "dump", sessionId = "session-1", requestId = "req-1", payload = {} })
|
|
152
|
+
|
|
153
|
+
local sent = controller.getSent()
|
|
154
|
+
expect(#sent).toEqual(1)
|
|
155
|
+
expect(sent[1].type).toEqual("error")
|
|
156
|
+
expect(sent[1].requestId).toEqual("req-1")
|
|
157
|
+
expect(sent[1].payload.code).toEqual("RESULT_TOO_LARGE")
|
|
158
|
+
expect(controller.connection:IsOpen()).toEqual(true)
|
|
159
|
+
|
|
160
|
+
controller:Destroy()
|
|
161
|
+
end)
|
|
162
|
+
|
|
163
|
+
it("should send nothing when the handler returns nil", function()
|
|
164
|
+
local controller = setup()
|
|
165
|
+
controller.router:register("quiet", function()
|
|
166
|
+
return nil
|
|
167
|
+
end)
|
|
168
|
+
controller.clearSent()
|
|
169
|
+
|
|
170
|
+
controller.receive({ type = "quiet", sessionId = "session-1", payload = {} })
|
|
171
|
+
|
|
172
|
+
expect(controller.getSent()).toEqual({})
|
|
173
|
+
|
|
174
|
+
controller:Destroy()
|
|
175
|
+
end)
|
|
176
|
+
|
|
177
|
+
it("should ignore a message that is not JSON", function()
|
|
178
|
+
local controller = setup()
|
|
179
|
+
controller.clearSent()
|
|
180
|
+
|
|
181
|
+
controller.webSocket.MessageReceived:Fire("not json")
|
|
182
|
+
|
|
183
|
+
expect(controller.getSent()).toEqual({})
|
|
184
|
+
expect(controller.connection:IsOpen()).toEqual(true)
|
|
185
|
+
|
|
186
|
+
controller:Destroy()
|
|
187
|
+
end)
|
|
188
|
+
|
|
189
|
+
it("should close the socket on shutdown and stop sending", function()
|
|
190
|
+
local controller = setup()
|
|
191
|
+
controller.clearSent()
|
|
192
|
+
|
|
193
|
+
controller.receive({ type = "shutdown", sessionId = "session-1", payload = {} })
|
|
194
|
+
controller.connection:Send({ type = "late" })
|
|
195
|
+
|
|
196
|
+
expect(controller.webSocket.closeCount).toEqual(1)
|
|
197
|
+
expect(controller.connection:IsOpen()).toEqual(false)
|
|
198
|
+
expect(controller.getSent()).toEqual({})
|
|
199
|
+
|
|
200
|
+
controller:Destroy()
|
|
201
|
+
end)
|
|
202
|
+
end)
|
|
203
|
+
|
|
204
|
+
describe("StudioBridgeConnection socket close", function()
|
|
205
|
+
it("should stop listening once the socket closes", function()
|
|
206
|
+
local controller = setup()
|
|
207
|
+
|
|
208
|
+
controller.webSocket.Closed:Fire()
|
|
209
|
+
|
|
210
|
+
expect(controller.connection:IsOpen()).toEqual(false)
|
|
211
|
+
expect(controller.webSocket.MessageReceived.GetHandlerCount()).toEqual(0)
|
|
212
|
+
expect(controller.webSocket.Closed.GetHandlerCount()).toEqual(0)
|
|
213
|
+
|
|
214
|
+
controller:Destroy()
|
|
215
|
+
end)
|
|
216
|
+
|
|
217
|
+
it("should end verbose logging with the command that asked for it", function()
|
|
218
|
+
local controller = setup()
|
|
219
|
+
StudioBridgeLogUtils.setVerbose(true)
|
|
220
|
+
|
|
221
|
+
controller.webSocket.Closed:Fire()
|
|
222
|
+
|
|
223
|
+
expect(StudioBridgeLogUtils.isVerbose()).toEqual(false)
|
|
224
|
+
|
|
225
|
+
controller:Destroy()
|
|
226
|
+
end)
|
|
227
|
+
end)
|
|
228
|
+
|
|
229
|
+
describe("StudioBridgeConnection:Destroy()", function()
|
|
230
|
+
it("should disconnect from the socket without closing it", function()
|
|
231
|
+
local controller = setup()
|
|
232
|
+
|
|
233
|
+
controller:Destroy()
|
|
234
|
+
|
|
235
|
+
expect(controller.connection:IsOpen()).toEqual(false)
|
|
236
|
+
expect(controller.webSocket.closeCount).toEqual(0)
|
|
237
|
+
expect(controller.webSocket.MessageReceived.GetHandlerCount()).toEqual(0)
|
|
238
|
+
end)
|
|
239
|
+
end)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[=[
|
|
3
|
+
Plugin output, kept quiet unless the command talking to the plugin ran with
|
|
4
|
+
--verbose. Real failures warn regardless.
|
|
5
|
+
|
|
6
|
+
@class StudioBridgeLogUtils
|
|
7
|
+
]=]
|
|
8
|
+
|
|
9
|
+
local StudioBridgeLogUtils = {}
|
|
10
|
+
|
|
11
|
+
--[=[
|
|
12
|
+
Prefix on every line the plugin writes, so its own output can be told
|
|
13
|
+
apart from the place's.
|
|
14
|
+
|
|
15
|
+
@prop PREFIX string
|
|
16
|
+
@within StudioBridgeLogUtils
|
|
17
|
+
]=]
|
|
18
|
+
StudioBridgeLogUtils.PREFIX = "[StudioBridge]"
|
|
19
|
+
|
|
20
|
+
StudioBridgeLogUtils._isVerbose = false
|
|
21
|
+
|
|
22
|
+
--[=[
|
|
23
|
+
Sets whether diagnostic output is printed. The bridge sends this with every
|
|
24
|
+
`syncActions`, so it follows the --verbose flag of the current command.
|
|
25
|
+
]=]
|
|
26
|
+
function StudioBridgeLogUtils.setVerbose(isVerbose: boolean)
|
|
27
|
+
StudioBridgeLogUtils._isVerbose = isVerbose
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
--[=[
|
|
31
|
+
Returns whether diagnostic output is printed.
|
|
32
|
+
]=]
|
|
33
|
+
function StudioBridgeLogUtils.isVerbose(): boolean
|
|
34
|
+
return StudioBridgeLogUtils._isVerbose
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
--[=[
|
|
38
|
+
Prints diagnostic output, only while verbose.
|
|
39
|
+
]=]
|
|
40
|
+
function StudioBridgeLogUtils.logVerbose(message: string)
|
|
41
|
+
if StudioBridgeLogUtils._isVerbose then
|
|
42
|
+
print(`{StudioBridgeLogUtils.PREFIX} {message}`)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
--[=[
|
|
47
|
+
Warns about a real failure, whether or not verbose is on.
|
|
48
|
+
]=]
|
|
49
|
+
function StudioBridgeLogUtils.warn(message: string)
|
|
50
|
+
warn(`{StudioBridgeLogUtils.PREFIX} {message}`)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
return StudioBridgeLogUtils
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[[
|
|
3
|
+
@class StudioBridgeLogUtils.spec.lua
|
|
4
|
+
]]
|
|
5
|
+
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
7
|
+
|
|
8
|
+
local Jest = require("Jest")
|
|
9
|
+
local StudioBridgeLogUtils = require("StudioBridgeLogUtils")
|
|
10
|
+
|
|
11
|
+
local describe = Jest.Globals.describe
|
|
12
|
+
local expect = Jest.Globals.expect
|
|
13
|
+
local it = Jest.Globals.it
|
|
14
|
+
|
|
15
|
+
describe("StudioBridgeLogUtils.setVerbose()", function()
|
|
16
|
+
it("should start quiet", function()
|
|
17
|
+
expect(StudioBridgeLogUtils.isVerbose()).toEqual(false)
|
|
18
|
+
end)
|
|
19
|
+
|
|
20
|
+
it("should toggle verbose output", function()
|
|
21
|
+
StudioBridgeLogUtils.setVerbose(true)
|
|
22
|
+
expect(StudioBridgeLogUtils.isVerbose()).toEqual(true)
|
|
23
|
+
|
|
24
|
+
StudioBridgeLogUtils.setVerbose(false)
|
|
25
|
+
expect(StudioBridgeLogUtils.isVerbose()).toEqual(false)
|
|
26
|
+
end)
|
|
27
|
+
end)
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[=[
|
|
3
|
+
Identifies this plugin instance to the bridge: which place it is in, which
|
|
4
|
+
DataModel context it runs in, and what it can do.
|
|
5
|
+
|
|
6
|
+
@class StudioBridgeSessionUtils
|
|
7
|
+
]=]
|
|
8
|
+
|
|
9
|
+
local RunService = game:GetService("RunService")
|
|
10
|
+
|
|
11
|
+
local PLUGIN_VERSION = "{{PLUGIN_VERSION}}"
|
|
12
|
+
local MAX_SLUG_LENGTH = 24
|
|
13
|
+
local NONCE_VALUE_NAME = "StudioBridgeNonce"
|
|
14
|
+
local LAUNCH_ID_ATTRIBUTE = "StudioBridgeSessionId"
|
|
15
|
+
|
|
16
|
+
local StudioBridgeSessionUtils = {}
|
|
17
|
+
|
|
18
|
+
export type PluginContext = "edit" | "client" | "server"
|
|
19
|
+
|
|
20
|
+
export type PlaytestArgs = {
|
|
21
|
+
port: number,
|
|
22
|
+
instanceId: string,
|
|
23
|
+
multiplayer: boolean,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
--[=[
|
|
27
|
+
Every message type the plugin can handle. Most arrive as action source pushed
|
|
28
|
+
by the bridge right after registering, but the plugin advertises them up front.
|
|
29
|
+
|
|
30
|
+
@prop CAPABILITIES { string }
|
|
31
|
+
@within StudioBridgeSessionUtils
|
|
32
|
+
]=]
|
|
33
|
+
StudioBridgeSessionUtils.CAPABILITIES = table.freeze({
|
|
34
|
+
"registerAction",
|
|
35
|
+
"syncActions",
|
|
36
|
+
"heartbeat",
|
|
37
|
+
"execute",
|
|
38
|
+
"queryState",
|
|
39
|
+
"captureScreenshot",
|
|
40
|
+
"queryDataModel",
|
|
41
|
+
"queryLogs",
|
|
42
|
+
"exportInstances",
|
|
43
|
+
"importInstances",
|
|
44
|
+
"findInstances",
|
|
45
|
+
"grepScripts",
|
|
46
|
+
"startPlaytest",
|
|
47
|
+
"endPlaytest",
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
--[=[
|
|
51
|
+
Returns the DataModel context this plugin instance runs in.
|
|
52
|
+
]=]
|
|
53
|
+
function StudioBridgeSessionUtils.getContext(): PluginContext
|
|
54
|
+
if not RunService:IsRunning() then
|
|
55
|
+
return "edit"
|
|
56
|
+
elseif RunService:IsClient() then
|
|
57
|
+
return "client"
|
|
58
|
+
else
|
|
59
|
+
return "server"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
function StudioBridgeSessionUtils._slugify(text: string, fallback: string): string
|
|
64
|
+
local slug = string.lower(text)
|
|
65
|
+
slug = string.gsub(slug, "[^%w]+", "-")
|
|
66
|
+
slug = string.gsub(slug, "^%-+", "")
|
|
67
|
+
slug = string.sub(slug, 1, MAX_SLUG_LENGTH)
|
|
68
|
+
slug = string.gsub(slug, "%-+$", "")
|
|
69
|
+
return if slug == "" then fallback else slug
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
--[=[
|
|
73
|
+
Returns a short, readable id for the open place: its name as a slug plus
|
|
74
|
+
`nonce`, which tells apart two Studios with the same place open.
|
|
75
|
+
]=]
|
|
76
|
+
function StudioBridgeSessionUtils.getInstanceId(placeName: string?, nonce: string): string
|
|
77
|
+
local name = string.gsub(placeName or "", "%.rbxl[x]?$", "")
|
|
78
|
+
return `{StudioBridgeSessionUtils._slugify(name, "place")}-{nonce}`
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
--[=[
|
|
82
|
+
Returns the nonce stored under `container`, creating it on first use. The
|
|
83
|
+
value is not archivable, so it lasts as long as the DataModel: plugin reloads
|
|
84
|
+
keep their session id, and a fresh Studio gets a new one.
|
|
85
|
+
]=]
|
|
86
|
+
function StudioBridgeSessionUtils.getOrCreateNonce(container: Instance, createNonce: () -> string): string
|
|
87
|
+
local existing = container:FindFirstChild(NONCE_VALUE_NAME)
|
|
88
|
+
if existing and existing:IsA("StringValue") and existing.Value ~= "" then
|
|
89
|
+
return existing.Value
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
local value = Instance.new("StringValue")
|
|
93
|
+
value.Name = NONCE_VALUE_NAME
|
|
94
|
+
value.Archivable = false
|
|
95
|
+
value.Value = createNonce()
|
|
96
|
+
value.Parent = container
|
|
97
|
+
return value.Value
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
--[=[
|
|
101
|
+
Returns the session id for an instance id and context. The clients of a
|
|
102
|
+
multiplayer test share both, so they add their player's name.
|
|
103
|
+
]=]
|
|
104
|
+
function StudioBridgeSessionUtils.getSessionId(instanceId: string, context: PluginContext, playerName: string?): string
|
|
105
|
+
if playerName then
|
|
106
|
+
return `{instanceId}-{context}-{StudioBridgeSessionUtils._slugify(playerName, "player")}`
|
|
107
|
+
end
|
|
108
|
+
return `{instanceId}-{context}`
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
--[=[
|
|
112
|
+
Returns the payload of the `register` message the plugin sends on connect.
|
|
113
|
+
]=]
|
|
114
|
+
function StudioBridgeSessionUtils.createRegisterPayload(
|
|
115
|
+
instanceId: string,
|
|
116
|
+
context: PluginContext,
|
|
117
|
+
launchId: string?,
|
|
118
|
+
playerName: string?
|
|
119
|
+
): { [string]: any }
|
|
120
|
+
return {
|
|
121
|
+
pluginVersion = PLUGIN_VERSION,
|
|
122
|
+
instanceId = instanceId,
|
|
123
|
+
context = context,
|
|
124
|
+
launchId = launchId,
|
|
125
|
+
playerName = playerName,
|
|
126
|
+
placeName = game.Name or "Unknown",
|
|
127
|
+
placeId = game.PlaceId,
|
|
128
|
+
gameId = game.GameId,
|
|
129
|
+
state = "Edit",
|
|
130
|
+
capabilities = table.clone(StudioBridgeSessionUtils.CAPABILITIES),
|
|
131
|
+
}
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
--[=[
|
|
135
|
+
Returns the launch id `process run` stamped onto the place it launched
|
|
136
|
+
Studio with, or nil for a place the user opened.
|
|
137
|
+
]=]
|
|
138
|
+
function StudioBridgeSessionUtils.getLaunchId(workspace: Instance): string?
|
|
139
|
+
local launchId = workspace:GetAttribute(LAUNCH_ID_ATTRIBUTE)
|
|
140
|
+
return if type(launchId) == "string" then launchId else nil
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
--[=[
|
|
144
|
+
Returns what studio-bridge handed a playtest through its StudioTestService
|
|
145
|
+
test args: the bridge port, the instance id of the edit session that
|
|
146
|
+
started it, and whether it is a multiplayer test. Nil when studio-bridge
|
|
147
|
+
did not start the playtest.
|
|
148
|
+
]=]
|
|
149
|
+
function StudioBridgeSessionUtils.getPlaytestArgs(testArgs: any): PlaytestArgs?
|
|
150
|
+
if
|
|
151
|
+
type(testArgs) == "table"
|
|
152
|
+
and type(testArgs.studioBridgePort) == "number"
|
|
153
|
+
and type(testArgs.studioBridgeInstanceId) == "string"
|
|
154
|
+
then
|
|
155
|
+
return {
|
|
156
|
+
port = testArgs.studioBridgePort,
|
|
157
|
+
instanceId = testArgs.studioBridgeInstanceId,
|
|
158
|
+
multiplayer = type(testArgs.studioBridgePlayers) == "number",
|
|
159
|
+
}
|
|
160
|
+
end
|
|
161
|
+
return nil
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
return StudioBridgeSessionUtils
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[[
|
|
3
|
+
@class StudioBridgeSessionUtils.spec.lua
|
|
4
|
+
]]
|
|
5
|
+
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
7
|
+
|
|
8
|
+
local Jest = require("Jest")
|
|
9
|
+
local StudioBridgeSessionUtils = require("StudioBridgeSessionUtils")
|
|
10
|
+
|
|
11
|
+
local describe = Jest.Globals.describe
|
|
12
|
+
local expect = Jest.Globals.expect
|
|
13
|
+
local it = Jest.Globals.it
|
|
14
|
+
|
|
15
|
+
describe("StudioBridgeSessionUtils.getInstanceId()", function()
|
|
16
|
+
it("should slug the place name and append the nonce", function()
|
|
17
|
+
expect(StudioBridgeSessionUtils.getInstanceId("My Cool Place!", "3f9a")).toEqual("my-cool-place-3f9a")
|
|
18
|
+
end)
|
|
19
|
+
|
|
20
|
+
it("should drop a place file extension", function()
|
|
21
|
+
expect(StudioBridgeSessionUtils.getInstanceId("test-place.rbxl", "3f9a")).toEqual("test-place-3f9a")
|
|
22
|
+
expect(StudioBridgeSessionUtils.getInstanceId("Map.rbxlx", "3f9a")).toEqual("map-3f9a")
|
|
23
|
+
end)
|
|
24
|
+
|
|
25
|
+
it("should keep long names short", function()
|
|
26
|
+
expect(StudioBridgeSessionUtils.getInstanceId("An Extremely Long Place Name For Testing", "3f9a")).toEqual(
|
|
27
|
+
"an-extremely-long-place-3f9a"
|
|
28
|
+
)
|
|
29
|
+
end)
|
|
30
|
+
|
|
31
|
+
it("should fall back to place when the name has nothing usable", function()
|
|
32
|
+
expect(StudioBridgeSessionUtils.getInstanceId("!!!", "3f9a")).toEqual("place-3f9a")
|
|
33
|
+
expect(StudioBridgeSessionUtils.getInstanceId(nil, "3f9a")).toEqual("place-3f9a")
|
|
34
|
+
end)
|
|
35
|
+
end)
|
|
36
|
+
|
|
37
|
+
describe("StudioBridgeSessionUtils.getOrCreateNonce()", function()
|
|
38
|
+
it("should keep the first nonce for later calls", function()
|
|
39
|
+
local container = Instance.new("Folder")
|
|
40
|
+
local count = 0
|
|
41
|
+
local function createNonce(): string
|
|
42
|
+
count += 1
|
|
43
|
+
return "nonce" .. tostring(count)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
expect(StudioBridgeSessionUtils.getOrCreateNonce(container, createNonce)).toEqual("nonce1")
|
|
47
|
+
expect(StudioBridgeSessionUtils.getOrCreateNonce(container, createNonce)).toEqual("nonce1")
|
|
48
|
+
|
|
49
|
+
container:Destroy()
|
|
50
|
+
end)
|
|
51
|
+
|
|
52
|
+
it("should not save the nonce with the place", function()
|
|
53
|
+
local container = Instance.new("Folder")
|
|
54
|
+
|
|
55
|
+
StudioBridgeSessionUtils.getOrCreateNonce(container, function()
|
|
56
|
+
return "3f9a"
|
|
57
|
+
end)
|
|
58
|
+
|
|
59
|
+
expect((container:FindFirstChild("StudioBridgeNonce") :: Instance).Archivable).toEqual(false)
|
|
60
|
+
|
|
61
|
+
container:Destroy()
|
|
62
|
+
end)
|
|
63
|
+
end)
|
|
64
|
+
|
|
65
|
+
describe("StudioBridgeSessionUtils.getLaunchId()", function()
|
|
66
|
+
it("should read the launch id stamped onto the workspace", function()
|
|
67
|
+
local container = Instance.new("Folder")
|
|
68
|
+
container:SetAttribute("StudioBridgeSessionId", "launch-1")
|
|
69
|
+
|
|
70
|
+
expect(StudioBridgeSessionUtils.getLaunchId(container)).toEqual("launch-1")
|
|
71
|
+
|
|
72
|
+
container:Destroy()
|
|
73
|
+
end)
|
|
74
|
+
|
|
75
|
+
it("should be nil for a place the user opened", function()
|
|
76
|
+
local container = Instance.new("Folder")
|
|
77
|
+
|
|
78
|
+
expect(StudioBridgeSessionUtils.getLaunchId(container)).toBeNil()
|
|
79
|
+
|
|
80
|
+
container:Destroy()
|
|
81
|
+
end)
|
|
82
|
+
end)
|
|
83
|
+
|
|
84
|
+
describe("StudioBridgeSessionUtils.getPlaytestArgs()", function()
|
|
85
|
+
it("should read the port and instance id studio-bridge passed in the test args", function()
|
|
86
|
+
expect(StudioBridgeSessionUtils.getPlaytestArgs({
|
|
87
|
+
studioBridgePlaytestId = "abc",
|
|
88
|
+
studioBridgePort = 38741,
|
|
89
|
+
studioBridgeInstanceId = "test-place-3f9a",
|
|
90
|
+
})).toEqual({ port = 38741, instanceId = "test-place-3f9a", multiplayer = false })
|
|
91
|
+
end)
|
|
92
|
+
|
|
93
|
+
it("should report a multiplayer test", function()
|
|
94
|
+
local args = StudioBridgeSessionUtils.getPlaytestArgs({
|
|
95
|
+
studioBridgePort = 38741,
|
|
96
|
+
studioBridgeInstanceId = "test-place-3f9a",
|
|
97
|
+
studioBridgePlayers = 2,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
expect(args and args.multiplayer).toEqual(true)
|
|
101
|
+
end)
|
|
102
|
+
|
|
103
|
+
it("should return nil for a playtest studio-bridge did not start", function()
|
|
104
|
+
expect(StudioBridgeSessionUtils.getPlaytestArgs(nil)).toBeNil()
|
|
105
|
+
expect(StudioBridgeSessionUtils.getPlaytestArgs({ custom = true })).toBeNil()
|
|
106
|
+
end)
|
|
107
|
+
end)
|
|
108
|
+
|
|
109
|
+
describe("StudioBridgeSessionUtils.getSessionId()", function()
|
|
110
|
+
it("should append the context to the instance id", function()
|
|
111
|
+
expect(StudioBridgeSessionUtils.getSessionId("test-place-3f9a", "edit")).toEqual("test-place-3f9a-edit")
|
|
112
|
+
end)
|
|
113
|
+
|
|
114
|
+
it("should append the player of a multiplayer client", function()
|
|
115
|
+
expect(StudioBridgeSessionUtils.getSessionId("test-place-3f9a", "client", "Player2")).toEqual(
|
|
116
|
+
"test-place-3f9a-client-player2"
|
|
117
|
+
)
|
|
118
|
+
end)
|
|
119
|
+
end)
|
|
120
|
+
|
|
121
|
+
describe("StudioBridgeSessionUtils.getContext()", function()
|
|
122
|
+
it("should be edit when the game is not running", function()
|
|
123
|
+
expect(StudioBridgeSessionUtils.getContext()).toEqual("edit")
|
|
124
|
+
end)
|
|
125
|
+
end)
|
|
126
|
+
|
|
127
|
+
describe("StudioBridgeSessionUtils.createRegisterPayload()", function()
|
|
128
|
+
it("should describe the plugin and the open place", function()
|
|
129
|
+
local payload = StudioBridgeSessionUtils.createRegisterPayload("test-place-3f9a", "edit")
|
|
130
|
+
|
|
131
|
+
expect(payload.instanceId).toEqual("test-place-3f9a")
|
|
132
|
+
expect(payload.context).toEqual("edit")
|
|
133
|
+
expect(payload.state).toEqual("Edit")
|
|
134
|
+
expect(payload.placeId).toEqual(game.PlaceId)
|
|
135
|
+
expect(payload.gameId).toEqual(game.GameId)
|
|
136
|
+
expect(type(payload.pluginVersion)).toEqual("string")
|
|
137
|
+
expect(payload.capabilities).toEqual(StudioBridgeSessionUtils.CAPABILITIES)
|
|
138
|
+
end)
|
|
139
|
+
|
|
140
|
+
it("should carry the launch id of a Studio that process run launched", function()
|
|
141
|
+
local payload = StudioBridgeSessionUtils.createRegisterPayload("test-place-3f9a", "edit", "launch-1")
|
|
142
|
+
|
|
143
|
+
expect(payload.launchId).toEqual("launch-1")
|
|
144
|
+
end)
|
|
145
|
+
|
|
146
|
+
it("should carry the player of a multiplayer client", function()
|
|
147
|
+
local payload = StudioBridgeSessionUtils.createRegisterPayload("test-place-3f9a", "client", nil, "Player2")
|
|
148
|
+
|
|
149
|
+
expect(payload.playerName).toEqual("Player2")
|
|
150
|
+
end)
|
|
151
|
+
|
|
152
|
+
it("should hand out a capabilities list the caller can change", function()
|
|
153
|
+
local payload = StudioBridgeSessionUtils.createRegisterPayload("test-place-3f9a", "edit")
|
|
154
|
+
|
|
155
|
+
table.insert(payload.capabilities, "extra")
|
|
156
|
+
|
|
157
|
+
expect(table.find(StudioBridgeSessionUtils.CAPABILITIES, "extra")).toBeNil()
|
|
158
|
+
end)
|
|
159
|
+
end)
|