Build and test fixes
This commit is contained in:
parent
e1a656b76f
commit
606d21b313
|
@ -2,7 +2,7 @@
|
||||||
"name": "@budibase/backend-core",
|
"name": "@budibase/backend-core",
|
||||||
"version": "1.0.126-alpha.0",
|
"version": "1.0.126-alpha.0",
|
||||||
"description": "Budibase backend core libraries used in server and worker",
|
"description": "Budibase backend core libraries used in server and worker",
|
||||||
"main": "src/index.js",
|
"main": "src/index.ts",
|
||||||
"types": "dist/src/index.d.ts",
|
"types": "dist/src/index.d.ts",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
|
@ -36,22 +36,29 @@
|
||||||
"zlib": "^1.0.5"
|
"zlib": "^1.0.5"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
"preset": "ts-jest",
|
||||||
|
"testEnvironment": "node",
|
||||||
"setupFiles": [
|
"setupFiles": [
|
||||||
"./scripts/jestSetup.js"
|
"./scripts/jestSetup.ts"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@shopify/jest-koa-mocks": "^3.1.5",
|
||||||
|
"@budibase/types": "^1.0.126-alpha.0",
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^27.4.1",
|
||||||
|
"@types/koa": "^2.13.3",
|
||||||
"@types/node": "^15.12.4",
|
"@types/node": "^15.12.4",
|
||||||
"@types/node-fetch": "^2.6.1",
|
"@types/node-fetch": "^2.6.1",
|
||||||
"@budibase/types": "^1.0.126-alpha.0",
|
"@types/tar-fs": "^2.0.1",
|
||||||
"typescript": "^4.5.5",
|
"@types/uuid": "^8.3.4",
|
||||||
"@shopify/jest-koa-mocks": "^3.1.5",
|
|
||||||
"ioredis-mock": "^5.5.5",
|
"ioredis-mock": "^5.5.5",
|
||||||
"jest": "^26.6.3",
|
"jest": "^27.0.3",
|
||||||
|
"koa": "2.7.0",
|
||||||
"pouchdb-adapter-memory": "^7.2.2",
|
"pouchdb-adapter-memory": "^7.2.2",
|
||||||
"pouchdb-all-dbs": "^1.0.2",
|
"pouchdb-all-dbs": "^1.0.2",
|
||||||
"timekeeper": "^2.2.0"
|
"timekeeper": "^2.2.0",
|
||||||
|
"ts-jest": "^27.0.3",
|
||||||
|
"typescript": "^4.5.5"
|
||||||
},
|
},
|
||||||
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const env = require("../src/environment")
|
import env from "../src/environment"
|
||||||
const { mocks } = require("../testUtils")
|
import { mocks } from "../testUtils"
|
||||||
|
|
||||||
// mock all dates to 2020-01-01T00:00:00.000Z
|
// mock all dates to 2020-01-01T00:00:00.000Z
|
||||||
// use tk.reset() to use real dates in individual tests
|
// use tk.reset() to use real dates in individual tests
|
||||||
const tk = require("timekeeper")
|
import tk from "timekeeper"
|
||||||
tk.freeze(mocks.date.MOCK_DATE)
|
tk.freeze(mocks.date.MOCK_DATE)
|
||||||
|
|
||||||
env._set("SELF_HOSTED", "1")
|
env._set("SELF_HOSTED", "1")
|
|
@ -1,6 +1,6 @@
|
||||||
import { newid } from "../hashing"
|
import { newid } from "../hashing"
|
||||||
import { DEFAULT_TENANT_ID, Configs } from "../constants"
|
import { DEFAULT_TENANT_ID, Configs } from "../constants"
|
||||||
import * as env from "../environment"
|
import env from "../environment"
|
||||||
import { SEPARATOR, DocumentTypes } from "./constants"
|
import { SEPARATOR, DocumentTypes } from "./constants"
|
||||||
import { getTenantId, getGlobalDBName } from "../tenancy"
|
import { getTenantId, getGlobalDBName } from "../tenancy"
|
||||||
import fetch from "node-fetch"
|
import fetch from "node-fetch"
|
||||||
|
|
|
@ -6,7 +6,7 @@ function isTest() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
JWT_SECRET: process.env.JWT_SECRET,
|
JWT_SECRET: process.env.JWT_SECRET,
|
||||||
COUCH_DB_URL: process.env.COUCH_DB_URL,
|
COUCH_DB_URL: process.env.COUCH_DB_URL,
|
||||||
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
|
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
|
||||||
|
@ -26,7 +26,7 @@ module.exports = {
|
||||||
process.env.ACCOUNT_PORTAL_URL || "https://account.budibase.app",
|
process.env.ACCOUNT_PORTAL_URL || "https://account.budibase.app",
|
||||||
ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY,
|
ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY,
|
||||||
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
|
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
|
||||||
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
|
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED || ""),
|
||||||
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
|
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
|
||||||
PLATFORM_URL: process.env.PLATFORM_URL,
|
PLATFORM_URL: process.env.PLATFORM_URL,
|
||||||
POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,
|
POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,
|
||||||
|
@ -34,7 +34,7 @@ module.exports = {
|
||||||
TENANT_FEATURE_FLAGS: process.env.TENANT_FEATURE_FLAGS,
|
TENANT_FEATURE_FLAGS: process.env.TENANT_FEATURE_FLAGS,
|
||||||
USE_COUCH: process.env.USE_COUCH || true,
|
USE_COUCH: process.env.USE_COUCH || true,
|
||||||
isTest,
|
isTest,
|
||||||
_set(key, value) {
|
_set(key: any, value: any) {
|
||||||
process.env[key] = value
|
process.env[key] = value
|
||||||
module.exports[key] = value
|
module.exports[key] = value
|
||||||
},
|
},
|
|
@ -1,10 +1,10 @@
|
||||||
import { AppServedEvent } from "./../../../../types/src/events/serve"
|
|
||||||
import { processEvent } from "../events"
|
import { processEvent } from "../events"
|
||||||
import {
|
import {
|
||||||
App,
|
App,
|
||||||
BuilderServedEvent,
|
BuilderServedEvent,
|
||||||
Events,
|
Events,
|
||||||
AppPreviewServedEvent,
|
AppPreviewServedEvent,
|
||||||
|
AppServedEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
|
@ -11,6 +11,9 @@ import {
|
||||||
ViewFilterDeletedEvent,
|
ViewFilterDeletedEvent,
|
||||||
ViewFilterUpdatedEvent,
|
ViewFilterUpdatedEvent,
|
||||||
ViewUpdatedEvent,
|
ViewUpdatedEvent,
|
||||||
|
View,
|
||||||
|
Table,
|
||||||
|
TableExportFormat,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
@ -30,7 +33,7 @@ export function deleted() {
|
||||||
processEvent(Events.VIEW_DELETED, properties)
|
processEvent(Events.VIEW_DELETED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function exported(table, format) {
|
export function exported(table: Table, format: TableExportFormat) {
|
||||||
const properties: ViewExportedEvent = {}
|
const properties: ViewExportedEvent = {}
|
||||||
processEvent(Events.VIEW_EXPORTED, properties)
|
processEvent(Events.VIEW_EXPORTED, properties)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const db = require("./db")
|
import db from "./db"
|
||||||
const errors = require("./errors")
|
import errors from "./errors"
|
||||||
import * as events from "./events"
|
import * as events from "./events"
|
||||||
|
|
||||||
module.exports = {
|
export = {
|
||||||
init(opts = {}) {
|
init(opts: any = {}) {
|
||||||
db.init(opts.db)
|
db.init(opts.db)
|
||||||
},
|
},
|
||||||
// some default exports from the library, however these ideally shouldn't
|
// some default exports from the library, however these ideally shouldn't
|
||||||
|
@ -18,7 +18,7 @@ module.exports = {
|
||||||
auth: require("../auth"),
|
auth: require("../auth"),
|
||||||
constants: require("../constants"),
|
constants: require("../constants"),
|
||||||
migrations: require("../migrations"),
|
migrations: require("../migrations"),
|
||||||
errors: require("./errors"),
|
errors,
|
||||||
...errors.errors,
|
...errors.errors,
|
||||||
env: require("./environment"),
|
env: require("./environment"),
|
||||||
accounts: require("./cloud/accounts"),
|
accounts: require("./cloud/accounts"),
|
|
@ -1,9 +1,9 @@
|
||||||
import sanitize from "sanitize-s3-objectkey"
|
const sanitize = require("sanitize-s3-objectkey")
|
||||||
import AWS from "aws-sdk"
|
import AWS from "aws-sdk"
|
||||||
import stream from "stream"
|
import stream from "stream"
|
||||||
import fetch from "node-fetch"
|
import fetch from "node-fetch"
|
||||||
import tar from "tar-fs"
|
import tar from "tar-fs"
|
||||||
import zlib from "zlib"
|
const zlib = require("zlib")
|
||||||
import { promisify } from "util"
|
import { promisify } from "util"
|
||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
|
@ -18,7 +18,7 @@ const STATE = {
|
||||||
bucketCreationPromises: {},
|
bucketCreationPromises: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONTENT_TYPE_MAP = {
|
const CONTENT_TYPE_MAP: any = {
|
||||||
html: "text/html",
|
html: "text/html",
|
||||||
css: "text/css",
|
css: "text/css",
|
||||||
js: "application/javascript",
|
js: "application/javascript",
|
||||||
|
@ -32,20 +32,16 @@ const STRING_CONTENT_TYPES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
// does normal sanitization and then swaps dev apps to apps
|
// does normal sanitization and then swaps dev apps to apps
|
||||||
function sanitizeKey(input) {
|
export function sanitizeKey(input: any) {
|
||||||
return sanitize(sanitizeBucket(input)).replace(/\\/g, "/")
|
return sanitize(sanitizeBucket(input)).replace(/\\/g, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.sanitizeKey = sanitizeKey
|
|
||||||
|
|
||||||
// simply handles the dev app to app conversion
|
// simply handles the dev app to app conversion
|
||||||
function sanitizeBucket(input) {
|
export function sanitizeBucket(input: any) {
|
||||||
return input.replace(new RegExp(APP_DEV_PREFIX, "g"), APP_PREFIX)
|
return input.replace(new RegExp(APP_DEV_PREFIX, "g"), APP_PREFIX)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.sanitizeBucket = sanitizeBucket
|
function publicPolicy(bucketName: any) {
|
||||||
|
|
||||||
function publicPolicy(bucketName) {
|
|
||||||
return {
|
return {
|
||||||
Version: "2012-10-17",
|
Version: "2012-10-17",
|
||||||
Statement: [
|
Statement: [
|
||||||
|
@ -69,13 +65,13 @@ const PUBLIC_BUCKETS = [ObjectStoreBuckets.APPS, ObjectStoreBuckets.GLOBAL]
|
||||||
* @return {Object} an S3 object store object, check S3 Nodejs SDK for usage.
|
* @return {Object} an S3 object store object, check S3 Nodejs SDK for usage.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
exports.ObjectStore = bucket => {
|
export const ObjectStore = (bucket: any) => {
|
||||||
AWS.config.update({
|
AWS.config.update({
|
||||||
accessKeyId: env.MINIO_ACCESS_KEY,
|
accessKeyId: env.MINIO_ACCESS_KEY,
|
||||||
secretAccessKey: env.MINIO_SECRET_KEY,
|
secretAccessKey: env.MINIO_SECRET_KEY,
|
||||||
region: env.AWS_REGION,
|
region: env.AWS_REGION,
|
||||||
})
|
})
|
||||||
const config = {
|
const config: any = {
|
||||||
s3ForcePathStyle: true,
|
s3ForcePathStyle: true,
|
||||||
signatureVersion: "v4",
|
signatureVersion: "v4",
|
||||||
apiVersion: "2006-03-01",
|
apiVersion: "2006-03-01",
|
||||||
|
@ -93,7 +89,7 @@ exports.ObjectStore = bucket => {
|
||||||
* Given an object store and a bucket name this will make sure the bucket exists,
|
* Given an object store and a bucket name this will make sure the bucket exists,
|
||||||
* if it does not exist then it will create it.
|
* if it does not exist then it will create it.
|
||||||
*/
|
*/
|
||||||
exports.makeSureBucketExists = async (client, bucketName) => {
|
export const makeSureBucketExists = async (client: any, bucketName: any) => {
|
||||||
bucketName = sanitizeBucket(bucketName)
|
bucketName = sanitizeBucket(bucketName)
|
||||||
try {
|
try {
|
||||||
await client
|
await client
|
||||||
|
@ -101,8 +97,8 @@ exports.makeSureBucketExists = async (client, bucketName) => {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
})
|
})
|
||||||
.promise()
|
.promise()
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
const promises = STATE.bucketCreationPromises
|
const promises: any = STATE.bucketCreationPromises
|
||||||
const doesntExist = err.statusCode === 404,
|
const doesntExist = err.statusCode === 404,
|
||||||
noAccess = err.statusCode === 403
|
noAccess = err.statusCode === 403
|
||||||
if (promises[bucketName]) {
|
if (promises[bucketName]) {
|
||||||
|
@ -138,20 +134,20 @@ exports.makeSureBucketExists = async (client, bucketName) => {
|
||||||
* Uploads the contents of a file given the required parameters, useful when
|
* Uploads the contents of a file given the required parameters, useful when
|
||||||
* temp files in use (for example file uploaded as an attachment).
|
* temp files in use (for example file uploaded as an attachment).
|
||||||
*/
|
*/
|
||||||
exports.upload = async ({
|
export const upload = async ({
|
||||||
bucket: bucketName,
|
bucket: bucketName,
|
||||||
filename,
|
filename,
|
||||||
path,
|
path,
|
||||||
type,
|
type,
|
||||||
metadata,
|
metadata,
|
||||||
}) => {
|
}: any) => {
|
||||||
const extension = [...filename.split(".")].pop()
|
const extension = [...filename.split(".")].pop()
|
||||||
const fileBytes = fs.readFileSync(path)
|
const fileBytes = fs.readFileSync(path)
|
||||||
|
|
||||||
const objectStore = exports.ObjectStore(bucketName)
|
const objectStore = ObjectStore(bucketName)
|
||||||
await exports.makeSureBucketExists(objectStore, bucketName)
|
await makeSureBucketExists(objectStore, bucketName)
|
||||||
|
|
||||||
const config = {
|
const config: any = {
|
||||||
// windows file paths need to be converted to forward slashes for s3
|
// windows file paths need to be converted to forward slashes for s3
|
||||||
Key: sanitizeKey(filename),
|
Key: sanitizeKey(filename),
|
||||||
Body: fileBytes,
|
Body: fileBytes,
|
||||||
|
@ -167,9 +163,14 @@ exports.upload = async ({
|
||||||
* Similar to the upload function but can be used to send a file stream
|
* Similar to the upload function but can be used to send a file stream
|
||||||
* through to the object store.
|
* through to the object store.
|
||||||
*/
|
*/
|
||||||
exports.streamUpload = async (bucketName, filename, stream, extra = {}) => {
|
export const streamUpload = async (
|
||||||
const objectStore = exports.ObjectStore(bucketName)
|
bucketName: any,
|
||||||
await exports.makeSureBucketExists(objectStore, bucketName)
|
filename: any,
|
||||||
|
stream: any,
|
||||||
|
extra = {}
|
||||||
|
) => {
|
||||||
|
const objectStore = ObjectStore(bucketName)
|
||||||
|
await makeSureBucketExists(objectStore, bucketName)
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: sanitizeBucket(bucketName),
|
Bucket: sanitizeBucket(bucketName),
|
||||||
|
@ -184,13 +185,13 @@ exports.streamUpload = async (bucketName, filename, stream, extra = {}) => {
|
||||||
* retrieves the contents of a file from the object store, if it is a known content type it
|
* retrieves the contents of a file from the object store, if it is a known content type it
|
||||||
* will be converted, otherwise it will be returned as a buffer stream.
|
* will be converted, otherwise it will be returned as a buffer stream.
|
||||||
*/
|
*/
|
||||||
exports.retrieve = async (bucketName, filepath) => {
|
export const retrieve = async (bucketName: any, filepath: any) => {
|
||||||
const objectStore = exports.ObjectStore(bucketName)
|
const objectStore = ObjectStore(bucketName)
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: sanitizeBucket(bucketName),
|
Bucket: sanitizeBucket(bucketName),
|
||||||
Key: sanitizeKey(filepath),
|
Key: sanitizeKey(filepath),
|
||||||
}
|
}
|
||||||
const response = await objectStore.getObject(params).promise()
|
const response: any = await objectStore.getObject(params).promise()
|
||||||
// currently these are all strings
|
// currently these are all strings
|
||||||
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
||||||
return response.Body.toString("utf8")
|
return response.Body.toString("utf8")
|
||||||
|
@ -202,10 +203,10 @@ exports.retrieve = async (bucketName, filepath) => {
|
||||||
/**
|
/**
|
||||||
* Same as retrieval function but puts to a temporary file.
|
* Same as retrieval function but puts to a temporary file.
|
||||||
*/
|
*/
|
||||||
exports.retrieveToTmp = async (bucketName, filepath) => {
|
export const retrieveToTmp = async (bucketName: any, filepath: any) => {
|
||||||
bucketName = sanitizeBucket(bucketName)
|
bucketName = sanitizeBucket(bucketName)
|
||||||
filepath = sanitizeKey(filepath)
|
filepath = sanitizeKey(filepath)
|
||||||
const data = await exports.retrieve(bucketName, filepath)
|
const data = await retrieve(bucketName, filepath)
|
||||||
const outputPath = join(budibaseTempDir(), v4())
|
const outputPath = join(budibaseTempDir(), v4())
|
||||||
fs.writeFileSync(outputPath, data)
|
fs.writeFileSync(outputPath, data)
|
||||||
return outputPath
|
return outputPath
|
||||||
|
@ -214,9 +215,9 @@ exports.retrieveToTmp = async (bucketName, filepath) => {
|
||||||
/**
|
/**
|
||||||
* Delete a single file.
|
* Delete a single file.
|
||||||
*/
|
*/
|
||||||
exports.deleteFile = async (bucketName, filepath) => {
|
export const deleteFile = async (bucketName: any, filepath: any) => {
|
||||||
const objectStore = exports.ObjectStore(bucketName)
|
const objectStore = ObjectStore(bucketName)
|
||||||
await exports.makeSureBucketExists(objectStore, bucketName)
|
await makeSureBucketExists(objectStore, bucketName)
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Key: filepath,
|
Key: filepath,
|
||||||
|
@ -224,13 +225,13 @@ exports.deleteFile = async (bucketName, filepath) => {
|
||||||
return objectStore.deleteObject(params)
|
return objectStore.deleteObject(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.deleteFiles = async (bucketName, filepaths) => {
|
export const deleteFiles = async (bucketName: any, filepaths: any) => {
|
||||||
const objectStore = exports.ObjectStore(bucketName)
|
const objectStore = ObjectStore(bucketName)
|
||||||
await exports.makeSureBucketExists(objectStore, bucketName)
|
await makeSureBucketExists(objectStore, bucketName)
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Delete: {
|
Delete: {
|
||||||
Objects: filepaths.map(path => ({ Key: path })),
|
Objects: filepaths.map((path: any) => ({ Key: path })),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return objectStore.deleteObjects(params).promise()
|
return objectStore.deleteObjects(params).promise()
|
||||||
|
@ -239,38 +240,45 @@ exports.deleteFiles = async (bucketName, filepaths) => {
|
||||||
/**
|
/**
|
||||||
* Delete a path, including everything within.
|
* Delete a path, including everything within.
|
||||||
*/
|
*/
|
||||||
exports.deleteFolder = async (bucketName, folder) => {
|
export const deleteFolder = async (
|
||||||
|
bucketName: any,
|
||||||
|
folder: any
|
||||||
|
): Promise<any> => {
|
||||||
bucketName = sanitizeBucket(bucketName)
|
bucketName = sanitizeBucket(bucketName)
|
||||||
folder = sanitizeKey(folder)
|
folder = sanitizeKey(folder)
|
||||||
const client = exports.ObjectStore(bucketName)
|
const client = ObjectStore(bucketName)
|
||||||
const listParams = {
|
const listParams = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Prefix: folder,
|
Prefix: folder,
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await client.listObjects(listParams).promise()
|
let response: any = await client.listObjects(listParams).promise()
|
||||||
if (response.Contents.length === 0) {
|
if (response.Contents.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const deleteParams = {
|
const deleteParams: any = {
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Delete: {
|
Delete: {
|
||||||
Objects: [],
|
Objects: [],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Contents.forEach(content => {
|
response.Contents.forEach((content: any) => {
|
||||||
deleteParams.Delete.Objects.push({ Key: content.Key })
|
deleteParams.Delete.Objects.push({ Key: content.Key })
|
||||||
})
|
})
|
||||||
|
|
||||||
response = await client.deleteObjects(deleteParams).promise()
|
response = await client.deleteObjects(deleteParams).promise()
|
||||||
// can only empty 1000 items at once
|
// can only empty 1000 items at once
|
||||||
if (response.Deleted.length === 1000) {
|
if (response.Deleted.length === 1000) {
|
||||||
return exports.deleteFolder(bucketName, folder)
|
return deleteFolder(bucketName, folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.uploadDirectory = async (bucketName, localPath, bucketPath) => {
|
export const uploadDirectory = async (
|
||||||
|
bucketName: any,
|
||||||
|
localPath: any,
|
||||||
|
bucketPath: any
|
||||||
|
) => {
|
||||||
bucketName = sanitizeBucket(bucketName)
|
bucketName = sanitizeBucket(bucketName)
|
||||||
let uploads = []
|
let uploads = []
|
||||||
const files = fs.readdirSync(localPath, { withFileTypes: true })
|
const files = fs.readdirSync(localPath, { withFileTypes: true })
|
||||||
|
@ -278,17 +286,15 @@ exports.uploadDirectory = async (bucketName, localPath, bucketPath) => {
|
||||||
const path = sanitizeKey(join(bucketPath, file.name))
|
const path = sanitizeKey(join(bucketPath, file.name))
|
||||||
const local = join(localPath, file.name)
|
const local = join(localPath, file.name)
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
uploads.push(exports.uploadDirectory(bucketName, local, path))
|
uploads.push(uploadDirectory(bucketName, local, path))
|
||||||
} else {
|
} else {
|
||||||
uploads.push(
|
uploads.push(streamUpload(bucketName, path, fs.createReadStream(local)))
|
||||||
exports.streamUpload(bucketName, path, fs.createReadStream(local))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Promise.all(uploads)
|
await Promise.all(uploads)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.downloadTarball = async (url, bucketName, path) => {
|
export const downloadTarball = async (url: any, bucketName: any, path: any) => {
|
||||||
bucketName = sanitizeBucket(bucketName)
|
bucketName = sanitizeBucket(bucketName)
|
||||||
path = sanitizeKey(path)
|
path = sanitizeKey(path)
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
|
@ -299,7 +305,7 @@ exports.downloadTarball = async (url, bucketName, path) => {
|
||||||
const tmpPath = join(budibaseTempDir(), path)
|
const tmpPath = join(budibaseTempDir(), path)
|
||||||
await streamPipeline(response.body, zlib.Unzip(), tar.extract(tmpPath))
|
await streamPipeline(response.body, zlib.Unzip(), tar.extract(tmpPath))
|
||||||
if (!env.isTest() && env.SELF_HOSTED) {
|
if (!env.isTest() && env.SELF_HOSTED) {
|
||||||
await exports.uploadDirectory(bucketName, tmpPath, path)
|
await uploadDirectory(bucketName, tmpPath, path)
|
||||||
}
|
}
|
||||||
// return the temporary path incase there is a use for it
|
// return the temporary path incase there is a use for it
|
||||||
return tmpPath
|
return tmpPath
|
|
@ -1,7 +0,0 @@
|
||||||
const mocks = require("./mocks")
|
|
||||||
const structures = require("./structures")
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
mocks,
|
|
||||||
structures,
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * as mocks from "./mocks"
|
||||||
|
export * as structures from "./structures"
|
|
@ -59,7 +59,7 @@ jest.mock("../../../events", () => {
|
||||||
created: jest.fn(),
|
created: jest.fn(),
|
||||||
updated: jest.fn(),
|
updated: jest.fn(),
|
||||||
deleted: jest.fn(),
|
deleted: jest.fn(),
|
||||||
import: jest.fn(),
|
imported: jest.fn(),
|
||||||
previewed: jest.fn(),
|
previewed: jest.fn(),
|
||||||
},
|
},
|
||||||
role: {
|
role: {
|
||||||
|
@ -70,7 +70,7 @@ jest.mock("../../../events", () => {
|
||||||
unassigned: jest.fn(),
|
unassigned: jest.fn(),
|
||||||
},
|
},
|
||||||
row: {
|
row: {
|
||||||
import: jest.fn(),
|
imported: jest.fn(),
|
||||||
},
|
},
|
||||||
screen: {
|
screen: {
|
||||||
created: jest.fn(),
|
created: jest.fn(),
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
require("../mocks")
|
|
||||||
const koa = require("./koa")
|
|
||||||
|
|
||||||
const structures = {
|
|
||||||
koa,
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = structures
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import "../mocks"
|
||||||
|
|
||||||
|
export * as koa from "./koa"
|
|
@ -1,5 +0,0 @@
|
||||||
const { createMockContext } = require("@shopify/jest-koa-mocks")
|
|
||||||
|
|
||||||
exports.newContext = () => {
|
|
||||||
return createMockContext()
|
|
||||||
}
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { createMockContext } from "@shopify/jest-koa-mocks"
|
||||||
|
|
||||||
|
export const newContext = () => {
|
||||||
|
return createMockContext()
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
module.exports = require("./src/tests/utilities")
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./src/tests/utilities"
|
File diff suppressed because it is too large
Load Diff
|
@ -143,6 +143,7 @@
|
||||||
"@babel/core": "^7.14.3",
|
"@babel/core": "^7.14.3",
|
||||||
"@babel/preset-env": "^7.14.4",
|
"@babel/preset-env": "^7.14.4",
|
||||||
"@budibase/standard-components": "^0.9.139",
|
"@budibase/standard-components": "^0.9.139",
|
||||||
|
"@budibase/types": "^1.0.126-alpha.0",
|
||||||
"@jest/test-sequencer": "^24.8.0",
|
"@jest/test-sequencer": "^24.8.0",
|
||||||
"@types/apidoc": "^0.50.0",
|
"@types/apidoc": "^0.50.0",
|
||||||
"@types/bull": "^3.15.1",
|
"@types/bull": "^3.15.1",
|
||||||
|
|
|
@ -52,6 +52,7 @@ const {
|
||||||
import { getUniqueRows } from "../../utilities/usageQuota/rows"
|
import { getUniqueRows } from "../../utilities/usageQuota/rows"
|
||||||
import { quotas } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
import { errors, events } from "@budibase/backend-core"
|
import { errors, events } from "@budibase/backend-core"
|
||||||
|
import { App } from "@budibase/types"
|
||||||
|
|
||||||
const URL_REGEX_SLASH = /\/|\\/g
|
const URL_REGEX_SLASH = /\/|\\/g
|
||||||
|
|
||||||
|
@ -233,7 +234,7 @@ const performAppCreate = async (ctx: any) => {
|
||||||
const apps = await getAllApps({ dev: true })
|
const apps = await getAllApps({ dev: true })
|
||||||
const name = ctx.request.body.name
|
const name = ctx.request.body.name
|
||||||
checkAppName(ctx, apps, name)
|
checkAppName(ctx, apps, name)
|
||||||
const url = exports.getAppUrl(ctx)
|
const url = getAppUrl(ctx)
|
||||||
checkAppUrl(ctx, apps, url)
|
checkAppUrl(ctx, apps, url)
|
||||||
|
|
||||||
const { useTemplate, templateKey, templateString } = ctx.request.body
|
const { useTemplate, templateKey, templateString } = ctx.request.body
|
||||||
|
@ -291,7 +292,7 @@ const performAppCreate = async (ctx: any) => {
|
||||||
return newApplication
|
return newApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
const creationEvents = (request: any) => {
|
const creationEvents = (request: any, app: App) => {
|
||||||
let creationFns = []
|
let creationFns = []
|
||||||
|
|
||||||
const body = request.body
|
const body = request.body
|
||||||
|
@ -312,15 +313,15 @@ const creationEvents = (request: any) => {
|
||||||
creationFns.push(events.app.created)
|
creationFns.push(events.app.created)
|
||||||
|
|
||||||
for (let fn of creationFns) {
|
for (let fn of creationFns) {
|
||||||
fn()
|
fn(app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const appPostCreate = async (ctx: any, appId: string) => {
|
const appPostCreate = async (ctx: any, app: App) => {
|
||||||
creationEvents(ctx.request)
|
creationEvents(ctx.request, app)
|
||||||
// app import & template creation
|
// app import & template creation
|
||||||
if (ctx.request.body.useTemplate === "true") {
|
if (ctx.request.body.useTemplate === "true") {
|
||||||
const rows = await getUniqueRows([appId])
|
const rows = await getUniqueRows([app.appId])
|
||||||
const rowCount = rows ? rows.length : 0
|
const rowCount = rows ? rows.length : 0
|
||||||
if (rowCount) {
|
if (rowCount) {
|
||||||
try {
|
try {
|
||||||
|
@ -330,7 +331,7 @@ const appPostCreate = async (ctx: any, appId: string) => {
|
||||||
// this import resulted in row usage exceeding the quota
|
// this import resulted in row usage exceeding the quota
|
||||||
// delete the app
|
// delete the app
|
||||||
// skip pre and post steps as no rows have been added to quotas yet
|
// skip pre and post steps as no rows have been added to quotas yet
|
||||||
ctx.params.appId = appId
|
ctx.params.appId = app.appId
|
||||||
await destroyApp(ctx)
|
await destroyApp(ctx)
|
||||||
}
|
}
|
||||||
throw err
|
throw err
|
||||||
|
@ -341,7 +342,7 @@ const appPostCreate = async (ctx: any, appId: string) => {
|
||||||
|
|
||||||
export const create = async (ctx: any) => {
|
export const create = async (ctx: any) => {
|
||||||
const newApplication = await quotas.addApp(() => performAppCreate(ctx))
|
const newApplication = await quotas.addApp(() => performAppCreate(ctx))
|
||||||
await appPostCreate(ctx, newApplication.appId)
|
await appPostCreate(ctx, newApplication)
|
||||||
ctx.body = newApplication
|
ctx.body = newApplication
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
@ -355,16 +356,16 @@ export const update = async (ctx: any) => {
|
||||||
if (name) {
|
if (name) {
|
||||||
checkAppName(ctx, apps, name, ctx.params.appId)
|
checkAppName(ctx, apps, name, ctx.params.appId)
|
||||||
}
|
}
|
||||||
const url = await exports.getAppUrl(ctx)
|
const url = getAppUrl(ctx)
|
||||||
if (url) {
|
if (url) {
|
||||||
checkAppUrl(ctx, apps, url, ctx.params.appId)
|
checkAppUrl(ctx, apps, url, ctx.params.appId)
|
||||||
ctx.request.body.url = url
|
ctx.request.body.url = url
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await updateAppPackage(ctx.request.body, ctx.params.appId)
|
const app = await updateAppPackage(ctx.request.body, ctx.params.appId)
|
||||||
events.app.updated()
|
events.app.updated(app)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.body = data
|
ctx.body = app
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateClient = async (ctx: any) => {
|
export const updateClient = async (ctx: any) => {
|
||||||
|
@ -384,10 +385,10 @@ export const updateClient = async (ctx: any) => {
|
||||||
version: packageJson.version,
|
version: packageJson.version,
|
||||||
revertableVersion: currentVersion,
|
revertableVersion: currentVersion,
|
||||||
}
|
}
|
||||||
const data = await updateAppPackage(appPackageUpdates, ctx.params.appId)
|
const app = await updateAppPackage(appPackageUpdates, ctx.params.appId)
|
||||||
events.app.versionUpdated()
|
events.app.versionUpdated(app)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.body = data
|
ctx.body = app
|
||||||
}
|
}
|
||||||
|
|
||||||
export const revertClient = async (ctx: any) => {
|
export const revertClient = async (ctx: any) => {
|
||||||
|
@ -408,10 +409,10 @@ export const revertClient = async (ctx: any) => {
|
||||||
version: application.revertableVersion,
|
version: application.revertableVersion,
|
||||||
revertableVersion: null,
|
revertableVersion: null,
|
||||||
}
|
}
|
||||||
const data = await updateAppPackage(appPackageUpdates, ctx.params.appId)
|
const app = await updateAppPackage(appPackageUpdates, ctx.params.appId)
|
||||||
events.app.versionReverted()
|
events.app.versionReverted(app)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.body = data
|
ctx.body = app
|
||||||
}
|
}
|
||||||
|
|
||||||
const destroyApp = async (ctx: any) => {
|
const destroyApp = async (ctx: any) => {
|
||||||
|
@ -423,14 +424,15 @@ const destroyApp = async (ctx: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const db = isUnpublish ? getProdAppDB() : getAppDB()
|
const db = isUnpublish ? getProdAppDB() : getAppDB()
|
||||||
|
const app = await db.get(DocumentTypes.APP_METADATA)
|
||||||
const result = await db.destroy()
|
const result = await db.destroy()
|
||||||
|
|
||||||
if (isUnpublish) {
|
if (isUnpublish) {
|
||||||
await quotas.removePublishedApp()
|
await quotas.removePublishedApp()
|
||||||
events.app.unpublished()
|
events.app.unpublished(app)
|
||||||
} else {
|
} else {
|
||||||
await quotas.removeApp()
|
await quotas.removeApp()
|
||||||
events.app.deleted()
|
events.app.deleted(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
|
@ -531,10 +533,10 @@ const updateAppPackage = async (appPackage: any, appId: any) => {
|
||||||
// Redis, shouldn't ever store it
|
// Redis, shouldn't ever store it
|
||||||
delete newAppPackage.lockedBy
|
delete newAppPackage.lockedBy
|
||||||
|
|
||||||
const response = await db.put(newAppPackage)
|
await db.put(newAppPackage)
|
||||||
// remove any cached metadata, so that it will be updated
|
// remove any cached metadata, so that it will be updated
|
||||||
await appCache.invalidateAppMetadata(appId)
|
await appCache.invalidateAppMetadata(appId)
|
||||||
return response
|
return newAppPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
const createEmptyAppPackage = async (ctx: any, app: any) => {
|
const createEmptyAppPackage = async (ctx: any, app: any) => {
|
||||||
|
|
|
@ -123,6 +123,7 @@ async function deployApp(deployment: any) {
|
||||||
console.log("Deployed app initialised, setting deployment to successful")
|
console.log("Deployed app initialised, setting deployment to successful")
|
||||||
deployment.setStatus(DeploymentStatus.SUCCESS)
|
deployment.setStatus(DeploymentStatus.SUCCESS)
|
||||||
await storeDeploymentHistory(deployment)
|
await storeDeploymentHistory(deployment)
|
||||||
|
return appDoc
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
deployment.setStatus(DeploymentStatus.FAILURE, err.message)
|
deployment.setStatus(DeploymentStatus.FAILURE, err.message)
|
||||||
await storeDeploymentHistory(deployment)
|
await storeDeploymentHistory(deployment)
|
||||||
|
@ -187,13 +188,14 @@ const _deployApp = async function (ctx: any) {
|
||||||
|
|
||||||
console.log("Deploying app...")
|
console.log("Deploying app...")
|
||||||
|
|
||||||
|
let app
|
||||||
if (await isFirstDeploy()) {
|
if (await isFirstDeploy()) {
|
||||||
await quotas.addPublishedApp(() => deployApp(deployment))
|
app = await quotas.addPublishedApp(() => deployApp(deployment))
|
||||||
} else {
|
} else {
|
||||||
await deployApp(deployment)
|
app = await deployApp(deployment)
|
||||||
}
|
}
|
||||||
|
|
||||||
events.app.published()
|
events.app.published(app)
|
||||||
ctx.body = deployment
|
ctx.body = deployment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,9 +84,9 @@ export class RestImporter {
|
||||||
const count = successQueries.length
|
const count = successQueries.length
|
||||||
const importSource = this.source.getImportSource()
|
const importSource = this.source.getImportSource()
|
||||||
const datasource = await db.get(datasourceId)
|
const datasource = await db.get(datasourceId)
|
||||||
events.query.import(datasource, importSource, count)
|
events.query.imported(datasource, importSource, count)
|
||||||
for (let query of successQueries) {
|
for (let query of successQueries) {
|
||||||
events.query.created(query)
|
events.query.created(datasource, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -106,8 +106,8 @@ describe("Rest Importer", () => {
|
||||||
const importResult = await restImporter.importQueries(datasource._id)
|
const importResult = await restImporter.importQueries(datasource._id)
|
||||||
expect(importResult.errorQueries.length).toBe(0)
|
expect(importResult.errorQueries.length).toBe(0)
|
||||||
expect(importResult.queries.length).toBe(assertions[key].count)
|
expect(importResult.queries.length).toBe(assertions[key].count)
|
||||||
expect(events.query.import).toBeCalledTimes(1)
|
expect(events.query.imported).toBeCalledTimes(1)
|
||||||
expect(events.query.import).toBeCalledWith(datasource, assertions[key].source, assertions[key].count)
|
expect(events.query.imported).toBeCalledWith(datasource, assertions[key].source, assertions[key].count)
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
await quotas.addRows(finalData.length, () => db.bulkDocs(finalData))
|
await quotas.addRows(finalData.length, () => db.bulkDocs(finalData))
|
||||||
events.row.import(table, "csv", finalData.length)
|
events.row.imported(table, "csv", finalData.length)
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ describe("/applications", () => {
|
||||||
.set(config.defaultHeaders())
|
.set(config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
expect(res.body.rev).toBeDefined()
|
expect(res.body._rev).toBeDefined()
|
||||||
expect(events.app.updated).toBeCalledTimes(1)
|
expect(events.app.updated).toBeCalledTimes(1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -201,7 +201,7 @@ describe("/applications", () => {
|
||||||
.set(headers)
|
.set(headers)
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
expect(res.body.rev).toBeDefined()
|
expect(res.body._rev).toBeDefined()
|
||||||
// retrieve the app to check it
|
// retrieve the app to check it
|
||||||
const getRes = await request
|
const getRes = await request
|
||||||
.get(`/api/applications/${config.getAppId()}/appPackage`)
|
.get(`/api/applications/${config.getAppId()}/appPackage`)
|
||||||
|
|
|
@ -55,8 +55,8 @@ describe("/tables", () => {
|
||||||
expect(events.table.created).toBeCalledWith(res.body)
|
expect(events.table.created).toBeCalledWith(res.body)
|
||||||
expect(events.table.imported).toBeCalledTimes(1)
|
expect(events.table.imported).toBeCalledTimes(1)
|
||||||
expect(events.table.imported).toBeCalledWith(res.body, "csv")
|
expect(events.table.imported).toBeCalledWith(res.body, "csv")
|
||||||
expect(events.row.import).toBeCalledTimes(1)
|
expect(events.row.imported).toBeCalledTimes(1)
|
||||||
expect(events.row.import).toBeCalledWith(res.body, "csv", 1)
|
expect(events.row.imported).toBeCalledWith(res.body, "csv", 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should apply authorization to endpoint", async () => {
|
it("should apply authorization to endpoint", async () => {
|
||||||
|
@ -163,8 +163,8 @@ describe("/tables", () => {
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
|
||||||
expect(events.table.created).not.toHaveBeenCalled()
|
expect(events.table.created).not.toHaveBeenCalled()
|
||||||
expect(events.row.import).toBeCalledTimes(1)
|
expect(events.row.imported).toBeCalledTimes(1)
|
||||||
expect(events.row.import).toBeCalledWith(table, "csv", 1)
|
expect(events.row.imported).toBeCalledWith(table, "csv", 1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"lib": ["es2019"],
|
"lib": ["es2020"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf dist/ && tsc -p tsconfig.json"
|
"build": "rimraf dist/ && tsc"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
export interface App {}
|
export interface App {
|
||||||
|
appId: string
|
||||||
|
}
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"lib": ["es2019"],
|
"lib": ["es2020"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"incremental": true
|
"incremental": true,
|
||||||
|
"types": [ "node", "jest"],
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src/**/*"
|
"./src/**/*"
|
||||||
|
|
|
@ -1297,6 +1297,13 @@ async-hook-jl@^1.7.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
stack-chain "^1.3.7"
|
stack-chain "^1.3.7"
|
||||||
|
|
||||||
|
async@~2.1.4:
|
||||||
|
version "2.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc"
|
||||||
|
integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=
|
||||||
|
dependencies:
|
||||||
|
lodash "^4.14.0"
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
asynckit@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
|
@ -2879,6 +2886,23 @@ globby@^11.0.4:
|
||||||
merge2 "^1.4.1"
|
merge2 "^1.4.1"
|
||||||
slash "^3.0.0"
|
slash "^3.0.0"
|
||||||
|
|
||||||
|
google-auth-library@~0.10.0:
|
||||||
|
version "0.10.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e"
|
||||||
|
integrity sha1-bhW6vuhf0d0U2NEoopW2g41SE24=
|
||||||
|
dependencies:
|
||||||
|
gtoken "^1.2.1"
|
||||||
|
jws "^3.1.4"
|
||||||
|
lodash.noop "^3.0.1"
|
||||||
|
request "^2.74.0"
|
||||||
|
|
||||||
|
google-p12-pem@^0.1.0:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177"
|
||||||
|
integrity sha1-M8RqsCGqc0+gMys5YKmj/8svMXc=
|
||||||
|
dependencies:
|
||||||
|
node-forge "^0.7.1"
|
||||||
|
|
||||||
googleapis@^16.0.0:
|
googleapis@^16.0.0:
|
||||||
version "16.1.0"
|
version "16.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-16.1.0.tgz#0f19f2d70572d918881a0f626e3b1a2fa8629576"
|
resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-16.1.0.tgz#0f19f2d70572d918881a0f626e3b1a2fa8629576"
|
||||||
|
@ -2927,6 +2951,16 @@ graceful-fs@^4.1.2, graceful-fs@^4.2.4:
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
|
||||||
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
||||||
|
|
||||||
|
gtoken@^1.2.1:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8"
|
||||||
|
integrity sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w==
|
||||||
|
dependencies:
|
||||||
|
google-p12-pem "^0.1.0"
|
||||||
|
jws "^3.0.0"
|
||||||
|
mime "^1.4.1"
|
||||||
|
request "^2.72.0"
|
||||||
|
|
||||||
har-schema@^2.0.0:
|
har-schema@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||||
|
@ -3986,7 +4020,7 @@ jwa@^1.4.1:
|
||||||
ecdsa-sig-formatter "1.0.11"
|
ecdsa-sig-formatter "1.0.11"
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
jws@^3.2.2:
|
jws@^3.0.0, jws@^3.1.4, jws@^3.2.2:
|
||||||
version "3.2.2"
|
version "3.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
||||||
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
||||||
|
@ -4306,6 +4340,11 @@ lodash.memoize@4.x:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
|
||||||
|
lodash.noop@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c"
|
||||||
|
integrity sha1-OBiPTWUKOkdCWEObluxFsyYXEzw=
|
||||||
|
|
||||||
lodash.once@^4.0.0:
|
lodash.once@^4.0.0:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
|
@ -4316,7 +4355,7 @@ lodash.pick@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||||
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
||||||
|
|
||||||
lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
|
lodash@^4.14.0, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
@ -4435,6 +4474,11 @@ mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24:
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db "1.51.0"
|
mime-db "1.51.0"
|
||||||
|
|
||||||
|
mime@^1.4.1:
|
||||||
|
version "1.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||||
|
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||||
|
|
||||||
mime@^2.5.0:
|
mime@^2.5.0:
|
||||||
version "2.6.0"
|
version "2.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
|
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
|
||||||
|
@ -4541,6 +4585,11 @@ node-fetch@2.6.7, node-fetch@^2.6.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-url "^5.0.0"
|
whatwg-url "^5.0.0"
|
||||||
|
|
||||||
|
node-forge@^0.7.1:
|
||||||
|
version "0.7.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
|
||||||
|
integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==
|
||||||
|
|
||||||
node-gyp-build@~4.1.0:
|
node-gyp-build@~4.1.0:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb"
|
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb"
|
||||||
|
@ -5502,7 +5551,7 @@ remove-trailing-slash@^0.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d"
|
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d"
|
||||||
integrity sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==
|
integrity sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==
|
||||||
|
|
||||||
request@^2.88.0:
|
request@^2.72.0, request@^2.74.0, request@^2.88.0:
|
||||||
version "2.88.2"
|
version "2.88.2"
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||||
|
@ -5931,6 +5980,11 @@ string-length@^4.0.1:
|
||||||
char-regex "^1.0.2"
|
char-regex "^1.0.2"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
string-template@~1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
|
||||||
|
integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
|
||||||
|
|
||||||
string-width@^3.0.0:
|
string-width@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
|
||||||
|
|
Loading…
Reference in New Issue