Merge branch 'frontend-core' of github.com:Budibase/budibase into experimental-hbs-caching
This commit is contained in:
commit
e9d0dcf8d0
|
@ -104,12 +104,14 @@ Budibase is made to scale. With Budibase, you can self-host on your own infrastr
|
||||||
|
|
||||||
## 🏁 Get started
|
## 🏁 Get started
|
||||||
|
|
||||||
<img src="https://res.cloudinary.com/daog6scxm/image/upload/v1634808888/logo/deploy_npl9za.png" />
|
<a href="https://docs.budibase.com/self-hosting/self-host"><img src="https://res.cloudinary.com/daog6scxm/image/upload/v1634808888/logo/deploy_npl9za.png" /></a>
|
||||||
|
|
||||||
Deploy Budibase self-Hosted in your existing infrastructure, using Docker, Kubernetes, and Digital Ocean.
|
Deploy Budibase self-hosted in your existing infrastructure, using Docker, Kubernetes, and Digital Ocean.
|
||||||
Or use Budibase Cloud if you don't need to self-host, and would like to get started quickly.
|
Or use Budibase Cloud if you don't need to self-host, and would like to get started quickly.
|
||||||
|
|
||||||
### [Get started with Budibase](https://budibase.com)
|
### [Get started with self-hosting Budibase](https://docs.budibase.com/self-hosting/self-host)
|
||||||
|
|
||||||
|
### [Get started with Budibase Cloud](https://budibase.com)
|
||||||
|
|
||||||
|
|
||||||
<br /><br />
|
<br /><br />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/backend-core",
|
"name": "@budibase/backend-core",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"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.js",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
|
|
|
@ -222,6 +222,7 @@ exports.getAllDbs = async () => {
|
||||||
/**
|
/**
|
||||||
* Lots of different points in the system need to find the full list of apps, this will
|
* Lots of different points in the system need to find the full list of apps, this will
|
||||||
* enumerate the entire CouchDB cluster and get the list of databases (every app).
|
* enumerate the entire CouchDB cluster and get the list of databases (every app).
|
||||||
|
*
|
||||||
* @return {Promise<object[]>} returns the app information document stored in each app database.
|
* @return {Promise<object[]>} returns the app information document stored in each app database.
|
||||||
*/
|
*/
|
||||||
exports.getAllApps = async ({ dev, all, idsOnly } = {}) => {
|
exports.getAllApps = async ({ dev, all, idsOnly } = {}) => {
|
||||||
|
|
|
@ -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": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"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",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -64,11 +64,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.49-alpha.6",
|
"@budibase/bbui": "^1.0.49-alpha.8",
|
||||||
"@budibase/client": "^1.0.49-alpha.6",
|
"@budibase/client": "^1.0.49-alpha.8",
|
||||||
"@budibase/colorpicker": "1.1.2",
|
"@budibase/frontend-core": "^1.0.49-alpha.8",
|
||||||
"@budibase/frontend-core": "^1.0.49-alpha.6",
|
"@budibase/string-templates": "^1.0.49-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.49-alpha.6",
|
|
||||||
"@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",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"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": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"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": "^1.0.49-alpha.6",
|
"@budibase/bbui": "^1.0.49-alpha.8",
|
||||||
"@budibase/frontend-core": "^1.0.49-alpha.6",
|
"@budibase/frontend-core": "^1.0.49-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.49-alpha.6",
|
"@budibase/string-templates": "^1.0.49-alpha.8",
|
||||||
"@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",
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/frontend-core",
|
"name": "@budibase/frontend-core",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"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": "^1.0.49-alpha.6",
|
"@budibase/bbui": "^1.0.49-alpha.8",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"svelte": "^3.46.2"
|
"svelte": "^3.46.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -70,9 +70,9 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apidevtools/swagger-parser": "^10.0.3",
|
"@apidevtools/swagger-parser": "^10.0.3",
|
||||||
"@budibase/backend-core": "^1.0.49-alpha.6",
|
"@budibase/backend-core": "^1.0.49-alpha.8",
|
||||||
"@budibase/client": "^1.0.49-alpha.6",
|
"@budibase/client": "^1.0.49-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.49-alpha.6",
|
"@budibase/string-templates": "^1.0.49-alpha.8",
|
||||||
"@bull-board/api": "^3.7.0",
|
"@bull-board/api": "^3.7.0",
|
||||||
"@bull-board/koa": "^3.7.0",
|
"@bull-board/koa": "^3.7.0",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
|
|
|
@ -31,23 +31,21 @@ async function handleRequest(operation, tableId, opts = {}) {
|
||||||
exports.handleRequest = handleRequest
|
exports.handleRequest = handleRequest
|
||||||
|
|
||||||
exports.patch = async ctx => {
|
exports.patch = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const inputs = ctx.request.body
|
const inputs = ctx.request.body
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const id = breakRowIdField(inputs._id)
|
const id = breakRowIdField(inputs._id)
|
||||||
// don't save the ID to db
|
// don't save the ID to db
|
||||||
delete inputs._id
|
delete inputs._id
|
||||||
return handleRequest(appId, DataSourceOperation.UPDATE, tableId, {
|
return handleRequest(DataSourceOperation.UPDATE, tableId, {
|
||||||
id,
|
id,
|
||||||
row: inputs,
|
row: inputs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.save = async ctx => {
|
exports.save = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const inputs = ctx.request.body
|
const inputs = ctx.request.body
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
return handleRequest(appId, DataSourceOperation.CREATE, tableId, {
|
return handleRequest(DataSourceOperation.CREATE, tableId, {
|
||||||
row: inputs,
|
row: inputs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -61,49 +59,35 @@ exports.fetchView = async ctx => {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.fetch = async ctx => {
|
exports.fetch = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
return handleRequest(appId, DataSourceOperation.READ, tableId)
|
return handleRequest(DataSourceOperation.READ, tableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.find = async ctx => {
|
exports.find = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const id = ctx.params.rowId
|
const id = ctx.params.rowId
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const response = await handleRequest(
|
const response = await handleRequest(DataSourceOperation.READ, tableId, {
|
||||||
appId,
|
id,
|
||||||
DataSourceOperation.READ,
|
})
|
||||||
tableId,
|
|
||||||
{
|
|
||||||
id,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return response ? response[0] : response
|
return response ? response[0] : response
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.destroy = async ctx => {
|
exports.destroy = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const id = ctx.request.body._id
|
const id = ctx.request.body._id
|
||||||
const { row } = await handleRequest(
|
const { row } = await handleRequest(DataSourceOperation.DELETE, tableId, {
|
||||||
appId,
|
id,
|
||||||
DataSourceOperation.DELETE,
|
})
|
||||||
tableId,
|
|
||||||
{
|
|
||||||
id,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return { response: { ok: true }, row }
|
return { response: { ok: true }, row }
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.bulkDestroy = async ctx => {
|
exports.bulkDestroy = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const { rows } = ctx.request.body
|
const { rows } = ctx.request.body
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
let promises = []
|
let promises = []
|
||||||
for (let row of rows) {
|
for (let row of rows) {
|
||||||
promises.push(
|
promises.push(
|
||||||
handleRequest(appId, DataSourceOperation.DELETE, tableId, {
|
handleRequest(DataSourceOperation.DELETE, tableId, {
|
||||||
id: breakRowIdField(row._id),
|
id: breakRowIdField(row._id),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -113,7 +97,6 @@ exports.bulkDestroy = async ctx => {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.search = async ctx => {
|
exports.search = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const { paginate, query, ...params } = ctx.request.body
|
const { paginate, query, ...params } = ctx.request.body
|
||||||
let { bookmark, limit } = params
|
let { bookmark, limit } = params
|
||||||
|
@ -143,26 +126,21 @@ exports.search = async ctx => {
|
||||||
[params.sort]: direction,
|
[params.sort]: direction,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const rows = await handleRequest(appId, DataSourceOperation.READ, tableId, {
|
const rows = await handleRequest(DataSourceOperation.READ, tableId, {
|
||||||
filters: query,
|
filters: query,
|
||||||
sort,
|
sort,
|
||||||
paginate: paginateObj,
|
paginate: paginateObj,
|
||||||
})
|
})
|
||||||
let hasNextPage = false
|
let hasNextPage = false
|
||||||
if (paginate && rows.length === limit) {
|
if (paginate && rows.length === limit) {
|
||||||
const nextRows = await handleRequest(
|
const nextRows = await handleRequest(DataSourceOperation.READ, tableId, {
|
||||||
appId,
|
filters: query,
|
||||||
DataSourceOperation.READ,
|
sort,
|
||||||
tableId,
|
paginate: {
|
||||||
{
|
limit: 1,
|
||||||
filters: query,
|
page: bookmark * limit + 1,
|
||||||
sort,
|
},
|
||||||
paginate: {
|
})
|
||||||
limit: 1,
|
|
||||||
page: bookmark * limit + 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
hasNextPage = nextRows.length > 0
|
hasNextPage = nextRows.length > 0
|
||||||
}
|
}
|
||||||
// need wrapper object for bookmarks etc when paginating
|
// need wrapper object for bookmarks etc when paginating
|
||||||
|
@ -175,7 +153,6 @@ exports.validate = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.fetchEnrichedRow = async ctx => {
|
exports.fetchEnrichedRow = async ctx => {
|
||||||
const appId = ctx.appId
|
|
||||||
const id = ctx.params.rowId
|
const id = ctx.params.rowId
|
||||||
const tableId = ctx.params.tableId
|
const tableId = ctx.params.tableId
|
||||||
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
||||||
|
@ -185,15 +162,10 @@ exports.fetchEnrichedRow = async ctx => {
|
||||||
ctx.throw(400, "Datasource has not been configured for plus API.")
|
ctx.throw(400, "Datasource has not been configured for plus API.")
|
||||||
}
|
}
|
||||||
const tables = datasource.entities
|
const tables = datasource.entities
|
||||||
const response = await handleRequest(
|
const response = await handleRequest(DataSourceOperation.READ, tableId, {
|
||||||
appId,
|
id,
|
||||||
DataSourceOperation.READ,
|
datasource,
|
||||||
tableId,
|
})
|
||||||
{
|
|
||||||
id,
|
|
||||||
datasource,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const table = tables[tableName]
|
const table = tables[tableName]
|
||||||
const row = response[0]
|
const row = response[0]
|
||||||
// this seems like a lot of work, but basically we need to dig deeper for the enrich
|
// this seems like a lot of work, but basically we need to dig deeper for the enrich
|
||||||
|
@ -212,7 +184,6 @@ exports.fetchEnrichedRow = async ctx => {
|
||||||
// don't support composite keys right now
|
// don't support composite keys right now
|
||||||
const linkedIds = links.map(link => breakRowIdField(link._id)[0])
|
const linkedIds = links.map(link => breakRowIdField(link._id)[0])
|
||||||
row[fieldName] = await handleRequest(
|
row[fieldName] = await handleRequest(
|
||||||
appId,
|
|
||||||
DataSourceOperation.READ,
|
DataSourceOperation.READ,
|
||||||
linkedTableId,
|
linkedTableId,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
// @ts-ignore
|
|
||||||
import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy"
|
import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
// @ts-ignore
|
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import { getUsageQuotaDoc } from "../../../utilities/usageQuota"
|
import { getUsageQuotaDoc } from "../../../utilities/usageQuota"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
// get app count
|
// get app count
|
||||||
|
// @ts-ignore
|
||||||
const devApps = await getAllApps({ dev: true })
|
const devApps = await getAllApps({ dev: true })
|
||||||
const appCount = devApps ? devApps.length : 0
|
const appCount = devApps ? devApps.length : 0
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// @ts-ignore
|
|
||||||
import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy"
|
import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
// @ts-ignore
|
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import { getUsageQuotaDoc } from "../../../utilities/usageQuota"
|
import { getUsageQuotaDoc } from "../../../utilities/usageQuota"
|
||||||
import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
||||||
|
@ -8,7 +6,9 @@ import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
// get all rows in all apps
|
// get all rows in all apps
|
||||||
|
// @ts-ignore
|
||||||
const allApps = await getAllApps({ all: true })
|
const allApps = await getAllApps({ all: true })
|
||||||
|
// @ts-ignore
|
||||||
const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : []
|
const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : []
|
||||||
const rows = await getUniqueRows(appIds)
|
const rows = await getUniqueRows(appIds)
|
||||||
const rowCount = rows ? rows.length : 0
|
const rowCount = rows ? rows.length : 0
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
declare module "@budibase/backend-core"
|
||||||
|
declare module "@budibase/backend-core/tenancy"
|
||||||
|
declare module "@budibase/backend-core/db"
|
|
@ -12,7 +12,8 @@
|
||||||
"incremental": true
|
"incremental": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src/**/*"
|
"./src/**/*",
|
||||||
|
"./src/module.d.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.cjs",
|
||||||
"module": "dist/bundle.mjs",
|
"module": "dist/bundle.mjs",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "1.0.49-alpha.6",
|
"version": "1.0.49-alpha.8",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "^1.0.49-alpha.6",
|
"@budibase/backend-core": "^1.0.49-alpha.8",
|
||||||
"@budibase/string-templates": "^1.0.49-alpha.6",
|
"@budibase/string-templates": "^1.0.49-alpha.8",
|
||||||
"@koa/router": "^8.0.0",
|
"@koa/router": "^8.0.0",
|
||||||
"@sentry/node": "^6.0.0",
|
"@sentry/node": "^6.0.0",
|
||||||
"@techpass/passport-openidconnect": "^0.3.0",
|
"@techpass/passport-openidconnect": "^0.3.0",
|
||||||
|
|
Loading…
Reference in New Issue