Move publisher to Azure Functions (#221)

* Functions MVP

* Actually commit root files

* Fix typo

* Enable remote build?

* Save temp directory as artifact?

* Blah

* Try to convince Oryx to use yarn

* Make independent tsconfig for deployed app

* Remote build doesn’t need to run tsc

* Whatever

* Functions have to be at the source root

* Add test function for fileshare

* Stooppppp

* SDFKLJSDFJKLDSFJKLSFDKLJ

* Make test HTTP trigger run the whole thing

* Set timeout to an hour

* Remove unused config

* App insights starts on its own, I think

* Update fs-extra

* Update node in dependencies

* Fix type error

* Use file lock, fix app insights

* Log response

* Bump timeout to 1:30

* Rename triggers for better alphabetical sort

* Update gitignore

* Update CI versions to latest two LTS
This commit is contained in:
Andrew Branch
2021-03-25 09:57:18 -07:00
committed by GitHub
parent b9edf7c41d
commit 5061974f41
25 changed files with 194 additions and 310 deletions

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [ '10', '12' ]
node: [ '12', '14' ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1

View File

@@ -1,5 +1,10 @@
on:
workflow_dispatch: {}
workflow_dispatch:
inputs:
checkout:
description: ref to deploy
required: true
default: master
repository_dispatch:
types: [published]
jobs:
@@ -8,39 +13,30 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
ref: master
ref: ${{ github.event.inputs.checkout || 'master' }}
- uses: actions/setup-node@v1
with:
node-version: 12.15.0
node-version: 14
- name: install
run: yarn install --frozen-lockfile
- name: lint
run: yarn lint
- name: test
run: yarn test
- name: package
run: |
pushd packages/publisher
mkdir packed && cd $_
cp ../../../yarn.lock ./
cp ../package.json ./
cp ../tsconfig.json ./
cp ../server.js ./
cp ../IISNode.yml ./
cp ../LICENSE ./
cp ../.deployment ./
cp ../deploy.sh ./
cp -r ../dist ./
popd
- name: copy yarn.lock
run: cp yarn.lock packages/publisher/
- name: deploy publisher
uses: azure/webapps-deploy@v2
uses: azure/functions-action@v1
with:
app-name: TypesPublisher
publish-profile: ${{ secrets.typesPublisherAzurePublishProfile }}
package: packages/publisher/packed
app-name: types-publisher
slot-name: production
- name: upload packed directory
publish-profile: ${{ secrets.typesPublisherFunctionsPublishProfile }}
package: packages/publisher
scm-do-build-during-deployment: true
enable-oryx-build: true
- name: upload artifacts
if: always()
uses: actions/upload-artifact@v1
with:
name: publisher
path: packages/publisher/packed
name: temp
path: /home/runner/work/_temp

View File

@@ -4,7 +4,8 @@
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"esbenp.prettier-vscode"
"esbenp.prettier-vscode",
"ms-azuretools.vscode-azurefunctions"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [

View File

@@ -15,7 +15,7 @@
},
"devDependencies": {
"@types/jest": "^25.1.3",
"@types/node": "^12.12.29",
"@types/node": "^14.14.35",
"@types/yargs": "^15.0.4",
"@typescript-eslint/eslint-plugin": "^4.8.1",
"@typescript-eslint/parser": "^4.8.1",

View File

@@ -22,11 +22,11 @@
"@definitelytyped/header-parser": "^0.0.73",
"@definitelytyped/typescript-versions": "^0.0.73",
"@definitelytyped/utils": "^0.0.74-next.1",
"@types/node": "^12.12.29",
"fs-extra": "^8.1.0"
"@types/node": "^14.14.35",
"fs-extra": "^9.1.0"
},
"devDependencies": {
"@types/fs-extra": "^8.1.0",
"@types/fs-extra": "^9.0.8",
"typescript": "^4.1.0"
},
"peerDependencies": {

View File

@@ -1,2 +0,0 @@
[config]
command = bash deploy.sh

View File

@@ -0,0 +1,6 @@
*.js.map
*.ts
.git*
.vscode
local.settings.json
test

View File

@@ -7,3 +7,5 @@ output/
validateOutput/
\#*
.\#*
local.settings.json
lock.json

View File

@@ -1,16 +0,0 @@
language: node_js
node_js:
- 'node'
sudo: false
branches:
only:
- master
install:
- npm ci
git:
depth: 1

View File

@@ -1,7 +0,0 @@
# For all options see https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/iisnode.yml
nodeProcessCommandLine: node.exe --stack-trace-limit=1000
loggingEnabled: true
devErrorsEnabled: false
maxLogFileSizeInKB: 2048
maxTotalLogFileSizeInKB: 65536
maxLogFiles: 16384

View File

@@ -1,132 +0,0 @@
#!/bin/bash
# ----------------------
# KUDU Deployment Script
# Version: 1.0.17
# ----------------------
# Helpers
# -------
exitWithMessageOnError () {
if [ ! $? -eq 0 ]; then
echo "An error has occurred during web site deployment."
echo $1
exit 1
fi
}
# Prerequisites
# -------------
# Verify node.js installed
hash node 2>/dev/null
exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment."
# Setup
# -----
SCRIPT_DIR="${BASH_SOURCE[0]%\\*}"
SCRIPT_DIR="${SCRIPT_DIR%/*}"
ARTIFACTS=$SCRIPT_DIR/../artifacts
KUDU_SYNC_CMD=${KUDU_SYNC_CMD//\"}
if [[ ! -n "$DEPLOYMENT_SOURCE" ]]; then
DEPLOYMENT_SOURCE=$SCRIPT_DIR
fi
if [[ ! -n "$NEXT_MANIFEST_PATH" ]]; then
NEXT_MANIFEST_PATH=$ARTIFACTS/manifest
if [[ ! -n "$PREVIOUS_MANIFEST_PATH" ]]; then
PREVIOUS_MANIFEST_PATH=$NEXT_MANIFEST_PATH
fi
fi
if [[ ! -n "$DEPLOYMENT_TARGET" ]]; then
DEPLOYMENT_TARGET=$ARTIFACTS/wwwroot
else
KUDU_SERVICE=true
fi
if [[ ! -n "$KUDU_SYNC_CMD" ]]; then
# Install kudu sync
echo Installing Kudu Sync
npm install kudusync -g --silent
exitWithMessageOnError "npm failed"
if [[ ! -n "$KUDU_SERVICE" ]]; then
# In case we are running locally this is the correct location of kuduSync
KUDU_SYNC_CMD=kuduSync
else
# In case we are running on kudu service this is the correct location of kuduSync
KUDU_SYNC_CMD=$APPDATA/npm/node_modules/kuduSync/bin/kuduSync
fi
fi
# Node Helpers
# ------------
selectNodeVersion () {
if [[ -n "$KUDU_SELECT_NODE_VERSION_CMD" ]]; then
SELECT_NODE_VERSION="$KUDU_SELECT_NODE_VERSION_CMD \"$DEPLOYMENT_SOURCE\" \"$DEPLOYMENT_TARGET\" \"$DEPLOYMENT_TEMP\""
eval $SELECT_NODE_VERSION
exitWithMessageOnError "select node version failed"
if [[ -e "$DEPLOYMENT_TEMP/__nodeVersion.tmp" ]]; then
NODE_EXE=`cat "$DEPLOYMENT_TEMP/__nodeVersion.tmp"`
exitWithMessageOnError "getting node version failed"
fi
if [[ -e "$DEPLOYMENT_TEMP/__npmVersion.tmp" ]]; then
NPM_JS_PATH=`cat "$DEPLOYMENT_TEMP/__npmVersion.tmp"`
exitWithMessageOnError "getting npm version failed"
fi
if [[ ! -n "$NODE_EXE" ]]; then
NODE_EXE=node
fi
NPM_CMD="\"$NODE_EXE\" \"$NPM_JS_PATH\""
else
NPM_CMD=npm
NODE_EXE=node
fi
}
##################################################################################################################################
# Deployment
# ----------
echo Handling node.js deployment.
# 1. Select node version
selectNodeVersion
# 2. Install npm packages
if [ -e "$DEPLOYMENT_SOURCE/package.json" ]; then
pushd "$DEPLOYMENT_SOURCE"
echo "Installing yarn"
eval $NPM_CMD install --global yarn@1.19.2
echo "Removing previous node_modules"
rm -rf node_modules || true
echo "Running yarn install --production"
NPM_BIN=`eval $NPM_CMD --global bin`
"$NPM_BIN/yarn" install --production
popd
exitWithMessageOnError "yarn failed"
fi
# 1. KuduSync
if [[ "$IN_PLACE_DEPLOYMENT" -ne "1" ]]; then
rm -rf "$DEPLOYMENT_TARGET/node_modules" # Sync sometimes messes up node_modules
"$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_SOURCE" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh"
exitWithMessageOnError "Kudu Sync failed"
fi
##################################################################################################################################
echo "Finished successfully."

View File

@@ -0,0 +1,16 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
},
"functionTimeout": "01:30:00"
}

View File

@@ -6,6 +6,7 @@
"types": "dist/index.d.ts",
"description": "Publish DefinitelyTyped definitions to NPM",
"dependencies": {
"@azure/functions": "^1.2.3",
"@definitelytyped/definitions-parser": "^0.0.74-next.1",
"@definitelytyped/header-parser": "^0.0.73",
"@definitelytyped/retag": "^0.0.74-next.1",
@@ -15,7 +16,7 @@
"adal-node": "^0.1.22",
"applicationinsights": "^1.0.7",
"azure-keyvault": "^3.0.4",
"fs-extra": "4.0.0",
"fs-extra": "^9.1.0",
"fstream": "^1.0.12",
"longjohn": "^0.2.11",
"npm": "^6.13.4",
@@ -26,9 +27,8 @@
"yargs": "15.3.1"
},
"devDependencies": {
"@types/fs-extra": "4.0.0",
"@types/fs-extra": "^9.0.8",
"@types/mz": "^0.0.31",
"@types/node": "^12.12.29",
"@types/oboe": "^2.0.28",
"@types/source-map-support": "^0.4.0",
"@types/travis-fold": "^0.1.0",
@@ -36,6 +36,7 @@
},
"scripts": {
"build": "tsc -b",
"oryx": "echo 'Skipping build, should already have built with tsc during CI, before deployment.'",
"test": "../../node_modules/.bin/jest --config ../../jest.config.js packages/publisher",
"clean": "node -r source-map-support/register dist/clean.js",
"get-definitely-typed": "node -r source-map-support/register dist/get-definitely-typed.js",

View File

@@ -1,3 +0,0 @@
require("./dist/main.js")
.default()
.catch(console.error);

View File

@@ -1,17 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "9229",
"port": 9229,
"sourceMaps": true,
"stopOnEntry": false
}
]
}

