Merge branch 'main' into bilal/cnx-2582-dui3-projectmodel-creation-enabled-in-load-flow
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# Irrelevant source files
|
||||
deployment/
|
||||
|
||||
# Build output and other temporary files
|
||||
.husky/_/
|
||||
.netlify/
|
||||
.nuxt/
|
||||
dist/
|
||||
node_modules/
|
||||
|
||||
# Version control
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# GitHub / CI metadata
|
||||
.github/
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
*.env
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# IDE / editor settings
|
||||
.vscode/
|
||||
.idea/
|
||||
.zed/
|
||||
*.iml
|
||||
|
||||
# OS / editor junk
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# AI
|
||||
.claude/
|
||||
.cursor/
|
||||
|
||||
# testing
|
||||
tests/
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Build Docker Container
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
PUBLISH:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
IMAGE_VERSION_TAG:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {} # purposefully empty by default at workflow level, explicitly overridden for specific jobs below
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
docker-build:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
name: Build Docker image
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # to be able to push images to ghcr.io. As permissions is static, it has to be granted even if PUBLISH is false
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- name: Login to Helm Chart & Container Image Registry
|
||||
if: ${{ inputs.PUBLISH == true }}
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ github.token }}
|
||||
- name: Setup Docker Builder
|
||||
uses: useblacksmith/setup-docker-builder@affa10db466676f3dfb3e54caeb228ee0691510f
|
||||
- name: Build and push
|
||||
uses: useblacksmith/build-push-action@30c71162f16ea2c27c3e21523255d209b8b538c1
|
||||
with:
|
||||
push: ${{ inputs.PUBLISH }}
|
||||
tags: ghcr.io/specklesystems/speckle-dui:${{ inputs.IMAGE_VERSION_TAG }}
|
||||
file: ./deployment/docker/Dockerfile
|
||||
network: host # to be able to connect to Tailscale and pull private base image during build
|
||||
allow: network.host # to be able to connect to Tailscale and pull private base image during build
|
||||
@@ -0,0 +1,63 @@
|
||||
name: Get Version
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
IMAGE_VERSION_TAG:
|
||||
description: 'The image version tag under which the Helm chart and docker image should be published'
|
||||
value: ${{ jobs.get-version.outputs.VERSION }}
|
||||
|
||||
permissions: {} # purposefully empty by default at workflow level, explicitly overridden for specific jobs below
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-get-version-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
outputs:
|
||||
VERSION: ${{ steps.get-version.outputs.VERSION }}
|
||||
name: Get Version
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
sparse-checkout: ''
|
||||
fetch-depth: 1
|
||||
fetch-tags: 1
|
||||
persist-credentials: true # zizmor: ignore[artipacked] need to fetch tags in the next step and this ensures that git is configured & authenticated
|
||||
- run: git fetch origin 'refs/tags/*:refs/tags/*'
|
||||
- name: Get version tag
|
||||
id: get-version
|
||||
run: |
|
||||
VERSION=""
|
||||
if [[ "${GITHUB_REF_NAME}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
VERSION="${GITHUB_REF_NAME}"
|
||||
echo "VERSION=${VERSION}" >> ${GITHUB_OUTPUT}
|
||||
echo "${VERSION} is a valid semver, we shall use it. Exiting"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LAST_RELEASE="$(git describe --always --tags $(git rev-list --tags --max-count=1) | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true)" # get the last release tag. FIXME: Fails if a commit is tagged with more than one tag: https://stackoverflow.com/questions/8089002/git-describe-with-two-tags-on-the-same-commit/56039163#56039163
|
||||
LAST_RELEASE="${LAST_RELEASE:-0.0.0}"
|
||||
NEXT_RELEASE="$(echo "${LAST_RELEASE}" | awk -F. -v OFS=. '{$NF += 1 ; print}')"
|
||||
|
||||
if [[ "${GITHUB_REF_NAME}" == "main" ]]; then
|
||||
VERSION="${NEXT_RELEASE}-alpha.${GITHUB_RUN_NUMBER}"
|
||||
echo "VERSION=${VERSION}" >> ${GITHUB_OUTPUT}
|
||||
echo "${VERSION} will be an alpha version. Exiting"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
BRANCH_NAME_TRUNCATED="$(echo "${GITHUB_REF_NAME}" | cut -c -28 | sed 's/[^a-zA-Z0-9.-]/-/g')" # docker has a 128 character tag limit, so ensuring the branch name will be short enough
|
||||
|
||||
PADDED_RUN_NUMBER="$(printf "%06d" "${GITHUB_RUN_NUMBER}")"
|
||||
COMMIT_SHA1_TRUNCATED="$(echo "${GITHUB_SHA}" | cut -c -7)"
|
||||
|
||||
VERSION="${NEXT_RELEASE}-branch.${BRANCH_NAME_TRUNCATED}.${PADDED_RUN_NUMBER}-${COMMIT_SHA1_TRUNCATED}"
|
||||
echo "VERSION=${VERSION}" >> ${GITHUB_OUTPUT}
|
||||
echo "${VERSION} will be a branch build version. Exiting"
|
||||
exit 0
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
workflow_call: {}
|
||||
|
||||
permissions: {} # purposefully empty by default at workflow level, explicitly overridden for specific jobs below
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-lint-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
|
||||
with:
|
||||
node-version: '22.14.0'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run Linter
|
||||
run: yarn lint
|
||||
+30
-35
@@ -1,44 +1,39 @@
|
||||
name: Linting
|
||||
name: Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true # other running workflows get cancelled on the same branch
|
||||
|
||||
permissions: {} # purposefully empty by default at workflow level, explicitly overridden for specific jobs below
|
||||
|
||||
jobs:
|
||||
lint-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
get-version:
|
||||
uses: ./.github/workflows/get-version.yml
|
||||
with: {}
|
||||
secrets: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
lint:
|
||||
uses: ./.github/workflows/lint.yml
|
||||
with: {}
|
||||
secrets: {}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22.14.0'
|
||||
|
||||
- name: Enable Corepack and Install Correct Yarn Version
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare yarn@$(jq -r .packageManager package.json | cut -d'@' -f2) --activate
|
||||
yarn --version
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
**/node_modules
|
||||
.yarn/cache
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run Linter
|
||||
run: yarn lint
|
||||
|
||||
- name: Run generate
|
||||
run: yarn generate
|
||||
build:
|
||||
needs:
|
||||
- get-version
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
PUBLISH: false
|
||||
IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }}
|
||||
secrets: {}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # to be able to push images to ghcr.io, even if PUBLISH is false, as permissions is static at workflow level
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- '[0-9]+.[0-9]+.[0-9]+'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true # other running workflows get cancelled on the same branch
|
||||
|
||||
permissions: {} # purposefully empty by default at workflow level, explicitly overridden for specific jobs below
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
uses: ./.github/workflows/get-version.yml
|
||||
with: {}
|
||||
secrets: {}
|
||||
permissions:
|
||||
contents: read
|
||||
lint:
|
||||
uses: ./.github/workflows/lint.yml
|
||||
with: {}
|
||||
secrets: {}
|
||||
permissions:
|
||||
contents: read
|
||||
build:
|
||||
uses: ./.github/workflows/build.yml
|
||||
needs:
|
||||
- get-version
|
||||
- lint
|
||||
with:
|
||||
PUBLISH: true
|
||||
IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }}
|
||||
secrets: {}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # to be able to push images to ghcr.io
|
||||
+5
-1
@@ -32,4 +32,8 @@ venv
|
||||
|
||||
storybook-static
|
||||
.tshy
|
||||
.tshy-build
|
||||
.tshy-build
|
||||
|
||||
# Helm
|
||||
deployment/helm
|
||||
tests/deployment
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
dist/
|
||||
@@ -74,7 +74,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="projectIsAccesible && !projectIsAccesible"
|
||||
v-if="projectIsAccesible === false"
|
||||
class="px-2 py-4 bg-foundation dark:bg-neutral-700/10 rounded-md shadow"
|
||||
>
|
||||
<CommonAlert
|
||||
@@ -145,10 +145,25 @@ const projectNavigatorTippy = computed(() =>
|
||||
|
||||
const clientId = projectAccount.value.accountInfo.id
|
||||
|
||||
const { result: projectDetailsResult, refetch: refetchProjectDetails } = useQuery(
|
||||
const accountExists = accountStore.isAccountExistsById(props.project.accountId)
|
||||
|
||||
if (!accountExists) {
|
||||
projectIsAccesible.value = false
|
||||
}
|
||||
|
||||
const {
|
||||
result: projectDetailsResult,
|
||||
refetch: refetchProjectDetails,
|
||||
onError: onProjectDetailsError
|
||||
} = useQuery(
|
||||
projectDetailsQuery,
|
||||
() => ({ projectId: props.project.projectId }),
|
||||
() => ({ clientId, debounce: 500, fetchPolicy: 'network-only' })
|
||||
() => ({
|
||||
clientId,
|
||||
debounce: 500,
|
||||
fetchPolicy: 'network-only',
|
||||
enabled: accountExists
|
||||
})
|
||||
)
|
||||
|
||||
const removeProjectModels = async () => {
|
||||
@@ -162,6 +177,10 @@ watch(projectDetails, (newValue) => {
|
||||
projectIsAccesible.value = newValue !== undefined
|
||||
})
|
||||
|
||||
onProjectDetailsError(() => {
|
||||
projectIsAccesible.value = false
|
||||
})
|
||||
|
||||
const canLoad = computed(() => !!projectDetails.value?.permissions.canLoad.authorized)
|
||||
const canPublish = computed(
|
||||
() => !!projectDetails.value?.permissions.canPublish.authorized
|
||||
@@ -194,13 +213,13 @@ const isWorkspaceReadOnly = computed(() => {
|
||||
const { onResult: userProjectsUpdated } = useSubscription(
|
||||
userProjectsUpdatedSubscription,
|
||||
() => ({}),
|
||||
() => ({ clientId })
|
||||
() => ({ clientId, enabled: accountExists })
|
||||
)
|
||||
|
||||
const { onResult: projectUpdated } = useSubscription(
|
||||
projectUpdatedSubscription,
|
||||
() => ({ projectId: props.project.projectId }),
|
||||
() => ({ clientId })
|
||||
() => ({ clientId, enabled: accountExists })
|
||||
)
|
||||
|
||||
// to catch changes on visibility of project
|
||||
@@ -236,7 +255,7 @@ const workspaceUrl = computed(() => {
|
||||
const { onResult } = useSubscription(
|
||||
versionCreatedSubscription,
|
||||
() => ({ projectId: props.project.projectId }),
|
||||
() => ({ clientId })
|
||||
() => ({ clientId, enabled: accountExists })
|
||||
)
|
||||
|
||||
onResult((res) => {
|
||||
|
||||
@@ -160,10 +160,11 @@ const isDisableCacheSupported = computed(() => {
|
||||
if (nonSharpApps.includes(appName.toLowerCase())) return false
|
||||
|
||||
// always show in dev environments
|
||||
if (version.includes('dev') || version.includes('local')) return true
|
||||
if (version.includes('dev') || version.includes('local') || version.includes('1.0.0'))
|
||||
return true
|
||||
|
||||
// for sharp connectors, check if version is >= 3.18.0
|
||||
const targetVersion = '3.18.0'
|
||||
const targetVersion = '3.19.0'
|
||||
return (
|
||||
version.localeCompare(targetVersion, undefined, {
|
||||
numeric: true,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM node:22-bookworm@sha256:7e791fc54bd02fc89fd4fb39eb37e5bea753c75679c8022478d81679367d995a AS build-stage
|
||||
WORKDIR /app
|
||||
RUN corepack enable
|
||||
COPY package.json .
|
||||
COPY yarn.lock .
|
||||
COPY .yarnrc.yml .
|
||||
RUN yarn install --immutable || (cat /tmp/xfs-*/build.log && exit 1)
|
||||
COPY . .
|
||||
# NODE_ENV must be set after the dependencies are installed because @nuxt/kit is a devDependency and is required to build the application
|
||||
ARG NODE_ENV=production
|
||||
ENV NODE_ENV=${NODE_ENV}
|
||||
ENV NUXT_PUBLIC_MIXPANEL_TOKEN_ID=acd87c5a50b56df91a795e999812a3a4
|
||||
ENV NUXT_PUBLIC_MIXPANEL_API_HOST=https://analytics.speckle.systems
|
||||
RUN yarn generate
|
||||
|
||||
FROM joseluisq/static-web-server:2.40@sha256:63528bfba5d86b00572e23b4e44ed0f7a791f931df650125156d0c24f7a8f877 AS production-stage
|
||||
WORKDIR /app
|
||||
COPY --from=build-stage /app/dist /app/dist
|
||||
CMD ["--config-file", "/app/configuration.toml"]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: v2
|
||||
name: speckle-dui-chart
|
||||
description: A Helm chart for deploying the Speckle DUI3 application
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "0.1.0"
|
||||
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "speckle-dui.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "speckle-dui.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "speckle-dui.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "speckle-dui.labels" -}}
|
||||
helm.sh/chart: {{ include "speckle-dui.chart" . }}
|
||||
{{ include "speckle-dui.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "speckle-dui.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "speckle-dui.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "speckle-dui.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "speckle-dui.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,122 @@
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ include "speckle-dui.fullname" . }}-configuration
|
||||
labels:
|
||||
{{- include "speckle-dui.labels" . | nindent 4 }}
|
||||
data:
|
||||
configuration.toml: |
|
||||
[general]
|
||||
|
||||
#### Address & Root dir
|
||||
host = "::"
|
||||
port = 80
|
||||
root = "/app/dist"
|
||||
|
||||
#### Logging
|
||||
log-level = "info"
|
||||
|
||||
#### Cache Control headers
|
||||
cache-control-headers = true
|
||||
|
||||
#### Auto Compression
|
||||
compression = true
|
||||
compression-level = "default"
|
||||
|
||||
#### Error pages
|
||||
# Note: If a relative path is used then it will be resolved under the root directory.
|
||||
page404 = "./404.html"
|
||||
page50x = "./50x.html"
|
||||
|
||||
#### HTTP/2 + TLS
|
||||
# Note: We expect TLS termination to be handled by a reverse proxy (e.g. Nginx, Traefik, Cloudflare, etc.)
|
||||
http2 = false
|
||||
http2-tls-cert = ""
|
||||
http2-tls-key = ""
|
||||
## we are terminating https upstream; redirect is at edge proxy (ingress/gateway)
|
||||
https-redirect = false
|
||||
https-redirect-host = "localhost"
|
||||
https-redirect-from-port = 80
|
||||
https-redirect-from-hosts = "localhost"
|
||||
|
||||
#### CORS & Security headers
|
||||
## security-headers must be disabled for iframe compatibility as they include x-frame-options: deny as default
|
||||
# security-headers = false
|
||||
## cors-allows-origins is unset as iframe embedding does not require CORS, we are not fetching from another origin via XHR/fetch, and wildcard increases attack surface.
|
||||
# cors-allow-origins = ""
|
||||
|
||||
#### Directory listing
|
||||
directory-listing = false
|
||||
|
||||
#### Directory listing sorting code
|
||||
directory-listing-order = 1
|
||||
|
||||
#### Directory listing content format
|
||||
directory-listing-format = "html"
|
||||
|
||||
#### Directory listing download format
|
||||
directory-listing-download = []
|
||||
|
||||
#### File descriptor binding
|
||||
# fd = ""
|
||||
|
||||
#### Worker threads
|
||||
threads-multiplier = 1
|
||||
|
||||
#### Grace period after a graceful shutdown
|
||||
grace-period = 0
|
||||
|
||||
#### Page fallback for 404s
|
||||
# page-fallback = ""
|
||||
|
||||
#### Log request Remote Address if available
|
||||
log-remote-address = true
|
||||
|
||||
#### Log real IP from X-Forwarded-For header if available
|
||||
log-forwarded-for = true
|
||||
|
||||
#### IPs to accept the X-Forwarded-For header from. Empty means all
|
||||
trusted-proxies = {{ .Values.security.trustedProxies | toJson }}
|
||||
|
||||
#### Redirect to trailing slash in the requested directory uri
|
||||
redirect-trailing-slash = true
|
||||
|
||||
#### Check for existing pre-compressed files
|
||||
compression-static = true
|
||||
|
||||
#### Health-check endpoint (GET or HEAD `/health`)
|
||||
health = true
|
||||
|
||||
#### Markdown content negotiation
|
||||
accept-markdown = false
|
||||
|
||||
#### Maintenance Mode
|
||||
|
||||
maintenance-mode = false
|
||||
# maintenance-mode-status = 503
|
||||
# maintenance-mode-file = "./maintenance.html"
|
||||
|
||||
[advanced]
|
||||
|
||||
#### HTTP Headers customization
|
||||
[[advanced.headers]]
|
||||
source = "/*.html"
|
||||
[advanced.headers.headers]
|
||||
# Cache-Control = "public, max-age=36000"
|
||||
Content-Security-Policy = """\
|
||||
frame-ancestors {{ if .Values.security.frameAncestors }}{{ .Values.security.frameAncestors | join " " }}{{ else }}'self'{{ end }}; \
|
||||
default-src 'self'; \
|
||||
frame-src {{ if .Values.security.frameSource }}{{ .Values.security.frameSource | join " " }}{{ else }}'self'{{ end }}; \
|
||||
script-src {{ if .Values.security.frameSource }}{{ .Values.security.frameSource | join " " }}{{ else }}'self'{{ end }} 'unsafe-inline'; \
|
||||
style-src {{ if .Values.security.frameSource }}{{ .Values.security.frameSource | join " " }}{{ else }}'self'{{ end }} 'unsafe-inline'; \
|
||||
img-src {{ if .Values.security.frameSource }}{{ .Values.security.frameSource | join " " }}{{ else }}'self'{{ end }} data: blob:; \
|
||||
connect-src {{ if .Values.security.frameAncestors }}{{ .Values.security.frameAncestors | join " " }}{{ else }}'self'{{ end }}; \
|
||||
object-src 'none'; \
|
||||
base-uri 'self'; \
|
||||
form-action {{ if .Values.security.frameAncestors }}{{ .Values.security.frameAncestors | join " " }}{{ else }}'self'{{ end }};\
|
||||
"""
|
||||
# Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload"
|
||||
X-Content-Type-Options = "nosniff"
|
||||
Referrer-Policy = "strict-origin-when-cross-origin"
|
||||
Permissions-Policy = "geolocation=(), microphone=(), camera=()"
|
||||
## Purposefully do not set X-Frame-Options as this is intended to be an iframe
|
||||
@@ -0,0 +1,84 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "speckle-dui.fullname" . }}
|
||||
labels:
|
||||
{{- include "speckle-dui.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "speckle-dui.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "speckle-dui.labels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "speckle-dui.serviceAccountName" . }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- with .Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
{{- with .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80 # Needs to match port defined in deployment/docker/configuration.toml
|
||||
protocol: TCP
|
||||
{{- with .Values.livenessProbe }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.readinessProbe }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: configuration
|
||||
mountPath: /app/configuration.toml
|
||||
subPath: configuration.toml
|
||||
readOnly: true
|
||||
{{- with .Values.volumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: configuration
|
||||
configMap:
|
||||
name: {{ include "speckle-dui.fullname" . }}-configuration
|
||||
{{- with .Values.volumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,38 @@
|
||||
{{- if .Values.httpRoute.enabled -}}
|
||||
{{- $fullName := include "speckle-dui.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "speckle-dui.labels" . | nindent 4 }}
|
||||
{{- with .Values.httpRoute.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
parentRefs:
|
||||
{{- with .Values.httpRoute.parentRefs }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.httpRoute.hostnames }}
|
||||
hostnames:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.httpRoute.rules }}
|
||||
- backendRefs:
|
||||
- name: {{ $fullName }}
|
||||
port: {{ $svcPort }}
|
||||
weight: 1
|
||||
{{- with .filters }}
|
||||
filters:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .matches }}
|
||||
matches:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "speckle-dui.fullname" . }}
|
||||
labels:
|
||||
{{- include "speckle-dui.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.ingress.className }}
|
||||
ingressClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- with .pathType }}
|
||||
pathType: {{ . }}
|
||||
{{- end }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "speckle-dui.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "speckle-dui.fullname" . }}
|
||||
labels: {{- include "speckle-dui.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector: {{- include "speckle-dui.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "speckle-dui.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "speckle-dui.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,150 @@
|
||||
# Default values for speckle-dui3.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
|
||||
replicaCount: 1
|
||||
|
||||
# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
|
||||
image:
|
||||
repository: ghcr.io/specklesystems/speckle-dui
|
||||
# This sets the pull policy for images.
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
imagePullSecrets: []
|
||||
# This is to override the chart name.
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created.
|
||||
create: true
|
||||
# Automatically mount a ServiceAccount's API credentials?
|
||||
automount: false
|
||||
# Annotations to add to the service account.
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template.
|
||||
name: ""
|
||||
|
||||
# This is for setting Kubernetes Annotations to a Pod.
|
||||
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
|
||||
podAnnotations: {}
|
||||
# This is for setting Kubernetes Labels to a Pod.
|
||||
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
|
||||
service:
|
||||
# This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
|
||||
type: ClusterIP
|
||||
# This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
|
||||
port: 80
|
||||
|
||||
security:
|
||||
## The IP addresses of trusted proxies, such as loadbalancers or WAFs, that may be forwarding traffic to the dashboards. This is important for correctly handling the X-Forwarded-For header and ensuring accurate client IP logging and security measures. Empty means all proxies are trusted, which may not be secure in production environments. We recommend setting this to the specific IP addresses of your trusted proxies.
|
||||
trustedProxies: []
|
||||
## A list of urls to be added as frame-ancestors of the Content-Security-Policy header. Empty means 'self', allowing embedding only from the same origin as the dashboards. We recommend setting this to the specific hostnames of your parent applications that will be embedding the dashboards in iframes.
|
||||
frameAncestors: []
|
||||
## A list of urls to be added as frame-src (and script-src, style-src, img-src) of the Content-Security-Policy header. Empty means 'self', allowing embedding of dashboards resources only from the same origin. We recommend setting this to the specific hostnames of Speckle DUI3.
|
||||
frameSource: []
|
||||
|
||||
# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
# As dashboards expect to serve all paths under the root, we recommend using a dedicated hostname for the service, e.g. dashboards.example.com, and not sharing it with other services.
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
# Please retain this path, the dashboards expect to serve all paths under the root.
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
# -- Expose the service via gateway-api HTTPRoute
|
||||
# Requires Gateway API resources and suitable controller installed within the cluster
|
||||
# (see: https://gateway-api.sigs.k8s.io/guides/)
|
||||
httpRoute:
|
||||
# HTTPRoute enabled.
|
||||
enabled: false
|
||||
# HTTPRoute annotations.
|
||||
annotations: {}
|
||||
# Which Gateways this Route is attached to.
|
||||
parentRefs:
|
||||
- name: gateway
|
||||
sectionName: http
|
||||
# namespace: default
|
||||
# Hostnames matching HTTP header.
|
||||
hostnames:
|
||||
# As dashboards expect to serve all paths under the root, we recommend using a dedicated hostname for the service, e.g. dashboards.example.com, and not sharing it with other services.
|
||||
- chart-example.local
|
||||
# List of rules and filters applied.
|
||||
rules:
|
||||
- matches:
|
||||
# Please retain this path, the dashboards expect to serve all paths under the root.
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
|
||||
# Additional volumes on the output Deployment definition.
|
||||
volumes: []
|
||||
# - name: foo
|
||||
# secret:
|
||||
# secretName: mysecret
|
||||
# optional: false
|
||||
|
||||
# Additional volumeMounts on the output Deployment definition.
|
||||
volumeMounts: []
|
||||
# - name: foo
|
||||
# mountPath: "/etc/foo"
|
||||
# readOnly: true
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
+478
-134
@@ -569,7 +569,6 @@ export type AutomateAuthCodePayloadTest = {
|
||||
action: Scalars['String']['input'];
|
||||
code: Scalars['String']['input'];
|
||||
userId: Scalars['String']['input'];
|
||||
workspaceId?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
/** Additional resources to validate user access to. */
|
||||
@@ -874,7 +873,7 @@ export type BlobMetadata = {
|
||||
streamId: Scalars['String']['output'];
|
||||
uploadError?: Maybe<Scalars['String']['output']>;
|
||||
uploadStatus: Scalars['Int']['output'];
|
||||
userId: Scalars['String']['output'];
|
||||
userId?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type BlobMetadataCollection = {
|
||||
@@ -1269,6 +1268,14 @@ export type CreateEmbedTokenReturn = {
|
||||
tokenMetadata: EmbedToken;
|
||||
};
|
||||
|
||||
export type CreateFromTemplateInput = {
|
||||
modelIds: Array<Scalars['String']['input']>;
|
||||
/** Override the template's name for this insight */
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
projectId: Scalars['String']['input'];
|
||||
templateId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type CreateIssueInput = {
|
||||
assigneeId?: InputMaybe<Scalars['ID']['input']>;
|
||||
attachmentBlobIds?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||
@@ -1530,6 +1537,17 @@ export type DashboardUpdateInput = {
|
||||
state?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
export type DataSourceColumn = {
|
||||
__typename?: 'DataSourceColumn';
|
||||
name: Scalars['String']['output'];
|
||||
type: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type DataSourceRefInput = {
|
||||
alias: Scalars['String']['input'];
|
||||
dataSourceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type DateIntervalFilter = {
|
||||
after?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
before?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
@@ -1625,6 +1643,26 @@ export type EmbedTokenCreateInput = {
|
||||
resourceIdString: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type ExecuteQueryInput = {
|
||||
dataSources?: InputMaybe<Array<DataSourceRefInput>>;
|
||||
modelIds: Array<Scalars['String']['input']>;
|
||||
projectId: Scalars['String']['input'];
|
||||
query: Scalars['JSONObject']['input'];
|
||||
};
|
||||
|
||||
export type ExecuteQueryResult = {
|
||||
__typename?: 'ExecuteQueryResult';
|
||||
aggregate: ModelExecutionResult;
|
||||
perModel: Array<ModelExecutionResult>;
|
||||
};
|
||||
|
||||
export type ExecuteVersionQueryInput = {
|
||||
modelId: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
query: Scalars['JSONObject']['input'];
|
||||
versionId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type ExtendedViewerResources = {
|
||||
__typename?: 'ExtendedViewerResources';
|
||||
/** The groups of viewer resources themselves */
|
||||
@@ -1646,6 +1684,19 @@ export type ExtendedViewerResourcesRequest = {
|
||||
savedViewId?: Maybe<Scalars['ID']['output']>;
|
||||
};
|
||||
|
||||
export type ExternalDataSource = {
|
||||
__typename?: 'ExternalDataSource';
|
||||
columns: Array<DataSourceColumn>;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
filename: Scalars['String']['output'];
|
||||
id: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
projectId?: Maybe<Scalars['String']['output']>;
|
||||
rowCount: Scalars['Int']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
workspaceId: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type FileImportResultInput = {
|
||||
/** Duration of the file download before parsing started in seconds */
|
||||
downloadDurationSeconds: Scalars['Float']['input'];
|
||||
@@ -1812,6 +1863,277 @@ export type IngestionHistoryInput = {
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
};
|
||||
|
||||
export type Insight = {
|
||||
__typename?: 'Insight';
|
||||
/**
|
||||
* Aggregate results across all tracked models (newest first).
|
||||
* Use limit=1 for KPI badge.
|
||||
*/
|
||||
aggregateResults: Array<InsightResult>;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
createdBy: Scalars['String']['output'];
|
||||
customized: Scalars['Boolean']['output'];
|
||||
dataSources: Array<InsightDataSourceLink>;
|
||||
/** Version history (previous snapshots) */
|
||||
history: Array<InsightVersion>;
|
||||
id: Scalars['String']['output'];
|
||||
/** Latest result per model (excludes aggregate) */
|
||||
latestResults: Array<InsightResult>;
|
||||
metadata: Scalars['JSONObject']['output'];
|
||||
modelIds: Array<Scalars['String']['output']>;
|
||||
/** Historical results for a specific model (newest first) */
|
||||
modelResults: Array<InsightResult>;
|
||||
name: Scalars['String']['output'];
|
||||
projectId: Scalars['String']['output'];
|
||||
query: Scalars['JSONObject']['output'];
|
||||
/** The template this insight was created from (null if ad-hoc or template deleted) */
|
||||
template?: Maybe<InsightTemplate>;
|
||||
/** Which template version was snapshotted at creation/last sync */
|
||||
templateVersion?: Maybe<Scalars['Int']['output']>;
|
||||
trigger: Scalars['String']['output'];
|
||||
type: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
updatedBy?: Maybe<Scalars['String']['output']>;
|
||||
version: Scalars['Int']['output'];
|
||||
/** Stored results for a specific version */
|
||||
versionResults: Array<InsightResult>;
|
||||
};
|
||||
|
||||
|
||||
export type InsightAggregateResultsArgs = {
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type InsightModelResultsArgs = {
|
||||
limit?: InputMaybe<Scalars['Int']['input']>;
|
||||
modelId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightVersionResultsArgs = {
|
||||
modelId: Scalars['String']['input'];
|
||||
versionId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type InsightCreateInput = {
|
||||
metadata?: InputMaybe<Scalars['JSONObject']['input']>;
|
||||
modelIds?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||
name: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
query: Scalars['JSONObject']['input'];
|
||||
trigger?: InputMaybe<Scalars['String']['input']>;
|
||||
type?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
export type InsightDataSourceLink = {
|
||||
__typename?: 'InsightDataSourceLink';
|
||||
alias: Scalars['String']['output'];
|
||||
dataSource?: Maybe<ExternalDataSource>;
|
||||
dataSourceId: Scalars['String']['output'];
|
||||
insightId: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type InsightMutations = {
|
||||
__typename?: 'InsightMutations';
|
||||
addModels: Insight;
|
||||
create: Insight;
|
||||
/** Create an insight by snapshotting a workspace template */
|
||||
createFromTemplate: Insight;
|
||||
delete: Scalars['Boolean']['output'];
|
||||
/** Execute a query ad-hoc against selected models (preview, no persistence) */
|
||||
executeQuery: ExecuteQueryResult;
|
||||
/** Execute a query against a single specific version of a model */
|
||||
executeVersionQuery: VersionQueryResult;
|
||||
linkDataSource: Scalars['Boolean']['output'];
|
||||
removeModel: Insight;
|
||||
/** Reset a customized insight back to its template's latest version */
|
||||
resetToTemplate: Insight;
|
||||
/** Rollback an insight to a previous version */
|
||||
rollbackInsight: Insight;
|
||||
update: Insight;
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsAddModelsArgs = {
|
||||
insightId: Scalars['String']['input'];
|
||||
modelIds: Array<Scalars['String']['input']>;
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsCreateArgs = {
|
||||
input: InsightCreateInput;
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsCreateFromTemplateArgs = {
|
||||
input: CreateFromTemplateInput;
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsDeleteArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsExecuteQueryArgs = {
|
||||
input: ExecuteQueryInput;
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsExecuteVersionQueryArgs = {
|
||||
input: ExecuteVersionQueryInput;
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsLinkDataSourceArgs = {
|
||||
alias: Scalars['String']['input'];
|
||||
dataSourceId: Scalars['String']['input'];
|
||||
insightId: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsRemoveModelArgs = {
|
||||
insightId: Scalars['String']['input'];
|
||||
modelId: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsResetToTemplateArgs = {
|
||||
insightId: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsRollbackInsightArgs = {
|
||||
insightId: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
toVersion: Scalars['Int']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightMutationsUpdateArgs = {
|
||||
input: InsightUpdateInput;
|
||||
};
|
||||
|
||||
export type InsightResult = {
|
||||
__typename?: 'InsightResult';
|
||||
id: Scalars['String']['output'];
|
||||
insightId: Scalars['String']['output'];
|
||||
modelId?: Maybe<Scalars['String']['output']>;
|
||||
result: Scalars['JSONObject']['output'];
|
||||
summary: Scalars['JSONObject']['output'];
|
||||
timestamp: Scalars['DateTime']['output'];
|
||||
versionId?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type InsightTemplate = {
|
||||
__typename?: 'InsightTemplate';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
createdBy: Scalars['String']['output'];
|
||||
description?: Maybe<Scalars['String']['output']>;
|
||||
/** Version history (previous snapshots) */
|
||||
history: Array<InsightTemplateVersion>;
|
||||
id: Scalars['String']['output'];
|
||||
metadata: Scalars['JSONObject']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
query: Scalars['JSONObject']['output'];
|
||||
type: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
updatedBy: Scalars['String']['output'];
|
||||
version: Scalars['Int']['output'];
|
||||
workspaceId: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
export type InsightTemplateCreateInput = {
|
||||
description?: InputMaybe<Scalars['String']['input']>;
|
||||
metadata?: InputMaybe<Scalars['JSONObject']['input']>;
|
||||
name: Scalars['String']['input'];
|
||||
query: Scalars['JSONObject']['input'];
|
||||
type: Scalars['String']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type InsightTemplateMutations = {
|
||||
__typename?: 'InsightTemplateMutations';
|
||||
create: InsightTemplate;
|
||||
delete: Scalars['Boolean']['output'];
|
||||
rollback: InsightTemplate;
|
||||
update: InsightTemplate;
|
||||
};
|
||||
|
||||
|
||||
export type InsightTemplateMutationsCreateArgs = {
|
||||
input: InsightTemplateCreateInput;
|
||||
};
|
||||
|
||||
|
||||
export type InsightTemplateMutationsDeleteArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightTemplateMutationsRollbackArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
toVersion: Scalars['Int']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type InsightTemplateMutationsUpdateArgs = {
|
||||
input: InsightTemplateUpdateInput;
|
||||
};
|
||||
|
||||
export type InsightTemplateUpdateInput = {
|
||||
description?: InputMaybe<Scalars['String']['input']>;
|
||||
id: Scalars['String']['input'];
|
||||
metadata?: InputMaybe<Scalars['JSONObject']['input']>;
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
/** If true, propagate changes to all non-customized insights using this template */
|
||||
propagateToInsights?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
query?: InputMaybe<Scalars['JSONObject']['input']>;
|
||||
type?: InputMaybe<Scalars['String']['input']>;
|
||||
workspaceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type InsightTemplateVersion = {
|
||||
__typename?: 'InsightTemplateVersion';
|
||||
metadata: Scalars['JSONObject']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
query: Scalars['JSONObject']['output'];
|
||||
type: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
updatedBy: Scalars['String']['output'];
|
||||
version: Scalars['Int']['output'];
|
||||
};
|
||||
|
||||
export type InsightUpdateInput = {
|
||||
id: Scalars['String']['input'];
|
||||
metadata?: InputMaybe<Scalars['JSONObject']['input']>;
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
projectId: Scalars['String']['input'];
|
||||
query?: InputMaybe<Scalars['JSONObject']['input']>;
|
||||
trigger?: InputMaybe<Scalars['String']['input']>;
|
||||
type?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
export type InsightVersion = {
|
||||
__typename?: 'InsightVersion';
|
||||
customized: Scalars['Boolean']['output'];
|
||||
metadata: Scalars['JSONObject']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
query: Scalars['JSONObject']['output'];
|
||||
type: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
updatedBy?: Maybe<Scalars['String']['output']>;
|
||||
version: Scalars['Int']['output'];
|
||||
};
|
||||
|
||||
export type InvitableCollaboratorsFilter = {
|
||||
search?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
@@ -2234,7 +2556,7 @@ export type LimitedWorkspace = {
|
||||
id: Scalars['ID']['output'];
|
||||
/**
|
||||
* Optional base64 encoded workspace logo image
|
||||
* @deprecated Use the `workspace.logoUrl` field instead. Will be removed after June 2025.
|
||||
* @deprecated Use the `workspace.logoUrl` field instead. Will be removed after June 2026.
|
||||
*/
|
||||
logo?: Maybe<Scalars['String']['output']>;
|
||||
/** URL for pulling the workspace logo image */
|
||||
@@ -2385,6 +2707,15 @@ export type ModelCollection = {
|
||||
totalCount: Scalars['Int']['output'];
|
||||
};
|
||||
|
||||
export type ModelExecutionResult = {
|
||||
__typename?: 'ModelExecutionResult';
|
||||
durationMs: Scalars['Int']['output'];
|
||||
modelId?: Maybe<Scalars['String']['output']>;
|
||||
result: Scalars['JSONObject']['output'];
|
||||
summary: Scalars['JSONObject']['output'];
|
||||
versionId?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type ModelIngestion = {
|
||||
__typename?: 'ModelIngestion';
|
||||
authorUser?: Maybe<LimitedUser>;
|
||||
@@ -2668,6 +2999,8 @@ export type Mutation = {
|
||||
commitsMove: Scalars['Boolean']['output'];
|
||||
dashboardMutations: DashboardMutations;
|
||||
fileUploadMutations: FileUploadMutations;
|
||||
insightMutations: InsightMutations;
|
||||
insightTemplateMutations: InsightTemplateMutations;
|
||||
/**
|
||||
* Delete a pending invite
|
||||
* Note: The required scope to invoke this is not given out to app or personal access tokens
|
||||
@@ -2710,30 +3043,8 @@ export type Mutation = {
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.create instead.
|
||||
*/
|
||||
streamCreate?: Maybe<Scalars['String']['output']>;
|
||||
/**
|
||||
* Deletes an existing stream.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.delete instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamDelete: Scalars['Boolean']['output'];
|
||||
/** @deprecated Part of the old API surface and will be removed in the future. */
|
||||
streamFavorite?: Maybe<Stream>;
|
||||
/**
|
||||
* Note: The required scope to invoke this is not given out to app or personal access tokens
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectInviteMutations.batchCreate instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamInviteBatchCreate: Scalars['Boolean']['output'];
|
||||
/**
|
||||
* Cancel a pending stream invite. Can only be invoked by a stream owner.
|
||||
* Note: The required scope to invoke this is not given out to app or personal access tokens
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectInviteMutations.cancel instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamInviteCancel: Scalars['Boolean']['output'];
|
||||
/**
|
||||
* Invite a new or registered user to the specified stream
|
||||
* Note: The required scope to invoke this is not given out to app or personal access tokens
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectInviteMutations.create instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamInviteCreate: Scalars['Boolean']['output'];
|
||||
/**
|
||||
* Accept or decline a stream invite
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectInviteMutations.use instead.
|
||||
@@ -2744,23 +3055,11 @@ export type Mutation = {
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.leave instead.
|
||||
*/
|
||||
streamLeave: Scalars['Boolean']['output'];
|
||||
/**
|
||||
* Revokes the permissions of a user on a given stream.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.updateRole instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamRevokePermission?: Maybe<Scalars['Boolean']['output']>;
|
||||
/**
|
||||
* Updates an existing stream.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.update instead.
|
||||
*/
|
||||
streamUpdate: Scalars['Boolean']['output'];
|
||||
/**
|
||||
* Update permissions of a user on a given stream.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.updateRole instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamUpdatePermission?: Maybe<Scalars['Boolean']['output']>;
|
||||
/** @deprecated Part of the old API surface and will be removed in the future. Use ProjectMutations.batchDelete instead. Field will be deleted on January 1st, 2026. */
|
||||
streamsDelete: Scalars['Boolean']['output'];
|
||||
/** Delete a user's account. */
|
||||
userDelete: Scalars['Boolean']['output'];
|
||||
userNotificationPreferencesUpdate?: Maybe<Scalars['Boolean']['output']>;
|
||||
@@ -2931,33 +3230,12 @@ export type MutationStreamCreateArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamDeleteArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamFavoriteArgs = {
|
||||
favorited: Scalars['Boolean']['input'];
|
||||
streamId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamInviteBatchCreateArgs = {
|
||||
input: Array<StreamInviteCreateInput>;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamInviteCancelArgs = {
|
||||
inviteId: Scalars['String']['input'];
|
||||
streamId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamInviteCreateArgs = {
|
||||
input: StreamInviteCreateInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamInviteUseArgs = {
|
||||
accept: Scalars['Boolean']['input'];
|
||||
streamId: Scalars['String']['input'];
|
||||
@@ -2970,26 +3248,11 @@ export type MutationStreamLeaveArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamRevokePermissionArgs = {
|
||||
permissionParams: StreamRevokePermissionInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamUpdateArgs = {
|
||||
stream: StreamUpdateInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamUpdatePermissionArgs = {
|
||||
permissionParams: StreamUpdatePermissionInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStreamsDeleteArgs = {
|
||||
ids?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUserDeleteArgs = {
|
||||
userConfirmation: UserDeleteInput;
|
||||
};
|
||||
@@ -3228,6 +3491,8 @@ export type Project = {
|
||||
allowPublicComments: Scalars['Boolean']['output'];
|
||||
/** List of allowed assignees for this issue */
|
||||
allowedIssueAssignees: IssueParticipantCollection;
|
||||
/** When the project was archived. Null if the project is active. */
|
||||
archivedAt?: Maybe<Scalars['DateTime']['output']>;
|
||||
/** Get a single automation by id. Error will be thrown if automation is not found or inaccessible. */
|
||||
automation: Automation;
|
||||
automations: AutomationCollection;
|
||||
@@ -4051,6 +4316,8 @@ export type ProjectMutations = {
|
||||
__typename?: 'ProjectMutations';
|
||||
/** Access request related mutations */
|
||||
accessRequestMutations: ProjectAccessRequestMutations;
|
||||
/** Archive an existing project. Only project owners can archive. */
|
||||
archive: Project;
|
||||
automationMutations: ProjectAutomationMutations;
|
||||
/** Batch delete projects */
|
||||
batchDelete: Scalars['Boolean']['output'];
|
||||
@@ -4071,6 +4338,8 @@ export type ProjectMutations = {
|
||||
/** @deprecated Part of the old API surface and will be removed in the future. Field will be deleted on October 1st, 2026. */
|
||||
revokeEmbedTokens: Scalars['Boolean']['output'];
|
||||
savedViewMutations: SavedViewMutations;
|
||||
/** Unarchive an archived project. Only project owners can unarchive. */
|
||||
unarchive: Project;
|
||||
/** Updates an existing project */
|
||||
update: Project;
|
||||
/** Update role for a collaborator */
|
||||
@@ -4078,6 +4347,11 @@ export type ProjectMutations = {
|
||||
};
|
||||
|
||||
|
||||
export type ProjectMutationsArchiveArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type ProjectMutationsAutomationMutationsArgs = {
|
||||
projectId: Scalars['ID']['input'];
|
||||
};
|
||||
@@ -4119,6 +4393,11 @@ export type ProjectMutationsRevokeEmbedTokensArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type ProjectMutationsUnarchiveArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type ProjectMutationsUpdateArgs = {
|
||||
update: ProjectUpdateInput;
|
||||
};
|
||||
@@ -4158,6 +4437,7 @@ export type ProjectPermissionChecks = {
|
||||
__typename?: 'ProjectPermissionChecks';
|
||||
canAccessIssuesFeature: PermissionCheckResult;
|
||||
canAccessViewerTableFeature: PermissionCheckResult;
|
||||
canArchive: PermissionCheckResult;
|
||||
canBroadcastActivity: PermissionCheckResult;
|
||||
canCreateAutomation: PermissionCheckResult;
|
||||
/** @deprecated Comments were moved to issues. Use canCreateIssue instead. This check will be removed after 01 Jun 2026. */
|
||||
@@ -4188,6 +4468,7 @@ export type ProjectPermissionChecks = {
|
||||
canRequestRender: PermissionCheckResult;
|
||||
/** @deprecated Part of the old API surface and will be removed in the future. Use canRevoke on ShareToken. Field will be deleted on October 1st, 2026. */
|
||||
canRevokeEmbedTokens: PermissionCheckResult;
|
||||
canUnarchive: PermissionCheckResult;
|
||||
canUpdate: PermissionCheckResult;
|
||||
canUpdateAllowPublicComments: PermissionCheckResult;
|
||||
canUpdateRole: PermissionCheckResult;
|
||||
@@ -4358,6 +4639,13 @@ export enum ProjectVisibility {
|
||||
Workspace = 'WORKSPACE'
|
||||
}
|
||||
|
||||
export type PropagationResult = {
|
||||
__typename?: 'PropagationResult';
|
||||
failed: Scalars['Int']['output'];
|
||||
skipped: Scalars['Int']['output'];
|
||||
updated: Scalars['Int']['output'];
|
||||
};
|
||||
|
||||
export type Query = {
|
||||
__typename?: 'Query';
|
||||
/** Stare into the void. */
|
||||
@@ -4395,6 +4683,14 @@ export type Query = {
|
||||
* @deprecated Part of the old API surface and will be removed in the future.
|
||||
*/
|
||||
discoverableStreams?: Maybe<StreamCollection>;
|
||||
/** Get a single insight by ID */
|
||||
insight?: Maybe<Insight>;
|
||||
/** Get a single insight result by ID */
|
||||
insightResult?: Maybe<InsightResult>;
|
||||
/** Get a single insight template by ID */
|
||||
insightTemplate?: Maybe<InsightTemplate>;
|
||||
/** List all insights tracking a specific model */
|
||||
modelInsights: Array<Insight>;
|
||||
/** Get the (limited) profile information of another server user */
|
||||
otherUser?: Maybe<LimitedUser>;
|
||||
permissions: RootPermissionChecks;
|
||||
@@ -4403,6 +4699,8 @@ export type Query = {
|
||||
* to see it, for example, if a project isn't public and the user doesn't have the appropriate rights.
|
||||
*/
|
||||
project: Project;
|
||||
/** List all insights for a project, optionally filtered by type */
|
||||
projectInsights: Array<Insight>;
|
||||
/**
|
||||
* Look for an invitation to a project, for the current user (authed or not). If token
|
||||
* isn't specified, the server will look for any valid invite.
|
||||
@@ -4432,11 +4730,6 @@ export type Query = {
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use Query.projectInvite instead.
|
||||
*/
|
||||
streamInvite?: Maybe<PendingStreamCollaborator>;
|
||||
/**
|
||||
* Get all invitations to streams that the active user has
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use User.projectInvites instead. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
streamInvites: Array<PendingStreamCollaborator>;
|
||||
/**
|
||||
* Returns all streams that the active user is a collaborator on.
|
||||
* Pass in the `query` parameter to search by name, description or ID.
|
||||
@@ -4467,6 +4760,8 @@ export type Query = {
|
||||
validateWorkspaceSlug: Scalars['Boolean']['output'];
|
||||
workspace: Workspace;
|
||||
workspaceBySlug: Workspace;
|
||||
/** List templates for a workspace, optionally filtered by type */
|
||||
workspaceInsightTemplates: Array<InsightTemplate>;
|
||||
/**
|
||||
* Look for an invitation to a workspace, for the current user (authed or not).
|
||||
*
|
||||
@@ -4524,6 +4819,30 @@ export type QueryDiscoverableStreamsArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryInsightArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryInsightResultArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryInsightTemplateArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
workspaceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryModelInsightsArgs = {
|
||||
modelId: Scalars['String']['input'];
|
||||
projectId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryOtherUserArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
};
|
||||
@@ -4534,6 +4853,12 @@ export type QueryProjectArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryProjectInsightsArgs = {
|
||||
projectId: Scalars['String']['input'];
|
||||
type?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryProjectInviteArgs = {
|
||||
projectId: Scalars['String']['input'];
|
||||
token?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -4628,6 +4953,12 @@ export type QueryWorkspaceBySlugArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryWorkspaceInsightTemplatesArgs = {
|
||||
type?: InputMaybe<Scalars['String']['input']>;
|
||||
workspaceId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryWorkspaceInviteArgs = {
|
||||
options?: InputMaybe<WorkspaceInviteLookupOptions>;
|
||||
token?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -5018,6 +5349,8 @@ export type ServerAutomateInfo = {
|
||||
export type ServerConfiguration = {
|
||||
__typename?: 'ServerConfiguration';
|
||||
blobSizeLimitBytes: Scalars['Int']['output'];
|
||||
/** Origin URL of the dashboards service */
|
||||
dashboardsOrigin?: Maybe<Scalars['String']['output']>;
|
||||
/** Email verification code timeout in minutes */
|
||||
emailVerificationTimeoutMinutes: Scalars['Int']['output'];
|
||||
/** Active server-level feature flags */
|
||||
@@ -5140,6 +5473,7 @@ export enum ServerRole {
|
||||
ServerAdmin = 'SERVER_ADMIN',
|
||||
ServerArchivedUser = 'SERVER_ARCHIVED_USER',
|
||||
ServerGuest = 'SERVER_GUEST',
|
||||
ServerSupport = 'SERVER_SUPPORT',
|
||||
ServerUser = 'SERVER_USER'
|
||||
}
|
||||
|
||||
@@ -5313,11 +5647,6 @@ export type StartFileImportInput = {
|
||||
|
||||
export type Stream = {
|
||||
__typename?: 'Stream';
|
||||
/**
|
||||
* All the recent activity on this stream in chronological order
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
activity?: Maybe<ActivityCollection>;
|
||||
allowPublicComments: Scalars['Boolean']['output'];
|
||||
/** @deprecated Part of the old API surface and will be removed in the future. Use Project.blob instead. */
|
||||
blob?: Maybe<BlobMetadata>;
|
||||
@@ -5390,15 +5719,6 @@ export type Stream = {
|
||||
};
|
||||
|
||||
|
||||
export type StreamActivityArgs = {
|
||||
actionType?: InputMaybe<Scalars['String']['input']>;
|
||||
after?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
before?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
cursor?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
limit?: Scalars['Int']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type StreamBlobArgs = {
|
||||
id: Scalars['String']['input'];
|
||||
};
|
||||
@@ -5490,22 +5810,6 @@ export type StreamCreateInput = {
|
||||
withContributors?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||
};
|
||||
|
||||
export type StreamInviteCreateInput = {
|
||||
email?: InputMaybe<Scalars['String']['input']>;
|
||||
message?: InputMaybe<Scalars['String']['input']>;
|
||||
/** Defaults to the contributor role, if not specified */
|
||||
role?: InputMaybe<Scalars['String']['input']>;
|
||||
/** Can only be specified if guest mode is on or if the user is an admin */
|
||||
serverRole?: InputMaybe<Scalars['String']['input']>;
|
||||
streamId: Scalars['String']['input'];
|
||||
userId?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
export type StreamRevokePermissionInput = {
|
||||
streamId: Scalars['String']['input'];
|
||||
userId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export enum StreamRole {
|
||||
StreamContributor = 'STREAM_CONTRIBUTOR',
|
||||
StreamOwner = 'STREAM_OWNER',
|
||||
@@ -5526,12 +5830,6 @@ export type StreamUpdateInput = {
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
export type StreamUpdatePermissionInput = {
|
||||
role: Scalars['String']['input'];
|
||||
streamId: Scalars['String']['input'];
|
||||
userId: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type Subscription = {
|
||||
__typename?: 'Subscription';
|
||||
/** It's lonely in the void. */
|
||||
@@ -5644,7 +5942,7 @@ export type Subscription = {
|
||||
* Track support session changes for a specific workspace.
|
||||
* Fires when sessions are requested, approved, revoked, or expire.
|
||||
*/
|
||||
workspaceSupportSessionUpdated: WorkspaceSupportSessionUpdatedMessage;
|
||||
workspaceSupportSessionUpdated?: Maybe<WorkspaceSupportSessionUpdatedMessage>;
|
||||
/**
|
||||
* Track updates to a specific workspace.
|
||||
* Either slug or id must be set.
|
||||
@@ -5998,7 +6296,7 @@ export type User = {
|
||||
/**
|
||||
* Get commits authored by the user. If requested for another user, then only commits
|
||||
* from public streams will be returned.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use User.versions instead. Field will be deleted on January 1st, 2026.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use User.versions instead.
|
||||
*/
|
||||
commits?: Maybe<CommitCollection>;
|
||||
company?: Maybe<Scalars['String']['output']>;
|
||||
@@ -6017,12 +6315,6 @@ export type User = {
|
||||
* (3) The user does not have a valid SSO session for the given SSO provider
|
||||
*/
|
||||
expiredSsoSessions: Array<LimitedWorkspace>;
|
||||
/**
|
||||
* All the streams that a active user has favorited.
|
||||
* Note: You can't use this to retrieve another user's favorite streams.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Field will be deleted on January 1st, 2026.
|
||||
*/
|
||||
favoriteStreams: StreamCollection;
|
||||
/** Whether the user has a pending/active email verification token */
|
||||
hasPendingVerification?: Maybe<Scalars['Boolean']['output']>;
|
||||
id: Scalars['ID']['output'];
|
||||
@@ -6045,7 +6337,7 @@ export type User = {
|
||||
/**
|
||||
* Returns all streams that the user is a collaborator on. If requested for a user, who isn't the
|
||||
* authenticated user, then this will only return discoverable streams.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use User.projects instead. Field will be deleted on January 1st, 2026.
|
||||
* @deprecated Part of the old API surface and will be removed in the future. Use User.projects instead.
|
||||
*/
|
||||
streams: UserStreamCollection;
|
||||
/**
|
||||
@@ -6108,16 +6400,6 @@ export type UserCommitsArgs = {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Full user type, should only be used in the context of admin operations or
|
||||
* when a user is reading/writing info about himself
|
||||
*/
|
||||
export type UserFavoriteStreamsArgs = {
|
||||
cursor?: InputMaybe<Scalars['String']['input']>;
|
||||
limit?: Scalars['Int']['input'];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Full user type, should only be used in the context of admin operations or
|
||||
* when a user is reading/writing info about himself
|
||||
@@ -6499,6 +6781,15 @@ export type VersionPermissionChecks = {
|
||||
canUpdate: PermissionCheckResult;
|
||||
};
|
||||
|
||||
export type VersionQueryResult = {
|
||||
__typename?: 'VersionQueryResult';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
durationMs: Scalars['Int']['output'];
|
||||
result: Scalars['JSONObject']['output'];
|
||||
summary: Scalars['JSONObject']['output'];
|
||||
versionId: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
/**
|
||||
* If only one is set, the other will be resolved automatically
|
||||
* If none are set, the view will be added to the end of the list
|
||||
@@ -6696,7 +6987,7 @@ export type Workspace = {
|
||||
issueLabels: IssueLabelCollection;
|
||||
/**
|
||||
* Logo image as base64-encoded string
|
||||
* @deprecated Use the `workspace.logoUrl` field instead. Will be removed after June 2025.
|
||||
* @deprecated Use the `workspace.logoUrl` field instead. Will be removed after June 2026.
|
||||
*/
|
||||
logo?: Maybe<Scalars['String']['output']>;
|
||||
/** URL for pulling the workspace logo image */
|
||||
@@ -6706,6 +6997,13 @@ export type Workspace = {
|
||||
plan?: Maybe<WorkspacePlan>;
|
||||
/** Shows the plan prices localized for the given workspace */
|
||||
planPrices?: Maybe<WorkspacePaidPlanPrices>;
|
||||
/**
|
||||
* Bulk project activity data for the workspace timeline widget.
|
||||
* Returns versions created within a date window, grouped by project.
|
||||
* First call discovers top N projects; pass the returned cursor to load older data.
|
||||
* Internal API — may change without notice.
|
||||
*/
|
||||
projectActivityTimeline?: Maybe<WorkspaceProjectActivityTimelineResult>;
|
||||
projects: ProjectCollection;
|
||||
/** A Workspace is marked as readOnly if its trial period is finished or a paid plan is subscribed but payment has failed */
|
||||
readOnly: Scalars['Boolean']['output'];
|
||||
@@ -6767,6 +7065,11 @@ export type WorkspaceIssueLabelsArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type WorkspaceProjectActivityTimelineArgs = {
|
||||
input: WorkspaceProjectActivityTimelineInput;
|
||||
};
|
||||
|
||||
|
||||
export type WorkspaceProjectsArgs = {
|
||||
cursor?: InputMaybe<Scalars['String']['input']>;
|
||||
filter?: InputMaybe<WorkspaceProjectsFilter>;
|
||||
@@ -6905,6 +7208,7 @@ export enum WorkspaceFeatureName {
|
||||
DomainDiscoverability = 'domainDiscoverability',
|
||||
EmbedPrivateProjects = 'embedPrivateProjects',
|
||||
ExclusiveMembership = 'exclusiveMembership',
|
||||
Frontend3 = 'frontend3',
|
||||
HideSpeckleBranding = 'hideSpeckleBranding',
|
||||
Issues = 'issues',
|
||||
Markup = 'markup',
|
||||
@@ -6914,6 +7218,7 @@ export enum WorkspaceFeatureName {
|
||||
Presentation = 'presentation',
|
||||
/** @deprecated Use presentation instead. Value will be dropped after July 19, 2026. */
|
||||
Presentations = 'presentations',
|
||||
ProjectArchival = 'projectArchival',
|
||||
ProjectDashboards = 'projectDashboards',
|
||||
SavedViews = 'savedViews',
|
||||
ViewerTable = 'viewerTable',
|
||||
@@ -7402,6 +7707,43 @@ export enum WorkspacePlans {
|
||||
Unlimited = 'unlimited'
|
||||
}
|
||||
|
||||
export type WorkspaceProjectActivityTimelineInput = {
|
||||
/**
|
||||
* Opaque cursor from a previous response. When provided, withProjectRoleOnly and projectLimit are ignored.
|
||||
* Encodes the locked-in project set and next date boundary.
|
||||
*/
|
||||
cursor?: InputMaybe<Scalars['String']['input']>;
|
||||
/**
|
||||
* Size of each date window in days. Default: 7.
|
||||
* Used for both discovery (now - N days) and pagination (cursor.before - N days).
|
||||
* Can change between pages — the cursor locks the project set and boundary,
|
||||
* while this controls how far back from that boundary to look.
|
||||
*/
|
||||
dateRangeDays?: InputMaybe<Scalars['Int']['input']>;
|
||||
/** Max projects to discover by updatedAt DESC. Default: 20. Ignored when cursor is provided. */
|
||||
projectLimit?: InputMaybe<Scalars['Int']['input']>;
|
||||
/**
|
||||
* Only return projects where the active user has an explicit project role.
|
||||
* Used on first call (discovery). Ignored when cursor is provided (as projects are pre-determined then).
|
||||
*/
|
||||
withProjectRoleOnly?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
};
|
||||
|
||||
export type WorkspaceProjectActivityTimelineProjectGroup = {
|
||||
__typename?: 'WorkspaceProjectActivityTimelineProjectGroup';
|
||||
project: Project;
|
||||
/** Versions within the date range, ordered by createdAt DESC. */
|
||||
versions: Array<Version>;
|
||||
};
|
||||
|
||||
export type WorkspaceProjectActivityTimelineResult = {
|
||||
__typename?: 'WorkspaceProjectActivityTimelineResult';
|
||||
/** Opaque cursor for loading older data. Null when no more data is available. */
|
||||
cursor?: Maybe<Scalars['String']['output']>;
|
||||
/** Projects with their versions, ordered by most recent version DESC. */
|
||||
projectGroups: Array<WorkspaceProjectActivityTimelineProjectGroup>;
|
||||
};
|
||||
|
||||
export type WorkspaceProjectCreateInput = {
|
||||
description?: InputMaybe<Scalars['String']['input']>;
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -7464,6 +7806,8 @@ export type WorkspaceProjectMutationsUpdateRoleArgs = {
|
||||
};
|
||||
|
||||
export type WorkspaceProjectsFilter = {
|
||||
/** Include archived projects in results. Only respected for workspace admins; silently ignored for non-admins. */
|
||||
includeArchived?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
/** Filter out projects by name */
|
||||
search?: InputMaybe<Scalars['String']['input']>;
|
||||
/** Only return workspace projects that the active user has an explicit project role in */
|
||||
|
||||
+9
-1
@@ -10,6 +10,13 @@
|
||||
"build": "nuxt build",
|
||||
"dev:nuxt": "nuxt dev",
|
||||
"dev": "concurrently \"nuxt dev\" \"yarn gqlgen:watch\"",
|
||||
"dev:kind:up": "ctlptl apply --filename ./tests/deployment/helm/cluster-config.yaml",
|
||||
"dev:kind:down": "ctlptl delete -f ./tests/deployment/helm/cluster-config.yaml",
|
||||
"dev:kind:helm:up": "yarn run dev:kind:up && tilt up --file ./tests/deployment/helm/Tiltfile --context kind-speckle-dui",
|
||||
"dev:kind:helm:down": "tilt down --file ./tests/deployment/helm/Tiltfile --context kind-speckle-dui",
|
||||
"dev:kind:helm:ci": "tilt ci --file ./tests/deployment/helm/Tiltfile --context kind-speckle-dui --timeout 10m",
|
||||
"docker:build": "docker build -f ./deployment/docker/Dockerfile -t ghcr.io/specklesystems/speckle-dui:local .",
|
||||
"docker:run": "docker run --rm -p 8083:80 -v ./deployment/docker/configuration.toml:/app/configuration.toml:ro ghcr.io/specklesystems/speckle-dui:local",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
@@ -20,7 +27,8 @@
|
||||
"lint": "yarn lint:js && yarn lint:tsc && yarn lint:prettier && yarn lint:css",
|
||||
"lint:ci": "yarn lint:tsc && yarn lint:css",
|
||||
"gqlgen": "graphql-codegen",
|
||||
"gqlgen:watch": "graphql-codegen --watch"
|
||||
"gqlgen:watch": "graphql-codegen --watch",
|
||||
"prettier:fix": "prettier --config .prettierrc --ignore-path .prettierignore --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.14",
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
print('🚀 Deploying Speckle DUI into a Kind Cluster via Tilt...')
|
||||
|
||||
# we limit tilt to run only on the kind cluster
|
||||
allow_k8s_contexts(['kind-speckle-dui'])
|
||||
if k8s_context() != 'kind-speckle-dui':
|
||||
fail('Failing early as tilt should only ever connect to kind-speckle-dui.')
|
||||
|
||||
# Install extensions
|
||||
load('ext://helm_resource', 'helm_resource', 'helm_repo')
|
||||
load('ext://k8s_yaml_glob', 'k8s_yaml_glob')
|
||||
|
||||
docker_build('ghcr.io/specklesystems/speckle-dui',
|
||||
context='../../..',
|
||||
dockerfile='../../../deployment/docker/Dockerfile',
|
||||
ignore = ['**/.nuxt', '**/node_modules', '**/dist', '**/build', '**/.git', '**/.claude', '**/.cursor', '**/deployment/**/*', '**/tests/**/*']
|
||||
)
|
||||
|
||||
# Create namespaces
|
||||
k8s_yaml_glob('./manifests/*.namespace.yaml')
|
||||
|
||||
k8s_yaml('./manifests/coredns.configmap.yaml')
|
||||
k8s_resource(new_name='coredns',
|
||||
objects=['coredns:configmap:kube-system'],
|
||||
resource_deps=[],
|
||||
labels=['coredns'])
|
||||
|
||||
# Update CoreDNS to allow for local resolution of services internally (i.e. speckle.internal will be routed to nginx)
|
||||
local_resource('coredns-up',
|
||||
cmd='./scripts/coredns-up.sh',
|
||||
resource_deps=['coredns'],
|
||||
deps=['./manifests/coredns.configmap.yaml', './scripts/coredns-up.sh'],
|
||||
labels=['coredns'])
|
||||
|
||||
helm_repo('ingress-nginx-repo',
|
||||
'https://kubernetes.github.io/ingress-nginx')
|
||||
|
||||
#nginx should be deployed as the last dependency as it opens ports to services
|
||||
#it expects these services to exist, which are created by the helm charts above
|
||||
helm_resource('ingress-nginx',
|
||||
release_name='ingress-nginx',
|
||||
namespace='ingress-nginx',
|
||||
chart='ingress-nginx-repo/ingress-nginx',
|
||||
flags=['--version=4.8.0',
|
||||
'--values=./values/nginx.values.yaml',
|
||||
'--kube-context=kind-speckle-dui'],
|
||||
deps=['./values/nginx.values.yaml'],
|
||||
resource_deps=['ingress-nginx-repo', 'coredns'],
|
||||
labels=['speckle-dependencies'])
|
||||
|
||||
helm_resource('speckle-dui',
|
||||
release_name='speckle-dui',
|
||||
namespace='speckle-dui',
|
||||
chart='./../../../deployment/helm/speckle-dui',
|
||||
flags=['--values=./values/speckle-dui.values.yaml',
|
||||
'--kube-context=kind-speckle-dui'],
|
||||
image_deps=[
|
||||
'ghcr.io/specklesystems/speckle-dui'
|
||||
],
|
||||
image_keys=[
|
||||
('image.repository', 'image.tag')
|
||||
],
|
||||
deps=['./../../../deployment/helm/speckle-dui',
|
||||
'./values/speckle-dui.values.yaml'],
|
||||
resource_deps=['ingress-nginx', 'coredns'],
|
||||
labels=['speckle-dui'])
|
||||
@@ -0,0 +1,29 @@
|
||||
apiVersion: ctlptl.dev/v1alpha1
|
||||
kind: Registry
|
||||
name: ctlptl-registry
|
||||
port: 5000
|
||||
---
|
||||
apiVersion: ctlptl.dev/v1alpha1
|
||||
kind: Cluster
|
||||
product: kind
|
||||
registry: ctlptl-registry
|
||||
name: kind-speckle-dui
|
||||
kindV1Alpha4Cluster:
|
||||
nodes:
|
||||
- role: control-plane
|
||||
kubeadmConfigPatches:
|
||||
- |
|
||||
kind: InitConfiguration
|
||||
nodeRegistration:
|
||||
kubeletExtraArgs:
|
||||
node-labels: "ingress-ready=true"
|
||||
extraMounts: []
|
||||
extraPortMappings:
|
||||
- containerPort: 80
|
||||
hostPort: 80 # Docker requires privileged ports binding permissions https://docs.docker.com/desktop/mac/permission-requirements/#binding-privileged-ports
|
||||
protocol: TCP
|
||||
listenAddress: '127.0.0.1' #DO NOT REMOVE - this is required to prevent access from the local network or the world!!!
|
||||
- containerPort: 443
|
||||
hostPort: 443 # Docker requires privileged ports binding permissions https://docs.docker.com/desktop/mac/permission-requirements/#binding-privileged-ports
|
||||
protocol: TCP
|
||||
listenAddress: '127.0.0.1' #DO NOT REMOVE - this is required to prevent access from the local network or the world!!!
|
||||
@@ -0,0 +1,24 @@
|
||||
{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/63dacb46bf939521bdc93981b4cbb7ecb58427a0.tar.gz") {} }:
|
||||
|
||||
let
|
||||
corepack = pkgs.stdenv.mkDerivation {
|
||||
name = "corepack";
|
||||
buildInputs = [ pkgs.nodejs_22 ];
|
||||
phases = [ "installPhase" ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
corepack enable --install-directory=$out/bin
|
||||
'';
|
||||
};
|
||||
in pkgs.mkShell {
|
||||
buildInputs = [
|
||||
pkgs.docker
|
||||
pkgs.kind
|
||||
pkgs.kubectl
|
||||
pkgs.nodejs_22
|
||||
pkgs.ctlptl
|
||||
pkgs.kubernetes-helm
|
||||
pkgs.tilt
|
||||
corepack
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
apiVersion: v1
|
||||
data:
|
||||
Corefile: |
|
||||
.:53 {
|
||||
errors
|
||||
health {
|
||||
lameduck 5s
|
||||
}
|
||||
ready
|
||||
rewrite name speckle.internal ingress-nginx-controller.ingress-nginx.svc.cluster.local.
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
ttl 30
|
||||
}
|
||||
prometheus :9153
|
||||
forward . /etc/resolv.conf {
|
||||
max_concurrent 1000
|
||||
}
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: coredns
|
||||
namespace: kube-system
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: 'ingress-nginx'
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: 'speckle-dui'
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
kubectl --context="kind-speckle-dui" --namespace="kube-system" rollout restart deployment/coredns
|
||||
kubectl --context="kind-speckle-dui" --namespace="kube-system" rollout status deployment "coredns" --timeout=90s
|
||||
@@ -0,0 +1,7 @@
|
||||
controller:
|
||||
# We must set the kind cluster listen address for every port to '127.0.0.1' when hostNetwork is true
|
||||
hostNetwork: true
|
||||
admissionWebhooks:
|
||||
enabled: false
|
||||
# progressDeadlineSeconds: 600 #HACK helm chart was complaining that this was less than minReadySeconds https://github.com/kubernetes/ingress-nginx/blob/c72441585e1ab1a32df86e760613d36fa804315d/charts/ingress-nginx/templates/controller-deployment.yaml#L26
|
||||
tcp: {}
|
||||
@@ -0,0 +1,16 @@
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations: {}
|
||||
hosts:
|
||||
- host: speckle.internal
|
||||
paths:
|
||||
# Please retain this path, the dashboards expect to serve all paths under the root.
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
security:
|
||||
trustedProxies: []
|
||||
frameAncestors:
|
||||
- "speckle.internal"
|
||||
frameSource:
|
||||
- "speckle.internal"
|
||||
Reference in New Issue
Block a user