remove squirrelly, compile a single bundle.css for each page, svelte and hbs server rendering
This commit is contained in:
parent
6d135fa965
commit
9b914e0395
|
@ -77,7 +77,6 @@
|
||||||
"pouchdb-all-dbs": "^1.0.2",
|
"pouchdb-all-dbs": "^1.0.2",
|
||||||
"pouchdb-replication-stream": "^1.2.9",
|
"pouchdb-replication-stream": "^1.2.9",
|
||||||
"sanitize-s3-objectkey": "^0.0.1",
|
"sanitize-s3-objectkey": "^0.0.1",
|
||||||
"squirrelly": "^7.5.0",
|
|
||||||
"svelte": "^3.29.4",
|
"svelte": "^3.29.4",
|
||||||
"tar-fs": "^2.1.0",
|
"tar-fs": "^2.1.0",
|
||||||
"to-json-schema": "^0.2.5",
|
"to-json-schema": "^0.2.5",
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
require("svelte/register")
|
require("svelte/register")
|
||||||
|
|
||||||
const send = require("koa-send")
|
const send = require("koa-send")
|
||||||
const { resolve, join } = require("../../utilities/centralPath")
|
const { resolve, join } = require("../../../utilities/centralPath")
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
const fs = require("fs-extra")
|
const fs = require("fs-extra")
|
||||||
const uuid = require("uuid")
|
const uuid = require("uuid")
|
||||||
const AWS = require("aws-sdk")
|
const AWS = require("aws-sdk")
|
||||||
const { prepareUploadForS3 } = require("./deploy/aws")
|
const { prepareUploadForS3 } = require("../deploy/aws")
|
||||||
|
const handlebars = require("handlebars")
|
||||||
const {
|
const {
|
||||||
budibaseAppsDir,
|
budibaseAppsDir,
|
||||||
budibaseTempDir,
|
budibaseTempDir,
|
||||||
} = require("../../utilities/budibaseDir")
|
} = require("../../../utilities/budibaseDir")
|
||||||
const CouchDB = require("../../db")
|
const { getPageParams } = require("../../../db/utils")
|
||||||
const setBuilderToken = require("../../utilities/builder/setBuilderToken")
|
const CouchDB = require("../../../db")
|
||||||
const fileProcessor = require("../../utilities/fileProcessor")
|
const setBuilderToken = require("../../../utilities/builder/setBuilderToken")
|
||||||
const { AuthTypes } = require("../../constants")
|
const fileProcessor = require("../../../utilities/fileProcessor")
|
||||||
const env = require("../../environment")
|
const { AuthTypes } = require("../../../constants")
|
||||||
|
const env = require("../../../environment")
|
||||||
|
|
||||||
// this was the version before we started versioning the component library
|
// this was the version before we started versioning the component library
|
||||||
const COMP_LIB_BASE_APP_VERSION = "0.2.5"
|
const COMP_LIB_BASE_APP_VERSION = "0.2.5"
|
||||||
|
|
||||||
exports.serveBuilder = async function(ctx) {
|
exports.serveBuilder = async function(ctx) {
|
||||||
let builderPath = resolve(__dirname, "../../../builder")
|
let builderPath = resolve(__dirname, "../../../../builder")
|
||||||
if (ctx.file === "index.html") {
|
if (ctx.file === "index.html") {
|
||||||
await setBuilderToken(ctx)
|
await setBuilderToken(ctx)
|
||||||
}
|
}
|
||||||
|
@ -141,37 +143,31 @@ exports.performLocalFileProcessing = async function(ctx) {
|
||||||
|
|
||||||
exports.serveAppNew = async function(ctx) {
|
exports.serveAppNew = async function(ctx) {
|
||||||
const App = require("./templates/BudibaseApp.svelte").default
|
const App = require("./templates/BudibaseApp.svelte").default
|
||||||
|
// Need to get app information here
|
||||||
|
|
||||||
const { html } = App.render({
|
const db = new CouchDB(ctx.params.appId)
|
||||||
name: "Budibase",
|
|
||||||
authenticated:
|
const appInfo = await db.get(ctx.params.appId)
|
||||||
|
|
||||||
|
console.log("INFO", appInfo)
|
||||||
|
|
||||||
|
const { head, html, css } = App.render({
|
||||||
|
title: appInfo.name,
|
||||||
|
pageName:
|
||||||
ctx.auth.authenticated === AuthTypes.APP ? "main" : "unauthenticated",
|
ctx.auth.authenticated === AuthTypes.APP ? "main" : "unauthenticated",
|
||||||
production: env.CLOUD,
|
production: env.CLOUD,
|
||||||
|
appId: ctx.params.appId,
|
||||||
})
|
})
|
||||||
|
|
||||||
// // default to homedir
|
const template = handlebars.compile(
|
||||||
// const appPath = resolve(
|
fs.readFileSync(`${__dirname}/templates/app.hbs`, "utf8")
|
||||||
// budibaseAppsDir(),
|
)
|
||||||
// ctx.params.appId,
|
|
||||||
// "public",
|
|
||||||
// mainOrAuth
|
|
||||||
// )
|
|
||||||
|
|
||||||
ctx.body = html
|
ctx.body = template({
|
||||||
|
head,
|
||||||
// const appId = ctx.user.appId
|
body: html,
|
||||||
|
style: css.code,
|
||||||
// if (env.CLOUD) {
|
})
|
||||||
// const S3_URL = `https://${appId}.app.budi.live/assets/${appId}/${mainOrAuth}/${ctx.file ||
|
|
||||||
// "index.production.html"}`
|
|
||||||
|
|
||||||
// const response = await fetch(S3_URL)
|
|
||||||
// const body = await response.text()
|
|
||||||
// ctx.body = body
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await send(ctx, ctx.file || "index.html", { root: ctx.devPath || appPath })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.serveApp = async function(ctx) {
|
exports.serveApp = async function(ctx) {
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
<script>
|
||||||
|
export let title = ""
|
||||||
|
export let favicon = ""
|
||||||
|
|
||||||
|
export let appId
|
||||||
|
export let pageName = ""
|
||||||
|
export let production
|
||||||
|
|
||||||
|
export const PRODUCTION_ASSETS_URL = `https://${appId}.app.budi.live`
|
||||||
|
|
||||||
|
function publicPath(path) {
|
||||||
|
if (production) {
|
||||||
|
return `${PRODUCTION_ASSETS_URL}/assets/${appId}/${pageName}/${path}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `/assets/${path}`
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<meta charset="utf8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
|
||||||
|
<title>{title}</title>
|
||||||
|
<link rel="icon" type="image/png" href={favicon} />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href={publicPath("bundle.css")} />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Roboto+Mono" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
font-family: Inter;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<body id="app">
|
||||||
|
<script src={publicPath('clientFrontendDefinition.js')}>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script src={publicPath('budibase-client.js')}>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
loadBudibase()
|
||||||
|
</script>
|
||||||
|
</body>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
{{{head}}}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
{{{body}}}
|
||||||
|
|
||||||
|
</html>
|
|
@ -1,63 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset='utf8'>
|
|
||||||
<meta name='viewport' content='width=device-width'>
|
|
||||||
|
|
||||||
<title>{{ title }}</title>
|
|
||||||
<link rel='icon' type='image/png' href='{{ favicon }}'>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
font-family: Inter;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
*, *:before, *:after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{{ each(options.stylesheets) }}
|
|
||||||
<link rel='stylesheet' href='{{ @this }}'>
|
|
||||||
{{ /each }}
|
|
||||||
|
|
||||||
{{ each(options.screenStyles) }}
|
|
||||||
{{ if(options.production) }}
|
|
||||||
<link rel='stylesheet' href='/assets/{{ appId }}/{{ pageName }}{{ @this }}'>
|
|
||||||
{{#else}}
|
|
||||||
<link rel='stylesheet' href='/assets{{ @this }}'>
|
|
||||||
{{ /if }}
|
|
||||||
{{ /each }}
|
|
||||||
|
|
||||||
{{ if(options.pageStyle) }}
|
|
||||||
{{ if(options.production) }}
|
|
||||||
<link rel='stylesheet' href='/assets/{{ appId }}/{{ pageName }}{{ pageStyle }}'>
|
|
||||||
{{#else}}
|
|
||||||
<link rel='stylesheet' href='/assets{{ pageStyle }}'>
|
|
||||||
{{ /if }}
|
|
||||||
{{ /if }}
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono">
|
|
||||||
|
|
||||||
{{ if(options.production) }}
|
|
||||||
<script src='/assets/{{ appId }}/{{ pageName }}/clientFrontendDefinition.js'></script>
|
|
||||||
<script src='/assets/{{ appId }}/{{ pageName }}/budibase-client.js'></script>
|
|
||||||
{{#else}}
|
|
||||||
<script src='/assets/clientFrontendDefinition.js'></script>
|
|
||||||
<script src='/assets/budibase-client.js'></script>
|
|
||||||
{{ /if }}
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body id="app">
|
|
||||||
<script>
|
|
||||||
loadBudibase();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -33,6 +33,6 @@ router
|
||||||
.get("/componentlibrary", controller.serveComponentLibrary)
|
.get("/componentlibrary", controller.serveComponentLibrary)
|
||||||
.get("/assets/:file*", controller.serveAppAsset)
|
.get("/assets/:file*", controller.serveAppAsset)
|
||||||
.get("/attachments/:file*", controller.serveAttachment)
|
.get("/attachments/:file*", controller.serveAttachment)
|
||||||
.get("/:appId/:path*", controller.serveApp)
|
.get("/:appId/:path*", controller.serveAppNew)
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -38,6 +38,6 @@ function replicateLocal() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//replicateLocal()
|
replicateLocal()
|
||||||
|
|
||||||
module.exports = Pouch
|
module.exports = Pouch
|
||||||
|
|
|
@ -1,27 +1,25 @@
|
||||||
const { constants, copyFile, writeFile, readFile } = require("fs-extra")
|
const { ensureDir, constants, copyFile, writeFile } = require("fs-extra")
|
||||||
const { join, resolve } = require("../centralPath")
|
const { join } = require("../centralPath")
|
||||||
const sqrl = require("squirrelly")
|
const { convertCssToBundle } = require("./convertCssToFiles")
|
||||||
const { convertCssToFiles } = require("./convertCssToFiles")
|
|
||||||
const publicPath = require("./publicPath")
|
|
||||||
const { budibaseAppsDir } = require("../budibaseDir")
|
const { budibaseAppsDir } = require("../budibaseDir")
|
||||||
|
|
||||||
module.exports = async (appId, pageName, pkg) => {
|
module.exports = async (appId, pageName, pkg) => {
|
||||||
const appPath = join(budibaseAppsDir(), appId)
|
const pagePath = join(budibaseAppsDir(), appId, "public", pageName)
|
||||||
|
|
||||||
pkg.screens = pkg.screens || []
|
pkg.screens = pkg.screens || []
|
||||||
|
|
||||||
await convertCssToFiles(publicPath(appPath, pageName), pkg)
|
await ensureDir(pagePath)
|
||||||
|
|
||||||
await buildIndexHtml(appId, pageName, appPath, pkg)
|
await convertCssToBundle(pagePath, pkg)
|
||||||
|
|
||||||
await buildFrontendAppDefinition(appId, pageName, pkg, appPath)
|
await buildFrontendAppDefinition(pagePath, pkg)
|
||||||
|
|
||||||
await copyClientLib(appPath, pageName)
|
await copyClientLib(pagePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyClientLib = async (appPath, pageName) => {
|
const copyClientLib = async pagePath => {
|
||||||
const sourcepath = require.resolve("@budibase/client")
|
const sourcepath = require.resolve("@budibase/client")
|
||||||
const destPath = join(publicPath(appPath, pageName), "budibase-client.js")
|
const destPath = join(pagePath, "budibase-client.js")
|
||||||
|
|
||||||
await copyFile(sourcepath, destPath, constants.COPYFILE_FICLONE)
|
await copyFile(sourcepath, destPath, constants.COPYFILE_FICLONE)
|
||||||
|
|
||||||
|
@ -32,44 +30,8 @@ const copyClientLib = async (appPath, pageName) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildIndexHtml = async (appId, pageName, appPath, pkg) => {
|
const buildFrontendAppDefinition = async (pagePath, pkg) => {
|
||||||
const appPublicPath = publicPath(appPath, pageName)
|
const filename = join(pagePath, "clientFrontendDefinition.js")
|
||||||
|
|
||||||
const stylesheetUrl = s => (s.startsWith("http") ? s : `/${appId}/${s}`)
|
|
||||||
|
|
||||||
const templateObj = {
|
|
||||||
title: pkg.page.title || "Budibase App",
|
|
||||||
favicon: `${pkg.page.favicon || "/_shared/favicon.png"}`,
|
|
||||||
stylesheets: (pkg.page.stylesheets || []).map(stylesheetUrl),
|
|
||||||
screenStyles: pkg.screens.filter(s => s._css).map(s => s._css),
|
|
||||||
pageStyle: pkg.page._css,
|
|
||||||
appId,
|
|
||||||
pageName,
|
|
||||||
}
|
|
||||||
|
|
||||||
const indexHtmlTemplate = await readFile(
|
|
||||||
resolve(__dirname, "index.template.html"),
|
|
||||||
"utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
const indexHtmlPath = join(appPublicPath, "index.html")
|
|
||||||
const deployableHtmlPath = join(appPublicPath, "index.production.html")
|
|
||||||
|
|
||||||
const indexHtml = sqrl.Render(indexHtmlTemplate, templateObj)
|
|
||||||
const deployableHtml = sqrl.Render(indexHtmlTemplate, {
|
|
||||||
...templateObj,
|
|
||||||
production: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
await writeFile(indexHtmlPath, indexHtml, { flag: "w+" })
|
|
||||||
await writeFile(deployableHtmlPath, deployableHtml, { flag: "w+" })
|
|
||||||
}
|
|
||||||
|
|
||||||
const buildFrontendAppDefinition = async (appId, pageName, pkg) => {
|
|
||||||
const appPath = join(budibaseAppsDir(), appId)
|
|
||||||
const appPublicPath = publicPath(appPath, pageName)
|
|
||||||
|
|
||||||
const filename = join(appPublicPath, "clientFrontendDefinition.js")
|
|
||||||
|
|
||||||
delete pkg.page._css
|
delete pkg.page._css
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
const crypto = require("crypto")
|
const { writeFile } = require("fs-extra")
|
||||||
const { ensureDir, emptyDir, writeFile } = require("fs-extra")
|
|
||||||
const { join } = require("../centralPath")
|
const { join } = require("../centralPath")
|
||||||
|
|
||||||
module.exports.convertCssToFiles = async (publicPagePath, pkg) => {
|
/**
|
||||||
const cssDir = join(publicPagePath, "css")
|
* Reads the _css property of all pages and screens in the budibase application, and creates a singlular CSS
|
||||||
await ensureDir(cssDir)
|
* bundle for the app at <appId>/public/bundle.css.
|
||||||
await emptyDir(cssDir)
|
* @param {*} publicPagePath - path to the public assets directory of the budibase application
|
||||||
|
* @param {*} pkg - app package information
|
||||||
|
* @param {*} pageName - the pagename of the page we are compiling CSS for.
|
||||||
|
*/
|
||||||
|
module.exports.convertCssToBundle = async (publicPagePath, pkg) => {
|
||||||
|
let cssString = ""
|
||||||
|
|
||||||
for (let screen of pkg.screens || []) {
|
for (let screen of pkg.screens || []) {
|
||||||
if (!screen._css) continue
|
if (!screen._css) continue
|
||||||
|
@ -13,31 +17,10 @@ module.exports.convertCssToFiles = async (publicPagePath, pkg) => {
|
||||||
delete screen._css
|
delete screen._css
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
screen._css = await createCssFile(cssDir, screen._css)
|
cssString += screen._css
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkg.page._css) {
|
if (pkg.page._css) cssString += pkg.page._css
|
||||||
pkg.page._css = await createCssFile(cssDir, pkg.page._css)
|
|
||||||
}
|
writeFile(join(publicPagePath, "bundle.css"), cssString)
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.getHashedCssPaths = (cssDir, _css) => {
|
|
||||||
const fileName =
|
|
||||||
crypto
|
|
||||||
.createHash("md5")
|
|
||||||
.update(_css)
|
|
||||||
.digest("hex") + ".css"
|
|
||||||
|
|
||||||
const filePath = join(cssDir, fileName)
|
|
||||||
const url = `/css/${fileName}`
|
|
||||||
|
|
||||||
return { filePath, url }
|
|
||||||
}
|
|
||||||
|
|
||||||
const createCssFile = async (cssDir, _css) => {
|
|
||||||
const { filePath, url } = module.exports.getHashedCssPaths(cssDir, _css)
|
|
||||||
|
|
||||||
await writeFile(filePath, _css)
|
|
||||||
|
|
||||||
return url
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
const { join } = require("../centralPath")
|
|
||||||
|
|
||||||
module.exports = (appPath, pageName) => join(appPath, "public", pageName)
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { existsSync, readFile, writeFile, ensureDir } = require("fs-extra")
|
const { existsSync, readFile, writeFile, ensureDir } = require("fs-extra")
|
||||||
const { join, resolve } = require("./centralPath")
|
const { join, resolve } = require("./centralPath")
|
||||||
const Sqrl = require("squirrelly")
|
const handlebars = require("handlebars")
|
||||||
const uuid = require("uuid")
|
const uuid = require("uuid")
|
||||||
|
|
||||||
module.exports = async opts => {
|
module.exports = async opts => {
|
||||||
|
@ -31,7 +31,8 @@ const createDevEnvFile = async opts => {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
opts.cookieKey1 = opts.cookieKey1 || uuid.v4()
|
opts.cookieKey1 = opts.cookieKey1 || uuid.v4()
|
||||||
const config = Sqrl.Render(template, opts)
|
const hbTemplate = handlebars.compile(template)
|
||||||
|
const config = hbTemplate.render(opts)
|
||||||
await writeFile(destConfigFile, config, { flag: "w+" })
|
await writeFile(destConfigFile, config, { flag: "w+" })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,10 +200,10 @@
|
||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@budibase/client@^0.3.4":
|
"@budibase/client@^0.3.6":
|
||||||
version "0.3.4"
|
version "0.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.3.4.tgz#aca2d13170dae870d069a56f53519d9fbb4bdc00"
|
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.3.7.tgz#8ed2d40d91ba3788a69ee5db5078f757adb4187f"
|
||||||
integrity sha512-zs9Jnr1CzvgZY4NrliatqDUm0gVhlcQkpdsMblO+3zRcwBzRXAeFyzwMtGpcbiQm29zHjPBOivmQQUMxgi3lUg==
|
integrity sha512-EgpHfw/WOUYeCG4cILDbaN2WFBDSPS698Z+So7FP5l+4E1fvmqtpXVKJYsviwYEx8AKKYyU3nuDi0l6xzb5Flg==
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-equal "^2.0.1"
|
deep-equal "^2.0.1"
|
||||||
mustache "^4.0.1"
|
mustache "^4.0.1"
|
||||||
|
@ -7146,11 +7146,6 @@ sprintf-js@~1.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||||
|
|
||||||
squirrelly@^7.5.0:
|
|
||||||
version "7.9.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/squirrelly/-/squirrelly-7.9.2.tgz#f8b0a08201b73653351afe9f7f24878237d2751a"
|
|
||||||
integrity sha512-QsLQ43p7/p5LfhqMsUM1PP0DU/YuirA/pZ1RQKU8/qZjWHD8uTblpfPoCVkD9VLrS1jCJ+2gqECv3amlPgrLCA==
|
|
||||||
|
|
||||||
sshpk@^1.7.0:
|
sshpk@^1.7.0:
|
||||||
version "1.16.1"
|
version "1.16.1"
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
||||||
|
|
Loading…
Reference in New Issue