View File

@@ -4,11 +4,6 @@ import { mapDefined } from "@definitelytyped/utils";
import { azureKeyvault } from "./settings";
export enum Secret {
/**
* Used to upload blobs.
* To find (or refresh) this value, go to https://ms.portal.azure.com -> All resources -> typespublisher -> General -> Access keys
*/
AZURE_STORAGE_ACCESS_KEY,
/**
* Lets the server update an issue (https://github.com/Microsoft/types-publisher/issues/40) on GitHub in case of an error.
* Create a token at: https://github.com/settings/tokens

View File

@@ -6,6 +6,7 @@ export const cacheDirPath = joinPaths(storageDirPath, "cache");
export const outputDirPath = joinPaths(storageDirPath, "output");
export const validateOutputPath = joinPaths(storageDirPath, "validateOutput");
export const logDir = joinPaths(storageDirPath, "logs");
export const lockFilePath = joinPaths(storageDirPath, "lock.json");
/** URL to download the repository from. */
export const definitelyTypedZipUrl = "https://codeload.github.com/DefinitelyTyped/DefinitelyTyped/tar.gz/master";

View File

@@ -1,85 +1,70 @@
import applicationinsights = require("applicationinsights");
import * as yargs from "yargs";
import { pathExists, writeFile, readFile, remove } from "fs-extra";
import { getSecret, Secret } from "./lib/secrets";
import { Fetcher, loggerWithErrors, LoggerWithErrors } from "@definitelytyped/utils";
import { Fetcher, loggerWithErrors } from "@definitelytyped/utils";
import { currentTimeStamp } from "./util/util";
import full from "./full";
import { lockFilePath } from "./lib/settings";
export default async function main(): Promise<void> {
const githubAccessToken = await getSecret(Secret.GITHUB_ACCESS_TOKEN);
const dry = !!(yargs.argv.dry || process.env.WEBHOOK_FORCE_DRY);
export default function main() {
return withFileLock(lockFilePath, async () => {
const githubAccessToken = await getSecret(Secret.GITHUB_ACCESS_TOKEN);
const dry = !!(yargs.argv.dry || process.env.WEBHOOK_FORCE_DRY);
if (!githubAccessToken) {
console.log("The environment variable GITHUB_ACCESS_TOKEN must be set.");
} else {
console.log(`=== ${dry ? "DRY" : "PRODUCTION"} RUN ===`);
if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
applicationinsights.setup().start();
console.log("Done initialising App Insights");
}
const fetcher = new Fetcher();
try {
if (!githubAccessToken) {
console.log("The environment variable GITHUB_ACCESS_TOKEN must be set.");
} else {
console.log(`=== ${dry ? "DRY" : "PRODUCTION"} RUN ===`);
if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
applicationinsights.setup().start();
console.log("Done initialising App Insights");
}
const fetcher = new Fetcher();
const log = loggerWithErrors()[0];
const fullOne = updateOneAtATime(async () => {
log.info("");
log.info("");
log.info(`# ${currentTimeStamp()}`);
log.info("");
log.info("Starting full...");
try {
await full(
dry,
githubAccessToken,
fetcher,
{
definitelyTypedPath: undefined,
parseInParallel: false,
progress: false
},
log
);
} catch (err) {
log.info(err.toString());
console.error(err);
}
});
log.info("");
log.info("");
log.info(`# ${currentTimeStamp()}`);
log.info("");
log.info("Starting full...");
await full(
dry,
githubAccessToken,
fetcher,
{
definitelyTypedPath: undefined,
parseInParallel: false,
progress: false
},
log
);
}
});
}
setInterval(fullOne, 2_000_000, log);
await fullOne(log);
} catch (e) {
type LockFileResult = { triggered: true } | { triggered: false, timestamp: string };
async function withFileLock(lockFilePath: string, cb: () => Promise<void>): Promise<LockFileResult> {
if (await pathExists(lockFilePath)) {
return { triggered: false, timestamp: await readFile(lockFilePath, "utf8")};
} else {
await writeFile(lockFilePath, currentTimeStamp());
cb().then(() => remove(lockFilePath), async error => {
await removeLock();
applicationinsights.defaultClient.trackEvent({
name: "crash",
properties: {
error: e.toString()
error: String(error)
}
});
throw e;
}
process.exit(1);
});
return { triggered: true };
}
async function removeLock() {
await remove(lockFilePath);
}
}
// If an update is still running after 2000 seconds, dont start a new one
function updateOneAtATime(doOnce: () => Promise<void>) {
let working = false;
return (log: LoggerWithErrors) => {
if (working) {
log.info("Not starting update, because already performing one.");
return undefined;
}
return work();
async function work(): Promise<void> {
log.info("Starting update");
working = true;
try {
await doOnce();
} catch (e) {
log.info(e.toString());
} finally {
working = false;
}
}
};
}

View File

@@ -0,0 +1,11 @@
import { AzureFunction, Context } from "@azure/functions";
import main from "../main";
const httpTrigger: AzureFunction = async function (context: Context): Promise<void> {
context.log('HTTP trigger function processed a request.');
const res = await main();
context.log(res);
context.res = res;
};
export default httpTrigger;

View File

@@ -0,0 +1,7 @@
import { Context } from "@azure/functions";
import main from "../main";
export default async function timerTrigger(context: Context) {
context.log("Running via timer trigger");
return main();
}

View File

@@ -0,0 +1,20 @@
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
],
"scriptFile": "../dist/functions/HttpTrigger.js"
}

