@verdaccio/core 6.0.0-6-next.47 → 6.0.0-6-next.49
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.
- package/CHANGELOG.md +12 -0
- package/build/constants.d.ts +2 -1
- package/build/constants.js +4 -3
- package/build/constants.js.map +1 -1
- package/build/error-utils.d.ts +1 -1
- package/build/error-utils.js +1 -1
- package/build/error-utils.js.map +1 -1
- package/build/index.d.ts +3 -2
- package/build/index.js +7 -3
- package/build/index.js.map +1 -1
- package/build/plugin-utils.d.ts +126 -10
- package/build/plugin-utils.js +23 -0
- package/build/plugin-utils.js.map +1 -1
- package/build/stream-utils.d.ts +3 -37
- package/build/stream-utils.js +1 -79
- package/build/stream-utils.js.map +1 -1
- package/build/string-utils.d.ts +8 -0
- package/build/string-utils.js +44 -0
- package/build/string-utils.js.map +1 -0
- package/build/validation-utils.d.ts +1 -0
- package/build/validation-utils.js +5 -0
- package/build/validation-utils.js.map +1 -1
- package/build/warning-utils.d.ts +1 -1
- package/build/warning-utils.js.map +1 -1
- package/package.json +6 -3
- package/src/constants.ts +2 -1
- package/src/error-utils.ts +2 -4
- package/src/index.ts +3 -1
- package/src/plugin-utils.ts +159 -9
- package/src/stream-utils.ts +3 -84
- package/src/string-utils.ts +36 -0
- package/src/validation-utils.ts +10 -1
- package/src/warning-utils.ts +1 -1
- package/test/mystreams.spec.ts +1 -27
- package/test/string-utils.spec.ts +40 -0
- package/test/validation-utilts.spec.ts +52 -1
- package/tsconfig.build.json +2 -1
- package/tsconfig.json +2 -1
- package/typedoc.json +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-utils.js","names":["getByQualityPriorityValue","headerValue","split","length","qList","header","reduce","acc","item","accept","q","query","push","trim","sort","a","b"],"sources":["../src/string-utils.ts"],"sourcesContent":["/**\n * Quality values, or q-values and q-factors, are used to describe the order\n * of priority of values in a comma-separated list.\n * It is a special syntax allowed in some HTTP headers and in HTML.\n * https://developer.mozilla.org/en-US/docs/Glossary/Quality_values\n * @param headerValue\n */\nexport function getByQualityPriorityValue(headerValue: string | undefined | null): string {\n if (typeof headerValue !== 'string') {\n return '';\n }\n\n const split = headerValue.split(',');\n\n if (split.length <= 1) {\n const qList = split[0].split(';');\n return qList[0];\n }\n\n let [header] = split\n .reduce((acc, item: string) => {\n const qList = item.split(';');\n if (qList.length > 1) {\n const [accept, q] = qList;\n const [, query] = q.split('=');\n acc.push([accept.trim(), query ? query : 0]);\n } else {\n acc.push([qList[0], 0]);\n }\n return acc;\n }, [] as any)\n .sort(function (a: number[], b: number[]) {\n return b[1] - a[1];\n });\n return header[0];\n}\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,yBAAT,CAAmCC,WAAnC,EAAmF;EACxF,IAAI,OAAOA,WAAP,KAAuB,QAA3B,EAAqC;IACnC,OAAO,EAAP;EACD;;EAED,MAAMC,KAAK,GAAGD,WAAW,CAACC,KAAZ,CAAkB,GAAlB,CAAd;;EAEA,IAAIA,KAAK,CAACC,MAAN,IAAgB,CAApB,EAAuB;IACrB,MAAMC,KAAK,GAAGF,KAAK,CAAC,CAAD,CAAL,CAASA,KAAT,CAAe,GAAf,CAAd;IACA,OAAOE,KAAK,CAAC,CAAD,CAAZ;EACD;;EAED,IAAI,CAACC,MAAD,IAAWH,KAAK,CACjBI,MADY,CACL,CAACC,GAAD,EAAMC,IAAN,KAAuB;IAC7B,MAAMJ,KAAK,GAAGI,IAAI,CAACN,KAAL,CAAW,GAAX,CAAd;;IACA,IAAIE,KAAK,CAACD,MAAN,GAAe,CAAnB,EAAsB;MACpB,MAAM,CAACM,MAAD,EAASC,CAAT,IAAcN,KAApB;MACA,MAAM,GAAGO,KAAH,IAAYD,CAAC,CAACR,KAAF,CAAQ,GAAR,CAAlB;MACAK,GAAG,CAACK,IAAJ,CAAS,CAACH,MAAM,CAACI,IAAP,EAAD,EAAgBF,KAAK,GAAGA,KAAH,GAAW,CAAhC,CAAT;IACD,CAJD,MAIO;MACLJ,GAAG,CAACK,IAAJ,CAAS,CAACR,KAAK,CAAC,CAAD,CAAN,EAAW,CAAX,CAAT;IACD;;IACD,OAAOG,GAAP;EACD,CAXY,EAWV,EAXU,EAYZO,IAZY,CAYP,UAAUC,CAAV,EAAuBC,CAAvB,EAAoC;IACxC,OAAOA,CAAC,CAAC,CAAD,CAAD,GAAOD,CAAC,CAAC,CAAD,CAAf;EACD,CAdY,CAAf;EAeA,OAAOV,MAAM,CAAC,CAAD,CAAb;AACD"}
|
|
@@ -8,6 +8,7 @@ exports.isPackageNameScoped = isPackageNameScoped;
|
|
|
8
8
|
exports.normalizeMetadata = normalizeMetadata;
|
|
9
9
|
exports.validateName = validateName;
|
|
10
10
|
exports.validatePackage = validatePackage;
|
|
11
|
+
exports.validatePassword = validatePassword;
|
|
11
12
|
Object.defineProperty(exports, "validatePublishSingleVersion", {
|
|
12
13
|
enumerable: true,
|
|
13
14
|
get: function () {
|
|
@@ -123,4 +124,8 @@ function isObject(obj) {
|
|
|
123
124
|
|
|
124
125
|
return (typeof obj === 'object' || typeof obj.prototype === 'undefined') && Array.isArray(obj) === false;
|
|
125
126
|
}
|
|
127
|
+
|
|
128
|
+
function validatePassword(password, validation = _constants.DEFAULT_PASSWORD_VALIDATION) {
|
|
129
|
+
return typeof password === 'string' && validation instanceof RegExp ? password.match(validation) !== null : false;
|
|
130
|
+
}
|
|
126
131
|
//# sourceMappingURL=validation-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-utils.js","names":["isPackageNameScoped","name","startsWith","validateName","normalizedName","toLowerCase","isScoped","scopedName","split","match","includes","validatePackage","nameList","length","slice","normalizeMetadata","manifest","assert","strictEqual","_manifest","isObject","DIST_TAGS","obj","prototype","Array","isArray"],"sources":["../src/validation-utils.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { Manifest } from '@verdaccio/types';\n\nimport { DIST_TAGS } from './constants';\n\nexport { validatePublishSingleVersion } from './schemes/publish-manifest';\n\nexport function isPackageNameScoped(name: string): boolean {\n return name.startsWith('@');\n}\n\n/**\n * From normalize-package-data/lib/fixer.js\n * @param {*} name the package name\n * @return {Boolean} whether is valid or not\n */\nexport function validateName(name: string): boolean {\n if (typeof name !== 'string') {\n return false;\n }\n\n let normalizedName: string = name.toLowerCase();\n\n const isScoped: boolean = isPackageNameScoped(name);\n const scopedName = name.split('/', 2)[1];\n\n if (isScoped && typeof scopedName !== 'undefined') {\n normalizedName = scopedName.toLowerCase();\n }\n\n /**\n * Some context about the first regex\n * - npm used to have a different tarball naming system.\n * eg: http://registry.npmjs.com/thirty-two\n * https://registry.npmjs.org/thirty-two/-/thirty-two@0.0.1.tgz\n * The file name thirty-two@0.0.1.tgz, the version and the pkg name was separated by an at (@)\n * while nowadays the naming system is based in dashes\n * https://registry.npmjs.org/verdaccio/-/verdaccio-1.4.0.tgz\n *\n * more info here: https://github.com/rlidwka/sinopia/issues/75\n */\n return !(\n !normalizedName.match(/^[-a-zA-Z0-9_.!~*'()@]+$/) ||\n normalizedName.startsWith('.') || // \".bin\", etc.\n ['node_modules', '__proto__', 'favicon.ico'].includes(normalizedName)\n );\n}\n\n/**\n * Validate a package.\n * @return {Boolean} whether the package is valid or not\n */\nexport function validatePackage(name: string): boolean {\n const nameList = name.split('/', 2);\n if (nameList.length === 1) {\n // normal package\n return validateName(nameList[0]);\n }\n // scoped package\n return nameList[0][0] === '@' && validateName(nameList[0].slice(1)) && validateName(nameList[1]);\n}\n\n/**\n * Validate the package metadata, add additional properties whether are missing within\n * the metadata properties.\n * @param {*} manifest\n * @param {*} name\n * @return {Object} the object with additional properties as dist-tags ad versions\n * FUTURE: rename to normalizeMetadata\n */\nexport function normalizeMetadata(manifest: Manifest, name: string): Manifest {\n assert.strictEqual(manifest.name, name);\n const _manifest = { ...manifest };\n\n if (!isObject(manifest[DIST_TAGS])) {\n _manifest[DIST_TAGS] = {};\n }\n\n // This may not be nee dit\n if (!isObject(manifest['versions'])) {\n _manifest['versions'] = {};\n }\n\n if (!isObject(manifest['time'])) {\n _manifest['time'] = {};\n }\n\n return _manifest;\n}\n\n/**\n * Check whether an element is an Object\n * @param {*} obj the element\n * @return {Boolean}\n */\nexport function isObject(obj: any): boolean {\n if (obj === null || typeof obj === 'undefined' || typeof obj === 'string') {\n return false;\n }\n\n return (\n (typeof obj === 'object' || typeof obj.prototype === 'undefined') &&\n Array.isArray(obj) === false\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation-utils.js","names":["isPackageNameScoped","name","startsWith","validateName","normalizedName","toLowerCase","isScoped","scopedName","split","match","includes","validatePackage","nameList","length","slice","normalizeMetadata","manifest","assert","strictEqual","_manifest","isObject","DIST_TAGS","obj","prototype","Array","isArray","validatePassword","password","validation","DEFAULT_PASSWORD_VALIDATION","RegExp"],"sources":["../src/validation-utils.ts"],"sourcesContent":["import assert from 'assert';\n\nimport { Manifest } from '@verdaccio/types';\n\nimport { DEFAULT_PASSWORD_VALIDATION, DIST_TAGS } from './constants';\n\nexport { validatePublishSingleVersion } from './schemes/publish-manifest';\n\nexport function isPackageNameScoped(name: string): boolean {\n return name.startsWith('@');\n}\n\n/**\n * From normalize-package-data/lib/fixer.js\n * @param {*} name the package name\n * @return {Boolean} whether is valid or not\n */\nexport function validateName(name: string): boolean {\n if (typeof name !== 'string') {\n return false;\n }\n\n let normalizedName: string = name.toLowerCase();\n\n const isScoped: boolean = isPackageNameScoped(name);\n const scopedName = name.split('/', 2)[1];\n\n if (isScoped && typeof scopedName !== 'undefined') {\n normalizedName = scopedName.toLowerCase();\n }\n\n /**\n * Some context about the first regex\n * - npm used to have a different tarball naming system.\n * eg: http://registry.npmjs.com/thirty-two\n * https://registry.npmjs.org/thirty-two/-/thirty-two@0.0.1.tgz\n * The file name thirty-two@0.0.1.tgz, the version and the pkg name was separated by an at (@)\n * while nowadays the naming system is based in dashes\n * https://registry.npmjs.org/verdaccio/-/verdaccio-1.4.0.tgz\n *\n * more info here: https://github.com/rlidwka/sinopia/issues/75\n */\n return !(\n !normalizedName.match(/^[-a-zA-Z0-9_.!~*'()@]+$/) ||\n normalizedName.startsWith('.') || // \".bin\", etc.\n ['node_modules', '__proto__', 'favicon.ico'].includes(normalizedName)\n );\n}\n\n/**\n * Validate a package.\n * @return {Boolean} whether the package is valid or not\n */\nexport function validatePackage(name: string): boolean {\n const nameList = name.split('/', 2);\n if (nameList.length === 1) {\n // normal package\n return validateName(nameList[0]);\n }\n // scoped package\n return nameList[0][0] === '@' && validateName(nameList[0].slice(1)) && validateName(nameList[1]);\n}\n\n/**\n * Validate the package metadata, add additional properties whether are missing within\n * the metadata properties.\n * @param {*} manifest\n * @param {*} name\n * @return {Object} the object with additional properties as dist-tags ad versions\n * FUTURE: rename to normalizeMetadata\n */\nexport function normalizeMetadata(manifest: Manifest, name: string): Manifest {\n assert.strictEqual(manifest.name, name);\n const _manifest = { ...manifest };\n\n if (!isObject(manifest[DIST_TAGS])) {\n _manifest[DIST_TAGS] = {};\n }\n\n // This may not be nee dit\n if (!isObject(manifest['versions'])) {\n _manifest['versions'] = {};\n }\n\n if (!isObject(manifest['time'])) {\n _manifest['time'] = {};\n }\n\n return _manifest;\n}\n\n/**\n * Check whether an element is an Object\n * @param {*} obj the element\n * @return {Boolean}\n */\nexport function isObject(obj: any): boolean {\n if (obj === null || typeof obj === 'undefined' || typeof obj === 'string') {\n return false;\n }\n\n return (\n (typeof obj === 'object' || typeof obj.prototype === 'undefined') &&\n Array.isArray(obj) === false\n );\n}\n\nexport function validatePassword(\n password: string,\n validation: RegExp = DEFAULT_PASSWORD_VALIDATION\n): boolean {\n return typeof password === 'string' && validation instanceof RegExp\n ? password.match(validation) !== null\n : false;\n}\n"],"mappings":"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"}
|
package/build/warning-utils.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"warning-utils.js","names":["warningInstance","warning","verdaccioWarning","verdaccioDeprecation","Codes","create","VERWAR002","VERWAR001","VERWAR003","VERWAR004","VERDEP003","emit","code","a","b","c"],"sources":["../src/warning-utils.ts"],"sourcesContent":["import warning from 'process-warning';\n\nconst warningInstance = warning();\nconst verdaccioWarning = 'VerdaccioWarning';\nconst verdaccioDeprecation = 'VerdaccioDeprecation';\n\nexport enum Codes {\n VERWAR001 = 'VERWAR001',\n VERWAR002 = 'VERWAR002',\n VERWAR003 = 'VERWAR003',\n VERWAR004 = 'VERWAR004',\n // deprecation warnings\n VERDEP003 = 'VERDEP003',\n}\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR002,\n `The property config \"logs\" property is longer supported, rename to \"log\" and use object instead`\n);\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR001,\n `Verdaccio doesn't need superuser privileges. don't run it under root`\n);\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR003,\n 'rotating-file type is not longer supported, consider use [logrotate] instead'\n);\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR004,\n `invalid address - %s, we expect a port (e.g. \"4873\"), \nhost:port (e.g. \"localhost:4873\") or full url '(e.g. \"http://localhost:4873/\")\nhttps://verdaccio.org/docs/en/configuration#listen-port`\n);\n\nwarningInstance.create(\n verdaccioDeprecation,\n Codes.VERDEP003,\n 'multiple addresses will be deprecated in the next major, only use one'\n);\n\nexport function emit(code, a?: string, b?: string, c?: string) {\n warningInstance.emit(code, a, b, c);\n}\n"],"mappings":";;;;;;;;AAAA;;;;AAEA,MAAMA,eAAe,GAAG,IAAAC,uBAAA,GAAxB;AACA,MAAMC,gBAAgB,GAAG,kBAAzB;AACA,MAAMC,oBAAoB,GAAG,sBAA7B;IAEYC,K;;;WAAAA,K;EAAAA,K;EAAAA,K;EAAAA,K;EAAAA,K;EAAAA,K;GAAAA,K,qBAAAA,K;;AASZJ,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACE,SAFR,EAGG,iGAHH;AAMAN,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACG,SAFR,EAGG,sEAHH;AAMAP,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACI,SAFR,EAGE,8EAHF;AAMAR,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACK,SAFR,EAGG;AACH;AACA,wDALA;AAQAT,eAAe,CAACK,MAAhB,CACEF,oBADF,EAEEC,KAAK,CAACM,SAFR,EAGE,uEAHF;;AAMO,SAASC,IAAT,CAAcC,IAAd,
|
|
1
|
+
{"version":3,"file":"warning-utils.js","names":["warningInstance","warning","verdaccioWarning","verdaccioDeprecation","Codes","create","VERWAR002","VERWAR001","VERWAR003","VERWAR004","VERDEP003","emit","code","a","b","c"],"sources":["../src/warning-utils.ts"],"sourcesContent":["import warning from 'process-warning';\n\nconst warningInstance = warning();\nconst verdaccioWarning = 'VerdaccioWarning';\nconst verdaccioDeprecation = 'VerdaccioDeprecation';\n\nexport enum Codes {\n VERWAR001 = 'VERWAR001',\n VERWAR002 = 'VERWAR002',\n VERWAR003 = 'VERWAR003',\n VERWAR004 = 'VERWAR004',\n // deprecation warnings\n VERDEP003 = 'VERDEP003',\n}\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR002,\n `The property config \"logs\" property is longer supported, rename to \"log\" and use object instead`\n);\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR001,\n `Verdaccio doesn't need superuser privileges. don't run it under root`\n);\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR003,\n 'rotating-file type is not longer supported, consider use [logrotate] instead'\n);\n\nwarningInstance.create(\n verdaccioWarning,\n Codes.VERWAR004,\n `invalid address - %s, we expect a port (e.g. \"4873\"), \nhost:port (e.g. \"localhost:4873\") or full url '(e.g. \"http://localhost:4873/\")\nhttps://verdaccio.org/docs/en/configuration#listen-port`\n);\n\nwarningInstance.create(\n verdaccioDeprecation,\n Codes.VERDEP003,\n 'multiple addresses will be deprecated in the next major, only use one'\n);\n\nexport function emit(code: string, a?: string, b?: string, c?: string) {\n warningInstance.emit(code, a, b, c);\n}\n"],"mappings":";;;;;;;;AAAA;;;;AAEA,MAAMA,eAAe,GAAG,IAAAC,uBAAA,GAAxB;AACA,MAAMC,gBAAgB,GAAG,kBAAzB;AACA,MAAMC,oBAAoB,GAAG,sBAA7B;IAEYC,K;;;WAAAA,K;EAAAA,K;EAAAA,K;EAAAA,K;EAAAA,K;EAAAA,K;GAAAA,K,qBAAAA,K;;AASZJ,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACE,SAFR,EAGG,iGAHH;AAMAN,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACG,SAFR,EAGG,sEAHH;AAMAP,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACI,SAFR,EAGE,8EAHF;AAMAR,eAAe,CAACK,MAAhB,CACEH,gBADF,EAEEE,KAAK,CAACK,SAFR,EAGG;AACH;AACA,wDALA;AAQAT,eAAe,CAACK,MAAhB,CACEF,oBADF,EAEEC,KAAK,CAACM,SAFR,EAGE,uEAHF;;AAMO,SAASC,IAAT,CAAcC,IAAd,EAA4BC,CAA5B,EAAwCC,CAAxC,EAAoDC,CAApD,EAAgE;EACrEf,eAAe,CAACW,IAAhB,CAAqBC,IAArB,EAA2BC,CAA3B,EAA8BC,CAA9B,EAAiCC,CAAjC;AACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/core",
|
|
3
|
-
"version": "6.0.0-6-next.
|
|
3
|
+
"version": "6.0.0-6-next.49",
|
|
4
4
|
"description": "core utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"private",
|
|
@@ -39,11 +39,13 @@
|
|
|
39
39
|
"semver": "7.3.7",
|
|
40
40
|
"ajv": "8.11.0",
|
|
41
41
|
"process-warning": "1.0.0",
|
|
42
|
-
"core-js": "3.25.
|
|
42
|
+
"core-js": "3.25.3"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"lodash": "4.17.21",
|
|
46
|
-
"
|
|
46
|
+
"typedoc": "0.23.15",
|
|
47
|
+
"typedoc-plugin-missing-exports": "latest",
|
|
48
|
+
"@verdaccio/types": "11.0.0-6-next.17"
|
|
47
49
|
},
|
|
48
50
|
"funding": {
|
|
49
51
|
"type": "opencollective",
|
|
@@ -53,6 +55,7 @@
|
|
|
53
55
|
"clean": "rimraf ./build",
|
|
54
56
|
"test": "jest",
|
|
55
57
|
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
|
58
|
+
"build:docs": "typedoc --options ./typedoc.json --tsconfig tsconfig.build.json",
|
|
56
59
|
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
|
57
60
|
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
|
58
61
|
"watch": "pnpm build:js -- --watch",
|
package/src/constants.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import httpCodes from 'http-status-codes';
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const DEFAULT_PASSWORD_VALIDATION = /.{3}$/;
|
|
4
4
|
export const TIME_EXPIRATION_24H = '24h';
|
|
5
5
|
export const TIME_EXPIRATION_7D = '7d';
|
|
6
6
|
export const DIST_TAGS = 'dist-tags';
|
|
@@ -46,6 +46,7 @@ export const HEADERS = {
|
|
|
46
46
|
NONE_MATCH: 'If-None-Match',
|
|
47
47
|
ETAG: 'ETag',
|
|
48
48
|
JSON_CHARSET: 'application/json; charset=utf-8',
|
|
49
|
+
JSON_INSTALL_CHARSET: 'application/vnd.npm.install-v1+json; charset=utf-8',
|
|
49
50
|
OCTET_STREAM: 'application/octet-stream; charset=utf-8',
|
|
50
51
|
TEXT_CHARSET: 'text/plain; charset=utf-8',
|
|
51
52
|
WWW_AUTH: 'WWW-Authenticate',
|
package/src/error-utils.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import createError, { HttpError } from 'http-errors';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { HTTP_STATUS } from './constants';
|
|
4
4
|
|
|
5
5
|
export const API_ERROR = {
|
|
6
|
-
PASSWORD_SHORT:
|
|
7
|
-
`The provided password is too short. Please pick a password longer than ` +
|
|
8
|
-
`${passLength} characters.`,
|
|
6
|
+
PASSWORD_SHORT: `The provided password does not pass the validation`,
|
|
9
7
|
MUST_BE_LOGGED: 'You must be logged in to publish packages.',
|
|
10
8
|
PLUGIN_ERROR: 'bug in the auth plugin system',
|
|
11
9
|
CONFIG_BAD_FORMAT: 'config file must be an object',
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import * as pkgUtils from './pkg-utils';
|
|
|
5
5
|
import * as pluginUtils from './plugin-utils';
|
|
6
6
|
import * as searchUtils from './search-utils';
|
|
7
7
|
import * as streamUtils from './stream-utils';
|
|
8
|
+
import * as stringUtils from './string-utils';
|
|
8
9
|
import * as validatioUtils from './validation-utils';
|
|
9
10
|
import * as warningUtils from './warning-utils';
|
|
10
11
|
|
|
@@ -19,7 +20,7 @@ export {
|
|
|
19
20
|
CHARACTER_ENCODING,
|
|
20
21
|
HEADER_TYPE,
|
|
21
22
|
LATEST,
|
|
22
|
-
|
|
23
|
+
DEFAULT_PASSWORD_VALIDATION,
|
|
23
24
|
DEFAULT_USER,
|
|
24
25
|
USERS,
|
|
25
26
|
} from './constants';
|
|
@@ -33,6 +34,7 @@ export {
|
|
|
33
34
|
// TODO: remove this typo
|
|
34
35
|
validatioUtils,
|
|
35
36
|
validationUtils,
|
|
37
|
+
stringUtils,
|
|
36
38
|
constants,
|
|
37
39
|
pluginUtils,
|
|
38
40
|
warningUtils,
|
package/src/plugin-utils.ts
CHANGED
|
@@ -1,24 +1,174 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Express, RequestHandler } from 'express';
|
|
2
|
+
import { Readable, Writable } from 'stream';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AllowAccess,
|
|
6
|
+
Callback,
|
|
7
|
+
Config,
|
|
8
|
+
Logger,
|
|
9
|
+
Manifest,
|
|
10
|
+
PackageAccess,
|
|
11
|
+
RemoteUser,
|
|
12
|
+
Token,
|
|
13
|
+
TokenFilter,
|
|
14
|
+
} from '@verdaccio/types';
|
|
4
15
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
16
|
+
import { VerdaccioError, searchUtils } from '.';
|
|
17
|
+
|
|
18
|
+
export interface AuthPluginPackage {
|
|
19
|
+
packageName: string;
|
|
20
|
+
packageVersion?: string;
|
|
21
|
+
tag?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PluginOptions {
|
|
24
|
+
config: Config;
|
|
25
|
+
logger: Logger;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The base plugin class, set of utilities for developing
|
|
30
|
+
* plugins.
|
|
31
|
+
* @alpha
|
|
32
|
+
* */
|
|
33
|
+
export class Plugin<PluginConfig> {
|
|
34
|
+
static version = 1;
|
|
35
|
+
public readonly version: number;
|
|
36
|
+
public readonly config: PluginConfig | unknown;
|
|
37
|
+
public readonly options: PluginOptions;
|
|
38
|
+
public constructor(config: PluginConfig, options: PluginOptions) {
|
|
39
|
+
this.version = Plugin.version;
|
|
40
|
+
this.config = config;
|
|
41
|
+
this.options = options;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public getVersion() {
|
|
45
|
+
return this.version;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export interface StorageHandler {
|
|
49
|
+
logger: Logger;
|
|
50
|
+
deletePackage(fileName: string): Promise<void>;
|
|
51
|
+
removePackage(): Promise<void>;
|
|
52
|
+
// next packages migration (this list is meant to replace the callback parent functions)
|
|
53
|
+
updatePackage(
|
|
54
|
+
packageName: string,
|
|
55
|
+
handleUpdate: (manifest: Manifest) => Promise<Manifest>
|
|
56
|
+
): Promise<Manifest>;
|
|
57
|
+
readPackage(name: string): Promise<Manifest>;
|
|
58
|
+
savePackage(pkgName: string, value: Manifest): Promise<void>;
|
|
59
|
+
readTarball(pkgName: string, { signal }: { signal: AbortSignal }): Promise<Readable>;
|
|
60
|
+
createPackage(name: string, manifest: Manifest): Promise<void>;
|
|
61
|
+
writeTarball(tarballName: string, { signal }: { signal: AbortSignal }): Promise<Writable>;
|
|
62
|
+
// verify if tarball exist in the storage
|
|
63
|
+
hasTarball(fileName: string): Promise<boolean>;
|
|
64
|
+
// verify if package exist in the storage
|
|
65
|
+
hasPackage(): Promise<boolean>;
|
|
9
66
|
}
|
|
10
67
|
|
|
11
|
-
export interface
|
|
12
|
-
config: T & Config;
|
|
68
|
+
export interface Storage<PluginConfig> extends Plugin<PluginConfig> {
|
|
13
69
|
add(name: string): Promise<void>;
|
|
14
70
|
remove(name: string): Promise<void>;
|
|
15
71
|
get(): Promise<any>;
|
|
16
72
|
init(): Promise<void>;
|
|
17
73
|
getSecret(): Promise<string>;
|
|
18
74
|
setSecret(secret: string): Promise<any>;
|
|
19
|
-
getPackageStorage(packageInfo: string):
|
|
75
|
+
getPackageStorage(packageInfo: string): StorageHandler;
|
|
20
76
|
search(query: searchUtils.SearchQuery): Promise<searchUtils.SearchItem[]>;
|
|
21
77
|
saveToken(token: Token): Promise<any>;
|
|
22
78
|
deleteToken(user: string, tokenKey: string): Promise<any>;
|
|
23
79
|
readTokens(filter: TokenFilter): Promise<Token[]>;
|
|
24
80
|
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* This function allow add additional middleware to the application.
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* import express, { Request, Response } from 'express';
|
|
87
|
+
*
|
|
88
|
+
* class Middleware extends Plugin {
|
|
89
|
+
* // instances of auth and storage are injected
|
|
90
|
+
* register_middlewares(app, auth, storage) {
|
|
91
|
+
* const router = express.Router();
|
|
92
|
+
* router.post('/my-endpoint', (req: Request, res: Response): void => {
|
|
93
|
+
res.status(200).end();
|
|
94
|
+
});
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
*
|
|
98
|
+
*
|
|
99
|
+
* const [plugin] = await asyncLoadPlugin(...);
|
|
100
|
+
* plugin.register_middlewares(app, auth, storage);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export interface ExpressMiddleware<PluginConfig, Storage, Auth> extends Plugin<PluginConfig> {
|
|
104
|
+
register_middlewares(app: Express, auth: Auth, storage: Storage): void;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* dasdsa
|
|
109
|
+
*/
|
|
110
|
+
export type AuthCallback = (error: VerdaccioError | null, groups?: string[] | false) => void;
|
|
111
|
+
|
|
112
|
+
export type AuthAccessCallback = (error: VerdaccioError | null, access?: boolean) => void;
|
|
113
|
+
export type AuthUserCallback = (error: VerdaccioError | null, access?: boolean | string) => void;
|
|
114
|
+
export type AuthChangePasswordCallback = (error: VerdaccioError | null, access?: boolean) => void;
|
|
115
|
+
export type AccessCallback = (error: VerdaccioError | null, ok?: boolean) => void;
|
|
116
|
+
export interface Auth<T> extends Plugin<T> {
|
|
117
|
+
/**
|
|
118
|
+
* Handles the authenticated method.
|
|
119
|
+
* ```ts
|
|
120
|
+
* class Auth {
|
|
121
|
+
public authenticate(user: string, password: string, done: AuthCallback): void {
|
|
122
|
+
if (!password) {
|
|
123
|
+
return done(errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
124
|
+
}
|
|
125
|
+
// always return an array of users
|
|
126
|
+
return done(null, [user]);
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
authenticate(user: string, password: string, cb: AuthCallback): void;
|
|
131
|
+
/**
|
|
132
|
+
* Handles the authenticated method.
|
|
133
|
+
* ```ts
|
|
134
|
+
* class Auth {
|
|
135
|
+
public adduser(user: string, password: string, done: AuthCallback): void {
|
|
136
|
+
if (!password) {
|
|
137
|
+
return done(errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
138
|
+
}
|
|
139
|
+
// return boolean
|
|
140
|
+
return done(null, true);
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
adduser?(user: string, password: string, cb: AuthUserCallback): void;
|
|
145
|
+
changePassword?(
|
|
146
|
+
user: string,
|
|
147
|
+
password: string,
|
|
148
|
+
newPassword: string,
|
|
149
|
+
cb: AuthChangePasswordCallback
|
|
150
|
+
): void;
|
|
151
|
+
allow_publish?(user: RemoteUser, pkg: T & PackageAccess, cb: AuthAccessCallback): void;
|
|
152
|
+
allow_publish?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
|
|
153
|
+
allow_access?(user: RemoteUser, pkg: T & PackageAccess, cb: AccessCallback): void;
|
|
154
|
+
allow_access?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AccessCallback): void;
|
|
155
|
+
allow_unpublish?(user: RemoteUser, pkg: T & PackageAccess, cb: AuthAccessCallback): void;
|
|
156
|
+
allow_unpublish?(
|
|
157
|
+
user: RemoteUser,
|
|
158
|
+
pkg: AllowAccess & PackageAccess,
|
|
159
|
+
cb: AuthAccessCallback
|
|
160
|
+
): void;
|
|
161
|
+
apiJWTmiddleware?(helpers: any): RequestHandler;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface IBasicAuth {
|
|
165
|
+
authenticate(user: string, password: string, cb: Callback): void;
|
|
166
|
+
invalidateToken?(token: string): Promise<void>;
|
|
167
|
+
changePassword(user: string, password: string, newPassword: string, cb: Callback): void;
|
|
168
|
+
allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
|
|
169
|
+
add_user(user: string, password: string, cb: Callback): any;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface ManifestFilter<T> extends Plugin<T> {
|
|
173
|
+
filterMetadata(packageInfo: Manifest): Promise<Manifest>;
|
|
174
|
+
}
|
package/src/stream-utils.ts
CHANGED
|
@@ -1,90 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export interface IReadTarball {
|
|
4
|
-
abort?: () => void;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface IUploadTarball {
|
|
8
|
-
done?: () => void;
|
|
9
|
-
abort?: () => void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* This stream is used to read tarballs from repository.
|
|
14
|
-
* @param {*} options
|
|
15
|
-
* @return {Stream}
|
|
16
|
-
*/
|
|
17
|
-
class ReadTarball extends PassThrough implements IReadTarball {
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @param {Object} options
|
|
21
|
-
*/
|
|
22
|
-
public constructor(options: TransformOptions) {
|
|
23
|
-
super(options);
|
|
24
|
-
// called when data is not needed anymore
|
|
25
|
-
addAbstractMethods(this, 'abort');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public abort(): void {}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* This stream is used to upload tarballs to a repository.
|
|
33
|
-
* @param {*} options
|
|
34
|
-
* @return {Stream}
|
|
35
|
-
*/
|
|
36
|
-
class UploadTarball extends PassThrough implements IUploadTarball {
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* @param {Object} options
|
|
40
|
-
*/
|
|
41
|
-
public constructor(options: any) {
|
|
42
|
-
super(options);
|
|
43
|
-
// called when user closes connection before upload finishes
|
|
44
|
-
addAbstractMethods(this, 'abort');
|
|
45
|
-
|
|
46
|
-
// called when upload finishes successfully
|
|
47
|
-
addAbstractMethods(this, 'done');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
public abort(): void {}
|
|
51
|
-
public done(): void {}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* This function intercepts abstract calls and replays them allowing.
|
|
56
|
-
* us to attach those functions after we are ready to do so
|
|
57
|
-
* @param {*} self
|
|
58
|
-
* @param {*} name
|
|
59
|
-
*/
|
|
60
|
-
// Perhaps someone knows a better way to write this
|
|
61
|
-
function addAbstractMethods(self: any, name: any): void {
|
|
62
|
-
self._called_methods = self._called_methods || {};
|
|
63
|
-
|
|
64
|
-
self.__defineGetter__(name, function () {
|
|
65
|
-
return function (): void {
|
|
66
|
-
self._called_methods[name] = true;
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
self.__defineSetter__(name, function (fn: any) {
|
|
71
|
-
delete self[name];
|
|
72
|
-
|
|
73
|
-
self[name] = fn;
|
|
74
|
-
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
|
76
|
-
if (self._called_methods && self._called_methods[name]) {
|
|
77
|
-
delete self._called_methods[name];
|
|
78
|
-
|
|
79
|
-
self[name]();
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
1
|
+
import { Readable, Transform } from 'stream';
|
|
83
2
|
|
|
84
3
|
/**
|
|
85
4
|
* Converts a buffer stream to a string.
|
|
86
5
|
*/
|
|
87
|
-
const readableToString = async (stream) => {
|
|
6
|
+
const readableToString = async (stream: Readable) => {
|
|
88
7
|
const chunks: Buffer[] = [];
|
|
89
8
|
for await (let chunk of stream) {
|
|
90
9
|
chunks.push(Buffer.from(chunk));
|
|
@@ -106,4 +25,4 @@ const transformObjectToString = () => {
|
|
|
106
25
|
});
|
|
107
26
|
};
|
|
108
27
|
|
|
109
|
-
export {
|
|
28
|
+
export { readableToString, transformObjectToString };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality values, or q-values and q-factors, are used to describe the order
|
|
3
|
+
* of priority of values in a comma-separated list.
|
|
4
|
+
* It is a special syntax allowed in some HTTP headers and in HTML.
|
|
5
|
+
* https://developer.mozilla.org/en-US/docs/Glossary/Quality_values
|
|
6
|
+
* @param headerValue
|
|
7
|
+
*/
|
|
8
|
+
export function getByQualityPriorityValue(headerValue: string | undefined | null): string {
|
|
9
|
+
if (typeof headerValue !== 'string') {
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const split = headerValue.split(',');
|
|
14
|
+
|
|
15
|
+
if (split.length <= 1) {
|
|
16
|
+
const qList = split[0].split(';');
|
|
17
|
+
return qList[0];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let [header] = split
|
|
21
|
+
.reduce((acc, item: string) => {
|
|
22
|
+
const qList = item.split(';');
|
|
23
|
+
if (qList.length > 1) {
|
|
24
|
+
const [accept, q] = qList;
|
|
25
|
+
const [, query] = q.split('=');
|
|
26
|
+
acc.push([accept.trim(), query ? query : 0]);
|
|
27
|
+
} else {
|
|
28
|
+
acc.push([qList[0], 0]);
|
|
29
|
+
}
|
|
30
|
+
return acc;
|
|
31
|
+
}, [] as any)
|
|
32
|
+
.sort(function (a: number[], b: number[]) {
|
|
33
|
+
return b[1] - a[1];
|
|
34
|
+
});
|
|
35
|
+
return header[0];
|
|
36
|
+
}
|
package/src/validation-utils.ts
CHANGED
|
@@ -2,7 +2,7 @@ import assert from 'assert';
|
|
|
2
2
|
|
|
3
3
|
import { Manifest } from '@verdaccio/types';
|
|
4
4
|
|
|
5
|
-
import { DIST_TAGS } from './constants';
|
|
5
|
+
import { DEFAULT_PASSWORD_VALIDATION, DIST_TAGS } from './constants';
|
|
6
6
|
|
|
7
7
|
export { validatePublishSingleVersion } from './schemes/publish-manifest';
|
|
8
8
|
|
|
@@ -104,3 +104,12 @@ export function isObject(obj: any): boolean {
|
|
|
104
104
|
Array.isArray(obj) === false
|
|
105
105
|
);
|
|
106
106
|
}
|
|
107
|
+
|
|
108
|
+
export function validatePassword(
|
|
109
|
+
password: string,
|
|
110
|
+
validation: RegExp = DEFAULT_PASSWORD_VALIDATION
|
|
111
|
+
): boolean {
|
|
112
|
+
return typeof password === 'string' && validation instanceof RegExp
|
|
113
|
+
? password.match(validation) !== null
|
|
114
|
+
: false;
|
|
115
|
+
}
|
package/src/warning-utils.ts
CHANGED
|
@@ -45,6 +45,6 @@ warningInstance.create(
|
|
|
45
45
|
'multiple addresses will be deprecated in the next major, only use one'
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
export function emit(code, a?: string, b?: string, c?: string) {
|
|
48
|
+
export function emit(code: string, a?: string, b?: string, c?: string) {
|
|
49
49
|
warningInstance.emit(code, a, b, c);
|
|
50
50
|
}
|
package/test/mystreams.spec.ts
CHANGED
|
@@ -1,34 +1,8 @@
|
|
|
1
1
|
import { Stream } from 'stream';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { readableToString } from '../src/stream-utils';
|
|
4
4
|
|
|
5
5
|
describe('mystreams', () => {
|
|
6
|
-
test('should delay events on ReadTarball abort', (cb) => {
|
|
7
|
-
const readTballStream = new ReadTarball({});
|
|
8
|
-
readTballStream.abort();
|
|
9
|
-
setTimeout(function () {
|
|
10
|
-
readTballStream.abort = function (): void {
|
|
11
|
-
cb();
|
|
12
|
-
};
|
|
13
|
-
readTballStream.abort = function (): never {
|
|
14
|
-
throw Error('fail');
|
|
15
|
-
};
|
|
16
|
-
}, 10);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test('should delay events on UploadTarball abort', (cb) => {
|
|
20
|
-
const uploadTballStream = new UploadTarball({});
|
|
21
|
-
uploadTballStream.abort();
|
|
22
|
-
setTimeout(function () {
|
|
23
|
-
uploadTballStream.abort = function (): void {
|
|
24
|
-
cb();
|
|
25
|
-
};
|
|
26
|
-
uploadTballStream.abort = function (): never {
|
|
27
|
-
throw Error('fail');
|
|
28
|
-
};
|
|
29
|
-
}, 10);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
6
|
test('readableToString single string', async () => {
|
|
33
7
|
expect(await readableToString(Stream.Readable.from('foo'))).toEqual('foo');
|
|
34
8
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { stringUtils } from '../src';
|
|
2
|
+
|
|
3
|
+
describe('string-utils', () => {
|
|
4
|
+
test('getByQualityPriorityValue', () => {
|
|
5
|
+
expect(stringUtils.getByQualityPriorityValue('')).toEqual('');
|
|
6
|
+
expect(stringUtils.getByQualityPriorityValue(null)).toEqual('');
|
|
7
|
+
expect(stringUtils.getByQualityPriorityValue(undefined)).toEqual('');
|
|
8
|
+
expect(stringUtils.getByQualityPriorityValue('something')).toEqual('something');
|
|
9
|
+
expect(stringUtils.getByQualityPriorityValue('something,')).toEqual('something');
|
|
10
|
+
expect(stringUtils.getByQualityPriorityValue('0,')).toEqual('0');
|
|
11
|
+
expect(stringUtils.getByQualityPriorityValue('application/json')).toEqual('application/json');
|
|
12
|
+
expect(stringUtils.getByQualityPriorityValue('application/json; q=1')).toEqual(
|
|
13
|
+
'application/json'
|
|
14
|
+
);
|
|
15
|
+
expect(stringUtils.getByQualityPriorityValue('application/json; q=')).toEqual(
|
|
16
|
+
'application/json'
|
|
17
|
+
);
|
|
18
|
+
expect(stringUtils.getByQualityPriorityValue('application/json;')).toEqual('application/json');
|
|
19
|
+
expect(
|
|
20
|
+
stringUtils.getByQualityPriorityValue(
|
|
21
|
+
'application/json; q=1.0, application/vnd.npm.install-v1+json; q=0.9, */*'
|
|
22
|
+
)
|
|
23
|
+
).toEqual('application/json');
|
|
24
|
+
expect(
|
|
25
|
+
stringUtils.getByQualityPriorityValue(
|
|
26
|
+
'application/json; q=1.0, application/vnd.npm.install-v1+json; q=, */*'
|
|
27
|
+
)
|
|
28
|
+
).toEqual('application/json');
|
|
29
|
+
expect(
|
|
30
|
+
stringUtils.getByQualityPriorityValue(
|
|
31
|
+
'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.9, */*'
|
|
32
|
+
)
|
|
33
|
+
).toEqual('application/vnd.npm.install-v1+json');
|
|
34
|
+
expect(
|
|
35
|
+
stringUtils.getByQualityPriorityValue(
|
|
36
|
+
'application/vnd.npm.install-v1+json; q=, application/json; q=0.9, */*'
|
|
37
|
+
)
|
|
38
|
+
).toEqual('application/json');
|
|
39
|
+
});
|
|
40
|
+
});
|