Compare commits
90 Commits
@verdaccio
...
@verdaccio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c2f5741f4 | ||
|
|
85413ae8b6 | ||
|
|
cbff8e4e31 | ||
|
|
e24eb59237 | ||
|
|
8297e2b36e | ||
|
|
020ede43f6 | ||
|
|
dd177d7166 | ||
|
|
5e53e168d4 | ||
|
|
e9ff724b68 | ||
|
|
5a61cdd0cf | ||
|
|
b849128ded | ||
|
|
efa2efe531 | ||
|
|
62ef397df1 | ||
|
|
e8fd4daf78 | ||
|
|
acc5862323 | ||
|
|
43c164efe0 | ||
|
|
cd02e8d56a | ||
|
|
5b270bdd06 | ||
|
|
e06d8a0956 | ||
|
|
44b7a0f300 | ||
|
|
351aeeaa88 | ||
|
|
3089c1c9cb | ||
|
|
d202128a06 | ||
|
|
3c81bf8945 | ||
|
|
20d63dc30e | ||
|
|
5e22a52d9d | ||
|
|
f332927f02 | ||
|
|
4137a96c20 | ||
|
|
37274e4c8d | ||
|
|
f1527f5f20 | ||
|
|
a32a7e617e | ||
|
|
08c36e688e | ||
|
|
ba3d100b63 | ||
|
|
37da9e0f61 | ||
|
|
e630954923 | ||
|
|
4b61029718 | ||
|
|
13398c6ab8 | ||
|
|
16f847fd7d | ||
|
|
225b5235a9 | ||
|
|
1b5bcfeac6 | ||
|
|
eaebffaf9e | ||
|
|
dc4fa8e20d | ||
|
|
99b947a2a5 | ||
|
|
83c4705821 | ||
|
|
3f5a1ee22a | ||
|
|
bf0f331dfc | ||
|
|
89b2b9104f | ||
|
|
21478f3221 | ||
|
|
12a05875c7 | ||
|
|
24c5d7ede5 | ||
|
|
b179541e66 | ||
|
|
353c9f386f | ||
|
|
f42db638eb | ||
|
|
a3a209b5e2 | ||
|
|
9bff9045f8 | ||
|
|
df7600d08a | ||
|
|
a136cefd49 | ||
|
|
93102eacc5 | ||
|
|
7d05f03525 | ||
|
|
04cc86374d | ||
|
|
bbf897d05a | ||
|
|
e21ccea3a1 | ||
|
|
5cf041a1a5 | ||
|
|
57908e24ba | ||
|
|
00d1d2a179 | ||
|
|
8db9cf93ce | ||
|
|
a6c88932a2 | ||
|
|
399343c6f9 | ||
|
|
6f8a2d37e6 | ||
|
|
0773e2ee2e | ||
|
|
a4c17858bf | ||
|
|
313c71c938 | ||
|
|
8342abde70 | ||
|
|
1755840cd3 | ||
|
|
a123775f20 | ||
|
|
292c0a37fc | ||
|
|
743ccff5ef | ||
|
|
4afb06347a | ||
|
|
bfe996735a | ||
|
|
1c7eb368ee | ||
|
|
09125ff004 | ||
|
|
43dd445200 | ||
|
|
63f8a8aa2e | ||
|
|
fcbc4bb781 | ||
|
|
d964353cb8 | ||
|
|
c5a6ff89bb | ||
|
|
d7dec2695f | ||
|
|
9beb77a44e | ||
|
|
cfcdbf6282 | ||
|
|
f75ddf8231 |
52
.changeset/angry-nails-appear.md
Normal file
52
.changeset/angry-nails-appear.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
'@verdaccio/api': major
|
||||
'@verdaccio/auth': major
|
||||
'@verdaccio/cli': major
|
||||
'@verdaccio/config': major
|
||||
'@verdaccio/core': major
|
||||
'@verdaccio/file-locking': major
|
||||
'@verdaccio/readme': major
|
||||
'@verdaccio/tarball': major
|
||||
'@verdaccio/types': major
|
||||
'@verdaccio/url': major
|
||||
'@verdaccio/hooks': major
|
||||
'@verdaccio/loaders': major
|
||||
'@verdaccio/logger': major
|
||||
'@verdaccio/logger-prettify': major
|
||||
'@verdaccio/middleware': major
|
||||
'@verdaccio/node-api': major
|
||||
'verdaccio-audit': major
|
||||
'verdaccio-auth-memory': major
|
||||
'verdaccio-htpasswd': major
|
||||
'@verdaccio/local-storage': major
|
||||
'verdaccio-memory': major
|
||||
'@verdaccio/ui-theme': major
|
||||
'@verdaccio/proxy': major
|
||||
'@verdaccio/server': major
|
||||
'@verdaccio/store': major
|
||||
'@verdaccio/utils': major
|
||||
'verdaccio': major
|
||||
'@verdaccio/web': major
|
||||
---
|
||||
|
||||
feat!: replace deprecated request dependency by got
|
||||
|
||||
This is a big refactoring of the core, fetching dependencies, improve code, more tests and better stability. This is essential for the next release, will take some time but would allow modularize more the core.
|
||||
|
||||
## Notes
|
||||
|
||||
- Remove deprecated `request` by other `got`, retry improved, custom Agent ( got does not include it built-in)
|
||||
- Remove `async` dependency from storage (used by core) it was linked with proxy somehow safe to remove now
|
||||
- Refactor with promises instead callback wherever is possible
|
||||
- ~Document the API~
|
||||
- Improve testing, integration tests
|
||||
- Bugfix
|
||||
- Clean up old validations
|
||||
- Improve performance
|
||||
|
||||
## 💥 Breaking changes
|
||||
|
||||
- Plugin API methods were callbacks based are returning promises, this will break current storage plugins, check documentation for upgrade.
|
||||
- Write Tarball, Read Tarball methods parameters change, a new set of options like `AbortController` signals are being provided to the `addAbortSignal` can be internally used with Streams when a request is aborted. eg: `addAbortSignal(signal, fs.createReadStream(pathName));`
|
||||
- `@verdaccio/streams` stream abort support is legacy is being deprecated removed
|
||||
- Remove AWS and Google Cloud packages for future refactoring [#2574](https://github.com/verdaccio/verdaccio/pull/2574).
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
'@verdaccio/api': major
|
||||
'@verdaccio/fastify-migration': major
|
||||
'@verdaccio/server-fastify': major
|
||||
'@verdaccio/tarball': major
|
||||
'@verdaccio/local-storage': major
|
||||
'verdaccio-memory': major
|
||||
|
||||
11
.changeset/clever-pugs-warn.md
Normal file
11
.changeset/clever-pugs-warn.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
'@verdaccio/cli': major
|
||||
'@verdaccio/core': major
|
||||
'@verdaccio/types': major
|
||||
'@verdaccio/logger': major
|
||||
'@verdaccio/logger-prettify': major
|
||||
'verdaccio-audit': major
|
||||
'@verdaccio/eslint-config': major
|
||||
---
|
||||
|
||||
feat: migrate to pino.js 8
|
||||
@@ -2,7 +2,9 @@
|
||||
"$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json",
|
||||
"changelog": "@changesets/cli/changelog",
|
||||
"commit": false,
|
||||
"linked": [],
|
||||
"fixed": [
|
||||
["verdaccio", "@verdaccio/cli", "@verdaccio/core", "@verdaccio/config", "@verdaccio/node-api"]
|
||||
],
|
||||
"access": "public",
|
||||
"baseBranch": "master",
|
||||
"updateInternalDependencies": "patch",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'@verdaccio/commons-api': major
|
||||
'@verdaccio/core': major
|
||||
'@verdaccio/local-storage': major
|
||||
'@verdaccio/fastify-migration': major
|
||||
'@verdaccio/server-fastify': major
|
||||
'@verdaccio/streams': major
|
||||
'@verdaccio/types': major
|
||||
'@verdaccio/hooks': major
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'@verdaccio/file-locking': major
|
||||
'verdaccio-htpasswd': major
|
||||
'@verdaccio/readme': major
|
||||
'@verdaccio/fastify-migration': major
|
||||
'@verdaccio/server-fastify': major
|
||||
'@verdaccio/streams': major
|
||||
'@verdaccio/tarball': major
|
||||
'@verdaccio/types': major
|
||||
@@ -16,7 +16,6 @@
|
||||
'@verdaccio/loaders': major
|
||||
'@verdaccio/logger': major
|
||||
'@verdaccio/middleware': major
|
||||
'@verdaccio/mock': major
|
||||
'@verdaccio/node-api': major
|
||||
'@verdaccio/active-directory': major
|
||||
'verdaccio-audit': major
|
||||
|
||||
42
.changeset/famous-tigers-doubt.md
Normal file
42
.changeset/famous-tigers-doubt.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
'@verdaccio/api': patch
|
||||
'@verdaccio/auth': patch
|
||||
'@verdaccio/cli': patch
|
||||
'@verdaccio/core': patch
|
||||
'@verdaccio/file-locking': patch
|
||||
'@verdaccio/readme': patch
|
||||
'@verdaccio/tarball': patch
|
||||
'@verdaccio/types': patch
|
||||
'@verdaccio/url': patch
|
||||
'@verdaccio/hooks': patch
|
||||
'@verdaccio/loaders': patch
|
||||
'@verdaccio/logger': patch
|
||||
'@verdaccio/node-api': patch
|
||||
'verdaccio-audit': patch
|
||||
'verdaccio-auth-memory': patch
|
||||
'verdaccio-htpasswd': patch
|
||||
'@verdaccio/local-storage': patch
|
||||
'verdaccio-memory': patch
|
||||
'@verdaccio/ui-theme': patch
|
||||
'@verdaccio/proxy': patch
|
||||
'@verdaccio/server': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/cli-standalone': patch
|
||||
'@verdaccio/store': patch
|
||||
'docusaurus-plugin-contributors': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'verdaccio': patch
|
||||
'@verdaccio/web': patch
|
||||
'@verdaccio/test-cli-commons': patch
|
||||
'@verdaccio/e2e-cli-npm6': patch
|
||||
'@verdaccio/e2e-cli-npm7': patch
|
||||
'@verdaccio/e2e-cli-npm8': patch
|
||||
'@verdaccio/e2e-cli-pnpm6': patch
|
||||
'@verdaccio/e2e-cli-pnpm7': patch
|
||||
'@verdaccio/e2e-cli-yarn1': patch
|
||||
'@verdaccio/e2e-cli-yarn2': patch
|
||||
'@verdaccio/e2e-cli-yarn3': patch
|
||||
'@verdaccio/e2e-cli-yarn4': patch
|
||||
---
|
||||
|
||||
fix(deps): @verdaccio/utils should be a prod dep of local-storage
|
||||
@@ -15,7 +15,6 @@
|
||||
'@verdaccio/logger': major
|
||||
'@verdaccio/logger-prettify': major
|
||||
'@verdaccio/middleware': major
|
||||
'@verdaccio/mock': major
|
||||
'@verdaccio/node-api': major
|
||||
'@verdaccio/active-directory': major
|
||||
'verdaccio-audit': major
|
||||
@@ -30,7 +29,6 @@
|
||||
'@verdaccio/utils': major
|
||||
'verdaccio': major
|
||||
'@verdaccio/web': major
|
||||
'@verdaccio/website': major
|
||||
---
|
||||
|
||||
feat!: experiments config renamed to flags
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
'@verdaccio/api': minor
|
||||
'@verdaccio/fastify-migration': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
'@verdaccio/hooks': minor
|
||||
'@verdaccio/logger-prettify': minor
|
||||
'@verdaccio/proxy': minor
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
'@verdaccio/logger': major
|
||||
'@verdaccio/logger-prettify': major
|
||||
'@verdaccio/middleware': major
|
||||
'@verdaccio/mock': major
|
||||
'@verdaccio/node-api': major
|
||||
'@verdaccio/proxy': major
|
||||
'@verdaccio/server': major
|
||||
|
||||
29
.changeset/green-yaks-divide.md
Normal file
29
.changeset/green-yaks-divide.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
'@verdaccio/api': minor
|
||||
'@verdaccio/cli': minor
|
||||
'@verdaccio/core': minor
|
||||
'@verdaccio/node-api': minor
|
||||
'@verdaccio/server': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
'verdaccio': minor
|
||||
---
|
||||
|
||||
chore: env variable for launch fastify
|
||||
|
||||
- Update fastify to major release `v4.3.0`
|
||||
- Update CLI launcher
|
||||
|
||||
via CLI
|
||||
|
||||
```
|
||||
VERDACCIO_SERVER=fastify verdaccio
|
||||
```
|
||||
|
||||
with docker
|
||||
|
||||
```
|
||||
docker run -it --rm --name verdaccio \
|
||||
-e "VERDACCIO_SERVER=8080" -p 8080:8080 \
|
||||
-e "VERDACCIO_SERVER=fastify" \
|
||||
verdaccio/verdaccio
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
'@verdaccio/cli': minor
|
||||
'@verdaccio/fastify-migration': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
---
|
||||
|
||||
[Fastify] Add ping endpoint
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
'@verdaccio/logger': patch
|
||||
'@verdaccio/logger-prettify': patch
|
||||
'@verdaccio/middleware': patch
|
||||
'@verdaccio/mock': patch
|
||||
'@verdaccio/node-api': patch
|
||||
'@verdaccio/active-directory': patch
|
||||
'verdaccio-audit': patch
|
||||
@@ -31,9 +30,6 @@
|
||||
'@verdaccio/utils': patch
|
||||
'verdaccio': patch
|
||||
'@verdaccio/web': patch
|
||||
'@verdaccio/e2e-cli': patch
|
||||
'@verdaccio/e2e-ui': patch
|
||||
'@verdaccio/website': patch
|
||||
---
|
||||
|
||||
chore: add release step to private regisry on merge changeset pr
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
'@verdaccio/tarball': patch
|
||||
'@verdaccio/mock': patch
|
||||
'@verdaccio/ui-theme': patch
|
||||
'@verdaccio/server': patch
|
||||
'@verdaccio/utils': patch
|
||||
|
||||
5
.changeset/moody-clocks-roll.md
Normal file
5
.changeset/moody-clocks-roll.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/cli': patch
|
||||
---
|
||||
|
||||
fix: version with breakline
|
||||
@@ -15,7 +15,6 @@
|
||||
'@verdaccio/logger': minor
|
||||
'@verdaccio/logger-prettify': minor
|
||||
'@verdaccio/middleware': minor
|
||||
'@verdaccio/mock': minor
|
||||
'@verdaccio/node-api': minor
|
||||
'@verdaccio/active-directory': minor
|
||||
'verdaccio-audit': minor
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'@verdaccio/core': minor
|
||||
'verdaccio-htpasswd': minor
|
||||
'@verdaccio/local-storage': minor
|
||||
'@verdaccio/fastify-migration': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
'@verdaccio/tarball': minor
|
||||
'@verdaccio/types': minor
|
||||
'@verdaccio/url': minor
|
||||
@@ -14,7 +14,6 @@
|
||||
'@verdaccio/loaders': minor
|
||||
'@verdaccio/logger': minor
|
||||
'@verdaccio/middleware': minor
|
||||
'@verdaccio/mock': minor
|
||||
'@verdaccio/node-api': minor
|
||||
'@verdaccio/active-directory': minor
|
||||
'verdaccio-auth-memory': minor
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
'@verdaccio/logger': minor
|
||||
'@verdaccio/logger-prettify': minor
|
||||
'@verdaccio/middleware': minor
|
||||
'@verdaccio/mock': minor
|
||||
'@verdaccio/node-api': minor
|
||||
'@verdaccio/proxy': minor
|
||||
'@verdaccio/server': minor
|
||||
@@ -24,7 +23,6 @@
|
||||
'@verdaccio/utils': minor
|
||||
'verdaccio': minor
|
||||
'@verdaccio/web': minor
|
||||
'@verdaccio/website': minor
|
||||
---
|
||||
|
||||
feat: add typescript project references settings
|
||||
|
||||
@@ -10,14 +10,12 @@
|
||||
"verdaccio-htpasswd": "11.0.0-alpha.0",
|
||||
"@verdaccio/local-storage": "11.0.0-alpha.0",
|
||||
"@verdaccio/readme": "11.0.0-alpha.0",
|
||||
"@verdaccio/streams": "11.0.0-alpha.0",
|
||||
"@verdaccio/types": "11.0.0-alpha.0",
|
||||
"@verdaccio/hooks": "6.0.0-alpha.0",
|
||||
"@verdaccio/loaders": "6.0.0-alpha.0",
|
||||
"@verdaccio/logger": "6.0.0-alpha.0",
|
||||
"@verdaccio/logger-prettify": "6.0.0-alpha.0",
|
||||
"@verdaccio/middleware": "6.0.0-alpha.0",
|
||||
"@verdaccio/mock": "6.0.0-alpha.0",
|
||||
"@verdaccio/node-api": "6.0.0-alpha.0",
|
||||
"@verdaccio/proxy": "6.0.0-alpha.0",
|
||||
"@verdaccio/server": "6.0.0-alpha.0",
|
||||
@@ -33,32 +31,44 @@
|
||||
"verdaccio-google-cloud": "11.0.0-alpha.0",
|
||||
"verdaccio-memory": "11.0.0-alpha.0",
|
||||
"@verdaccio/ui-theme": "6.0.0-alpha.1",
|
||||
"@verdaccio/e2e-cli": "1.0.0",
|
||||
"@verdaccio/e2e-ui": "1.0.0",
|
||||
"@verdaccio/cli-standalone": "6.0.0-alpha.3",
|
||||
"@verdaccio/tarball": "11.0.0-alpha.3",
|
||||
"@verdaccio/url": "11.0.0-alpha.3",
|
||||
"@verdaccio/fastify-migration": "6.0.0-6-next.9",
|
||||
"@verdaccio/server-fastify": "6.0.0-6-next.9",
|
||||
"@verdaccio/eslint-config": "1.0.0",
|
||||
"@verdaccio/benchmark": "1.0.0",
|
||||
"@verdaccio/core": "6.0.0-next.0",
|
||||
"@verdaccio/test-helper": "1.0.0",
|
||||
"docusaurus-plugin-contributors": "1.0.0",
|
||||
"@verdaccio/website": "5.4.0"
|
||||
"@verdaccio/website": "5.4.0",
|
||||
"@verdaccio/test-cli-commons": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-npm6": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-npm7": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-npm8": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-pnpm6": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-pnpm7": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-yarn1": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-yarn2": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-yarn3": "1.0.1-6-next.1",
|
||||
"@verdaccio/e2e-cli-yarn4": "1.0.1-6-next.1",
|
||||
"@verdaccio/local-publish": "0.0.1"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-mice-obey",
|
||||
"angry-nails-appear",
|
||||
"big-lobsters-sin",
|
||||
"bright-poems-obey",
|
||||
"brown-cycles-laugh",
|
||||
"brown-pandas-wink",
|
||||
"calm-pants-impress",
|
||||
"chilled-ways-fetch",
|
||||
"clever-pugs-warn",
|
||||
"dry-planes-tap",
|
||||
"dull-monkeys-search",
|
||||
"eleven-brooms-hunt",
|
||||
"eleven-spoons-matter",
|
||||
"fair-lemons-beam",
|
||||
"famous-tigers-doubt",
|
||||
"few-cooks-destroy",
|
||||
"few-mangos-grow",
|
||||
"fifty-jars-rest",
|
||||
@@ -67,6 +77,7 @@
|
||||
"gentle-parrots-lay",
|
||||
"gentle-trains-switch",
|
||||
"gold-vans-tease",
|
||||
"green-yaks-divide",
|
||||
"healthy-bikes-behave",
|
||||
"healthy-pants-smash",
|
||||
"healthy-poets-compare",
|
||||
@@ -81,6 +92,7 @@
|
||||
"lovely-drinks-argue",
|
||||
"many-vans-care",
|
||||
"modern-spies-tell",
|
||||
"moody-clocks-roll",
|
||||
"neat-toes-report",
|
||||
"neat-toys-float",
|
||||
"olive-candles-speak",
|
||||
@@ -103,9 +115,11 @@
|
||||
"slow-carrots-relate",
|
||||
"smart-apricots-kneel",
|
||||
"smart-beds-cross",
|
||||
"smooth-owls-pump",
|
||||
"sour-buses-shout",
|
||||
"spicy-frogs-press",
|
||||
"spicy-snakes-sip",
|
||||
"strange-ladybugs-nail",
|
||||
"swift-pumpkins-knock",
|
||||
"ten-parents-breathe",
|
||||
"tender-bags-call",
|
||||
@@ -114,7 +128,9 @@
|
||||
"three-moles-drop",
|
||||
"three-pots-sit",
|
||||
"tiny-seals-join",
|
||||
"tricky-taxis-watch",
|
||||
"two-dolls-check",
|
||||
"wild-jokes-beam"
|
||||
"wild-jokes-beam",
|
||||
"witty-ties-speak"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
---
|
||||
'verdaccio-htpasswd': patch
|
||||
'@verdaccio/local-storage': patch
|
||||
'@verdaccio/fastify-migration': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/hooks': patch
|
||||
'@verdaccio/mock': patch
|
||||
'@verdaccio/node-api': patch
|
||||
---
|
||||
|
||||
|
||||
@@ -14,11 +14,8 @@
|
||||
'@verdaccio/ui-theme': major
|
||||
'@verdaccio/proxy': major
|
||||
'@verdaccio/server': major
|
||||
'@verdaccio/mock': major
|
||||
'verdaccio': major
|
||||
'@verdaccio/web': major
|
||||
'@verdaccio/e2e-cli': major
|
||||
'@verdaccio/website': major
|
||||
---
|
||||
|
||||
feat!: config.logs throw an error, logging config not longer accept array or logs property
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
'@verdaccio/dev-types': major
|
||||
'@verdaccio/web': major
|
||||
'@verdaccio/e2e-ui': major
|
||||
'@verdaccio/website': major
|
||||
---
|
||||
|
||||
feat: upgrade to material ui 5
|
||||
|
||||
5
.changeset/smooth-owls-pump.md
Normal file
5
.changeset/smooth-owls-pump.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/ui-theme': patch
|
||||
---
|
||||
|
||||
ui: basic grammatical fixes in the Ukraine Message
|
||||
@@ -1,9 +1,8 @@
|
||||
---
|
||||
'@verdaccio/fastify-migration': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
'@verdaccio/store': minor
|
||||
'@verdaccio/utils': minor
|
||||
'@verdaccio/web': minor
|
||||
'@verdaccio/website': minor
|
||||
---
|
||||
|
||||
feat: migrate web sidebar endpoint to fastify
|
||||
|
||||
9
.changeset/strange-ladybugs-nail.md
Normal file
9
.changeset/strange-ladybugs-nail.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@verdaccio/types': minor
|
||||
---
|
||||
|
||||
feat: add dist.signatures to core/types
|
||||
|
||||
According to [`npm`](https://docs.npmjs.com/about-registry-signatures): _"Signatures are provided in the package's `packument` in each published version within the `dist` object"_
|
||||
|
||||
Here's an [example of a package version from the public npm registry with `dist.signatures`](https://registry.npmjs.org/light-cycle/1.4.3).
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
'@verdaccio/auth': minor
|
||||
'@verdaccio/fastify-migration': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
'@verdaccio/web': minor
|
||||
---
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
'@verdaccio/logger': patch
|
||||
'@verdaccio/logger-prettify': patch
|
||||
'@verdaccio/middleware': patch
|
||||
'@verdaccio/mock': patch
|
||||
'@verdaccio/node-api': patch
|
||||
'@verdaccio/proxy': patch
|
||||
'@verdaccio/server': patch
|
||||
|
||||
28
.changeset/tricky-taxis-watch.md
Normal file
28
.changeset/tricky-taxis-watch.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
'@verdaccio/api': minor
|
||||
'@verdaccio/types': minor
|
||||
'@verdaccio/local-storage': minor
|
||||
'@verdaccio/server-fastify': minor
|
||||
'@verdaccio/store': minor
|
||||
'@verdaccio/test-helper': minor
|
||||
'@verdaccio/web': minor
|
||||
---
|
||||
|
||||
feat: implement abbreviated manifest
|
||||
|
||||
Enable abbreviated manifest data by adding the header:
|
||||
|
||||
```
|
||||
curl -H "Accept: application/vnd.npm.install-v1+json" https://registry.npmjs.org/verdaccio
|
||||
```
|
||||
|
||||
It returns a filtered manifest, additionally includes the [time](https://github.com/pnpm/rfcs/pull/2) field by request.
|
||||
|
||||
Current support for packages managers:
|
||||
|
||||
- npm: yes
|
||||
- pnpm: yes
|
||||
- yarn classic: yes
|
||||
- yarn modern (+2.x): [no](https://github.com/yarnpkg/berry/pull/3981#issuecomment-1076566096)
|
||||
|
||||
https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#abbreviated-metadata-format
|
||||
11
.changeset/witty-ties-speak.md
Normal file
11
.changeset/witty-ties-speak.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
'@verdaccio/api': patch
|
||||
'@verdaccio/cli': patch
|
||||
'@verdaccio/core': patch
|
||||
'@verdaccio/types': patch
|
||||
'@verdaccio/store': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'@verdaccio/local-publish': patch
|
||||
---
|
||||
|
||||
fix: handle upload scoped tarball
|
||||
@@ -12,3 +12,5 @@ dist/
|
||||
docs/
|
||||
test/functional/store/*
|
||||
docker-examples/**/lib/**/*.js
|
||||
test/cli/e2e-yarn4/bin/yarn-4.0.0-rc.14.cjs
|
||||
yarn.js
|
||||
|
||||
28
.github/workflows/benchmark.yml
vendored
28
.github/workflows/benchmark.yml
vendored
@@ -18,8 +18,8 @@ jobs:
|
||||
name: Prepare build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
- name: install pnpm
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: install dependencies
|
||||
run: pnpm install
|
||||
- name: Cache .pnpm-store
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
- name: tar packages
|
||||
run: |
|
||||
tar -czvf ${{ github.workspace }}/pkg.tar.gz -C ${{ github.workspace }}/packages .
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3
|
||||
with:
|
||||
name: verdaccio-artifact
|
||||
path: pkg.tar.gz
|
||||
@@ -65,11 +65,11 @@ jobs:
|
||||
name: Benchmark autocannon
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # tag=v3
|
||||
with:
|
||||
name: verdaccio-artifact
|
||||
- name: untar packages
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
- name: install pnpm
|
||||
# require fixed version
|
||||
run: sudo npm i pnpm@latest-6 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
DEBUG: metrics*
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3
|
||||
with:
|
||||
name: verdaccio-metrics-api
|
||||
path: ./api-results-${{matrix.verdaccioVersion}}-${{matrix.benchmark}}.json
|
||||
@@ -126,11 +126,11 @@ jobs:
|
||||
name: Benchmark hyperfine
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # tag=v3
|
||||
with:
|
||||
name: verdaccio-artifact
|
||||
- name: untar packages
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
- name: install pnpm
|
||||
# require fixed version
|
||||
run: sudo npm i pnpm@latest-6 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
shell: bash
|
||||
- name: rename
|
||||
run: mv ./hyper-results.json ./hyper-results-${{matrix.verdaccioVersion}}-${{matrix.benchmark}}.json
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3
|
||||
with:
|
||||
name: verdaccio-metrics
|
||||
path: ./hyper-results-${{matrix.verdaccioVersion}}-${{matrix.benchmark}}.json
|
||||
|
||||
10
.github/workflows/changesets.yml
vendored
10
.github/workflows/changesets.yml
vendored
@@ -20,12 +20,12 @@ jobs:
|
||||
if: github.ref == 'refs/heads/master' && github.repository == 'verdaccio/verdaccio'
|
||||
steps:
|
||||
- name: checkout code repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: setup node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 14
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
@@ -56,14 +56,16 @@ jobs:
|
||||
run: pnpm build
|
||||
|
||||
- name: create versions
|
||||
uses: verdaccio/changeset-action@master
|
||||
uses: changesets/action@master
|
||||
with:
|
||||
version: pnpm ci:version
|
||||
commit: 'chore: update versions'
|
||||
title: 'chore: update versions'
|
||||
publish: pnpm ci:publish
|
||||
createGithubReleases: false
|
||||
setupGitUser: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.CHANGESET_RELEASE_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.REGISTRY_AUTH_TOKEN }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.REGISTRY_AUTH_TOKEN }}
|
||||
NPM_CONFIG_REGISTRY: https://registry.npmjs.org
|
||||
|
||||
101
.github/workflows/ci.yml
vendored
101
.github/workflows/ci.yml
vendored
@@ -2,14 +2,12 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 'changeset-release/master'
|
||||
pull_request:
|
||||
paths:
|
||||
- .changeset/**
|
||||
- .github/workflows/ci.yml
|
||||
- 'packages/**'
|
||||
- 'test/**'
|
||||
- 'docker-examples/**'
|
||||
- 'jest/**'
|
||||
- 'package.json'
|
||||
@@ -27,9 +25,9 @@ jobs:
|
||||
ports:
|
||||
- 4873:4873
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
@@ -41,7 +39,7 @@ jobs:
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile --registry http://localhost:4873
|
||||
- name: Cache .pnpm-store
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -52,14 +50,14 @@ jobs:
|
||||
name: Lint
|
||||
needs: prepare
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -72,14 +70,14 @@ jobs:
|
||||
name: Format
|
||||
needs: prepare
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -93,19 +91,18 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
## Node 16 breaks UI test, jest issue
|
||||
node_version: [16, 17]
|
||||
node_version: [16, 18]
|
||||
name: ${{ matrix.os }} / Node ${{ matrix.node_version }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node ${{ matrix.node_version }}
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -120,13 +117,36 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: UI Test E2E Node 16
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: Test UI
|
||||
run: pnpm test:e2e:ui
|
||||
# env:
|
||||
# DEBUG: verdaccio:e2e*
|
||||
ci-e2e-cli:
|
||||
needs: [format, lint]
|
||||
runs-on: ubuntu-latest
|
||||
name: CLI Test E2E Node 16
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
@@ -135,50 +155,23 @@ jobs:
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: Test UI
|
||||
run: pnpm test:e2e:ui
|
||||
- name: Test CLI
|
||||
run: pnpm test:e2e:cli
|
||||
# env:
|
||||
# DEBUG: verdaccio:e2e*
|
||||
# FIXME verify why fails on Node 16 (locally works fine)
|
||||
# ci-e2e-cli:
|
||||
# needs: [format, lint]
|
||||
# runs-on: ubuntu-latest
|
||||
# # TODO: fails on migrate to node 16, we need to check why
|
||||
# name: CLI Test E2E Node 16
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: actions/setup-node@v3
|
||||
# with:
|
||||
# node-version: 16
|
||||
# - name: Install pnpm
|
||||
# run: npm i pnpm@latest -g
|
||||
# - uses: actions/cache@v3
|
||||
# with:
|
||||
# path: ~/.pnpm-store
|
||||
# key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
# - name: Install
|
||||
# ## we need scripts, pupetter downloads aditional content
|
||||
# run: pnpm recursive install --frozen-lockfile
|
||||
# - name: build
|
||||
# run: pnpm build
|
||||
# - name: Test CLI
|
||||
# run: pnpm test:e2e:cli
|
||||
# env:
|
||||
# DEBUG: verdaccio*
|
||||
# DEBUG: verdaccio*
|
||||
sync-translations:
|
||||
# needs: [ci-e2e-cli, ci-e2e-ui]
|
||||
needs: [ci-e2e-ui]
|
||||
needs: [ci-e2e-cli, ci-e2e-ui]
|
||||
runs-on: ubuntu-latest
|
||||
name: synchronize translations
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'workflow_dispatch'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@c7f292ea4f542c473194b33813ccd4c207a6c725 # tag=v2
|
||||
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@c7f292ea4f542c473194b33813ccd4c207a6c725 # tag=v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -56,4 +56,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@c7f292ea4f542c473194b33813ccd4c207a6c725 # tag=v2
|
||||
|
||||
6
.github/workflows/contributors.yml
vendored
6
.github/workflows/contributors.yml
vendored
@@ -15,11 +15,11 @@ jobs:
|
||||
name: Run script
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 17.x
|
||||
- name: install pnpm
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
- name: format
|
||||
run: pnpm format
|
||||
- name: Commit & Push changes
|
||||
uses: actions-js/push@v1.3
|
||||
uses: actions-js/push@a52398fac807b0c1e5f1492c969b477c8560a0ba # tag=v1.3
|
||||
with:
|
||||
github_token: ${{ secrets.TOKEN_VERDACCIOBOT_GITHUB }}
|
||||
message: "chore: updated contributors list"
|
||||
|
||||
4
.github/workflows/docker-publish.yml
vendored
4
.github/workflows/docker-publish.yml
vendored
@@ -19,8 +19,8 @@ jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: docker/setup-qemu-action@v1
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: docker/setup-qemu-action@27d0a4f181a40b142cce983c5393082c365d1480 # tag=v1
|
||||
- uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
29
.github/workflows/website.yml
vendored
29
.github/workflows/website.yml
vendored
@@ -3,13 +3,12 @@ name: Verdaccio Website CI
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'website/**'
|
||||
- './.github/workflows/website.yml'
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'website/**'
|
||||
- 'package.json'
|
||||
- './.github/workflows/website.yml'
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -17,15 +16,15 @@ jobs:
|
||||
env:
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
|
||||
- name: Use Node 16
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Cache pnpm modules
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
env:
|
||||
cache-name: cache-pnpm-modules
|
||||
with:
|
||||
@@ -34,7 +33,7 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-build-${{ env.cache-name }}-${{ matrix.node-version }}-
|
||||
|
||||
- uses: pnpm/action-setup@v2.2.2
|
||||
- uses: pnpm/action-setup@10693b3829bf86eb2572aef5f3571dcf5ca9287d # tag=v2.2.2
|
||||
with:
|
||||
version: 6.32.15
|
||||
run_install: |
|
||||
@@ -43,7 +42,7 @@ jobs:
|
||||
- name: Build Plugins
|
||||
run: pnpm build --filter "docusaurus-plugin-contributors"
|
||||
- name: Cache Docusaurus Build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: website/node_modules/.cache/webpack
|
||||
key: cache/webpack-${{github.ref}}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
@@ -62,7 +61,7 @@ jobs:
|
||||
|
||||
- name: 🔥 Deploy Production Netlify
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'workflow_dispatch'
|
||||
uses: semoal/action-netlify-deploy@master
|
||||
uses: semoal/action-netlify-deploy@1a53f098745bf78555d11b436f5ee3af87e6b566
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
@@ -77,7 +76,7 @@ jobs:
|
||||
|
||||
- name: 🤖 Deploy Preview Netlify
|
||||
if: github.repository == 'verdaccio/verdaccio'
|
||||
uses: semoal/action-netlify-deploy@master
|
||||
uses: semoal/action-netlify-deploy@1a53f098745bf78555d11b436f5ee3af87e6b566
|
||||
id: netlify_preview
|
||||
with:
|
||||
draft: true
|
||||
@@ -92,7 +91,7 @@ jobs:
|
||||
- name: Audit preview URL with Lighthouse
|
||||
if: github.repository == 'verdaccio/verdaccio'
|
||||
id: lighthouse_audit
|
||||
uses: treosh/lighthouse-ci-action@9.3.0
|
||||
uses: treosh/lighthouse-ci-action@b4dfae3eb959c5226e2c5c6afd563d493188bfaf # tag=9.3.0
|
||||
with:
|
||||
urls: |
|
||||
${{ steps.netlify_preview.outputs.preview-url }}
|
||||
@@ -101,7 +100,7 @@ jobs:
|
||||
|
||||
- name: Format lighthouse score
|
||||
id: format_lighthouse_score
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@c713e510dbd7d213d92d41b7a7805a986f4c5c66 # tag=v6
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
@@ -126,7 +125,7 @@ jobs:
|
||||
- name: Add comment to PR
|
||||
if: github.repository == 'verdaccio/verdaccio'
|
||||
id: comment_to_pr
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
uses: marocchino/sticky-pull-request-comment@39c5b5dc7717447d0cba270cd115037d32d28443 # tag=v2
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
number: ${{ github.event.issue.number }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -46,7 +46,8 @@ api-results.json
|
||||
hyper-results.json
|
||||
hyper-results*.json
|
||||
api-results*.json
|
||||
.clinic/
|
||||
|
||||
#docs
|
||||
./api
|
||||
packages/core/core/docs
|
||||
**/docs/**
|
||||
|
||||
@@ -31,3 +31,5 @@ api/**
|
||||
packages/core/local-storage/tests/__fixtures__/test-storage/
|
||||
packages/plugins/ui-theme/static/
|
||||
.verdaccio-db.json
|
||||
test/cli/e2e-yarn4/bin/yarn-4.0.0-rc.14.cjs
|
||||
yarn.js
|
||||
|
||||
78
.vscode/launch.json
vendored
78
.vscode/launch.json
vendored
@@ -4,88 +4,12 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Attach",
|
||||
"port": 9229,
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "pwa-node"
|
||||
},
|
||||
{
|
||||
"name": "Verdaccio Debug",
|
||||
"name": "Attach",
|
||||
"port": 9229,
|
||||
"request": "attach",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"type": "pwa-node"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "CLI Babel Registry",
|
||||
"stopOnEntry": false,
|
||||
"program": "${workspaceFolder}/debug/bootstrap.js",
|
||||
"args": ["-l", "0.0.0.0:4873"],
|
||||
"env": {
|
||||
"BABEL_ENV": "registry"
|
||||
},
|
||||
"preLaunchTask": "npm: build:webui",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Unit Tests",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/node_modules/bin/jest",
|
||||
"stopOnEntry": false,
|
||||
"args": ["--debug=true"],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"runtimeExecutable": null,
|
||||
"runtimeArgs": ["--nolazy"],
|
||||
"env": {
|
||||
"NODE_ENV": "test",
|
||||
"TZ": "UTC"
|
||||
},
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Functional Tests",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/node_modules/.bin/jest",
|
||||
"stopOnEntry": false,
|
||||
"args": [
|
||||
"--config",
|
||||
"./test/jest.config.functional.js",
|
||||
"--testPathPattern",
|
||||
"./test/functional/index*",
|
||||
"--debug=false",
|
||||
"--verbose",
|
||||
"--useStderr",
|
||||
"--detectOpenHandles"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {
|
||||
"BABEL_ENV": "testOldEnv",
|
||||
"VERDACCIO_DEBUG": "true",
|
||||
"VERDACCIO_DEBUG_INJECT": "true",
|
||||
"NODE_DEBUG": "TO_DEBUG_REQUEST_REMOVE_THIS_request"
|
||||
},
|
||||
"preLaunchTask": "pre-test",
|
||||
"console": "integratedTerminal",
|
||||
"runtimeExecutable": null,
|
||||
"runtimeArgs": ["--nolazy"]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Verdaccio Compiled",
|
||||
"preLaunchTask": "npm: code:build",
|
||||
"program": "${workspaceRoot}/bin/verdaccio",
|
||||
"args": ["-l", "0.0.0.0:4873"],
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
21
.vscode/tasks.json
vendored
21
.vscode/tasks.json
vendored
@@ -1,21 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build:webui",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "code:build",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "pre-test",
|
||||
"dependsOn": ["npm: code:build", "npm: test:clean"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -183,7 +183,7 @@ a report in our [issue tracker](https://github.com/verdaccio/verdaccio/issues).
|
||||
- _Features clearly flagged as not supported_
|
||||
- _Node.js issues installation in any platform_: If you cannot install the
|
||||
global package (this is considered external issue)
|
||||
- Any ticket which has beed flagged as an [external issue
|
||||
- Any ticket which has been flagged as an [external issue
|
||||
](https://github.com/verdaccio/verdaccio/labels/external-issue)
|
||||
|
||||
If you intend to report a **security** issue, please follow our [Security policy
|
||||
@@ -234,7 +234,7 @@ the project. Adding in context and the use-case will really help!
|
||||
|
||||
- A detailed description the advantages of your request
|
||||
- Whether or not it's compatible with `npm`, `pnpm` and [_yarn classic_
|
||||
](https://github.com/yarnpkg/yarn) or [_yarn berry_
|
||||
](https://github.com/yarnpkg/yarn) or [_yarn modern_
|
||||
](https://github.com/yarnpkg/berry).
|
||||
- A potential implementation or design
|
||||
- Whatever else is on your mind! 🤓
|
||||
@@ -278,7 +278,7 @@ clean git history.
|
||||
#### Before Commit
|
||||
|
||||
Before committing, **you must ensure there are no linting errors and
|
||||
all tests pass.** To do this, run these commands before create the PR:
|
||||
all tests pass.** To do this, run these commands before creating the PR:
|
||||
|
||||
```bash
|
||||
pnpm lint
|
||||
@@ -420,3 +420,25 @@ If you want to develop your own plugin:
|
||||
3. You are free to host your plugin in your repository
|
||||
4. Provide a detailed description of your plugin to help users understand how to
|
||||
use it
|
||||
|
||||
## Testing your changes in a local registry
|
||||
|
||||
Once you have perform your changes in the code base, the build and tests passes you can publish a local version:
|
||||
|
||||
- Ensure you have build all modules (or the one you have modified)
|
||||
- Run `pnpm local:publish:release` to launch a local registry and publish all packages into it. This command will be alive until server is killed (Control Key + C)
|
||||
|
||||
```
|
||||
pnpm build
|
||||
pnpm local:publish:release
|
||||
```
|
||||
|
||||
The last step consist on install globally the package from the local registry.
|
||||
|
||||
```
|
||||
npm i -g verdaccio --registry=http://localhost:4873
|
||||
|
||||
verdaccio
|
||||
```
|
||||
|
||||
If you perform more changes in the source code, repeat this process, there is not _hot reloading_ support.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} node:16.15.0-alpine as builder
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} node:16-alpine as builder
|
||||
|
||||
ENV NODE_ENV=development \
|
||||
VERDACCIO_BUILD_REGISTRY=https://registry.verdaccio.org
|
||||
|
||||
RUN apk --no-cache add openssl ca-certificates wget && \
|
||||
apk --no-cache add g++ gcc libgcc libstdc++ linux-headers make python2 && \
|
||||
apk --no-cache add g++ gcc libgcc libstdc++ linux-headers make python3 && \
|
||||
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
|
||||
wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.25-r0/glibc-2.25-r0.apk && \
|
||||
apk add glibc-2.25-r0.apk
|
||||
@@ -20,7 +20,7 @@ RUN npm -g i pnpm@6.32.15 && \
|
||||
# FIXME: need to remove devDependencies from the build
|
||||
# RUN pnpm install --prod --ignore-scripts
|
||||
|
||||
FROM node:16.15.0-alpine
|
||||
FROM node:16-alpine
|
||||
LABEL maintainer="https://github.com/verdaccio/verdaccio"
|
||||
|
||||
ENV VERDACCIO_APPDIR=/opt/verdaccio \
|
||||
|
||||
18
README.md
18
README.md
@@ -44,7 +44,19 @@ Google Cloud Storage** or create your own plugin.
|
||||
Install with npm:
|
||||
|
||||
```bash
|
||||
npm install --global verdaccio@6-next
|
||||
npm install --location=global verdaccio@6-next
|
||||
```
|
||||
|
||||
With `yarn`
|
||||
|
||||
```bash
|
||||
yarn global add verdaccio@6-next
|
||||
```
|
||||
|
||||
With `pnpm`
|
||||
|
||||
```bash
|
||||
pnpm i -g verdaccio@6-next
|
||||
```
|
||||
|
||||
or
|
||||
@@ -68,8 +80,8 @@ Furthermore, you can read the [**Debugging Guidelines**](https://github.com/verd
|
||||
You can develop your own [plugins](https://verdaccio.org/docs/plugins) with the [verdaccio generator](https://github.com/verdaccio/generator-verdaccio-plugin). Installing [Yeoman](https://yeoman.io/) is required.
|
||||
|
||||
```
|
||||
npm install -g yo
|
||||
npm install -g generator-verdaccio-plugin
|
||||
npm install --location=global yo
|
||||
npm install --location=global generator-verdaccio-plugin
|
||||
```
|
||||
|
||||
Learn more [here](https://verdaccio.org/docs/dev-plugins) how to develop plugins. Share your plugins with the community.
|
||||
|
||||
@@ -66,6 +66,6 @@ middlewares:
|
||||
enabled: true
|
||||
|
||||
# log settings
|
||||
logs:
|
||||
log:
|
||||
- { type: stdout, format: pretty, level: trace }
|
||||
#- {type: file, path: verdaccio.log, level: info}
|
||||
|
||||
@@ -7,4 +7,9 @@ module.exports = {
|
||||
collectCoverage: true,
|
||||
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**', '!**/partials/**', '!**/fixture/**'],
|
||||
coveragePathIgnorePatterns: ['node_modules', 'fixtures'],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
lines: 90,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
124
package.json
124
package.json
@@ -15,110 +15,109 @@
|
||||
"url": "https://opencollective.com/verdaccio"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.16.8",
|
||||
"@babel/core": "7.16.12",
|
||||
"@babel/node": "7.16.8",
|
||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||
"@babel/plugin-proposal-decorators": "7.16.7",
|
||||
"@babel/plugin-proposal-export-namespace-from": "7.16.7",
|
||||
"@babel/plugin-proposal-function-sent": "7.16.7",
|
||||
"@babel/plugin-proposal-json-strings": "7.16.7",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.16.7",
|
||||
"@babel/plugin-proposal-numeric-separator": "7.16.7",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.16.7",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
||||
"@babel/plugin-proposal-throw-expressions": "7.16.7",
|
||||
"@babel/cli": "7.18.10",
|
||||
"@babel/core": "7.18.13",
|
||||
"@babel/node": "7.18.10",
|
||||
"@babel/plugin-proposal-class-properties": "7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "7.18.10",
|
||||
"@babel/plugin-proposal-export-namespace-from": "7.18.9",
|
||||
"@babel/plugin-proposal-function-sent": "7.18.6",
|
||||
"@babel/plugin-proposal-json-strings": "7.18.6",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
|
||||
"@babel/plugin-proposal-numeric-separator": "7.18.6",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.18.9",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.18.9",
|
||||
"@babel/plugin-proposal-throw-expressions": "7.18.6",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/plugin-syntax-import-meta": "7.10.4",
|
||||
"@babel/plugin-transform-async-to-generator": "7.16.8",
|
||||
"@babel/plugin-transform-classes": "7.16.7",
|
||||
"@babel/plugin-transform-runtime": "7.16.10",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@babel/preset-react": "7.16.7",
|
||||
"@babel/preset-typescript": "7.16.7",
|
||||
"@babel/register": "7.16.9",
|
||||
"@babel/runtime": "7.16.7",
|
||||
"@dianmora/contributors": "2.0.2",
|
||||
"@changesets/changelog-github": "0.4.2",
|
||||
"@changesets/cli": "2.15.0",
|
||||
"@changesets/get-dependents-graph": "1.2.4",
|
||||
"@crowdin/cli": "3.7.7",
|
||||
"@trivago/prettier-plugin-sort-imports": "3.2.0",
|
||||
"@types/async": "3.2.12",
|
||||
"@babel/plugin-transform-async-to-generator": "7.18.6",
|
||||
"@babel/plugin-transform-classes": "7.18.9",
|
||||
"@babel/plugin-transform-runtime": "7.18.10",
|
||||
"@babel/preset-env": "7.18.10",
|
||||
"@babel/preset-react": "7.18.6",
|
||||
"@babel/preset-typescript": "7.18.6",
|
||||
"@babel/register": "7.18.9",
|
||||
"@babel/runtime": "7.18.9",
|
||||
"@dianmora/contributors": "5.0.0",
|
||||
"@changesets/changelog-github": "0.4.6",
|
||||
"@changesets/cli": "2.24.4",
|
||||
"@changesets/get-dependents-graph": "1.3.3",
|
||||
"@crowdin/cli": "3.7.10",
|
||||
"@trivago/prettier-plugin-sort-imports": "3.3.0",
|
||||
"@types/async": "3.2.15",
|
||||
"@types/autocannon": "4.1.1",
|
||||
"@types/express": "4.17.13",
|
||||
"@types/http-errors": "1.8.2",
|
||||
"@types/jest": "27.4.0",
|
||||
"@types/lodash": "4.14.178",
|
||||
"@types/jest": "27.5.2",
|
||||
"@types/lodash": "4.14.184",
|
||||
"@types/mime": "2.0.3",
|
||||
"@types/minimatch": "3.0.5",
|
||||
"@types/node": "16.11.21",
|
||||
"@types/jsonwebtoken": "8.5.1",
|
||||
"@types/node": "16.11.56",
|
||||
"@types/jsonwebtoken": "8.5.9",
|
||||
"@types/request": "2.48.8",
|
||||
"@types/semver": "7.3.9",
|
||||
"@types/semver": "7.3.12",
|
||||
"@types/node-fetch": "2.6.2",
|
||||
"@types/supertest": "2.0.12",
|
||||
"@types/testing-library__jest-dom": "5.14.2",
|
||||
"@types/validator": "13.7.1",
|
||||
"@types/testing-library__jest-dom": "5.14.5",
|
||||
"@types/validator": "13.7.6",
|
||||
"@types/webpack": "5.28.0",
|
||||
"@types/webpack-env": "1.16.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.25.0",
|
||||
"@typescript-eslint/parser": "5.25.0",
|
||||
"@types/webpack-env": "1.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.33.1",
|
||||
"@typescript-eslint/parser": "5.33.1",
|
||||
"@verdaccio/benchmark": "workspace:*",
|
||||
"@verdaccio/eslint-config": "workspace:*",
|
||||
"@verdaccio/types": "workspace:*",
|
||||
"@verdaccio/ui-theme": "workspace:*",
|
||||
"autocannon": "7.6.0",
|
||||
"autocannon": "7.9.0",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "27.4.6",
|
||||
"babel-jest": "29.0.2",
|
||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||
"babel-plugin-emotion": "10.2.2",
|
||||
"codecov": "3.8.3",
|
||||
"concurrently": "6.5.1",
|
||||
"core-js": "3.20.3",
|
||||
"core-js": "3.25.0",
|
||||
"cross-env": "7.0.3",
|
||||
"debug": "4.3.4",
|
||||
"detect-secrets": "1.0.6",
|
||||
"pretty-format": "27.5.1",
|
||||
"jest-diff": "27.5.1",
|
||||
"eslint": "8.15.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"jest-diff": "29.0.2",
|
||||
"eslint": "8.22.0",
|
||||
"fs-extra": "10.1.0",
|
||||
"husky": "7.0.4",
|
||||
"in-publish": "2.0.1",
|
||||
"jest": "27.4.7",
|
||||
"jest-environment-jsdom": "27.4.6",
|
||||
"jest-environment-jsdom-global": "3.0.0",
|
||||
"jest-environment-node": "27.4.6",
|
||||
"jest": "29.0.2",
|
||||
"jest-environment-jsdom": "29.0.2",
|
||||
"jest-environment-jsdom-global": "3.1.2",
|
||||
"jest-environment-node": "29.0.2",
|
||||
"jest-junit": "12.3.0",
|
||||
"kleur": "3.0.3",
|
||||
"lint-staged": "11.2.6",
|
||||
"nock": "12.0.3",
|
||||
"nock": "13.2.9",
|
||||
"node-fetch": "cjs",
|
||||
"nodemon": "2.0.15",
|
||||
"nodemon": "2.0.19",
|
||||
"npm-run-all": "4.1.5",
|
||||
"prettier": "2.6.2",
|
||||
"prettier": "2.7.1",
|
||||
"rimraf": "3.0.2",
|
||||
"selfsigned": "1.10.14",
|
||||
"supertest": "6.2.2",
|
||||
"ts-node": "10.4.0",
|
||||
"typescript": "4.5.5",
|
||||
"supertest": "6.2.4",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.8.2",
|
||||
"update-ts-references": "2.4.1",
|
||||
"verdaccio": "5.5.0",
|
||||
"verdaccio-audit": "workspace:*",
|
||||
"verdaccio-auth-memory": "workspace:*",
|
||||
"verdaccio-htpasswd": "workspace:*",
|
||||
"verdaccio-memory": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "husky install",
|
||||
"husky:pre-commit": "lint-staged",
|
||||
"clean": "pnpm recursive run clean",
|
||||
"build": "pnpm recursive run build --filter=!@verdaccio/website",
|
||||
"docker": "docker build -t verdaccio/verdaccio:local . --no-cache",
|
||||
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
|
||||
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
|
||||
"lint": "eslint --max-warnings 46 \"**/*.{js,jsx,ts,tsx}\"",
|
||||
"lint": "eslint --max-warnings 100 \"**/*.{js,jsx,ts,tsx}\"",
|
||||
"test": "pnpm recursive test --filter ./packages",
|
||||
"test:e2e:cli": "pnpm test --filter ...@verdaccio/e2e-cli",
|
||||
"test:e2e:cli": "pnpm test --filter ...@verdaccio/e2e-* -- --coverage=false",
|
||||
"test:e2e:ui": "pnpm test --filter ...@verdaccio/e2e-ui",
|
||||
"start": "concurrently --kill-others \"pnpm _start:server\" \"pnpm _start:web\"",
|
||||
"benchmark:hyper": "verdaccio-benchmark hyper -r ./hyper-results.json",
|
||||
@@ -132,7 +131,7 @@
|
||||
"_debug:reload": "nodemon -d 3 packages/verdaccio/debug/bootstrap.js",
|
||||
"start:ts": "ts-node packages/verdaccio/src/start.ts -- --listen 8000",
|
||||
"debug": "node --trace-warnings --trace-uncaught --inspect packages/verdaccio/debug/bootstrap.js",
|
||||
"debug:fastify": "node --trace-warnings --trace-uncaught --inspect packages/verdaccio/debug/bootstrap.js -- fastify-server",
|
||||
"debug:fastify": "cross-env VERDACCIO_SERVER=fastify node --trace-warnings --trace-uncaught --inspect packages/verdaccio/debug/bootstrap.js",
|
||||
"debug:break": "node --trace-warnings --trace-uncaught --inspect-brk packages/verdaccio/debug/bootstrap.js",
|
||||
"changeset": "changeset",
|
||||
"changeset:check": "changeset status --since-master",
|
||||
@@ -145,7 +144,10 @@
|
||||
"crowdin:upload": "crowdin upload sources --auto-update --config ./crowdin.yaml",
|
||||
"crowdin:download": "crowdin download --verbose --config ./crowdin.yaml",
|
||||
"crowdin:sync": "pnpm crowdin:upload && pnpm crowdin:download --verbose",
|
||||
"postinstall": "husky install"
|
||||
"postinstall": "husky install",
|
||||
"local:registry": "pnpm start --filter ...@verdaccio/local-publish",
|
||||
"local:publish": "cross-env npm_config_registry=http://localhost:4873 pnpm ci:publish",
|
||||
"local:publish:release": "concurrently \"pnpm local:registry\" \"pnpm local:publish\""
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.5",
|
||||
|
||||
@@ -1,5 +1,137 @@
|
||||
# @verdaccio/api
|
||||
|
||||
## 6.0.0-6-next.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/core@6.0.0-6-next.47
|
||||
- @verdaccio/config@6.0.0-6-next.47
|
||||
- @verdaccio/auth@6.0.0-6-next.26
|
||||
- @verdaccio/logger@6.0.0-6-next.15
|
||||
- @verdaccio/middleware@6.0.0-6-next.26
|
||||
- @verdaccio/store@6.0.0-6-next.27
|
||||
- @verdaccio/utils@6.0.0-6-next.15
|
||||
|
||||
## 6.0.0-6-next.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b849128d: fix: handle upload scoped tarball
|
||||
- Updated dependencies [b849128d]
|
||||
- @verdaccio/core@6.0.0-6-next.8
|
||||
- @verdaccio/store@6.0.0-6-next.26
|
||||
- @verdaccio/auth@6.0.0-6-next.25
|
||||
- @verdaccio/config@6.0.0-6-next.17
|
||||
- @verdaccio/logger@6.0.0-6-next.14
|
||||
- @verdaccio/middleware@6.0.0-6-next.25
|
||||
- @verdaccio/utils@6.0.0-6-next.14
|
||||
|
||||
## 6.0.0-6-next.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 351aeeaa: fix(deps): @verdaccio/utils should be a prod dep of local-storage
|
||||
- Updated dependencies [351aeeaa]
|
||||
- @verdaccio/auth@6.0.0-6-next.24
|
||||
- @verdaccio/core@6.0.0-6-next.7
|
||||
- @verdaccio/logger@6.0.0-6-next.13
|
||||
- @verdaccio/store@6.0.0-6-next.25
|
||||
- @verdaccio/middleware@6.0.0-6-next.24
|
||||
- @verdaccio/config@6.0.0-6-next.16
|
||||
- @verdaccio/utils@6.0.0-6-next.13
|
||||
|
||||
## 6.0.0-6-next.27
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 37274e4c: feat: implement abbreviated manifest
|
||||
|
||||
Enable abbreviated manifest data by adding the header:
|
||||
|
||||
```
|
||||
curl -H "Accept: application/vnd.npm.install-v1+json" https://registry.npmjs.org/verdaccio
|
||||
```
|
||||
|
||||
It returns a filtered manifest, additionally includes the [time](https://github.com/pnpm/rfcs/pull/2) field by request.
|
||||
|
||||
Current support for packages managers:
|
||||
|
||||
- npm: yes
|
||||
- pnpm: yes
|
||||
- yarn classic: yes
|
||||
- yarn modern (+2.x): [no](https://github.com/yarnpkg/berry/pull/3981#issuecomment-1076566096)
|
||||
|
||||
https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#abbreviated-metadata-format
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [37274e4c]
|
||||
- @verdaccio/store@6.0.0-6-next.24
|
||||
- @verdaccio/auth@6.0.0-6-next.23
|
||||
- @verdaccio/core@6.0.0-6-next.6
|
||||
- @verdaccio/logger@6.0.0-6-next.12
|
||||
|
||||
## 6.0.0-6-next.26
|
||||
|
||||
### Major Changes
|
||||
|
||||
- 292c0a37: feat!: replace deprecated request dependency by got
|
||||
|
||||
This is a big refactoring of the core, fetching dependencies, improve code, more tests and better stability. This is essential for the next release, will take some time but would allow modularize more the core.
|
||||
|
||||
## Notes
|
||||
|
||||
- Remove deprecated `request` by other `got`, retry improved, custom Agent ( got does not include it built-in)
|
||||
- Remove `async` dependency from storage (used by core) it was linked with proxy somehow safe to remove now
|
||||
- Refactor with promises instead callback wherever is possible
|
||||
- ~Document the API~
|
||||
- Improve testing, integration tests
|
||||
- Bugfix
|
||||
- Clean up old validations
|
||||
- Improve performance
|
||||
|
||||
## 💥 Breaking changes
|
||||
|
||||
- Plugin API methods were callbacks based are returning promises, this will break current storage plugins, check documentation for upgrade.
|
||||
- Write Tarball, Read Tarball methods parameters change, a new set of options like `AbortController` signals are being provided to the `addAbortSignal` can be internally used with Streams when a request is aborted. eg: `addAbortSignal(signal, fs.createReadStream(pathName));`
|
||||
- `@verdaccio/streams` stream abort support is legacy is being deprecated removed
|
||||
- Remove AWS and Google Cloud packages for future refactoring [#2574](https://github.com/verdaccio/verdaccio/pull/2574).
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 00d1d2a1: chore: env variable for launch fastify
|
||||
|
||||
- Update fastify to major release `v4.3.0`
|
||||
- Update CLI launcher
|
||||
|
||||
via CLI
|
||||
|
||||
```
|
||||
VERDACCIO_SERVER=fastify verdaccio
|
||||
```
|
||||
|
||||
with docker
|
||||
|
||||
```
|
||||
docker run -it --rm --name verdaccio \
|
||||
-e "VERDACCIO_SERVER=8080" -p 8080:8080 \
|
||||
-e "VERDACCIO_SERVER=fastify" \
|
||||
verdaccio/verdaccio
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [292c0a37]
|
||||
- Updated dependencies [a3a209b5]
|
||||
- Updated dependencies [00d1d2a1]
|
||||
- @verdaccio/auth@6.0.0-6-next.23
|
||||
- @verdaccio/config@6.0.0-6-next.15
|
||||
- @verdaccio/core@6.0.0-6-next.6
|
||||
- @verdaccio/logger@6.0.0-6-next.12
|
||||
- @verdaccio/middleware@6.0.0-6-next.23
|
||||
- @verdaccio/store@6.0.0-6-next.23
|
||||
- @verdaccio/utils@6.0.0-6-next.12
|
||||
|
||||
## 6.0.0-6-next.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
const debug = require('debug')('verdaccio:test');
|
||||
|
||||
const setup = debug;
|
||||
const logger = {
|
||||
child: jest.fn(() => ({
|
||||
debug,
|
||||
trace: debug,
|
||||
warn: debug,
|
||||
info: debug,
|
||||
error: debug,
|
||||
fatal: debug,
|
||||
})),
|
||||
debug: debug,
|
||||
trace: debug,
|
||||
warn: debug,
|
||||
info: debug,
|
||||
error: debug,
|
||||
fatal: debug,
|
||||
};
|
||||
|
||||
export { setup, logger };
|
||||
@@ -1,3 +1,10 @@
|
||||
const config = require('../../jest/config');
|
||||
|
||||
module.exports = Object.assign({}, config, {});
|
||||
module.exports = Object.assign({}, config, {
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
// FIXME: increase to 90
|
||||
lines: 60,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/api",
|
||||
"version": "6.0.0-6-next.25",
|
||||
"version": "6.0.0-6-next.30",
|
||||
"description": "loaders logic",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"test": "cross-env NODE_ENV=test BABEL_ENV=test jest",
|
||||
"test": "jest",
|
||||
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||
@@ -39,29 +39,30 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.22",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.14",
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.5",
|
||||
"@verdaccio/hooks": "workspace:6.0.0-6-next.13",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.11",
|
||||
"@verdaccio/middleware": "workspace:6.0.0-6-next.22",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.22",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.11",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.26",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.47",
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.47",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.15",
|
||||
"@verdaccio/middleware": "workspace:6.0.0-6-next.26",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.27",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.15",
|
||||
"abortcontroller-polyfill": "1.7.3",
|
||||
"cookies": "0.8.0",
|
||||
"debug": "4.3.3",
|
||||
"body-parser": "1.19.1",
|
||||
"express": "4.17.2",
|
||||
"debug": "4.3.4",
|
||||
"body-parser": "1.20.0",
|
||||
"express": "4.18.1",
|
||||
"lodash": "4.17.21",
|
||||
"mime": "2.6.0",
|
||||
"semver": "7.3.5"
|
||||
"semver": "7.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "16.11.21",
|
||||
"@verdaccio/server": "workspace:6.0.0-6-next.31",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.12",
|
||||
"@verdaccio/test-helper": "workspace:1.1.0-6-next.1",
|
||||
"supertest": "6.2.2"
|
||||
"@types/node": "16.11.56",
|
||||
"@verdaccio/server": "workspace:6.0.0-6-next.36",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.16",
|
||||
"@verdaccio/test-helper": "workspace:1.1.0-6-next.4",
|
||||
"supertest": "6.2.4",
|
||||
"nock": "13.2.9",
|
||||
"mockdate": "3.0.5"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -3,106 +3,119 @@ import _ from 'lodash';
|
||||
import mime from 'mime';
|
||||
|
||||
import { IAuth } from '@verdaccio/auth';
|
||||
import { VerdaccioError, constants } from '@verdaccio/core';
|
||||
import { constants, errorUtils } from '@verdaccio/core';
|
||||
import { allow, media } from '@verdaccio/middleware';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { Package } from '@verdaccio/types';
|
||||
|
||||
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
|
||||
|
||||
export default function (route: Router, auth: IAuth, storage: Storage): void {
|
||||
const can = allow(auth);
|
||||
const tag_package_version = function (
|
||||
const addTagPackageVersionMiddleware = async function (
|
||||
req: $RequestExtend,
|
||||
res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): $NextFunctionVer {
|
||||
): Promise<$NextFunctionVer> {
|
||||
if (_.isString(req.body) === false) {
|
||||
return next('route');
|
||||
return next(errorUtils.getBadRequest('version is missing'));
|
||||
}
|
||||
|
||||
const tags = {};
|
||||
tags[req.params.tag] = req.body;
|
||||
storage.mergeTags(req.params.package, tags, function (err: Error): $NextFunctionVer {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
try {
|
||||
await storage.mergeTagsNext(req.params.package, tags);
|
||||
res.status(constants.HTTP_STATUS.CREATED);
|
||||
return next({ ok: constants.API_MESSAGE.TAG_ADDED });
|
||||
});
|
||||
return next({
|
||||
ok: constants.API_MESSAGE.TAG_ADDED,
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
|
||||
// tagging a package.
|
||||
route.put('/:package/:tag', can('publish'), media(mime.getType('json')), tag_package_version);
|
||||
|
||||
route.post(
|
||||
'/-/package/:package/dist-tags/:tag',
|
||||
route.put(
|
||||
'/:package/:tag',
|
||||
can('publish'),
|
||||
media(mime.getType('json')),
|
||||
tag_package_version
|
||||
addTagPackageVersionMiddleware
|
||||
);
|
||||
|
||||
route.put(
|
||||
'/-/package/:package/dist-tags/:tag',
|
||||
can('publish'),
|
||||
media(mime.getType('json')),
|
||||
tag_package_version
|
||||
addTagPackageVersionMiddleware
|
||||
);
|
||||
|
||||
route.delete(
|
||||
'/-/package/:package/dist-tags/:tag',
|
||||
can('publish'),
|
||||
function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
async function (
|
||||
req: $RequestExtend,
|
||||
res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): Promise<void> {
|
||||
const tags = {};
|
||||
tags[req.params.tag] = null;
|
||||
storage.mergeTags(req.params.package, tags, function (err: VerdaccioError): $NextFunctionVer {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
try {
|
||||
await storage.mergeTagsNext(req.params.package, tags);
|
||||
res.status(constants.HTTP_STATUS.CREATED);
|
||||
return next({
|
||||
ok: constants.API_MESSAGE.TAG_REMOVED,
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
route.get(
|
||||
'/-/package/:package/dist-tags',
|
||||
can('access'),
|
||||
function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
storage.getPackage({
|
||||
name: req.params.package,
|
||||
uplinksLook: true,
|
||||
req,
|
||||
callback: function (err: VerdaccioError, info: Package): $NextFunctionVer {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
next(info[constants.DIST_TAGS]);
|
||||
},
|
||||
});
|
||||
async function (
|
||||
req: $RequestExtend,
|
||||
res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): Promise<void> {
|
||||
const name = req.params.package;
|
||||
const requestOptions = {
|
||||
protocol: req.protocol,
|
||||
headers: req.headers as any,
|
||||
// FIXME: if we migrate to req.hostname, the port is not longer included.
|
||||
host: req.host,
|
||||
remoteAddress: req.socket.remoteAddress,
|
||||
};
|
||||
try {
|
||||
const manifest = await storage.getPackageByOptions({
|
||||
name,
|
||||
uplinksLook: true,
|
||||
requestOptions,
|
||||
});
|
||||
next(manifest[constants.DIST_TAGS]);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
route.post(
|
||||
'/-/package/:package/dist-tags',
|
||||
can('publish'),
|
||||
function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
storage.mergeTags(
|
||||
req.params.package,
|
||||
req.body,
|
||||
function (err: VerdaccioError): $NextFunctionVer {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
res.status(constants.HTTP_STATUS.CREATED);
|
||||
return next({
|
||||
ok: constants.API_MESSAGE.TAG_UPDATED,
|
||||
});
|
||||
}
|
||||
);
|
||||
async function (
|
||||
req: $RequestExtend,
|
||||
res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): Promise<void> {
|
||||
try {
|
||||
await storage.mergeTagsNext(req.params.package, req.body);
|
||||
res.status(constants.HTTP_STATUS.CREATED);
|
||||
return next({
|
||||
ok: constants.API_MESSAGE.TAG_UPDATED,
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import bodyParser from 'body-parser';
|
||||
import express, { Router } from 'express';
|
||||
import semver from 'semver';
|
||||
|
||||
import { IAuth } from '@verdaccio/auth';
|
||||
import {
|
||||
@@ -25,10 +24,6 @@ import v1Search from './v1/search';
|
||||
import token from './v1/token';
|
||||
import whoami from './whoami';
|
||||
|
||||
if (semver.lte(process.version, 'v15.0.0')) {
|
||||
global.AbortController = require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;
|
||||
}
|
||||
|
||||
export default function (config: Config, auth: IAuth, storage: Storage): Router {
|
||||
/* eslint new-cap:off */
|
||||
const app = express.Router();
|
||||
@@ -62,7 +57,7 @@ export default function (config: Config, auth: IAuth, storage: Storage): Router
|
||||
search(app);
|
||||
user(app, auth, config);
|
||||
distTags(app, auth, storage);
|
||||
publish(app, auth, storage, config);
|
||||
publish(app, auth, storage);
|
||||
ping(app);
|
||||
stars(app, storage);
|
||||
// @ts-ignore
|
||||
|
||||
@@ -2,7 +2,7 @@ import buildDebug from 'debug';
|
||||
import { Router } from 'express';
|
||||
|
||||
import { IAuth } from '@verdaccio/auth';
|
||||
import { HEADERS, errorUtils } from '@verdaccio/core';
|
||||
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
||||
import { allow } from '@verdaccio/middleware';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
|
||||
@@ -10,27 +10,6 @@ import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/cust
|
||||
|
||||
const debug = buildDebug('verdaccio:api:package');
|
||||
|
||||
const downloadStream = (
|
||||
packageName: string,
|
||||
filename: string,
|
||||
storage: any,
|
||||
_req: $RequestExtend,
|
||||
res: $ResponseExtend
|
||||
): void => {
|
||||
const stream = storage.getTarball(packageName, filename);
|
||||
|
||||
stream.on('content-length', function (content): void {
|
||||
res.header('Content-Length', content);
|
||||
});
|
||||
|
||||
stream.on('error', function (err): void {
|
||||
return res.locals.report_error(err);
|
||||
});
|
||||
|
||||
res.header(HEADERS.CONTENT_TYPE, HEADERS.OCTET_STREAM);
|
||||
stream.pipe(res);
|
||||
};
|
||||
|
||||
export default function (route: Router, auth: IAuth, storage: Storage): void {
|
||||
const can = allow(auth);
|
||||
|
||||
@@ -44,28 +23,24 @@ export default function (route: Router, auth: IAuth, storage: Storage): void {
|
||||
): Promise<void> {
|
||||
debug('init package by version');
|
||||
const name = req.params.package;
|
||||
let queryVersion = req.params.version;
|
||||
let version = req.params.version;
|
||||
const write = req.query.write === 'true';
|
||||
const abbreviated = req.get('Accept') === Storage.ABBREVIATED_HEADER;
|
||||
const requestOptions = {
|
||||
protocol: req.protocol,
|
||||
headers: req.headers as any,
|
||||
// FIXME: if we migrate to req.hostname, the port is not longer included.
|
||||
host: req.host,
|
||||
remoteAddress: req.socket.remoteAddress,
|
||||
byPassCache: write,
|
||||
};
|
||||
|
||||
try {
|
||||
// TODO: this is just temporary while I migrate all plugins to use the new API
|
||||
// the method will be renamed to getPackage again but Promise Based.
|
||||
if (!storage.getPackageByOptions) {
|
||||
throw errorUtils.getInternalError(
|
||||
'getPackageByOptions not implemented, check pr-2750 for more details'
|
||||
);
|
||||
}
|
||||
|
||||
const manifest = await storage.getPackageByOptions({
|
||||
name,
|
||||
uplinksLook: true,
|
||||
req,
|
||||
version: queryVersion,
|
||||
abbreviated,
|
||||
version,
|
||||
requestOptions,
|
||||
});
|
||||
next(manifest);
|
||||
@@ -76,20 +51,39 @@ export default function (route: Router, auth: IAuth, storage: Storage): void {
|
||||
);
|
||||
|
||||
route.get(
|
||||
'/:scopedPackage/-/:scope/:filename',
|
||||
'/:pkg/-/:filename',
|
||||
can('access'),
|
||||
function (req: $RequestExtend, res: $ResponseExtend): void {
|
||||
const { scopedPackage, filename } = req.params;
|
||||
async function (req: $RequestExtend, res: $ResponseExtend, next): Promise<void> {
|
||||
const { pkg, filename } = req.params;
|
||||
const abort = new AbortController();
|
||||
try {
|
||||
const stream = (await storage.getTarballNext(pkg, filename, {
|
||||
signal: abort.signal,
|
||||
// TODO: review why this param
|
||||
// enableRemote: true,
|
||||
})) as any;
|
||||
|
||||
downloadStream(scopedPackage, filename, storage, req, res);
|
||||
}
|
||||
);
|
||||
stream.on('content-length', (size) => {
|
||||
res.header(HEADER_TYPE.CONTENT_LENGTH, size);
|
||||
});
|
||||
|
||||
route.get(
|
||||
'/:package/-/:filename',
|
||||
can('access'),
|
||||
function (req: $RequestExtend, res: $ResponseExtend): void {
|
||||
downloadStream(req.params.package, req.params.filename, storage, req, res);
|
||||
stream.once('error', (err) => {
|
||||
res.locals.report_error(err);
|
||||
next(err);
|
||||
});
|
||||
|
||||
req.on('abort', () => {
|
||||
debug('request aborted for %o', req.url);
|
||||
abort.abort();
|
||||
});
|
||||
|
||||
res.header(HEADERS.CONTENT_TYPE, HEADERS.OCTET_STREAM);
|
||||
stream.pipe(res);
|
||||
} catch (err: any) {
|
||||
// console.log('catch API error request', err);
|
||||
res.locals.report_error(err);
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,40 +1,21 @@
|
||||
import buildDebug from 'debug';
|
||||
import { Router } from 'express';
|
||||
import _ from 'lodash';
|
||||
import mime from 'mime';
|
||||
import Path from 'path';
|
||||
|
||||
import { IAuth } from '@verdaccio/auth';
|
||||
import {
|
||||
API_ERROR,
|
||||
API_MESSAGE,
|
||||
DIST_TAGS,
|
||||
HEADERS,
|
||||
HTTP_STATUS,
|
||||
errorUtils,
|
||||
} from '@verdaccio/core';
|
||||
import { notify } from '@verdaccio/hooks';
|
||||
import { API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { allow, expectJson, media } from '@verdaccio/middleware';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { Callback, CallbackAction, Config, MergeTags, Package, Version } from '@verdaccio/types';
|
||||
import { hasDiffOneKey, isObject, validateMetadata } from '@verdaccio/utils';
|
||||
|
||||
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
|
||||
import star from './star';
|
||||
import { isPublishablePackage, isRelatedToDeprecation } from './utils';
|
||||
|
||||
// import star from './star';
|
||||
// import { isPublishablePackage, isRelatedToDeprecation } from './utils';
|
||||
|
||||
const debug = buildDebug('verdaccio:api:publish');
|
||||
|
||||
export default function publish(
|
||||
router: Router,
|
||||
auth: IAuth,
|
||||
storage: Storage,
|
||||
config: Config
|
||||
): void {
|
||||
const can = allow(auth);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Publish a package / update package / un/start a package
|
||||
*
|
||||
* There are multiples scenarios here to be considered:
|
||||
@@ -73,20 +54,34 @@ export default function publish(
|
||||
*
|
||||
* Example flow of unpublish.
|
||||
*
|
||||
* npm http fetch GET 200 http://localhost:4873/@scope%2ftest1?write=true 1680ms
|
||||
* npm http fetch PUT 201 http://localhost:4873/@scope%2ftest1/-rev/14-5d500cfce92f90fd
|
||||
* 956606ms attempt #2
|
||||
* npm http fetch GET 200 http://localhost:4873/@scope%2ftest1?write=true 1601ms
|
||||
* npm http fetch DELETE 201 http://localhost:4873/@scope%2ftest1/-/test1-1.0.3.tgz/-rev/16
|
||||
* -e11c8db282b2d992 19ms
|
||||
* There are two possible flows:
|
||||
*
|
||||
* - Remove all packages (entirely)
|
||||
* eg: npm unpublish package-name@* --force
|
||||
* eg: npm unpublish package-name --force
|
||||
*
|
||||
* npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1680ms
|
||||
* npm http fetch DELETE 201 http://localhost:4873/custom-name/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
|
||||
*
|
||||
* - Remove a specific version
|
||||
* eg: npm unpublish package-name@1.0.0 --force
|
||||
*
|
||||
* Get fresh manifest
|
||||
* npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1680ms
|
||||
* Update manifest without the version to be unpublished
|
||||
* npm http fetch PUT 201 http://localhost:4873/custom-name/-rev/14-5d500cfce92f90fd 956606ms
|
||||
* Get fresh manifest (revision should be different)
|
||||
* npm http fetch GET 200 http://localhost:4873/custom-name?write=true 1601ms
|
||||
* Remove the tarball
|
||||
* npm http fetch DELETE 201 http://localhost:4873/custom-name/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
|
||||
*
|
||||
* 3. Star a package
|
||||
*
|
||||
* Permissions: start a package depends of the publish and unpublish permissions, there is no
|
||||
* specific flag for star or un start.
|
||||
* The URL for star is similar to the unpublish (change package format)
|
||||
*
|
||||
* npm has no enpoint for star a package, rather mutate the metadata and acts as, the difference
|
||||
* npm has no endpoint for star a package, rather mutate the metadata and acts as, the difference
|
||||
* is the users property which is part of the payload and the body only includes
|
||||
*
|
||||
* {
|
||||
@@ -98,12 +93,24 @@ export default function publish(
|
||||
}
|
||||
*
|
||||
*/
|
||||
export default function publish(router: Router, auth: IAuth, storage: Storage): void {
|
||||
const can = allow(auth);
|
||||
// publish (update manifest) v6
|
||||
router.put(
|
||||
'/:package/:_rev?/:revision?',
|
||||
'/:package',
|
||||
can('publish'),
|
||||
media(mime.getType('json')),
|
||||
expectJson,
|
||||
publishPackage(storage, config, auth)
|
||||
publishPackageNext(storage)
|
||||
);
|
||||
|
||||
// unpublish a pacakge v6
|
||||
router.put(
|
||||
'/:package/-rev/:revision',
|
||||
can('unpublish'),
|
||||
media(mime.getType('json')),
|
||||
expectJson,
|
||||
publishPackageNext(storage)
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -111,330 +118,101 @@ export default function publish(
|
||||
*
|
||||
* This scenario happens when the first call detect there is only one version remaining
|
||||
* in the metadata, then the client decides to DELETE the resource
|
||||
* npm http fetch GET 304 http://localhost:4873/@scope%2ftest1?write=true 1076ms (from cache)
|
||||
npm http fetch DELETE 201 http://localhost:4873/@scope%2ftest1/-rev/18-d8ebe3020bd4ac9c 22ms
|
||||
* npm http fetch GET 304 http://localhost:4873/package-name?write=true 1076ms (from cache)
|
||||
* npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
|
||||
*/
|
||||
router.delete('/:package/-rev/*', can('unpublish'), unPublishPackage(storage));
|
||||
// v6
|
||||
router.delete(
|
||||
'/:package/-rev/:revision',
|
||||
can('unpublish'),
|
||||
async function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||
const packageName = req.params.package;
|
||||
const rev = req.params.revision;
|
||||
|
||||
// removing a tarball
|
||||
logger.debug({ packageName }, `unpublishing @{packageName}`);
|
||||
try {
|
||||
await storage.removePackage(packageName, rev);
|
||||
debug('package %s unpublished', packageName);
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
return next({ ok: API_MESSAGE.PKG_REMOVED });
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
Remove a tarball, this happens when npm unpublish a package unique version.
|
||||
npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
|
||||
*/
|
||||
router.delete(
|
||||
'/:package/-/:filename/-rev/:revision',
|
||||
can('unpublish'),
|
||||
can('publish'),
|
||||
removeTarball(storage)
|
||||
);
|
||||
|
||||
// uploading package tarball
|
||||
router.put(
|
||||
'/:package/-/:filename/*',
|
||||
can('publish'),
|
||||
media(HEADERS.OCTET_STREAM),
|
||||
uploadPackageTarball(storage)
|
||||
);
|
||||
|
||||
// adding a version
|
||||
router.put(
|
||||
'/:package/:version/-tag/:tag',
|
||||
can('publish'),
|
||||
media(mime.getType('json')),
|
||||
expectJson,
|
||||
addVersion(storage)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a package
|
||||
*/
|
||||
export function publishPackage(storage: Storage, config: Config, auth: IAuth): any {
|
||||
const starApi = star(storage);
|
||||
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
const packageName = req.params.package;
|
||||
|
||||
debug('publishing or updating a new version for %o', packageName);
|
||||
|
||||
/**
|
||||
* Write tarball of stream data from package clients.
|
||||
*/
|
||||
const createTarball = function (filename: string, data, cb: Callback): void {
|
||||
const stream = storage.addTarball(packageName, filename);
|
||||
stream.on('error', function (err) {
|
||||
debug(
|
||||
'error on stream a tarball %o for %o with error %o',
|
||||
filename,
|
||||
packageName,
|
||||
err.message
|
||||
);
|
||||
cb(err);
|
||||
});
|
||||
stream.on('success', function () {
|
||||
debug('success on stream a tarball %o for %o', filename, packageName);
|
||||
cb();
|
||||
});
|
||||
// this is dumb and memory-consuming, but what choices do we have?
|
||||
// flow: we need first refactor this file before decides which type use here
|
||||
stream.end(Buffer.from(data.data, 'base64'));
|
||||
stream.done();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add new package version in storage
|
||||
*/
|
||||
const createVersion = function (version: string, metadata: Version, cb: CallbackAction): void {
|
||||
debug('add a new package version %o to storage %o', version, metadata);
|
||||
storage.addVersion(packageName, version, metadata, null, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add new tags in storage
|
||||
*/
|
||||
const addTags = function (tags: MergeTags, cb: CallbackAction): void {
|
||||
debug('add new tag %o to storage', packageName);
|
||||
storage.mergeTags(packageName, tags, cb);
|
||||
};
|
||||
|
||||
const afterChange = function (error, okMessage, metadata: Package): void {
|
||||
const metadataCopy: Package = { ...metadata };
|
||||
debug('after change metadata %o', metadata);
|
||||
|
||||
const { _attachments, versions } = metadataCopy;
|
||||
|
||||
// `npm star` wouldn't have attachments
|
||||
// and `npm deprecate` would have attachments as a empty object, i.e {}
|
||||
if (_.isNil(_attachments) || JSON.stringify(_attachments) === '{}') {
|
||||
debug('no attachments detected');
|
||||
if (error) {
|
||||
debug('no_attachments: after change error with %o', error.message);
|
||||
return next(error);
|
||||
}
|
||||
|
||||
debug('no_attachments: after change success');
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
return next({
|
||||
ok: okMessage,
|
||||
success: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* npm-registry-client 0.3+ embeds tarball into the json upload
|
||||
* issue https://github.com/rlidwka/sinopia/issues/31, dealing with it here:
|
||||
*/
|
||||
|
||||
const isInvalidBodyFormat =
|
||||
isObject(_attachments) === false ||
|
||||
hasDiffOneKey(_attachments) ||
|
||||
isObject(versions) === false ||
|
||||
hasDiffOneKey(versions);
|
||||
|
||||
if (isInvalidBodyFormat) {
|
||||
// npm is doing something strange again
|
||||
// if this happens in normal circumstances, report it as a bug
|
||||
debug('invalid body format');
|
||||
logger.info({ packageName }, `wrong package format on publish a package @{packageName}`);
|
||||
return next(errorUtils.getBadRequest(API_ERROR.UNSUPORTED_REGISTRY_CALL));
|
||||
}
|
||||
|
||||
if (error && error.status !== HTTP_STATUS.CONFLICT) {
|
||||
debug('error on change or update a package with %o', error.message);
|
||||
return next(error);
|
||||
}
|
||||
|
||||
// at this point document is either created or existed before
|
||||
const [firstAttachmentKey] = Object.keys(_attachments);
|
||||
|
||||
createTarball(
|
||||
Path.basename(firstAttachmentKey),
|
||||
_attachments[firstAttachmentKey],
|
||||
function (error) {
|
||||
debug('creating a tarball %o', firstAttachmentKey);
|
||||
if (error) {
|
||||
debug('error on create a tarball for %o with error %o', packageName, error.message);
|
||||
return next(error);
|
||||
}
|
||||
|
||||
const versionToPublish = Object.keys(versions)[0];
|
||||
|
||||
versions[versionToPublish].readme =
|
||||
_.isNil(metadataCopy.readme) === false ? String(metadataCopy.readme) : '';
|
||||
|
||||
createVersion(versionToPublish, versions[versionToPublish], function (error) {
|
||||
if (error) {
|
||||
debug('error on create a version for %o with error %o', packageName, error.message);
|
||||
return next(error);
|
||||
}
|
||||
|
||||
addTags(metadataCopy[DIST_TAGS], async function (error) {
|
||||
if (error) {
|
||||
debug('error on create a tag for %o with error %o', packageName, error.message);
|
||||
return next(error);
|
||||
}
|
||||
|
||||
try {
|
||||
await notify(
|
||||
metadataCopy,
|
||||
config,
|
||||
req.remote_user,
|
||||
`${metadataCopy.name}@${versionToPublish}`
|
||||
);
|
||||
} catch (error: any) {
|
||||
debug(
|
||||
'error on notify add a new tag %o',
|
||||
`${metadataCopy.name}@${versionToPublish}`
|
||||
);
|
||||
logger.error({ error }, 'notify batch service has failed: @{error}');
|
||||
}
|
||||
|
||||
debug('add a tag succesfully for %o', `${metadataCopy.name}@${versionToPublish}`);
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
return next({ ok: okMessage, success: true });
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (isPublishablePackage(req.body) === false && isObject(req.body.users)) {
|
||||
debug('starting star a package');
|
||||
return starApi(req, res, next);
|
||||
}
|
||||
|
||||
try {
|
||||
debug('pre validation metadata to publish %o', req.body);
|
||||
const metadata = validateMetadata(req.body, packageName);
|
||||
debug('post validation metadata to publish %o', metadata);
|
||||
// treating deprecation as updating a package
|
||||
if (req.params._rev || isRelatedToDeprecation(req.body)) {
|
||||
debug('updating a new version for %o', packageName);
|
||||
// we check unpublish permissions, an update is basically remove versions
|
||||
const remote = req.remote_user;
|
||||
auth.allow_unpublish({ packageName }, remote, (error) => {
|
||||
debug('allowed to unpublish a package %o', packageName);
|
||||
if (error) {
|
||||
debug('not allowed to unpublish a version for %o', packageName);
|
||||
return next(error);
|
||||
}
|
||||
|
||||
debug('update a package');
|
||||
storage.changePackage(packageName, metadata, req.params.revision, function (error) {
|
||||
afterChange(error, API_MESSAGE.PKG_CHANGED, metadata);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
debug('adding a new version for the package %o', packageName);
|
||||
storage.addPackage(packageName, metadata, function (error) {
|
||||
debug('package metadata updated %o', metadata);
|
||||
afterChange(error, API_MESSAGE.PKG_CREATED, metadata);
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
debug('error on publish, bad package format %o', packageName);
|
||||
logger.error({ packageName }, 'error on publish, bad package data for @{packageName}');
|
||||
return next(errorUtils.getBadData(API_ERROR.BAD_PACKAGE_DATA));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* un-publish a package
|
||||
*/
|
||||
export function unPublishPackage(storage: Storage) {
|
||||
return async function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||
const packageName = req.params.package;
|
||||
|
||||
logger.debug({ packageName }, `unpublishing @{packageName}`);
|
||||
try {
|
||||
await storage.removePackage(packageName);
|
||||
} catch (err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
return next({ ok: API_MESSAGE.PKG_REMOVED });
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete tarball
|
||||
*/
|
||||
export function removeTarball(storage: Storage) {
|
||||
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
const packageName = req.params.package;
|
||||
const { filename, revision } = req.params;
|
||||
|
||||
logger.debug(
|
||||
{ packageName, filename, revision },
|
||||
`removing a tarball for @{packageName}-@{tarballName}-@{revision}`
|
||||
);
|
||||
storage.removeTarball(packageName, filename, revision, function (err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
async function (
|
||||
req: $RequestExtend,
|
||||
res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): Promise<void> {
|
||||
const packageName = req.params.package;
|
||||
const { filename, revision } = req.params;
|
||||
|
||||
logger.debug(
|
||||
{ packageName, filename, revision },
|
||||
`success remove tarball for @{packageName}-@{tarballName}-@{revision}`
|
||||
`removing a tarball for @{packageName}-@{tarballName}-@{revision}`
|
||||
);
|
||||
return next({ ok: API_MESSAGE.TARBALL_REMOVED });
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Adds a new version
|
||||
*/
|
||||
export function addVersion(storage: Storage) {
|
||||
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
const { version, tag } = req.params;
|
||||
const packageName = req.params.package;
|
||||
debug('add a new version %o and tag %o for %o', version, tag, packageName);
|
||||
try {
|
||||
await storage.removeTarball(packageName, filename, revision);
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
|
||||
storage.addVersion(packageName, version, req.body, tag, function (error) {
|
||||
if (error) {
|
||||
debug('error on add new version');
|
||||
return next(error);
|
||||
logger.debug(
|
||||
{ packageName, filename, revision },
|
||||
`success remove tarball for @{packageName}-@{tarballName}-@{revision}`
|
||||
);
|
||||
return next({ ok: API_MESSAGE.TARBALL_REMOVED });
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
debug('success on add new version');
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
return next({
|
||||
ok: API_MESSAGE.PKG_PUBLISHED,
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* uploadPackageTarball
|
||||
*/
|
||||
export function uploadPackageTarball(storage: Storage) {
|
||||
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
export function publishPackageNext(storage: Storage): any {
|
||||
return async function (
|
||||
req: $RequestExtend,
|
||||
_res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): Promise<void> {
|
||||
const ac = new AbortController();
|
||||
const packageName = req.params.package;
|
||||
const stream = storage.addTarball(packageName, req.params.filename);
|
||||
req.pipe(stream);
|
||||
const { revision } = req.params;
|
||||
const metadata = req.body;
|
||||
|
||||
// checking if end event came before closing
|
||||
let complete = false;
|
||||
req.on('end', function () {
|
||||
complete = true;
|
||||
stream.done();
|
||||
});
|
||||
|
||||
req.on('close', function () {
|
||||
if (!complete) {
|
||||
stream.abort();
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('error', function (err) {
|
||||
return res.locals.report_error(err);
|
||||
});
|
||||
|
||||
stream.on('success', function () {
|
||||
res.status(HTTP_STATUS.CREATED);
|
||||
return next({
|
||||
ok: API_MESSAGE.TARBALL_UPLOADED,
|
||||
try {
|
||||
debug('publishing %s', packageName);
|
||||
await storage.updateManifest(metadata, {
|
||||
name: packageName,
|
||||
revision,
|
||||
signal: ac.signal,
|
||||
requestOptions: {
|
||||
host: req.hostname,
|
||||
protocol: req.protocol,
|
||||
// @ts-ignore
|
||||
headers: req.headers,
|
||||
},
|
||||
});
|
||||
});
|
||||
_res.status(HTTP_STATUS.CREATED);
|
||||
|
||||
return next({
|
||||
// TODO: this could be also Package Updated based on the
|
||||
// action, deprecate, star, publish new version, or create a package
|
||||
// the message some return from the method
|
||||
ok: API_MESSAGE.PKG_CREATED,
|
||||
success: true,
|
||||
});
|
||||
} catch (err: any) {
|
||||
// TODO: review if we need the abort controller here
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import buildDebug from 'debug';
|
||||
import { Response } from 'express';
|
||||
import _ from 'lodash';
|
||||
@@ -27,61 +28,61 @@ export default function (
|
||||
return (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
||||
const name = req.params.package;
|
||||
debug('starring a package for %o', name);
|
||||
const afterChangePackage = function (err?: Error) {
|
||||
if (err) {
|
||||
debug('error on update package for %o', name);
|
||||
return next(err);
|
||||
}
|
||||
// const afterChangePackage = function (err?: Error) {
|
||||
// if (err) {
|
||||
// debug('error on update package for %o', name);
|
||||
// return next(err);
|
||||
// }
|
||||
|
||||
debug('succes update package for %o', name);
|
||||
res.status(HTTP_STATUS.OK);
|
||||
next({
|
||||
success: true,
|
||||
});
|
||||
};
|
||||
// debug('succes update package for %o', name);
|
||||
// res.status(HTTP_STATUS.OK);
|
||||
// next({
|
||||
// success: true,
|
||||
// });
|
||||
// };
|
||||
|
||||
debug('get package info package for %o', name);
|
||||
// @ts-ignore
|
||||
storage.getPackage({
|
||||
name,
|
||||
req,
|
||||
callback: function (err, info) {
|
||||
if (err) {
|
||||
debug('error on get package info package for %o', name);
|
||||
return next(err);
|
||||
}
|
||||
const newStarUser = req.body[USERS];
|
||||
const remoteUsername = req.remote_user.name;
|
||||
const localStarUsers = info[USERS];
|
||||
// Check is star or unstar
|
||||
const isStar = Object.keys(newStarUser).includes(remoteUsername);
|
||||
debug('is start? %o', isStar);
|
||||
if (
|
||||
_.isNil(localStarUsers) === false &&
|
||||
validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)
|
||||
) {
|
||||
return afterChangePackage();
|
||||
}
|
||||
const users = isStar
|
||||
? {
|
||||
...localStarUsers,
|
||||
[remoteUsername]: true,
|
||||
}
|
||||
: _.reduce(
|
||||
localStarUsers,
|
||||
(users, value, key) => {
|
||||
if (key !== remoteUsername) {
|
||||
users[key] = value;
|
||||
}
|
||||
return users;
|
||||
},
|
||||
{}
|
||||
);
|
||||
debug('update package for %o', name);
|
||||
storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {
|
||||
afterChangePackage(err);
|
||||
});
|
||||
},
|
||||
});
|
||||
// storage.getPackage({
|
||||
// name,
|
||||
// req,
|
||||
// callback: function (err, info) {
|
||||
// if (err) {
|
||||
// debug('error on get package info package for %o', name);
|
||||
// return next(err);
|
||||
// }
|
||||
// const newStarUser = req.body[USERS];
|
||||
// const remoteUsername = req.remote_user.name;
|
||||
// const localStarUsers = info[USERS];
|
||||
// // Check is star or unstar
|
||||
// const isStar = Object.keys(newStarUser).includes(remoteUsername);
|
||||
// debug('is start? %o', isStar);
|
||||
// if (
|
||||
// _.isNil(localStarUsers) === false &&
|
||||
// validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)
|
||||
// ) {
|
||||
// return afterChangePackage();
|
||||
// }
|
||||
// const users = isStar
|
||||
// ? {
|
||||
// ...localStarUsers,
|
||||
// [remoteUsername]: true,
|
||||
// }
|
||||
// : _.reduce(
|
||||
// localStarUsers,
|
||||
// (users, value, key) => {
|
||||
// if (key !== remoteUsername) {
|
||||
// users[key] = value;
|
||||
// }
|
||||
// return users;
|
||||
// },
|
||||
// {}
|
||||
// );
|
||||
// debug('update package for %o', name);
|
||||
// storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {
|
||||
// afterChangePackage(err);
|
||||
// });
|
||||
// },
|
||||
// });
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,34 +3,32 @@ import _ from 'lodash';
|
||||
|
||||
import { HTTP_STATUS, USERS } from '@verdaccio/core';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { Package } from '@verdaccio/types';
|
||||
import { Version } from '@verdaccio/types';
|
||||
|
||||
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
||||
|
||||
type Packages = Package[];
|
||||
|
||||
export default function (route: Router, storage: Storage): void {
|
||||
route.get(
|
||||
'/-/_view/starredByUser',
|
||||
(req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
||||
async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
|
||||
const remoteUsername = req.remote_user.name;
|
||||
|
||||
storage.getLocalDatabase((err, localPackages: Packages) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
try {
|
||||
const localPackages: Version[] = await storage.getLocalDatabaseNext();
|
||||
|
||||
const filteredPackages: Packages = localPackages.filter((localPackage: Package) =>
|
||||
const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>
|
||||
_.keys(localPackage[USERS]).includes(remoteUsername)
|
||||
);
|
||||
|
||||
res.status(HTTP_STATUS.OK);
|
||||
next({
|
||||
rows: filteredPackages.map((filteredPackage: Package) => ({
|
||||
rows: filteredPackages.map((filteredPackage: Version) => ({
|
||||
value: filteredPackage.name,
|
||||
})),
|
||||
});
|
||||
});
|
||||
} catch (err: any) {
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { createRemoteUser } from '@verdaccio/config';
|
||||
import { API_ERROR, API_MESSAGE, HTTP_STATUS, errorUtils } from '@verdaccio/core';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { Config, RemoteUser } from '@verdaccio/types';
|
||||
import { getAuthenticatedMessage, validatePassword } from '@verdaccio/utils';
|
||||
import { getAuthenticatedMessage, mask, validatePassword } from '@verdaccio/utils';
|
||||
|
||||
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
||||
|
||||
@@ -28,6 +28,23 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* body example
|
||||
* req.body = {
|
||||
_id: "org.couchdb.user:jjjj",
|
||||
name: "jjjj",
|
||||
password: "jjjj",
|
||||
type: "user",
|
||||
roles: [],
|
||||
date: "2022-07-08T15:51:04.002Z",
|
||||
}
|
||||
*
|
||||
* @export
|
||||
* @param {Router} route
|
||||
* @param {IAuth} auth
|
||||
* @param {Config} config
|
||||
*/
|
||||
route.put(
|
||||
'/-/user/:org_couchdb_user/:_rev?/:revision?',
|
||||
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
|
||||
@@ -92,7 +109,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
||||
|
||||
const token =
|
||||
name && password ? await getApiToken(auth, config, user, password) : undefined;
|
||||
debug('adduser: new token %o', token);
|
||||
debug('adduser: new token %o', mask(token as string, 4));
|
||||
if (!token) {
|
||||
return next(errorUtils.getUnauthorized());
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Package } from '@verdaccio/types';
|
||||
|
||||
/**
|
||||
* Check whether the package metadta has enough data to be published
|
||||
* @param pkg metadata
|
||||
*/
|
||||
|
||||
export function isPublishablePackage(pkg: Package): boolean {
|
||||
// TODO: we can do better, no need get keys
|
||||
const keys: string[] = Object.keys(pkg);
|
||||
|
||||
return _.includes(keys, 'versions');
|
||||
}
|
||||
|
||||
export function isRelatedToDeprecation(pkgInfo: Package): boolean {
|
||||
const { versions } = pkgInfo;
|
||||
for (const version in versions) {
|
||||
if (Object.prototype.hasOwnProperty.call(versions[version], 'deprecated')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import { IAuth } from '@verdaccio/auth';
|
||||
import { HTTP_STATUS, searchUtils } from '@verdaccio/core';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { Package } from '@verdaccio/types';
|
||||
import { Manifest } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:api:search');
|
||||
|
||||
@@ -16,7 +16,7 @@ const debug = buildDebug('verdaccio:api:search');
|
||||
* req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'
|
||||
*/
|
||||
export default function (route, auth: IAuth, storage: Storage): void {
|
||||
function checkAccess(pkg: any, auth: any, remoteUser): Promise<Package | null> {
|
||||
function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {
|
||||
if (err) {
|
||||
@@ -49,7 +49,7 @@ export default function (route, auth: IAuth, storage: Storage): void {
|
||||
from = parseInt(from, 10) || 0;
|
||||
|
||||
try {
|
||||
data = await storage.searchManager?.search({
|
||||
data = await storage.search({
|
||||
query,
|
||||
url,
|
||||
abort,
|
||||
|
||||
@@ -1,36 +1,20 @@
|
||||
import buildDebug from 'debug';
|
||||
import { Response, Router } from 'express';
|
||||
|
||||
import { errorUtils } from '@verdaccio/core';
|
||||
|
||||
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
||||
|
||||
const debug = buildDebug('verdaccio:api:user');
|
||||
|
||||
export default function (route: Router): void {
|
||||
route.get('/whoami', (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
||||
debug('whoami: reditect');
|
||||
if (req.headers.referer === 'whoami') {
|
||||
const username = req.remote_user.name;
|
||||
// FIXME: this service should return 401 if user missing
|
||||
// if (!username) {
|
||||
// debug('whoami: user not found');
|
||||
// return next(getUnauthorized('Unauthorized'));
|
||||
// }
|
||||
debug('whoami: logged by user');
|
||||
return next({ username: username });
|
||||
} else {
|
||||
debug('whoami: redirect next route');
|
||||
// redirect to the route below
|
||||
return next('route');
|
||||
route.get('/-/whoami', (req: $RequestExtend, _res: Response, next: $NextFunctionVer): any => {
|
||||
// remote_user is set by the auth middleware
|
||||
const username = req?.remote_user?.name;
|
||||
if (!username) {
|
||||
debug('whoami: user not found');
|
||||
return next(errorUtils.getUnauthorized('Unauthorized'));
|
||||
}
|
||||
});
|
||||
|
||||
route.get('/-/whoami', (req: $RequestExtend, res: Response, next: $NextFunctionVer): any => {
|
||||
const username = req.remote_user.name;
|
||||
// FIXME: this service should return 401 if user missing
|
||||
// if (!username) {
|
||||
// debug('whoami: user not found');
|
||||
// return next(getUnauthorized('Unauthorized'));
|
||||
// }
|
||||
|
||||
debug('whoami: response %o', username);
|
||||
return next({ username: username });
|
||||
|
||||
@@ -1,83 +1,126 @@
|
||||
import bodyParser from 'body-parser';
|
||||
import express, { Application } from 'express';
|
||||
import { Application } from 'express';
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { Auth, IAuth } from '@verdaccio/auth';
|
||||
import { Config, parseConfigFile } from '@verdaccio/config';
|
||||
import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
|
||||
import { errorReportingMiddleware, final, handleError } from '@verdaccio/middleware';
|
||||
import { parseConfigFile } from '@verdaccio/config';
|
||||
import { HEADERS, HEADER_TYPE, HTTP_STATUS, TOKEN_BEARER } from '@verdaccio/core';
|
||||
import { setup } from '@verdaccio/logger';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { generatePackageMetadata } from '@verdaccio/test-helper';
|
||||
import {
|
||||
generatePackageMetadata,
|
||||
initializeServer as initializeServerHelper,
|
||||
} from '@verdaccio/test-helper';
|
||||
import { GenericBody } from '@verdaccio/types';
|
||||
import { buildToken, generateRandomHexString } from '@verdaccio/utils';
|
||||
|
||||
import apiEndpoints from '../../src';
|
||||
import apiMiddleware from '../../src';
|
||||
|
||||
const getConf = (conf) => {
|
||||
setup();
|
||||
|
||||
export const getConf = (conf) => {
|
||||
const configPath = path.join(__dirname, 'config', conf);
|
||||
|
||||
return parseConfigFile(configPath);
|
||||
const config = parseConfigFile(configPath);
|
||||
// custom config to avoid conflict with other tests
|
||||
config.auth.htpasswd.file = `${config.auth.htpasswd.file}-${generateRandomHexString()}`;
|
||||
return config;
|
||||
};
|
||||
|
||||
// TODO: replace by @verdaccio/test-helper
|
||||
export async function initializeServer(configName): Promise<Application> {
|
||||
const app = express();
|
||||
const config = new Config(getConf(configName));
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config, []);
|
||||
const auth: IAuth = new Auth(config);
|
||||
// TODO: this might not be need it, used in apiEndpoints
|
||||
app.use(bodyParser.json({ strict: false, limit: '10mb' }));
|
||||
// @ts-ignore
|
||||
app.use(errorReportingMiddleware);
|
||||
// @ts-ignore
|
||||
app.use(apiEndpoints(config, auth, storage));
|
||||
// @ts-ignore
|
||||
app.use(handleError);
|
||||
// @ts-ignore
|
||||
app.use(final);
|
||||
|
||||
app.use(function (request, response) {
|
||||
response.status(590);
|
||||
console.log('respo', response);
|
||||
response.json({ error: 'cannot handle this' });
|
||||
});
|
||||
|
||||
return app;
|
||||
return initializeServerHelper(getConf(configName), [apiMiddleware], Storage);
|
||||
}
|
||||
|
||||
export function publishVersion(app, _configFile, pkgName, version): supertest.Test {
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, version);
|
||||
export function createUser(app, name: string, password: string): supertest.Test {
|
||||
return supertest(app)
|
||||
.put(`/-/user/org.couchdb.user:${name}`)
|
||||
.send({
|
||||
name: name,
|
||||
password: password,
|
||||
})
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.CREATED);
|
||||
}
|
||||
|
||||
export async function getNewToken(app: any, credentials: any): Promise<string> {
|
||||
const response = await createUser(app, credentials.name, credentials.password);
|
||||
const { token, ok } = response.body;
|
||||
expect(ok).toBeDefined();
|
||||
expect(token).toBeDefined();
|
||||
expect(typeof token).toBe('string');
|
||||
return token;
|
||||
}
|
||||
|
||||
export async function generateTokenCLI(app, token, payload): Promise<any> {
|
||||
return supertest(app)
|
||||
.post('/-/npm/v1/tokens')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify(payload))
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET);
|
||||
}
|
||||
|
||||
export async function deleteTokenCLI(app, token, tokenToDelete): Promise<any> {
|
||||
return supertest(app)
|
||||
.delete(`/-/npm/v1/tokens/token/${tokenToDelete}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
}
|
||||
|
||||
export function publishVersionWithToken(
|
||||
app,
|
||||
pkgName: string,
|
||||
version: string,
|
||||
token: string,
|
||||
distTags?: GenericBody
|
||||
): supertest.Test {
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, version, distTags);
|
||||
|
||||
return supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
|
||||
.send(JSON.stringify(pkgMetadata))
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
||||
}
|
||||
|
||||
export function publishVersion(
|
||||
app,
|
||||
pkgName: string,
|
||||
version: string,
|
||||
distTags?: GenericBody
|
||||
): supertest.Test {
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, version, distTags);
|
||||
|
||||
return supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify(pkgMetadata))
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON);
|
||||
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
||||
}
|
||||
|
||||
export async function publishTaggedVersion(
|
||||
app,
|
||||
configFile,
|
||||
pkgName: string,
|
||||
version: string,
|
||||
tag: string
|
||||
) {
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, version, {
|
||||
[tag]: version,
|
||||
});
|
||||
|
||||
export function getDisTags(app, pkgName) {
|
||||
return supertest(app)
|
||||
.put(
|
||||
`/${encodeURIComponent(pkgName)}/${encodeURIComponent(version)}/-tag/${encodeURIComponent(
|
||||
tag
|
||||
)}`
|
||||
)
|
||||
.get(`/-/package/${encodeURIComponent(pkgName)}/dist-tags`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify(pkgMetadata))
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON);
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
}
|
||||
|
||||
export function getPackage(
|
||||
app: any,
|
||||
token: string,
|
||||
pkgName: string,
|
||||
statusCode: number = HTTP_STATUS.OK
|
||||
): supertest.Test {
|
||||
const test = supertest(app).get(`/${pkgName}`);
|
||||
|
||||
if (_.isNil(token) === false || _.isEmpty(token) === false) {
|
||||
test.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token));
|
||||
}
|
||||
|
||||
return test.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET).expect(statusCode);
|
||||
}
|
||||
|
||||
25
packages/api/test/integration/config/distTag.yaml
Normal file
25
packages/api/test/integration/config/distTag.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
storage: ./storage
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd-distTag
|
||||
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
|
||||
publish:
|
||||
allow_offline: false
|
||||
|
||||
uplinks:
|
||||
|
||||
log: { type: stdout, format: pretty, level: trace }
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $anonymous
|
||||
publish: $anonymous
|
||||
'**':
|
||||
access: $anonymous
|
||||
publish: $anonymous
|
||||
_debug: true
|
||||
@@ -1,13 +1,8 @@
|
||||
store:
|
||||
memory:
|
||||
limit: 1000
|
||||
storage: ./storage
|
||||
|
||||
auth:
|
||||
auth-memory:
|
||||
users:
|
||||
test:
|
||||
name: test
|
||||
password: test
|
||||
htpasswd:
|
||||
file: ./htpasswd-package
|
||||
|
||||
web:
|
||||
enable: true
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
store:
|
||||
memory:
|
||||
limit: 10
|
||||
|
||||
auth:
|
||||
auth-memory:
|
||||
users:
|
||||
htpasswd:
|
||||
file: ./htpasswd-ping
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
|
||||
26
packages/api/test/integration/config/publish-proxy.yaml
Normal file
26
packages/api/test/integration/config/publish-proxy.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd-publish-proxy
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
|
||||
log: { type: stdout, format: pretty, level: trace }
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $anonymous
|
||||
unpublish: $anonymous
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: $all
|
||||
publish: $anonymous
|
||||
unpublish: $anonymous
|
||||
proxy: npmjs
|
||||
|
||||
_debug: true
|
||||
@@ -1,14 +1,6 @@
|
||||
store:
|
||||
memory:
|
||||
limit: 1000
|
||||
|
||||
auth:
|
||||
auth-memory:
|
||||
users:
|
||||
test:
|
||||
name: test
|
||||
password: test
|
||||
|
||||
htpasswd:
|
||||
file: ./htpasswd-publish
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
@@ -24,7 +16,9 @@ packages:
|
||||
'@*/*':
|
||||
access: $anonymous
|
||||
publish: $anonymous
|
||||
unpublish: $anonymous
|
||||
'**':
|
||||
access: $anonymous
|
||||
publish: $anonymous
|
||||
unpublish: $anonymous
|
||||
_debug: true
|
||||
|
||||
29
packages/api/test/integration/config/search.yaml
Normal file
29
packages/api/test/integration/config/search.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
storage: ./storage
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd-search
|
||||
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
|
||||
uplinks:
|
||||
|
||||
log: { type: stdout, format: pretty, level: trace }
|
||||
|
||||
packages:
|
||||
'private-*':
|
||||
access: $all
|
||||
publish: jota
|
||||
'@private/*':
|
||||
access: $all
|
||||
publish: jota
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
|
||||
_debug: true
|
||||
@@ -1,6 +1,3 @@
|
||||
storage: ./storage
|
||||
plugins: ./plugins
|
||||
|
||||
security:
|
||||
api:
|
||||
jwt:
|
||||
@@ -9,6 +6,8 @@ security:
|
||||
# to avoid invalid verification token, more info on JWT page
|
||||
notBefore: 0
|
||||
|
||||
storage: ./storage
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
@@ -20,7 +19,9 @@ packages:
|
||||
'only-you-can-publish':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
log: { type: stdout, format: pretty, level: warn }
|
||||
|
||||
log: { type: stdout, format: pretty, level: debug }
|
||||
|
||||
## enable token for testing
|
||||
flags:
|
||||
## enable token for testing
|
||||
token: true
|
||||
19
packages/api/test/integration/config/token.yaml
Normal file
19
packages/api/test/integration/config/token.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
storage: ./storage
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
|
||||
packages:
|
||||
'@token/*':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
'only-you-can-publish':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
|
||||
log: { type: stdout, format: pretty, level: debug }
|
||||
|
||||
## enable token for testing
|
||||
flags:
|
||||
token: true
|
||||
@@ -8,6 +8,10 @@ auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
|
||||
uplinks:
|
||||
ver:
|
||||
url: https://registry.verdaccio.org
|
||||
|
||||
security:
|
||||
api:
|
||||
jwt:
|
||||
@@ -18,18 +22,16 @@ packages:
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: remote
|
||||
'vue':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
proxy: remote
|
||||
proxy: ver
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: remote
|
||||
|
||||
middlewares:
|
||||
audit:
|
||||
enabled: true
|
||||
|
||||
log: { type: stdout, format: pretty, level: warn }
|
||||
log: { type: stdout, format: pretty, level: info }
|
||||
@@ -1,21 +1,13 @@
|
||||
store:
|
||||
memory:
|
||||
limit: 1000
|
||||
|
||||
auth:
|
||||
auth-memory:
|
||||
users:
|
||||
test:
|
||||
name: test
|
||||
password: test
|
||||
|
||||
htpasswd:
|
||||
file: ./htpasswd-user
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
ver:
|
||||
url: https://registry.verdaccio.org
|
||||
|
||||
log: { type: stdout, format: pretty, level: trace }
|
||||
|
||||
@@ -24,13 +16,15 @@ packages:
|
||||
access: $all
|
||||
publish: $all
|
||||
unpublish: $all
|
||||
proxy: npmjs
|
||||
'verdaccio':
|
||||
access: $all
|
||||
publish: $all
|
||||
'vue':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
proxy: ver
|
||||
'**':
|
||||
access: $all
|
||||
publish: $all
|
||||
unpublish: $all
|
||||
proxy: npmjs
|
||||
_debug: true
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
store:
|
||||
memory:
|
||||
limit: 1000
|
||||
|
||||
auth:
|
||||
auth-memory:
|
||||
users:
|
||||
test:
|
||||
name: test
|
||||
password: test
|
||||
|
||||
web:
|
||||
enable: true
|
||||
title: verdaccio
|
||||
@@ -19,6 +8,10 @@ uplinks:
|
||||
|
||||
log: { type: stdout, format: pretty, level: trace }
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd-whoami
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $all
|
||||
|
||||
76
packages/api/test/integration/distTag.spec.ts
Normal file
76
packages/api/test/integration/distTag.spec.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { API_MESSAGE, HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
|
||||
|
||||
import { getDisTags, initializeServer, publishVersion } from './_helper';
|
||||
|
||||
describe('package', () => {
|
||||
let app;
|
||||
beforeEach(async () => {
|
||||
app = await initializeServer('distTag.yaml');
|
||||
});
|
||||
|
||||
test.each([['foo'], ['@scope/foo']])('should display dist-tag (npm dist-tag ls)', async (pkg) => {
|
||||
await publishVersion(app, pkg, '1.0.0');
|
||||
await publishVersion(app, pkg, '1.0.1');
|
||||
const response = await getDisTags(app, pkg);
|
||||
expect(response.body).toEqual({ latest: '1.0.1' });
|
||||
});
|
||||
|
||||
test('should add a version to a tag (npm dist-tag add)', async () => {
|
||||
await publishVersion(app, encodeURIComponent('foo'), '1.0.0');
|
||||
await publishVersion(app, encodeURIComponent('foo'), '1.0.1');
|
||||
|
||||
const response = await supertest(app)
|
||||
.put(`/${encodeURIComponent('foo')}/test`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.GZIP)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify('1.0.1'))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.CREATED);
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.TAG_ADDED);
|
||||
const response2 = await getDisTags(app, 'foo');
|
||||
expect(response2.body).toEqual({ latest: '1.0.1', test: '1.0.1' });
|
||||
});
|
||||
|
||||
test('should fails if a version is missing (npm dist-tag add)', async () => {
|
||||
await publishVersion(app, encodeURIComponent('foo'), '1.0.0');
|
||||
await publishVersion(app, encodeURIComponent('foo'), '1.0.1');
|
||||
|
||||
await supertest(app)
|
||||
.put(`/${encodeURIComponent('foo')}/test`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.GZIP)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify({}))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.BAD_REQUEST);
|
||||
});
|
||||
|
||||
test('should delete a previous added tag (npm dist-tag rm)', async () => {
|
||||
await publishVersion(app, encodeURIComponent('foo'), '1.0.0');
|
||||
await publishVersion(app, encodeURIComponent('foo'), '1.0.1');
|
||||
|
||||
const response = await supertest(app)
|
||||
.put(`/${encodeURIComponent('foo')}/beta`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.GZIP)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify('1.0.1'))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.CREATED);
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.TAG_ADDED);
|
||||
|
||||
const response2 = await getDisTags(app, 'foo');
|
||||
expect(response2.body).toEqual({ latest: '1.0.1', beta: '1.0.1' });
|
||||
|
||||
const response3 = await supertest(app)
|
||||
.delete(`/-/package/${encodeURIComponent('foo')}/dist-tags/beta`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.CREATED);
|
||||
expect(response3.body.ok).toEqual(API_MESSAGE.TAG_REMOVED);
|
||||
|
||||
const response4 = await getDisTags(app, 'foo');
|
||||
expect(response4.body).toEqual({ latest: '1.0.1' });
|
||||
});
|
||||
});
|
||||
@@ -1,91 +1,105 @@
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
|
||||
import { DIST_TAGS, HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
|
||||
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
||||
import { initializeServer, publishTaggedVersion, publishVersion } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
jest.mock('@verdaccio/auth', () => ({
|
||||
Auth: class {
|
||||
apiJWTmiddleware() {
|
||||
return mockApiJWTmiddleware();
|
||||
}
|
||||
allow_access(_d, _f, cb) {
|
||||
// always allow access
|
||||
cb(null, true);
|
||||
}
|
||||
allow_publish(_d, _f, cb) {
|
||||
// always allow publish
|
||||
cb(null, true);
|
||||
}
|
||||
},
|
||||
}));
|
||||
import { initializeServer, publishVersion } from './_helper';
|
||||
|
||||
describe('package', () => {
|
||||
let app;
|
||||
beforeEach(async () => {
|
||||
app = await initializeServer('package.yaml');
|
||||
});
|
||||
|
||||
test('should return a package', async () => {
|
||||
await publishVersion(app, 'package.yaml', 'foo', '1.0.0');
|
||||
return new Promise((resolve) => {
|
||||
supertest(app)
|
||||
.get('/foo')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.then((response) => {
|
||||
expect(response.body.name).toEqual('foo');
|
||||
resolve(response);
|
||||
});
|
||||
describe('get tarball', () => {
|
||||
let app;
|
||||
beforeEach(async () => {
|
||||
app = await initializeServer('package.yaml');
|
||||
});
|
||||
});
|
||||
|
||||
test('should return a package by version', async () => {
|
||||
await publishVersion(app, 'package.yaml', 'foo2', '1.0.0');
|
||||
return new Promise((resolve) => {
|
||||
supertest(app)
|
||||
.get('/foo2/1.0.0')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.then((response) => {
|
||||
expect(response.body.name).toEqual('foo2');
|
||||
resolve(response);
|
||||
});
|
||||
test.each([
|
||||
['foo', 'foo-1.0.0.tgz'],
|
||||
['@scope/foo', 'foo-1.0.0.tgz'],
|
||||
])('should return a file tarball', async (pkg, fileName) => {
|
||||
await publishVersion(app, pkg, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.get(`/${pkg}/-/${fileName}`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.OCTET_STREAM)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(Buffer.from(response.body).toString('utf8')).toBeDefined();
|
||||
});
|
||||
|
||||
test.each([
|
||||
['foo', 'foo-1.0.0.tgz'],
|
||||
['@scope/foo', 'foo-1.0.0.tgz'],
|
||||
])('should fails if tarball does not exist', async (pkg, fileName) => {
|
||||
await publishVersion(app, pkg, '1.0.1');
|
||||
return await supertest(app)
|
||||
.get(`/${pkg}/-/${fileName}`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.OCTET_STREAM)
|
||||
.expect(HTTP_STATUS.NOT_FOUND);
|
||||
});
|
||||
test.todo('check content length file header');
|
||||
test.todo('fails on file was aborted');
|
||||
});
|
||||
|
||||
// FIXME: investigate the 404
|
||||
test.skip('should return a package by dist-tag', async (done) => {
|
||||
// await publishVersion(app, 'package.yaml', 'foo3', '1.0.0');
|
||||
await publishVersion(app, 'package.yaml', 'foo-tagged', '1.0.0');
|
||||
await publishTaggedVersion(app, 'package.yaml', 'foo-tagged', '1.0.1', 'test');
|
||||
return supertest(app)
|
||||
.get('/foo-tagged/1.0.1')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.name).toEqual('foo3');
|
||||
done();
|
||||
});
|
||||
});
|
||||
describe('get package', () => {
|
||||
let app;
|
||||
beforeEach(async () => {
|
||||
app = await initializeServer('package.yaml');
|
||||
});
|
||||
|
||||
test('should return 404', async () => {
|
||||
return supertest(app)
|
||||
.get('/404-not-found')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.NOT_FOUND);
|
||||
test.each([['foo'], ['@scope/foo']])('should return a foo private package', async (pkg) => {
|
||||
await publishVersion(app, pkg, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.get(`/${pkg}`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body.name).toEqual(pkg);
|
||||
});
|
||||
|
||||
test.each([['foo'], ['@scope/foo']])(
|
||||
'should return a foo private package by version',
|
||||
async (pkg) => {
|
||||
await publishVersion(app, pkg, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.get(`/${pkg}`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body.name).toEqual(pkg);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['foo'], ['@scope/foo']])(
|
||||
'should return a foo private package by version',
|
||||
async (pkg) => {
|
||||
await publishVersion(app, pkg, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.get(`/${pkg}`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body.name).toEqual(pkg);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['foo-abbreviated'], ['@scope/foo-abbreviated']])(
|
||||
'should return abbreviated local manifest',
|
||||
async (pkg) => {
|
||||
await publishVersion(app, pkg, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.get(`/${pkg}`)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.set(HEADERS.ACCEPT, Storage.ABBREVIATED_HEADER)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body.name).toEqual(pkg);
|
||||
expect(response.body.time).toBeDefined();
|
||||
expect(response.body.modified).toBeDefined();
|
||||
expect(response.body[DIST_TAGS]).toEqual({ latest: '1.0.0' });
|
||||
expect(response.body.readme).not.toBeDefined();
|
||||
expect(response.body._rev).not.toBeDefined();
|
||||
expect(response.body.users).not.toBeDefined();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,11 +6,12 @@ import { initializeServer } from './_helper';
|
||||
|
||||
describe('ping', () => {
|
||||
test('should return the reply the ping', async () => {
|
||||
return supertest(await initializeServer('ping.yaml'))
|
||||
const app = await initializeServer('ping.yaml');
|
||||
const response = await supertest(app)
|
||||
.get('/-/ping')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.then((response) => expect(response.body).toEqual({}));
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import nock from 'nock';
|
||||
import { basename } from 'path';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { HTTP_STATUS } from '@verdaccio/core';
|
||||
import { API_ERROR, API_MESSAGE, HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
||||
import { generatePackageMetadata } from '@verdaccio/test-helper';
|
||||
import { generatePackageMetadata, generateRemotePackageMetadata } from '@verdaccio/test-helper';
|
||||
|
||||
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
||||
import { initializeServer, publishVersion } from './_helper';
|
||||
import { getPackage, initializeServer, publishVersion } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() =>
|
||||
@@ -33,36 +35,13 @@ jest.mock('@verdaccio/auth', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// const mockStorage = jest.fn(() => {
|
||||
// const { Storage } = jest.requireActual('@verdaccio/store');
|
||||
// return {
|
||||
// Storage: class extends Storage {
|
||||
// addPackage(name, metadata, cb) {
|
||||
// super.addPackage(name, metadata, cb);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
|
||||
// jest.mock('@verdaccio/store', () => {
|
||||
// const { Storage } = jest.requireActual('@verdaccio/store');
|
||||
// return ({
|
||||
// Storage: class extends Storage {
|
||||
// addPackage(name, metadata, cb) {
|
||||
// // super.addPackage(name, metadata, cb);
|
||||
// return mockStorage(name, metadata, cb);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// });
|
||||
|
||||
describe('publish', () => {
|
||||
describe('handle invalid publish formats', () => {
|
||||
describe('handle errors', () => {
|
||||
const pkgName = 'test';
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, '1.0.0');
|
||||
test.skip('should fail on publish a bad _attachments package', async (done) => {
|
||||
test('should fail on publish a bad _attachments package', async () => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return supertest(app)
|
||||
const response = await supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
@@ -73,12 +52,8 @@ describe('publish', () => {
|
||||
)
|
||||
)
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.expect(HTTP_STATUS.BAD_REQUEST)
|
||||
.then((response) => {
|
||||
console.log('response.body', response.body);
|
||||
expect(response.body.error).toEqual(API_ERROR.UNSUPORTED_REGISTRY_CALL);
|
||||
done();
|
||||
});
|
||||
.expect(HTTP_STATUS.BAD_REQUEST);
|
||||
expect(response.body.error).toEqual(API_ERROR.UNSUPORTED_REGISTRY_CALL);
|
||||
});
|
||||
|
||||
test('should fail on publish a bad versions package', async () => {
|
||||
@@ -97,7 +72,6 @@ describe('publish', () => {
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.expect(HTTP_STATUS.BAD_REQUEST)
|
||||
.then((response) => {
|
||||
console.log('response.body', response.body);
|
||||
expect(response.body.error).toEqual(API_ERROR.UNSUPORTED_REGISTRY_CALL);
|
||||
resolve(response);
|
||||
});
|
||||
@@ -106,94 +80,179 @@ describe('publish', () => {
|
||||
});
|
||||
|
||||
describe('publish a package', () => {
|
||||
test('should publish a package', async () => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return new Promise((resolve) => {
|
||||
publishVersion(app, 'publish.yaml', 'foo', '1.0.0')
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should publish a new package', async () => {
|
||||
const pkgName = 'test';
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, '1.0.0');
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return new Promise((resolve) => {
|
||||
supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify(
|
||||
Object.assign({}, pkgMetadata, {
|
||||
_attachments: null,
|
||||
})
|
||||
)
|
||||
)
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should publish a new package with no readme', async () => {
|
||||
const pkgName = 'test';
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, '1.0.0');
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return new Promise((resolve) => {
|
||||
supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify(
|
||||
Object.assign({}, pkgMetadata, {
|
||||
versions: {
|
||||
['1.0.0']: {
|
||||
readme: null,
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
)
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should fails on publish a duplicated package', async () => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
await publishVersion(app, 'publish.yaml', 'foo', '1.0.0');
|
||||
return new Promise((resolve) => {
|
||||
publishVersion(app, 'publish.yaml', 'foo', '1.0.0')
|
||||
.expect(HTTP_STATUS.CONFLICT)
|
||||
.then((response) => {
|
||||
console.log('response.body', response.body);
|
||||
expect(response.body.error).toEqual(API_ERROR.PACKAGE_EXIST);
|
||||
resolve(response);
|
||||
describe('no proxies setup', () => {
|
||||
test.each([['foo', '@scope/foo']])('should publish a package', async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return new Promise((resolve) => {
|
||||
publishVersion(app, pkgName, '1.0.0')
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.each([['foo', '@scope/foo']])('should publish a new package', async (pkgName) => {
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, '1.0.0');
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return new Promise((resolve) => {
|
||||
supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(JSON.stringify(Object.assign({}, pkgMetadata)))
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should publish a new package with no readme', async () => {
|
||||
const pkgName = 'test';
|
||||
const pkgMetadata = generatePackageMetadata(pkgName, '1.0.0');
|
||||
const app = await initializeServer('publish.yaml');
|
||||
return new Promise((resolve) => {
|
||||
supertest(app)
|
||||
.put(`/${encodeURIComponent(pkgName)}`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify(
|
||||
Object.assign({}, pkgMetadata, {
|
||||
versions: {
|
||||
['1.0.0']: {
|
||||
readme: null,
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
)
|
||||
.set('accept', HEADERS.GZIP)
|
||||
.expect(HTTP_STATUS.CREATED)
|
||||
.then((response) => {
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('proxies setup', () => {
|
||||
test.each([['foo', '@scope%2Ffoo']])(
|
||||
'should publish a a patch package that already exist on a remote',
|
||||
async (pkgName) => {
|
||||
const upstreamManifest = generateRemotePackageMetadata(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
'https://registry.npmjs.org',
|
||||
['1.0.1', '1.0.2', '1.0.3']
|
||||
);
|
||||
nock('https://registry.npmjs.org').get(`/${pkgName}`).reply(200, upstreamManifest);
|
||||
const app = await initializeServer('publish-proxy.yaml');
|
||||
const manifest = await getPackage(app, '', decodeURIComponent(pkgName));
|
||||
expect(manifest.body.name).toEqual(decodeURIComponent(pkgName));
|
||||
const response = await publishVersion(
|
||||
app,
|
||||
decodeURIComponent(pkgName),
|
||||
'1.0.1-patch'
|
||||
).expect(HTTP_STATUS.CREATED);
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
const response2 = await publishVersion(
|
||||
app,
|
||||
decodeURIComponent(pkgName),
|
||||
'1.0.2-patch'
|
||||
).expect(HTTP_STATUS.CREATED);
|
||||
expect(response2.body.ok).toEqual(API_MESSAGE.PKG_CREATED);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.each([['foo', '@scope/foo']])(
|
||||
'should fails on publish a duplicated package',
|
||||
async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
await publishVersion(app, pkgName, '1.0.0');
|
||||
return new Promise((resolve) => {
|
||||
publishVersion(app, pkgName, '1.0.0')
|
||||
.expect(HTTP_STATUS.CONFLICT)
|
||||
.then((response) => {
|
||||
expect(response.body.error).toEqual(API_ERROR.PACKAGE_EXIST);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
describe('unpublish a package', () => {
|
||||
let app;
|
||||
|
||||
beforeEach(async () => {
|
||||
app = await initializeServer('publish.yaml');
|
||||
await publishVersion(app, 'publish.yaml', 'foo', '1.0.0');
|
||||
test.each([['foo', '@scope/foo']])('should unpublish entirely a package', async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
await publishVersion(app, pkgName, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
// FIXME: should be filtered by revision to avoid
|
||||
// conflicts
|
||||
.delete(`/${encodeURIComponent(pkgName)}/-rev/xxx`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HTTP_STATUS.CREATED);
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.PKG_REMOVED);
|
||||
// package should be completely un published
|
||||
await supertest(app)
|
||||
.get(`/${pkgName}`)
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.NOT_FOUND);
|
||||
});
|
||||
|
||||
test('should unpublish a package', () => {});
|
||||
test.each([['foo', '@scope/foo']])(
|
||||
'should fails unpublish entirely a package',
|
||||
async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
const response = await supertest(app)
|
||||
.delete(`/${encodeURIComponent(pkgName)}/-rev/1cf3-fe3`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HTTP_STATUS.NOT_FOUND);
|
||||
expect(response.body.error).toEqual(API_ERROR.NO_PACKAGE);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['foo', '@scope/foo']])(
|
||||
'should fails remove a tarball of a package does not exist',
|
||||
async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
const response = await supertest(app)
|
||||
.delete(`/${pkgName}/-/${basename(pkgName)}-1.0.3.tgz/-rev/revision`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HTTP_STATUS.NOT_FOUND);
|
||||
expect(response.body.error).toEqual(API_ERROR.NO_PACKAGE);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['foo', '@scope/foo']])(
|
||||
'should fails on try remove a tarball does not exist',
|
||||
async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
await publishVersion(app, pkgName, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.delete(`/${pkgName}/-/${basename(pkgName)}-1.0.3.tgz/-rev/revision`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HTTP_STATUS.NOT_FOUND);
|
||||
expect(response.body.error).toEqual(API_ERROR.NO_SUCH_FILE);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['foo', '@scope/foo']])(
|
||||
'should remove a tarball that does exist',
|
||||
async (pkgName) => {
|
||||
const app = await initializeServer('publish.yaml');
|
||||
await publishVersion(app, pkgName, '1.0.0');
|
||||
const response = await supertest(app)
|
||||
.delete(`/${pkgName}/-/${basename(pkgName)}-1.0.0.tgz/-rev/revision`)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HTTP_STATUS.CREATED);
|
||||
expect(response.body.ok).toEqual(API_MESSAGE.TARBALL_REMOVED);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('star a package', () => {});
|
||||
|
||||
126
packages/api/test/integration/search.spec.ts
Normal file
126
packages/api/test/integration/search.spec.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import MockDate from 'mockdate';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
|
||||
|
||||
import { createUser, initializeServer, publishVersionWithToken } from './_helper';
|
||||
|
||||
describe('search', () => {
|
||||
let app;
|
||||
beforeEach(async () => {
|
||||
app = await initializeServer('search.yaml');
|
||||
});
|
||||
|
||||
describe('search authenticated', () => {
|
||||
test.each([['foo']])('should return a foo private package', async (pkg) => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const res = await createUser(app, 'test', 'test');
|
||||
await publishVersionWithToken(app, pkg, '1.0.0', res.body.token);
|
||||
// this should not be displayed as part of the search
|
||||
await publishVersionWithToken(app, 'private-auth', '1.0.0', res.body.token);
|
||||
const response = await supertest(app)
|
||||
.get(
|
||||
`/-/v1/search?text=${encodeURIComponent(
|
||||
pkg
|
||||
)}&size=2000&from=0&quality=1&popularity=0.1&maintenance=0.1`
|
||||
)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HEADERS.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body).toEqual({
|
||||
objects: [
|
||||
{
|
||||
package: {
|
||||
author: {
|
||||
email: 'user@domain.com',
|
||||
name: 'User NPM',
|
||||
},
|
||||
date: mockDate,
|
||||
description: 'package generated',
|
||||
keywords: [],
|
||||
links: {
|
||||
npm: '',
|
||||
},
|
||||
name: pkg,
|
||||
publisher: {},
|
||||
scope: '',
|
||||
version: '1.0.0',
|
||||
},
|
||||
score: {
|
||||
detail: {
|
||||
maintenance: 0,
|
||||
popularity: 1,
|
||||
quality: 1,
|
||||
},
|
||||
final: 1,
|
||||
},
|
||||
searchScore: 1,
|
||||
verdaccioPkgCached: false,
|
||||
verdaccioPrivate: true,
|
||||
},
|
||||
],
|
||||
time: 'Sun, 14 Jan 2018 11:17:40 GMT',
|
||||
total: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test.each([['@scope/foo']])('should return a scoped foo private package', async (pkg) => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const res = await createUser(app, 'test', 'test');
|
||||
await publishVersionWithToken(app, pkg, '1.0.0', res.body.token);
|
||||
// this should not be displayed as part of the search
|
||||
await publishVersionWithToken(app, '@private/auth', '1.0.0', res.body.token);
|
||||
const response = await supertest(app)
|
||||
.get(
|
||||
`/-/v1/search?text=${encodeURIComponent(
|
||||
pkg
|
||||
)}&size=2000&from=0&quality=1&popularity=0.1&maintenance=0.1`
|
||||
)
|
||||
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.expect(HEADERS.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body).toEqual({
|
||||
objects: [
|
||||
{
|
||||
package: {
|
||||
author: {
|
||||
email: 'user@domain.com',
|
||||
name: 'User NPM',
|
||||
},
|
||||
date: mockDate,
|
||||
description: 'package generated',
|
||||
keywords: [],
|
||||
links: {
|
||||
npm: '',
|
||||
},
|
||||
name: pkg,
|
||||
publisher: {},
|
||||
scope: '@scope',
|
||||
version: '1.0.0',
|
||||
},
|
||||
score: {
|
||||
detail: {
|
||||
maintenance: 0,
|
||||
popularity: 1,
|
||||
quality: 1,
|
||||
},
|
||||
final: 1,
|
||||
},
|
||||
searchScore: 1,
|
||||
verdaccioPkgCached: false,
|
||||
verdaccioPrivate: true,
|
||||
},
|
||||
],
|
||||
time: 'Sun, 14 Jan 2018 11:17:40 GMT',
|
||||
total: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('error handling', () => {
|
||||
test.todo('should able to abort the request');
|
||||
});
|
||||
});
|
||||
124
packages/api/test/integration/token.spec.ts
Normal file
124
packages/api/test/integration/token.spec.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import _ from 'lodash';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import {
|
||||
API_ERROR,
|
||||
HEADERS,
|
||||
HEADER_TYPE,
|
||||
HTTP_STATUS,
|
||||
SUPPORT_ERRORS,
|
||||
TOKEN_BEARER,
|
||||
} from '@verdaccio/core';
|
||||
import { buildToken } from '@verdaccio/utils';
|
||||
|
||||
import { deleteTokenCLI, generateTokenCLI, getNewToken, initializeServer } from './_helper';
|
||||
|
||||
describe('token', () => {
|
||||
describe('basics', () => {
|
||||
test.each([['token.yaml'], ['token.jwt.yaml']])('should list empty tokens', async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const token = await getNewToken(app, { name: 'jota_token', password: 'secretPass' });
|
||||
const response = await supertest(app)
|
||||
.get('/-/npm/v1/tokens')
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response.body.objects).toHaveLength(0);
|
||||
});
|
||||
|
||||
test.each([['token.yaml'], ['token.jwt.yaml']])('should generate one token', async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'jota_token', password: 'secretPass' };
|
||||
const token = await getNewToken(app, credentials);
|
||||
await generateTokenCLI(app, token, {
|
||||
password: credentials.password,
|
||||
readonly: false,
|
||||
cidr_whitelist: [],
|
||||
});
|
||||
const response = await supertest(app)
|
||||
.get('/-/npm/v1/tokens')
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
const { objects, urls } = response.body;
|
||||
|
||||
expect(objects).toHaveLength(1);
|
||||
const [tokenGenerated] = objects;
|
||||
expect(tokenGenerated.user).toEqual(credentials.name);
|
||||
expect(tokenGenerated.readonly).toBeFalsy();
|
||||
expect(tokenGenerated.token).toMatch(/.../);
|
||||
expect(_.isString(tokenGenerated.created)).toBeTruthy();
|
||||
|
||||
// we don't support pagination yet
|
||||
expect(urls.next).toEqual('');
|
||||
});
|
||||
|
||||
test.each([['token.yaml'], ['token.jwt.yaml']])('should delete a token', async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'jota_token', password: 'secretPass' };
|
||||
const token = await getNewToken(app, credentials);
|
||||
const response = await generateTokenCLI(app, token, {
|
||||
password: credentials.password,
|
||||
readonly: false,
|
||||
cidr_whitelist: [],
|
||||
});
|
||||
|
||||
const key = response.body.key;
|
||||
await deleteTokenCLI(app, token, key);
|
||||
const response2 = await supertest(app)
|
||||
.get('/-/npm/v1/tokens')
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
const { objects } = response2.body;
|
||||
expect(objects).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('handle errors', () => {
|
||||
test.each([['token.yaml'], ['token.jwt.yaml']])('should delete a token', async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'jota_token', password: 'secretPass' };
|
||||
const token = await getNewToken(app, credentials);
|
||||
const resp = await generateTokenCLI(app, token, {
|
||||
password: 'wrongPassword',
|
||||
readonly: false,
|
||||
cidr_whitelist: [],
|
||||
});
|
||||
expect(resp.body.error).toEqual(API_ERROR.BAD_USERNAME_PASSWORD);
|
||||
});
|
||||
|
||||
test.each([['token.yaml'], ['token.jwt.yaml']])(
|
||||
'should fail if readonly is missing',
|
||||
async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'jota_token', password: 'secretPass' };
|
||||
const token = await getNewToken(app, credentials);
|
||||
const resp = await generateTokenCLI(app, token, {
|
||||
password: credentials.password,
|
||||
cidr_whitelist: [],
|
||||
});
|
||||
expect(resp.body.error).toEqual(SUPPORT_ERRORS.PARAMETERS_NOT_VALID);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test.each([['token.yaml'], ['token.jwt.yaml']])(
|
||||
'should fail if cidr_whitelist is missing',
|
||||
async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'jota_token', password: 'secretPass' };
|
||||
const token = await getNewToken(app, credentials);
|
||||
const resp = await generateTokenCLI(app, token, {
|
||||
password: credentials.password,
|
||||
readonly: false,
|
||||
});
|
||||
expect(resp.body.error).toEqual(SUPPORT_ERRORS.PARAMETERS_NOT_VALID);
|
||||
}
|
||||
);
|
||||
|
||||
test.todo('handle failure if delete token');
|
||||
test.todo('handle failure if getApiToken fails');
|
||||
test.todo('handle failure if token creating fails');
|
||||
test.todo('handle failure if token list fails');
|
||||
});
|
||||
78
packages/api/test/integration/user.jwt.spec.ts
Normal file
78
packages/api/test/integration/user.jwt.spec.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { API_ERROR, HEADERS, HEADER_TYPE, HTTP_STATUS, TOKEN_BEARER } from '@verdaccio/core';
|
||||
import { buildToken } from '@verdaccio/utils';
|
||||
|
||||
import { createUser, getPackage, initializeServer } from './_helper';
|
||||
|
||||
const FORBIDDEN_VUE = 'authorization required to access package vue';
|
||||
|
||||
describe('token', () => {
|
||||
describe('basics', () => {
|
||||
const FAKE_TOKEN: string = buildToken(TOKEN_BEARER, 'fake');
|
||||
test.each([['user.yaml'], ['user.jwt.yaml']])('should test add a new user', async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'JotaJWT', password: 'secretPass' };
|
||||
const response = await createUser(app, credentials.name, credentials.password);
|
||||
expect(response.body.ok).toMatch(`user '${credentials.name}' created`);
|
||||
|
||||
const vueResponse = await getPackage(app, response.body.token, 'vue');
|
||||
expect(vueResponse.body).toBeDefined();
|
||||
expect(vueResponse.body.name).toMatch('vue');
|
||||
|
||||
const vueFailResp = await getPackage(app, FAKE_TOKEN, 'vue', HTTP_STATUS.UNAUTHORIZED);
|
||||
expect(vueFailResp.body.error).toMatch(FORBIDDEN_VUE);
|
||||
});
|
||||
|
||||
test.each([['user.yaml'], ['user.jwt.yaml']])('should test add a new user', async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'JotaJWT', password: 'secretPass' };
|
||||
const response = await createUser(app, credentials.name, credentials.password);
|
||||
expect(response.body.ok).toMatch(`user '${credentials.name}' created`);
|
||||
const response2 = await supertest(app)
|
||||
.put(`/-/user/org.couchdb.user:${credentials.name}`)
|
||||
.send({
|
||||
name: credentials.name,
|
||||
password: credentials.password,
|
||||
})
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.CONFLICT);
|
||||
expect(response2.body.error).toBe(API_ERROR.USERNAME_ALREADY_REGISTERED);
|
||||
});
|
||||
|
||||
test.each([['user.yaml'], ['user.jwt.yaml']])(
|
||||
'should fails on login if user credentials are invalid even if jwt',
|
||||
async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'newFailsUser', password: 'secretPass' };
|
||||
const response = await createUser(app, credentials.name, credentials.password);
|
||||
expect(response.body.ok).toMatch(`user '${credentials.name}' created`);
|
||||
const response2 = await supertest(app)
|
||||
.put(`/-/user/org.couchdb.user:${credentials.name}`)
|
||||
.send({
|
||||
name: credentials.name,
|
||||
password: 'BAD_PASSWORD',
|
||||
})
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||
expect(response2.body.error).toBe(API_ERROR.UNAUTHORIZED_ACCESS);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['user.yaml'], ['user.jwt.yaml']])(
|
||||
'should verify if user is logged',
|
||||
async (conf) => {
|
||||
const app = await initializeServer(conf);
|
||||
const credentials = { name: 'jota', password: 'secretPass' };
|
||||
const response = await createUser(app, credentials.name, credentials.password);
|
||||
expect(response.body.ok).toMatch(`user '${credentials.name}' created`);
|
||||
const response2 = await supertest(app)
|
||||
.get(`/-/user/org.couchdb.user:${credentials.name}`)
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
expect(response2.body.ok).toBe(`you are authenticated as '${credentials.name}'`);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -47,6 +47,7 @@ jest.mock('@verdaccio/auth', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// FIXME: This might be covered with user.jwt.spec
|
||||
describe('user', () => {
|
||||
const credentials = { name: 'test', password: 'test' };
|
||||
|
||||
|
||||
@@ -1,53 +1,35 @@
|
||||
import supertest from 'supertest';
|
||||
|
||||
import { HEADERS, HTTP_STATUS } from '@verdaccio/core';
|
||||
import { HEADERS, HTTP_STATUS, TOKEN_BEARER } from '@verdaccio/core';
|
||||
import { buildToken } from '@verdaccio/utils';
|
||||
|
||||
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
||||
import { initializeServer } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
jest.mock('@verdaccio/auth', () => ({
|
||||
Auth: class {
|
||||
apiJWTmiddleware() {
|
||||
return mockApiJWTmiddleware();
|
||||
}
|
||||
allow_access(_d, f_, cb) {
|
||||
cb(null, true);
|
||||
}
|
||||
},
|
||||
}));
|
||||
import { createUser, initializeServer } from './_helper';
|
||||
|
||||
describe('whoami', () => {
|
||||
test.skip('should test referer /whoami endpoint', async (done) => {
|
||||
return supertest(await initializeServer('whoami.yaml'))
|
||||
.get('/whoami')
|
||||
.set('referer', 'whoami')
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.end(done);
|
||||
});
|
||||
|
||||
test.skip('should test no referer /whoami endpoint', async (done) => {
|
||||
return supertest(await initializeServer('whoami.yaml'))
|
||||
.get('/whoami')
|
||||
.expect(HTTP_STATUS.NOT_FOUND)
|
||||
.end(done);
|
||||
});
|
||||
|
||||
test('should return the logged username', async () => {
|
||||
return supertest(await initializeServer('whoami.yaml'))
|
||||
const app = await initializeServer('whoami.yaml');
|
||||
// @ts-expect-error internal property
|
||||
const { _body } = await createUser(app, 'test', 'test');
|
||||
return supertest(app)
|
||||
.get('/-/whoami')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, _body.token))
|
||||
.expect('Content-Type', HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.then((response) => {
|
||||
expect(response.body.username).toEqual('foo');
|
||||
expect(response.body.username).toEqual('test');
|
||||
});
|
||||
});
|
||||
|
||||
test('should fails with 401 if is not logged in', async () => {
|
||||
const app = await initializeServer('whoami.yaml');
|
||||
// @ts-expect-error internal property
|
||||
const { _body } = await createUser(app, 'test', 'test');
|
||||
return supertest(app)
|
||||
.get('/-/whoami')
|
||||
.set('Accept', HEADERS.JSON)
|
||||
.set(HEADERS.AUTHORIZATION, buildToken('invalid-token', _body.token))
|
||||
.expect('Content-Type', HEADERS.JSON_CHARSET)
|
||||
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Publish endpoints - publish package should change the existing package 1`] = `[MockFunction]`;
|
||||
|
||||
exports[`Publish endpoints - publish package should publish a new a new package 1`] = `
|
||||
[MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"verdaccio",
|
||||
Object {
|
||||
"dist-tags": Object {},
|
||||
"name": "verdaccio",
|
||||
"time": Object {},
|
||||
"versions": Object {},
|
||||
},
|
||||
[Function],
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Publish endpoints - publish package test start should star a package 1`] = `
|
||||
[MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"verdaccio",
|
||||
Object {
|
||||
"users": Object {
|
||||
"verdaccio": true,
|
||||
},
|
||||
},
|
||||
"15-e53a77096b0ee33e",
|
||||
[Function],
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
252
packages/api/test/unit/publish.disabled.ts
Normal file
252
packages/api/test/unit/publish.disabled.ts
Normal file
@@ -0,0 +1,252 @@
|
||||
// import { API_ERROR, HTTP_STATUS, errorUtils } from '@verdaccio/core';
|
||||
|
||||
// import { addVersion, publishPackage, removeTarball, unPublishPackage } from '../../src/publish';
|
||||
|
||||
// const REVISION_MOCK = '15-e53a77096b0ee33e';
|
||||
|
||||
// require('@verdaccio/logger').setup([{ type: 'stdout', format: 'pretty', level: 'info' }]);
|
||||
|
||||
// describe('Publish endpoints - add a tag', () => {
|
||||
// let req;
|
||||
// let res;
|
||||
// let next;
|
||||
|
||||
// beforeEach(() => {
|
||||
// req = {
|
||||
// params: {
|
||||
// version: '1.0.0',
|
||||
// tag: 'tag',
|
||||
// package: 'verdaccio',
|
||||
// },
|
||||
// body: '',
|
||||
// };
|
||||
// res = {
|
||||
// status: jest.fn(),
|
||||
// };
|
||||
|
||||
// next = jest.fn();
|
||||
// });
|
||||
|
||||
// test('should add a version', (done) => {
|
||||
// const storage = {
|
||||
// addVersion: (packageName, version, body, tag, cb) => {
|
||||
// expect(packageName).toEqual(req.params.package);
|
||||
// expect(version).toEqual(req.params.version);
|
||||
// expect(body).toEqual(req.body);
|
||||
// expect(tag).toEqual(req.params.tag);
|
||||
// cb();
|
||||
// done();
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// addVersion(storage)(req, res, next);
|
||||
|
||||
// expect(res.status).toHaveBeenLastCalledWith(HTTP_STATUS.CREATED);
|
||||
// expect(next).toHaveBeenLastCalledWith({ ok: 'package published' });
|
||||
// });
|
||||
|
||||
// test('when failed to add a version', (done) => {
|
||||
// const storage = {
|
||||
// addVersion: (packageName, version, body, tag, cb) => {
|
||||
// const error = {
|
||||
// message: 'failure',
|
||||
// };
|
||||
// cb(error);
|
||||
// done();
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// addVersion(storage)(req, res, next);
|
||||
|
||||
// expect(next).toHaveBeenLastCalledWith({ message: 'failure' });
|
||||
// });
|
||||
// });
|
||||
|
||||
// /**
|
||||
// * Delete tarball: '/:package/-/:filename/-rev/:revision'
|
||||
// */
|
||||
// describe('Publish endpoints - delete tarball', () => {
|
||||
// let req;
|
||||
// let res;
|
||||
// let next;
|
||||
|
||||
// beforeEach(() => {
|
||||
// req = {
|
||||
// params: {
|
||||
// filename: 'verdaccio.gzip',
|
||||
// package: 'verdaccio',
|
||||
// revision: REVISION_MOCK,
|
||||
// },
|
||||
// };
|
||||
// res = { status: jest.fn() };
|
||||
// next = jest.fn();
|
||||
// });
|
||||
|
||||
// test('should delete tarball successfully', (done) => {
|
||||
// const storage = {
|
||||
// removeTarball(packageName, filename, revision, cb) {
|
||||
// expect(packageName).toEqual(req.params.package);
|
||||
// expect(filename).toEqual(req.params.filename);
|
||||
// expect(revision).toEqual(req.params.revision);
|
||||
// cb();
|
||||
// done();
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// removeTarball(storage)(req, res, next);
|
||||
// expect(res.status).toHaveBeenCalledWith(HTTP_STATUS.CREATED);
|
||||
// expect(next).toHaveBeenCalledWith({ ok: 'tarball removed' });
|
||||
// });
|
||||
|
||||
// test('failed while deleting the tarball', (done) => {
|
||||
// const error = {
|
||||
// message: 'deletion failed',
|
||||
// };
|
||||
// const storage = {
|
||||
// removeTarball(packageName, filename, revision, cb) {
|
||||
// cb(error);
|
||||
// done();
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// removeTarball(storage)(req, res, next);
|
||||
// expect(next).toHaveBeenCalledWith(error);
|
||||
// });
|
||||
// });
|
||||
|
||||
// /**
|
||||
// * Un-publish package: '/:package/-rev/*'
|
||||
// */
|
||||
// describe('Publish endpoints - un-publish package', () => {
|
||||
// let req;
|
||||
// let res;
|
||||
// let next;
|
||||
|
||||
// beforeEach(() => {
|
||||
// req = {
|
||||
// params: {
|
||||
// package: 'verdaccio',
|
||||
// },
|
||||
// };
|
||||
// res = { status: jest.fn() };
|
||||
// next = jest.fn();
|
||||
// });
|
||||
|
||||
// test('should un-publish package successfully', async () => {
|
||||
// const storage = {
|
||||
// removePackage(packageName) {
|
||||
// expect(packageName).toEqual(req.params.package);
|
||||
// return Promise.resolve();
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// await unPublishPackage(storage)(req, res, next);
|
||||
// expect(res.status).toHaveBeenCalledWith(HTTP_STATUS.CREATED);
|
||||
// expect(next).toHaveBeenCalledWith({ ok: 'package removed' });
|
||||
// });
|
||||
|
||||
// test('un-publish failed', async () => {
|
||||
// const storage = {
|
||||
// removePackage(packageName) {
|
||||
// expect(packageName).toEqual(req.params.package);
|
||||
// return Promise.reject(errorUtils.getInternalError());
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// await unPublishPackage(storage)(req, res, next);
|
||||
// expect(next).toHaveBeenCalledWith(errorUtils.getInternalError());
|
||||
// });
|
||||
// });
|
||||
|
||||
// /**
|
||||
// * Publish package: '/:package/:_rev?/:revision?'
|
||||
// */
|
||||
// describe('Publish endpoints - publish package', () => {
|
||||
// let req;
|
||||
// let res;
|
||||
// let next;
|
||||
|
||||
// beforeEach(() => {
|
||||
// req = {
|
||||
// body: {
|
||||
// name: 'verdaccio',
|
||||
// },
|
||||
// params: {
|
||||
// package: 'verdaccio',
|
||||
// },
|
||||
// };
|
||||
// res = { status: jest.fn() };
|
||||
// next = jest.fn();
|
||||
// });
|
||||
|
||||
// test('should change the existing package', () => {
|
||||
// const storage = {
|
||||
// changePackage: jest.fn(),
|
||||
// };
|
||||
|
||||
// req.params._rev = REVISION_MOCK;
|
||||
|
||||
// // @ts-ignore
|
||||
// publishPackage(storage)(req, res, next);
|
||||
// expect(storage.changePackage).toMatchSnapshot();
|
||||
// });
|
||||
|
||||
// test('should publish a new a new package', () => {
|
||||
// const storage = {
|
||||
// addPackage: jest.fn(),
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// publishPackage(storage)(req, res, next);
|
||||
// expect(storage.addPackage).toMatchSnapshot();
|
||||
// });
|
||||
|
||||
// test('should throw an error while publishing package', () => {
|
||||
// const storage = {
|
||||
// addPackage() {
|
||||
// throw new Error();
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// publishPackage(storage)(req, res, next);
|
||||
// expect(next).toHaveBeenCalledWith(new Error(API_ERROR.BAD_PACKAGE_DATA));
|
||||
// });
|
||||
|
||||
// describe('test start', () => {
|
||||
// test('should star a package', () => {
|
||||
// const storage = {
|
||||
// changePackage: jest.fn(),
|
||||
// getPackage({ callback }) {
|
||||
// callback(null, {
|
||||
// users: {},
|
||||
// });
|
||||
// },
|
||||
// };
|
||||
// req = {
|
||||
// params: {
|
||||
// package: 'verdaccio',
|
||||
// },
|
||||
// body: {
|
||||
// _rev: REVISION_MOCK,
|
||||
// users: {
|
||||
// verdaccio: true,
|
||||
// },
|
||||
// },
|
||||
// remote_user: {
|
||||
// name: 'verdaccio',
|
||||
// },
|
||||
// };
|
||||
|
||||
// // @ts-ignore
|
||||
// publishPackage(storage)(req, res, next);
|
||||
// expect(storage.changePackage).toMatchSnapshot();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
@@ -1,300 +0,0 @@
|
||||
import { API_ERROR, HTTP_STATUS, errorUtils } from '@verdaccio/core';
|
||||
|
||||
import {
|
||||
addVersion,
|
||||
publishPackage,
|
||||
removeTarball,
|
||||
unPublishPackage,
|
||||
uploadPackageTarball,
|
||||
} from '../../src/publish';
|
||||
|
||||
const REVISION_MOCK = '15-e53a77096b0ee33e';
|
||||
|
||||
require('@verdaccio/logger').setup([{ type: 'stdout', format: 'pretty', level: 'info' }]);
|
||||
|
||||
describe('Publish endpoints - add a tag', () => {
|
||||
let req;
|
||||
let res;
|
||||
let next;
|
||||
|
||||
beforeEach(() => {
|
||||
req = {
|
||||
params: {
|
||||
version: '1.0.0',
|
||||
tag: 'tag',
|
||||
package: 'verdaccio',
|
||||
},
|
||||
body: '',
|
||||
};
|
||||
res = {
|
||||
status: jest.fn(),
|
||||
};
|
||||
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
test('should add a version', (done) => {
|
||||
const storage = {
|
||||
addVersion: (packageName, version, body, tag, cb) => {
|
||||
expect(packageName).toEqual(req.params.package);
|
||||
expect(version).toEqual(req.params.version);
|
||||
expect(body).toEqual(req.body);
|
||||
expect(tag).toEqual(req.params.tag);
|
||||
cb();
|
||||
done();
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
addVersion(storage)(req, res, next);
|
||||
|
||||
expect(res.status).toHaveBeenLastCalledWith(HTTP_STATUS.CREATED);
|
||||
expect(next).toHaveBeenLastCalledWith({ ok: 'package published' });
|
||||
});
|
||||
|
||||
test('when failed to add a version', (done) => {
|
||||
const storage = {
|
||||
addVersion: (packageName, version, body, tag, cb) => {
|
||||
const error = {
|
||||
message: 'failure',
|
||||
};
|
||||
cb(error);
|
||||
done();
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
addVersion(storage)(req, res, next);
|
||||
|
||||
expect(next).toHaveBeenLastCalledWith({ message: 'failure' });
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* upload package: '/:package/-/:filename/*'
|
||||
*/
|
||||
describe('Publish endpoints - upload package tarball', () => {
|
||||
let req;
|
||||
let res;
|
||||
let next;
|
||||
|
||||
beforeEach(() => {
|
||||
req = {
|
||||
params: {
|
||||
filename: 'verdaccio.gzip',
|
||||
package: 'verdaccio',
|
||||
},
|
||||
pipe: jest.fn(),
|
||||
on: jest.fn(),
|
||||
};
|
||||
res = { status: jest.fn(), locals: { report_error: jest.fn() } };
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
test('should upload package tarball successfully', () => {
|
||||
const stream = {
|
||||
done: jest.fn(),
|
||||
abort: jest.fn(),
|
||||
on: jest.fn(() => (status, cb) => cb()),
|
||||
};
|
||||
const storage = {
|
||||
addTarball(packageName, filename) {
|
||||
expect(packageName).toEqual(req.params.package);
|
||||
expect(filename).toEqual(req.params.filename);
|
||||
return stream;
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
uploadPackageTarball(storage)(req, res, next);
|
||||
expect(req.pipe).toHaveBeenCalled();
|
||||
expect(req.on).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete tarball: '/:package/-/:filename/-rev/:revision'
|
||||
*/
|
||||
describe('Publish endpoints - delete tarball', () => {
|
||||
let req;
|
||||
let res;
|
||||
let next;
|
||||
|
||||
beforeEach(() => {
|
||||
req = {
|
||||
params: {
|
||||
filename: 'verdaccio.gzip',
|
||||
package: 'verdaccio',
|
||||
revision: REVISION_MOCK,
|
||||
},
|
||||
};
|
||||
res = { status: jest.fn() };
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
test('should delete tarball successfully', (done) => {
|
||||
const storage = {
|
||||
removeTarball(packageName, filename, revision, cb) {
|
||||
expect(packageName).toEqual(req.params.package);
|
||||
expect(filename).toEqual(req.params.filename);
|
||||
expect(revision).toEqual(req.params.revision);
|
||||
cb();
|
||||
done();
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
removeTarball(storage)(req, res, next);
|
||||
expect(res.status).toHaveBeenCalledWith(HTTP_STATUS.CREATED);
|
||||
expect(next).toHaveBeenCalledWith({ ok: 'tarball removed' });
|
||||
});
|
||||
|
||||
test('failed while deleting the tarball', (done) => {
|
||||
const error = {
|
||||
message: 'deletion failed',
|
||||
};
|
||||
const storage = {
|
||||
removeTarball(packageName, filename, revision, cb) {
|
||||
cb(error);
|
||||
done();
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
removeTarball(storage)(req, res, next);
|
||||
expect(next).toHaveBeenCalledWith(error);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Un-publish package: '/:package/-rev/*'
|
||||
*/
|
||||
describe('Publish endpoints - un-publish package', () => {
|
||||
let req;
|
||||
let res;
|
||||
let next;
|
||||
|
||||
beforeEach(() => {
|
||||
req = {
|
||||
params: {
|
||||
package: 'verdaccio',
|
||||
},
|
||||
};
|
||||
res = { status: jest.fn() };
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
test('should un-publish package successfully', async () => {
|
||||
const storage = {
|
||||
removePackage(packageName) {
|
||||
expect(packageName).toEqual(req.params.package);
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
await unPublishPackage(storage)(req, res, next);
|
||||
expect(res.status).toHaveBeenCalledWith(HTTP_STATUS.CREATED);
|
||||
expect(next).toHaveBeenCalledWith({ ok: 'package removed' });
|
||||
});
|
||||
|
||||
test('un-publish failed', async () => {
|
||||
const storage = {
|
||||
removePackage(packageName) {
|
||||
expect(packageName).toEqual(req.params.package);
|
||||
return Promise.reject(errorUtils.getInternalError());
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
await unPublishPackage(storage)(req, res, next);
|
||||
expect(next).toHaveBeenCalledWith(errorUtils.getInternalError());
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Publish package: '/:package/:_rev?/:revision?'
|
||||
*/
|
||||
describe('Publish endpoints - publish package', () => {
|
||||
let req;
|
||||
let res;
|
||||
let next;
|
||||
|
||||
beforeEach(() => {
|
||||
req = {
|
||||
body: {
|
||||
name: 'verdaccio',
|
||||
},
|
||||
params: {
|
||||
package: 'verdaccio',
|
||||
},
|
||||
};
|
||||
res = { status: jest.fn() };
|
||||
next = jest.fn();
|
||||
});
|
||||
|
||||
test('should change the existing package', () => {
|
||||
const storage = {
|
||||
changePackage: jest.fn(),
|
||||
};
|
||||
|
||||
req.params._rev = REVISION_MOCK;
|
||||
|
||||
// @ts-ignore
|
||||
publishPackage(storage)(req, res, next);
|
||||
expect(storage.changePackage).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should publish a new a new package', () => {
|
||||
const storage = {
|
||||
addPackage: jest.fn(),
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
publishPackage(storage)(req, res, next);
|
||||
expect(storage.addPackage).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should throw an error while publishing package', () => {
|
||||
const storage = {
|
||||
addPackage() {
|
||||
throw new Error();
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
publishPackage(storage)(req, res, next);
|
||||
expect(next).toHaveBeenCalledWith(new Error(API_ERROR.BAD_PACKAGE_DATA));
|
||||
});
|
||||
|
||||
describe('test start', () => {
|
||||
test('should star a package', () => {
|
||||
const storage = {
|
||||
changePackage: jest.fn(),
|
||||
getPackage({ callback }) {
|
||||
callback(null, {
|
||||
users: {},
|
||||
});
|
||||
},
|
||||
};
|
||||
req = {
|
||||
params: {
|
||||
package: 'verdaccio',
|
||||
},
|
||||
body: {
|
||||
_rev: REVISION_MOCK,
|
||||
users: {
|
||||
verdaccio: true,
|
||||
},
|
||||
},
|
||||
remote_user: {
|
||||
name: 'verdaccio',
|
||||
},
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
publishPackage(storage)(req, res, next);
|
||||
expect(storage.changePackage).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -29,7 +29,7 @@
|
||||
"path": "../middleware"
|
||||
},
|
||||
{
|
||||
"path": "../server"
|
||||
"path": "../server/express"
|
||||
},
|
||||
{
|
||||
"path": "../store"
|
||||
|
||||
@@ -1,5 +1,79 @@
|
||||
# @verdaccio/auth
|
||||
|
||||
## 6.0.0-6-next.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/core@6.0.0-6-next.47
|
||||
- @verdaccio/config@6.0.0-6-next.47
|
||||
- @verdaccio/loaders@6.0.0-6-next.16
|
||||
- @verdaccio/logger@6.0.0-6-next.15
|
||||
- verdaccio-htpasswd@11.0.0-6-next.17
|
||||
- @verdaccio/utils@6.0.0-6-next.15
|
||||
|
||||
## 6.0.0-6-next.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b849128d]
|
||||
- @verdaccio/core@6.0.0-6-next.8
|
||||
- @verdaccio/config@6.0.0-6-next.17
|
||||
- @verdaccio/loaders@6.0.0-6-next.15
|
||||
- @verdaccio/logger@6.0.0-6-next.14
|
||||
- verdaccio-htpasswd@11.0.0-6-next.16
|
||||
- @verdaccio/utils@6.0.0-6-next.14
|
||||
|
||||
## 6.0.0-6-next.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 351aeeaa: fix(deps): @verdaccio/utils should be a prod dep of local-storage
|
||||
- Updated dependencies [351aeeaa]
|
||||
- @verdaccio/core@6.0.0-6-next.7
|
||||
- @verdaccio/loaders@6.0.0-6-next.14
|
||||
- @verdaccio/logger@6.0.0-6-next.13
|
||||
- verdaccio-htpasswd@11.0.0-6-next.15
|
||||
- @verdaccio/config@6.0.0-6-next.16
|
||||
- @verdaccio/utils@6.0.0-6-next.13
|
||||
|
||||
## 6.0.0-6-next.23
|
||||
|
||||
### Major Changes
|
||||
|
||||
- 292c0a37: feat!: replace deprecated request dependency by got
|
||||
|
||||
This is a big refactoring of the core, fetching dependencies, improve code, more tests and better stability. This is essential for the next release, will take some time but would allow modularize more the core.
|
||||
|
||||
## Notes
|
||||
|
||||
- Remove deprecated `request` by other `got`, retry improved, custom Agent ( got does not include it built-in)
|
||||
- Remove `async` dependency from storage (used by core) it was linked with proxy somehow safe to remove now
|
||||
- Refactor with promises instead callback wherever is possible
|
||||
- ~Document the API~
|
||||
- Improve testing, integration tests
|
||||
- Bugfix
|
||||
- Clean up old validations
|
||||
- Improve performance
|
||||
|
||||
## 💥 Breaking changes
|
||||
|
||||
- Plugin API methods were callbacks based are returning promises, this will break current storage plugins, check documentation for upgrade.
|
||||
- Write Tarball, Read Tarball methods parameters change, a new set of options like `AbortController` signals are being provided to the `addAbortSignal` can be internally used with Streams when a request is aborted. eg: `addAbortSignal(signal, fs.createReadStream(pathName));`
|
||||
- `@verdaccio/streams` stream abort support is legacy is being deprecated removed
|
||||
- Remove AWS and Google Cloud packages for future refactoring [#2574](https://github.com/verdaccio/verdaccio/pull/2574).
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [292c0a37]
|
||||
- Updated dependencies [a3a209b5]
|
||||
- Updated dependencies [00d1d2a1]
|
||||
- @verdaccio/config@6.0.0-6-next.15
|
||||
- @verdaccio/core@6.0.0-6-next.6
|
||||
- @verdaccio/loaders@6.0.0-6-next.13
|
||||
- @verdaccio/logger@6.0.0-6-next.12
|
||||
- verdaccio-htpasswd@11.0.0-6-next.14
|
||||
- @verdaccio/utils@6.0.0-6-next.12
|
||||
|
||||
## 6.0.0-6-next.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
const config = require('../../jest/config');
|
||||
|
||||
module.exports = Object.assign({}, config, {});
|
||||
module.exports = Object.assign({}, config, {
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
// FIXME: increase to 90
|
||||
lines: 42,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/auth",
|
||||
"version": "6.0.0-6-next.22",
|
||||
"version": "6.0.0-6-next.26",
|
||||
"description": "logger",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"test": "cross-env NODE_ENV=test BABEL_ENV=test jest",
|
||||
"test": "jest",
|
||||
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||
@@ -39,20 +39,19 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.5",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.14",
|
||||
"@verdaccio/loaders": "workspace:6.0.0-6-next.12",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.11",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.11",
|
||||
"debug": "4.3.3",
|
||||
"express": "4.17.2",
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.47",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.47",
|
||||
"@verdaccio/loaders": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.15",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.15",
|
||||
"debug": "4.3.4",
|
||||
"express": "4.18.1",
|
||||
"jsonwebtoken": "8.5.1",
|
||||
"lodash": "4.17.21",
|
||||
"verdaccio-htpasswd": "workspace:11.0.0-6-next.13"
|
||||
"verdaccio-htpasswd": "workspace:11.0.0-6-next.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.15",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.12"
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -497,10 +497,10 @@ class Auth implements IAuth {
|
||||
next: Function
|
||||
): void {
|
||||
debug('handle legacy api middleware');
|
||||
debug('api middleware secret %o', secret);
|
||||
debug('api middleware authorization %o', authorization);
|
||||
debug('api middleware secret %o', typeof secret === 'string');
|
||||
debug('api middleware authorization %o', typeof authorization === 'string');
|
||||
const credentials: any = getMiddlewareCredentials(security, secret, authorization);
|
||||
debug('api middleware credentials %o', credentials);
|
||||
debug('api middleware credentials %o', credentials?.name);
|
||||
if (credentials) {
|
||||
const { user, password } = credentials;
|
||||
debug('authenticating %o', user);
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
createRemoteUser,
|
||||
parseConfigFile,
|
||||
} from '@verdaccio/config';
|
||||
import { getDefaultConfig } from '@verdaccio/config';
|
||||
import {
|
||||
API_ERROR,
|
||||
CHARACTER_ENCODING,
|
||||
@@ -16,14 +17,9 @@ import {
|
||||
errorUtils,
|
||||
} from '@verdaccio/core';
|
||||
import { setup } from '@verdaccio/logger';
|
||||
import { configExample } from '@verdaccio/mock';
|
||||
import { Config, RemoteUser, Security } from '@verdaccio/types';
|
||||
import {
|
||||
AllowActionCallbackResponse,
|
||||
buildToken,
|
||||
buildUserBuffer,
|
||||
getAuthenticatedMessage,
|
||||
} from '@verdaccio/utils';
|
||||
import { buildToken, buildUserBuffer, getAuthenticatedMessage } from '@verdaccio/utils';
|
||||
import type { AllowActionCallbackResponse } from '@verdaccio/utils';
|
||||
|
||||
import {
|
||||
ActionsAllowed,
|
||||
@@ -58,7 +54,7 @@ describe('Auth utilities', () => {
|
||||
function getConfig(configFileName: string, secret: string) {
|
||||
const conf = parseConfigFile(parseConfigurationSecurityFile(configFileName));
|
||||
// @ts-ignore
|
||||
const secConf = _.merge(configExample(), conf);
|
||||
const secConf = _.merge(getDefaultConfig(), conf);
|
||||
secConf.secret = secret;
|
||||
const config: Config = new AppConfig(secConf);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ describe('AuthTest', () => {
|
||||
});
|
||||
|
||||
test('should be a fail on login', () => {
|
||||
const config: Config = new AppConfig(_.cloneDeep(authPluginFailureConf));
|
||||
const config: Config = new AppConfig(authPluginFailureConf);
|
||||
config.checkSecretKey('12345');
|
||||
const auth: IAuth = new Auth(config);
|
||||
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import path from 'path';
|
||||
|
||||
import { configExample as config } from '@verdaccio/mock';
|
||||
import { getDefaultConfig } from '@verdaccio/config';
|
||||
|
||||
export const authProfileConf = config({
|
||||
export const authProfileConf = {
|
||||
...getDefaultConfig(),
|
||||
auth: {
|
||||
[`${path.join(__dirname, '../partials/plugin/authenticate.success')}`]: {},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const authPluginFailureConf = config({
|
||||
export const authPluginFailureConf = {
|
||||
...getDefaultConfig(),
|
||||
auth: {
|
||||
[`${path.join(__dirname, '../partials/plugin/authenticate.fail')}`]: {},
|
||||
[`${path.join(__dirname, '../partials/plugin/authenticate.fail.js')}`]: {},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const authPluginPassThrougConf = config({
|
||||
export const authPluginPassThrougConf = {
|
||||
...getDefaultConfig(),
|
||||
auth: {
|
||||
[`${path.join(__dirname, '../partials/plugin/authenticate.passthroug')}`]: {},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { getInternalError } from '@verdaccio/commons-api';
|
||||
import { errorUtils } from '@verdaccio/core';
|
||||
|
||||
module.exports = function () {
|
||||
return {
|
||||
authenticate(user, pass, callback) {
|
||||
// we return an 500 error, the second argument must be false.
|
||||
// https://verdaccio.org/docs/en/dev-plugins#onerror
|
||||
callback(getInternalError(), false);
|
||||
callback(errorUtils.getInternalError(), false);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,105 @@
|
||||
# @verdaccio/cli
|
||||
|
||||
## 6.0.0-6-next.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 020ede43: fix: version with breakline
|
||||
- @verdaccio/core@6.0.0-6-next.47
|
||||
- @verdaccio/config@6.0.0-6-next.47
|
||||
- @verdaccio/node-api@6.0.0-6-next.47
|
||||
- @verdaccio/logger@6.0.0-6-next.15
|
||||
|
||||
## 6.0.0-6-next.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b849128d: fix: handle upload scoped tarball
|
||||
- Updated dependencies [b849128d]
|
||||
- @verdaccio/core@6.0.0-6-next.8
|
||||
- @verdaccio/config@6.0.0-6-next.17
|
||||
- @verdaccio/logger@6.0.0-6-next.14
|
||||
- @verdaccio/node-api@6.0.0-6-next.36
|
||||
|
||||
## 6.0.0-6-next.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 351aeeaa: fix(deps): @verdaccio/utils should be a prod dep of local-storage
|
||||
- Updated dependencies [351aeeaa]
|
||||
- @verdaccio/core@6.0.0-6-next.7
|
||||
- @verdaccio/logger@6.0.0-6-next.13
|
||||
- @verdaccio/node-api@6.0.0-6-next.35
|
||||
- @verdaccio/config@6.0.0-6-next.16
|
||||
|
||||
## 6.0.0-6-next.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/core@6.0.0-6-next.6
|
||||
- @verdaccio/logger@6.0.0-6-next.12
|
||||
- @verdaccio/node-api@6.0.0-6-next.34
|
||||
|
||||
## 6.0.0-6-next.35
|
||||
|
||||
### Major Changes
|
||||
|
||||
- 292c0a37: feat!: replace deprecated request dependency by got
|
||||
|
||||
This is a big refactoring of the core, fetching dependencies, improve code, more tests and better stability. This is essential for the next release, will take some time but would allow modularize more the core.
|
||||
|
||||
## Notes
|
||||
|
||||
- Remove deprecated `request` by other `got`, retry improved, custom Agent ( got does not include it built-in)
|
||||
- Remove `async` dependency from storage (used by core) it was linked with proxy somehow safe to remove now
|
||||
- Refactor with promises instead callback wherever is possible
|
||||
- ~Document the API~
|
||||
- Improve testing, integration tests
|
||||
- Bugfix
|
||||
- Clean up old validations
|
||||
- Improve performance
|
||||
|
||||
## 💥 Breaking changes
|
||||
|
||||
- Plugin API methods were callbacks based are returning promises, this will break current storage plugins, check documentation for upgrade.
|
||||
- Write Tarball, Read Tarball methods parameters change, a new set of options like `AbortController` signals are being provided to the `addAbortSignal` can be internally used with Streams when a request is aborted. eg: `addAbortSignal(signal, fs.createReadStream(pathName));`
|
||||
- `@verdaccio/streams` stream abort support is legacy is being deprecated removed
|
||||
- Remove AWS and Google Cloud packages for future refactoring [#2574](https://github.com/verdaccio/verdaccio/pull/2574).
|
||||
|
||||
- a3a209b5: feat: migrate to pino.js 8
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 00d1d2a1: chore: env variable for launch fastify
|
||||
|
||||
- Update fastify to major release `v4.3.0`
|
||||
- Update CLI launcher
|
||||
|
||||
via CLI
|
||||
|
||||
```
|
||||
VERDACCIO_SERVER=fastify verdaccio
|
||||
```
|
||||
|
||||
with docker
|
||||
|
||||
```
|
||||
docker run -it --rm --name verdaccio \
|
||||
-e "VERDACCIO_SERVER=8080" -p 8080:8080 \
|
||||
-e "VERDACCIO_SERVER=fastify" \
|
||||
verdaccio/verdaccio
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [292c0a37]
|
||||
- Updated dependencies [a3a209b5]
|
||||
- Updated dependencies [00d1d2a1]
|
||||
- @verdaccio/config@6.0.0-6-next.15
|
||||
- @verdaccio/core@6.0.0-6-next.6
|
||||
- @verdaccio/logger@6.0.0-6-next.12
|
||||
- @verdaccio/node-api@6.0.0-6-next.33
|
||||
|
||||
## 6.0.0-6-next.34
|
||||
|
||||
### Patch Changes
|
||||
@@ -13,7 +113,7 @@
|
||||
- Updated dependencies [d43894e8]
|
||||
- Updated dependencies [d08fe29d]
|
||||
- @verdaccio/config@6.0.0-6-next.14
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.23
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.23
|
||||
- @verdaccio/node-api@6.0.0-6-next.31
|
||||
- @verdaccio/core@6.0.0-6-next.5
|
||||
- @verdaccio/logger@6.0.0-6-next.11
|
||||
@@ -59,20 +159,20 @@
|
||||
- @verdaccio/core@6.0.0-6-next.5
|
||||
- @verdaccio/logger@6.0.0-6-next.11
|
||||
- @verdaccio/node-api@6.0.0-6-next.30
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.22
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.22
|
||||
|
||||
## 6.0.0-6-next.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.21
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.21
|
||||
- @verdaccio/node-api@6.0.0-6-next.29
|
||||
|
||||
## 6.0.0-6-next.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.20
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.20
|
||||
- @verdaccio/node-api@6.0.0-6-next.28
|
||||
|
||||
## 6.0.0-6-next.28
|
||||
@@ -81,7 +181,7 @@
|
||||
|
||||
- Updated dependencies [b78f3525]
|
||||
- @verdaccio/logger@6.0.0-6-next.10
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.19
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.19
|
||||
- @verdaccio/node-api@6.0.0-6-next.27
|
||||
|
||||
## 6.0.0-6-next.27
|
||||
@@ -91,7 +191,7 @@
|
||||
- Updated dependencies [730b5d8c]
|
||||
- @verdaccio/logger@6.0.0-6-next.9
|
||||
- @verdaccio/node-api@6.0.0-6-next.26
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.18
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.18
|
||||
|
||||
## 6.0.0-6-next.26
|
||||
|
||||
@@ -100,7 +200,7 @@
|
||||
- Updated dependencies [a828271d]
|
||||
- Updated dependencies [24b9be02]
|
||||
- Updated dependencies [e75c0a3b]
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.17
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.17
|
||||
- @verdaccio/core@6.0.0-6-next.4
|
||||
- @verdaccio/logger@6.0.0-6-next.8
|
||||
- @verdaccio/node-api@6.0.0-6-next.25
|
||||
@@ -112,7 +212,7 @@
|
||||
|
||||
- Updated dependencies [f86c31ed]
|
||||
- Updated dependencies [20c9e43e]
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.16
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.16
|
||||
- @verdaccio/config@6.0.0-6-next.11
|
||||
- @verdaccio/node-api@6.0.0-6-next.24
|
||||
|
||||
@@ -129,7 +229,7 @@
|
||||
- @verdaccio/logger@6.0.0-6-next.7
|
||||
- @verdaccio/node-api@6.0.0-6-next.23
|
||||
- @verdaccio/config@6.0.0-6-next.10
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.15
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.15
|
||||
|
||||
## 6.0.0-6-next.23
|
||||
|
||||
@@ -149,7 +249,7 @@
|
||||
- Updated dependencies [b702ea36]
|
||||
- Updated dependencies [154b2ecd]
|
||||
- @verdaccio/config@6.0.0-6-next.9
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.14
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.14
|
||||
- @verdaccio/logger@6.0.0-6-next.6
|
||||
- @verdaccio/node-api@6.0.0-6-next.22
|
||||
|
||||
@@ -159,7 +259,7 @@
|
||||
|
||||
- Updated dependencies [2c594910]
|
||||
- @verdaccio/logger@6.0.0-6-next.5
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.13
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.13
|
||||
- @verdaccio/node-api@6.0.0-6-next.21
|
||||
|
||||
## 6.0.0-6-next.21
|
||||
@@ -203,7 +303,7 @@
|
||||
|
||||
- Updated dependencies [459b6fa7]
|
||||
- @verdaccio/config@6.0.0-6-next.8
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.12
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.12
|
||||
- @verdaccio/node-api@6.0.0-6-next.20
|
||||
- @verdaccio/logger@6.0.0-6-next.4
|
||||
|
||||
@@ -212,7 +312,7 @@
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [df0da3d6]
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.11
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.11
|
||||
- @verdaccio/node-api@6.0.0-6-next.19
|
||||
|
||||
## 6.0.0-6-next.19
|
||||
@@ -236,7 +336,7 @@
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [55ee3fdd]
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.10
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.10
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/node-api@6.0.0-6-next.17
|
||||
|
||||
@@ -250,7 +350,7 @@
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.9
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.9
|
||||
- @verdaccio/logger@6.0.0-6-next.4
|
||||
- @verdaccio/node-api@6.0.0-6-next.15
|
||||
|
||||
@@ -258,7 +358,7 @@
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.9
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.9
|
||||
- @verdaccio/logger@6.0.0-6-next.4
|
||||
- @verdaccio/node-api@6.0.0-6-next.14
|
||||
|
||||
@@ -291,7 +391,7 @@
|
||||
|
||||
- Updated dependencies [19d272d1]
|
||||
- @verdaccio/node-api@6.0.0-6-next.12
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.9
|
||||
- @verdaccio/server-fastify@6.0.0-6-next.9
|
||||
- @verdaccio/logger@6.0.0-6-next.4
|
||||
|
||||
## 6.0.0-6-next.11
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
module.exports = require('../../jest/config');
|
||||
const config = require('../../jest/config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
// FIXME: increase to 90
|
||||
lines: 4,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/cli",
|
||||
"version": "6.0.0-6-next.34",
|
||||
"version": "6.0.0-6-next.47",
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
@@ -35,7 +35,7 @@
|
||||
"types": "build/index.d.ts",
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"test": "cross-env NODE_ENV=test BABEL_ENV=test jest",
|
||||
"test": "jest",
|
||||
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||
@@ -44,18 +44,17 @@
|
||||
"start": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.5",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.14",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.11",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.32",
|
||||
"@verdaccio/fastify-migration": "workspace:6.0.0-6-next.23",
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.47",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.47",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.15",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.47",
|
||||
"clipanion": "3.1.0",
|
||||
"envinfo": "7.8.1",
|
||||
"kleur": "3.0.3",
|
||||
"semver": "7.3.5"
|
||||
"semver": "7.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-node": "10.4.0"
|
||||
"ts-node": "10.9.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Cli } from 'clipanion';
|
||||
|
||||
import { warningUtils } from '@verdaccio/core';
|
||||
|
||||
import { FastifyServer } from './commands/FastifyServer';
|
||||
import { InfoCommand } from './commands/info';
|
||||
import { InitCommand } from './commands/init';
|
||||
import { VersionCommand } from './commands/version';
|
||||
@@ -30,7 +29,6 @@ const cli = new Cli({
|
||||
cli.register(InfoCommand);
|
||||
cli.register(InitCommand);
|
||||
cli.register(VersionCommand);
|
||||
cli.register(FastifyServer);
|
||||
cli.runExit(args, Cli.defaultContext);
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { Command, Option } from 'clipanion';
|
||||
|
||||
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
|
||||
import server from '@verdaccio/fastify-migration';
|
||||
import { logger, setup } from '@verdaccio/logger';
|
||||
import { ConfigRuntime } from '@verdaccio/types';
|
||||
|
||||
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
|
||||
|
||||
/**
|
||||
* This command is intended to run the server with Fastify
|
||||
* as a migration step.
|
||||
* More info: https://github.com/verdaccio/verdaccio/discussions/2155
|
||||
* To try out.
|
||||
* pnpm debug:fastify
|
||||
*/
|
||||
export class FastifyServer extends Command {
|
||||
public static paths = [['fastify-server']];
|
||||
|
||||
private port = Option.String('-l,-p,--listen,--port', {
|
||||
description: 'host:port number to listen on (default: localhost:4873)',
|
||||
});
|
||||
|
||||
private config = Option.String('-c,--config', {
|
||||
description: 'use this configuration file (default: ./config.yaml)',
|
||||
});
|
||||
|
||||
private initLogger(logConfig: ConfigRuntime) {
|
||||
try {
|
||||
if (logConfig.log) {
|
||||
throw Error('logger as array not longer supported');
|
||||
}
|
||||
// FUTURE: remove fallback when is ready
|
||||
setup(logConfig.log);
|
||||
} catch (err: any) {
|
||||
throw new Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async execute() {
|
||||
try {
|
||||
const configPathLocation = findConfigFile(this.config as string);
|
||||
const configParsed = parseConfigFile(configPathLocation);
|
||||
const { web } = configParsed;
|
||||
this.initLogger(configParsed);
|
||||
|
||||
process.title = web?.title || DEFAULT_PROCESS_NAME;
|
||||
// FIXME: need a way to get version of the package.
|
||||
// const { version, name } = require('../../package.json');
|
||||
const ser = await server({ logger, config: configParsed });
|
||||
// FIXME: harcoded, this would need to come from the configuration and the --listen flag.
|
||||
await ser.listen(process.env.PORT || 4873);
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user