@verdaccio/core 8.0.0-next-8.11 → 8.0.0-next-8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,106 +0,0 @@
1
- import createError, { HttpError } from 'http-errors';
2
-
3
- import { HTTP_STATUS } from './constants';
4
-
5
- export const API_ERROR = {
6
- PASSWORD_SHORT: 'The provided password does not pass the validation',
7
- MUST_BE_LOGGED: 'You must be logged in to publish packages.',
8
- PLUGIN_ERROR: 'bug in the auth plugin system',
9
- CONFIG_BAD_FORMAT: 'config file must be an object',
10
- BAD_USERNAME_PASSWORD: 'bad username/password, access denied',
11
- NO_PACKAGE: 'no such package available',
12
- PACKAGE_CANNOT_BE_ADDED: 'this package cannot be added',
13
- BAD_DATA: 'bad data',
14
- NOT_ALLOWED: 'not allowed to access package',
15
- NOT_ALLOWED_PUBLISH: 'not allowed to publish package',
16
- INTERNAL_SERVER_ERROR: 'internal server error',
17
- UNKNOWN_ERROR: 'unknown error',
18
- NOT_PACKAGE_UPLINK: 'package does not exist on uplink',
19
- UPLINK_OFFLINE_PUBLISH: 'one of the uplinks is down, refuse to publish',
20
- UPLINK_OFFLINE: 'uplink is offline',
21
- NOT_MODIFIED_NO_DATA: 'no data',
22
- CONTENT_MISMATCH: 'content length mismatch',
23
- NOT_FILE_UPLINK: "file doesn't exist on uplink",
24
- MAX_USERS_REACHED: 'maximum amount of users reached',
25
- VERSION_NOT_EXIST: "this version doesn't exist",
26
- NO_SUCH_FILE: 'no such file available',
27
- UNSUPORTED_REGISTRY_CALL: 'unsupported registry call',
28
- FILE_NOT_FOUND: 'File not found',
29
- REGISTRATION_DISABLED: 'user registration disabled',
30
- UNAUTHORIZED_ACCESS: 'unauthorized access',
31
- BAD_STATUS_CODE: 'bad status code',
32
- SERVER_TIME_OUT: 'looks like the server is taking to long to respond',
33
- PACKAGE_EXIST: 'this package is already present',
34
- BAD_AUTH_HEADER: 'bad authorization header',
35
- WEB_DISABLED: 'Web interface is disabled in the config file',
36
- DEPRECATED_BASIC_HEADER: 'basic authentication is deprecated, please use JWT instead',
37
- BAD_FORMAT_USER_GROUP: 'user groups is different than an array',
38
- RESOURCE_UNAVAILABLE: 'resource unavailable',
39
- BAD_PACKAGE_DATA: 'bad incoming package data',
40
- USERNAME_PASSWORD_REQUIRED: 'username and password is required',
41
- USERNAME_ALREADY_REGISTERED: 'username is already registered',
42
- USERNAME_MISMATCH: 'username does not match logged in user',
43
- };
44
-
45
- export const SUPPORT_ERRORS = {
46
- PLUGIN_MISSING_INTERFACE: 'the plugin does not provide implementation of the requested feature',
47
- TFA_DISABLED: 'the two-factor authentication is not yet supported',
48
- STORAGE_NOT_IMPLEMENT: 'the storage does not support token saving',
49
- PARAMETERS_NOT_VALID: 'the parameters are not valid',
50
- };
51
-
52
- export const APP_ERROR = {
53
- CONFIG_NOT_VALID: 'CONFIG: it does not look like a valid config file',
54
- PROFILE_ERROR: 'profile unexpected error',
55
- PASSWORD_VALIDATION: 'not valid password',
56
- };
57
-
58
- export type VerdaccioError = HttpError & { code: number };
59
-
60
- function getError(code: number, message: string): VerdaccioError {
61
- const httpError = createError(code, message);
62
-
63
- httpError.code = code;
64
-
65
- return httpError as VerdaccioError;
66
- }
67
-
68
- export function getConflict(message: string = API_ERROR.PACKAGE_EXIST): VerdaccioError {
69
- return getError(HTTP_STATUS.CONFLICT, message);
70
- }
71
-
72
- export function getBadData(customMessage?: string): VerdaccioError {
73
- return getError(HTTP_STATUS.BAD_DATA, customMessage || API_ERROR.BAD_DATA);
74
- }
75
-
76
- export function getBadRequest(customMessage: string): VerdaccioError {
77
- return getError(HTTP_STATUS.BAD_REQUEST, customMessage);
78
- }
79
-
80
- export function getInternalError(customMessage?: string): VerdaccioError {
81
- return customMessage
82
- ? getError(HTTP_STATUS.INTERNAL_ERROR, customMessage)
83
- : getError(HTTP_STATUS.INTERNAL_ERROR, API_ERROR.UNKNOWN_ERROR);
84
- }
85
-
86
- export function getUnauthorized(message = 'no credentials provided'): VerdaccioError {
87
- return getError(HTTP_STATUS.UNAUTHORIZED, message);
88
- }
89
-
90
- export function getForbidden(message = "can't use this filename"): VerdaccioError {
91
- return getError(HTTP_STATUS.FORBIDDEN, message);
92
- }
93
-
94
- export function getServiceUnavailable(
95
- message: string = API_ERROR.RESOURCE_UNAVAILABLE
96
- ): VerdaccioError {
97
- return getError(HTTP_STATUS.SERVICE_UNAVAILABLE, message);
98
- }
99
-
100
- export function getNotFound(customMessage?: string): VerdaccioError {
101
- return getError(HTTP_STATUS.NOT_FOUND, customMessage || API_ERROR.NO_PACKAGE);
102
- }
103
-
104
- export function getCode(statusCode: number, customMessage: string): VerdaccioError {
105
- return getError(statusCode, customMessage);
106
- }
package/src/file-utils.ts DELETED
@@ -1,31 +0,0 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
-
5
- export const Files = {
6
- DatabaseName: '.verdaccio-db.json',
7
- };
8
-
9
- const { mkdir, mkdtemp } = fs.promises ? fs.promises : require('fs/promises');
10
-
11
- /**
12
- * Create a temporary folder.
13
- * @param prefix The prefix of the folder name.
14
- * @returns string
15
- */
16
- export async function createTempFolder(prefix: string): Promise<string> {
17
- return await mkdtemp(path.join(os.tmpdir(), 'verdaccio-' + prefix + '-'));
18
- }
19
-
20
- /**
21
- * Create temporary folder for an asset.
22
- * @param prefix
23
- * @param folder name
24
- * @returns
25
- */
26
- export async function createTempStorageFolder(prefix: string, folder = 'storage'): Promise<string> {
27
- const tempFolder = await createTempFolder(prefix);
28
- const storageFolder = path.join(tempFolder, folder);
29
- await mkdir(storageFolder);
30
- return storageFolder;
31
- }
package/src/index.ts DELETED
@@ -1,46 +0,0 @@
1
- import * as constants from './constants';
2
- import * as errorUtils from './error-utils';
3
- import * as fileUtils from './file-utils';
4
- import * as pkgUtils from './pkg-utils';
5
- import * as pluginUtils from './plugin-utils';
6
- import * as searchUtils from './search-utils';
7
- import * as streamUtils from './stream-utils';
8
- import * as stringUtils from './string-utils';
9
- import * as tarballUtils from './tarball-utils';
10
- import * as validatioUtils from './validation-utils';
11
- import * as warningUtils from './warning-utils';
12
-
13
- export { VerdaccioError, API_ERROR, SUPPORT_ERRORS, APP_ERROR } from './error-utils';
14
- export {
15
- TOKEN_BASIC,
16
- TOKEN_BEARER,
17
- HTTP_STATUS,
18
- API_MESSAGE,
19
- HEADERS,
20
- DIST_TAGS,
21
- CHARACTER_ENCODING,
22
- HEADER_TYPE,
23
- LATEST,
24
- DEFAULT_PASSWORD_VALIDATION,
25
- DEFAULT_USER,
26
- USERS,
27
- MAINTAINERS,
28
- PLUGIN_CATEGORY,
29
- HtpasswdHashAlgorithm,
30
- } from './constants';
31
- const validationUtils = validatioUtils;
32
- export {
33
- fileUtils,
34
- pkgUtils,
35
- searchUtils,
36
- streamUtils,
37
- errorUtils,
38
- // TODO: remove this typo
39
- validatioUtils,
40
- validationUtils,
41
- stringUtils,
42
- constants,
43
- pluginUtils,
44
- warningUtils,
45
- tarballUtils,
46
- };
package/src/path-utils.ts DELETED
File without changes
package/src/pkg-utils.ts DELETED
@@ -1,68 +0,0 @@
1
- import semver from 'semver';
2
-
3
- import { Manifest } from '@verdaccio/types';
4
-
5
- import { DIST_TAGS } from './constants';
6
-
7
- /**
8
- * Function filters out bad semver versions and sorts the array.
9
- * @return {Array} sorted Array
10
- */
11
- export function semverSort(listVersions: string[]): string[] {
12
- return listVersions
13
- .filter(function (x): boolean {
14
- if (!semver.parse(x, true)) {
15
- return false;
16
- }
17
- return true;
18
- })
19
- .sort(semver.compareLoose)
20
- .map(String);
21
- }
22
-
23
- /**
24
- * Get the latest publihsed version of a package.
25
- * @param package metadata
26
- **/
27
- export function getLatest(pkg: Manifest): string {
28
- const listVersions: string[] = Object.keys(pkg.versions);
29
- if (listVersions.length < 1) {
30
- throw Error('cannot get lastest version of none');
31
- }
32
-
33
- const versions: string[] = semverSort(listVersions);
34
- const latest: string | undefined = pkg[DIST_TAGS]?.latest ? pkg[DIST_TAGS].latest : versions[0];
35
-
36
- return latest;
37
- }
38
-
39
- /**
40
- * Function gets a local info and an info from uplinks and tries to merge it
41
- exported for unit tests only.
42
- * @param {*} local
43
- * @param {*} upstream
44
- * @param {*} config sds
45
- * @deprecated use @verdaccio/storage mergeVersions method
46
- */
47
- // @deprecated
48
- export function mergeVersions(local: Manifest, upstream: Manifest) {
49
- // copy new versions to a cache
50
- // NOTE: if a certain version was updated, we can't refresh it reliably
51
- for (const i in upstream.versions) {
52
- if (typeof local.versions[i] === 'undefined') {
53
- local.versions[i] = upstream.versions[i];
54
- }
55
- }
56
-
57
- for (const i in upstream[DIST_TAGS]) {
58
- if (local[DIST_TAGS][i] !== upstream[DIST_TAGS][i]) {
59
- if (!local[DIST_TAGS][i] || semver.lte(local[DIST_TAGS][i], upstream[DIST_TAGS][i])) {
60
- local[DIST_TAGS][i] = upstream[DIST_TAGS][i];
61
- }
62
- if (i === 'latest' && local[DIST_TAGS][i] === upstream[DIST_TAGS][i]) {
63
- // if remote has more fresh package, we should borrow its readme
64
- local.readme = upstream.readme;
65
- }
66
- }
67
- }
68
- }
@@ -1,205 +0,0 @@
1
- import { Express, RequestHandler } from 'express';
2
- import { Readable, Writable } from 'stream';
3
-
4
- import {
5
- AllowAccess,
6
- Callback,
7
- Config,
8
- Logger,
9
- Manifest,
10
- PackageAccess,
11
- RemoteUser,
12
- Token,
13
- TokenFilter,
14
- } from '@verdaccio/types';
15
-
16
- import { VerdaccioError, searchUtils } from '.';
17
-
18
- export interface PluginOptions {
19
- config: Config;
20
- logger: Logger;
21
- }
22
-
23
- /**
24
- * Base Plugin Class
25
- *
26
- * Set of utilities for developing plugins.
27
- */
28
- export class Plugin<PluginConfig> {
29
- static version = 1;
30
- public readonly version: number;
31
- public readonly config: PluginConfig | unknown;
32
- public readonly options: PluginOptions;
33
- public constructor(config: PluginConfig, options: PluginOptions) {
34
- this.version = Plugin.version;
35
- this.config = config;
36
- this.options = options;
37
- }
38
-
39
- public getVersion() {
40
- return this.version;
41
- }
42
- }
43
-
44
- // --- STORAGE PLUGIN ---
45
-
46
- /**
47
- * Storage Handler
48
- *
49
- * Used in storage plugin for managing packages and tarballs.
50
- */
51
- export interface StorageHandler {
52
- logger: Logger;
53
- deletePackage(fileName: string): Promise<void>;
54
- removePackage(): Promise<void>;
55
- // next packages migration (this list is meant to replace the callback parent functions)
56
- updatePackage(
57
- packageName: string,
58
- handleUpdate: (manifest: Manifest) => Promise<Manifest>
59
- ): Promise<Manifest>;
60
- readPackage(packageName: string): Promise<Manifest>;
61
- savePackage(packageName: string, manifest: Manifest): Promise<void>;
62
- readTarball(fileName: string, { signal }: { signal: AbortSignal }): Promise<Readable>;
63
- createPackage(packageName: string, manifest: Manifest): Promise<void>;
64
- writeTarball(fileName: string, { signal }: { signal: AbortSignal }): Promise<Writable>;
65
- // verify if tarball exist in the storage
66
- hasTarball(fileName: string): Promise<boolean>;
67
- // verify if package exist in the storage
68
- hasPackage(): Promise<boolean>;
69
- }
70
-
71
- /**
72
- * Storage Plugin interface
73
- *
74
- * https://verdaccio.org/docs/next/plugin-storage
75
- */
76
- export interface Storage<PluginConfig> extends Plugin<PluginConfig> {
77
- add(packageName: string): Promise<void>;
78
- remove(packageName: string): Promise<void>;
79
- get(): Promise<string[]>;
80
- init(): Promise<void>;
81
- getSecret(): Promise<string>;
82
- setSecret(secret: string): Promise<any>;
83
- getPackageStorage(packageName: string): StorageHandler;
84
- search(query: searchUtils.SearchQuery): Promise<searchUtils.SearchItem[]>;
85
- saveToken(token: Token): Promise<any>;
86
- deleteToken(user: string, tokenKey: string): Promise<any>;
87
- readTokens(filter: TokenFilter): Promise<Token[]>;
88
- }
89
-
90
- // --- MIDDLEWARE PLUGIN ---
91
-
92
- /**
93
- * Middleware Plugin Interface
94
- *
95
- * https://verdaccio.org/docs/next/plugin-middleware
96
- *
97
- * This function allow add middleware to the application.
98
- *
99
- * ```ts
100
- * import express, { Request, Response } from 'express';
101
- *
102
- * class Middleware extends Plugin {
103
- * // instances of auth and storage are injected
104
- * register_middlewares(app, auth, storage) {
105
- * const router = express.Router();
106
- * router.post('/my-endpoint', (req: Request, res: Response): void => {
107
- res.status(200).end();
108
- });
109
- * }
110
- * }
111
- *
112
- * const [plugin] = await asyncLoadPlugin(...);
113
- * plugin.register_middlewares(app, auth, storage);
114
- * ```
115
- */
116
- export interface ExpressMiddleware<PluginConfig, Storage, Auth> extends Plugin<PluginConfig> {
117
- register_middlewares(app: Express, auth: Auth, storage: Storage): void;
118
- }
119
-
120
- // --- AUTH PLUGIN ---
121
-
122
- export type AuthCallback = (error: VerdaccioError | null, groups?: string[] | false) => void;
123
-
124
- export type AuthAccessCallback = (error: VerdaccioError | null, access?: boolean) => void;
125
- export type AuthUserCallback = (error: VerdaccioError | null, access?: boolean | string) => void;
126
- export type AuthChangePasswordCallback = (error: VerdaccioError | null, access?: boolean) => void;
127
- export type AccessCallback = (error: VerdaccioError | null, ok?: boolean) => void;
128
-
129
- export interface AuthPluginPackage {
130
- packageName: string;
131
- packageVersion?: string;
132
- tag?: string;
133
- }
134
-
135
- /**
136
- * Authentication Plugin Interface
137
- *
138
- * https://verdaccio.org/docs/next/plugin-auth
139
- */
140
- export interface Auth<T> extends Plugin<T> {
141
- /**
142
- * Handles the authenticated method.
143
- * ```ts
144
- * class Auth {
145
- public authenticate(user: string, password: string, done: AuthCallback): void {
146
- if (!password) {
147
- return done(errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
148
- }
149
- // always return an array of users
150
- return done(null, [user]);
151
- * }
152
- * ```
153
- */
154
- authenticate(user: string, password: string, cb: AuthCallback): void;
155
- /**
156
- * Handles the authenticated method.
157
- * ```ts
158
- * class Auth {
159
- public adduser(user: string, password: string, done: AuthCallback): void {
160
- if (!password) {
161
- return done(errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
162
- }
163
- // return boolean
164
- return done(null, true);
165
- * }
166
- * ```
167
- */
168
- adduser?(user: string, password: string, cb: AuthUserCallback): void;
169
- changePassword?(
170
- user: string,
171
- password: string,
172
- newPassword: string,
173
- cb: AuthChangePasswordCallback
174
- ): void;
175
- allow_publish?(user: RemoteUser, pkg: T & PackageAccess, cb: AuthAccessCallback): void;
176
- allow_publish?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
177
- allow_access?(user: RemoteUser, pkg: T & PackageAccess, cb: AccessCallback): void;
178
- allow_access?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AccessCallback): void;
179
- allow_unpublish?(user: RemoteUser, pkg: T & PackageAccess, cb: AuthAccessCallback): void;
180
- allow_unpublish?(
181
- user: RemoteUser,
182
- pkg: AllowAccess & PackageAccess,
183
- cb: AuthAccessCallback
184
- ): void;
185
- apiJWTmiddleware?(helpers: any): RequestHandler;
186
- }
187
-
188
- export interface IBasicAuth {
189
- authenticate(user: string, password: string, cb: Callback): void;
190
- invalidateToken?(token: string): Promise<void>;
191
- changePassword(user: string, password: string, newPassword: string, cb: Callback): void;
192
- allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
193
- add_user(user: string, password: string, cb: Callback): any;
194
- }
195
-
196
- // --- FILTER PLUGIN ---
197
-
198
- /**
199
- * Filter Plugin Interface
200
- *
201
- * https://verdaccio.org/docs/next/plugin-filter
202
- */
203
- export interface ManifestFilter<T> extends Plugin<T> {
204
- filter_metadata(manifest: Manifest): Promise<Manifest>;
205
- }
@@ -1,38 +0,0 @@
1
- import Ajv, { JSONSchemaType } from 'ajv';
2
-
3
- const ajv = new Ajv();
4
-
5
- // FIXME: this could extend from @verdaccio/types but we need
6
- // schemas from @verdaccio/types to be able to validate them
7
- interface Manifest {
8
- name: string;
9
- versions: object;
10
- _attachments: object;
11
- }
12
-
13
- const schema: JSONSchemaType<Manifest> = {
14
- type: 'object',
15
- properties: {
16
- name: { type: 'string' },
17
- versions: { type: 'object', maxProperties: 1 },
18
- _attachments: { type: 'object', maxProperties: 1 },
19
- },
20
- required: ['name', 'versions', '_attachments'],
21
- additionalProperties: true,
22
- };
23
-
24
- // validate is a type guard for MyData - type is inferred from schema type
25
- const validate = ajv.compile(schema);
26
-
27
- /**
28
- * Validate if a manifest has the correct structure when a new package
29
- * is being created. The properties name, versions and _attachments must contain 1 element.
30
- * @param data a manifest object
31
- * @returns boolean
32
- */
33
- export function validatePublishSingleVersion(manifest: any) {
34
- if (!manifest) {
35
- return false;
36
- }
37
- return validate(manifest);
38
- }
@@ -1,69 +0,0 @@
1
- import Ajv, { JSONSchemaType } from 'ajv';
2
-
3
- const ajv = new Ajv();
4
-
5
- interface Manifest {
6
- name: string;
7
- versions: Record<string, unknown>;
8
- _rev: string;
9
- _id: string;
10
- time: {
11
- created: string;
12
- modified: string;
13
- [key: string]: string; // Allows pattern properties such as version numbers
14
- };
15
- readme: string;
16
- 'dist-tags': {
17
- latest: string;
18
- [key: string]: unknown; // Allows additional properties
19
- };
20
- }
21
-
22
- // @ts-ignore
23
- const schema: JSONSchemaType<Manifest> = {
24
- type: 'object',
25
- properties: {
26
- name: { type: 'string' },
27
- versions: { type: 'object', minProperties: 1 },
28
- _rev: { type: 'string' },
29
- _id: { type: 'string' },
30
- time: {
31
- type: 'object',
32
- properties: {
33
- created: { type: 'string' },
34
- modified: { type: 'string' },
35
- },
36
- patternProperties: {
37
- '^[0-9]+\\.[0-9]+\\.[0-9]+-\\d+$': { type: 'string' },
38
- },
39
- additionalProperties: true,
40
- },
41
- readme: { type: 'string' },
42
- 'dist-tags': {
43
- type: 'object',
44
- properties: {
45
- latest: { type: 'string' },
46
- },
47
- required: ['latest'],
48
- additionalProperties: true,
49
- },
50
- },
51
- required: ['name', 'versions', 'dist-tags', '_rev', '_id', 'readme', 'time'],
52
- additionalProperties: true,
53
- };
54
-
55
- // validate is a type guard for MyData - type is inferred from schema type
56
- const validate = ajv.compile(schema);
57
-
58
- /**
59
- * Validate if a manifest has the correct structure when a new package
60
- * is being created. The properties name, versions and _attachments must contain 1 element.
61
- * @param data a manifest object
62
- * @returns boolean
63
- */
64
- export function validateUnPublishSingleVersion(manifest: any) {
65
- if (!manifest) {
66
- return false;
67
- }
68
- return validate(manifest);
69
- }
@@ -1,81 +0,0 @@
1
- export type SearchMetrics = {
2
- quality: number;
3
- popularity: number;
4
- maintenance: number;
5
- };
6
- export type UnStable = {
7
- flags?: {
8
- // if is false is not be included in search results (majority are stable)
9
- unstable?: boolean;
10
- };
11
- };
12
- export type SearchItemPkg = {
13
- name: string;
14
- scoped?: string;
15
- path?: string;
16
- time?: number | Date;
17
- };
18
-
19
- type PrivatePackage = {
20
- // note: prefixed to avoid external conflicts
21
-
22
- // the package is published as private
23
- verdaccioPrivate?: boolean;
24
- // if the package is not private but is cached
25
- verdaccioPkgCached?: boolean;
26
- };
27
-
28
- export interface SearchItem extends UnStable, PrivatePackage {
29
- package: SearchItemPkg;
30
- score: Score;
31
- }
32
-
33
- export type Score = {
34
- final: number;
35
- detail: SearchMetrics;
36
- };
37
-
38
- export type SearchResults = {
39
- objects: SearchItemPkg[];
40
- total: number;
41
- time: string;
42
- };
43
-
44
- // @deprecated use @verdaccio/types
45
- type PublisherMaintainer = {
46
- username: string;
47
- email: string;
48
- };
49
-
50
- // @deprecated use @verdaccio/types
51
- export type SearchPackageBody = {
52
- name: string;
53
- scope: string;
54
- description: string;
55
- author: string | PublisherMaintainer;
56
- version: string;
57
- keywords: string | string[] | undefined;
58
- date: string;
59
- links?: {
60
- npm: string; // only include placeholder for URL eg: {url}/{packageName}
61
- homepage?: string;
62
- repository?: string;
63
- bugs?: string;
64
- };
65
- publisher?: any;
66
- maintainers?: PublisherMaintainer[];
67
- };
68
-
69
- export interface SearchPackageItem extends UnStable, PrivatePackage {
70
- package: SearchPackageBody;
71
- score: Score;
72
- searchScore?: number;
73
- }
74
-
75
- export const UNSCOPED = 'unscoped';
76
-
77
- export type SearchQuery = {
78
- text: string;
79
- size?: number;
80
- from?: number;
81
- } & SearchMetrics;
@@ -1,28 +0,0 @@
1
- import { Readable, Transform } from 'stream';
2
-
3
- /**
4
- * Converts a buffer stream to a string.
5
- */
6
- const readableToString = async (stream: Readable) => {
7
- const chunks: Buffer[] = [];
8
- for await (let chunk of stream) {
9
- chunks.push(Buffer.from(chunk));
10
- }
11
- const buffer = Buffer.concat(chunks);
12
- const str = buffer.toString('utf-8');
13
- return str;
14
- };
15
-
16
- /**
17
- * Transform stream object mode to string
18
- **/
19
- const transformObjectToString = () => {
20
- return new Transform({
21
- objectMode: true,
22
- transform: (chunk, encoding, callback) => {
23
- callback(null, JSON.stringify(chunk));
24
- },
25
- });
26
- };
27
-
28
- export { readableToString, transformObjectToString };