View File

@@ -0,0 +1,11 @@
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */30 * * * *"
}
],
"scriptFile": "../dist/functions/TimerTrigger.js"
}

View File

@@ -20,7 +20,7 @@
},
"dependencies": {
"@definitelytyped/typescript-versions": "^0.0.73",
"@types/node": "^12.12.29",
"@types/node": "^14.14.35",
"charm": "^1.0.2",
"fs-extra": "^8.1.0",
"fstream": "^1.0.12",

View File

@@ -1,5 +1,5 @@
import assert from "assert";
import { ChildProcess, exec as node_exec, fork } from "child_process";
import { ChildProcess, exec as node_exec, fork, Serializable } from "child_process";
import { Socket } from "net";
const DEFAULT_CRASH_RECOVERY_MAX_OLD_SPACE_SIZE = 4096;
@@ -113,7 +113,7 @@ interface RunWithListeningChildProcessesOptions<In> {
handleStart?(input: In, processIndex: number | undefined): void;
handleCrash?(input: In, state: CrashRecoveryState, processIndex: number | undefined): void;
}
export function runWithListeningChildProcesses<In>({
export function runWithListeningChildProcesses<In extends Serializable>({
inputs,
commandLineArgs,
workerFile,

View File

@@ -18,6 +18,11 @@
tslib "^1.10.0"
uuid "^3.3.2"
"@azure/functions@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@azure/functions/-/functions-1.2.3.tgz#65765837e7319eedffbf8a971cb2f78d4e043d54"
integrity sha512-dZITbYPNg6ay6ngcCOjRUh1wDhlFITS0zIkqplyH5KfKEAVPooaoaye5mUFnR+WP9WdGRjlNXyl/y2tgWKHcRg==
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
@@ -1488,13 +1493,6 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
"@types/fs-extra@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.0.tgz#1dd742ad5c9bce308f7a52d02ebc01421bc9102f"
integrity sha512-PlKJw6ujJXLJjbvB3T0UCbY3jibKM6/Ya5cc9j1q+mYDeK3aR4Dp+20ZwxSuvJr9mIoPxp7+IL4aMOEvsscRTA==
dependencies:
"@types/node" "*"
"@types/fs-extra@^8.1.0":
version "8.1.0"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d"
@@ -1502,6 +1500,13 @@
dependencies:
"@types/node" "*"
"@types/fs-extra@^9.0.8":
version "9.0.8"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.8.tgz#32c3c07ddf8caa5020f84b5f65a48470519f78ba"
integrity sha512-bnlTVTwq03Na7DpWxFJ1dvnORob+Otb8xHyUqUWhqvz/Ksg8+JXPlR52oeMSZ37YEOa5PyccbgUNutiQdi13TA==
dependencies:
"@types/node" "*"
"@types/glob@^7.1.1":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
@@ -1590,6 +1595,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.2.tgz#9565ed5c72ba96038fc3add643edd5e7820598e7"
integrity sha512-SRH6QM0IMOBBFmDiJ75vlhcbUEYEquvSuhsVW9ijG20JvdFTfOrB1p6ddZxz5y/JNnbf+9HoHhjhOVSX2hsJyA==
"@types/node@^14.14.35":
version "14.14.35"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313"
integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==
"@types/node@^8.0.47":
version "8.10.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.60.tgz#73eb4d1e1c8aa5dc724363b57db019cf28863ef7"
@@ -4101,15 +4111,6 @@ fs-constants@^1.0.0:
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-extra@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.0.tgz#414fb4ca2d2170ba0014159d3a8aec3303418d9e"
integrity sha1-QU+0yi0hcLoAFBWdOorsMwNBjZ4=
dependencies:
graceful-fs "^4.1.2"
jsonfile "^3.0.0"
universalify "^0.1.0"
fs-extra@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"
@@ -4138,6 +4139,16 @@ fs-extra@^9.0.0:
jsonfile "^6.0.1"
universalify "^1.0.0"
fs-extra@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
dependencies:
at-least-node "^1.0.0"
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
fs-minipass@^1.2.5:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
@@ -5662,13 +5673,6 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
jsonfile@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@@ -9326,6 +9330,11 @@ universalify@^1.0.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"