App migrations finished
This commit is contained in:
parent
498c130e71
commit
756f5b51aa
|
@ -12,6 +12,7 @@ import {
|
|||
ViewFilterUpdatedEvent,
|
||||
ViewUpdatedEvent,
|
||||
View,
|
||||
ViewCalculation,
|
||||
Table,
|
||||
TableExportFormat,
|
||||
} from "@budibase/types"
|
||||
|
@ -53,7 +54,7 @@ export function filterDeleted() {
|
|||
publishEvent(Event.VIEW_FILTER_DELETED, properties)
|
||||
}
|
||||
|
||||
export function calculationCreated() {
|
||||
export function calculationCreated(calculation: ViewCalculation) {
|
||||
const properties: ViewCalculationCreatedEvent = {}
|
||||
publishEvent(Event.VIEW_CALCULATION_CREATED, properties)
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ jest.mock("../../../events", () => {
|
|||
assigned: jest.fn(),
|
||||
unassigned: jest.fn(),
|
||||
},
|
||||
row: {
|
||||
rows: {
|
||||
imported: jest.fn(),
|
||||
},
|
||||
screen: {
|
||||
|
|
|
@ -3,11 +3,11 @@ import { generateQueryID } from "../../../../db/utils"
|
|||
import { ImportInfo, ImportSource } from "./sources/base"
|
||||
import { OpenAPI2 } from "./sources/openapi2"
|
||||
import { OpenAPI3 } from "./sources/openapi3"
|
||||
import { Query } from "./../../../../definitions/common"
|
||||
import { Curl } from "./sources/curl"
|
||||
// @ts-ignore
|
||||
import { getAppDB } from "@budibase/backend-core/context"
|
||||
import { events } from "@budibase/backend-core"
|
||||
import { Datasource, Query } from "@budibase/types"
|
||||
|
||||
interface ImportResult {
|
||||
errorQueries: Query[]
|
||||
|
@ -83,7 +83,7 @@ export class RestImporter {
|
|||
// events
|
||||
const count = successQueries.length
|
||||
const importSource = this.source.getImportSource()
|
||||
const datasource = await db.get(datasourceId)
|
||||
const datasource: Datasource = await db.get(datasourceId)
|
||||
events.query.imported(datasource, importSource, count)
|
||||
for (let query of successQueries) {
|
||||
events.query.created(datasource, query)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Query, QueryParameter } from "../../../../../../definitions/datasource"
|
||||
import { Query, QueryParameter } from "@budibase/types"
|
||||
import { URL } from "url"
|
||||
|
||||
export interface ImportInfo {
|
||||
|
|
|
@ -55,8 +55,8 @@ describe("/tables", () => {
|
|||
expect(events.table.created).toBeCalledWith(res.body)
|
||||
expect(events.table.imported).toBeCalledTimes(1)
|
||||
expect(events.table.imported).toBeCalledWith(res.body, "csv")
|
||||
expect(events.row.imported).toBeCalledTimes(1)
|
||||
expect(events.row.imported).toBeCalledWith(res.body, "csv", 1)
|
||||
expect(events.rowsimported).toBeCalledTimes(1)
|
||||
expect(events.rows.imported).toBeCalledWith(res.body, "csv", 1)
|
||||
})
|
||||
|
||||
it("should apply authorization to endpoint", async () => {
|
||||
|
|
|
@ -5,6 +5,7 @@ import * as layouts from "./app/layouts"
|
|||
import * as queries from "./app/queries"
|
||||
import * as roles from "./app/roles"
|
||||
import * as tables from "./app/tables"
|
||||
import * as screens from "./app/screens"
|
||||
|
||||
/**
|
||||
* Date:
|
||||
|
@ -22,4 +23,5 @@ export const run = async (appDb: any) => {
|
|||
await queries.backfill(appDb)
|
||||
await roles.backfill(appDb)
|
||||
await tables.backfill(appDb)
|
||||
await screens.backfill(appDb)
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import { events } from "@budibase/backend-core"
|
||||
import { Row } from "@budibase/types"
|
||||
|
||||
export const backfill = async (appDb: any) => {
|
||||
const rows: Row[] = []
|
||||
const count = rows.length
|
||||
events.rows.created(count)
|
||||
}
|
|
@ -1 +1,22 @@
|
|||
// SCREEN_CREATED = "screen:created",
|
||||
import { events, db } from "@budibase/backend-core"
|
||||
import { getScreenParams } from "../../../../db/utils"
|
||||
import { Screen } from "@budibase/types"
|
||||
|
||||
const getScreens = async (appDb: any): Promise<Screen[]> => {
|
||||
const response = await appDb.allDocs(
|
||||
getScreenParams(null, {
|
||||
include_docs: true,
|
||||
})
|
||||
)
|
||||
return response.rows.map((row: any) => row.doc)
|
||||
}
|
||||
|
||||
export const backfill = async (appDb: any) => {
|
||||
if (db.isDevAppID(appDb.name)) {
|
||||
const screens = await getScreens(appDb)
|
||||
|
||||
for (const screen of screens) {
|
||||
events.screen.created(screen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,20 @@ export const backfill = async (appDb: any) => {
|
|||
|
||||
for (const table of tables) {
|
||||
events.table.created(table)
|
||||
|
||||
if (table.views) {
|
||||
for (const view of Object.values(table.views)) {
|
||||
events.view.created(view)
|
||||
|
||||
if (view.calculation) {
|
||||
events.view.calculationCreated(view.calculation)
|
||||
}
|
||||
|
||||
if (view.filters?.length) {
|
||||
events.view.filterCreated()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
// VIEW_CREATED = "view:created",
|
||||
// VIEW_FILTER_CREATED = "view:filter:created",
|
||||
// VIEW_CALCULATION_CREATED = "view:calculation:created",
|
|
@ -0,0 +1,14 @@
|
|||
import { events, db } from "@budibase/backend-core"
|
||||
import { Row } from "@budibase/types"
|
||||
import { getUniqueRows } from "../../../../utilities/usageQuota/rows"
|
||||
|
||||
// Rows is a special circumstance where we get rows across all apps
|
||||
// therefore migration is performed at the global level
|
||||
|
||||
export const backfill = async () => {
|
||||
const allApps = await db.getAllApps({ all: true })
|
||||
const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : []
|
||||
const rows: Row[] = await getUniqueRows(appIds)
|
||||
const rowCount = rows ? rows.length : 0
|
||||
events.rows.created(rowCount)
|
||||
}
|
|
@ -29,7 +29,11 @@ describe("migrations", () => {
|
|||
await config.createRole()
|
||||
await config.createRole()
|
||||
await config.createTable()
|
||||
await config.createView()
|
||||
await config.createTable()
|
||||
await config.createView(structures.view(config.table._id))
|
||||
await config.createScreen()
|
||||
await config.createScreen()
|
||||
|
||||
jest.clearAllMocks()
|
||||
const migration = MIGRATIONS.filter(
|
||||
|
@ -46,6 +50,10 @@ describe("migrations", () => {
|
|||
expect(events.query.created).toBeCalledTimes(2)
|
||||
expect(events.role.created).toBeCalledTimes(2)
|
||||
expect(events.table.created).toBeCalledTimes(3)
|
||||
expect(events.view.created).toBeCalledTimes(2)
|
||||
expect(events.view.calculationCreated).toBeCalledTimes(1)
|
||||
expect(events.view.filterCreated).toBeCalledTimes(1)
|
||||
expect(events.screen.created).toBeCalledTimes(2)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -409,7 +409,6 @@ class TestConfiguration {
|
|||
throw "Test requires table to be configured."
|
||||
}
|
||||
const view = config || {
|
||||
map: "function(doc) { emit(doc[doc.key], doc._id); } ",
|
||||
tableId: this.table._id,
|
||||
name: "ViewTest",
|
||||
}
|
||||
|
|
|
@ -30,6 +30,41 @@ exports.basicTable = () => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.basicView = tableId => {
|
||||
return {
|
||||
tableId,
|
||||
name: "ViewTest",
|
||||
}
|
||||
}
|
||||
|
||||
exports.filterView = tableId => {
|
||||
return {
|
||||
...this.basicView(tableId),
|
||||
filters: [
|
||||
{
|
||||
value: 0,
|
||||
condition: "MT",
|
||||
key: "count",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
exports.calculationView = tableId => {
|
||||
return {
|
||||
...this.basicView(tableId),
|
||||
field: "count",
|
||||
calculation: "sum",
|
||||
}
|
||||
}
|
||||
|
||||
exports.view = tableId => {
|
||||
return {
|
||||
...this.filterView(tableId),
|
||||
...this.calculationView(tableId),
|
||||
}
|
||||
}
|
||||
|
||||
exports.automationStep = (actionDefinition = ACTION_DEFINITIONS.CREATE_ROW) => {
|
||||
return {
|
||||
id: uuidv4(),
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export interface Automation {
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface Automation extends Document {
|
||||
definition: {
|
||||
steps: AutomationStep[]
|
||||
trigger: AutomationTrigger
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export interface Datasource {}
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface Datasource extends Document {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export interface Document {
|
||||
_id: string
|
||||
_id?: string
|
||||
_rev?: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
createdAt?: string
|
||||
updatedAt?: string
|
||||
}
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export interface Layout {}
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface Layout extends Document {}
|
||||
|
|
|
@ -1,3 +1,44 @@
|
|||
export interface Query {
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface Query extends Document {
|
||||
datasourceId: string
|
||||
name: string
|
||||
parameters: QueryParameter[]
|
||||
fields: RestQueryFields | any
|
||||
transformer: string | null
|
||||
schema: any
|
||||
readable: boolean
|
||||
queryVerb: string
|
||||
}
|
||||
|
||||
export interface QueryParameter {
|
||||
name: string
|
||||
default: string
|
||||
}
|
||||
|
||||
export interface RestQueryFields {
|
||||
path: string
|
||||
queryString?: string
|
||||
headers: { [key: string]: any }
|
||||
disabledHeaders: { [key: string]: any }
|
||||
requestBody: any
|
||||
bodyType: string
|
||||
json: object
|
||||
method: string
|
||||
authConfigId: string
|
||||
pagination: PaginationConfig | null
|
||||
paginationValues: PaginationValues | null
|
||||
}
|
||||
|
||||
export interface PaginationConfig {
|
||||
type: string
|
||||
location: string
|
||||
pageParam: string
|
||||
sizeParam: string | null
|
||||
responseParam: string | null
|
||||
}
|
||||
|
||||
export interface PaginationValues {
|
||||
page: string | number | null
|
||||
limit: number | null
|
||||
}
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export interface Row {}
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface Row extends Document {}
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export interface Screen {}
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface Screen extends Document {}
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
export interface Table {}
|
||||
import { Document } from "./document"
|
||||
import { View } from "./view"
|
||||
|
||||
export interface Table extends Document {
|
||||
views: { [key: string]: View }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export interface UserMetadata {
|
||||
import { Document } from "./document"
|
||||
|
||||
export interface UserMetadata extends Document {
|
||||
roleId: string
|
||||
}
|
||||
|
|
|
@ -1 +1,43 @@
|
|||
export interface View {}
|
||||
export interface View {
|
||||
name: string
|
||||
tableId: string
|
||||
field?: string
|
||||
filters: ViewFilter[]
|
||||
schema: ViewSchema
|
||||
calculation?: ViewCalculation
|
||||
}
|
||||
|
||||
export type ViewSchema = ViewCountOrSumSchema | ViewStatisticsSchema
|
||||
|
||||
export interface ViewCountOrSumSchema {
|
||||
field: string
|
||||
value: string
|
||||
}
|
||||
|
||||
/**
|
||||
e.g:
|
||||
"min": {
|
||||
"type": "number"
|
||||
},
|
||||
"max": {
|
||||
"type": "number"
|
||||
}
|
||||
*/
|
||||
export interface ViewStatisticsSchema {
|
||||
[key: string]: {
|
||||
type: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ViewFilter {
|
||||
value: any
|
||||
condition: string
|
||||
key: string
|
||||
conjunction?: string
|
||||
}
|
||||
|
||||
export enum ViewCalculation {
|
||||
SUM = "sum",
|
||||
COUNT = "count",
|
||||
STATISTICS = "stats",
|
||||
}
|
||||
|
|
|
@ -139,12 +139,13 @@ describe("/api/global/users", () => {
|
|||
}
|
||||
|
||||
await createUser(user)
|
||||
const savedUser = await config.getUser(user.email)
|
||||
|
||||
expect(events.user.created).toBeCalledTimes(1)
|
||||
expect(events.user.updated).not.toBeCalled()
|
||||
expect(events.role.assigned).toBeCalledTimes(2)
|
||||
expect(events.role.assigned).toBeCalledWith("role1")
|
||||
expect(events.role.assigned).toBeCalledWith("role2")
|
||||
expect(events.role.assigned).toBeCalledWith(savedUser, "role1")
|
||||
expect(events.role.assigned).toBeCalledWith(savedUser, "role2")
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -243,12 +244,13 @@ describe("/api/global/users", () => {
|
|||
"app_456": "role2",
|
||||
}
|
||||
await updateUser(user)
|
||||
const savedUser = await config.getUser(user.email)
|
||||
|
||||
expect(events.user.created).not.toBeCalled()
|
||||
expect(events.user.updated).toBeCalledTimes(1)
|
||||
expect(events.role.assigned).toBeCalledTimes(2)
|
||||
expect(events.role.assigned).toBeCalledWith("role1")
|
||||
expect(events.role.assigned).toBeCalledWith("role2")
|
||||
expect(events.role.assigned).toBeCalledWith(savedUser, "role1")
|
||||
expect(events.role.assigned).toBeCalledWith(savedUser, "role2")
|
||||
})
|
||||
|
||||
it("should be able to unassign app roles", async () => {
|
||||
|
@ -262,12 +264,13 @@ describe("/api/global/users", () => {
|
|||
|
||||
user.roles = {}
|
||||
await updateUser(user)
|
||||
const savedUser = await config.getUser(user.email)
|
||||
|
||||
expect(events.user.created).not.toBeCalled()
|
||||
expect(events.user.updated).toBeCalledTimes(1)
|
||||
expect(events.role.unassigned).toBeCalledTimes(2)
|
||||
expect(events.role.unassigned).toBeCalledWith("role1")
|
||||
expect(events.role.unassigned).toBeCalledWith("role2")
|
||||
expect(events.role.unassigned).toBeCalledWith(savedUser, "role1")
|
||||
expect(events.role.unassigned).toBeCalledWith(savedUser, "role2")
|
||||
})
|
||||
|
||||
it("should be able to update existing app roles", async () => {
|
||||
|
@ -284,13 +287,14 @@ describe("/api/global/users", () => {
|
|||
"app_456": "role2-edit",
|
||||
}
|
||||
await updateUser(user)
|
||||
const savedUser = await config.getUser(user.email)
|
||||
|
||||
expect(events.user.created).not.toBeCalled()
|
||||
expect(events.user.updated).toBeCalledTimes(1)
|
||||
expect(events.role.unassigned).toBeCalledTimes(1)
|
||||
expect(events.role.unassigned).toBeCalledWith("role2")
|
||||
expect(events.role.unassigned).toBeCalledWith(savedUser, "role2")
|
||||
expect(events.role.assigned).toBeCalledTimes(1)
|
||||
expect(events.role.assigned).toBeCalledWith("role2-edit")
|
||||
expect(events.role.assigned).toBeCalledWith(savedUser, "role2-edit")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ export const save = async (
|
|||
} else {
|
||||
response = await putUserFn()
|
||||
}
|
||||
user._rev = response.rev
|
||||
|
||||
eventHelpers.handleSaveEvents(user, dbUser)
|
||||
|
||||
|
|
Loading…
Reference in New Issue