@konker.dev/middleware-fp 0.0.17 → 0.0.19
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/dist/contrib/basicAuthAuthenticator.js +3 -3
- package/dist/contrib/basicAuthAuthenticator.js.map +1 -1
- package/dist/contrib/jwtAuthenticator.js +6 -4
- package/dist/contrib/jwtAuthenticator.js.map +1 -1
- package/dist/contrib/jwtAuthenticatorRsa.js +6 -4
- package/dist/contrib/jwtAuthenticatorRsa.js.map +1 -1
- package/package.json +2 -2
|
@@ -32,12 +32,12 @@ const TAG = 'basicAuthAuthenticator';
|
|
|
32
32
|
exports.BasicAuthAuthenticatorDeps = P.Context.GenericTag('BasicAuthAuthenticatorDeps');
|
|
33
33
|
// --------------------------------------------------------------------------
|
|
34
34
|
const middleware = () => (wrapped) => (i) => {
|
|
35
|
-
return P.pipe(P.Effect.Do, P.Effect.tap(P.Effect.logDebug(`[${TAG}] IN`)), P.Effect.bind('deps', () => exports.BasicAuthAuthenticatorDeps), P.Effect.bind('authToken', () => (0, helpers_1.extractBasicAuthHeaderValue)(i.headers['authorization'])), P.Effect.bind('decoded', ({ authToken }) => (0, basic_auth_1.basicAuthDecodeHeaderValue)(authToken)), P.Effect.bind('
|
|
35
|
+
return P.pipe(P.Effect.Do, P.Effect.tap(P.Effect.logDebug(`[${TAG}] IN`)), P.Effect.bind('deps', () => exports.BasicAuthAuthenticatorDeps), P.Effect.bind('authToken', () => (0, helpers_1.extractBasicAuthHeaderValue)(i.headers['authorization'])), P.Effect.bind('decoded', ({ authToken }) => (0, basic_auth_1.basicAuthDecodeHeaderValue)(authToken)), P.Effect.bind('verification', ({ decoded, deps }) => P.pipe(decoded, (0, basic_auth_1.basicAuthVerifyCredentials)(deps.validBasicAuthCredentialSet))), P.Effect.flatMap(({ verification }) => verification.verified
|
|
36
36
|
? P.Effect.succeed({
|
|
37
37
|
...i,
|
|
38
|
-
userId:
|
|
38
|
+
userId: verification.userId,
|
|
39
39
|
})
|
|
40
|
-
: P.Effect.fail(void 0)), P.Effect.mapError((e) => (0, HttpApiError_1.HttpApiError)('UnauthorizedError', `Invalid basic auth credentials: ${e?.message}`, 401, TAG, e)), P.Effect.tapError(
|
|
40
|
+
: P.Effect.fail(void 0)), P.Effect.mapError((e) => (0, HttpApiError_1.HttpApiError)('UnauthorizedError', `Invalid basic auth credentials: ${e?.message}`, 401, TAG, e)), P.Effect.tapError(P.Effect.logError), P.Effect.flatMap(wrapped), P.Effect.tap(P.Effect.logDebug(`[${TAG}] OUT`)));
|
|
41
41
|
};
|
|
42
42
|
exports.middleware = middleware;
|
|
43
43
|
//# sourceMappingURL=basicAuthAuthenticator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basicAuthAuthenticator.js","sourceRoot":"","sources":["../../src/contrib/basicAuthAuthenticator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAAmD;AAGnD,+
|
|
1
|
+
{"version":3,"file":"basicAuthAuthenticator.js","sourceRoot":"","sources":["../../src/contrib/basicAuthAuthenticator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAAmD;AAGnD,+EAAwH;AACxH,yEAA0F;AAI1F,sDAAmD;AAGnD,MAAM,GAAG,GAAG,wBAAwB,CAAC;AAMxB,QAAA,0BAA0B,GACrC,CAAC,CAAC,OAAO,CAAC,UAAU,CAA6B,4BAA4B,CAAC,CAAC;AAEjF,6EAA6E;AACtE,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAyC,EACqD,EAAE,CAClG,CAAC,CAAiC,EAAE,EAAE;IACpC,OAAO,CAAC,CAAC,IAAI,CACX,CAAC,CAAC,MAAM,CAAC,EAAE,EACX,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,EAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,kCAA0B,CAAC,EACvD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAA,qCAA2B,EAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EACzF,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,IAAA,uCAA0B,EAAC,SAAS,CAAC,CAAC,EAClF,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAClD,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAA,uCAA0B,EAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAC9E,EACD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CACpC,YAAY,CAAC,QAAQ;QACnB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YACf,GAAG,CAAC;YACJ,MAAM,EAAE,YAAY,CAAC,MAAM;SAC5B,CAAC;QACJ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAC1B,EACD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,IAAA,2BAAY,EAAC,mBAAmB,EAAE,mCAAmC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAChG,EACD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EACpC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EACzB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAChD,CAAC;AACJ,CAAC,CAAC;AA9BS,QAAA,UAAU,cA8BnB"}
|
|
@@ -33,10 +33,12 @@ const TAG = 'jwtAuthenticator';
|
|
|
33
33
|
exports.JwtAuthenticatorDeps = P.Context.GenericTag('JwtAuthenticatorDeps');
|
|
34
34
|
// --------------------------------------------------------------------------
|
|
35
35
|
const middleware = () => (wrapped) => (i) => {
|
|
36
|
-
return P.pipe(P.Effect.Do, P.Effect.tap(P.Effect.logDebug(`[${TAG}] IN`)), P.Effect.bind('deps', () => exports.JwtAuthenticatorDeps), P.Effect.bind('authToken', () => (0, helpers_1.extractBearerToken)(i.headers['authorization'])), P.Effect.bind('verification', ({ authToken, deps }) => (0, jwt_1.jwtVerifyToken)(authToken, deps)), P.Effect.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
return P.pipe(P.Effect.Do, P.Effect.tap(P.Effect.logDebug(`[${TAG}] IN`)), P.Effect.bind('deps', () => exports.JwtAuthenticatorDeps), P.Effect.bind('authToken', () => (0, helpers_1.extractBearerToken)(i.headers['authorization'])), P.Effect.bind('verification', ({ authToken, deps }) => (0, jwt_1.jwtVerifyToken)(authToken, deps)), P.Effect.flatMap(({ verification }) => verification.verified
|
|
37
|
+
? P.Effect.succeed({
|
|
38
|
+
...i,
|
|
39
|
+
userId: verification.sub,
|
|
40
|
+
})
|
|
41
|
+
: P.Effect.fail(void 0)), P.Effect.mapError((e) => (0, HttpApiError_1.HttpApiError)('UnauthorizedError', `Invalid JWT credentials: ${e?.message}`, 401, TAG, e)), P.Effect.tapError(P.Effect.logError), P.Effect.flatMap(wrapped), P.Effect.tap(P.Effect.logDebug(`[${TAG}] OUT`)));
|
|
40
42
|
};
|
|
41
43
|
exports.middleware = middleware;
|
|
42
44
|
//# sourceMappingURL=jwtAuthenticator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwtAuthenticator.js","sourceRoot":"","sources":["../../src/contrib/jwtAuthenticator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAAmD;AAEnD,yEAAiF;AAEjF,iEAAyE;AAIzE,sDAAmD;AAGnD,MAAM,GAAG,GAAG,kBAAkB,CAAC;AAE/B,6EAA6E;AAChE,QAAA,oBAAoB,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAwB,sBAAsB,CAAC,CAAC;AAIxG,6EAA6E;AACtE,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAyC,EACgD,EAAE,CAC7F,CAAC,CAAiC,EAAE,EAAE;IACpC,OAAO,CAAC,CAAC,IAAI,CACX,CAAC,CAAC,MAAM,CAAC,EAAE,EACX,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,EAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,4BAAoB,CAAC,EACjD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAA,4BAAkB,EAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAChF,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAA,oBAAc,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EACvF,CAAC,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"jwtAuthenticator.js","sourceRoot":"","sources":["../../src/contrib/jwtAuthenticator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAAmD;AAEnD,yEAAiF;AAEjF,iEAAyE;AAIzE,sDAAmD;AAGnD,MAAM,GAAG,GAAG,kBAAkB,CAAC;AAE/B,6EAA6E;AAChE,QAAA,oBAAoB,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAwB,sBAAsB,CAAC,CAAC;AAIxG,6EAA6E;AACtE,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAyC,EACgD,EAAE,CAC7F,CAAC,CAAiC,EAAE,EAAE;IACpC,OAAO,CAAC,CAAC,IAAI,CACX,CAAC,CAAC,MAAM,CAAC,EAAE,EACX,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,EAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,4BAAoB,CAAC,EACjD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAA,4BAAkB,EAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAChF,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAA,oBAAc,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EACvF,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CACpC,YAAY,CAAC,QAAQ;QACnB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YACf,GAAG,CAAC;YACJ,MAAM,EAAE,YAAY,CAAC,GAAG;SACzB,CAAC;QACJ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAC1B,EACD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,IAAA,2BAAY,EAAC,mBAAmB,EAAE,4BAA4B,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CACzF,EACD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EACpC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EACzB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAChD,CAAC;AACJ,CAAC,CAAC;AA3BS,QAAA,UAAU,cA2BnB"}
|
|
@@ -33,10 +33,12 @@ const TAG = 'jwtAuthenticatorRsa';
|
|
|
33
33
|
exports.JwtAuthenticatorRsaDeps = P.Context.GenericTag('JwtAuthenticatorRsaDeps');
|
|
34
34
|
// --------------------------------------------------------------------------
|
|
35
35
|
const middleware = () => (wrapped) => (i) => {
|
|
36
|
-
return P.pipe(P.Effect.Do, P.Effect.tap(P.Effect.logDebug(`[${TAG}] IN`)), P.Effect.bind('deps', () => exports.JwtAuthenticatorRsaDeps), P.Effect.bind('authToken', () => (0, helpers_1.extractBearerToken)(i.headers['authorization'])), P.Effect.bind('verification', ({ authToken, deps }) => (0, rsa_1.jwtVerifyTokenRsa)(authToken, deps)), P.Effect.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
return P.pipe(P.Effect.Do, P.Effect.tap(P.Effect.logDebug(`[${TAG}] IN`)), P.Effect.bind('deps', () => exports.JwtAuthenticatorRsaDeps), P.Effect.bind('authToken', () => (0, helpers_1.extractBearerToken)(i.headers['authorization'])), P.Effect.bind('verification', ({ authToken, deps }) => (0, rsa_1.jwtVerifyTokenRsa)(authToken, deps)), P.Effect.flatMap(({ verification }) => verification.verified
|
|
37
|
+
? P.Effect.succeed({
|
|
38
|
+
...i,
|
|
39
|
+
userId: verification.sub,
|
|
40
|
+
})
|
|
41
|
+
: P.Effect.fail(void 0)), P.Effect.mapError((e) => (0, HttpApiError_1.HttpApiError)('UnauthorizedError', `Invalid JWT RSA credentials: ${e?.message}`, 401, TAG, e)), P.Effect.tapError((_) => P.Effect.logError(`UnauthorizedError: Invalid JWT RSA credentials: ${i.headers}`)), P.Effect.flatMap(wrapped), P.Effect.tap(P.Effect.logDebug(`[${TAG}] OUT`)));
|
|
40
42
|
};
|
|
41
43
|
exports.middleware = middleware;
|
|
42
44
|
//# sourceMappingURL=jwtAuthenticatorRsa.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwtAuthenticatorRsa.js","sourceRoot":"","sources":["../../src/contrib/jwtAuthenticatorRsa.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAAmD;AAEnD,yEAAiF;AAEjF,qEAAgF;AAIhF,sDAAmD;AAGnD,MAAM,GAAG,GAAG,qBAAqB,CAAC;AAElC,6EAA6E;AAChE,QAAA,uBAAuB,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAA2B,yBAAyB,CAAC,CAAC;AAIjH,6EAA6E;AACtE,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAyC,EACmD,EAAE,CAChG,CAAC,CAAiC,EAAE,EAAE;IACpC,OAAO,CAAC,CAAC,IAAI,CACX,CAAC,CAAC,MAAM,CAAC,EAAE,EACX,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,EAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,+BAAuB,CAAC,EACpD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAA,4BAAkB,EAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAChF,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAA,uBAAiB,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAC1F,CAAC,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"jwtAuthenticatorRsa.js","sourceRoot":"","sources":["../../src/contrib/jwtAuthenticatorRsa.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAAmD;AAEnD,yEAAiF;AAEjF,qEAAgF;AAIhF,sDAAmD;AAGnD,MAAM,GAAG,GAAG,qBAAqB,CAAC;AAElC,6EAA6E;AAChE,QAAA,uBAAuB,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAA2B,yBAAyB,CAAC,CAAC;AAIjH,6EAA6E;AACtE,MAAM,UAAU,GACrB,GAAG,EAAE,CACL,CACE,OAAyC,EACmD,EAAE,CAChG,CAAC,CAAiC,EAAE,EAAE;IACpC,OAAO,CAAC,CAAC,IAAI,CACX,CAAC,CAAC,MAAM,CAAC,EAAE,EACX,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,EAC9C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,+BAAuB,CAAC,EACpD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAA,4BAAkB,EAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAChF,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAA,uBAAiB,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAC1F,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CACpC,YAAY,CAAC,QAAQ;QACnB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YACf,GAAG,CAAC;YACJ,MAAM,EAAE,YAAY,CAAC,GAAG;SACzB,CAAC;QACJ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAC1B,EACD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,IAAA,2BAAY,EAAC,mBAAmB,EAAE,gCAAgC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAC7F,EACD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,mDAAmD,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAC3G,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EACzB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAChD,CAAC;AACJ,CAAC,CAAC;AA3BS,QAAA,UAAU,cA2BnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konker.dev/middleware-fp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"author": "Konrad Markus <mail@konker.dev>",
|
|
5
5
|
"description": "Type safe middleware system based on Effect-ts",
|
|
6
6
|
"license": "ISC",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@gomomento/sdk": "^1.95.0",
|
|
25
25
|
"@konker.dev/aws-client-effect-dynamodb": "^0.0.8",
|
|
26
26
|
"@konker.dev/momento-cache-client-effect": "^0.0.7",
|
|
27
|
-
"@konker.dev/tiny-auth-utils-fp": "^0.0.
|
|
27
|
+
"@konker.dev/tiny-auth-utils-fp": "^0.0.18",
|
|
28
28
|
"aws-lambda": "^1.0.7"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|