feat!: remove fastify server packages (#5463)
This commit is contained in:
@@ -10,7 +10,6 @@
|
||||
'verdaccio-memory': major
|
||||
'@verdaccio/search-indexer': major
|
||||
'@verdaccio/server': major
|
||||
'@verdaccio/server-fastify': major
|
||||
'@verdaccio/logger': major
|
||||
'verdaccio-audit': major
|
||||
'@verdaccio/ui-components': major
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
'@verdaccio/local-storage': patch
|
||||
'@verdaccio/server': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'@verdaccio/ui-components': patch
|
||||
'@verdaccio/tarball': patch
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
'@verdaccio/local-scripts': patch
|
||||
'@verdaccio/file-locking': patch
|
||||
'@verdaccio/ui-theme': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'@verdaccio/middleware': patch
|
||||
'verdaccio': patch
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
'@verdaccio/local-storage': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/middleware': patch
|
||||
'@verdaccio/core': patch
|
||||
'@verdaccio/config': patch
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
'verdaccio-memory': patch
|
||||
'@verdaccio/search-indexer': patch
|
||||
'@verdaccio/server': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/logger': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'@verdaccio/ui-components': patch
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
"@verdaccio/search": "7.0.0",
|
||||
"@verdaccio/search-indexer": "7.0.0",
|
||||
"@verdaccio/server": "7.0.0",
|
||||
"@verdaccio/server-fastify": "7.0.0",
|
||||
"@verdaccio/signature": "7.0.0",
|
||||
"@verdaccio/cli-standalone": "7.0.0",
|
||||
"@verdaccio/store": "7.0.0",
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
'verdaccio-memory': patch
|
||||
'@verdaccio/search-indexer': patch
|
||||
'@verdaccio/server': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/logger': patch
|
||||
'verdaccio-audit': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
'@verdaccio/ui-theme': patch
|
||||
'@verdaccio/search-indexer': patch
|
||||
'@verdaccio/server': patch
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/test-helper': patch
|
||||
'@verdaccio/middleware': patch
|
||||
'verdaccio': patch
|
||||
|
||||
@@ -136,7 +136,6 @@ Any interaction with the server should be done through the port `8000` eg: `npm
|
||||
#### Useful commands
|
||||
|
||||
- `pnpm debug`: Run the server in debug mode `--inspect`. UI runs too but without hot reload. For automatic break use `pnpm debug:break`.
|
||||
- `pnpm debug:fastify`: To contribute on the [fastify migration](https://github.com/verdaccio/verdaccio/discussions/2155) this is a temporary command for such purpose.
|
||||
- `pnpm website`: Build the website, for more commands to run the _website_, run `cd website` and then `pnpm serve`, website will run on port `3000`.
|
||||
- `pnpm docker`: Build the docker image. Requires `docker` command available in your system.
|
||||
|
||||
|
||||
@@ -147,7 +147,6 @@
|
||||
"_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": "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",
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/server": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/server-fastify": "workspace:8.0.0-next-8.24",
|
||||
"debug": "4.4.3",
|
||||
"lodash": "4.17.21"
|
||||
},
|
||||
|
||||
@@ -10,7 +10,6 @@ import url from 'node:url';
|
||||
import { getConfigParsed, getListenAddress } from '@verdaccio/config';
|
||||
import { logger, setup } from '@verdaccio/logger';
|
||||
import expressServer from '@verdaccio/server';
|
||||
import fastifyServer from '@verdaccio/server-fastify';
|
||||
import { ConfigYaml, HttpsConfKeyCert, HttpsConfPfx } from '@verdaccio/types';
|
||||
|
||||
import { displayExperimentsInfoBox } from './experiments';
|
||||
@@ -123,60 +122,48 @@ export async function initServer(
|
||||
const addr = getListenAddress(port ?? config?.listen, logger);
|
||||
displayExperimentsInfoBox(config.flags);
|
||||
|
||||
let app;
|
||||
if (process.env.VERDACCIO_SERVER === 'fastify') {
|
||||
app = await fastifyServer(config);
|
||||
app.listen({ port: addr.port, host: addr.host }, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
let app = await expressServer(config);
|
||||
const serverFactory = createServerFactory(config, addr, app);
|
||||
serverFactory
|
||||
.listen(addr.port || addr.path, addr.host, (): void => {
|
||||
// send a message for test
|
||||
if (isFunction(process.send)) {
|
||||
process.send({
|
||||
verdaccio_started: true,
|
||||
});
|
||||
}
|
||||
const addressServer = `${
|
||||
addr.path
|
||||
? url.format({
|
||||
protocol: 'unix',
|
||||
pathname: addr.path,
|
||||
})
|
||||
: url.format({
|
||||
protocol: addr.proto,
|
||||
hostname: addr.host,
|
||||
port: addr.port,
|
||||
pathname: '/',
|
||||
})
|
||||
}`;
|
||||
logger.info({ addressServer }, 'http address: @{addressServer}');
|
||||
logger.info({ version }, 'version: @{version}');
|
||||
resolve();
|
||||
})
|
||||
.on('error', function (err): void {
|
||||
reject(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
} else {
|
||||
app = await expressServer(config);
|
||||
const serverFactory = createServerFactory(config, addr, app);
|
||||
serverFactory
|
||||
.listen(addr.port || addr.path, addr.host, (): void => {
|
||||
// send a message for test
|
||||
if (isFunction(process.send)) {
|
||||
process.send({
|
||||
verdaccio_started: true,
|
||||
});
|
||||
}
|
||||
const addressServer = `${
|
||||
addr.path
|
||||
? url.format({
|
||||
protocol: 'unix',
|
||||
pathname: addr.path,
|
||||
})
|
||||
: url.format({
|
||||
protocol: addr.proto,
|
||||
hostname: addr.host,
|
||||
port: addr.port,
|
||||
pathname: '/',
|
||||
})
|
||||
}`;
|
||||
logger.info({ addressServer }, 'http address: @{addressServer}');
|
||||
logger.info({ version }, 'version: @{version}');
|
||||
resolve();
|
||||
})
|
||||
.on('error', function (err): void {
|
||||
reject(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
function handleShutdownGracefully() {
|
||||
logger.info('received shutdown signal - closing server gracefully...');
|
||||
serverFactory.close(() => {
|
||||
logger.info('server closed.');
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
function handleShutdownGracefully() {
|
||||
logger.info('received shutdown signal - closing server gracefully...');
|
||||
serverFactory.close(() => {
|
||||
logger.info('server closed.');
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
||||
// Use once() so that receiving double signals exit the app.
|
||||
process.once(signal, handleShutdownGracefully);
|
||||
}
|
||||
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
||||
// Use once() so that receiving double signals exit the app.
|
||||
process.once(signal, handleShutdownGracefully);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
},
|
||||
{
|
||||
"path": "../server/express"
|
||||
},
|
||||
{
|
||||
"path": "../server/fastify"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "../../../.babelrc"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
node_modules
|
||||
coverage/
|
||||
lib/
|
||||
.nyc_output
|
||||
tests-report/
|
||||
build/
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"@typescript-eslint/no-use-before-define": "off"
|
||||
}
|
||||
}
|
||||
1
packages/server/fastify/.gitignore
vendored
1
packages/server/fastify/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
lib/
|
||||
@@ -1,6 +0,0 @@
|
||||
/*
|
||||
!/bin/**/*
|
||||
!/build/**/*
|
||||
!index.js
|
||||
!LICENSE
|
||||
!README.md
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Verdaccio contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,88 +0,0 @@
|
||||
# @verdaccio/server-fastify - Verdaccio Fastify Server
|
||||
|
||||
[](https://verdaccio.org)
|
||||
[](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)
|
||||
[](https://github.com/verdaccio/verdaccio)
|
||||
[](https://npmjs.com/package/@verdaccio/server-fastify)
|
||||
|
||||
[](https://verdaccio.org/docs)
|
||||
[](https://discord.com/channels/388674437219745793)
|
||||
[](https://bsky.app/profile/verdaccio.org)
|
||||
[](https://opencollective.com/verdaccio/contribute)
|
||||
[](https://opencollective.com/verdaccio/contribute)
|
||||
|
||||
[](https://www.npmjs.com/package/verdaccio)
|
||||
[](https://hub.docker.com/r/verdaccio/verdaccio)
|
||||
[](https://github.com/verdaccio/verdaccio/stargazers)
|
||||
|
||||
A package intended to start a migration from Express to fastify. (WIP).
|
||||
|
||||
Run from root folder
|
||||
|
||||
```js
|
||||
pnpm debug -- new
|
||||
```
|
||||
|
||||
## Donations
|
||||
|
||||
Verdaccio is run by **volunteers**; nobody is working full-time on it. If you find this project to be useful and would like to support its development, consider making a donation - **your logo might end up in this readme.** 😉
|
||||
|
||||
**[Donate](https://opencollective.com/verdaccio)** 💵👍🏻 starting from _\$1/month_ or just one single contribution.
|
||||
|
||||
## Report a vulnerability
|
||||
|
||||
If you want to report a security vulnerability, please follow the steps which we have defined for you in our [security policy](https://github.com/verdaccio/verdaccio/security/policy).
|
||||
|
||||
## Open Collective Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/verdaccio/contribute)]
|
||||
|
||||
[](https://opencollective.com/verdaccio/sponsor/0/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/1/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/2/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/3/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/4/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/5/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/6/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/7/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/8/website)
|
||||
[](https://opencollective.com/verdaccio/sponsor/9/website)
|
||||
|
||||
## Open Collective Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/verdaccio/contribute)]
|
||||
|
||||
[](https://opencollective.com/verdaccio/contributes)
|
||||
|
||||
## Special Thanks
|
||||
|
||||
Thanks to the following companies to help us to achieve our goals providing free open source licenses.
|
||||
|
||||
[](https://www.jetbrains.com/)
|
||||
[](https://crowdin.com/)
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](https://github.com/verdaccio/verdaccio/blob/master/CONTRIBUTING.md)].
|
||||
|
||||
[](https://github.com/verdaccio/verdaccio/graphs/contributors)
|
||||
|
||||
## FAQ / Contact / Troubleshoot
|
||||
|
||||
If you have any issue you can try the following options. Do not hesitate to ask or check our issues database. Perhaps someone has asked already what you are looking for.
|
||||
|
||||
- [Blog](https://verdaccio.org/blog/)
|
||||
- [Donations](https://opencollective.com/verdaccio)
|
||||
- [Reporting an issue](https://github.com/verdaccio/verdaccio/blob/master/CONTRIBUTING.md#reporting-a-bug)
|
||||
- [Running discussions](https://github.com/orgs/verdaccio/discussions)
|
||||
- [Chat](https://discord.com/channels/388674437219745793)
|
||||
- [Logos](https://verdaccio.org/docs/logo)
|
||||
- [Docker Examples](https://github.com/verdaccio/verdaccio/tree/master/docker-examples)
|
||||
- [FAQ](https://github.com/verdaccio/verdaccio/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Aquestion%20)
|
||||
|
||||
## License
|
||||
|
||||
Verdaccio is [MIT licensed](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)
|
||||
|
||||
The Verdaccio documentation and logos (excluding /thanks, e.g., .md, .png, .sketch files within the /assets folder) are
|
||||
[Creative Commons licensed](https://creativecommons.org/licenses/by/4.0/).
|
||||
@@ -1,39 +0,0 @@
|
||||
storage: ./storage
|
||||
plugins: ./plugins
|
||||
web:
|
||||
title: Verdaccio
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: npmjs
|
||||
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: npmjs
|
||||
|
||||
server:
|
||||
keepAliveTimeout: 60
|
||||
|
||||
middlewares:
|
||||
audit:
|
||||
enabled: true
|
||||
|
||||
log: { type: stdout, format: pretty, level: http }
|
||||
flags:
|
||||
token: false
|
||||
search: false
|
||||
|
||||
i18n:
|
||||
web: en-US
|
||||
@@ -1,32 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import path from 'node:path';
|
||||
|
||||
import { parseConfigFile } from '@verdaccio/config';
|
||||
import { logger, setup } from '@verdaccio/logger';
|
||||
|
||||
import server from '../src/index';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:debug');
|
||||
|
||||
/**
|
||||
* This file is intended for fast development and debug, it should
|
||||
* be removed eventually and the app start from @verdaccio/cli package.
|
||||
*/
|
||||
(async () => {
|
||||
try {
|
||||
const configFile = path.join(__dirname, './fastify-conf.yaml');
|
||||
debug('configFile %s', configFile);
|
||||
const configParsed = parseConfigFile(configFile);
|
||||
setup(configParsed.log);
|
||||
logger.info(`config location ${configFile}`);
|
||||
debug('configParsed %s', configParsed);
|
||||
process.title = 'fastify-verdaccio';
|
||||
const ser = await server({ logger, config: configParsed });
|
||||
await ser.listen(4873);
|
||||
logger.info('fastify running on port 4873');
|
||||
} catch (err: any) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
@@ -1,63 +0,0 @@
|
||||
{
|
||||
"name": "@verdaccio/server-fastify",
|
||||
"version": "8.0.0-next-8.24",
|
||||
"description": "Verdaccio Fastify Server",
|
||||
"keywords": [
|
||||
"private",
|
||||
"package",
|
||||
"repository",
|
||||
"registry",
|
||||
"enterprise",
|
||||
"modules",
|
||||
"proxy",
|
||||
"server",
|
||||
"verdaccio"
|
||||
],
|
||||
"main": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"author": "Juan Picado <juanpicado19@gmail.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"repository": {
|
||||
"type": "https",
|
||||
"url": "https://github.com/verdaccio/verdaccio",
|
||||
"directory": "packages/server/fastify"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/verdaccio/verdaccio/issues"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/config": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/auth": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/logger": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/store": "workspace:8.0.0-next-8.24",
|
||||
"debug": "4.4.3",
|
||||
"fastify": "4.25.2",
|
||||
"fastify-plugin": "4.5.1",
|
||||
"lodash": "4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.8",
|
||||
"ts-node": "10.9.2"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
"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",
|
||||
"watch": "pnpm build:js -- --watch",
|
||||
"build": "pnpm run build:js && pnpm run build:types",
|
||||
"start": "ts-node debug/index.ts"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/verdaccio"
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { MergeTags } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:dist-tags');
|
||||
|
||||
interface ParamsInterface {
|
||||
packageName: string;
|
||||
}
|
||||
|
||||
async function distTagsRoute(fastify: FastifyInstance) {
|
||||
fastify.get<{ Params: ParamsInterface }>(
|
||||
'/-/package/:packageName/dist-tags',
|
||||
async (request, reply) => {
|
||||
// @ts-ignore
|
||||
const { packageName } = request.params;
|
||||
debug('dist-tags: response %o', packageName);
|
||||
const requestOptions = {
|
||||
protocol: request.protocol,
|
||||
headers: request.headers as any,
|
||||
host: request.hostname,
|
||||
remoteAddress: request.socket.remoteAddress,
|
||||
};
|
||||
const manifest = fastify.storage.getPackageByOptions({
|
||||
name: packageName,
|
||||
uplinksLook: true,
|
||||
keepUpLinkData: true,
|
||||
requestOptions,
|
||||
});
|
||||
reply.code(fastify.statusCode.OK).send(manifest[fastify.constants.DIST_TAGS]);
|
||||
}
|
||||
);
|
||||
|
||||
fastify.post<{ Params: ParamsInterface; Body: MergeTags }>(
|
||||
'/-/package/:packageName/dist-tags',
|
||||
async (request) => {
|
||||
const { packageName } = request.params;
|
||||
await fastify.storage.mergeTagsNext(packageName, request.body);
|
||||
return { ok: fastify.constants.API_MESSAGE.TAG_UPDATED };
|
||||
}
|
||||
);
|
||||
|
||||
fastify.delete('/-/package/:packageName/dist-tags', async (request, reply) => {
|
||||
// @ts-ignore
|
||||
// const { packageName } = request.params;
|
||||
|
||||
reply.code(fastify.statusCode.NOT_FOUND);
|
||||
});
|
||||
}
|
||||
|
||||
export default distTagsRoute;
|
||||
@@ -1,68 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { stringUtils } from '@verdaccio/core';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { Package, Version } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:api:sidebar');
|
||||
export type $SidebarPackage = Package & { latest: Version };
|
||||
|
||||
interface ParamsInterface {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
async function manifestRoute(fastify: FastifyInstance) {
|
||||
fastify.get<{ Params: ParamsInterface }>('/:name', async (request) => {
|
||||
const { name } = request.params;
|
||||
const storage = fastify.storage;
|
||||
debug('pkg name %s ', name);
|
||||
// @ts-ignore
|
||||
const abbreviated =
|
||||
stringUtils.getByQualityPriorityValue(request.headers['accept']) ===
|
||||
Storage.ABBREVIATED_HEADER;
|
||||
const data = await storage?.getPackageByOptions({
|
||||
name,
|
||||
// @ts-ignore
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
protocol: request.protocol,
|
||||
headers: request.headers as any,
|
||||
host: request.hostname,
|
||||
},
|
||||
abbreviated,
|
||||
});
|
||||
return data;
|
||||
});
|
||||
|
||||
interface QueryInterface {
|
||||
write: string;
|
||||
}
|
||||
|
||||
fastify.get<{ Params: ParamsInterface; Querystring: QueryInterface }>(
|
||||
'/:packageName/:version',
|
||||
async (request) => {
|
||||
const { name, version } = request.params;
|
||||
const storage = fastify.storage;
|
||||
const write = request.query.write === 'true';
|
||||
debug('pkg name %s, with version / tag: %s ', name, version);
|
||||
const requestOptions = {
|
||||
protocol: request.protocol,
|
||||
headers: request.headers as any,
|
||||
host: request.hostname,
|
||||
remoteAddress: request.socket.remoteAddress,
|
||||
byPassCache: write,
|
||||
};
|
||||
const data = await storage?.getPackageByOptions({
|
||||
name,
|
||||
version,
|
||||
uplinksLook: true,
|
||||
requestOptions,
|
||||
});
|
||||
return data;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default manifestRoute;
|
||||
@@ -1,15 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/* eslint-disable no-invalid-this */
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { logger } from '@verdaccio/logger';
|
||||
|
||||
async function pingRoute(fastify: FastifyInstance) {
|
||||
fastify.get('/-/ping', async () => {
|
||||
logger.http('ping');
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
export default pingRoute;
|
||||
@@ -1,30 +0,0 @@
|
||||
// import buildDebug from 'debug';
|
||||
// import { FastifyInstance } from 'fastify';
|
||||
|
||||
// import { Package, Version } from '@verdaccio/types';
|
||||
|
||||
// const debug = buildDebug('verdaccio:web:api:sidebar');
|
||||
// export type $SidebarPackage = Package & { latest: Version };
|
||||
|
||||
// async function manifestRoute(fastify: FastifyInstance) {
|
||||
// // TODO: review // :_rev?/:revision?
|
||||
// fastify.put('/:packageName', async (request) => {
|
||||
// // @ts-ignore
|
||||
// const { packageName } = request.params;
|
||||
// const storage = fastify.storage;
|
||||
// debug('pkg name %s ', packageName);
|
||||
// // const data = await storage?.getPackageNext({
|
||||
// // name: packageName,
|
||||
// // req: request.raw,
|
||||
// // uplinksLook: true,
|
||||
// // requestOptions: {
|
||||
// // protocol: request.protocol,
|
||||
// // headers: request.headers as any,
|
||||
// // host: request.hostname,
|
||||
// // },
|
||||
// // });
|
||||
// // return data;
|
||||
// });
|
||||
// }
|
||||
|
||||
// export default manifestRoute;
|
||||
@@ -1,37 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/* eslint-disable no-invalid-this */
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { searchUtils } from '@verdaccio/core';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
|
||||
interface QueryInterface {
|
||||
url: string;
|
||||
query: searchUtils.SearchQuery;
|
||||
}
|
||||
|
||||
async function searchRoute(fastify: FastifyInstance) {
|
||||
fastify.get<{ Querystring: QueryInterface }>('/-/v1/search', async (request, reply) => {
|
||||
// TODO: apply security layer here like in
|
||||
// packages/api/src/v1/search.ts
|
||||
// TODO: add validations for query, some parameters are mandatory
|
||||
// TODO: review which query fields are mandatory
|
||||
const abort = new AbortController();
|
||||
request.socket.on('aborted', () => {
|
||||
abort.abort();
|
||||
});
|
||||
const { url, query } = request.query;
|
||||
const storage = fastify.storage;
|
||||
const data = await storage.search({
|
||||
query,
|
||||
url,
|
||||
abort,
|
||||
});
|
||||
|
||||
logger.http('search endpoint');
|
||||
reply.code(200).send(data);
|
||||
});
|
||||
}
|
||||
|
||||
export default searchRoute;
|
||||
@@ -1,69 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:tarball');
|
||||
|
||||
interface ParamsInterface {
|
||||
package: string;
|
||||
filename: string;
|
||||
}
|
||||
|
||||
async function tarballRoute(fastify: FastifyInstance) {
|
||||
fastify.get<{ Params: ParamsInterface }>('/:package/-/:filename', async (request, reply) => {
|
||||
const { package: pkg, filename } = request.params;
|
||||
debug('stream tarball for %s@%s', pkg, filename);
|
||||
const abort = new AbortController();
|
||||
const stream = (await fastify.storage.getTarball(pkg, filename, {
|
||||
signal: abort.signal,
|
||||
// enableRemote: true,
|
||||
})) as any;
|
||||
|
||||
stream.on('content-length', (size: number) => {
|
||||
reply.header(HEADER_TYPE.CONTENT_LENGTH, size);
|
||||
});
|
||||
|
||||
// request.socket.on('abort', () => {
|
||||
// debug('request aborted for %o', request.url);
|
||||
// abort.abort();
|
||||
// });
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
interface ScopeParamsInterface {
|
||||
filename: string;
|
||||
scope: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
fastify.get<{ Params: ScopeParamsInterface }>(
|
||||
'/:scope/:name/-/:filename',
|
||||
async (request, reply) => {
|
||||
const abort = new AbortController();
|
||||
const { scope, name, filename } = request.params;
|
||||
const scopedPackage = `${scope}/${name}`;
|
||||
debug('stream scope tarball for %s@%s', scopedPackage, filename);
|
||||
const stream = (await fastify.storage.getTarball(scopedPackage, filename, {
|
||||
signal: abort.signal,
|
||||
// enableRemote: true,
|
||||
})) as any;
|
||||
|
||||
stream.on('content-length', (size: number) => {
|
||||
reply.header(HEADER_TYPE.CONTENT_LENGTH, size);
|
||||
});
|
||||
|
||||
// request.socket.on('abort', () => {
|
||||
// debug('request aborted for %o', request.url);
|
||||
// abort.abort();
|
||||
// });
|
||||
|
||||
reply.header(HEADERS.CONTENT_TYPE, HEADERS.OCTET_STREAM);
|
||||
return stream;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default tarballRoute;
|
||||
@@ -1,151 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/* eslint-disable no-invalid-this */
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { getApiToken } from '@verdaccio/auth';
|
||||
import { createRemoteUser } from '@verdaccio/config';
|
||||
import { authUtils, validationUtils } from '@verdaccio/core';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { RemoteUser } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:user');
|
||||
|
||||
async function userRoute(fastify: FastifyInstance) {
|
||||
interface UserParamsInterface {
|
||||
org_couchdb_user: string;
|
||||
}
|
||||
|
||||
fastify.get<{ Params: UserParamsInterface }>('/:org_couchdb_user', async (request, reply) => {
|
||||
// @ts-ignore
|
||||
// TODO: compare org_couchdb_user with remote user name
|
||||
const message = authUtils.getAuthenticatedMessage(request.userRemote.name);
|
||||
logger.info('user authenticated message %o', message);
|
||||
reply.code(fastify.statusCode.OK);
|
||||
return { ok: message };
|
||||
});
|
||||
|
||||
interface DeleteTokenParamsInterface {
|
||||
token: string;
|
||||
}
|
||||
|
||||
fastify.delete<{ Params: DeleteTokenParamsInterface }>(
|
||||
'/token/:token',
|
||||
async (request, reply) => {
|
||||
debug('loging out');
|
||||
const { token } = request.params;
|
||||
const userRemote: RemoteUser = request.userRemote;
|
||||
await fastify.auth.invalidateToken(token);
|
||||
console.log('userRoute', userRemote);
|
||||
reply.code(fastify.statusCode.OK);
|
||||
return { ok: fastify.apiMessage.LOGGED_OUT };
|
||||
}
|
||||
);
|
||||
|
||||
interface UpdateUserParamsInterface {
|
||||
username: string;
|
||||
}
|
||||
|
||||
fastify.put<{
|
||||
Body: { name: string; password: string };
|
||||
Params: UpdateUserParamsInterface;
|
||||
}>('/:username', async (request, reply) => {
|
||||
const { name, password } = request.body;
|
||||
const remoteName = request.userRemote.name;
|
||||
if (_.isNil(remoteName) === false && _.isNil(name) === false && remoteName === name) {
|
||||
// debug('login: no remote user detected');
|
||||
fastify.auth.authenticate(
|
||||
name,
|
||||
password,
|
||||
async function callbackAuthenticate(err, user): Promise<void> {
|
||||
if (err) {
|
||||
logger.trace(
|
||||
{ name, err },
|
||||
'authenticating for user @{username} failed. Error: @{err.message}'
|
||||
);
|
||||
reply
|
||||
.code(fastify.statusCode.UNAUTHORIZED)
|
||||
.send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.statusCode.UNAUTHORIZED,
|
||||
fastify.apiError.BAD_USERNAME_PASSWORD
|
||||
)
|
||||
);
|
||||
}
|
||||
const restoredRemoteUser: RemoteUser = createRemoteUser(name, user?.groups || []);
|
||||
const token = await getApiToken(
|
||||
fastify.auth,
|
||||
fastify.configInstance,
|
||||
restoredRemoteUser,
|
||||
password
|
||||
);
|
||||
debug('login: new token');
|
||||
if (!token) {
|
||||
return reply.send(fastify.errorUtils.getUnauthorized());
|
||||
} else {
|
||||
reply.code(fastify.statusCode.CREATED);
|
||||
const message = authUtils.getAuthenticatedMessage(remoteName);
|
||||
debug('login: created user message %o', message);
|
||||
reply.send({
|
||||
ok: message,
|
||||
token,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
if (
|
||||
validationUtils.validatePassword(
|
||||
password as string,
|
||||
fastify.configInstance?.server?.passwordValidationRegex
|
||||
) === false
|
||||
) {
|
||||
debug('adduser: invalid password');
|
||||
reply.code(fastify.statusCode.BAD_REQUEST).send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.statusCode.BAD_REQUEST,
|
||||
// eslint-disable-next-line new-cap
|
||||
fastify.apiError.PASSWORD_SHORT
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
fastify.auth.add_user(name, password, async function (err, user): Promise<void> {
|
||||
if (err) {
|
||||
if (
|
||||
err.status >= fastify.statusCode.BAD_REQUEST &&
|
||||
err.status < fastify.statusCode.INTERNAL_ERROR
|
||||
) {
|
||||
debug('adduser: error on create user');
|
||||
// With npm registering is the same as logging in,
|
||||
// and npm accepts only an 409 error.
|
||||
// So, changing status code here.
|
||||
const addUserError =
|
||||
fastify.errorUtils.getCode(err.status, err.message) ||
|
||||
fastify.errorUtils.getConflict(err.message);
|
||||
|
||||
reply.send(addUserError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const token =
|
||||
name && password
|
||||
? await getApiToken(fastify.auth, fastify.configInstance, user as RemoteUser, password)
|
||||
: undefined;
|
||||
debug('adduser: new token %o', token);
|
||||
if (!token) {
|
||||
return reply.send(fastify.errorUtils.getUnauthorized());
|
||||
}
|
||||
debug('adduser: user has been created');
|
||||
reply.code(fastify.statusCode.CREATED).send({
|
||||
ok: `user '${name}' created`,
|
||||
token,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default userRoute;
|
||||
@@ -1,15 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:whoami');
|
||||
|
||||
async function whoamiRoute(fastify: FastifyInstance) {
|
||||
fastify.get('/-/whoami', async (request, reply) => {
|
||||
const username: string | void = request.userRemote.name;
|
||||
debug('whoami: response %o', username);
|
||||
reply.code(fastify.statusCode.OK);
|
||||
return { username };
|
||||
});
|
||||
}
|
||||
|
||||
export default whoamiRoute;
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './server';
|
||||
@@ -1,24 +0,0 @@
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import fp from 'fastify-plugin';
|
||||
|
||||
import { Auth } from '@verdaccio/auth';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { Config as IConfig } from '@verdaccio/types';
|
||||
|
||||
export default fp(
|
||||
async function (fastify: FastifyInstance, opts: { config: IConfig; filters?: unknown }) {
|
||||
const { config } = opts;
|
||||
const auth = new Auth(config, logger);
|
||||
await auth.init();
|
||||
fastify.decorate('auth', auth);
|
||||
},
|
||||
{
|
||||
fastify: '>=4.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
auth: Auth;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import fp from 'fastify-plugin';
|
||||
|
||||
import { Config as AppConfig } from '@verdaccio/config';
|
||||
import { ConfigYaml, Config as IConfig } from '@verdaccio/types';
|
||||
|
||||
export default fp(
|
||||
async function (fastify: FastifyInstance, opts: { config: ConfigYaml }) {
|
||||
const { config } = opts;
|
||||
const configInstance: IConfig = new AppConfig(Object.assign({}, config) as any);
|
||||
fastify.decorate('configInstance', configInstance);
|
||||
},
|
||||
{
|
||||
fastify: '>=4.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
configInstance: IConfig;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import fp from 'fastify-plugin';
|
||||
|
||||
import {
|
||||
API_ERROR,
|
||||
API_MESSAGE,
|
||||
HTTP_STATUS,
|
||||
constants,
|
||||
errorUtils,
|
||||
pluginUtils,
|
||||
searchUtils,
|
||||
streamUtils,
|
||||
validationUtils,
|
||||
warningUtils,
|
||||
} from '@verdaccio/core';
|
||||
|
||||
export default fp(
|
||||
async function (fastify) {
|
||||
fastify.decorate('errorUtils', errorUtils);
|
||||
fastify.decorate('searchUtils', searchUtils);
|
||||
fastify.decorate('streamUtils', streamUtils);
|
||||
fastify.decorate('validationUtils', validationUtils);
|
||||
fastify.decorate('pluginUtils', pluginUtils);
|
||||
fastify.decorate('warningUtils', warningUtils);
|
||||
fastify.decorate('apiError', API_ERROR);
|
||||
fastify.decorate('constants', constants);
|
||||
fastify.decorate('apiMessage', API_MESSAGE);
|
||||
fastify.decorate('statusCode', HTTP_STATUS);
|
||||
},
|
||||
{
|
||||
fastify: '>=4.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
apiError: typeof API_ERROR;
|
||||
apiMessage: typeof API_MESSAGE;
|
||||
statusCode: typeof HTTP_STATUS;
|
||||
errorUtils: typeof errorUtils;
|
||||
warningUtils: typeof warningUtils;
|
||||
searchUtils: typeof searchUtils;
|
||||
streamUtils: typeof streamUtils;
|
||||
pluginUtils: typeof pluginUtils;
|
||||
validationUtils: typeof validationUtils;
|
||||
constants: typeof constants;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import fp from 'fastify-plugin';
|
||||
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { Config as IConfig } from '@verdaccio/types';
|
||||
|
||||
export default fp(
|
||||
async function (fastify: FastifyInstance, opts: { config: IConfig; filters?: unknown }) {
|
||||
const { config } = opts;
|
||||
const storage: Storage = new Storage(config, logger);
|
||||
// @ts-ignore
|
||||
await storage.init(config, []);
|
||||
fastify.decorate('storage', storage);
|
||||
},
|
||||
{
|
||||
fastify: '>=4.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
storage: Storage;
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { validationUtils } from '@verdaccio/core';
|
||||
import { JWTSignOptions, RemoteUser } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:web:login');
|
||||
const loginBodySchema = {
|
||||
body: {
|
||||
type: 'object',
|
||||
required: ['username', 'password'],
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
password: { type: 'string' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const resetPasswordSchema = {
|
||||
body: {
|
||||
type: 'object',
|
||||
required: ['password'],
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
password: { type: 'string' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
async function loginRoute(fastify: FastifyInstance) {
|
||||
fastify.post(
|
||||
'/login',
|
||||
{
|
||||
schema: loginBodySchema,
|
||||
},
|
||||
async (request, reply) => {
|
||||
// @ts-expect-error
|
||||
const { username, password } = request.body;
|
||||
debug('authenticate %o', username);
|
||||
fastify.auth.authenticate(
|
||||
username,
|
||||
password,
|
||||
async function callbackAuthenticate(err, user): Promise<void> {
|
||||
if (err) {
|
||||
const errorCode = err.message
|
||||
? fastify.statusCode.UNAUTHORIZED
|
||||
: fastify.statusCode.INTERNAL_ERROR;
|
||||
reply.send(fastify.errorUtils.getCode(errorCode, err.message));
|
||||
} else {
|
||||
const jWTSignOptions: JWTSignOptions = fastify.configInstance.security.web.sign;
|
||||
debug('jwtSignOptions: %o', jWTSignOptions);
|
||||
const token = await fastify.auth.jwtEncrypt(user as RemoteUser, jWTSignOptions);
|
||||
reply.code(fastify.statusCode.OK).send({ token, username });
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
fastify.put(
|
||||
'/reset_password',
|
||||
{
|
||||
schema: resetPasswordSchema,
|
||||
},
|
||||
async (request, reply) => {
|
||||
if (_.isNil(request.userRemote.name)) {
|
||||
reply.send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.statusCode.UNAUTHORIZED,
|
||||
fastify.errorUtils.API_ERROR.MUST_BE_LOGGED
|
||||
)
|
||||
);
|
||||
}
|
||||
// @ts-ignore
|
||||
const { password } = request.body;
|
||||
const { name } = request.userRemote;
|
||||
|
||||
if (
|
||||
validationUtils.validatePassword(
|
||||
password.new,
|
||||
fastify.configInstance?.server?.passwordValidationRegex
|
||||
) === false
|
||||
) {
|
||||
reply.send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.statusCode.BAD_REQUEST,
|
||||
fastify.errorUtils.APP_ERROR.PASSWORD_VALIDATION
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
fastify.auth.changePassword(
|
||||
name as string,
|
||||
password.old,
|
||||
password.new,
|
||||
(err, isUpdated): void => {
|
||||
if (_.isNil(err) && isUpdated) {
|
||||
reply.code(fastify.statusCode.OK);
|
||||
} else {
|
||||
reply.send(
|
||||
fastify.errorUtils.getInternalError(
|
||||
fastify.errorUtils.API_ERROR.INTERNAL_SERVER_ERROR
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
// });
|
||||
}
|
||||
export default loginRoute;
|
||||
@@ -1,60 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { Manifest } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:web:readme');
|
||||
export const NOT_README_FOUND = 'ERROR: No README data found!';
|
||||
|
||||
async function readmeRoute(fastify: FastifyInstance) {
|
||||
fastify.get('/package/readme/:packageName', async (request, reply) => {
|
||||
// @ts-ignore
|
||||
const { version, packageName } = request.params;
|
||||
debug('readme name %s version: %s', packageName, version);
|
||||
const manifest = (await fastify.storage?.getPackageByOptions({
|
||||
name: packageName,
|
||||
// remove on refactor getPackageByOptions
|
||||
// @ts-ignore
|
||||
req: request.raw,
|
||||
version,
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
protocol: request.protocol,
|
||||
headers: request.headers as any,
|
||||
host: request.hostname,
|
||||
},
|
||||
})) as Manifest;
|
||||
try {
|
||||
const parsedReadme = manifest.readme;
|
||||
reply.code(fastify.statusCode.OK).send(parsedReadme);
|
||||
} catch {
|
||||
reply.code(fastify.statusCode.OK).send(NOT_README_FOUND);
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/package/readme/:scope/:packageName', async (request, reply) => {
|
||||
// @ts-ignore
|
||||
const { version, packageName } = request.params;
|
||||
debug('readme name %s version: %s', packageName, version);
|
||||
const manifest = (await fastify.storage?.getPackageByOptions({
|
||||
name: packageName,
|
||||
// remove on refactor getPackageByOptions
|
||||
// @ts-ignore
|
||||
req: request.raw,
|
||||
version,
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
protocol: request.protocol,
|
||||
headers: request.headers as any,
|
||||
host: request.hostname,
|
||||
},
|
||||
})) as Manifest;
|
||||
try {
|
||||
reply.code(fastify.statusCode.OK).send(manifest.readme);
|
||||
} catch {
|
||||
reply.code(fastify.statusCode.OK).send(NOT_README_FOUND);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default readmeRoute;
|
||||
@@ -1,82 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
import { Manifest, Version } from '@verdaccio/types';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:web:sidebar');
|
||||
export type $SidebarPackage = Manifest & { latest: Version };
|
||||
const stringType = { type: 'string' };
|
||||
const packageNameSchema = { packageName: stringType };
|
||||
const paramsSchema = {
|
||||
scope: stringType,
|
||||
packageName: stringType,
|
||||
};
|
||||
|
||||
async function sidebarRoute(fastify: FastifyInstance) {
|
||||
fastify.get(
|
||||
'/sidebar/:scope/:packageName',
|
||||
{
|
||||
schema: {
|
||||
params: paramsSchema,
|
||||
},
|
||||
},
|
||||
async (request, reply) => {
|
||||
// @ts-ignore
|
||||
const { packageName, scope } = request.params;
|
||||
debug('pkg name %s, scope %s ', packageName, scope);
|
||||
reply.code(fastify.statusCode.NOT_FOUND);
|
||||
}
|
||||
);
|
||||
|
||||
fastify.get(
|
||||
'/sidebar/:packageName',
|
||||
{
|
||||
schema: {
|
||||
params: packageNameSchema,
|
||||
},
|
||||
},
|
||||
async (request, reply) => {
|
||||
// @ts-ignore
|
||||
const { packageName, scope } = request.params;
|
||||
debug('pkg name %s, scope %s ', packageName, scope);
|
||||
reply.code(fastify.statusCode.NOT_FOUND);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// function getSidebar(fastify: FastifyInstance, request: any, packageName, callback) {
|
||||
// // fastify.storage.getPackage({
|
||||
// // name: packageName,
|
||||
// // uplinksLook: true,
|
||||
// // keepUpLinkData: true,
|
||||
// // req: request.raw,
|
||||
// // callback: function (err: Error, info: $SidebarPackage): void {
|
||||
// // debug('sidebar pkg info %o', info);
|
||||
// // if (_.isNil(err)) {
|
||||
// // const { v } = request.query;
|
||||
// // let sideBarInfo = _.clone(info);
|
||||
// // sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(
|
||||
// // info,
|
||||
// // { protocol: request.protocol, headers: request.headers as any, host: request.hostname },
|
||||
// // fastify.configInstance.url_prefix
|
||||
// // ).versions;
|
||||
// // if (typeof v === 'string' && isVersionValid(info, v)) {
|
||||
// // sideBarInfo.latest = sideBarInfo.versions[v];
|
||||
// // sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);
|
||||
// // } else {
|
||||
// // sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest];
|
||||
// // sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);
|
||||
// // }
|
||||
// // sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo);
|
||||
// // const authorAvatar = fastify.configInstance.web
|
||||
// // ? addGravatarSupport(sideBarInfo, fastify.configInstance.web.gravatar)
|
||||
// // : addGravatarSupport(sideBarInfo);
|
||||
// // callback(null, authorAvatar);
|
||||
// // } else {
|
||||
// // callback(fastify.statusCode.NOT_FOUND).send(err);
|
||||
// // }
|
||||
// // },
|
||||
// // });
|
||||
// reply.code(fastify.statusCode.NOT_FOUND);
|
||||
// }
|
||||
export default sidebarRoute;
|
||||
@@ -1,74 +0,0 @@
|
||||
import buildDebug from 'debug';
|
||||
import fastify from 'fastify';
|
||||
|
||||
import { Config as AppConfig, createAnonymousRemoteUser } from '@verdaccio/config';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { ConfigYaml, Config as IConfig, RemoteUser } from '@verdaccio/types';
|
||||
|
||||
import distTags from './endpoints/dist-tags';
|
||||
import manifest from './endpoints/manifest';
|
||||
import ping from './endpoints/ping';
|
||||
import search from './endpoints/search';
|
||||
import tarball from './endpoints/tarball';
|
||||
import user from './endpoints/user';
|
||||
import whoami from './endpoints/whoami';
|
||||
import authPlugin from './plugins/auth';
|
||||
import configPlugin from './plugins/config';
|
||||
import coreUtils from './plugins/coreUtils';
|
||||
import storagePlugin from './plugins/storage';
|
||||
import login from './routes/web/api/login';
|
||||
import readme from './routes/web/api/readme';
|
||||
import sidebar from './routes/web/api/sidebar';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify');
|
||||
enum PREFIX {
|
||||
WEB = '/-/verdaccio',
|
||||
USER = '/-/user',
|
||||
}
|
||||
|
||||
async function startServer(config: ConfigYaml): Promise<any> {
|
||||
// eslint-disable-next-line prettier/prettier
|
||||
const configInstance: IConfig = new AppConfig({ ...config } as any);
|
||||
debug('start fastify server');
|
||||
// TODO: custom logger type and logger accepted by fastify does not match
|
||||
const fastifyInstance = fastify({ logger: logger as any });
|
||||
fastifyInstance.addHook('onRequest', (request, reply, done) => {
|
||||
request.userRemote = createAnonymousRemoteUser();
|
||||
done();
|
||||
});
|
||||
fastifyInstance.register(coreUtils);
|
||||
fastifyInstance.register(configPlugin, { config });
|
||||
fastifyInstance.register(storagePlugin, { config: configInstance });
|
||||
fastifyInstance.register(authPlugin, { config: configInstance });
|
||||
|
||||
// api
|
||||
fastifyInstance.register((instance, opts, done) => {
|
||||
instance.register(ping);
|
||||
instance.register(user, { prefix: PREFIX.USER });
|
||||
instance.register(search);
|
||||
instance.register(whoami);
|
||||
instance.register(manifest);
|
||||
instance.register(tarball);
|
||||
instance.register(distTags);
|
||||
instance.register(readme, { prefix: PREFIX.WEB });
|
||||
instance.register(sidebar, { prefix: PREFIX.WEB });
|
||||
instance.register(login, { prefix: PREFIX.WEB });
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
// web
|
||||
fastifyInstance.register((instance, opts, done) => {
|
||||
instance.register(ping, { prefix: '/web' });
|
||||
done();
|
||||
});
|
||||
return fastifyInstance;
|
||||
}
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyRequest {
|
||||
userRemote: RemoteUser;
|
||||
}
|
||||
}
|
||||
|
||||
export default startServer;
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./build"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.reference.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./build"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["src/**/*.test.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../store"
|
||||
},
|
||||
{
|
||||
"path": "../../config"
|
||||
},
|
||||
{
|
||||
"path": "../../auth"
|
||||
},
|
||||
{
|
||||
"path": "../../logger/logger"
|
||||
},
|
||||
{
|
||||
"path": "../../utils"
|
||||
},
|
||||
{
|
||||
"path": "../../core/core"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -57,7 +57,6 @@
|
||||
"@verdaccio/store": "workspace:8.0.0-next-8.24",
|
||||
"@verdaccio/test-helper": "workspace:4.0.0-next-8.8",
|
||||
"@verdaccio/types": "workspace:13.0.0-next-8.8",
|
||||
"fastify": "4.25.2",
|
||||
"get-port": "5.1.1",
|
||||
"got": "11.8.6",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import fastify, { FastifyInstance } from 'fastify';
|
||||
|
||||
/**
|
||||
* Simple Server
|
||||
*
|
||||
* A empty express server with the objective to emumate any external API.
|
||||
*
|
||||
* eg: test/functional/tags/tags.ts
|
||||
*
|
||||
* express.get('/testexp_tags', function(req, res) {
|
||||
let f = readTags().toString().replace(/__NAME__/g, 'testexp_tags');
|
||||
res.send(JSON.parse(f));
|
||||
});
|
||||
*
|
||||
* or at test/functional/package/gzip.ts
|
||||
*/
|
||||
export default class SimpleServer {
|
||||
public server: FastifyInstance;
|
||||
|
||||
public constructor() {
|
||||
this.server = fastify({ logger: true });
|
||||
}
|
||||
|
||||
public async start(port: number = 55550): Promise<void> {
|
||||
await this.server.listen(port);
|
||||
// prevent keeping the process running.
|
||||
this.server.server.unref();
|
||||
}
|
||||
}
|
||||
556
pnpm-lock.yaml
generated
556
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user