diff --git a/.devcontainer/docker-compose-devcontainer.yml b/.devcontainer/docker-compose-devcontainer.yml index 6562ba975..0e4a03563 100644 --- a/.devcontainer/docker-compose-devcontainer.yml +++ b/.devcontainer/docker-compose-devcontainer.yml @@ -13,10 +13,6 @@ services: source: node_modules # top-level volume target: /workspaces/speckle-server/node_modules read_only: false - - type: volume - source: dui3-node_modules - target: /workspaces/speckle-server/packages/dui3/node_modules - read_only: false - type: volume source: fileimport-service-node_modules target: /workspaces/speckle-server/packages/fileimport-service/node_modules @@ -104,10 +100,6 @@ services: source: node_modules target: /workspaces/speckle-server/node_modules read_only: false - - type: volume - source: dui3-node_modules - target: /workspaces/speckle-server/packages/dui3/node_modules - read_only: false - type: volume source: fileimport-service-node_modules target: /workspaces/speckle-server/packages/fileimport-service/node_modules @@ -176,7 +168,6 @@ volumes: # (this allows the devcontainer to be based on linux yet work on Apple Silicon etc..) # If you add a new package with a new `node_modules`, it needs to be added here node_modules: - dui3-node_modules: fileimport-service-node_modules: frontend-2-node_modules: monitor-deployment-node_modules: diff --git a/package.json b/package.json index 4e017faa5..cfa811979 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "dev": "yarn workspaces foreach -pivW -j unlimited run dev", "dev:no-server": "yarn workspaces foreach --exclude @speckle/server -pivW -j unlimited run dev", "dev:minimal": "yarn workspaces foreach -pivW -j unlimited --include '{@speckle/server,@speckle/frontend-2}' run dev", - "gqlgen": "yarn workspaces foreach -pivW -j unlimited --include '{@speckle/server,@speckle/frontend,@speckle/frontend-2,@speckle/dui3}' run gqlgen", + "gqlgen": "yarn workspaces foreach -pivW -j unlimited --include '{@speckle/server,@speckle/frontend,@speckle/frontend-2}' run gqlgen", "dev:server": "yarn workspace @speckle/server dev", "dev:frontend-2": "yarn workspace @speckle/frontend-2 dev", "dev:shared": "yarn workspace @speckle/shared dev", diff --git a/packages/dui3/.env.example b/packages/dui3/.env.example deleted file mode 100644 index dc1e6882c..000000000 --- a/packages/dui3/.env.example +++ /dev/null @@ -1,11 +0,0 @@ -HOST=0.0.0.0 -PORT=8082 - -NUXT_PUBLIC_MIXPANEL_TOKEN_ID=acd87c5a50b56df91a795e999812a3a4 -NUXT_PUBLIC_MIXPANEL_API_HOST=https://analytics.speckle.systems - -########################################################## -# Local dev settings -########################################################## -# Uncomment to enable pino-pretty log formatting in debug mode (disabled cause of node22 issues) -# ALLOW_PRETTY_DEBUGGER=true \ No newline at end of file diff --git a/packages/dui3/.gitignore b/packages/dui3/.gitignore deleted file mode 100644 index bc4319efa..000000000 --- a/packages/dui3/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -node_modules -*.log* -.nuxt -.nitro -.cache -.output -.env -dist -.DS_Store -.env \ No newline at end of file diff --git a/packages/dui3/.vscode/settings.json b/packages/dui3/.vscode/settings.json deleted file mode 100644 index 4ef7f0183..000000000 --- a/packages/dui3/.vscode/settings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "css.validate": false, - "less.validate": false, - "scss.validate": false, - "stylelint.validate": ["css", "scss", "vue", "postcss"], - "stylelint.enable": true, - "stylelint.configFile": "${workspaceFolder}/stylelint.config.js", - "volar.completion.preferredTagNameCase": "pascal", - "javascript.suggest.autoImports": true, - "typescript.suggest.autoImports": true, - "typescript.preferences.importModuleSpecifier": "non-relative", - "javascript.preferences.importModuleSpecifier": "non-relative" -} diff --git a/packages/dui3/README.md b/packages/dui3/README.md deleted file mode 100644 index 37a9b5316..000000000 --- a/packages/dui3/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# dui3 - -DUIv3 is a Speckle interface embedded inside the desktop connectors that allows users to interact with them - sync streams, manage servers etc. It's built in Vue 3 with Nuxt 3 and only supports client side rendering. - -Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. - -## Setup - -Make sure to install the dependencies: - -```bash -# yarn -yarn install -``` - -And create an `.env` file from `.env.example`. - -## Development Server - -Start the development server on `http://localhost:3000` - -```bash -npm run dev -``` - -## Production - -Build the application for production: - -```bash -npm run build -``` - -Locally preview production build: - -```bash -npm run preview -``` - -Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/packages/dui3/app.vue b/packages/dui3/app.vue deleted file mode 100644 index aaadc1d36..000000000 --- a/packages/dui3/app.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - diff --git a/packages/dui3/assets/css/tailwind.css b/packages/dui3/assets/css/tailwind.css deleted file mode 100644 index df90400c7..000000000 --- a/packages/dui3/assets/css/tailwind.css +++ /dev/null @@ -1,25 +0,0 @@ -/* stylelint-disable selector-id-pattern */ -@import '@speckle/ui-components/style.css'; -@tailwind base; -@tailwind components; -@tailwind utilities; - -/** - * Don't pollute this - it's going to be bundled in all pages! - */ - -/** - * Making sure page is always stretched to the bottom of the screen even if there's nothing in it - */ -html, -body, -div#__nuxt, -div#__nuxt > div { - min-height: 100%; -} - -html, -body, -div#__nuxt { - height: 100%; -} diff --git a/packages/dui3/assets/images/speckle_logo_big.png b/packages/dui3/assets/images/speckle_logo_big.png deleted file mode 100644 index c2a7002af..000000000 Binary files a/packages/dui3/assets/images/speckle_logo_big.png and /dev/null differ diff --git a/packages/dui3/codegen.ts b/packages/dui3/codegen.ts deleted file mode 100644 index 1614f18a4..000000000 --- a/packages/dui3/codegen.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { CodegenConfig } from '@graphql-codegen/cli' - -const config: CodegenConfig = { - schema: 'http://127.0.0.1:3000/graphql', - documents: ['{lib,components,layouts,pages,middleware}/**/*.{vue,js,ts}'], - ignoreNoDocuments: true, // for better experience with the watcher - generates: { - './lib/common/generated/gql/': { - preset: 'client', - config: { - useTypeImports: true, - fragmentMasking: false, - dedupeFragments: true, - scalars: { - JSONObject: '{}', - DateTime: 'string' - } - }, - presetConfig: { - fragmentMasking: false, - dedupeFragments: true - }, - plugins: [] - } - } -} - -export default config diff --git a/packages/dui3/components/header/LogoBlock.vue b/packages/dui3/components/header/LogoBlock.vue deleted file mode 100644 index 3ef4b3514..000000000 --- a/packages/dui3/components/header/LogoBlock.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Speckle - - - - diff --git a/packages/dui3/components/header/NavBar.vue b/packages/dui3/components/header/NavBar.vue deleted file mode 100644 index ce7230d16..000000000 --- a/packages/dui3/components/header/NavBar.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/packages/dui3/components/header/NavLink.vue b/packages/dui3/components/header/NavLink.vue deleted file mode 100644 index a2035c275..000000000 --- a/packages/dui3/components/header/NavLink.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - {{ name || to }} - - - - - diff --git a/packages/dui3/components/header/UserAccount.vue b/packages/dui3/components/header/UserAccount.vue deleted file mode 100644 index d66d50b05..000000000 --- a/packages/dui3/components/header/UserAccount.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - {{ account.accountInfo.serverInfo.name }} - - {{ account.accountInfo.serverInfo.url.split('//')[1] }} - - - - {{ account.accountInfo.userInfo.email }} - - - - - - - - - diff --git a/packages/dui3/components/header/UserMenu.vue b/packages/dui3/components/header/UserMenu.vue deleted file mode 100644 index ac00e6d22..000000000 --- a/packages/dui3/components/header/UserMenu.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - - - Open user menu - - - - - - - - - - - Loading accounts... - - Your accounts - - - Refresh - - - - - - - - - - - - - Open Dev Tools - - - Test Page - - - - - - {{ isDarkTheme ? 'Switch To Light Theme' : 'Switch To Dark Theme' }} - - - - - - - - - - diff --git a/packages/dui3/components/user/Avatar.vue b/packages/dui3/components/user/Avatar.vue deleted file mode 100644 index 9d623086e..000000000 --- a/packages/dui3/components/user/Avatar.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - {{ initials }} - - - - - - diff --git a/packages/dui3/eslint.config.mjs b/packages/dui3/eslint.config.mjs deleted file mode 100644 index efa50520e..000000000 --- a/packages/dui3/eslint.config.mjs +++ /dev/null @@ -1,125 +0,0 @@ -import { omit } from 'lodash-es' -import { baseConfigs, globals, getESMDirname } from '../../eslint.config.mjs' -import withNuxt from './.nuxt/eslint.config.mjs' -import pluginVueA11y from 'eslint-plugin-vuejs-accessibility' - -const configs = await withNuxt([ - { - rules: { - camelcase: [ - 'error', - { - properties: 'always', - allow: ['^[\\w]+_[\\w]+Fragment$'] - } - ], - 'no-alert': 'error', - eqeqeq: ['error', 'always', { null: 'always' }], - 'no-console': 'off', - 'no-var': 'error' - } - }, - { - files: ['**/*.{ts,vue,tsx,mts,cts}'], - languageOptions: { - parserOptions: { - project: ['./tsconfig.eslint.json'], - extraFileExtensions: ['.vue'], - tsconfigRootDir: getESMDirname(import.meta.url) - } - } - }, - { - files: ['**/*.test.{ts,js}'], - languageOptions: { - globals: { - ...globals.jest - } - } - }, - { - files: ['./{components|pages|store|lib}/*.{js,ts,vue}'], - languageOptions: { - globals: { - ...globals.browser - } - } - }, - { - files: ['**/*.{ts,tsx,vue}'], - rules: { - '@typescript-eslint/no-explicit-any': ['error'], - '@typescript-eslint/no-unsafe-argument': ['error'], - '@typescript-eslint/no-unsafe-assignment': 'error', - '@typescript-eslint/no-unsafe-call': 'error', - '@typescript-eslint/no-unsafe-member-access': 'error', - '@typescript-eslint/no-unsafe-return': 'error', - '@typescript-eslint/no-for-in-array': ['error'], - '@typescript-eslint/restrict-plus-operands': ['error'], - '@typescript-eslint/await-thenable': ['warn'], - '@typescript-eslint/no-restricted-types': ['warn'], - 'require-await': 'off', - '@typescript-eslint/require-await': 'error', - 'no-undef': 'off', - - '@typescript-eslint/unified-signatures': 'off', // DX sucks in vue event definitions - '@typescript-eslint/no-dynamic-delete': 'off', // too restrictive - '@typescript-eslint/restrict-template-expressions': 'off', // too restrictive - '@typescript-eslint/no-invalid-void-type': 'off' // too restrictive - } - }, - ...pluginVueA11y.configs['flat/recommended'].map((c) => ({ - ...c, - files: [...(c.files || []), '**/*.vue'], - languageOptions: c.languageOptions - ? omit(c.languageOptions, ['parserOptions', 'parser']) // Prevent overriding parser - : undefined - })), - { - files: ['**/*.vue'], - rules: { - 'vue/component-tags-order': [ - 'error', - { order: ['docs', 'template', 'script', 'style'] } - ], - 'vue/require-default-prop': 'off', - 'vue/multi-word-component-names': 'off', - 'vue/component-name-in-template-casing': [ - 'error', - 'PascalCase', - { registeredComponentsOnly: false } - ], - 'vuejs-accessibility/label-has-for': [ - 'error', - { - required: { - some: ['nesting', 'id'] - } - } - ], - 'vue/html-self-closing': 'off' // messes with prettier - } - }, - { - files: ['**/*.d.ts'], - rules: { - 'no-var': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-restricted-types': 'off' - } - } -]).prepend([ - { - ignores: [ - '**/node_modules/**', - '**/templates/*', - './lib/common/generated/**/*', - 'storybook-static', - '.nuxt/**', - '.output/**' - ] - }, - ...baseConfigs -]) - -export default configs diff --git a/packages/dui3/layouts/default.vue b/packages/dui3/layouts/default.vue deleted file mode 100644 index 47180542b..000000000 --- a/packages/dui3/layouts/default.vue +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/packages/dui3/lib/accounts/composables/setup.ts b/packages/dui3/lib/accounts/composables/setup.ts deleted file mode 100644 index 06da215de..000000000 --- a/packages/dui3/lib/accounts/composables/setup.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { ApolloClient, gql } from '@apollo/client/core' -import { ApolloClients } from '@vue/apollo-composable' -import type { ComputedRef, Ref } from 'vue' -import type { Account } from '~/lib/bindings/definitions/IBasicConnectorBinding' -import { resolveClientConfig } from '~/lib/core/configs/apollo' - -export type DUIAccount = { - /** account info coming from the host app */ - accountInfo: Account - /** the graphql client; a bit superflous */ - client?: ApolloClient - /** whether an intial serverinfo query succeeded. */ - isValid: boolean -} - -export type DUIAccountsState = { - accounts: Ref - validAccounts: ComputedRef - refreshAccounts: () => Promise - defaultAccount: ComputedRef - loading: Ref -} - -const AccountsInjectionKey = 'DUI_ACCOUNTS_STATE' - -/** - * Use this composable to set up the account bindings and graphql clients at the top of the app. - * TODO: Properly handle cases when user was not connected to the internet, - * and then actually got connected. - */ -export function useAccountsSetup(): DUIAccountsState { - const app = useNuxtApp() - const $baseBinding = app.$baseBinding - - const accounts = ref([]) - - const apolloClients = {} as Record> - - // Tries to connect to the accounts and sets their is valid prop to false if fails. - const testAccounts = async (accs: DUIAccount[]) => { - const accountTestQuery = gql` - query AcccountTestQuery { - serverInfo { - version - name - company - } - } - ` - for (const acc of accs) { - if (!acc.client) continue - try { - await acc.client.query({ query: accountTestQuery }) - acc.isValid = true - } catch { - // TODO: properly dispose and kill this client. It's unclear how to do it. - acc.isValid = false - // NOTE: we do not want to delete the client, as we might want to "refresh" in - // case the user was not connected to the interweb. - // acc.client.disableNetworkFetches = true - // acc.client.stop() - // delete acc.client - } - } - } - - const loading = ref(false) - - // Matches local accounts coming from the host app to app state. - const refreshAccounts = async () => { - loading.value = true - - const accs = await $baseBinding.getAccounts() - // We create a whole new list of accounts that will replace the old list. This way we ensure we drop - // out of scope old accounts that not exist anymore (TODO: test), and we don't need to do complex diffing. - const newAccs = [] as DUIAccount[] - for (const acc of accs) { - const existing = accounts.value.find((a) => a.accountInfo.id === acc.id) - if (existing) { - newAccs.push(existing as DUIAccount) - continue - } - - const client = new ApolloClient( - resolveClientConfig({ - httpEndpoint: new URL('/graphql', acc.serverInfo.url).href, - authToken: () => acc.token - }) - ) - - apolloClients[acc.id] = client - - newAccs.push({ - accountInfo: acc, - client, - isValid: true - }) - } - // We test accounts here so we try to prevent the app from querying/using invalid accounts. - await testAccounts(newAccs) - // Once we have tested the new accounts, finally set them. - accounts.value = newAccs - loading.value = false - } - - void refreshAccounts() // Promise that we do not want to await (convention with void) - - const defaultAccount = computed(() => - accounts.value.find((acc) => acc.accountInfo.isDefault) - ) - - const validAccounts = computed(() => { - return accounts.value.filter((a) => a.isValid) - }) - - const accState = { - accounts, - defaultAccount, - validAccounts, - refreshAccounts, - loading - } - - app.vueApp.provide(ApolloClients, apolloClients) - provide(AccountsInjectionKey, accState) - - return accState // as DUIAccountsState -} - -/** - * Use this composable to access the users' local accounts and their corresponding graphql client. - */ -export function useInjectedAccounts(): DUIAccountsState { - const state = inject(AccountsInjectionKey) as DUIAccountsState - return state -} diff --git a/packages/dui3/lib/bindings/definitions/IBasicConnectorBinding.ts b/packages/dui3/lib/bindings/definitions/IBasicConnectorBinding.ts deleted file mode 100644 index 296567095..000000000 --- a/packages/dui3/lib/bindings/definitions/IBasicConnectorBinding.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-disable @typescript-eslint/require-await */ - -import { BaseBridge } from '~~/lib/bridge/base' -import type { IBinding } from '~~/lib/bindings/definitions/IBinding' - -export const IBasicConnectorBindingKey = 'baseBinding' - -// Needs to be agreed between Frontend and Core -export interface IBasicConnectorBinding - extends IBinding { - getAccounts: () => Promise - getSourceApplicationName: () => Promise - getSourceApplicationVersion: () => Promise - getDocumentInfo: () => Promise -} - -export interface IBasicConnectorBindingHostEvents { - displayToastNotification: (args: ToastInfo) => void - documentChanged: () => void -} - -// An almost 1-1 mapping of what we need from the Core accounts class. -export type Account = { - id: string - isDefault: boolean - token: string - serverInfo: { - name: string - url: string - } - userInfo: { - id: string - avatar: string - email: string - name: string - commits: { totalCount: number } - streams: { totalCount: number } - } -} - -export type DocumentInfo = { - location: string - name: string - id: string -} - -// NOTE: just a reminder for now -export type ToastInfo = { - text: string - details?: string - type: 'info' | 'error' | 'warning' -} - -export class MockedBaseBinding extends BaseBridge { - public async getAccounts() { - return [] - } - - public async getSourceApplicationName() { - return 'Mocks' - } - - public async getSourceApplicationVersion() { - return Math.random().toString() - } - - public async getDocumentInfo() { - return { - name: 'Mocked File', - location: 'www', - id: Math.random().toString() - } - } - - public async showDevTools() { - console.log('Mocked bindings cannot do this') - } -} diff --git a/packages/dui3/lib/bindings/definitions/IBinding.ts b/packages/dui3/lib/bindings/definitions/IBinding.ts deleted file mode 100644 index 1351b5e48..000000000 --- a/packages/dui3/lib/bindings/definitions/IBinding.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Basic interface scaffolding two standard method. - */ -export interface IBinding { - /** - * Events sent over from the host application. - */ - on: (event: E, callback: T[E]) => void - /** - * If possible, opens up dev tools from the embedded browser window. - * Currently needed for CefSharp, as right click inspect doesn't exist. - */ - showDevTools: () => Promise - /** - * Opens an url in the OS's default browser. - */ - openUrl: (url: string) => Promise -} diff --git a/packages/dui3/lib/bindings/definitions/IConfigBinding.ts b/packages/dui3/lib/bindings/definitions/IConfigBinding.ts deleted file mode 100644 index e3874a88a..000000000 --- a/packages/dui3/lib/bindings/definitions/IConfigBinding.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { BaseBridge } from '~~/lib/bridge/base' -import type { IBinding } from '~~/lib/bindings/definitions/IBinding' - -/** - * The name under which this binding will be registered. - */ -export const IConfigBindingKey = 'configBinding' - -/** - * A test binding interface to ensure compatbility. Ideally all host environments would implement and register it. - */ -export interface IConfigBinding extends IBinding { - getConfig: () => Promise - updateConfig: (config: Config) => Promise -} - -export interface IConfigBindingEvents { - void: () => void -} - -export type Config = { - darkTheme: boolean -} - -export class MockedConfigBinding extends BaseBridge { - getConfig() { - return { - darkTheme: false - } - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - updateConfig(config: Config) { - // do nothing - } -} diff --git a/packages/dui3/lib/bindings/definitions/ITestBinding.ts b/packages/dui3/lib/bindings/definitions/ITestBinding.ts deleted file mode 100644 index 838edef6a..000000000 --- a/packages/dui3/lib/bindings/definitions/ITestBinding.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-disable @typescript-eslint/require-await */ - -import { BaseBridge } from '~~/lib/bridge/base' -import type { IBinding } from '~~/lib/bindings/definitions/IBinding' - -/** - * The name under which this binding will be registered. - */ -export const ITestBindingKey = 'testBinding' - -/** - * A test binding interface to ensure compatbility. Ideally all host environments would implement and register it. - */ -export interface ITestBinding extends IBinding { - sayHi: (name: string, count: number, sayHelloNotHi: boolean) => Promise - goAway: () => Promise - getComplexType: () => Promise - shouldThrow: () => Promise - triggerEvent: (eventName: string) => Promise -} - -export interface ITestBindingEvents { - emptyTestEvent: () => void - testEvent: (args: TestEventArgs) => void -} - -export type TestEventArgs = { - name: string - isOk: boolean - count: number -} - -export type ComplexType = { - id: string - count: number -} - -export class MockedTestBinding extends BaseBridge { - public async sayHi(name: string, count: number, sayHelloNotHi: boolean) { - return `Hello from mocked bindings. Args: name = ${name}, count = ${count}, sayHelloNotHi = ${sayHelloNotHi.toString()}.` - } - - public async goAway() { - return - } - - public async getComplexType() { - return { id: 'wow', count: 42 } - } - - public async shouldThrow() { - return - } - - public async triggerEvent(eventName: string) { - return eventName - } -} diff --git a/packages/dui3/lib/bridge/base.ts b/packages/dui3/lib/bridge/base.ts deleted file mode 100644 index a769589b6..000000000 --- a/packages/dui3/lib/bridge/base.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { Emitter } from 'nanoevents' -import { createNanoEvents } from 'nanoevents' - -/** - * A simple (typed) event emitter base class that host applications can use to send messages (and data) to the web ui, - * e.g. via `browser.executeScriptAsync("myBindings.on('eventName', serializedData)")`. - */ -export class BaseBridge { - public emitter: Emitter - - constructor() { - this.emitter = createNanoEvents() - } - - // NOTE: these do not need to be typed extra in here, as they will be properly typed on the specific binding's interface. - on(event: string | number, callback: (...args: unknown[]) => void) { - return this.emitter.on(event, callback) - } - - // NOTE: this could be private - as it should be only used by the host application. - emit(eventName: string, payload: string) { - const parsedPayload = payload ? (JSON.parse(payload) as unknown) : null - this.emitter.emit(eventName, parsedPayload) - } -} diff --git a/packages/dui3/lib/bridge/definitions/index.ts b/packages/dui3/lib/bridge/definitions/index.ts deleted file mode 100644 index b2a789991..000000000 --- a/packages/dui3/lib/bridge/definitions/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Defines the expected contract of the host application bound object. - */ -export type IRawBridge = { - GetBindingsMethodNames: () => Promise - RunMethod: (methodName: string, args: string) => Promise - ShowDevTools: () => Promise - OpenUrl: (url: string) => Promise -} diff --git a/packages/dui3/lib/bridge/generic.ts b/packages/dui3/lib/bridge/generic.ts deleted file mode 100644 index 7b441868c..000000000 --- a/packages/dui3/lib/bridge/generic.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { BaseBridge } from '~/lib/bridge/base' -import type { IRawBridge } from '~/lib/bridge/definitions' -/** - * A generic bridge class for Webivew2 or CefSharp. - */ -export class GenericBridge extends BaseBridge { - private bridge: IRawBridge - - constructor(object: IRawBridge) { - super() - this.bridge = object - } - - public async create(): Promise { - // NOTE: GetMethods is a call to the .NET side. - let availableMethodNames = [] as string[] - - try { - availableMethodNames = await this.bridge.GetBindingsMethodNames() - } catch { - console.warn(`Failed to get method names.`) - return false - } - - // NOTE: hoisting original calls as lowerCasedMethodNames, but using the UpperCasedName for the .NET call - // This allows us to follow js convetions and keep .NET ones too (eg. bindings.sayHi('') => public string SayHi(string name) {} - for (const methodName of availableMethodNames) { - const lowercasedMethodName = lowercaseMethodName(methodName) - const hoistTarget = this as unknown as Record - hoistTarget[lowercasedMethodName] = (...args: unknown[]) => - this.runMethod(methodName, args) - } - - return true - } - - private async runMethod(methodName: string, args: unknown[]): Promise { - const preserializedArgs = args.map((a) => JSON.stringify(a)) - - // NOTE: RunMethod is a call to the .NET side. - const result = await this.bridge.RunMethod( - methodName, - JSON.stringify(preserializedArgs) - ) - - const parsed = result ? (JSON.parse(result) as Record) : null - - if (parsed && parsed['error']) { - console.error(parsed) - throw new Error( - `Failed to run ${methodName} with args ${JSON.stringify( - args - )}. The host app error is logged above.` - ) - } - - return parsed - } - - public showDevTools() { - this.bridge.ShowDevTools() - } - - public openUrl(url: string) { - this.bridge.OpenUrl(url) - } -} - -const lowercaseMethodName = (name: string) => - name.charAt(0).toLowerCase() + name.slice(1) diff --git a/packages/dui3/lib/bridge/sketchup.ts b/packages/dui3/lib/bridge/sketchup.ts deleted file mode 100644 index a8f25d32e..000000000 --- a/packages/dui3/lib/bridge/sketchup.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { uniqueId } from 'lodash-es' -import { BaseBridge } from './base' - -declare let sketchup: { - exec: (data: Record) => void - getCommands: (viewId: string) => void -} - -/** - * This class operates in different way than the others, because calls into Sketchup are one way only. - * E.g., we cannot return values from internal calls to it (e.g., const test = sketchup.rubyCall() does not work ). - * This class basically makes the sketchup bindings work in the same way as cef/webview by returning a promise - * on each method call. That promise is either resolved once sketchup sends back (via receiveResponse) a corresponding - * reply, or it's rejected after a given TIMEOUT_MS (currently 2s). - * TODO: implement the event dispatcher side as well. - */ -export class SketchupBridge extends BaseBridge { - private requests = {} as Record< - string, - { - resolve: (value: unknown) => void - reject: (reason: string | Error) => void - rejectTimerId: number - } - > - private bindingName: string - private TIMEOUT_MS = 2000 // 2s - public isInitalized: Promise - private resolveIsInitializedPromise!: (v: boolean) => unknown - private rejectIsInitializedPromise!: (message: string) => unknown - - constructor(bindingName: string) { - super() - this.bindingName = bindingName || 'default_bindings' - - this.isInitalized = new Promise((resolve, reject) => { - this.resolveIsInitializedPromise = resolve - this.rejectIsInitializedPromise = reject - setTimeout( - () => - reject( - `Failed to get command names from Sketchup; timed out after ${this.TIMEOUT_MS}ms.` - ), - this.TIMEOUT_MS - ) - }) - - // NOTE: we need to hoist the bindings in global scope BEFORE we call sketchup exec get comands below. - ;(globalThis as Record).bindings = this - } - - // NOTE: Overriden emit as we do not need to parse the data back - the Sketchup bridge already parses it for us. - emit(eventName: string, payload: string): void { - this.emitter.emit(eventName, payload as unknown as Record) - } - - public async create(): Promise { - // Initialization continues in the receiveCommandsAndInitializeBridge function, - // where we expect sketchup to return to us the command names for related bindings/views. - sketchup.getCommands(this.bindingName) - - // - try { - await this.isInitalized - return true - } catch { - return false - } - } - - /** - * Will be called by `executeScript('bindings.receiveCommandsAndInitializeBridge()')` from sketchup. This is where the hoisting happens. - * NOTE: Oguhzan, we can defintively have commandNames be a string, and not a string[] - * And do JSON.parse() here to get them out properly. - * @param commandNames - */ - private receiveCommandsAndInitializeBridge(commandNamesString: string) { - const commandNames = JSON.parse(commandNamesString) as string[] - const hoistTarget = this as unknown as Record - for (const commandName of commandNames) { - hoistTarget[commandName] = (...args: unknown[]) => - this.runMethod(commandName, args) - } - - this.resolveIsInitializedPromise(true) - } - - /** - * Will be called by `executeScript('bindings.rejectBindings()')` from sketchup. - * @param message - */ - private rejectBindings(message: string) { - this.rejectIsInitializedPromise(message) - } - - /** - * Internal calls to Sketchup. - * @param methodName - * @param args - */ - private async runMethod(methodName: string, args: unknown[]): Promise { - const requestId = uniqueId(this.bindingName) - - // TODO: more on the ruby end, but for now Oguzhan seems happy with this. - // Changes might be needed in the future. - sketchup.exec({ - name: methodName, - // eslint-disable-next-line camelcase - request_id: requestId, - // eslint-disable-next-line camelcase - binding_name: this.bindingName, - data: { args } - }) - - return new Promise((resolve, reject) => { - this.requests[requestId] = { - resolve, - reject, - rejectTimerId: window.setTimeout(() => { - reject( - `Sketchup response timed out - did not receive anything back in good time (${this.TIMEOUT_MS}ms).` - ) - delete this.requests[requestId] - }, this.TIMEOUT_MS) - } - }) - } - - private receiveResponse(requestId: string, data: object) { - if (!this.requests[requestId]) - throw new Error( - `Sketchup Bridge found no request to resolve with the id of ${requestId}. Something is weird!` - ) - const request = this.requests[requestId] - try { - // eslint-disable-next-line no-prototype-builtins - if (data && data.hasOwnProperty('error')) { - console.error(data) - throw new Error( - `Failed to run ${requestId}. The host app error is logged above.` - ) - } - - // NOTE/TODO: does not need parsing - // const parsedData = JSON.parse(data) as Record // TODO: check if data is undefined - request.resolve(data) - } catch (e) { - request.reject(e as Error) - } finally { - window.clearTimeout(request.rejectTimerId) - delete this.requests[requestId] - } - } - - public showDevTools() { - // eslint-disable-next-line no-alert - window.alert( - 'Sketchup cannot do this. The dev tools menu is accessible via a right click.' - ) - } -} diff --git a/packages/dui3/lib/common/generated/gql/gql.ts b/packages/dui3/lib/common/generated/gql/gql.ts deleted file mode 100644 index 5b13f7036..000000000 --- a/packages/dui3/lib/common/generated/gql/gql.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable */ -import * as types from './graphql'; -import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - -/** - * Map of all GraphQL operations in the project. - * - * This map has several performance disadvantages: - * 1. It is not tree-shakeable, so it will include all operations in the project. - * 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle. - * 3. It does not support dead code elimination, so it will add unused operations. - * - * Therefore it is highly recommended to use the babel or swc plugin for production. - */ -const documents = { - "\n query AcccountTestQuery {\n serverInfo {\n version\n name\n company\n }\n }\n ": types.AcccountTestQueryDocument, -}; - -/** - * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - * - * - * @example - * ```ts - * const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`); - * ``` - * - * The query argument is unknown! - * Please regenerate the types. - */ -export function graphql(source: string): unknown; - -/** - * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function graphql(source: "\n query AcccountTestQuery {\n serverInfo {\n version\n name\n company\n }\n }\n "): (typeof documents)["\n query AcccountTestQuery {\n serverInfo {\n version\n name\n company\n }\n }\n "]; - -export function graphql(source: string) { - return (documents as any)[source] ?? {}; -} - -export type DocumentType> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never; \ No newline at end of file diff --git a/packages/dui3/lib/common/generated/gql/graphql.ts b/packages/dui3/lib/common/generated/gql/graphql.ts deleted file mode 100644 index a30bbdd95..000000000 --- a/packages/dui3/lib/common/generated/gql/graphql.ts +++ /dev/null @@ -1,5084 +0,0 @@ -/* eslint-disable */ -import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: { input: string; output: string; } - String: { input: string; output: string; } - Boolean: { input: boolean; output: boolean; } - Int: { input: number; output: number; } - Float: { input: number; output: number; } - /** The `BigInt` scalar type represents non-fractional signed whole numeric values. */ - BigInt: { input: any; output: any; } - /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */ - DateTime: { input: string; output: string; } - /** The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */ - JSONObject: { input: {}; output: {}; } -}; - -export type ActiveUserMutations = { - __typename?: 'ActiveUserMutations'; - emailMutations: UserEmailMutations; - /** Mark onboarding as complete */ - finishOnboarding: Scalars['Boolean']['output']; - meta: UserMetaMutations; - setActiveWorkspace: Scalars['Boolean']['output']; - /** Edit a user's profile */ - update: User; -}; - - -export type ActiveUserMutationsFinishOnboardingArgs = { - input?: InputMaybe; -}; - - -export type ActiveUserMutationsSetActiveWorkspaceArgs = { - isProjectsActive?: InputMaybe; - slug?: InputMaybe; -}; - - -export type ActiveUserMutationsUpdateArgs = { - user: UserUpdateInput; -}; - -export type Activity = { - __typename?: 'Activity'; - actionType: Scalars['String']['output']; - id: Scalars['ID']['output']; - info: Scalars['JSONObject']['output']; - message: Scalars['String']['output']; - resourceId: Scalars['String']['output']; - resourceType: Scalars['String']['output']; - streamId?: Maybe; - time: Scalars['DateTime']['output']; - userId: Scalars['String']['output']; -}; - -export type ActivityCollection = { - __typename?: 'ActivityCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type AddDomainToWorkspaceInput = { - domain: Scalars['String']['input']; - workspaceId: Scalars['ID']['input']; -}; - -export type AdminInviteList = { - __typename?: 'AdminInviteList'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type AdminMutations = { - __typename?: 'AdminMutations'; - updateWorkspacePlan: Scalars['Boolean']['output']; -}; - - -export type AdminMutationsUpdateWorkspacePlanArgs = { - input: AdminUpdateWorkspacePlanInput; -}; - -export type AdminQueries = { - __typename?: 'AdminQueries'; - inviteList: AdminInviteList; - projectList: ProjectCollection; - serverStatistics: ServerStatistics; - userList: AdminUserList; - workspaceList: WorkspaceCollection; -}; - - -export type AdminQueriesInviteListArgs = { - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; - query?: InputMaybe; -}; - - -export type AdminQueriesProjectListArgs = { - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; - orderBy?: InputMaybe; - query?: InputMaybe; - visibility?: InputMaybe; -}; - - -export type AdminQueriesUserListArgs = { - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; - query?: InputMaybe; - role?: InputMaybe; -}; - - -export type AdminQueriesWorkspaceListArgs = { - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; - query?: InputMaybe; -}; - -export type AdminUpdateWorkspacePlanInput = { - plan: WorkspacePlans; - status: WorkspacePlanStatuses; - workspaceId: Scalars['ID']['input']; -}; - -export type AdminUserList = { - __typename?: 'AdminUserList'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type AdminUserListItem = { - __typename?: 'AdminUserListItem'; - avatar?: Maybe; - company?: Maybe; - email?: Maybe; - id: Scalars['ID']['output']; - name: Scalars['String']['output']; - role?: Maybe; - verified?: Maybe; -}; - -export type AdminUsersListCollection = { - __typename?: 'AdminUsersListCollection'; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -/** - * A representation of a registered or invited user in the admin users list. Either registeredUser - * or invitedUser will always be set, both values can't be null. - */ -export type AdminUsersListItem = { - __typename?: 'AdminUsersListItem'; - id: Scalars['String']['output']; - invitedUser?: Maybe; - registeredUser?: Maybe; -}; - -export type AdminWorkspaceJoinRequestFilter = { - status?: InputMaybe; -}; - -export type ApiToken = { - __typename?: 'ApiToken'; - createdAt: Scalars['DateTime']['output']; - id: Scalars['String']['output']; - lastChars: Scalars['String']['output']; - lastUsed: Scalars['DateTime']['output']; - lifespan: Scalars['BigInt']['output']; - name: Scalars['String']['output']; - scopes: Array>; -}; - -export type ApiTokenCreateInput = { - lifespan?: InputMaybe; - name: Scalars['String']['input']; - scopes: Array; -}; - -export type AppAuthor = { - __typename?: 'AppAuthor'; - avatar?: Maybe; - id: Scalars['String']['output']; - name: Scalars['String']['output']; -}; - -export type AppCreateInput = { - description: Scalars['String']['input']; - logo?: InputMaybe; - name: Scalars['String']['input']; - public?: InputMaybe; - redirectUrl: Scalars['String']['input']; - scopes: Array>; - termsAndConditionsLink?: InputMaybe; -}; - -export type AppTokenCreateInput = { - lifespan?: InputMaybe; - /** Optionally limit the token to only have access to specific resources */ - limitResources?: InputMaybe>; - name: Scalars['String']['input']; - scopes: Array; -}; - -export type AppUpdateInput = { - description: Scalars['String']['input']; - id: Scalars['String']['input']; - logo?: InputMaybe; - name: Scalars['String']['input']; - public?: InputMaybe; - redirectUrl: Scalars['String']['input']; - scopes: Array>; - termsAndConditionsLink?: InputMaybe; -}; - -export type ApproveWorkspaceJoinRequestInput = { - userId: Scalars['String']['input']; - workspaceId: Scalars['String']['input']; -}; - -export type ArchiveCommentInput = { - archived: Scalars['Boolean']['input']; - commentId: Scalars['String']['input']; - projectId: Scalars['String']['input']; -}; - -export type AuthStrategy = { - __typename?: 'AuthStrategy'; - color?: Maybe; - icon: Scalars['String']['output']; - id: Scalars['String']['output']; - name: Scalars['String']['output']; - url: Scalars['String']['output']; -}; - -export type AutomateAuthCodePayloadTest = { - action: Scalars['String']['input']; - code: Scalars['String']['input']; - userId: Scalars['String']['input']; - workspaceId?: InputMaybe; -}; - -/** Additional resources to validate user access to. */ -export type AutomateAuthCodeResources = { - workspaceId?: InputMaybe; -}; - -export type AutomateFunction = { - __typename?: 'AutomateFunction'; - /** Only returned if user is a part of this speckle server */ - creator?: Maybe; - description: Scalars['String']['output']; - id: Scalars['ID']['output']; - isFeatured: Scalars['Boolean']['output']; - logo?: Maybe; - name: Scalars['String']['output']; - releases: AutomateFunctionReleaseCollection; - repo: BasicGitRepositoryMetadata; - /** SourceAppNames values from @speckle/shared. Empty array means - all of them */ - supportedSourceApps: Array; - tags: Array; - workspaceIds?: Maybe>; -}; - - -export type AutomateFunctionReleasesArgs = { - cursor?: InputMaybe; - filter?: InputMaybe; - limit?: InputMaybe; -}; - -export type AutomateFunctionCollection = { - __typename?: 'AutomateFunctionCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type AutomateFunctionRelease = { - __typename?: 'AutomateFunctionRelease'; - commitId: Scalars['String']['output']; - createdAt: Scalars['DateTime']['output']; - function: AutomateFunction; - functionId: Scalars['String']['output']; - id: Scalars['ID']['output']; - inputSchema?: Maybe; - versionTag: Scalars['String']['output']; -}; - -export type AutomateFunctionReleaseCollection = { - __typename?: 'AutomateFunctionReleaseCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type AutomateFunctionReleasesFilter = { - search?: InputMaybe; -}; - -export type AutomateFunctionRun = { - __typename?: 'AutomateFunctionRun'; - contextView?: Maybe; - createdAt: Scalars['DateTime']['output']; - elapsed: Scalars['Float']['output']; - /** Nullable, in case the function is not retrievable due to poor network conditions */ - function?: Maybe; - functionId?: Maybe; - functionReleaseId?: Maybe; - id: Scalars['ID']['output']; - /** AutomateTypes.ResultsSchema type from @speckle/shared */ - results?: Maybe; - status: AutomateRunStatus; - statusMessage?: Maybe; - updatedAt: Scalars['DateTime']['output']; -}; - -export type AutomateFunctionRunStatusReportInput = { - contextView?: InputMaybe; - functionRunId: Scalars['String']['input']; - projectId: Scalars['String']['input']; - /** AutomateTypes.ResultsSchema type from @speckle/shared */ - results?: InputMaybe; - status: AutomateRunStatus; - statusMessage?: InputMaybe; -}; - -export type AutomateFunctionTemplate = { - __typename?: 'AutomateFunctionTemplate'; - id: AutomateFunctionTemplateLanguage; - logo: Scalars['String']['output']; - title: Scalars['String']['output']; - url: Scalars['String']['output']; -}; - -export enum AutomateFunctionTemplateLanguage { - DotNet = 'DOT_NET', - Python = 'PYTHON', - Typescript = 'TYPESCRIPT' -} - -export type AutomateFunctionToken = { - __typename?: 'AutomateFunctionToken'; - functionId: Scalars['String']['output']; - functionToken: Scalars['String']['output']; -}; - -export type AutomateFunctionsFilter = { - /** By default, we include featured ("public") functions. Set this to false to exclude them. */ - includeFeatured?: InputMaybe; - /** By default, we exclude functions without releases. Set this to false to include them. */ - requireRelease?: InputMaybe; - search?: InputMaybe; -}; - -export type AutomateMutations = { - __typename?: 'AutomateMutations'; - createFunction: AutomateFunction; - createFunctionWithoutVersion: AutomateFunctionToken; - updateFunction: AutomateFunction; -}; - - -export type AutomateMutationsCreateFunctionArgs = { - input: CreateAutomateFunctionInput; -}; - - -export type AutomateMutationsCreateFunctionWithoutVersionArgs = { - input: CreateAutomateFunctionWithoutVersionInput; -}; - - -export type AutomateMutationsUpdateFunctionArgs = { - input: UpdateAutomateFunctionInput; -}; - -export type AutomateRun = { - __typename?: 'AutomateRun'; - automation: Automation; - automationId: Scalars['String']['output']; - createdAt: Scalars['DateTime']['output']; - functionRuns: Array; - id: Scalars['ID']['output']; - status: AutomateRunStatus; - trigger: AutomationRunTrigger; - updatedAt: Scalars['DateTime']['output']; -}; - -export type AutomateRunCollection = { - __typename?: 'AutomateRunCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export enum AutomateRunStatus { - Canceled = 'CANCELED', - Exception = 'EXCEPTION', - Failed = 'FAILED', - Initializing = 'INITIALIZING', - Pending = 'PENDING', - Running = 'RUNNING', - Succeeded = 'SUCCEEDED', - Timeout = 'TIMEOUT' -} - -export enum AutomateRunTriggerType { - VersionCreated = 'VERSION_CREATED' -} - -export type Automation = { - __typename?: 'Automation'; - createdAt: Scalars['DateTime']['output']; - /** Only accessible to automation owners */ - creationPublicKeys: Array; - currentRevision?: Maybe; - enabled: Scalars['Boolean']['output']; - id: Scalars['ID']['output']; - isTestAutomation: Scalars['Boolean']['output']; - name: Scalars['String']['output']; - permissions: AutomationPermissionChecks; - runs: AutomateRunCollection; - updatedAt: Scalars['DateTime']['output']; -}; - - -export type AutomationRunsArgs = { - cursor?: InputMaybe; - limit?: InputMaybe; -}; - -export type AutomationCollection = { - __typename?: 'AutomationCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type AutomationPermissionChecks = { - __typename?: 'AutomationPermissionChecks'; - canDelete: PermissionCheckResult; - canRead: PermissionCheckResult; - canUpdate: PermissionCheckResult; -}; - -export type AutomationRevision = { - __typename?: 'AutomationRevision'; - functions: Array; - id: Scalars['ID']['output']; - triggerDefinitions: Array; -}; - -export type AutomationRevisionCreateFunctionInput = { - functionId: Scalars['String']['input']; - functionReleaseId: Scalars['String']['input']; - /** Should be encrypted from the client side */ - parameters?: InputMaybe; -}; - -export type AutomationRevisionFunction = { - __typename?: 'AutomationRevisionFunction'; - /** The secrets in parameters are redacted with six asterisks - ****** */ - parameters?: Maybe; - release: AutomateFunctionRelease; -}; - -export type AutomationRevisionTriggerDefinition = VersionCreatedTriggerDefinition; - -export type AutomationRunTrigger = VersionCreatedTrigger; - -export type BasicGitRepositoryMetadata = { - __typename?: 'BasicGitRepositoryMetadata'; - id: Scalars['ID']['output']; - name: Scalars['String']['output']; - owner: Scalars['String']['output']; - url: Scalars['String']['output']; -}; - -export enum BillingInterval { - Monthly = 'monthly', - Yearly = 'yearly' -} - -export type BlobMetadata = { - __typename?: 'BlobMetadata'; - createdAt: Scalars['DateTime']['output']; - fileHash?: Maybe; - fileName: Scalars['String']['output']; - fileSize?: Maybe; - fileType: Scalars['String']['output']; - id: Scalars['String']['output']; - streamId: Scalars['String']['output']; - uploadError?: Maybe; - uploadStatus: Scalars['Int']['output']; - userId: Scalars['String']['output']; -}; - -export type BlobMetadataCollection = { - __typename?: 'BlobMetadataCollection'; - cursor?: Maybe; - items?: Maybe>; - totalCount: Scalars['Int']['output']; - totalSize: Scalars['Int']['output']; -}; - -export type Branch = { - __typename?: 'Branch'; - /** - * All the recent activity on this branch in chronological order - * @deprecated Part of the old API surface and will be removed in the future. - */ - activity?: Maybe; - author?: Maybe; - commits?: Maybe; - createdAt?: Maybe; - description?: Maybe; - id: Scalars['String']['output']; - name: Scalars['String']['output']; -}; - - -export type BranchActivityArgs = { - actionType?: InputMaybe; - after?: InputMaybe; - before?: InputMaybe; - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; -}; - - -export type BranchCommitsArgs = { - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; -}; - -export type BranchCollection = { - __typename?: 'BranchCollection'; - cursor?: Maybe; - items?: Maybe>; - totalCount: Scalars['Int']['output']; -}; - -export type BranchCreateInput = { - description?: InputMaybe; - name: Scalars['String']['input']; - streamId: Scalars['String']['input']; -}; - -export type BranchDeleteInput = { - id: Scalars['String']['input']; - streamId: Scalars['String']['input']; -}; - -export type BranchUpdateInput = { - description?: InputMaybe; - id: Scalars['String']['input']; - name?: InputMaybe; - streamId: Scalars['String']['input']; -}; - -export type BulkUsersRetrievalInput = { - cursor?: InputMaybe; - emails: Array; - limit?: InputMaybe; -}; - -export type CancelCheckoutSessionInput = { - sessionId: Scalars['ID']['input']; - workspaceId: Scalars['ID']['input']; -}; - -export type CheckoutSession = { - __typename?: 'CheckoutSession'; - billingInterval: BillingInterval; - createdAt: Scalars['DateTime']['output']; - id: Scalars['ID']['output']; - paymentStatus: SessionPaymentStatus; - updatedAt: Scalars['DateTime']['output']; - url: Scalars['String']['output']; - workspacePlan: PaidWorkspacePlans; -}; - -export type CheckoutSessionInput = { - billingInterval: BillingInterval; - currency?: InputMaybe; - isCreateFlow?: InputMaybe; - workspaceId: Scalars['ID']['input']; - workspacePlan: PaidWorkspacePlans; -}; - -export type Comment = { - __typename?: 'Comment'; - archived: Scalars['Boolean']['output']; - author: LimitedUser; - authorId: Scalars['String']['output']; - createdAt: Scalars['DateTime']['output']; - /** - * Legacy comment viewer data field - * @deprecated Use the new viewerState field instead - */ - data?: Maybe; - /** Whether or not comment is a reply to another comment */ - hasParent: Scalars['Boolean']['output']; - id: Scalars['String']['output']; - /** Parent thread, if there's any */ - parent?: Maybe; - permissions: CommentPermissionChecks; - /** Plain-text version of the comment text, ideal for previews */ - rawText?: Maybe; - /** @deprecated Not actually implemented */ - reactions?: Maybe>>; - /** Gets the replies to this comment. */ - replies: CommentCollection; - /** Get authors of replies to this comment */ - replyAuthors: CommentReplyAuthorCollection; - /** Resources that this comment targets. Can be a mixture of either one stream, or multiple commits and objects. */ - resources: Array; - screenshot?: Maybe; - text?: Maybe; - /** The time this comment was last updated. Corresponds also to the latest reply to this comment, if any. */ - updatedAt: Scalars['DateTime']['output']; - /** The last time you viewed this comment. Present only if an auth'ed request. Relevant only if a top level commit. */ - viewedAt?: Maybe; - /** Resource identifiers as defined and implemented in the Viewer of the new frontend */ - viewerResources: Array; - /** SerializedViewerState */ - viewerState?: Maybe; -}; - - -export type CommentRepliesArgs = { - cursor?: InputMaybe; - limit?: InputMaybe; -}; - - -export type CommentReplyAuthorsArgs = { - limit?: Scalars['Int']['input']; -}; - -export type CommentActivityMessage = { - __typename?: 'CommentActivityMessage'; - comment: Comment; - type: Scalars['String']['output']; -}; - -export type CommentCollection = { - __typename?: 'CommentCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type CommentContentInput = { - blobIds?: InputMaybe>; - doc?: InputMaybe; -}; - -/** Deprecated: Used by old stream-based mutations */ -export type CommentCreateInput = { - /** IDs of uploaded blobs that should be attached to this comment */ - blobIds: Array; - data: Scalars['JSONObject']['input']; - /** - * Specifies the resources this comment is linked to. There are several use cases: - * - a comment targets only one resource (commit or object) - * - a comment targets one or more resources (commits or objects) - * - a comment targets only a stream - */ - resources: Array>; - screenshot?: InputMaybe; - streamId: Scalars['String']['input']; - /** ProseMirror document object */ - text?: InputMaybe; -}; - -export type CommentDataFilters = { - __typename?: 'CommentDataFilters'; - hiddenIds?: Maybe>; - isolatedIds?: Maybe>; - passMax?: Maybe; - passMin?: Maybe; - propertyInfoKey?: Maybe; - sectionBox?: Maybe; -}; - -/** Equivalent to frontend-1's LocalFilterState */ -export type CommentDataFiltersInput = { - hiddenIds?: InputMaybe>; - isolatedIds?: InputMaybe>; - passMax?: InputMaybe; - passMin?: InputMaybe; - propertyInfoKey?: InputMaybe; - sectionBox?: InputMaybe; -}; - -/** Deprecated: Used by old stream-based mutations */ -export type CommentEditInput = { - /** IDs of uploaded blobs that should be attached to this comment */ - blobIds: Array; - id: Scalars['String']['input']; - streamId: Scalars['String']['input']; - /** ProseMirror document object */ - text?: InputMaybe; -}; - -export type CommentMutations = { - __typename?: 'CommentMutations'; - archive: Scalars['Boolean']['output']; - create: Comment; - edit: Comment; - markViewed: Scalars['Boolean']['output']; - reply: Comment; -}; - - -export type CommentMutationsArchiveArgs = { - input: ArchiveCommentInput; -}; - - -export type CommentMutationsCreateArgs = { - input: CreateCommentInput; -}; - - -export type CommentMutationsEditArgs = { - input: EditCommentInput; -}; - - -export type CommentMutationsMarkViewedArgs = { - input: MarkCommentViewedInput; -}; - - -export type CommentMutationsReplyArgs = { - input: CreateCommentReplyInput; -}; - -export type CommentPermissionChecks = { - __typename?: 'CommentPermissionChecks'; - canArchive: PermissionCheckResult; -}; - -export type CommentReplyAuthorCollection = { - __typename?: 'CommentReplyAuthorCollection'; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type CommentThreadActivityMessage = { - __typename?: 'CommentThreadActivityMessage'; - data?: Maybe; - reply?: Maybe; - type: Scalars['String']['output']; -}; - -export type Commit = { - __typename?: 'Commit'; - /** - * All the recent activity on this commit in chronological order - * @deprecated Part of the old API surface and will be removed in the future. - */ - activity?: Maybe; - authorAvatar?: Maybe; - authorId?: Maybe; - authorName?: Maybe; - branch?: Maybe; - branchName?: Maybe; - /** - * The total number of comments for this commit. To actually get the comments, use the comments query and pass in a resource array consisting of of this commit's id. - * E.g., - * ``` - * query{ - * comments(streamId:"streamId" resources:[{resourceType: commit, resourceId:"commitId"}] ){ - * ... - * } - * ``` - * @deprecated Part of the old API surface and will be removed in the future. - */ - commentCount: Scalars['Int']['output']; - createdAt?: Maybe; - id: Scalars['String']['output']; - message?: Maybe; - parents?: Maybe>>; - referencedObject: Scalars['String']['output']; - sourceApplication?: Maybe; - /** - * Will throw an authorization error if active user isn't authorized to see it, for example, - * if a stream isn't public and the user doesn't have the appropriate rights. - */ - stream: Stream; - /** @deprecated Use the stream field instead */ - streamId?: Maybe; - /** @deprecated Use the stream field instead */ - streamName?: Maybe; - totalChildrenCount?: Maybe; -}; - - -export type CommitActivityArgs = { - actionType?: InputMaybe; - after?: InputMaybe; - before?: InputMaybe; - cursor?: InputMaybe; - limit?: Scalars['Int']['input']; -}; - -export type CommitCollection = { - __typename?: 'CommitCollection'; - cursor?: Maybe; - items?: Maybe>; - totalCount: Scalars['Int']['output']; -}; - -export type CommitCreateInput = { - branchName: Scalars['String']['input']; - message?: InputMaybe; - objectId: Scalars['String']['input']; - parents?: InputMaybe>>; - sourceApplication?: InputMaybe; - streamId: Scalars['String']['input']; - totalChildrenCount?: InputMaybe; -}; - -export type CommitDeleteInput = { - id: Scalars['String']['input']; - streamId: Scalars['String']['input']; -}; - -export type CommitReceivedInput = { - commitId: Scalars['String']['input']; - message?: InputMaybe; - sourceApplication: Scalars['String']['input']; - streamId: Scalars['String']['input']; -}; - -export type CommitUpdateInput = { - id: Scalars['String']['input']; - message?: InputMaybe; - /** To move the commit to a different branch, please the name of the branch. */ - newBranchName?: InputMaybe; - streamId: Scalars['String']['input']; -}; - -export type CommitsDeleteInput = { - commitIds: Array; - streamId: Scalars['ID']['input']; -}; - -export type CommitsMoveInput = { - commitIds: Array; - streamId: Scalars['ID']['input']; - targetBranch: Scalars['String']['input']; -}; - -/** - * Can be used instead of a full item collection, when the implementation doesn't call for it yet. Because - * of the structure, it can be swapped out to a full item collection in the future - */ -export type CountOnlyCollection = { - __typename?: 'CountOnlyCollection'; - totalCount: Scalars['Int']['output']; -}; - -export type CreateAutomateFunctionInput = { - description: Scalars['String']['input']; - /** Base64 encoded image data string */ - logo?: InputMaybe; - name: Scalars['String']['input']; - /** GitHub organization to create the repository in */ - org?: InputMaybe; - /** SourceAppNames values from @speckle/shared */ - supportedSourceApps: Array; - tags: Array; - template: AutomateFunctionTemplateLanguage; -}; - -export type CreateAutomateFunctionWithoutVersionInput = { - description: Scalars['String']['input']; - name: Scalars['String']['input']; -}; - -export type CreateCommentInput = { - content: CommentContentInput; - projectId: Scalars['String']['input']; - /** Resources that this comment should be attached to */ - resourceIdString: Scalars['String']['input']; - screenshot?: InputMaybe; - /** - * SerializedViewerState. If omitted, comment won't render (correctly) inside the - * viewer, but will still be retrievable through the API - */ - viewerState?: InputMaybe; -}; - -export type CreateCommentReplyInput = { - content: CommentContentInput; - projectId: Scalars['String']['input']; - threadId: Scalars['String']['input']; -}; - -export type CreateModelInput = { - description?: InputMaybe; - name: Scalars['String']['input']; - projectId: Scalars['ID']['input']; -}; - -export type CreateServerRegionInput = { - description?: InputMaybe; - key: Scalars['String']['input']; - name: Scalars['String']['input']; -}; - -export type CreateUserEmailInput = { - email: Scalars['String']['input']; -}; - -export type CreateVersionInput = { - message?: InputMaybe; - modelId: Scalars['String']['input']; - objectId: Scalars['String']['input']; - parents?: InputMaybe>; - projectId: Scalars['String']['input']; - sourceApplication?: InputMaybe; - totalChildrenCount?: InputMaybe; -}; - -export enum Currency { - Gbp = 'gbp', - Usd = 'usd' -} - -export type CurrencyBasedPrices = { - __typename?: 'CurrencyBasedPrices'; - gbp: WorkspacePaidPlanPrices; - usd: WorkspacePaidPlanPrices; -}; - -export type DeleteModelInput = { - id: Scalars['ID']['input']; - projectId: Scalars['ID']['input']; -}; - -export type DeleteUserEmailInput = { - id: Scalars['ID']['input']; -}; - -export type DeleteVersionsInput = { - projectId: Scalars['ID']['input']; - versionIds: Array; -}; - -export type DenyWorkspaceJoinRequestInput = { - userId: Scalars['String']['input']; - workspaceId: Scalars['String']['input']; -}; - -export enum DiscoverableStreamsSortType { - CreatedDate = 'CREATED_DATE', - FavoritesCount = 'FAVORITES_COUNT' -} - -export type DiscoverableStreamsSortingInput = { - direction: SortDirection; - type: DiscoverableStreamsSortType; -}; - -export type DiscoverableWorkspaceCollaborator = { - __typename?: 'DiscoverableWorkspaceCollaborator'; - avatar?: Maybe; -}; - -export type DiscoverableWorkspaceCollaboratorCollection = { - __typename?: 'DiscoverableWorkspaceCollaboratorCollection'; - cursor?: Maybe; - items: Array; - totalCount: Scalars['Int']['output']; -}; - -export type EditCommentInput = { - commentId: Scalars['String']['input']; - content: CommentContentInput; - projectId: Scalars['String']['input']; -}; - -export type EmailVerificationRequestInput = { - id: Scalars['ID']['input']; -}; - -export type FileUpload = { - __typename?: 'FileUpload'; - branchName: Scalars['String']['output']; - /** If present, the conversion result is stored in this commit. */ - convertedCommitId?: Maybe; - convertedLastUpdate: Scalars['DateTime']['output']; - /** Holds any errors or info. */ - convertedMessage?: Maybe; - /** 0 = queued, 1 = processing, 2 = success, 3 = error */ - convertedStatus: Scalars['Int']['output']; - /** Alias for convertedCommitId */ - convertedVersionId?: Maybe; - fileName: Scalars['String']['output']; - fileSize: Scalars['Int']['output']; - fileType: Scalars['String']['output']; - id: Scalars['String']['output']; - /** Model associated with the file upload, if it exists already */ - model?: Maybe; - /** Alias for branchName */ - modelName: Scalars['String']['output']; - /** Alias for streamId */ - projectId: Scalars['String']['output']; - streamId: Scalars['String']['output']; - uploadComplete: Scalars['Boolean']['output']; - uploadDate: Scalars['DateTime']['output']; - /** The user's id that uploaded this file. */ - userId: Scalars['String']['output']; -}; - -export type GendoAiRender = { - __typename?: 'GendoAIRender'; - camera?: Maybe; - createdAt: Scalars['DateTime']['output']; - gendoGenerationId?: Maybe; - id: Scalars['ID']['output']; - modelId: Scalars['String']['output']; - projectId: Scalars['String']['output']; - prompt: Scalars['String']['output']; - /** This is a blob id. */ - responseImage?: Maybe