Skip to content

Commit

Permalink
chore: simplify package scripts (#3736)
Browse files Browse the repository at this point in the history
# Simplify package scripts

This PR's purpose is to raise a discussion surrounding our current
package scripts.

It includes some suggestions that aim to simplify the scripts and
hopefully bring a much more straightforward approach to developing and
contributing to Unleash.

Building (prod) should only happen **explicitly** and when needed.

## Before PR (current behavior)

- Clone the project;
- Open 2 terminals: One for `unleash` and another for
`unleash/frontend`;
- On `unleash`: 
  - Run `yarn` (which will also build, for some reason?);
  - Run `yarn start:dev` to start backend in dev mode (`tsc-watch`);
- On `unleash/frontend`:
  - Run `yarn` (which will also build, for some reason?);
  - Run `yarn start` to start frontend in dev mode (`vite`);

So it seems to me like we build unnecessarily every time we install
dependencies. Neither dev scripts need to build the project, as backend
uses `tsc-watch` and frontend uses `vite`. I'm unsure why this is the
case, as building can take a very long time.


![image](https://github.com/Unleash/unleash/assets/14320932/5ecb7df1-e5b4-4d70-ba7e-97119f5d1116)

There's also some complexity in the way we need to split the terminal to
`cd` into `frontend` and treat it as a different project. The fact that
we have different script names is also confusing (`yarn start`, `yarn
start:dev`, etc).

## After PR

- Clone the project;
- Run `yarn` to install all dependencies;
- Run `yarn dev` to get started developing Unleash;

Running `yarn` should take care of everything needed to start
developing. This includes installing dependencies for frontend as well.
It should not build projects if we are not being explicit about it,
especially since we don't need to build them at this stage.


![image](https://github.com/Unleash/unleash/assets/14320932/614e42fc-3467-432f-91fc-624b1b35c7c1)

Running `yarn dev` should start the project in dev mode. This means
running both projects in `dev` mode, which for `backend` means running
`tsc-watch` and for `frontend` means running `vite`.

Here this PR attempts to provide a better DX by using
[concurrently](https://www.npmjs.com/package/concurrently) and
[wait-on](https://www.npmjs.com/package/wait-on) - This means both tasks
are ran simultaneously, stdout is labeled accordingly, and are stopped
together. It also means that `frontend` waits for `backend` to be
serving at `4242` before starting, since `frontend` starts pretty much
immediately with `vite` and `backend` takes a bit longer. Of course,
when the `backend` is hot-reloading you may still find some
`ECONNREFUSED`s on `frontend` stdout while it recompiles.


![image](https://github.com/Unleash/unleash/assets/14320932/8bde8ee2-3cad-4e3f-a0db-9eed60cfb04d)

No more splitting your terminal and treating `frontend` as a separate
project.

## Discussion points

Maybe there's a better alternative to `tsc-watch`? I briefly explored
some alternatives and while they had a much faster starting speed,
hot-reload was sometimes slower. IMO we should aspire to run
`src/server-dev.ts` directly and only compile when needed.

Running `dev:backend` still serves a version of the frontend (at 4242).
**Why? Can we remove that behavior?**
I can't imagine a scenario in dev where we wouldn't want to run the
latest version of the frontend with `vite`.

~~**Note:** This PR removes all other out-of-scope scripts to focus on
this revamp. If we decide to merge it, we should evaluate what other
existing scripts we still want to include. May be a good opportunity to
clean up unused ones and only include the ones we really use. This
includes scripts that our GH actions rely on.~~

**Update:** In an effort to minimize impact surface of this PR and make
it a bit more ready for merging:
- It updates some docs in
2a4ff80
and
1bbc488
to reflect our new simplified flow;
- It includes the old package scripts for now in
039bc04;
- It updates some of our GH actions to reflect the new scripts in
7782cb9;

Given its current status I'll promote the PR to "ready for review". 

I still think we should have a second look at our existing scripts and
GH actions to see what we really need and/or should adapt, but it should
be a team effort so we have a broader context. Maybe on a follow-up PR.

Does this require any changes to related projects (e.g. Enterprise)?

---------

Co-authored-by: Gastón Fournier <gaston@getunleash.io>
  • Loading branch information
nunogois and gastonfournier committed May 12, 2023
1 parent b42b18f commit a9c24e4
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_prs.yaml
Expand Up @@ -19,5 +19,5 @@ jobs:
cache: 'yarn'
- run: yarn install --frozen-lockfile --ignore-scripts
- run: yarn lint
- run: yarn build
- run: yarn build:backend
#- run: yarn build:frontend # not needed
4 changes: 2 additions & 2 deletions .github/workflows/gradual-strict-null-checks.yml
Expand Up @@ -50,9 +50,9 @@ jobs:
YARN_1="yarn --mutex network --cwd ./current"
YARN_2="yarn --mutex network --cwd ./main"
$YARN_1 install --ignore-scripts &> /dev/null && $YARN_1 build --strictNullChecks true 2> .stderr-current > .out-current &
$YARN_1 install --ignore-scripts &> /dev/null && $YARN_1 build:backend --strictNullChecks true 2> .stderr-current > .out-current &
pid1=$!
$YARN_2 install --ignore-scripts &> /dev/null && $YARN_2 build --strictNullChecks true 2> .stderr-main > .out-main &
$YARN_2 install --ignore-scripts &> /dev/null && $YARN_2 build:backend --strictNullChecks true 2> .stderr-main > .out-main &
pid2=$!
# wait for the processes that are expected to fail
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Expand Up @@ -102,13 +102,13 @@ You'll need:
docker start postgres
```

4. **Start the server.** Run the below command and the server will start up and try to connect to the database. On a successful connection it will also configure the database for Unleash.
4. **Start Unleash.** Run the below command and Unleash will start up and try to connect to the database. On a successful connection it will also configure the database.

```bash
yarn start:dev
yarn dev
```

5. **Log into the admin UI**. Use a browser and navigate to `localhost:4242`. Log in using:
5. **Log into the admin UI**. Use a browser and navigate to `localhost:3000`. Log in using:
- username: `admin`
- password: `unleash4all`

Expand Down
7 changes: 3 additions & 4 deletions frontend/README.md
Expand Up @@ -4,13 +4,12 @@ This directory contains the Unleash Admin UI frontend app.

## Run with a local instance of the unleash-api

First, start the unleash-api backend on port 4242.
Then, start the frontend dev server:
Refer to the [Contributing to Unleash](../CONTRIBUTING.md#how-to-run-the-project) guide for instructions.
The frontend dev server runs (in port 3000) simultaneously with the backend dev server (in port 4242):

```
cd ./frontend
yarn install
yarn run start
yarn dev
```

## Run with a sandbox instance of the Unleash API
Expand Down
4 changes: 2 additions & 2 deletions frontend/package.json
Expand Up @@ -11,6 +11,7 @@
},
"scripts": {
"build": "vite build",
"dev": "vite",
"start": "vite",
"start:prod": "vite build && vite preview",
"start:sandbox": "UNLEASH_API=https://sandbox.getunleash.io/ospro yarn run start",
Expand All @@ -29,8 +30,7 @@
"e2e:heroku": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" yarn run cypress open --config baseUrl='https://unleash.herokuapp.com' --env AUTH_USER=admin,AUTH_PASSWORD=unleash4all",
"gen:api": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" orval --config orval.config.js",
"gen:api:demo": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" UNLEASH_OPENAPI_URL=https://app.unleash-hosted.com/demo/docs/openapi.json yarn run gen:api",
"gen:api:sandbox": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" UNLEASH_OPENAPI_URL=https://sandbox.getunleash.io/demo2/docs/openapi.json yarn run gen:api",
"prepare": "yarn run build"
"gen:api:sandbox": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" UNLEASH_OPENAPI_URL=https://sandbox.getunleash.io/demo2/docs/openapi.json yarn run gen:api"
},
"devDependencies": {
"@codemirror/lang-json": "6.0.1",
Expand Down
14 changes: 10 additions & 4 deletions package.json
Expand Up @@ -31,6 +31,13 @@
"main": "./dist/lib/server-impl.js",
"scripts": {
"start": "TZ=UTC node ./dist/server.js",
"build:backend": "copyfiles -u 1 src/mailtemplates/**/*.mustache dist/ && tsc --pretty --strictNullChecks false",
"build:frontend": "yarn --cwd ./frontend run build",
"build": "yarn run build:frontend && yarn run build:backend",
"dev:backend": "TZ=UTC NODE_ENV=development tsc-watch --strictNullChecks false --onSuccess \"node dist/server-dev.js\"",
"dev:frontend": "wait-on tcp:4242 && yarn --cwd ./frontend run dev",
"dev": "concurrently \"yarn:dev:backend\" \"yarn:dev:frontend\"",
"prepare": "node scripts/husky-install && yarn --cwd ./frontend install",
"prestart:dev": "yarn run clean",
"start:dev": "TZ=UTC NODE_ENV=development tsc-watch --strictNullChecks false --onSuccess \"node dist/server-dev.js\"",
"copy-templates": "copyfiles -u 1 src/mailtemplates/**/*.mustache dist/",
Expand All @@ -40,9 +47,6 @@
"prebuild:watch": "yarn run clean",
"build:watch": "tsc -w --strictNullChecks false",
"prebuild": "yarn run clean",
"build": "yarn run copy-templates && tsc --pretty --strictNullChecks false",
"build:frontend": "yarn --cwd ./frontend",
"prepare": "node scripts/husky-install && yarn run build",
"test": "NODE_ENV=test PORT=4243 jest",
"test:unit": "NODE_ENV=test PORT=4243 jest --testPathIgnorePatterns=src/test/e2e --testPathIgnorePatterns=dist",
"test:docker": "./scripts/docker-postgres.sh",
Expand Down Expand Up @@ -172,6 +176,7 @@
"@types/uuid": "9.0.1",
"@typescript-eslint/eslint-plugin": "5.59.2",
"@typescript-eslint/parser": "5.59.2",
"concurrently": "^8.0.1",
"copyfiles": "2.4.1",
"coveralls": "3.1.1",
"del-cli": "5.0.0",
Expand All @@ -198,7 +203,8 @@
"supertest": "6.3.3",
"ts-node": "10.9.1",
"tsc-watch": "6.0.4",
"typescript": "4.8.4"
"typescript": "4.8.4",
"wait-on": "^7.0.1"
},
"resolutions": {
"async": "^3.2.4",
Expand Down
10 changes: 5 additions & 5 deletions website/docs/contributing/backend/overview.md
Expand Up @@ -20,7 +20,7 @@ Before developing on this project you will need two things:

```sh
yarn install
yarn run start:dev
yarn dev
```

## PostgreSQL {#postgresql}
Expand Down Expand Up @@ -65,14 +65,14 @@ In order to start the application you will need Node.js v14.x or newer installed
// Install dependencies
yarn install
// Start server in development
yarn start:dev
// Start Unleash in development
yarn dev
// Unleash UI
http://localhost:4242
http://localhost:3000
// API:
http://localhost:4242/api/
http://localhost:3000/api/
// Execute tests in all packages:
yarn test
Expand Down
93 changes: 89 additions & 4 deletions yarn.lock
Expand Up @@ -976,7 +976,7 @@
dependencies:
"@hapi/hoek" "^9.0.0"

"@sideway/formula@^3.0.0":
"@sideway/formula@^3.0.0", "@sideway/formula@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f"
integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==
Expand Down Expand Up @@ -1798,6 +1798,14 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==

axios@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
dependencies:
follow-redirects "^1.14.9"
form-data "^4.0.0"

babel-jest@^29.5.0:
version "29.5.0"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5"
Expand Down Expand Up @@ -2076,7 +2084,7 @@ chalk@^2.0.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"

chalk@^4.0.0:
chalk@^4.0.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
Expand Down Expand Up @@ -2288,6 +2296,21 @@ concat-stream@^1.5.2:
readable-stream "^2.2.2"
typedarray "^0.0.6"

concurrently@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.0.1.tgz#80c0591920a9fa3e68ba0dd8aa6eac8487eb904c"
integrity sha512-Sh8bGQMEL0TAmAm2meAXMjcASHZa7V0xXQVDBLknCPa9TPtkY9yYs+0cnGGgfdkW0SV1Mlg+hVGfXcoI8d3MJA==
dependencies:
chalk "^4.1.2"
date-fns "^2.29.3"
lodash "^4.17.21"
rxjs "^7.8.0"
shell-quote "^1.8.0"
spawn-command "0.0.2-1"
supports-color "^8.1.1"
tree-kill "^1.2.2"
yargs "^17.7.1"

confusing-browser-globals@^1.0.10:
version "1.0.11"
resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81"
Expand Down Expand Up @@ -2470,6 +2493,13 @@ date-fns@^2.25.0:
dependencies:
"@babel/runtime" "^7.21.0"

date-fns@^2.29.3:
version "2.30.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
dependencies:
"@babel/runtime" "^7.21.0"

date-format@^4.0.14:
version "4.0.14"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400"
Expand Down Expand Up @@ -3400,6 +3430,11 @@ flatted@^3.1.0, flatted@^3.2.7:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==

follow-redirects@^1.14.9:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==

for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
Expand Down Expand Up @@ -4650,6 +4685,17 @@ joi@^17.3.0:
"@sideway/formula" "^3.0.0"
"@sideway/pinpoint" "^2.0.0"

joi@^17.7.0:
version "17.9.2"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690"
integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo" "^5.0.0"
"@sideway/address" "^4.1.3"
"@sideway/formula" "^3.0.1"
"@sideway/pinpoint" "^2.0.0"

js-sdsl@^4.1.4:
version "4.4.0"
resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430"
Expand Down Expand Up @@ -5217,7 +5263,7 @@ minimist-options@4.1.0:
is-plain-obj "^1.1.0"
kind-of "^6.0.3"

minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
Expand Down Expand Up @@ -6422,6 +6468,11 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==

shell-quote@^1.8.0:
version "1.8.1"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680"
integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==

side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
Expand Down Expand Up @@ -6520,6 +6571,11 @@ source-map@^0.6.0, source-map@^0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==

spawn-command@0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==

spdx-correct@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
Expand Down Expand Up @@ -6817,7 +6873,7 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"

supports-color@^8.0.0:
supports-color@^8.0.0, supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
Expand Down Expand Up @@ -6942,6 +6998,11 @@ tr46@^1.0.1:
dependencies:
punycode "^2.1.0"

tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==

trim-newlines@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.0.2.tgz#d6aaaf6a0df1b4b536d183879a6b939489808c7c"
Expand Down Expand Up @@ -7257,6 +7318,17 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"

wait-on@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.0.1.tgz#5cff9f8427e94f4deacbc2762e6b0a489b19eae9"
integrity sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==
dependencies:
axios "^0.27.2"
joi "^17.7.0"
lodash "^4.17.21"
minimist "^1.2.7"
rxjs "^7.8.0"

walker@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
Expand Down Expand Up @@ -7445,6 +7517,19 @@ yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.1.1"

yargs@^17.7.1:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"

yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
Expand Down

0 comments on commit a9c24e4

Please sign in to comment.