Merge branch 'feature/environment-variables' of github.com:Budibase/budibase into feature/environment-variables
This commit is contained in:
commit
5646e18cb2
|
@ -6,6 +6,8 @@ labels: bug
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## Checklist
|
||||||
|
- [ ] I have searched budibase discussions and github issues to check if my issue already exists
|
||||||
|
|
||||||
**Hosting**
|
**Hosting**
|
||||||
<!-- Delete as appropriate -->
|
<!-- Delete as appropriate -->
|
||||||
|
|
|
@ -20,8 +20,8 @@ spec:
|
||||||
annotations:
|
annotations:
|
||||||
kompose.cmd: kompose convert
|
kompose.cmd: kompose convert
|
||||||
kompose.version: 1.21.0 (992df58d8)
|
kompose.version: 1.21.0 (992df58d8)
|
||||||
{{ if .Values.globals.appServiceAnnotations }}
|
{{ if .Values.services.apps.annotations }}
|
||||||
{{ toYaml .Values.globals.appServiceAnnotations | indent 4 }}
|
{{- toYaml .Values.services.apps.annotations | indent 8 -}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
labels:
|
labels:
|
||||||
|
|
|
@ -20,8 +20,8 @@ spec:
|
||||||
annotations:
|
annotations:
|
||||||
kompose.cmd: kompose convert
|
kompose.cmd: kompose convert
|
||||||
kompose.version: 1.21.0 (992df58d8)
|
kompose.version: 1.21.0 (992df58d8)
|
||||||
{{ if .Values.globals.proxyServiceAnnotations }}
|
{{ if .Values.services.proxy.annotations }}
|
||||||
{{ toYaml .Values.globals.proxyServiceAnnotations | indent 4 }}
|
{{- toYaml .Values.services.proxy.annotations | indent 8 -}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
labels:
|
labels:
|
||||||
|
|
|
@ -21,8 +21,8 @@ spec:
|
||||||
annotations:
|
annotations:
|
||||||
kompose.cmd: kompose convert
|
kompose.cmd: kompose convert
|
||||||
kompose.version: 1.21.0 (992df58d8)
|
kompose.version: 1.21.0 (992df58d8)
|
||||||
{{ if .Values.globals.workerServiceAnnotations }}
|
{{ if .Values.services.worker.annotations }}
|
||||||
{{ toYaml .Values.globals.workerServiceAnnotations | indent 4 }}
|
{{- toYaml .Values.services.worker.annotations | indent 8 -}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
labels:
|
labels:
|
||||||
|
|
|
@ -22,23 +22,6 @@ serviceAccount:
|
||||||
|
|
||||||
podAnnotations: {}
|
podAnnotations: {}
|
||||||
|
|
||||||
# appServiceAnnotations:
|
|
||||||
# co.elastic.logs/multiline.type: pattern
|
|
||||||
# co.elastic.logs/multiline.pattern: '^[[:space:]]'
|
|
||||||
# co.elastic.logs/multiline.negate: false
|
|
||||||
# co.elastic.logs/multiline.match: after
|
|
||||||
|
|
||||||
# workerServiceAnnotations:
|
|
||||||
# co.elastic.logs/multiline.type: pattern
|
|
||||||
# co.elastic.logs/multiline.pattern: '^[[:space:]]'
|
|
||||||
# co.elastic.logs/multiline.negate: false
|
|
||||||
# co.elastic.logs/multiline.match: after
|
|
||||||
|
|
||||||
# proxyServiceAnnotations:
|
|
||||||
# co.elastic.logs/module: nginx
|
|
||||||
# co.elastic.logs/fileset.stdout: access
|
|
||||||
# co.elastic.logs/fileset.stderr: error
|
|
||||||
|
|
||||||
podSecurityContext:
|
podSecurityContext:
|
||||||
{}
|
{}
|
||||||
# fsGroup: 2000
|
# fsGroup: 2000
|
||||||
|
@ -141,6 +124,10 @@ services:
|
||||||
minio: 'http://minio-service.{{ .Release.Namespace }}.svc.{{ .Values.services.dns }}:{{ .Values.services.objectStore.port }}'
|
minio: 'http://minio-service.{{ .Release.Namespace }}.svc.{{ .Values.services.dns }}:{{ .Values.services.objectStore.port }}'
|
||||||
couchdb: 'http://{{ .Release.Name }}-svc-couchdb:{{ .Values.services.couchdb.port }}'
|
couchdb: 'http://{{ .Release.Name }}-svc-couchdb:{{ .Values.services.couchdb.port }}'
|
||||||
resources: {}
|
resources: {}
|
||||||
|
# annotations:
|
||||||
|
# co.elastic.logs/module: nginx
|
||||||
|
# co.elastic.logs/fileset.stdout: access
|
||||||
|
# co.elastic.logs/fileset.stderr: error
|
||||||
|
|
||||||
apps:
|
apps:
|
||||||
port: 4002
|
port: 4002
|
||||||
|
@ -148,11 +135,20 @@ services:
|
||||||
logLevel: info
|
logLevel: info
|
||||||
resources: {}
|
resources: {}
|
||||||
# nodeDebug: "" # set the value of NODE_DEBUG
|
# nodeDebug: "" # set the value of NODE_DEBUG
|
||||||
|
# annotations:
|
||||||
|
# co.elastic.logs/multiline.type: pattern
|
||||||
|
# co.elastic.logs/multiline.pattern: '^[[:space:]]'
|
||||||
|
# co.elastic.logs/multiline.negate: false
|
||||||
|
# co.elastic.logs/multiline.match: after
|
||||||
worker:
|
worker:
|
||||||
port: 4003
|
port: 4003
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
resources: {}
|
resources: {}
|
||||||
|
# annotations:
|
||||||
|
# co.elastic.logs/multiline.type: pattern
|
||||||
|
# co.elastic.logs/multiline.pattern: '^[[:space:]]'
|
||||||
|
# co.elastic.logs/multiline.negate: false
|
||||||
|
# co.elastic.logs/multiline.match: after
|
||||||
|
|
||||||
couchdb:
|
couchdb:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -6,6 +6,9 @@ const config: Config.InitialOptions = {
|
||||||
setupFiles: ["./tests/jestSetup.ts"],
|
setupFiles: ["./tests/jestSetup.ts"],
|
||||||
collectCoverageFrom: ["src/**/*.{js,ts}"],
|
collectCoverageFrom: ["src/**/*.{js,ts}"],
|
||||||
coverageReporters: ["lcov", "json", "clover"],
|
coverageReporters: ["lcov", "json", "clover"],
|
||||||
|
transform: {
|
||||||
|
"^.+\\.ts?$": "@swc/jest",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!process.env.CI) {
|
if (!process.env.CI) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/backend-core",
|
"name": "@budibase/backend-core",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"description": "Budibase backend core libraries used in server and worker",
|
"description": "Budibase backend core libraries used in server and worker",
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
"types": "dist/src/index.d.ts",
|
"types": "dist/src/index.d.ts",
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/nano": "10.1.1",
|
"@budibase/nano": "10.1.1",
|
||||||
"@budibase/types": "2.2.12-alpha.2",
|
"@budibase/types": "2.2.12-alpha.10",
|
||||||
"@shopify/jest-koa-mocks": "5.0.1",
|
"@shopify/jest-koa-mocks": "5.0.1",
|
||||||
"@techpass/passport-openidconnect": "0.3.2",
|
"@techpass/passport-openidconnect": "0.3.2",
|
||||||
"aws-cloudfront-sign": "2.2.0",
|
"aws-cloudfront-sign": "2.2.0",
|
||||||
|
@ -56,6 +56,8 @@
|
||||||
"zlib": "1.0.5"
|
"zlib": "1.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@swc/core": "^1.3.25",
|
||||||
|
"@swc/jest": "^0.2.24",
|
||||||
"@types/chance": "1.1.3",
|
"@types/chance": "1.1.3",
|
||||||
"@types/ioredis": "4.28.0",
|
"@types/ioredis": "4.28.0",
|
||||||
"@types/jest": "27.5.1",
|
"@types/jest": "27.5.1",
|
||||||
|
|
|
@ -7,7 +7,7 @@ function generateTenantKey(key: string) {
|
||||||
return `${key}:${tenantId}`
|
return `${key}:${tenantId}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export = class BaseCache {
|
export default class BaseCache {
|
||||||
client: Client | undefined
|
client: Client | undefined
|
||||||
|
|
||||||
constructor(client: Client | undefined = undefined) {
|
constructor(client: Client | undefined = undefined) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const BaseCache = require("./base")
|
const BaseCache = require("./base")
|
||||||
|
|
||||||
const GENERIC = new BaseCache()
|
const GENERIC = new BaseCache.default()
|
||||||
|
|
||||||
export enum CacheKey {
|
export enum CacheKey {
|
||||||
CHECKLIST = "checklist",
|
CHECKLIST = "checklist",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import fetch from "node-fetch"
|
import fetch from "node-fetch"
|
||||||
|
|
||||||
export = class API {
|
export default class API {
|
||||||
host: string
|
host: string
|
||||||
|
|
||||||
constructor(host: string) {
|
constructor(host: string) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require("../../../tests")
|
require("../../../tests")
|
||||||
const context = require("../")
|
const context = require("../")
|
||||||
const { DEFAULT_TENANT_ID } = require("../../constants")
|
const { DEFAULT_TENANT_ID } = require("../../constants")
|
||||||
const env = require("../../environment")
|
import env from "../../environment"
|
||||||
|
|
||||||
describe("context", () => {
|
describe("context", () => {
|
||||||
describe("doInTenant", () => {
|
describe("doInTenant", () => {
|
||||||
|
@ -26,7 +26,7 @@ describe("context", () => {
|
||||||
|
|
||||||
it("fails when no tenant id is set", () => {
|
it("fails when no tenant id is set", () => {
|
||||||
const test = () => {
|
const test = () => {
|
||||||
let error
|
let error: any
|
||||||
try {
|
try {
|
||||||
context.getTenantId()
|
context.getTenantId()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -45,7 +45,7 @@ describe("context", () => {
|
||||||
|
|
||||||
it("fails when no tenant db is set", () => {
|
it("fails when no tenant db is set", () => {
|
||||||
const test = () => {
|
const test = () => {
|
||||||
let error
|
let error: any
|
||||||
try {
|
try {
|
||||||
context.getGlobalDB()
|
context.getGlobalDB()
|
||||||
} catch (e) {
|
} catch (e) {
|
|
@ -5,18 +5,13 @@ const {
|
||||||
isDevAppID,
|
isDevAppID,
|
||||||
isProdAppID,
|
isProdAppID,
|
||||||
} = require("../conversions")
|
} = require("../conversions")
|
||||||
const {
|
const { generateAppID, getPlatformUrl, getScopedConfig } = require("../utils")
|
||||||
generateAppID,
|
|
||||||
getPlatformUrl,
|
|
||||||
getScopedConfig
|
|
||||||
} = require("../utils")
|
|
||||||
const tenancy = require("../../tenancy")
|
const tenancy = require("../../tenancy")
|
||||||
const { Config, DEFAULT_TENANT_ID } = require("../../constants")
|
const { Config, DEFAULT_TENANT_ID } = require("../../constants")
|
||||||
const env = require("../../environment")
|
import env from "../../environment"
|
||||||
|
|
||||||
describe("utils", () => {
|
describe("utils", () => {
|
||||||
describe("app ID manipulation", () => {
|
describe("app ID manipulation", () => {
|
||||||
|
|
||||||
function getID() {
|
function getID() {
|
||||||
const appId = generateAppID()
|
const appId = generateAppID()
|
||||||
const split = appId.split("_")
|
const split = appId.split("_")
|
||||||
|
@ -28,42 +23,42 @@ describe("utils", () => {
|
||||||
it("should be able to generate a new app ID", () => {
|
it("should be able to generate a new app ID", () => {
|
||||||
expect(generateAppID().startsWith("app_")).toEqual(true)
|
expect(generateAppID().startsWith("app_")).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to convert a production app ID to development", () => {
|
it("should be able to convert a production app ID to development", () => {
|
||||||
const { appId, uuid } = getID()
|
const { appId, uuid } = getID()
|
||||||
expect(getDevelopmentAppID(appId)).toEqual(`app_dev_${uuid}`)
|
expect(getDevelopmentAppID(appId)).toEqual(`app_dev_${uuid}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to convert a development app ID to development", () => {
|
it("should be able to convert a development app ID to development", () => {
|
||||||
const { devAppId, uuid } = getID()
|
const { devAppId, uuid } = getID()
|
||||||
expect(getDevelopmentAppID(devAppId)).toEqual(`app_dev_${uuid}`)
|
expect(getDevelopmentAppID(devAppId)).toEqual(`app_dev_${uuid}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to convert a development ID to a production", () => {
|
it("should be able to convert a development ID to a production", () => {
|
||||||
const { devAppId, uuid } = getID()
|
const { devAppId, uuid } = getID()
|
||||||
expect(getProdAppID(devAppId)).toEqual(`app_${uuid}`)
|
expect(getProdAppID(devAppId)).toEqual(`app_${uuid}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to convert a production ID to production", () => {
|
it("should be able to convert a production ID to production", () => {
|
||||||
const { appId, uuid } = getID()
|
const { appId, uuid } = getID()
|
||||||
expect(getProdAppID(appId)).toEqual(`app_${uuid}`)
|
expect(getProdAppID(appId)).toEqual(`app_${uuid}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to confirm dev app ID is development", () => {
|
it("should be able to confirm dev app ID is development", () => {
|
||||||
const { devAppId } = getID()
|
const { devAppId } = getID()
|
||||||
expect(isDevAppID(devAppId)).toEqual(true)
|
expect(isDevAppID(devAppId)).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to confirm prod app ID is not development", () => {
|
it("should be able to confirm prod app ID is not development", () => {
|
||||||
const { appId } = getID()
|
const { appId } = getID()
|
||||||
expect(isDevAppID(appId)).toEqual(false)
|
expect(isDevAppID(appId)).toEqual(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to confirm prod app ID is prod", () => {
|
it("should be able to confirm prod app ID is prod", () => {
|
||||||
const { appId } = getID()
|
const { appId } = getID()
|
||||||
expect(isProdAppID(appId)).toEqual(true)
|
expect(isProdAppID(appId)).toEqual(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to confirm dev app ID is not prod", () => {
|
it("should be able to confirm dev app ID is not prod", () => {
|
||||||
const { devAppId } = getID()
|
const { devAppId } = getID()
|
||||||
expect(isProdAppID(devAppId)).toEqual(false)
|
expect(isProdAppID(devAppId)).toEqual(false)
|
||||||
|
@ -81,8 +76,8 @@ const setDbPlatformUrl = async () => {
|
||||||
_id: "config_settings",
|
_id: "config_settings",
|
||||||
type: Config.SETTINGS,
|
type: Config.SETTINGS,
|
||||||
config: {
|
config: {
|
||||||
platformUrl: DB_URL
|
platformUrl: DB_URL,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,17 +87,16 @@ const clearSettingsConfig = async () => {
|
||||||
try {
|
try {
|
||||||
const config = await db.get("config_settings")
|
const config = await db.get("config_settings")
|
||||||
await db.remove("config_settings", config._rev)
|
await db.remove("config_settings", config._rev)
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
if (e.status !== 404) {
|
if (e.status !== 404) {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("getPlatformUrl", () => {
|
describe("getPlatformUrl", () => {
|
||||||
describe("self host", () => {
|
describe("self host", () => {
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
env._set("SELF_HOST", 1)
|
env._set("SELF_HOST", 1)
|
||||||
await clearSettingsConfig()
|
await clearSettingsConfig()
|
||||||
|
@ -129,10 +123,9 @@ describe("getPlatformUrl", () => {
|
||||||
const url = await getPlatformUrl()
|
const url = await getPlatformUrl()
|
||||||
expect(url).toBe(DB_URL)
|
expect(url).toBe(DB_URL)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
describe("cloud", () => {
|
describe("cloud", () => {
|
||||||
const TENANT_AWARE_URL = "http://default.env.com"
|
const TENANT_AWARE_URL = "http://default.env.com"
|
||||||
|
|
||||||
|
@ -163,13 +156,12 @@ describe("getPlatformUrl", () => {
|
||||||
const url = await getPlatformUrl()
|
const url = await getPlatformUrl()
|
||||||
expect(url).toBe(TENANT_AWARE_URL)
|
expect(url).toBe(TENANT_AWARE_URL)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("getScopedConfig", () => {
|
describe("getScopedConfig", () => {
|
||||||
describe("settings config", () => {
|
describe("settings config", () => {
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
env._set("SELF_HOSTED", 1)
|
env._set("SELF_HOSTED", 1)
|
||||||
env._set("PLATFORM_URL", "")
|
env._set("PLATFORM_URL", "")
|
|
@ -102,4 +102,4 @@ for (let [key, value] of Object.entries(environment)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export = environment
|
export default environment
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import * as licensing from "./licensing"
|
||||||
|
|
||||||
|
// combine all error codes into single object
|
||||||
|
|
||||||
|
export const codes = {
|
||||||
|
...licensing.codes,
|
||||||
|
}
|
||||||
|
|
||||||
|
// combine all error types
|
||||||
|
export const types = [licensing.type]
|
||||||
|
|
||||||
|
// combine all error contexts
|
||||||
|
const context = {
|
||||||
|
...licensing.context,
|
||||||
|
}
|
||||||
|
|
||||||
|
// derive a public error message using codes, types and any custom contexts
|
||||||
|
export const getPublicError = (err: any) => {
|
||||||
|
let error
|
||||||
|
if (err.code || err.type) {
|
||||||
|
// add generic error information
|
||||||
|
error = {
|
||||||
|
code: err.code,
|
||||||
|
type: err.type,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err.code && context[err.code]) {
|
||||||
|
error = {
|
||||||
|
...error,
|
||||||
|
// get any additional context from this error
|
||||||
|
...context[err.code](err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error
|
||||||
|
}
|
|
@ -1,47 +1,3 @@
|
||||||
import { HTTPError } from "./http"
|
export * from "./errors"
|
||||||
import { UsageLimitError, FeatureDisabledError } from "./licensing"
|
export { UsageLimitError, FeatureDisabledError } from "./licensing"
|
||||||
import * as licensing from "./licensing"
|
export { HTTPError } from "./http"
|
||||||
|
|
||||||
const codes = {
|
|
||||||
...licensing.codes,
|
|
||||||
}
|
|
||||||
|
|
||||||
const types = [licensing.type]
|
|
||||||
|
|
||||||
const context = {
|
|
||||||
...licensing.context,
|
|
||||||
}
|
|
||||||
|
|
||||||
const getPublicError = (err: any) => {
|
|
||||||
let error
|
|
||||||
if (err.code || err.type) {
|
|
||||||
// add generic error information
|
|
||||||
error = {
|
|
||||||
code: err.code,
|
|
||||||
type: err.type,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err.code && context[err.code]) {
|
|
||||||
error = {
|
|
||||||
...error,
|
|
||||||
// get any additional context from this error
|
|
||||||
...context[err.code](err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return error
|
|
||||||
}
|
|
||||||
|
|
||||||
const pkg = {
|
|
||||||
codes,
|
|
||||||
types,
|
|
||||||
errors: {
|
|
||||||
UsageLimitError,
|
|
||||||
FeatureDisabledError,
|
|
||||||
HTTPError,
|
|
||||||
},
|
|
||||||
getPublicError,
|
|
||||||
}
|
|
||||||
|
|
||||||
export = pkg
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Event } from "@budibase/types"
|
import { Event } from "@budibase/types"
|
||||||
import { processors } from "./processors"
|
import { processors } from "./processors"
|
||||||
import * as identification from "./identification"
|
import identification from "./identification"
|
||||||
import * as backfill from "./backfill"
|
import * as backfill from "./backfill"
|
||||||
|
|
||||||
export const publishEvent = async (
|
export const publishEvent = async (
|
||||||
|
|
|
@ -33,7 +33,7 @@ const pkg = require("../../package.json")
|
||||||
* - tenant
|
* - tenant
|
||||||
* - installation
|
* - installation
|
||||||
*/
|
*/
|
||||||
export const getCurrentIdentity = async (): Promise<Identity> => {
|
const getCurrentIdentity = async (): Promise<Identity> => {
|
||||||
let identityContext = identityCtx.getIdentity()
|
let identityContext = identityCtx.getIdentity()
|
||||||
const environment = getDeploymentEnvironment()
|
const environment = getDeploymentEnvironment()
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ export const getCurrentIdentity = async (): Promise<Identity> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const identifyInstallationGroup = async (
|
const identifyInstallationGroup = async (
|
||||||
installId: string,
|
installId: string,
|
||||||
timestamp?: string | number
|
timestamp?: string | number
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
|
@ -118,7 +118,7 @@ export const identifyInstallationGroup = async (
|
||||||
await identify({ ...group, id: `$${type}_${id}` }, timestamp)
|
await identify({ ...group, id: `$${type}_${id}` }, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const identifyTenantGroup = async (
|
const identifyTenantGroup = async (
|
||||||
tenantId: string,
|
tenantId: string,
|
||||||
account: Account | undefined,
|
account: Account | undefined,
|
||||||
timestamp?: string | number
|
timestamp?: string | number
|
||||||
|
@ -156,7 +156,7 @@ export const identifyTenantGroup = async (
|
||||||
await identify({ ...group, id: `$${type}_${id}` }, timestamp)
|
await identify({ ...group, id: `$${type}_${id}` }, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const identifyUser = async (
|
const identifyUser = async (
|
||||||
user: User,
|
user: User,
|
||||||
account: CloudAccount | undefined,
|
account: CloudAccount | undefined,
|
||||||
timestamp?: string | number
|
timestamp?: string | number
|
||||||
|
@ -191,7 +191,7 @@ export const identifyUser = async (
|
||||||
await identify(identity, timestamp)
|
await identify(identity, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const identifyAccount = async (account: Account) => {
|
const identifyAccount = async (account: Account) => {
|
||||||
let id = account.accountId
|
let id = account.accountId
|
||||||
const tenantId = account.tenantId
|
const tenantId = account.tenantId
|
||||||
let type = IdentityType.USER
|
let type = IdentityType.USER
|
||||||
|
@ -224,17 +224,11 @@ export const identifyAccount = async (account: Account) => {
|
||||||
await identify(identity)
|
await identify(identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const identify = async (
|
const identify = async (identity: Identity, timestamp?: string | number) => {
|
||||||
identity: Identity,
|
|
||||||
timestamp?: string | number
|
|
||||||
) => {
|
|
||||||
await processors.identify(identity, timestamp)
|
await processors.identify(identity, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const identifyGroup = async (
|
const identifyGroup = async (group: Group, timestamp?: string | number) => {
|
||||||
group: Group,
|
|
||||||
timestamp?: string | number
|
|
||||||
) => {
|
|
||||||
await processors.identifyGroup(group, timestamp)
|
await processors.identifyGroup(group, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +244,7 @@ const getHostingFromEnv = () => {
|
||||||
return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD
|
return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getInstallationId = async () => {
|
const getInstallationId = async () => {
|
||||||
if (isAccountPortal()) {
|
if (isAccountPortal()) {
|
||||||
return "account-portal"
|
return "account-portal"
|
||||||
}
|
}
|
||||||
|
@ -300,3 +294,14 @@ const formatDistinctId = (id: string, type: IdentityType) => {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getCurrentIdentity,
|
||||||
|
identifyInstallationGroup,
|
||||||
|
identifyTenantGroup,
|
||||||
|
identifyUser,
|
||||||
|
identifyAccount,
|
||||||
|
identify,
|
||||||
|
identifyGroup,
|
||||||
|
getInstallationId,
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export * from "./publishers"
|
export * from "./publishers"
|
||||||
export * as processors from "./processors"
|
export * as processors from "./processors"
|
||||||
export * as analytics from "./analytics"
|
export * as analytics from "./analytics"
|
||||||
export * as identification from "./identification"
|
export { default as identification } from "./identification"
|
||||||
export * as backfillCache from "./backfill"
|
export * as backfillCache from "./backfill"
|
||||||
|
|
||||||
import { processors } from "./processors"
|
import { processors } from "./processors"
|
||||||
|
|
|
@ -7,23 +7,29 @@ import {
|
||||||
AccountVerifiedEvent,
|
AccountVerifiedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(account: Account) {
|
async function created(account: Account) {
|
||||||
const properties: AccountCreatedEvent = {
|
const properties: AccountCreatedEvent = {
|
||||||
tenantId: account.tenantId,
|
tenantId: account.tenantId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.ACCOUNT_CREATED, properties)
|
await publishEvent(Event.ACCOUNT_CREATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(account: Account) {
|
async function deleted(account: Account) {
|
||||||
const properties: AccountDeletedEvent = {
|
const properties: AccountDeletedEvent = {
|
||||||
tenantId: account.tenantId,
|
tenantId: account.tenantId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.ACCOUNT_DELETED, properties)
|
await publishEvent(Event.ACCOUNT_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function verified(account: Account) {
|
async function verified(account: Account) {
|
||||||
const properties: AccountVerifiedEvent = {
|
const properties: AccountVerifiedEvent = {
|
||||||
tenantId: account.tenantId,
|
tenantId: account.tenantId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.ACCOUNT_VERIFIED, properties)
|
await publishEvent(Event.ACCOUNT_VERIFIED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
deleted,
|
||||||
|
verified,
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
AppExportedEvent,
|
AppExportedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export const created = async (app: App, timestamp?: string | number) => {
|
const created = async (app: App, timestamp?: string | number) => {
|
||||||
const properties: AppCreatedEvent = {
|
const properties: AppCreatedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
version: app.version,
|
version: app.version,
|
||||||
|
@ -23,7 +23,7 @@ export const created = async (app: App, timestamp?: string | number) => {
|
||||||
await publishEvent(Event.APP_CREATED, properties, timestamp)
|
await publishEvent(Event.APP_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(app: App) {
|
async function updated(app: App) {
|
||||||
const properties: AppUpdatedEvent = {
|
const properties: AppUpdatedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
version: app.version,
|
version: app.version,
|
||||||
|
@ -31,35 +31,35 @@ export async function updated(app: App) {
|
||||||
await publishEvent(Event.APP_UPDATED, properties)
|
await publishEvent(Event.APP_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(app: App) {
|
async function deleted(app: App) {
|
||||||
const properties: AppDeletedEvent = {
|
const properties: AppDeletedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_DELETED, properties)
|
await publishEvent(Event.APP_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function published(app: App, timestamp?: string | number) {
|
async function published(app: App, timestamp?: string | number) {
|
||||||
const properties: AppPublishedEvent = {
|
const properties: AppPublishedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_PUBLISHED, properties, timestamp)
|
await publishEvent(Event.APP_PUBLISHED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function unpublished(app: App) {
|
async function unpublished(app: App) {
|
||||||
const properties: AppUnpublishedEvent = {
|
const properties: AppUnpublishedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_UNPUBLISHED, properties)
|
await publishEvent(Event.APP_UNPUBLISHED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fileImported(app: App) {
|
async function fileImported(app: App) {
|
||||||
const properties: AppFileImportedEvent = {
|
const properties: AppFileImportedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_FILE_IMPORTED, properties)
|
await publishEvent(Event.APP_FILE_IMPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function templateImported(app: App, templateKey: string) {
|
async function templateImported(app: App, templateKey: string) {
|
||||||
const properties: AppTemplateImportedEvent = {
|
const properties: AppTemplateImportedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
templateKey,
|
templateKey,
|
||||||
|
@ -67,7 +67,7 @@ export async function templateImported(app: App, templateKey: string) {
|
||||||
await publishEvent(Event.APP_TEMPLATE_IMPORTED, properties)
|
await publishEvent(Event.APP_TEMPLATE_IMPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function versionUpdated(
|
async function versionUpdated(
|
||||||
app: App,
|
app: App,
|
||||||
currentVersion: string,
|
currentVersion: string,
|
||||||
updatedToVersion: string
|
updatedToVersion: string
|
||||||
|
@ -80,7 +80,7 @@ export async function versionUpdated(
|
||||||
await publishEvent(Event.APP_VERSION_UPDATED, properties)
|
await publishEvent(Event.APP_VERSION_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function versionReverted(
|
async function versionReverted(
|
||||||
app: App,
|
app: App,
|
||||||
currentVersion: string,
|
currentVersion: string,
|
||||||
revertedToVersion: string
|
revertedToVersion: string
|
||||||
|
@ -93,16 +93,30 @@ export async function versionReverted(
|
||||||
await publishEvent(Event.APP_VERSION_REVERTED, properties)
|
await publishEvent(Event.APP_VERSION_REVERTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function reverted(app: App) {
|
async function reverted(app: App) {
|
||||||
const properties: AppRevertedEvent = {
|
const properties: AppRevertedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_REVERTED, properties)
|
await publishEvent(Event.APP_REVERTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exported(app: App) {
|
async function exported(app: App) {
|
||||||
const properties: AppExportedEvent = {
|
const properties: AppExportedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_EXPORTED, properties)
|
await publishEvent(Event.APP_EXPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
published,
|
||||||
|
unpublished,
|
||||||
|
fileImported,
|
||||||
|
templateImported,
|
||||||
|
versionUpdated,
|
||||||
|
versionReverted,
|
||||||
|
reverted,
|
||||||
|
exported,
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { identification } from ".."
|
import { identification } from ".."
|
||||||
|
|
||||||
export async function login(source: LoginSource) {
|
async function login(source: LoginSource) {
|
||||||
const identity = await identification.getCurrentIdentity()
|
const identity = await identification.getCurrentIdentity()
|
||||||
const properties: LoginEvent = {
|
const properties: LoginEvent = {
|
||||||
userId: identity.id,
|
userId: identity.id,
|
||||||
|
@ -21,7 +21,7 @@ export async function login(source: LoginSource) {
|
||||||
await publishEvent(Event.AUTH_LOGIN, properties)
|
await publishEvent(Event.AUTH_LOGIN, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function logout() {
|
async function logout() {
|
||||||
const identity = await identification.getCurrentIdentity()
|
const identity = await identification.getCurrentIdentity()
|
||||||
const properties: LogoutEvent = {
|
const properties: LogoutEvent = {
|
||||||
userId: identity.id,
|
userId: identity.id,
|
||||||
|
@ -29,30 +29,39 @@ export async function logout() {
|
||||||
await publishEvent(Event.AUTH_LOGOUT, properties)
|
await publishEvent(Event.AUTH_LOGOUT, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SSOCreated(type: SSOType, timestamp?: string | number) {
|
async function SSOCreated(type: SSOType, timestamp?: string | number) {
|
||||||
const properties: SSOCreatedEvent = {
|
const properties: SSOCreatedEvent = {
|
||||||
type,
|
type,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.AUTH_SSO_CREATED, properties, timestamp)
|
await publishEvent(Event.AUTH_SSO_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SSOUpdated(type: SSOType) {
|
async function SSOUpdated(type: SSOType) {
|
||||||
const properties: SSOUpdatedEvent = {
|
const properties: SSOUpdatedEvent = {
|
||||||
type,
|
type,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.AUTH_SSO_UPDATED, properties)
|
await publishEvent(Event.AUTH_SSO_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SSOActivated(type: SSOType, timestamp?: string | number) {
|
async function SSOActivated(type: SSOType, timestamp?: string | number) {
|
||||||
const properties: SSOActivatedEvent = {
|
const properties: SSOActivatedEvent = {
|
||||||
type,
|
type,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.AUTH_SSO_ACTIVATED, properties, timestamp)
|
await publishEvent(Event.AUTH_SSO_ACTIVATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SSODeactivated(type: SSOType) {
|
async function SSODeactivated(type: SSOType) {
|
||||||
const properties: SSODeactivatedEvent = {
|
const properties: SSODeactivatedEvent = {
|
||||||
type,
|
type,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.AUTH_SSO_DEACTIVATED, properties)
|
await publishEvent(Event.AUTH_SSO_DEACTIVATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
SSOCreated,
|
||||||
|
SSOUpdated,
|
||||||
|
SSOActivated,
|
||||||
|
SSODeactivated,
|
||||||
|
}
|
||||||
|
|
|
@ -12,10 +12,7 @@ import {
|
||||||
AutomationsRunEvent,
|
AutomationsRunEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(
|
async function created(automation: Automation, timestamp?: string | number) {
|
||||||
automation: Automation,
|
|
||||||
timestamp?: string | number
|
|
||||||
) {
|
|
||||||
const properties: AutomationCreatedEvent = {
|
const properties: AutomationCreatedEvent = {
|
||||||
appId: automation.appId,
|
appId: automation.appId,
|
||||||
automationId: automation._id as string,
|
automationId: automation._id as string,
|
||||||
|
@ -25,7 +22,7 @@ export async function created(
|
||||||
await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)
|
await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function triggerUpdated(automation: Automation) {
|
async function triggerUpdated(automation: Automation) {
|
||||||
const properties: AutomationTriggerUpdatedEvent = {
|
const properties: AutomationTriggerUpdatedEvent = {
|
||||||
appId: automation.appId,
|
appId: automation.appId,
|
||||||
automationId: automation._id as string,
|
automationId: automation._id as string,
|
||||||
|
@ -35,7 +32,7 @@ export async function triggerUpdated(automation: Automation) {
|
||||||
await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)
|
await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(automation: Automation) {
|
async function deleted(automation: Automation) {
|
||||||
const properties: AutomationDeletedEvent = {
|
const properties: AutomationDeletedEvent = {
|
||||||
appId: automation.appId,
|
appId: automation.appId,
|
||||||
automationId: automation._id as string,
|
automationId: automation._id as string,
|
||||||
|
@ -45,7 +42,7 @@ export async function deleted(automation: Automation) {
|
||||||
await publishEvent(Event.AUTOMATION_DELETED, properties)
|
await publishEvent(Event.AUTOMATION_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function tested(automation: Automation) {
|
async function tested(automation: Automation) {
|
||||||
const properties: AutomationTestedEvent = {
|
const properties: AutomationTestedEvent = {
|
||||||
appId: automation.appId,
|
appId: automation.appId,
|
||||||
automationId: automation._id as string,
|
automationId: automation._id as string,
|
||||||
|
@ -55,14 +52,14 @@ export async function tested(automation: Automation) {
|
||||||
await publishEvent(Event.AUTOMATION_TESTED, properties)
|
await publishEvent(Event.AUTOMATION_TESTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const run = async (count: number, timestamp?: string | number) => {
|
const run = async (count: number, timestamp?: string | number) => {
|
||||||
const properties: AutomationsRunEvent = {
|
const properties: AutomationsRunEvent = {
|
||||||
count,
|
count,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.AUTOMATIONS_RUN, properties, timestamp)
|
await publishEvent(Event.AUTOMATIONS_RUN, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stepCreated(
|
async function stepCreated(
|
||||||
automation: Automation,
|
automation: Automation,
|
||||||
step: AutomationStep,
|
step: AutomationStep,
|
||||||
timestamp?: string | number
|
timestamp?: string | number
|
||||||
|
@ -78,10 +75,7 @@ export async function stepCreated(
|
||||||
await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)
|
await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stepDeleted(
|
async function stepDeleted(automation: Automation, step: AutomationStep) {
|
||||||
automation: Automation,
|
|
||||||
step: AutomationStep
|
|
||||||
) {
|
|
||||||
const properties: AutomationStepDeletedEvent = {
|
const properties: AutomationStepDeletedEvent = {
|
||||||
appId: automation.appId,
|
appId: automation.appId,
|
||||||
automationId: automation._id as string,
|
automationId: automation._id as string,
|
||||||
|
@ -92,3 +86,13 @@ export async function stepDeleted(
|
||||||
}
|
}
|
||||||
await publishEvent(Event.AUTOMATION_STEP_DELETED, properties)
|
await publishEvent(Event.AUTOMATION_STEP_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
triggerUpdated,
|
||||||
|
deleted,
|
||||||
|
tested,
|
||||||
|
run,
|
||||||
|
stepCreated,
|
||||||
|
stepDeleted,
|
||||||
|
}
|
||||||
|
|
|
@ -8,18 +8,18 @@ import {
|
||||||
InstallationBackfillSucceededEvent,
|
InstallationBackfillSucceededEvent,
|
||||||
InstallationBackfillFailedEvent,
|
InstallationBackfillFailedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
const env = require("../../environment")
|
import env from "../../environment"
|
||||||
|
|
||||||
const shouldSkip = !env.SELF_HOSTED && !env.isDev()
|
const shouldSkip = !env.SELF_HOSTED && !env.isDev()
|
||||||
|
|
||||||
export async function appSucceeded(properties: AppBackfillSucceededEvent) {
|
async function appSucceeded(properties: AppBackfillSucceededEvent) {
|
||||||
if (shouldSkip) {
|
if (shouldSkip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_BACKFILL_SUCCEEDED, properties)
|
await publishEvent(Event.APP_BACKFILL_SUCCEEDED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function appFailed(error: any) {
|
async function appFailed(error: any) {
|
||||||
if (shouldSkip) {
|
if (shouldSkip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -29,16 +29,14 @@ export async function appFailed(error: any) {
|
||||||
await publishEvent(Event.APP_BACKFILL_FAILED, properties)
|
await publishEvent(Event.APP_BACKFILL_FAILED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function tenantSucceeded(
|
async function tenantSucceeded(properties: TenantBackfillSucceededEvent) {
|
||||||
properties: TenantBackfillSucceededEvent
|
|
||||||
) {
|
|
||||||
if (shouldSkip) {
|
if (shouldSkip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await publishEvent(Event.TENANT_BACKFILL_SUCCEEDED, properties)
|
await publishEvent(Event.TENANT_BACKFILL_SUCCEEDED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function tenantFailed(error: any) {
|
async function tenantFailed(error: any) {
|
||||||
if (shouldSkip) {
|
if (shouldSkip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -48,7 +46,7 @@ export async function tenantFailed(error: any) {
|
||||||
await publishEvent(Event.TENANT_BACKFILL_FAILED, properties)
|
await publishEvent(Event.TENANT_BACKFILL_FAILED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function installationSucceeded() {
|
async function installationSucceeded() {
|
||||||
if (shouldSkip) {
|
if (shouldSkip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -56,7 +54,7 @@ export async function installationSucceeded() {
|
||||||
await publishEvent(Event.INSTALLATION_BACKFILL_SUCCEEDED, properties)
|
await publishEvent(Event.INSTALLATION_BACKFILL_SUCCEEDED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function installationFailed(error: any) {
|
async function installationFailed(error: any) {
|
||||||
if (shouldSkip) {
|
if (shouldSkip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -65,3 +63,12 @@ export async function installationFailed(error: any) {
|
||||||
}
|
}
|
||||||
await publishEvent(Event.INSTALLATION_BACKFILL_FAILED, properties)
|
await publishEvent(Event.INSTALLATION_BACKFILL_FAILED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
appSucceeded,
|
||||||
|
appFailed,
|
||||||
|
tenantSucceeded,
|
||||||
|
tenantFailed,
|
||||||
|
installationSucceeded,
|
||||||
|
installationFailed,
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { publishEvent } from "../events"
|
import { publishEvent } from "../events"
|
||||||
|
|
||||||
export async function appBackupRestored(backup: AppBackup) {
|
async function appBackupRestored(backup: AppBackup) {
|
||||||
const properties: AppBackupRestoreEvent = {
|
const properties: AppBackupRestoreEvent = {
|
||||||
appId: backup.appId,
|
appId: backup.appId,
|
||||||
restoreId: backup._id!,
|
restoreId: backup._id!,
|
||||||
|
@ -18,7 +18,7 @@ export async function appBackupRestored(backup: AppBackup) {
|
||||||
await publishEvent(Event.APP_BACKUP_RESTORED, properties)
|
await publishEvent(Event.APP_BACKUP_RESTORED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function appBackupTriggered(
|
async function appBackupTriggered(
|
||||||
appId: string,
|
appId: string,
|
||||||
backupId: string,
|
backupId: string,
|
||||||
type: AppBackupType,
|
type: AppBackupType,
|
||||||
|
@ -32,3 +32,8 @@ export async function appBackupTriggered(
|
||||||
}
|
}
|
||||||
await publishEvent(Event.APP_BACKUP_TRIGGERED, properties)
|
await publishEvent(Event.APP_BACKUP_TRIGGERED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
appBackupRestored,
|
||||||
|
appBackupTriggered,
|
||||||
|
}
|
||||||
|
|
|
@ -14,10 +14,7 @@ function isCustom(datasource: Datasource) {
|
||||||
return !sources.includes(datasource.source)
|
return !sources.includes(datasource.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function created(
|
async function created(datasource: Datasource, timestamp?: string | number) {
|
||||||
datasource: Datasource,
|
|
||||||
timestamp?: string | number
|
|
||||||
) {
|
|
||||||
const properties: DatasourceCreatedEvent = {
|
const properties: DatasourceCreatedEvent = {
|
||||||
datasourceId: datasource._id as string,
|
datasourceId: datasource._id as string,
|
||||||
source: datasource.source,
|
source: datasource.source,
|
||||||
|
@ -26,7 +23,7 @@ export async function created(
|
||||||
await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)
|
await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(datasource: Datasource) {
|
async function updated(datasource: Datasource) {
|
||||||
const properties: DatasourceUpdatedEvent = {
|
const properties: DatasourceUpdatedEvent = {
|
||||||
datasourceId: datasource._id as string,
|
datasourceId: datasource._id as string,
|
||||||
source: datasource.source,
|
source: datasource.source,
|
||||||
|
@ -35,7 +32,7 @@ export async function updated(datasource: Datasource) {
|
||||||
await publishEvent(Event.DATASOURCE_UPDATED, properties)
|
await publishEvent(Event.DATASOURCE_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(datasource: Datasource) {
|
async function deleted(datasource: Datasource) {
|
||||||
const properties: DatasourceDeletedEvent = {
|
const properties: DatasourceDeletedEvent = {
|
||||||
datasourceId: datasource._id as string,
|
datasourceId: datasource._id as string,
|
||||||
source: datasource.source,
|
source: datasource.source,
|
||||||
|
@ -43,3 +40,9 @@ export async function deleted(datasource: Datasource) {
|
||||||
}
|
}
|
||||||
await publishEvent(Event.DATASOURCE_DELETED, properties)
|
await publishEvent(Event.DATASOURCE_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import { publishEvent } from "../events"
|
import { publishEvent } from "../events"
|
||||||
import { Event, SMTPCreatedEvent, SMTPUpdatedEvent } from "@budibase/types"
|
import { Event, SMTPCreatedEvent, SMTPUpdatedEvent } from "@budibase/types"
|
||||||
|
|
||||||
export async function SMTPCreated(timestamp?: string | number) {
|
async function SMTPCreated(timestamp?: string | number) {
|
||||||
const properties: SMTPCreatedEvent = {}
|
const properties: SMTPCreatedEvent = {}
|
||||||
await publishEvent(Event.EMAIL_SMTP_CREATED, properties, timestamp)
|
await publishEvent(Event.EMAIL_SMTP_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SMTPUpdated() {
|
async function SMTPUpdated() {
|
||||||
const properties: SMTPUpdatedEvent = {}
|
const properties: SMTPUpdatedEvent = {}
|
||||||
await publishEvent(Event.EMAIL_SMTP_UPDATED, properties)
|
await publishEvent(Event.EMAIL_SMTP_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
SMTPCreated,
|
||||||
|
SMTPUpdated,
|
||||||
|
}
|
||||||
|
|
|
@ -11,28 +11,28 @@ import {
|
||||||
UserGroupRoles,
|
UserGroupRoles,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(group: UserGroup, timestamp?: number) {
|
async function created(group: UserGroup, timestamp?: number) {
|
||||||
const properties: GroupCreatedEvent = {
|
const properties: GroupCreatedEvent = {
|
||||||
groupId: group._id as string,
|
groupId: group._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_GROUP_CREATED, properties, timestamp)
|
await publishEvent(Event.USER_GROUP_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(group: UserGroup) {
|
async function updated(group: UserGroup) {
|
||||||
const properties: GroupUpdatedEvent = {
|
const properties: GroupUpdatedEvent = {
|
||||||
groupId: group._id as string,
|
groupId: group._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_GROUP_UPDATED, properties)
|
await publishEvent(Event.USER_GROUP_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(group: UserGroup) {
|
async function deleted(group: UserGroup) {
|
||||||
const properties: GroupDeletedEvent = {
|
const properties: GroupDeletedEvent = {
|
||||||
groupId: group._id as string,
|
groupId: group._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_GROUP_DELETED, properties)
|
await publishEvent(Event.USER_GROUP_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function usersAdded(count: number, group: UserGroup) {
|
async function usersAdded(count: number, group: UserGroup) {
|
||||||
const properties: GroupUsersAddedEvent = {
|
const properties: GroupUsersAddedEvent = {
|
||||||
count,
|
count,
|
||||||
groupId: group._id as string,
|
groupId: group._id as string,
|
||||||
|
@ -40,7 +40,7 @@ export async function usersAdded(count: number, group: UserGroup) {
|
||||||
await publishEvent(Event.USER_GROUP_USERS_ADDED, properties)
|
await publishEvent(Event.USER_GROUP_USERS_ADDED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function usersDeleted(count: number, group: UserGroup) {
|
async function usersDeleted(count: number, group: UserGroup) {
|
||||||
const properties: GroupUsersDeletedEvent = {
|
const properties: GroupUsersDeletedEvent = {
|
||||||
count,
|
count,
|
||||||
groupId: group._id as string,
|
groupId: group._id as string,
|
||||||
|
@ -48,7 +48,7 @@ export async function usersDeleted(count: number, group: UserGroup) {
|
||||||
await publishEvent(Event.USER_GROUP_USERS_REMOVED, properties)
|
await publishEvent(Event.USER_GROUP_USERS_REMOVED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createdOnboarding(groupId: string) {
|
async function createdOnboarding(groupId: string) {
|
||||||
const properties: GroupAddedOnboardingEvent = {
|
const properties: GroupAddedOnboardingEvent = {
|
||||||
groupId: groupId,
|
groupId: groupId,
|
||||||
onboarding: true,
|
onboarding: true,
|
||||||
|
@ -56,9 +56,19 @@ export async function createdOnboarding(groupId: string) {
|
||||||
await publishEvent(Event.USER_GROUP_ONBOARDING, properties)
|
await publishEvent(Event.USER_GROUP_ONBOARDING, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function permissionsEdited(roles: UserGroupRoles) {
|
async function permissionsEdited(roles: UserGroupRoles) {
|
||||||
const properties: UserGroupRoles = {
|
const properties: UserGroupRoles = {
|
||||||
...roles,
|
...roles,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_GROUP_PERMISSIONS_EDITED, properties)
|
await publishEvent(Event.USER_GROUP_PERMISSIONS_EDITED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
usersAdded,
|
||||||
|
usersDeleted,
|
||||||
|
createdOnboarding,
|
||||||
|
permissionsEdited,
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
export * as account from "./account"
|
export { default as account } from "./account"
|
||||||
export * as app from "./app"
|
export { default as app } from "./app"
|
||||||
export * as auth from "./auth"
|
export { default as auth } from "./auth"
|
||||||
export * as automation from "./automation"
|
export { default as automation } from "./automation"
|
||||||
export * as datasource from "./datasource"
|
export { default as datasource } from "./datasource"
|
||||||
export * as email from "./email"
|
export { default as email } from "./email"
|
||||||
export * as license from "./license"
|
export { default as license } from "./license"
|
||||||
export * as layout from "./layout"
|
export { default as layout } from "./layout"
|
||||||
export * as org from "./org"
|
export { default as org } from "./org"
|
||||||
export * as query from "./query"
|
export { default as query } from "./query"
|
||||||
export * as role from "./role"
|
export { default as role } from "./role"
|
||||||
export * as screen from "./screen"
|
export { default as screen } from "./screen"
|
||||||
export * as rows from "./rows"
|
export { default as rows } from "./rows"
|
||||||
export * as table from "./table"
|
export { default as table } from "./table"
|
||||||
export * as serve from "./serve"
|
export { default as serve } from "./serve"
|
||||||
export * as user from "./user"
|
export { default as user } from "./user"
|
||||||
export * as view from "./view"
|
export { default as view } from "./view"
|
||||||
export * as installation from "./installation"
|
export { default as installation } from "./installation"
|
||||||
export * as backfill from "./backfill"
|
export { default as backfill } from "./backfill"
|
||||||
export * as group from "./group"
|
export { default as group } from "./group"
|
||||||
export * as plugin from "./plugin"
|
export { default as plugin } from "./plugin"
|
||||||
export * as backup from "./backup"
|
export { default as backup } from "./backup"
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { publishEvent } from "../events"
|
import { publishEvent } from "../events"
|
||||||
import { Event, VersionCheckedEvent, VersionChangeEvent } from "@budibase/types"
|
import { Event, VersionCheckedEvent, VersionChangeEvent } from "@budibase/types"
|
||||||
|
|
||||||
export async function versionChecked(version: string) {
|
async function versionChecked(version: string) {
|
||||||
const properties: VersionCheckedEvent = {
|
const properties: VersionCheckedEvent = {
|
||||||
currentVersion: version,
|
currentVersion: version,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.INSTALLATION_VERSION_CHECKED, properties)
|
await publishEvent(Event.INSTALLATION_VERSION_CHECKED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function upgraded(from: string, to: string) {
|
async function upgraded(from: string, to: string) {
|
||||||
const properties: VersionChangeEvent = {
|
const properties: VersionChangeEvent = {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
|
@ -17,7 +17,7 @@ export async function upgraded(from: string, to: string) {
|
||||||
await publishEvent(Event.INSTALLATION_VERSION_UPGRADED, properties)
|
await publishEvent(Event.INSTALLATION_VERSION_UPGRADED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downgraded(from: string, to: string) {
|
async function downgraded(from: string, to: string) {
|
||||||
const properties: VersionChangeEvent = {
|
const properties: VersionChangeEvent = {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
|
@ -25,7 +25,14 @@ export async function downgraded(from: string, to: string) {
|
||||||
await publishEvent(Event.INSTALLATION_VERSION_DOWNGRADED, properties)
|
await publishEvent(Event.INSTALLATION_VERSION_DOWNGRADED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function firstStartup() {
|
async function firstStartup() {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
await publishEvent(Event.INSTALLATION_FIRST_STARTUP, properties)
|
await publishEvent(Event.INSTALLATION_FIRST_STARTUP, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
versionChecked,
|
||||||
|
upgraded,
|
||||||
|
downgraded,
|
||||||
|
firstStartup,
|
||||||
|
}
|
||||||
|
|
|
@ -6,16 +6,21 @@ import {
|
||||||
LayoutDeletedEvent,
|
LayoutDeletedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(layout: Layout, timestamp?: string | number) {
|
async function created(layout: Layout, timestamp?: string | number) {
|
||||||
const properties: LayoutCreatedEvent = {
|
const properties: LayoutCreatedEvent = {
|
||||||
layoutId: layout._id as string,
|
layoutId: layout._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LAYOUT_CREATED, properties, timestamp)
|
await publishEvent(Event.LAYOUT_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(layoutId: string) {
|
async function deleted(layoutId: string) {
|
||||||
const properties: LayoutDeletedEvent = {
|
const properties: LayoutDeletedEvent = {
|
||||||
layoutId,
|
layoutId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LAYOUT_DELETED, properties)
|
await publishEvent(Event.LAYOUT_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
deleted,
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
LicensePaymentRecoveredEvent,
|
LicensePaymentRecoveredEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function tierChanged(account: Account, from: number, to: number) {
|
async function tierChanged(account: Account, from: number, to: number) {
|
||||||
const properties: LicenseTierChangedEvent = {
|
const properties: LicenseTierChangedEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
to,
|
to,
|
||||||
|
@ -22,11 +22,7 @@ export async function tierChanged(account: Account, from: number, to: number) {
|
||||||
await publishEvent(Event.LICENSE_TIER_CHANGED, properties)
|
await publishEvent(Event.LICENSE_TIER_CHANGED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function planChanged(
|
async function planChanged(account: Account, from: PlanType, to: PlanType) {
|
||||||
account: Account,
|
|
||||||
from: PlanType,
|
|
||||||
to: PlanType
|
|
||||||
) {
|
|
||||||
const properties: LicensePlanChangedEvent = {
|
const properties: LicensePlanChangedEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
to,
|
to,
|
||||||
|
@ -35,44 +31,55 @@ export async function planChanged(
|
||||||
await publishEvent(Event.LICENSE_PLAN_CHANGED, properties)
|
await publishEvent(Event.LICENSE_PLAN_CHANGED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function activated(account: Account) {
|
async function activated(account: Account) {
|
||||||
const properties: LicenseActivatedEvent = {
|
const properties: LicenseActivatedEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LICENSE_ACTIVATED, properties)
|
await publishEvent(Event.LICENSE_ACTIVATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkoutOpened(account: Account) {
|
async function checkoutOpened(account: Account) {
|
||||||
const properties: LicenseCheckoutOpenedEvent = {
|
const properties: LicenseCheckoutOpenedEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LICENSE_CHECKOUT_OPENED, properties)
|
await publishEvent(Event.LICENSE_CHECKOUT_OPENED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkoutSuccess(account: Account) {
|
async function checkoutSuccess(account: Account) {
|
||||||
const properties: LicenseCheckoutSuccessEvent = {
|
const properties: LicenseCheckoutSuccessEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LICENSE_CHECKOUT_SUCCESS, properties)
|
await publishEvent(Event.LICENSE_CHECKOUT_SUCCESS, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function portalOpened(account: Account) {
|
async function portalOpened(account: Account) {
|
||||||
const properties: LicensePortalOpenedEvent = {
|
const properties: LicensePortalOpenedEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LICENSE_PORTAL_OPENED, properties)
|
await publishEvent(Event.LICENSE_PORTAL_OPENED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function paymentFailed(account: Account) {
|
async function paymentFailed(account: Account) {
|
||||||
const properties: LicensePaymentFailedEvent = {
|
const properties: LicensePaymentFailedEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LICENSE_PAYMENT_FAILED, properties)
|
await publishEvent(Event.LICENSE_PAYMENT_FAILED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function paymentRecovered(account: Account) {
|
async function paymentRecovered(account: Account) {
|
||||||
const properties: LicensePaymentRecoveredEvent = {
|
const properties: LicensePaymentRecoveredEvent = {
|
||||||
accountId: account.accountId,
|
accountId: account.accountId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.LICENSE_PAYMENT_RECOVERED, properties)
|
await publishEvent(Event.LICENSE_PAYMENT_RECOVERED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
tierChanged,
|
||||||
|
planChanged,
|
||||||
|
activated,
|
||||||
|
checkoutOpened,
|
||||||
|
checkoutSuccess,
|
||||||
|
portalOpened,
|
||||||
|
paymentFailed,
|
||||||
|
paymentRecovered,
|
||||||
|
}
|
||||||
|
|
|
@ -1,29 +1,37 @@
|
||||||
import { publishEvent } from "../events"
|
import { publishEvent } from "../events"
|
||||||
import { Event } from "@budibase/types"
|
import { Event } from "@budibase/types"
|
||||||
|
|
||||||
export async function nameUpdated(timestamp?: string | number) {
|
async function nameUpdated(timestamp?: string | number) {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
await publishEvent(Event.ORG_NAME_UPDATED, properties, timestamp)
|
await publishEvent(Event.ORG_NAME_UPDATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function logoUpdated(timestamp?: string | number) {
|
async function logoUpdated(timestamp?: string | number) {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
await publishEvent(Event.ORG_LOGO_UPDATED, properties, timestamp)
|
await publishEvent(Event.ORG_LOGO_UPDATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function platformURLUpdated(timestamp?: string | number) {
|
async function platformURLUpdated(timestamp?: string | number) {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties, timestamp)
|
await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
export async function analyticsOptOut() {
|
async function analyticsOptOut() {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
await publishEvent(Event.ANALYTICS_OPT_OUT, properties)
|
await publishEvent(Event.ANALYTICS_OPT_OUT, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function analyticsOptIn() {
|
async function analyticsOptIn() {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
await publishEvent(Event.ANALYTICS_OPT_OUT, properties)
|
await publishEvent(Event.ANALYTICS_OPT_OUT, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
nameUpdated,
|
||||||
|
logoUpdated,
|
||||||
|
platformURLUpdated,
|
||||||
|
analyticsOptOut,
|
||||||
|
analyticsOptIn,
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
PluginInitEvent,
|
PluginInitEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function init(plugin: Plugin) {
|
async function init(plugin: Plugin) {
|
||||||
const properties: PluginInitEvent = {
|
const properties: PluginInitEvent = {
|
||||||
type: plugin.schema.type,
|
type: plugin.schema.type,
|
||||||
name: plugin.name,
|
name: plugin.name,
|
||||||
|
@ -17,7 +17,7 @@ export async function init(plugin: Plugin) {
|
||||||
await publishEvent(Event.PLUGIN_INIT, properties)
|
await publishEvent(Event.PLUGIN_INIT, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function imported(plugin: Plugin) {
|
async function imported(plugin: Plugin) {
|
||||||
const properties: PluginImportedEvent = {
|
const properties: PluginImportedEvent = {
|
||||||
pluginId: plugin._id as string,
|
pluginId: plugin._id as string,
|
||||||
type: plugin.schema.type,
|
type: plugin.schema.type,
|
||||||
|
@ -29,7 +29,7 @@ export async function imported(plugin: Plugin) {
|
||||||
await publishEvent(Event.PLUGIN_IMPORTED, properties)
|
await publishEvent(Event.PLUGIN_IMPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(plugin: Plugin) {
|
async function deleted(plugin: Plugin) {
|
||||||
const properties: PluginDeletedEvent = {
|
const properties: PluginDeletedEvent = {
|
||||||
pluginId: plugin._id as string,
|
pluginId: plugin._id as string,
|
||||||
type: plugin.schema.type,
|
type: plugin.schema.type,
|
||||||
|
@ -39,3 +39,9 @@ export async function deleted(plugin: Plugin) {
|
||||||
}
|
}
|
||||||
await publishEvent(Event.PLUGIN_DELETED, properties)
|
await publishEvent(Event.PLUGIN_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
init,
|
||||||
|
imported,
|
||||||
|
deleted,
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
export const created = async (
|
const created = async (
|
||||||
datasource: Datasource,
|
datasource: Datasource,
|
||||||
query: Query,
|
query: Query,
|
||||||
timestamp?: string | number
|
timestamp?: string | number
|
||||||
|
@ -27,7 +27,7 @@ export const created = async (
|
||||||
await publishEvent(Event.QUERY_CREATED, properties, timestamp)
|
await publishEvent(Event.QUERY_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updated = async (datasource: Datasource, query: Query) => {
|
const updated = async (datasource: Datasource, query: Query) => {
|
||||||
const properties: QueryUpdatedEvent = {
|
const properties: QueryUpdatedEvent = {
|
||||||
queryId: query._id as string,
|
queryId: query._id as string,
|
||||||
datasourceId: datasource._id as string,
|
datasourceId: datasource._id as string,
|
||||||
|
@ -37,7 +37,7 @@ export const updated = async (datasource: Datasource, query: Query) => {
|
||||||
await publishEvent(Event.QUERY_UPDATED, properties)
|
await publishEvent(Event.QUERY_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deleted = async (datasource: Datasource, query: Query) => {
|
const deleted = async (datasource: Datasource, query: Query) => {
|
||||||
const properties: QueryDeletedEvent = {
|
const properties: QueryDeletedEvent = {
|
||||||
queryId: query._id as string,
|
queryId: query._id as string,
|
||||||
datasourceId: datasource._id as string,
|
datasourceId: datasource._id as string,
|
||||||
|
@ -47,7 +47,7 @@ export const deleted = async (datasource: Datasource, query: Query) => {
|
||||||
await publishEvent(Event.QUERY_DELETED, properties)
|
await publishEvent(Event.QUERY_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const imported = async (
|
const imported = async (
|
||||||
datasource: Datasource,
|
datasource: Datasource,
|
||||||
importSource: any,
|
importSource: any,
|
||||||
count: any
|
count: any
|
||||||
|
@ -61,14 +61,14 @@ export const imported = async (
|
||||||
await publishEvent(Event.QUERY_IMPORT, properties)
|
await publishEvent(Event.QUERY_IMPORT, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const run = async (count: number, timestamp?: string | number) => {
|
const run = async (count: number, timestamp?: string | number) => {
|
||||||
const properties: QueriesRunEvent = {
|
const properties: QueriesRunEvent = {
|
||||||
count,
|
count,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.QUERIES_RUN, properties, timestamp)
|
await publishEvent(Event.QUERIES_RUN, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const previewed = async (datasource: Datasource, query: Query) => {
|
const previewed = async (datasource: Datasource, query: Query) => {
|
||||||
const properties: QueryPreviewedEvent = {
|
const properties: QueryPreviewedEvent = {
|
||||||
queryId: query._id,
|
queryId: query._id,
|
||||||
datasourceId: datasource._id as string,
|
datasourceId: datasource._id as string,
|
||||||
|
@ -77,3 +77,12 @@ export const previewed = async (datasource: Datasource, query: Query) => {
|
||||||
}
|
}
|
||||||
await publishEvent(Event.QUERY_PREVIEWED, properties)
|
await publishEvent(Event.QUERY_PREVIEWED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
imported,
|
||||||
|
run,
|
||||||
|
previewed,
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
User,
|
User,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(role: Role, timestamp?: string | number) {
|
async function created(role: Role, timestamp?: string | number) {
|
||||||
const properties: RoleCreatedEvent = {
|
const properties: RoleCreatedEvent = {
|
||||||
roleId: role._id as string,
|
roleId: role._id as string,
|
||||||
permissionId: role.permissionId,
|
permissionId: role.permissionId,
|
||||||
|
@ -19,7 +19,7 @@ export async function created(role: Role, timestamp?: string | number) {
|
||||||
await publishEvent(Event.ROLE_CREATED, properties, timestamp)
|
await publishEvent(Event.ROLE_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(role: Role) {
|
async function updated(role: Role) {
|
||||||
const properties: RoleUpdatedEvent = {
|
const properties: RoleUpdatedEvent = {
|
||||||
roleId: role._id as string,
|
roleId: role._id as string,
|
||||||
permissionId: role.permissionId,
|
permissionId: role.permissionId,
|
||||||
|
@ -28,7 +28,7 @@ export async function updated(role: Role) {
|
||||||
await publishEvent(Event.ROLE_UPDATED, properties)
|
await publishEvent(Event.ROLE_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(role: Role) {
|
async function deleted(role: Role) {
|
||||||
const properties: RoleDeletedEvent = {
|
const properties: RoleDeletedEvent = {
|
||||||
roleId: role._id as string,
|
roleId: role._id as string,
|
||||||
permissionId: role.permissionId,
|
permissionId: role.permissionId,
|
||||||
|
@ -37,7 +37,7 @@ export async function deleted(role: Role) {
|
||||||
await publishEvent(Event.ROLE_DELETED, properties)
|
await publishEvent(Event.ROLE_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function assigned(user: User, roleId: string, timestamp?: number) {
|
async function assigned(user: User, roleId: string, timestamp?: number) {
|
||||||
const properties: RoleAssignedEvent = {
|
const properties: RoleAssignedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
roleId,
|
roleId,
|
||||||
|
@ -45,10 +45,18 @@ export async function assigned(user: User, roleId: string, timestamp?: number) {
|
||||||
await publishEvent(Event.ROLE_ASSIGNED, properties, timestamp)
|
await publishEvent(Event.ROLE_ASSIGNED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function unassigned(user: User, roleId: string) {
|
async function unassigned(user: User, roleId: string) {
|
||||||
const properties: RoleUnassignedEvent = {
|
const properties: RoleUnassignedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
roleId,
|
roleId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.ROLE_UNASSIGNED, properties)
|
await publishEvent(Event.ROLE_UNASSIGNED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
assigned,
|
||||||
|
unassigned,
|
||||||
|
}
|
||||||
|
|
|
@ -9,14 +9,14 @@ import {
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
export const created = async (count: number, timestamp?: string | number) => {
|
const created = async (count: number, timestamp?: string | number) => {
|
||||||
const properties: RowsCreatedEvent = {
|
const properties: RowsCreatedEvent = {
|
||||||
count,
|
count,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.ROWS_CREATED, properties, timestamp)
|
await publishEvent(Event.ROWS_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const imported = async (
|
const imported = async (
|
||||||
table: Table,
|
table: Table,
|
||||||
format: RowImportFormat,
|
format: RowImportFormat,
|
||||||
count: number
|
count: number
|
||||||
|
@ -28,3 +28,8 @@ export const imported = async (
|
||||||
}
|
}
|
||||||
await publishEvent(Event.ROWS_IMPORTED, properties)
|
await publishEvent(Event.ROWS_IMPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
imported,
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
ScreenDeletedEvent,
|
ScreenDeletedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(screen: Screen, timestamp?: string | number) {
|
async function created(screen: Screen, timestamp?: string | number) {
|
||||||
const properties: ScreenCreatedEvent = {
|
const properties: ScreenCreatedEvent = {
|
||||||
layoutId: screen.layoutId,
|
layoutId: screen.layoutId,
|
||||||
screenId: screen._id as string,
|
screenId: screen._id as string,
|
||||||
|
@ -15,7 +15,7 @@ export async function created(screen: Screen, timestamp?: string | number) {
|
||||||
await publishEvent(Event.SCREEN_CREATED, properties, timestamp)
|
await publishEvent(Event.SCREEN_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(screen: Screen) {
|
async function deleted(screen: Screen) {
|
||||||
const properties: ScreenDeletedEvent = {
|
const properties: ScreenDeletedEvent = {
|
||||||
layoutId: screen.layoutId,
|
layoutId: screen.layoutId,
|
||||||
screenId: screen._id as string,
|
screenId: screen._id as string,
|
||||||
|
@ -23,3 +23,8 @@ export async function deleted(screen: Screen) {
|
||||||
}
|
}
|
||||||
await publishEvent(Event.SCREEN_DELETED, properties)
|
await publishEvent(Event.SCREEN_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
deleted,
|
||||||
|
}
|
||||||
|
|
|
@ -7,14 +7,14 @@ import {
|
||||||
AppServedEvent,
|
AppServedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function servedBuilder(timezone: string) {
|
async function servedBuilder(timezone: string) {
|
||||||
const properties: BuilderServedEvent = {
|
const properties: BuilderServedEvent = {
|
||||||
timezone,
|
timezone,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.SERVED_BUILDER, properties)
|
await publishEvent(Event.SERVED_BUILDER, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function servedApp(app: App, timezone: string) {
|
async function servedApp(app: App, timezone: string) {
|
||||||
const properties: AppServedEvent = {
|
const properties: AppServedEvent = {
|
||||||
appVersion: app.version,
|
appVersion: app.version,
|
||||||
timezone,
|
timezone,
|
||||||
|
@ -22,7 +22,7 @@ export async function servedApp(app: App, timezone: string) {
|
||||||
await publishEvent(Event.SERVED_APP, properties)
|
await publishEvent(Event.SERVED_APP, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function servedAppPreview(app: App, timezone: string) {
|
async function servedAppPreview(app: App, timezone: string) {
|
||||||
const properties: AppPreviewServedEvent = {
|
const properties: AppPreviewServedEvent = {
|
||||||
appId: app.appId,
|
appId: app.appId,
|
||||||
appVersion: app.version,
|
appVersion: app.version,
|
||||||
|
@ -30,3 +30,9 @@ export async function servedAppPreview(app: App, timezone: string) {
|
||||||
}
|
}
|
||||||
await publishEvent(Event.SERVED_APP_PREVIEW, properties)
|
await publishEvent(Event.SERVED_APP_PREVIEW, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
servedBuilder,
|
||||||
|
servedApp,
|
||||||
|
servedAppPreview,
|
||||||
|
}
|
||||||
|
|
|
@ -11,28 +11,28 @@ import {
|
||||||
TableImportedEvent,
|
TableImportedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(table: Table, timestamp?: string | number) {
|
async function created(table: Table, timestamp?: string | number) {
|
||||||
const properties: TableCreatedEvent = {
|
const properties: TableCreatedEvent = {
|
||||||
tableId: table._id as string,
|
tableId: table._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.TABLE_CREATED, properties, timestamp)
|
await publishEvent(Event.TABLE_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(table: Table) {
|
async function updated(table: Table) {
|
||||||
const properties: TableUpdatedEvent = {
|
const properties: TableUpdatedEvent = {
|
||||||
tableId: table._id as string,
|
tableId: table._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.TABLE_UPDATED, properties)
|
await publishEvent(Event.TABLE_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(table: Table) {
|
async function deleted(table: Table) {
|
||||||
const properties: TableDeletedEvent = {
|
const properties: TableDeletedEvent = {
|
||||||
tableId: table._id as string,
|
tableId: table._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.TABLE_DELETED, properties)
|
await publishEvent(Event.TABLE_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exported(table: Table, format: TableExportFormat) {
|
async function exported(table: Table, format: TableExportFormat) {
|
||||||
const properties: TableExportedEvent = {
|
const properties: TableExportedEvent = {
|
||||||
tableId: table._id as string,
|
tableId: table._id as string,
|
||||||
format,
|
format,
|
||||||
|
@ -40,10 +40,18 @@ export async function exported(table: Table, format: TableExportFormat) {
|
||||||
await publishEvent(Event.TABLE_EXPORTED, properties)
|
await publishEvent(Event.TABLE_EXPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function imported(table: Table, format: TableImportFormat) {
|
async function imported(table: Table, format: TableImportFormat) {
|
||||||
const properties: TableImportedEvent = {
|
const properties: TableImportedEvent = {
|
||||||
tableId: table._id as string,
|
tableId: table._id as string,
|
||||||
format,
|
format,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.TABLE_IMPORTED, properties)
|
await publishEvent(Event.TABLE_IMPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
exported,
|
||||||
|
imported,
|
||||||
|
}
|
||||||
|
|
|
@ -15,21 +15,21 @@ import {
|
||||||
UserUpdatedEvent,
|
UserUpdatedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export async function created(user: User, timestamp?: number) {
|
async function created(user: User, timestamp?: number) {
|
||||||
const properties: UserCreatedEvent = {
|
const properties: UserCreatedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_CREATED, properties, timestamp)
|
await publishEvent(Event.USER_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(user: User) {
|
async function updated(user: User) {
|
||||||
const properties: UserUpdatedEvent = {
|
const properties: UserUpdatedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_UPDATED, properties)
|
await publishEvent(Event.USER_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(user: User) {
|
async function deleted(user: User) {
|
||||||
const properties: UserDeletedEvent = {
|
const properties: UserDeletedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ export async function deleted(user: User) {
|
||||||
|
|
||||||
// PERMISSIONS
|
// PERMISSIONS
|
||||||
|
|
||||||
export async function permissionAdminAssigned(user: User, timestamp?: number) {
|
async function permissionAdminAssigned(user: User, timestamp?: number) {
|
||||||
const properties: UserPermissionAssignedEvent = {
|
const properties: UserPermissionAssignedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
|
@ -49,17 +49,14 @@ export async function permissionAdminAssigned(user: User, timestamp?: number) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function permissionAdminRemoved(user: User) {
|
async function permissionAdminRemoved(user: User) {
|
||||||
const properties: UserPermissionRemovedEvent = {
|
const properties: UserPermissionRemovedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties)
|
await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function permissionBuilderAssigned(
|
async function permissionBuilderAssigned(user: User, timestamp?: number) {
|
||||||
user: User,
|
|
||||||
timestamp?: number
|
|
||||||
) {
|
|
||||||
const properties: UserPermissionAssignedEvent = {
|
const properties: UserPermissionAssignedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
|
@ -70,7 +67,7 @@ export async function permissionBuilderAssigned(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function permissionBuilderRemoved(user: User) {
|
async function permissionBuilderRemoved(user: User) {
|
||||||
const properties: UserPermissionRemovedEvent = {
|
const properties: UserPermissionRemovedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
|
@ -79,12 +76,12 @@ export async function permissionBuilderRemoved(user: User) {
|
||||||
|
|
||||||
// INVITE
|
// INVITE
|
||||||
|
|
||||||
export async function invited() {
|
async function invited() {
|
||||||
const properties: UserInvitedEvent = {}
|
const properties: UserInvitedEvent = {}
|
||||||
await publishEvent(Event.USER_INVITED, properties)
|
await publishEvent(Event.USER_INVITED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function inviteAccepted(user: User) {
|
async function inviteAccepted(user: User) {
|
||||||
const properties: UserInviteAcceptedEvent = {
|
const properties: UserInviteAcceptedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
|
@ -93,30 +90,46 @@ export async function inviteAccepted(user: User) {
|
||||||
|
|
||||||
// PASSWORD
|
// PASSWORD
|
||||||
|
|
||||||
export async function passwordForceReset(user: User) {
|
async function passwordForceReset(user: User) {
|
||||||
const properties: UserPasswordForceResetEvent = {
|
const properties: UserPasswordForceResetEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_PASSWORD_FORCE_RESET, properties)
|
await publishEvent(Event.USER_PASSWORD_FORCE_RESET, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function passwordUpdated(user: User) {
|
async function passwordUpdated(user: User) {
|
||||||
const properties: UserPasswordUpdatedEvent = {
|
const properties: UserPasswordUpdatedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_PASSWORD_UPDATED, properties)
|
await publishEvent(Event.USER_PASSWORD_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function passwordResetRequested(user: User) {
|
async function passwordResetRequested(user: User) {
|
||||||
const properties: UserPasswordResetRequestedEvent = {
|
const properties: UserPasswordResetRequestedEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_PASSWORD_RESET_REQUESTED, properties)
|
await publishEvent(Event.USER_PASSWORD_RESET_REQUESTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function passwordReset(user: User) {
|
async function passwordReset(user: User) {
|
||||||
const properties: UserPasswordResetEvent = {
|
const properties: UserPasswordResetEvent = {
|
||||||
userId: user._id as string,
|
userId: user._id as string,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.USER_PASSWORD_RESET, properties)
|
await publishEvent(Event.USER_PASSWORD_RESET, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
permissionAdminAssigned,
|
||||||
|
permissionAdminRemoved,
|
||||||
|
permissionBuilderAssigned,
|
||||||
|
permissionBuilderRemoved,
|
||||||
|
invited,
|
||||||
|
inviteAccepted,
|
||||||
|
passwordForceReset,
|
||||||
|
passwordUpdated,
|
||||||
|
passwordResetRequested,
|
||||||
|
passwordReset,
|
||||||
|
}
|
||||||
|
|
|
@ -19,28 +19,28 @@ import {
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
export async function created(view: View, timestamp?: string | number) {
|
async function created(view: View, timestamp?: string | number) {
|
||||||
const properties: ViewCreatedEvent = {
|
const properties: ViewCreatedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_CREATED, properties, timestamp)
|
await publishEvent(Event.VIEW_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updated(view: View) {
|
async function updated(view: View) {
|
||||||
const properties: ViewUpdatedEvent = {
|
const properties: ViewUpdatedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_UPDATED, properties)
|
await publishEvent(Event.VIEW_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleted(view: View) {
|
async function deleted(view: View) {
|
||||||
const properties: ViewDeletedEvent = {
|
const properties: ViewDeletedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_DELETED, properties)
|
await publishEvent(Event.VIEW_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exported(table: Table, format: TableExportFormat) {
|
async function exported(table: Table, format: TableExportFormat) {
|
||||||
const properties: ViewExportedEvent = {
|
const properties: ViewExportedEvent = {
|
||||||
tableId: table._id as string,
|
tableId: table._id as string,
|
||||||
format,
|
format,
|
||||||
|
@ -48,31 +48,28 @@ export async function exported(table: Table, format: TableExportFormat) {
|
||||||
await publishEvent(Event.VIEW_EXPORTED, properties)
|
await publishEvent(Event.VIEW_EXPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function filterCreated(view: View, timestamp?: string | number) {
|
async function filterCreated(view: View, timestamp?: string | number) {
|
||||||
const properties: ViewFilterCreatedEvent = {
|
const properties: ViewFilterCreatedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_FILTER_CREATED, properties, timestamp)
|
await publishEvent(Event.VIEW_FILTER_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function filterUpdated(view: View) {
|
async function filterUpdated(view: View) {
|
||||||
const properties: ViewFilterUpdatedEvent = {
|
const properties: ViewFilterUpdatedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_FILTER_UPDATED, properties)
|
await publishEvent(Event.VIEW_FILTER_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function filterDeleted(view: View) {
|
async function filterDeleted(view: View) {
|
||||||
const properties: ViewFilterDeletedEvent = {
|
const properties: ViewFilterDeletedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_FILTER_DELETED, properties)
|
await publishEvent(Event.VIEW_FILTER_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function calculationCreated(
|
async function calculationCreated(view: View, timestamp?: string | number) {
|
||||||
view: View,
|
|
||||||
timestamp?: string | number
|
|
||||||
) {
|
|
||||||
const properties: ViewCalculationCreatedEvent = {
|
const properties: ViewCalculationCreatedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
calculation: view.calculation as ViewCalculation,
|
calculation: view.calculation as ViewCalculation,
|
||||||
|
@ -80,7 +77,7 @@ export async function calculationCreated(
|
||||||
await publishEvent(Event.VIEW_CALCULATION_CREATED, properties, timestamp)
|
await publishEvent(Event.VIEW_CALCULATION_CREATED, properties, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function calculationUpdated(view: View) {
|
async function calculationUpdated(view: View) {
|
||||||
const properties: ViewCalculationUpdatedEvent = {
|
const properties: ViewCalculationUpdatedEvent = {
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
calculation: view.calculation as ViewCalculation,
|
calculation: view.calculation as ViewCalculation,
|
||||||
|
@ -88,10 +85,23 @@ export async function calculationUpdated(view: View) {
|
||||||
await publishEvent(Event.VIEW_CALCULATION_UPDATED, properties)
|
await publishEvent(Event.VIEW_CALCULATION_UPDATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function calculationDeleted(existingView: View) {
|
async function calculationDeleted(existingView: View) {
|
||||||
const properties: ViewCalculationDeletedEvent = {
|
const properties: ViewCalculationDeletedEvent = {
|
||||||
tableId: existingView.tableId,
|
tableId: existingView.tableId,
|
||||||
calculation: existingView.calculation as ViewCalculation,
|
calculation: existingView.calculation as ViewCalculation,
|
||||||
}
|
}
|
||||||
await publishEvent(Event.VIEW_CALCULATION_DELETED, properties)
|
await publishEvent(Event.VIEW_CALCULATION_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created,
|
||||||
|
updated,
|
||||||
|
deleted,
|
||||||
|
exported,
|
||||||
|
filterCreated,
|
||||||
|
filterUpdated,
|
||||||
|
filterDeleted,
|
||||||
|
calculationCreated,
|
||||||
|
calculationUpdated,
|
||||||
|
calculationDeleted,
|
||||||
|
}
|
||||||
|
|
|
@ -1,68 +1,42 @@
|
||||||
import errors from "./errors"
|
export * as events from "./events"
|
||||||
const errorClasses = errors.errors
|
export * as migrations from "./migrations"
|
||||||
import * as events from "./events"
|
export * as users from "./users"
|
||||||
import * as migrations from "./migrations"
|
export * as roles from "./security/roles"
|
||||||
import * as users from "./users"
|
export * as permissions from "./security/permissions"
|
||||||
import * as roles from "./security/roles"
|
export * as accounts from "./cloud/accounts"
|
||||||
import * as permissions from "./security/permissions"
|
export * as installation from "./installation"
|
||||||
import * as accounts from "./cloud/accounts"
|
export * as tenancy from "./tenancy"
|
||||||
import * as installation from "./installation"
|
export * as featureFlags from "./featureFlags"
|
||||||
import env from "./environment"
|
export * as sessions from "./security/sessions"
|
||||||
import * as tenancy from "./tenancy"
|
export * as deprovisioning from "./context/deprovision"
|
||||||
import * as featureFlags from "./featureFlags"
|
export * as auth from "./auth"
|
||||||
import * as sessions from "./security/sessions"
|
export * as constants from "./constants"
|
||||||
import * as deprovisioning from "./context/deprovision"
|
export * as logging from "./logging"
|
||||||
import * as auth from "./auth"
|
export * as middleware from "./middleware"
|
||||||
import * as constants from "./constants"
|
export * as plugins from "./plugin"
|
||||||
import * as logging from "./logging"
|
export * as encryption from "./security/encryption"
|
||||||
import * as pino from "./pino"
|
export * as queue from "./queue"
|
||||||
import * as middleware from "./middleware"
|
export * as db from "./db"
|
||||||
import * as plugins from "./plugin"
|
export * as context from "./context"
|
||||||
import * as encryption from "./security/encryption"
|
export * as cache from "./cache"
|
||||||
import * as queue from "./queue"
|
export * as objectStore from "./objectStore"
|
||||||
import * as db from "./db"
|
export * as redis from "./redis"
|
||||||
import * as context from "./context"
|
export * as utils from "./utils"
|
||||||
import * as cache from "./cache"
|
export * as errors from "./errors"
|
||||||
import * as objectStore from "./objectStore"
|
export { default as env } from "./environment"
|
||||||
import * as redis from "./redis"
|
|
||||||
import * as utils from "./utils"
|
|
||||||
|
|
||||||
const init = (opts: any = {}) => {
|
// expose error classes directly
|
||||||
|
export * from "./errors"
|
||||||
|
|
||||||
|
// expose constants directly
|
||||||
|
export * from "./constants"
|
||||||
|
|
||||||
|
// expose inner locks from redis directly
|
||||||
|
import * as redis from "./redis"
|
||||||
|
export const locks = redis.redlock
|
||||||
|
|
||||||
|
// expose package init function
|
||||||
|
import * as db from "./db"
|
||||||
|
export const init = (opts: any = {}) => {
|
||||||
db.init(opts.db)
|
db.init(opts.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
const core = {
|
|
||||||
init,
|
|
||||||
db,
|
|
||||||
...constants,
|
|
||||||
redis,
|
|
||||||
locks: redis.redlock,
|
|
||||||
objectStore,
|
|
||||||
utils,
|
|
||||||
users,
|
|
||||||
cache,
|
|
||||||
auth,
|
|
||||||
constants,
|
|
||||||
migrations,
|
|
||||||
env,
|
|
||||||
accounts,
|
|
||||||
tenancy,
|
|
||||||
context,
|
|
||||||
featureFlags,
|
|
||||||
events,
|
|
||||||
sessions,
|
|
||||||
deprovisioning,
|
|
||||||
installation,
|
|
||||||
errors,
|
|
||||||
logging,
|
|
||||||
roles,
|
|
||||||
plugins,
|
|
||||||
...pino,
|
|
||||||
...errorClasses,
|
|
||||||
middleware,
|
|
||||||
encryption,
|
|
||||||
queue,
|
|
||||||
permissions,
|
|
||||||
}
|
|
||||||
|
|
||||||
export = core
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import env from "./environment"
|
||||||
|
|
||||||
const NonErrors = ["AccountError"]
|
const NonErrors = ["AccountError"]
|
||||||
|
|
||||||
function isSuppressed(e?: any) {
|
function isSuppressed(e?: any) {
|
||||||
|
@ -29,8 +31,14 @@ export function logWarn(message: string) {
|
||||||
console.warn(`bb-warn: ${message}`)
|
console.warn(`bb-warn: ${message}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export function pinoSettings() {
|
||||||
logAlert,
|
return {
|
||||||
logAlertWithInfo,
|
prettyPrint: {
|
||||||
logWarn,
|
levelFirst: true,
|
||||||
|
},
|
||||||
|
level: env.LOG_LEVEL || "error",
|
||||||
|
autoLogging: {
|
||||||
|
ignore: (req: { url: string }) => req.url.includes("/health"),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BBContext } from "@budibase/types"
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
export = async (ctx: BBContext, next: any) => {
|
export default async (ctx: BBContext, next: any) => {
|
||||||
if (
|
if (
|
||||||
!ctx.internal &&
|
!ctx.internal &&
|
||||||
(!ctx.user || !ctx.user.admin || !ctx.user.admin.global)
|
(!ctx.user || !ctx.user.admin || !ctx.user.admin.global)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BBContext } from "@budibase/types"
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
export = async (ctx: BBContext | any, next: any) => {
|
export default async (ctx: BBContext | any, next: any) => {
|
||||||
// Placeholder for audit log middleware
|
// Placeholder for audit log middleware
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ async function checkApiKey(apiKey: string, populateUser?: Function) {
|
||||||
* The tenancy modules should not be used here and it should be assumed that the tenancy context
|
* The tenancy modules should not be used here and it should be assumed that the tenancy context
|
||||||
* has not yet been populated.
|
* has not yet been populated.
|
||||||
*/
|
*/
|
||||||
export = function (
|
export default function (
|
||||||
noAuthPatterns: EndpointMatcher[] = [],
|
noAuthPatterns: EndpointMatcher[] = [],
|
||||||
opts: { publicAllowed?: boolean; populateUser?: Function } = {
|
opts: { publicAllowed?: boolean; populateUser?: Function } = {
|
||||||
publicAllowed: false,
|
publicAllowed: false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BBContext } from "@budibase/types"
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
export = async (ctx: BBContext, next: any) => {
|
export default async (ctx: BBContext, next: any) => {
|
||||||
if (
|
if (
|
||||||
!ctx.internal &&
|
!ctx.internal &&
|
||||||
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BBContext } from "@budibase/types"
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
export = async (ctx: BBContext, next: any) => {
|
export default async (ctx: BBContext, next: any) => {
|
||||||
if (
|
if (
|
||||||
!ctx.internal &&
|
!ctx.internal &&
|
||||||
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global) &&
|
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global) &&
|
||||||
|
|
|
@ -32,7 +32,7 @@ const INCLUDED_CONTENT_TYPES = [
|
||||||
* https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern
|
* https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export = function (
|
export default function (
|
||||||
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
|
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
|
||||||
) {
|
) {
|
||||||
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
|
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
|
||||||
|
|
|
@ -1,38 +1,18 @@
|
||||||
import * as jwt from "./passport/jwt"
|
export * as jwt from "./passport/jwt"
|
||||||
import * as local from "./passport/local"
|
export * as local from "./passport/local"
|
||||||
import * as google from "./passport/google"
|
export * as google from "./passport/google"
|
||||||
import * as oidc from "./passport/oidc"
|
export * as oidc from "./passport/oidc"
|
||||||
import { authError, ssoCallbackUrl } from "./passport/utils"
|
|
||||||
import authenticated from "./authenticated"
|
|
||||||
import auditLog from "./auditLog"
|
|
||||||
import tenancy from "./tenancy"
|
|
||||||
import internalApi from "./internalApi"
|
|
||||||
import * as datasourceGoogle from "./passport/datasource/google"
|
import * as datasourceGoogle from "./passport/datasource/google"
|
||||||
import csrf from "./csrf"
|
export const datasource = {
|
||||||
import adminOnly from "./adminOnly"
|
google: datasourceGoogle,
|
||||||
import builderOrAdmin from "./builderOrAdmin"
|
|
||||||
import builderOnly from "./builderOnly"
|
|
||||||
import * as joiValidator from "./joi-validator"
|
|
||||||
|
|
||||||
const pkg = {
|
|
||||||
google,
|
|
||||||
oidc,
|
|
||||||
jwt,
|
|
||||||
local,
|
|
||||||
authenticated,
|
|
||||||
auditLog,
|
|
||||||
tenancy,
|
|
||||||
authError,
|
|
||||||
internalApi,
|
|
||||||
ssoCallbackUrl,
|
|
||||||
datasource: {
|
|
||||||
google: datasourceGoogle,
|
|
||||||
},
|
|
||||||
csrf,
|
|
||||||
adminOnly,
|
|
||||||
builderOnly,
|
|
||||||
builderOrAdmin,
|
|
||||||
joiValidator,
|
|
||||||
}
|
}
|
||||||
|
export { authError, ssoCallbackUrl } from "./passport/utils"
|
||||||
export = pkg
|
export { default as authenticated } from "./authenticated"
|
||||||
|
export { default as auditLog } from "./auditLog"
|
||||||
|
export { default as tenancy } from "./tenancy"
|
||||||
|
export { default as internalApi } from "./internalApi"
|
||||||
|
export { default as csrf } from "./csrf"
|
||||||
|
export { default as adminOnly } from "./adminOnly"
|
||||||
|
export { default as builderOrAdmin } from "./builderOrAdmin"
|
||||||
|
export { default as builderOnly } from "./builderOnly"
|
||||||
|
export * as joiValidator from "./joi-validator"
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { BBContext } from "@budibase/types"
|
||||||
/**
|
/**
|
||||||
* API Key only endpoint.
|
* API Key only endpoint.
|
||||||
*/
|
*/
|
||||||
export = async (ctx: BBContext, next: any) => {
|
export default async (ctx: BBContext, next: any) => {
|
||||||
const apiKey = ctx.request.headers[Header.API_KEY]
|
const apiKey = ctx.request.headers[Header.API_KEY]
|
||||||
if (apiKey !== env.INTERNAL_API_KEY) {
|
if (apiKey !== env.INTERNAL_API_KEY) {
|
||||||
ctx.throw(403, "Unauthorized")
|
ctx.throw(403, "Unauthorized")
|
||||||
|
|
|
@ -2,7 +2,6 @@ import fetch from "node-fetch"
|
||||||
import { authenticateThirdParty, SaveUserFunction } from "./third-party-common"
|
import { authenticateThirdParty, SaveUserFunction } from "./third-party-common"
|
||||||
import { ssoCallbackUrl } from "./utils"
|
import { ssoCallbackUrl } from "./utils"
|
||||||
import {
|
import {
|
||||||
Config,
|
|
||||||
ConfigType,
|
ConfigType,
|
||||||
OIDCInnerCfg,
|
OIDCInnerCfg,
|
||||||
Database,
|
Database,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
TenantResolutionStrategy,
|
TenantResolutionStrategy,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
export = function (
|
export default function (
|
||||||
allowQueryStringPatterns: EndpointMatcher[],
|
allowQueryStringPatterns: EndpointMatcher[],
|
||||||
noTenancyPatterns: EndpointMatcher[],
|
noTenancyPatterns: EndpointMatcher[],
|
||||||
opts: { noTenancyRequired?: boolean } = { noTenancyRequired: false }
|
opts: { noTenancyRequired?: boolean } = { noTenancyRequired: false }
|
||||||
|
|
|
@ -88,7 +88,7 @@ export const runMigration = async (
|
||||||
|
|
||||||
await doWithDB(dbName, async (db: any) => {
|
await doWithDB(dbName, async (db: any) => {
|
||||||
try {
|
try {
|
||||||
const doc = await exports.getMigrationsDoc(db)
|
const doc = await getMigrationsDoc(db)
|
||||||
|
|
||||||
// the migration has already been run
|
// the migration has already been run
|
||||||
if (doc[migrationName]) {
|
if (doc[migrationName]) {
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import env from "./environment"
|
|
||||||
|
|
||||||
export function pinoSettings() {
|
|
||||||
return {
|
|
||||||
prettyPrint: {
|
|
||||||
levelFirst: true,
|
|
||||||
},
|
|
||||||
level: env.LOG_LEVEL || "error",
|
|
||||||
autoLogging: {
|
|
||||||
ignore: (req: { url: string }) => req.url.includes("/health"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -137,4 +137,4 @@ class InMemoryQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export = InMemoryQueue
|
export default InMemoryQueue
|
||||||
|
|
|
@ -276,4 +276,4 @@ class RedisWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export = RedisWrapper
|
export default RedisWrapper
|
||||||
|
|
|
@ -12,9 +12,9 @@ function stretchString(string: string, salt: Buffer) {
|
||||||
return crypto.pbkdf2Sync(string, salt, ITERATIONS, STRETCH_LENGTH, "sha512")
|
return crypto.pbkdf2Sync(string, salt, ITERATIONS, STRETCH_LENGTH, "sha512")
|
||||||
}
|
}
|
||||||
|
|
||||||
export function encrypt(input: string) {
|
export function encrypt(input: string, secret: string | undefined = SECRET) {
|
||||||
const salt = crypto.randomBytes(RANDOM_BYTES)
|
const salt = crypto.randomBytes(RANDOM_BYTES)
|
||||||
const stretched = stretchString(SECRET!, salt)
|
const stretched = stretchString(secret!, salt)
|
||||||
const cipher = crypto.createCipheriv(ALGO, stretched, salt)
|
const cipher = crypto.createCipheriv(ALGO, stretched, salt)
|
||||||
const base = cipher.update(input)
|
const base = cipher.update(input)
|
||||||
const final = cipher.final()
|
const final = cipher.final()
|
||||||
|
@ -22,10 +22,10 @@ export function encrypt(input: string) {
|
||||||
return `${salt.toString("hex")}${SEPARATOR}${encrypted}`
|
return `${salt.toString("hex")}${SEPARATOR}${encrypted}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decrypt(input: string) {
|
export function decrypt(input: string, secret: string | undefined = SECRET) {
|
||||||
const [salt, encrypted] = input.split(SEPARATOR)
|
const [salt, encrypted] = input.split(SEPARATOR)
|
||||||
const saltBuffer = Buffer.from(salt, "hex")
|
const saltBuffer = Buffer.from(salt, "hex")
|
||||||
const stretched = stretchString(SECRET!, saltBuffer)
|
const stretched = stretchString(secret!, saltBuffer)
|
||||||
const decipher = crypto.createDecipheriv(ALGO, stretched, saltBuffer)
|
const decipher = crypto.createDecipheriv(ALGO, stretched, saltBuffer)
|
||||||
const base = decipher.update(Buffer.from(encrypted, "hex"))
|
const base = decipher.update(Buffer.from(encrypted, "hex"))
|
||||||
const final = decipher.final()
|
const final = decipher.final()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const redis = require("../redis/init")
|
const redis = require("../redis/init")
|
||||||
const { v4: uuidv4 } = require("uuid")
|
const { v4: uuidv4 } = require("uuid")
|
||||||
const { logWarn } = require("../logging")
|
const { logWarn } = require("../logging")
|
||||||
const env = require("../environment")
|
import env from "../environment"
|
||||||
import {
|
import {
|
||||||
Session,
|
Session,
|
||||||
ScannedSession,
|
ScannedSession,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { structures } from "../../../tests"
|
import { structures } from "../../../tests"
|
||||||
import * as utils from "../../utils"
|
import * as utils from "../../utils"
|
||||||
import * as events from "../../events"
|
import * as events from "../../events"
|
||||||
import { DEFAULT_TENANT_ID } from "../../constants"
|
import * as db from "../../db"
|
||||||
|
import { DEFAULT_TENANT_ID, Header } from "../../constants"
|
||||||
import { doInTenant } from "../../context"
|
import { doInTenant } from "../../context"
|
||||||
|
|
||||||
describe("utils", () => {
|
describe("utils", () => {
|
||||||
|
@ -14,4 +15,95 @@ describe("utils", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("getAppIdFromCtx", () => {
|
||||||
|
it("gets appId from header", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const expected = db.generateAppID()
|
||||||
|
ctx.request.headers = {
|
||||||
|
[Header.APP_ID]: expected,
|
||||||
|
}
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("gets appId from body", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const expected = db.generateAppID()
|
||||||
|
ctx.request.body = {
|
||||||
|
appId: expected,
|
||||||
|
}
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("gets appId from path", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const expected = db.generateAppID()
|
||||||
|
ctx.path = `/apps/${expected}`
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("gets appId from url", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const expected = db.generateAppID()
|
||||||
|
const app = structures.apps.app(expected)
|
||||||
|
|
||||||
|
// set custom url
|
||||||
|
const appUrl = "custom-url"
|
||||||
|
app.url = `/${appUrl}`
|
||||||
|
ctx.path = `/app/${appUrl}`
|
||||||
|
|
||||||
|
// save the app
|
||||||
|
const database = db.getDB(expected)
|
||||||
|
await database.put(app)
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("doesn't get appId from url when previewing", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const appId = db.generateAppID()
|
||||||
|
const app = structures.apps.app(appId)
|
||||||
|
|
||||||
|
// set custom url
|
||||||
|
const appUrl = "preview"
|
||||||
|
app.url = `/${appUrl}`
|
||||||
|
ctx.path = `/app/${appUrl}`
|
||||||
|
|
||||||
|
// save the app
|
||||||
|
const database = db.getDB(appId)
|
||||||
|
await database.put(app)
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(undefined)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("gets appId from referer", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const expected = db.generateAppID()
|
||||||
|
ctx.request.headers = {
|
||||||
|
referer: `http://test.com/builder/app/${expected}/design/screen_123/screens`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("doesn't get appId from referer when not builder", async () => {
|
||||||
|
const ctx = structures.koa.newContext()
|
||||||
|
const appId = db.generateAppID()
|
||||||
|
ctx.request.headers = {
|
||||||
|
referer: `http://test.com/foo/app/${appId}/bar`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const actual = await utils.getAppIdFromCtx(ctx)
|
||||||
|
expect(actual).toBe(undefined)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,13 +25,16 @@ const jwt = require("jsonwebtoken")
|
||||||
const APP_PREFIX = DocumentType.APP + SEPARATOR
|
const APP_PREFIX = DocumentType.APP + SEPARATOR
|
||||||
const PROD_APP_PREFIX = "/app/"
|
const PROD_APP_PREFIX = "/app/"
|
||||||
|
|
||||||
|
const BUILDER_PREVIEW_PATH = "/app/preview"
|
||||||
|
const BUILDER_REFERER_PREFIX = "/builder/app/"
|
||||||
|
|
||||||
function confirmAppId(possibleAppId: string | undefined) {
|
function confirmAppId(possibleAppId: string | undefined) {
|
||||||
return possibleAppId && possibleAppId.startsWith(APP_PREFIX)
|
return possibleAppId && possibleAppId.startsWith(APP_PREFIX)
|
||||||
? possibleAppId
|
? possibleAppId
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveAppUrl(ctx: Ctx) {
|
export async function resolveAppUrl(ctx: Ctx) {
|
||||||
const appUrl = ctx.path.split("/")[2]
|
const appUrl = ctx.path.split("/")[2]
|
||||||
let possibleAppUrl = `/${appUrl.toLowerCase()}`
|
let possibleAppUrl = `/${appUrl.toLowerCase()}`
|
||||||
|
|
||||||
|
@ -75,7 +78,7 @@ export function isServingApp(ctx: Ctx) {
|
||||||
*/
|
*/
|
||||||
export async function getAppIdFromCtx(ctx: Ctx) {
|
export async function getAppIdFromCtx(ctx: Ctx) {
|
||||||
// look in headers
|
// look in headers
|
||||||
const options = [ctx.headers[Header.APP_ID]]
|
const options = [ctx.request.headers[Header.APP_ID]]
|
||||||
let appId
|
let appId
|
||||||
for (let option of options) {
|
for (let option of options) {
|
||||||
appId = confirmAppId(option as string)
|
appId = confirmAppId(option as string)
|
||||||
|
@ -95,15 +98,23 @@ export async function getAppIdFromCtx(ctx: Ctx) {
|
||||||
appId = confirmAppId(pathId)
|
appId = confirmAppId(pathId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// look in the referer
|
// lookup using custom url - prod apps only
|
||||||
const refererId = parseAppIdFromUrl(ctx.request.headers.referer)
|
// filter out the builder preview path which collides with the prod app path
|
||||||
if (!appId && refererId) {
|
// to ensure we don't load all apps excessively
|
||||||
appId = confirmAppId(refererId)
|
const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH)
|
||||||
|
const isViewingProdApp =
|
||||||
|
ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview
|
||||||
|
if (!appId && isViewingProdApp) {
|
||||||
|
appId = confirmAppId(await resolveAppUrl(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// look in the url - prod app
|
// look in the referer - builder only
|
||||||
if (!appId && ctx.path.startsWith(PROD_APP_PREFIX)) {
|
// make sure this is performed after prod app url resolution, in case the
|
||||||
appId = confirmAppId(await resolveAppUrl(ctx))
|
// referer header is present from a builder redirect
|
||||||
|
const referer = ctx.request.headers.referer
|
||||||
|
if (!appId && referer?.includes(BUILDER_REFERER_PREFIX)) {
|
||||||
|
const refererId = parseAppIdFromUrl(ctx.request.headers.referer)
|
||||||
|
appId = confirmAppId(refererId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return appId
|
return appId
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
export const getAccount = jest.fn()
|
const mockGetAccount = jest.fn()
|
||||||
export const getAccountByTenantId = jest.fn()
|
const mockGetAccountByTenantId = jest.fn()
|
||||||
export const getStatus = jest.fn()
|
const mockGetStatus = jest.fn()
|
||||||
|
|
||||||
jest.mock("../../../src/cloud/accounts", () => ({
|
jest.mock("../../../src/cloud/accounts", () => ({
|
||||||
getAccount,
|
getAccount: mockGetAccount,
|
||||||
getAccountByTenantId,
|
getAccountByTenantId: mockGetAccountByTenantId,
|
||||||
getStatus,
|
getStatus: mockGetStatus,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
export const getAccount = mockGetAccount
|
||||||
|
export const getAccountByTenantId = mockGetAccountByTenantId
|
||||||
|
export const getStatus = mockGetStatus
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
const processors = require("../../../src/events/processors")
|
import * as processors from "../../../src/events/processors"
|
||||||
|
import * as events from "../../../src/events"
|
||||||
|
|
||||||
jest.spyOn(processors.analyticsProcessor, "processEvent")
|
jest.spyOn(processors.analyticsProcessor, "processEvent")
|
||||||
|
|
||||||
const events = require("../../../src/events")
|
|
||||||
|
|
||||||
jest.spyOn(events.identification, "identifyTenantGroup")
|
jest.spyOn(events.identification, "identifyTenantGroup")
|
||||||
jest.spyOn(events.identification, "identifyUser")
|
jest.spyOn(events.identification, "identifyUser")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { generator } from "."
|
||||||
|
import { App } from "@budibase/types"
|
||||||
|
import { DEFAULT_TENANT_ID, DocumentType } from "../../../src/constants"
|
||||||
|
|
||||||
|
export function app(id: string): App {
|
||||||
|
return {
|
||||||
|
_id: DocumentType.APP_METADATA,
|
||||||
|
appId: id,
|
||||||
|
type: "",
|
||||||
|
version: "0.0.1",
|
||||||
|
componentLibraries: [],
|
||||||
|
name: generator.name(),
|
||||||
|
url: `/custom-url`,
|
||||||
|
instance: {
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
tenantId: DEFAULT_TENANT_ID,
|
||||||
|
status: "",
|
||||||
|
template: undefined,
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,8 @@ export * from "./common"
|
||||||
import Chance from "chance"
|
import Chance from "chance"
|
||||||
export const generator = new Chance()
|
export const generator = new Chance()
|
||||||
|
|
||||||
export * as koa from "./koa"
|
|
||||||
export * as accounts from "./accounts"
|
export * as accounts from "./accounts"
|
||||||
|
export * as apps from "./apps"
|
||||||
|
export * as koa from "./koa"
|
||||||
export * as licenses from "./licenses"
|
export * as licenses from "./licenses"
|
||||||
export * as plugins from "./plugins"
|
export * as plugins from "./plugins"
|
||||||
|
|
|
@ -5,9 +5,11 @@ export const newContext = (): BBContext => {
|
||||||
const ctx = createMockContext()
|
const ctx = createMockContext()
|
||||||
return {
|
return {
|
||||||
...ctx,
|
...ctx,
|
||||||
|
path: "/",
|
||||||
cookies: createMockCookies(),
|
cookies: createMockCookies(),
|
||||||
request: {
|
request: {
|
||||||
...ctx.request,
|
...ctx.request,
|
||||||
|
headers: {},
|
||||||
body: {},
|
body: {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"dist",
|
"dist",
|
||||||
"**/*.spec.ts",
|
"**/*.spec.ts",
|
||||||
"**/*.spec.js"
|
"**/*.spec.js",
|
||||||
|
"__mocks__"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -12,6 +12,6 @@
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"dist"
|
"dist",
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -564,6 +564,13 @@
|
||||||
slash "^3.0.0"
|
slash "^3.0.0"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
"@jest/create-cache-key-function@^27.4.2":
|
||||||
|
version "27.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz#7448fae15602ea95c828f5eceed35c202a820b31"
|
||||||
|
integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==
|
||||||
|
dependencies:
|
||||||
|
"@jest/types" "^27.5.1"
|
||||||
|
|
||||||
"@jest/environment@^28.1.3":
|
"@jest/environment@^28.1.3":
|
||||||
version "28.1.3"
|
version "28.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e"
|
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e"
|
||||||
|
@ -698,6 +705,17 @@
|
||||||
slash "^3.0.0"
|
slash "^3.0.0"
|
||||||
write-file-atomic "^4.0.1"
|
write-file-atomic "^4.0.1"
|
||||||
|
|
||||||
|
"@jest/types@^27.5.1":
|
||||||
|
version "27.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80"
|
||||||
|
integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==
|
||||||
|
dependencies:
|
||||||
|
"@types/istanbul-lib-coverage" "^2.0.0"
|
||||||
|
"@types/istanbul-reports" "^3.0.0"
|
||||||
|
"@types/node" "*"
|
||||||
|
"@types/yargs" "^16.0.0"
|
||||||
|
chalk "^4.0.0"
|
||||||
|
|
||||||
"@jest/types@^28.1.1", "@jest/types@^28.1.3":
|
"@jest/types@^28.1.1", "@jest/types@^28.1.3":
|
||||||
version "28.1.3"
|
version "28.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b"
|
resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b"
|
||||||
|
@ -884,6 +902,80 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sinonjs/commons" "^1.7.0"
|
"@sinonjs/commons" "^1.7.0"
|
||||||
|
|
||||||
|
"@swc/core-darwin-arm64@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.25.tgz#01ce7b8a88b545a4fc5283ed6f96b22c5733d6c4"
|
||||||
|
integrity sha512-8PWAVcjTJyj2VrqPBFOIi2w2P0Z8kOCbzHW3+pe+bSXxfGMG0MKPl5U2IXhsEL0ovm4xSFlqW0yygpoP3MmRPw==
|
||||||
|
|
||||||
|
"@swc/core-darwin-x64@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.25.tgz#9fad102c507011f42c5a5d1f84919b81ab96d7f8"
|
||||||
|
integrity sha512-5DHGiMYFEj5aa208tCjo7Sn5tiG4xPz+4gUiWVlglxqXFptkNim5xu/1G6VYm5Zk7dI5jJkjTU76GQG7IRvPug==
|
||||||
|
|
||||||
|
"@swc/core-linux-arm-gnueabihf@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.25.tgz#ecf3a34899fdbdc742523524caab29c0db97a6ad"
|
||||||
|
integrity sha512-YNfLxv9PhZk+jrJbpR1mMrYBUkufo0hiFv3S1OrX3l8edsIP4wPND5w9ZH0Oi898f6Jg9DBrY2zXJMQ+gWkbvA==
|
||||||
|
|
||||||
|
"@swc/core-linux-arm64-gnu@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.25.tgz#50524c9db2dbf874570e45f0a66e0283f02bc2d9"
|
||||||
|
integrity sha512-kS+spM5/xQ6QvWF1ms3byfjnhUlpjTfFwgCyHnIKgjvsYkDa+vkAIhKq6HuEdaTPaCRCjts0Zarhub1nClUU0g==
|
||||||
|
|
||||||
|
"@swc/core-linux-arm64-musl@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.25.tgz#f04a3d3784cff14f96ad9901861485ec0fa14ebf"
|
||||||
|
integrity sha512-vM3D7LWmjotUAJ2D4F+L+dspFeWrcPNVh0o8TCoTOYCt8DPD5YsUKTpIgOsZ+gReeWUAnNTh0Btx5pGGVfajGA==
|
||||||
|
|
||||||
|
"@swc/core-linux-x64-gnu@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.25.tgz#761fb020b8a0130e4dccc9c8dce355fa06df63f4"
|
||||||
|
integrity sha512-xUCLLMDlYa/zB8BftVa4SrxuVpcDxkltCfmBg5r2pZPVskhC5ZJsQZ/AvWNChoAB11shRhjTaWDlmxJEsa7TIg==
|
||||||
|
|
||||||
|
"@swc/core-linux-x64-musl@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.25.tgz#f944ee48c972ebdcb3e6d6fd62d67eb98dbb1268"
|
||||||
|
integrity sha512-QzHU3BIaUVRSFNsUn3Qxx1vgtF/f5NqsFMAAPSq9Y8Yq5nrlc2t7cNuOROxHLbUqE+NPUp6+RglleJMoeWz5mA==
|
||||||
|
|
||||||
|
"@swc/core-win32-arm64-msvc@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.25.tgz#af63ae850ef6e7322e8a5a0959529e96096239d2"
|
||||||
|
integrity sha512-77VSVtneVOAUL4zkRyQZ6pWVpTsVVdqwly/DKnRnloglGKxYuk5DG5MUBsL72Nnfv4OCHjZ27eI3NUrpLsUb2Q==
|
||||||
|
|
||||||
|
"@swc/core-win32-ia32-msvc@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.25.tgz#96a869aa4b4c41c44c9c9893ac4aad68d1233022"
|
||||||
|
integrity sha512-kz0v3K3H6OPEZR3ry72Ad/6C5GrZBRRUk69K58LORQ8tZXQD3UGl85pUbQqyHl8fR5NU76Muxgovj9CI9iTHGA==
|
||||||
|
|
||||||
|
"@swc/core-win32-x64-msvc@1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.25.tgz#9035c11626653322a404f3f44af11a02d989094c"
|
||||||
|
integrity sha512-nmQOAzIpNRRnupWzkenJmW4i+h1M76cVNUqEU2MjmtesEkRZEGqv//jefXiyCP2zcbeLNLKiB2ptVJhpd1BvRA==
|
||||||
|
|
||||||
|
"@swc/core@^1.3.25":
|
||||||
|
version "1.3.25"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.25.tgz#53786ea51fac319684d6822de1738eb55b73a4b7"
|
||||||
|
integrity sha512-wqzvM/wu6OsTVYPMStOpm7kIQcPX3GoZ0sC85qzDdsCxmJ1rmItLAD91sXPUmmdk0XqPYjLgT9MRDEIP5woz4g==
|
||||||
|
optionalDependencies:
|
||||||
|
"@swc/core-darwin-arm64" "1.3.25"
|
||||||
|
"@swc/core-darwin-x64" "1.3.25"
|
||||||
|
"@swc/core-linux-arm-gnueabihf" "1.3.25"
|
||||||
|
"@swc/core-linux-arm64-gnu" "1.3.25"
|
||||||
|
"@swc/core-linux-arm64-musl" "1.3.25"
|
||||||
|
"@swc/core-linux-x64-gnu" "1.3.25"
|
||||||
|
"@swc/core-linux-x64-musl" "1.3.25"
|
||||||
|
"@swc/core-win32-arm64-msvc" "1.3.25"
|
||||||
|
"@swc/core-win32-ia32-msvc" "1.3.25"
|
||||||
|
"@swc/core-win32-x64-msvc" "1.3.25"
|
||||||
|
|
||||||
|
"@swc/jest@^0.2.24":
|
||||||
|
version "0.2.24"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/jest/-/jest-0.2.24.tgz#35d9377ede049613cd5fdd6c24af2b8dcf622875"
|
||||||
|
integrity sha512-fwgxQbM1wXzyKzl1+IW0aGrRvAA8k0Y3NxFhKigbPjOJ4mCKnWEcNX9HQS3gshflcxq8YKhadabGUVfdwjCr6Q==
|
||||||
|
dependencies:
|
||||||
|
"@jest/create-cache-key-function" "^27.4.2"
|
||||||
|
jsonc-parser "^3.2.0"
|
||||||
|
|
||||||
"@szmarczak/http-timer@^1.1.2":
|
"@szmarczak/http-timer@^1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
|
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
|
||||||
|
@ -1362,6 +1454,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
|
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
|
||||||
integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==
|
integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==
|
||||||
|
|
||||||
|
"@types/yargs@^16.0.0":
|
||||||
|
version "16.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3"
|
||||||
|
integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/yargs-parser" "*"
|
||||||
|
|
||||||
"@types/yargs@^17.0.8":
|
"@types/yargs@^17.0.8":
|
||||||
version "17.0.13"
|
version "17.0.13"
|
||||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76"
|
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76"
|
||||||
|
@ -3546,9 +3645,14 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||||
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
|
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
|
||||||
|
|
||||||
json5@^2.2.1:
|
json5@^2.2.1:
|
||||||
version "2.2.3"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
|
||||||
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
|
||||||
|
|
||||||
|
jsonc-parser@^3.2.0:
|
||||||
|
version "3.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
|
||||||
|
integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
|
||||||
|
|
||||||
jsonwebtoken@9.0.0:
|
jsonwebtoken@9.0.0:
|
||||||
version "9.0.0"
|
version "9.0.0"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/bbui",
|
"name": "@budibase/bbui",
|
||||||
"description": "A UI solution used in the different Budibase projects.",
|
"description": "A UI solution used in the different Budibase projects.",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"module": "dist/bbui.es.js",
|
"module": "dist/bbui.es.js",
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
||||||
"@budibase/string-templates": "2.2.12-alpha.2",
|
"@budibase/string-templates": "2.2.12-alpha.10",
|
||||||
"@spectrum-css/actionbutton": "1.0.1",
|
"@spectrum-css/actionbutton": "1.0.1",
|
||||||
"@spectrum-css/actiongroup": "1.0.1",
|
"@spectrum-css/actiongroup": "1.0.1",
|
||||||
"@spectrum-css/avatar": "3.0.2",
|
"@spectrum-css/avatar": "3.0.2",
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
.main {
|
.main {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@ -57,10 +58,10 @@
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
.wide {
|
.content.wide {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
.narrow {
|
.content.narrow {
|
||||||
max-width: 840px;
|
max-width: 840px;
|
||||||
}
|
}
|
||||||
#side-panel {
|
#side-panel {
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
border-left: var(--border-light);
|
border-left: var(--border-light);
|
||||||
width: 320px;
|
width: 320px;
|
||||||
|
max-width: calc(100vw - 48px - 48px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
transform: translateX(100%);
|
transform: translateX(100%);
|
||||||
|
@ -81,4 +83,13 @@
|
||||||
#side-panel.visible {
|
#side-panel.visible {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.content {
|
||||||
|
padding: 24px;
|
||||||
|
max-width: calc(100vw - 48px) !important;
|
||||||
|
width: calc(100vw - 48px) !important;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,9 +13,9 @@ filterTests(["smoke", "all"], () => {
|
||||||
const datasource = "REST"
|
const datasource = "REST"
|
||||||
const restUrl = "https://api.openbrewerydb.org/breweries"
|
const restUrl = "https://api.openbrewerydb.org/breweries"
|
||||||
cy.selectExternalDatasource(datasource)
|
cy.selectExternalDatasource(datasource)
|
||||||
cy.createRestQuery("GET", restUrl, "/breweries")
|
cy.createRestQuery("GET", restUrl, "breweries")
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.contains(".nav-item-content", "/breweries", { timeout: 20000 }).click()
|
cy.contains(".nav-item-content", "breweries", { timeout: 20000 }).click()
|
||||||
cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true })
|
cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true })
|
||||||
// Get Transformer Function from file
|
// Get Transformer Function from file
|
||||||
cy.readFile("cypress/support/queryLevelTransformerFunction.js").then(
|
cy.readFile("cypress/support/queryLevelTransformerFunction.js").then(
|
||||||
|
@ -44,9 +44,9 @@ filterTests(["smoke", "all"], () => {
|
||||||
const datasource = "REST"
|
const datasource = "REST"
|
||||||
const restUrl = "https://api.openbrewerydb.org/breweries"
|
const restUrl = "https://api.openbrewerydb.org/breweries"
|
||||||
cy.selectExternalDatasource(datasource)
|
cy.selectExternalDatasource(datasource)
|
||||||
cy.createRestQuery("GET", restUrl, "/breweries")
|
cy.createRestQuery("GET", restUrl, "breweries")
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.contains(".nav-item-content", "/breweries", { timeout: 2000 }).click()
|
cy.contains(".nav-item-content", "breweries", { timeout: 2000 }).click()
|
||||||
cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true })
|
cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true })
|
||||||
// Get Transformer Function with Data from file
|
// Get Transformer Function with Data from file
|
||||||
cy.readFile(
|
cy.readFile(
|
||||||
|
@ -75,9 +75,9 @@ filterTests(["smoke", "all"], () => {
|
||||||
const datasource = "REST"
|
const datasource = "REST"
|
||||||
const restUrl = "https://api.openbrewerydb.org/breweries"
|
const restUrl = "https://api.openbrewerydb.org/breweries"
|
||||||
cy.selectExternalDatasource(datasource)
|
cy.selectExternalDatasource(datasource)
|
||||||
cy.createRestQuery("GET", restUrl, "/breweries")
|
cy.createRestQuery("GET", restUrl, "breweries")
|
||||||
cy.reload()
|
cy.reload()
|
||||||
cy.contains(".nav-item-content", "/breweries", { timeout: 2000 }).click()
|
cy.contains(".nav-item-content", "breweries", { timeout: 10000 }).click()
|
||||||
cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true })
|
cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true })
|
||||||
// Clear the code box and add "test"
|
// Clear the code box and add "test"
|
||||||
cy.get(interact.CODEMIRROR_TEXTAREA)
|
cy.get(interact.CODEMIRROR_TEXTAREA)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -71,10 +71,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "2.2.12-alpha.2",
|
"@budibase/bbui": "2.2.12-alpha.10",
|
||||||
"@budibase/client": "2.2.12-alpha.2",
|
"@budibase/client": "2.2.12-alpha.10",
|
||||||
"@budibase/frontend-core": "2.2.12-alpha.2",
|
"@budibase/frontend-core": "2.2.12-alpha.10",
|
||||||
"@budibase/string-templates": "2.2.12-alpha.2",
|
"@budibase/string-templates": "2.2.12-alpha.10",
|
||||||
"@sentry/browser": "5.19.1",
|
"@sentry/browser": "5.19.1",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
|
|
|
@ -63,7 +63,8 @@
|
||||||
name="LockClosed"
|
name="LockClosed"
|
||||||
hoverable
|
hoverable
|
||||||
size={buttonSize}
|
size={buttonSize}
|
||||||
on:click={() => {
|
on:click={e => {
|
||||||
|
e.stopPropagation()
|
||||||
appLockModal.show()
|
appLockModal.show()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -144,6 +144,11 @@
|
||||||
drawer.show()
|
drawer.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getQueryValue = queries => {
|
||||||
|
value = queries.find(q => q._id === value._id) || value
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
const saveQueryParams = () => {
|
const saveQueryParams = () => {
|
||||||
handleSelected({
|
handleSelected({
|
||||||
...value,
|
...value,
|
||||||
|
@ -175,7 +180,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
<IntegrationQueryEditor
|
<IntegrationQueryEditor
|
||||||
height={200}
|
height={200}
|
||||||
query={value}
|
query={getQueryValue(queries)}
|
||||||
schema={fetchQueryDefinition(value)}
|
schema={fetchQueryDefinition(value)}
|
||||||
datasource={getQueryDatasource(value)}
|
datasource={getQueryDatasource(value)}
|
||||||
editable={false}
|
editable={false}
|
||||||
|
|
|
@ -117,10 +117,17 @@
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cleanUrl = inputUrl =>
|
||||||
|
url
|
||||||
|
?.replace(/(http)|(https)|[{}:]/g, "")
|
||||||
|
?.replaceAll(".", "_")
|
||||||
|
?.replaceAll("/", " ")
|
||||||
|
?.trim() || inputUrl
|
||||||
|
|
||||||
function checkQueryName(inputUrl = null) {
|
function checkQueryName(inputUrl = null) {
|
||||||
if (query && (!query.name || query.flags.urlName)) {
|
if (query && (!query.name || query.flags.urlName)) {
|
||||||
query.flags.urlName = true
|
query.flags.urlName = true
|
||||||
query.name = url || inputUrl
|
query.name = cleanUrl(inputUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@
|
||||||
{#if !query.fields.steps?.length}
|
{#if !query.fields.steps?.length}
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<Button
|
<Button
|
||||||
|
disabled={!editable}
|
||||||
secondary
|
secondary
|
||||||
slot="buttons"
|
slot="buttons"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
@ -131,6 +132,7 @@
|
||||||
{#if index > 0}
|
{#if index > 0}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
quiet
|
quiet
|
||||||
|
disabled={!editable}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
updateEditorsOnSwap(index, index - 1)
|
updateEditorsOnSwap(index, index - 1)
|
||||||
const target = query.fields.steps[index - 1].key
|
const target = query.fields.steps[index - 1].key
|
||||||
|
@ -144,6 +146,7 @@
|
||||||
{#if index < query.fields.steps.length - 1}
|
{#if index < query.fields.steps.length - 1}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
quiet
|
quiet
|
||||||
|
disabled={!editable}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
updateEditorsOnSwap(index, index + 1)
|
updateEditorsOnSwap(index, index + 1)
|
||||||
const target = query.fields.steps[index + 1].key
|
const target = query.fields.steps[index + 1].key
|
||||||
|
@ -156,6 +159,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
disabled={!editable}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
updateEditorsOnDelete(index)
|
updateEditorsOnDelete(index)
|
||||||
query.fields.steps.splice(index, 1)
|
query.fields.steps.splice(index, 1)
|
||||||
|
@ -169,6 +173,7 @@
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="block-field">
|
<div class="block-field">
|
||||||
<Select
|
<Select
|
||||||
|
disabled={!editable}
|
||||||
value={step.key}
|
value={step.key}
|
||||||
options={schema.steps.map(s => s.key)}
|
options={schema.steps.map(s => s.key)}
|
||||||
on:change={({ detail }) => {
|
on:change={({ detail }) => {
|
||||||
|
@ -178,6 +183,7 @@
|
||||||
<Editor
|
<Editor
|
||||||
bind:this={stepEditors[index]}
|
bind:this={stepEditors[index]}
|
||||||
editorHeight={height / 2}
|
editorHeight={height / 2}
|
||||||
|
readOnly={!editable}
|
||||||
mode="json"
|
mode="json"
|
||||||
value={typeof step.value === "string"
|
value={typeof step.value === "string"
|
||||||
? step.value
|
? step.value
|
||||||
|
@ -194,9 +200,11 @@
|
||||||
<div class="separator" />
|
<div class="separator" />
|
||||||
{#if index === query.fields.steps.length - 1}
|
{#if index === query.fields.steps.length - 1}
|
||||||
<Icon
|
<Icon
|
||||||
|
disabled={!editable}
|
||||||
hoverable
|
hoverable
|
||||||
name="AddCircle"
|
name="AddCircle"
|
||||||
size="S"
|
size="S"
|
||||||
|
readOnly={!editable}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
query.fields.steps = [
|
query.fields.steps = [
|
||||||
...query.fields.steps,
|
...query.fields.steps,
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
export let narrow = false
|
export let narrow = false
|
||||||
|
export let showMobileNav = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="side-nav">
|
<div class="side-nav" class:show-mobile={showMobileNav}>
|
||||||
<slot name="side-nav" />
|
<slot name="side-nav" />
|
||||||
</div>
|
</div>
|
||||||
<div class="main" class:narrow>
|
<div class="main" class:narrow>
|
||||||
|
@ -28,4 +29,18 @@
|
||||||
.main.narrow {
|
.main.narrow {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.content {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.side-nav:not(.show-mobile) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.side-nav.show-mobile :global(.side-nav) {
|
||||||
|
border-bottom: var(--border-light);
|
||||||
|
margin: 0 -24px;
|
||||||
|
padding: 0 24px 32px 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
import { Heading } from "@budibase/bbui"
|
import { Heading } from "@budibase/bbui"
|
||||||
|
|
||||||
export let title
|
export let title
|
||||||
|
export let wrap = true
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="header">
|
<div class="header" class:wrap>
|
||||||
<slot name="icon" />
|
<slot name="icon" />
|
||||||
<Heading size="L">{title}</Heading>
|
<Heading size="L">{title}</Heading>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
|
@ -20,10 +21,19 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--spacing-xl);
|
gap: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
.header.wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
.header :global(.spectrum-Heading) {
|
.header :global(.spectrum-Heading) {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
.header:not(.wrap) :global(.spectrum-Heading) {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
.buttons {
|
.buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -34,4 +44,9 @@
|
||||||
.buttons :global(> div) {
|
.buttons :global(> div) {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.wrap .buttons {
|
||||||
|
margin-bottom: var(--spacing-m);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,41 +8,39 @@
|
||||||
export let appOverview
|
export let appOverview
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="app-row">
|
<div class="app-row" on:click={() => editApp(app)}>
|
||||||
<div class="header">
|
<div class="title" data-cy={`${app.devId}`}>
|
||||||
<div class="title" data-cy={`${app.devId}`}>
|
<div class="app-icon">
|
||||||
<div class="app-icon">
|
<Icon size="L" name={app.icon?.name || "Apps"} color={app.icon?.color} />
|
||||||
<Icon
|
|
||||||
size="L"
|
|
||||||
name={app.icon?.name || "Apps"}
|
|
||||||
color={app.icon?.color}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="name" data-cy="app-name-link" on:click={() => editApp(app)}>
|
|
||||||
<Heading size="S">
|
|
||||||
{app.name}
|
|
||||||
</Heading>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="name" data-cy="app-name-link">
|
||||||
|
<Heading size="S">
|
||||||
|
{app.name}
|
||||||
|
</Heading>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="updated">
|
<div class="updated">
|
||||||
{#if app.updatedAt}
|
{#if app.updatedAt}
|
||||||
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
|
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
|
||||||
time: new Date().getTime() - new Date(app.updatedAt).getTime(),
|
time: new Date().getTime() - new Date(app.updatedAt).getTime(),
|
||||||
})}
|
})}
|
||||||
{:else}
|
{:else}
|
||||||
Never updated
|
Never updated
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="title app-status" class:deployed={app.deployed}>
|
<div class="title app-status" class:deployed={app.deployed}>
|
||||||
<Icon size="L" name={app.deployed ? "GlobeCheck" : "GlobeStrike"} />
|
<Icon size="L" name={app.deployed ? "GlobeCheck" : "GlobeStrike"} />
|
||||||
<Body size="S">{`${window.origin}/app${app.url}`}</Body>
|
<Body size="S">{app.deployed ? "Published" : "Unpublished"}</Body>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-cy={`row_actions_${app.appId}`}>
|
<div data-cy={`row_actions_${app.appId}`}>
|
||||||
<div class="app-row-actions">
|
<div class="app-row-actions">
|
||||||
|
<AppLockModal {app} buttonSize="M" />
|
||||||
|
<Button size="S" secondary on:click={() => appOverview(app)}>
|
||||||
|
Manage
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="S"
|
size="S"
|
||||||
primary
|
primary
|
||||||
|
@ -51,10 +49,6 @@
|
||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="S" secondary on:click={() => appOverview(app)}>
|
|
||||||
Manage
|
|
||||||
</Button>
|
|
||||||
<AppLockModal {app} buttonSize="M" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,24 +58,29 @@
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
padding: 24px 32px;
|
padding: 24px 32px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-columns: 35% 25% 15% auto;
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
gap: var(--spacing-m);
|
||||||
|
transition: border 130ms ease-out;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
.app-row:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
border-color: var(--spectrum-global-color-gray-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
.updated {
|
.updated {
|
||||||
color: var(--spectrum-global-color-gray-700);
|
color: var(--spectrum-global-color-gray-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title,
|
||||||
|
.name {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
.title,
|
.title,
|
||||||
.app-status {
|
.app-status {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -106,9 +105,8 @@
|
||||||
gap: var(--spacing-m);
|
gap: var(--spacing-m);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: flex-end;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: var(--spacing-m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
@ -120,15 +118,26 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.title :global(h1:hover) {
|
|
||||||
color: var(--spectrum-global-color-blue-600);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 130ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
.app-row {
|
||||||
|
grid-template-columns: 45% 30% auto;
|
||||||
|
}
|
||||||
|
.updated {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.app-row {
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
}
|
||||||
|
.app-status {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.desktop {
|
.app-row {
|
||||||
display: none !important;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<script>
|
||||||
|
import Logo from "assets/bb-emblem.svg"
|
||||||
|
import { goto } from "@roxi/routify"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<img src={Logo} alt="Budibase Logo" on:click={() => $goto("./apps")} />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,79 @@
|
||||||
|
<script>
|
||||||
|
import { Layout } from "@budibase/bbui"
|
||||||
|
import { SideNav, SideNavItem } from "components/portal/page"
|
||||||
|
import { createEventDispatcher } from "svelte"
|
||||||
|
import { isActive } from "@roxi/routify"
|
||||||
|
import UpgradeButton from "./UpgradeButton.svelte"
|
||||||
|
import { fade } from "svelte/transition"
|
||||||
|
import Logo from "./Logo.svelte"
|
||||||
|
|
||||||
|
export let visible = false
|
||||||
|
export let menu
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
const close = () => dispatch("close")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if visible}
|
||||||
|
<div
|
||||||
|
class="mobile-nav-underlay"
|
||||||
|
transition:fade={{ duration: 130 }}
|
||||||
|
on:click={close}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
<div class="mobile-nav" class:visible>
|
||||||
|
<Layout noPadding gap="M">
|
||||||
|
<div on:click={close}>
|
||||||
|
<Logo />
|
||||||
|
</div>
|
||||||
|
<SideNav>
|
||||||
|
{#each menu as { title, href }}
|
||||||
|
<SideNavItem
|
||||||
|
text={title}
|
||||||
|
url={href}
|
||||||
|
active={$isActive(href)}
|
||||||
|
on:click={close}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</SideNav>
|
||||||
|
<div>
|
||||||
|
<UpgradeButton />
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.mobile-nav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.mobile-nav-underlay {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.mobile-nav {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 16px 24px;
|
||||||
|
height: 100%;
|
||||||
|
width: 240px;
|
||||||
|
background: var(--background);
|
||||||
|
z-index: 2;
|
||||||
|
transition: transform 130ms ease-out;
|
||||||
|
}
|
||||||
|
.mobile-nav.visible {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script>
|
||||||
|
import { Button } from "@budibase/bbui"
|
||||||
|
import { goto } from "@roxi/routify"
|
||||||
|
import { auth, admin } from "stores/portal"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if $admin.cloud && $auth?.user?.accountPortalAccess}
|
||||||
|
<Button
|
||||||
|
cta
|
||||||
|
on:click={() => {
|
||||||
|
$goto($admin.accountPortalUrl + "/portal/upgrade")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Upgrade
|
||||||
|
</Button>
|
||||||
|
{:else if !$admin.cloud && $auth.isAdmin}
|
||||||
|
<Button cta on:click={() => $goto("/builder/portal/account/upgrade")}>
|
||||||
|
Upgrade
|
||||||
|
</Button>
|
||||||
|
{/if}
|
|
@ -0,0 +1,78 @@
|
||||||
|
<script>
|
||||||
|
import { auth } from "stores/portal"
|
||||||
|
import { ActionMenu, Avatar, MenuItem, Icon, Modal } from "@budibase/bbui"
|
||||||
|
import { goto } from "@roxi/routify"
|
||||||
|
import ProfileModal from "components/settings/ProfileModal.svelte"
|
||||||
|
import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte"
|
||||||
|
import ThemeModal from "components/settings/ThemeModal.svelte"
|
||||||
|
import APIKeyModal from "components/settings/APIKeyModal.svelte"
|
||||||
|
|
||||||
|
let themeModal
|
||||||
|
let profileModal
|
||||||
|
let updatePasswordModal
|
||||||
|
let apiKeyModal
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
try {
|
||||||
|
await auth.logout()
|
||||||
|
} catch (error) {
|
||||||
|
// Swallow error and do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ActionMenu align="right" dataCy="user-menu">
|
||||||
|
<div slot="control" class="user-dropdown">
|
||||||
|
<Avatar size="L" initials={$auth.initials} url={$auth.user.pictureUrl} />
|
||||||
|
<Icon size="XL" name="ChevronDown" />
|
||||||
|
</div>
|
||||||
|
<MenuItem icon="Moon" on:click={() => themeModal.show()} dataCy="theme">
|
||||||
|
Theme
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="UserEdit"
|
||||||
|
on:click={() => profileModal.show()}
|
||||||
|
dataCy="user-info"
|
||||||
|
>
|
||||||
|
My profile
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem icon="LockClosed" on:click={() => updatePasswordModal.show()}>
|
||||||
|
Update password
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem icon="Key" on:click={() => apiKeyModal.show()} dataCy="api-key">
|
||||||
|
View API key
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
|
||||||
|
Close developer mode
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem dataCy="user-logout" icon="LogOut" on:click={logout}>
|
||||||
|
Log out
|
||||||
|
</MenuItem>
|
||||||
|
</ActionMenu>
|
||||||
|
|
||||||
|
<Modal bind:this={themeModal}>
|
||||||
|
<ThemeModal />
|
||||||
|
</Modal>
|
||||||
|
<Modal bind:this={profileModal}>
|
||||||
|
<ProfileModal />
|
||||||
|
</Modal>
|
||||||
|
<Modal bind:this={updatePasswordModal}>
|
||||||
|
<ChangePasswordModal />
|
||||||
|
</Modal>
|
||||||
|
<Modal bind:this={apiKeyModal}>
|
||||||
|
<APIKeyModal />
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.user-dropdown {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-s);
|
||||||
|
}
|
||||||
|
.user-dropdown:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: brightness(110%);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,30 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { isActive, redirect, goto, url } from "@roxi/routify"
|
import { isActive, redirect, goto, url } from "@roxi/routify"
|
||||||
import {
|
import { Icon, notifications, Tabs, Tab } from "@budibase/bbui"
|
||||||
Icon,
|
|
||||||
Avatar,
|
|
||||||
ActionMenu,
|
|
||||||
MenuItem,
|
|
||||||
Modal,
|
|
||||||
notifications,
|
|
||||||
Tabs,
|
|
||||||
Tab,
|
|
||||||
Button,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
import { organisation, auth, admin as adminStore } from "stores/portal"
|
import { organisation, auth, admin as adminStore } from "stores/portal"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import ProfileModal from "components/settings/ProfileModal.svelte"
|
|
||||||
import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte"
|
|
||||||
import ThemeModal from "components/settings/ThemeModal.svelte"
|
|
||||||
import APIKeyModal from "components/settings/APIKeyModal.svelte"
|
|
||||||
import Logo from "assets/bb-emblem.svg"
|
|
||||||
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
||||||
|
import UpgradeButton from "./_components/UpgradeButton.svelte"
|
||||||
|
import MobileMenu from "./_components/MobileMenu.svelte"
|
||||||
|
import Logo from "./_components/Logo.svelte"
|
||||||
|
import UserDropdown from "./_components/UserDropdown.svelte"
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let themeModal
|
|
||||||
let profileModal
|
|
||||||
let updatePasswordModal
|
|
||||||
let apiKeyModal
|
|
||||||
let mobileMenuVisible = false
|
let mobileMenuVisible = false
|
||||||
let activeTab = "Apps"
|
let activeTab = "Apps"
|
||||||
|
|
||||||
|
@ -96,14 +81,6 @@
|
||||||
return menu
|
return menu
|
||||||
}
|
}
|
||||||
|
|
||||||
const logout = async () => {
|
|
||||||
try {
|
|
||||||
await auth.logout()
|
|
||||||
} catch (error) {
|
|
||||||
// Swallow error and do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const showMobileMenu = () => (mobileMenuVisible = true)
|
const showMobileMenu = () => (mobileMenuVisible = true)
|
||||||
const hideMobileMenu = () => (mobileMenuVisible = false)
|
const hideMobileMenu = () => (mobileMenuVisible = false)
|
||||||
|
|
||||||
|
@ -127,92 +104,31 @@
|
||||||
{#if $auth.user && loaded}
|
{#if $auth.user && loaded}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<div class="branding" on:click={() => $goto("./apps")}>
|
<div class="branding">
|
||||||
<img src={Logo} alt="Logotype" />
|
<Logo />
|
||||||
</div>
|
</div>
|
||||||
<Tabs selected={activeTab}>
|
<div class="desktop">
|
||||||
{#each menu as { title, href }}
|
<Tabs selected={activeTab}>
|
||||||
<Tab {title} on:click={() => $goto(href)} />
|
{#each menu as { title, href }}
|
||||||
{/each}
|
<Tab {title} on:click={() => $goto(href)} />
|
||||||
</Tabs>
|
{/each}
|
||||||
<div class="toolbar">
|
</Tabs>
|
||||||
<div class="mobile-toggle">
|
</div>
|
||||||
<Icon hoverable name="ShowMenu" on:click={showMobileMenu} />
|
<div class="mobile">
|
||||||
</div>
|
<Icon hoverable name="ShowMenu" on:click={showMobileMenu} />
|
||||||
<div class="mobile-logo">
|
</div>
|
||||||
<img
|
<div class="desktop">
|
||||||
src={$organisation?.logoUrl || Logo}
|
<UpgradeButton />
|
||||||
alt={$organisation?.company || "Budibase"}
|
</div>
|
||||||
/>
|
<div class="dropdown">
|
||||||
</div>
|
<UserDropdown />
|
||||||
{#if !$adminStore.cloud && $auth.isAdmin}
|
|
||||||
<Button cta on:click={() => $goto("/builder/portal/account/upgrade")}>
|
|
||||||
Upgrade
|
|
||||||
</Button>
|
|
||||||
{/if}
|
|
||||||
<div class="user-dropdown">
|
|
||||||
<ActionMenu align="right" dataCy="user-menu">
|
|
||||||
<div slot="control" class="avatar">
|
|
||||||
<Avatar
|
|
||||||
size="L"
|
|
||||||
initials={$auth.initials}
|
|
||||||
url={$auth.user.pictureUrl}
|
|
||||||
/>
|
|
||||||
<Icon size="XL" name="ChevronDown" />
|
|
||||||
</div>
|
|
||||||
<MenuItem
|
|
||||||
icon="Moon"
|
|
||||||
on:click={() => themeModal.show()}
|
|
||||||
dataCy="theme"
|
|
||||||
>
|
|
||||||
Theme
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="UserEdit"
|
|
||||||
on:click={() => profileModal.show()}
|
|
||||||
dataCy="user-info"
|
|
||||||
>
|
|
||||||
My profile
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="LockClosed"
|
|
||||||
on:click={() => updatePasswordModal.show()}
|
|
||||||
>
|
|
||||||
Update password
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="Key"
|
|
||||||
on:click={() => apiKeyModal.show()}
|
|
||||||
dataCy="api-key"
|
|
||||||
>
|
|
||||||
View API key
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
|
|
||||||
Close developer mode
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem dataCy="user-logout" icon="LogOut" on:click={logout}>
|
|
||||||
Log out
|
|
||||||
</MenuItem>
|
|
||||||
</ActionMenu>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
<MobileMenu visible={mobileMenuVisible} {menu} on:close={hideMobileMenu} />
|
||||||
</div>
|
</div>
|
||||||
<Modal bind:this={themeModal}>
|
|
||||||
<ThemeModal />
|
|
||||||
</Modal>
|
|
||||||
<Modal bind:this={profileModal}>
|
|
||||||
<ProfileModal />
|
|
||||||
</Modal>
|
|
||||||
<Modal bind:this={updatePasswordModal}>
|
|
||||||
<ChangePasswordModal />
|
|
||||||
</Modal>
|
|
||||||
<Modal bind:this={apiKeyModal}>
|
|
||||||
<APIKeyModal />
|
|
||||||
</Modal>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -228,54 +144,30 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: center;
|
||||||
border-bottom: var(--border-light);
|
border-bottom: var(--border-light);
|
||||||
padding: 0 20px;
|
padding: 0 24px;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Customise tabs appearance*/
|
||||||
.nav :global(.spectrum-Tabs) {
|
.nav :global(.spectrum-Tabs) {
|
||||||
margin-bottom: -2px;
|
margin-bottom: -2px;
|
||||||
padding: 7px 0;
|
padding: 7px 0;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
.nav :global(.spectrum-Tabs-content) {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
.nav :global(.spectrum-Tabs-itemLabel) {
|
.nav :global(.spectrum-Tabs-itemLabel) {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.branding {
|
.branding {
|
||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
}
|
}
|
||||||
.avatar {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto auto;
|
|
||||||
place-items: center;
|
|
||||||
grid-gap: var(--spacing-s);
|
|
||||||
}
|
|
||||||
.avatar:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
filter: brightness(110%);
|
|
||||||
}
|
|
||||||
.toolbar {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
gap: 24px;
|
|
||||||
}
|
|
||||||
.mobile-toggle,
|
|
||||||
.mobile-logo {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.user-dropdown {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -284,38 +176,29 @@
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.mobile {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.desktop {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.toolbar {
|
.mobile {
|
||||||
background: var(--background);
|
display: contents;
|
||||||
border-bottom: var(--border-light);
|
}
|
||||||
display: flex;
|
.desktop {
|
||||||
flex-direction: row;
|
display: none;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: var(--spacing-m) calc(var(--spacing-xl) * 1.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
|
flex: 0 0 52px;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.branding {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -250px;
|
left: 50%;
|
||||||
height: 100%;
|
top: 50%;
|
||||||
transition: left ease-in-out 230ms;
|
transform: translateX(-50%) translateY(-50%);
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
.nav.visible {
|
|
||||||
left: 0;
|
|
||||||
box-shadow: 0 0 80px 20px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-toggle,
|
|
||||||
.mobile-logo {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-toggle,
|
|
||||||
.user-dropdown {
|
|
||||||
flex: 0 1 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -49,8 +49,6 @@
|
||||||
)
|
)
|
||||||
: true)
|
: true)
|
||||||
)
|
)
|
||||||
$: lockedApps = filteredApps.filter(app => app?.lockedYou || app?.lockedOther)
|
|
||||||
$: unlocked = lockedApps?.length === 0
|
|
||||||
$: automationErrors = getAutomationErrors(enrichedApps)
|
$: automationErrors = getAutomationErrors(enrichedApps)
|
||||||
|
|
||||||
const enrichApps = (apps, user, sortBy) => {
|
const enrichApps = (apps, user, sortBy) => {
|
||||||
|
@ -309,7 +307,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="appTable" class:unlocked>
|
<div class="app-table">
|
||||||
{#each filteredApps as app (app.appId)}
|
{#each filteredApps as app (app.appId)}
|
||||||
<AppRow {app} {editApp} {appOverview} />
|
<AppRow {app} {editApp} {appOverview} />
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -356,11 +354,6 @@
|
||||||
gap: var(--spacing-xl);
|
gap: var(--spacing-xl);
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@media (max-width: 1000px) {
|
|
||||||
.img-logo {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.app-actions {
|
.app-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -369,19 +362,15 @@
|
||||||
gap: var(--spacing-xl);
|
gap: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.appTable {
|
.app-table {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: 24px;
|
gap: var(--spacing-xl);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
.appTable {
|
|
||||||
grid-template-columns: 1fr auto !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.empty-wrapper {
|
.empty-wrapper {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -394,4 +383,23 @@
|
||||||
width: 160px;
|
width: 160px;
|
||||||
height: 160px;
|
height: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
.img-logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.app-actions {
|
||||||
|
margin-top: var(--spacing-xl);
|
||||||
|
margin-bottom: calc(-1 * var(--spacing-m));
|
||||||
|
}
|
||||||
|
/* Hide download apps icon */
|
||||||
|
.app-actions :global(> .spectrum-Icon) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.app-actions > :global(*) {
|
||||||
|
flex: 0 0 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
<Breadcrumb url={$url("../")} text="Apps" />
|
<Breadcrumb url={$url("../")} text="Apps" />
|
||||||
<Breadcrumb text={app?.name} />
|
<Breadcrumb text={app?.name} />
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
<Header title={app?.name}>
|
<Header title={app?.name} wrap={false}>
|
||||||
<div slot="icon">
|
<div slot="icon">
|
||||||
<EditableIcon
|
<EditableIcon
|
||||||
{app}
|
{app}
|
||||||
|
@ -132,28 +132,46 @@
|
||||||
</div>
|
</div>
|
||||||
<div slot="buttons">
|
<div slot="buttons">
|
||||||
<AppLockModal {app} />
|
<AppLockModal {app} />
|
||||||
<Button
|
<span class="desktop">
|
||||||
size="M"
|
<Button
|
||||||
quiet
|
size="M"
|
||||||
secondary
|
quiet
|
||||||
disabled={!isPublished}
|
secondary
|
||||||
on:click={viewApp}
|
disabled={!isPublished}
|
||||||
dataCy="view-app"
|
on:click={viewApp}
|
||||||
>
|
dataCy="view-app"
|
||||||
View
|
>
|
||||||
</Button>
|
View
|
||||||
<Button
|
</Button>
|
||||||
size="M"
|
</span>
|
||||||
cta
|
<span class="desktop">
|
||||||
disabled={appLocked && !lockedByYou}
|
<Button
|
||||||
on:click={editApp}
|
size="M"
|
||||||
>
|
cta
|
||||||
Edit
|
disabled={appLocked && !lockedByYou}
|
||||||
</Button>
|
on:click={editApp}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
<ActionMenu align="right" dataCy="app-overview-menu-popover">
|
<ActionMenu align="right" dataCy="app-overview-menu-popover">
|
||||||
<span slot="control" class="app-overview-actions-icon">
|
<span slot="control" class="app-overview-actions-icon">
|
||||||
<Icon hoverable name="More" />
|
<Icon hoverable name="More" />
|
||||||
</span>
|
</span>
|
||||||
|
<span class="mobile">
|
||||||
|
<MenuItem icon="Globe" disabled={!isPublished} on:click={viewApp}>
|
||||||
|
View
|
||||||
|
</MenuItem>
|
||||||
|
</span>
|
||||||
|
<span class="mobile">
|
||||||
|
<MenuItem
|
||||||
|
icon="Edit"
|
||||||
|
disabled={appLocked && !lockedByYou}
|
||||||
|
on:click={editApp}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</MenuItem>
|
||||||
|
</span>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
on:click={() => exportApp({ published: false })}
|
on:click={() => exportApp({ published: false })}
|
||||||
icon="DownloadFromCloud"
|
icon="DownloadFromCloud"
|
||||||
|
@ -177,7 +195,7 @@
|
||||||
</ActionMenu>
|
</ActionMenu>
|
||||||
</div>
|
</div>
|
||||||
</Header>
|
</Header>
|
||||||
<Content>
|
<Content showMobileNav>
|
||||||
<SideNav slot="side-nav">
|
<SideNav slot="side-nav">
|
||||||
<SideNavItem
|
<SideNavItem
|
||||||
text="Overview"
|
text="Overview"
|
||||||
|
@ -237,3 +255,15 @@
|
||||||
/>
|
/>
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
{/key}
|
{/key}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.desktop {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
[PluginSource.FILE]: [opt("File Upload")],
|
[PluginSource.FILE]: [opt("File Upload")],
|
||||||
}
|
}
|
||||||
let file
|
let file
|
||||||
let source = PluginSource.URL
|
let source = PluginSource.GITHUB
|
||||||
let dynamicValues = {}
|
let dynamicValues = {}
|
||||||
|
|
||||||
let validation
|
let validation
|
||||||
|
|
|
@ -2,24 +2,21 @@ import { writable } from "svelte/store"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
|
|
||||||
export function createEnvVarsStore() {
|
export function createEnvVarsStore() {
|
||||||
const { subscribe, set, update } = writable([])
|
const { subscribe, set, update } = writable([])
|
||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
// const envVars = await API.fetchEnvVars()
|
// const envVars = await API.fetchEnvVars()
|
||||||
|
|
||||||
let testVars = ['blah', 'blah123']
|
let testVars = ['blah', 'blah123']
|
||||||
|
const vars = testVars.map((name) => ({ name }))
|
||||||
|
console.log(vars)
|
||||||
|
set(vars)
|
||||||
|
}
|
||||||
|
|
||||||
// turn the testVars array in to a map with "name" being the value of each
|
return {
|
||||||
// item in the array
|
subscribe,
|
||||||
const vars = testVars.map((name) => ({ name }))
|
load,
|
||||||
console.log(vars)
|
}
|
||||||
set(vars)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
subscribe,
|
|
||||||
load,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const envVars = createEnvVarsStore()
|
export const envVars = createEnvVarsStore()
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -26,9 +26,9 @@
|
||||||
"outputPath": "build"
|
"outputPath": "build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "2.2.12-alpha.2",
|
"@budibase/backend-core": "2.2.12-alpha.10",
|
||||||
"@budibase/string-templates": "2.2.12-alpha.2",
|
"@budibase/string-templates": "2.2.12-alpha.10",
|
||||||
"@budibase/types": "2.2.12-alpha.2",
|
"@budibase/types": "2.2.12-alpha.10",
|
||||||
"axios": "0.21.2",
|
"axios": "0.21.2",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
"cli-progress": "3.11.2",
|
"cli-progress": "3.11.2",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "2.2.12-alpha.2",
|
"@budibase/bbui": "2.2.12-alpha.10",
|
||||||
"@budibase/frontend-core": "2.2.12-alpha.2",
|
"@budibase/frontend-core": "2.2.12-alpha.10",
|
||||||
"@budibase/string-templates": "2.2.12-alpha.2",
|
"@budibase/string-templates": "2.2.12-alpha.10",
|
||||||
"@spectrum-css/button": "^3.0.3",
|
"@spectrum-css/button": "^3.0.3",
|
||||||
"@spectrum-css/card": "^3.0.3",
|
"@spectrum-css/card": "^3.0.3",
|
||||||
"@spectrum-css/divider": "^1.0.3",
|
"@spectrum-css/divider": "^1.0.3",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/frontend-core",
|
"name": "@budibase/frontend-core",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"description": "Budibase frontend core libraries used in builder and client",
|
"description": "Budibase frontend core libraries used in builder and client",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "2.2.12-alpha.2",
|
"@budibase/bbui": "2.2.12-alpha.10",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"svelte": "^3.46.2"
|
"svelte": "^3.46.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
export const buildEnvironmentVariableEndpoints = API => ({
|
export const buildEnvironmentVariableEndpoints = API => ({
|
||||||
/**
|
/**
|
||||||
* Fetches a list of environment variables
|
* Fetches a list of environment variables
|
||||||
*/
|
*/
|
||||||
fetchEnvVars: async () => {
|
fetchEnvVars: async () => {
|
||||||
return await API.get({
|
return await API.get({
|
||||||
url: `/api/env/variables`,
|
url: `/api/env/variables`,
|
||||||
json: false,
|
json: false,
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/sdk",
|
"name": "@budibase/sdk",
|
||||||
"version": "2.2.12-alpha.2",
|
"version": "2.2.12-alpha.10",
|
||||||
"description": "Budibase Public API SDK",
|
"description": "Budibase Public API SDK",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
// @ts-ignore
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
module FetchMock {
|
module FetchMock {
|
||||||
|
// @ts-ignore
|
||||||
const fetch = jest.requireActual("node-fetch")
|
const fetch = jest.requireActual("node-fetch")
|
||||||
let failCount = 0
|
let failCount = 0
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,18 @@ import { Config } from "@jest/types"
|
||||||
import * as fs from "fs"
|
import * as fs from "fs"
|
||||||
|
|
||||||
const config: Config.InitialOptions = {
|
const config: Config.InitialOptions = {
|
||||||
preset: "ts-jest",
|
|
||||||
testEnvironment: "node",
|
testEnvironment: "node",
|
||||||
setupFiles: ["./src/tests/jestSetup.ts"],
|
setupFiles: ["./src/tests/jestEnv.ts"],
|
||||||
|
setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
"src/**/*.{js,ts}",
|
"src/**/*.{js,ts}",
|
||||||
// The use of coverage with couchdb view functions breaks tests
|
// The use of coverage with couchdb view functions breaks tests
|
||||||
"!src/db/views/staticViews.*",
|
"!src/db/views/staticViews.*",
|
||||||
],
|
],
|
||||||
coverageReporters: ["lcov", "json", "clover"],
|
coverageReporters: ["lcov", "json", "clover"],
|
||||||
|
transform: {
|
||||||
|
"^.+\\.ts?$": "@swc/jest",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!process.env.CI) {
|
if (!process.env.CI) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue