@pristine-ts/networking 0.0.191 → 0.0.192
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/lib/cjs/interceptors/request-body-converter.interceptor.js +10 -13
- package/dist/lib/cjs/interceptors/request-body-converter.interceptor.js.map +1 -1
- package/dist/lib/cjs/interceptors/response-headers.interceptor.js +1 -1
- package/dist/lib/cjs/interceptors/response-headers.interceptor.js.map +1 -1
- package/dist/lib/esm/interceptors/request-body-converter.interceptor.js +10 -13
- package/dist/lib/esm/interceptors/request-body-converter.interceptor.js.map +1 -1
- package/dist/lib/esm/interceptors/response-headers.interceptor.js +1 -1
- package/dist/lib/esm/interceptors/response-headers.interceptor.js.map +1 -1
- package/package.json +8 -7
|
@@ -36,24 +36,21 @@ let RequestBodyConverterInterceptor = class RequestBodyConverterInterceptor {
|
|
|
36
36
|
if (this.isActive === false) {
|
|
37
37
|
return request;
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
for (let key in request.headers) {
|
|
41
|
-
if (request.headers.hasOwnProperty(key) === false) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
const requestHeader = request.headers[key];
|
|
45
|
-
if (key.toLowerCase() === "content-type") {
|
|
46
|
-
contentType = requestHeader;
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (contentType === undefined) {
|
|
39
|
+
if (request.hasHeader("Content-Type") === false) {
|
|
51
40
|
return request;
|
|
52
41
|
}
|
|
42
|
+
const contentType = request.getHeader("Content-Type");
|
|
53
43
|
switch (contentType.toLowerCase()) {
|
|
54
44
|
case "application/json":
|
|
55
45
|
switch (typeof request.body) {
|
|
46
|
+
case "undefined":
|
|
47
|
+
return request;
|
|
56
48
|
case "object":
|
|
49
|
+
if (request.body.constructor === Date) {
|
|
50
|
+
const errorMessage = "This request has the Content-Type header 'application/json' but the body is a Date object which is invalid JSON.";
|
|
51
|
+
this.logHandler.error(errorMessage);
|
|
52
|
+
throw new invalid_body_http_error_1.InvalidBodyHttpError(errorMessage);
|
|
53
|
+
}
|
|
57
54
|
return request;
|
|
58
55
|
case "string":
|
|
59
56
|
try {
|
|
@@ -62,7 +59,7 @@ let RequestBodyConverterInterceptor = class RequestBodyConverterInterceptor {
|
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
61
|
catch (e) {
|
|
65
|
-
const errorMessage = "This request has the Content-Type header 'application/json' but the body contains invalid JSON.";
|
|
62
|
+
const errorMessage = "This request has the Content-Type header 'application/json', and the body is of type string, but the body contains invalid JSON.";
|
|
66
63
|
this.logHandler.error(errorMessage);
|
|
67
64
|
throw new invalid_body_http_error_1.InvalidBodyHttpError(errorMessage);
|
|
68
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-body-converter.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/request-body-converter.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAA4C;AAE5C,gDAAyF;AACzF,4EAAqE;AAErE,+EAAuE;AAKvE,IAAa,+BAA+B,GAA5C,MAAa,+BAA+B;IACxC,YAA2G,QAAiB,EAChE,UAA+B;QADgB,aAAQ,GAAR,QAAQ,CAAS;QAChE,eAAU,GAAV,UAAU,CAAqB;IAC3F,CAAC;IAEK,gBAAgB,CAAC,OAAgB;;YACnC,IAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE;gBACxB,OAAO,OAAO,CAAC;aAClB;YAED,
|
|
1
|
+
{"version":3,"file":"request-body-converter.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/request-body-converter.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAA4C;AAE5C,gDAAyF;AACzF,4EAAqE;AAErE,+EAAuE;AAKvE,IAAa,+BAA+B,GAA5C,MAAa,+BAA+B;IACxC,YAA2G,QAAiB,EAChE,UAA+B;QADgB,aAAQ,GAAR,QAAQ,CAAS;QAChE,eAAU,GAAV,UAAU,CAAqB;IAC3F,CAAC;IAEK,gBAAgB,CAAC,OAAgB;;YACnC,IAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE;gBACxB,OAAO,OAAO,CAAC;aAClB;YAED,IAAG,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,KAAK,EAAE;gBAC5C,OAAO,OAAO,CAAC;aAClB;YAED,MAAM,WAAW,GAAW,OAAO,CAAC,SAAS,CAAC,cAAc,CAAW,CAAC;YAExE,QAAQ,WAAW,CAAC,WAAW,EAAE,EAAE;gBAC/B,KAAK,kBAAkB;oBAGnB,QAAQ,OAAO,OAAO,CAAC,IAAI,EAAE;wBACzB,KAAK,WAAW;4BACZ,OAAO,OAAO,CAAC;wBACnB,KAAK,QAAQ;4BACT,IAAG,OAAO,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE;gCAClC,MAAM,YAAY,GAAG,kHAAkH,CAAC;gCACxI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gCAEpC,MAAM,IAAI,8CAAoB,CAAC,YAAY,CAAC,CAAC;6BAChD;4BACD,OAAO,OAAO,CAAC;wBAEnB,KAAK,QAAQ;4BACT,IAAI;gCACA,IAAG,OAAO,CAAC,IAAI,EAAE;oCACb,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iCAC3C;6BACJ;4BACD,OAAO,CAAC,EAAE;gCACN,MAAM,YAAY,GAAG,kIAAkI,CAAC;gCACxJ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gCAEpC,MAAM,IAAI,8CAAoB,CAAC,YAAY,CAAC,CAAC;6BAChD;4BACD,MAAM;wBAEV;4BACI,MAAM,YAAY,GAAG,iGAAiG,CAAC;4BACvH,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;4BAEpC,MAAM,IAAI,8CAAoB,CAAC,YAAY,CAAC,CAAC;qBACpD;aAGR;YAED,OAAO,OAAO,CAAC;QACnB,CAAC;KAAA;CAEJ,CAAA;AA3DY,+BAA+B;IAH3C,YAAG,CAAC,iCAAwB,CAAC,kBAAkB,CAAC;IAChD,qBAAY,CAAC,mDAAuB,CAAC;IACrC,qBAAU,EAAE;IAEI,WAAA,iBAAM,CAAC,GAAG,GAAG,mDAAuB,GAAG,oCAAoC,CAAC,CAAA;IAC5E,WAAA,iBAAM,CAAC,qBAAqB,CAAC,CAAA;;GAFjC,+BAA+B,CA2D3C;AA3DY,0EAA+B"}
|
|
@@ -27,7 +27,7 @@ let ResponseHeadersInterceptor = class ResponseHeadersInterceptor {
|
|
|
27
27
|
interceptResponse(response, request, methodNode) {
|
|
28
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
29
|
if (methodNode && methodNode.route.context && methodNode.route.context.hasOwnProperty("responseHeaders")) {
|
|
30
|
-
response.
|
|
30
|
+
response.setHeaders(Object.assign(Object.assign({}, response.headers), methodNode.route.context.responseHeaders));
|
|
31
31
|
}
|
|
32
32
|
return response;
|
|
33
33
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-headers.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/response-headers.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,gDAAmG;AACnG,4EAAqE;AAGrE,uCAAoC;AACpC;;;GAGG;AAIH,IAAa,0BAA0B,GAAvC,MAAa,0BAA0B;IAC7B,iBAAiB,CAAC,QAAkB,EAAE,OAAgB,EAAE,UAA6B;;YACvF,IAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAC;gBACpG,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"response-headers.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/response-headers.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,gDAAmG;AACnG,4EAAqE;AAGrE,uCAAoC;AACpC;;;GAGG;AAIH,IAAa,0BAA0B,GAAvC,MAAa,0BAA0B;IAC7B,iBAAiB,CAAC,QAAkB,EAAE,OAAgB,EAAE,UAA6B;;YACvF,IAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAC;gBACpG,QAAQ,CAAC,UAAU,iCAAK,QAAQ,CAAC,OAAO,GAAK,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;aAC3F;YAED,OAAO,QAAQ,CAAC;QACpB,CAAC;KAAA;CACJ,CAAA;AARY,0BAA0B;IAHtC,YAAG,CAAC,iCAAwB,CAAC,kBAAkB,CAAC;IAChD,qBAAY,CAAC,mDAAuB,CAAC;IACrC,qBAAU,EAAE;GACA,0BAA0B,CAQtC;AARY,gEAA0B"}
|
|
@@ -33,24 +33,21 @@ let RequestBodyConverterInterceptor = class RequestBodyConverterInterceptor {
|
|
|
33
33
|
if (this.isActive === false) {
|
|
34
34
|
return request;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
for (let key in request.headers) {
|
|
38
|
-
if (request.headers.hasOwnProperty(key) === false) {
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
const requestHeader = request.headers[key];
|
|
42
|
-
if (key.toLowerCase() === "content-type") {
|
|
43
|
-
contentType = requestHeader;
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (contentType === undefined) {
|
|
36
|
+
if (request.hasHeader("Content-Type") === false) {
|
|
48
37
|
return request;
|
|
49
38
|
}
|
|
39
|
+
const contentType = request.getHeader("Content-Type");
|
|
50
40
|
switch (contentType.toLowerCase()) {
|
|
51
41
|
case "application/json":
|
|
52
42
|
switch (typeof request.body) {
|
|
43
|
+
case "undefined":
|
|
44
|
+
return request;
|
|
53
45
|
case "object":
|
|
46
|
+
if (request.body.constructor === Date) {
|
|
47
|
+
const errorMessage = "This request has the Content-Type header 'application/json' but the body is a Date object which is invalid JSON.";
|
|
48
|
+
this.logHandler.error(errorMessage);
|
|
49
|
+
throw new InvalidBodyHttpError(errorMessage);
|
|
50
|
+
}
|
|
54
51
|
return request;
|
|
55
52
|
case "string":
|
|
56
53
|
try {
|
|
@@ -59,7 +56,7 @@ let RequestBodyConverterInterceptor = class RequestBodyConverterInterceptor {
|
|
|
59
56
|
}
|
|
60
57
|
}
|
|
61
58
|
catch (e) {
|
|
62
|
-
const errorMessage = "This request has the Content-Type header 'application/json' but the body contains invalid JSON.";
|
|
59
|
+
const errorMessage = "This request has the Content-Type header 'application/json', and the body is of type string, but the body contains invalid JSON.";
|
|
63
60
|
this.logHandler.error(errorMessage);
|
|
64
61
|
throw new InvalidBodyHttpError(errorMessage);
|
|
65
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-body-converter.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/request-body-converter.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAC,UAAU,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAC,YAAY,EAAW,wBAAwB,EAAE,GAAG,EAAC,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAC,oBAAoB,EAAC,MAAM,mCAAmC,CAAC;AAKvE,IAAa,+BAA+B,GAA5C,MAAa,+BAA+B;IACxC,YAA2G,QAAiB,EAChE,UAA+B;QADgB,aAAQ,GAAR,QAAQ,CAAS;QAChE,eAAU,GAAV,UAAU,CAAqB;IAC3F,CAAC;IAEK,gBAAgB,CAAC,OAAgB;;YACnC,IAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE;gBACxB,OAAO,OAAO,CAAC;aAClB;YAED,
|
|
1
|
+
{"version":3,"file":"request-body-converter.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/request-body-converter.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAC,UAAU,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAC,YAAY,EAAW,wBAAwB,EAAE,GAAG,EAAC,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAC,oBAAoB,EAAC,MAAM,mCAAmC,CAAC;AAKvE,IAAa,+BAA+B,GAA5C,MAAa,+BAA+B;IACxC,YAA2G,QAAiB,EAChE,UAA+B;QADgB,aAAQ,GAAR,QAAQ,CAAS;QAChE,eAAU,GAAV,UAAU,CAAqB;IAC3F,CAAC;IAEK,gBAAgB,CAAC,OAAgB;;YACnC,IAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,EAAE;gBACxB,OAAO,OAAO,CAAC;aAClB;YAED,IAAG,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,KAAK,EAAE;gBAC5C,OAAO,OAAO,CAAC;aAClB;YAED,MAAM,WAAW,GAAW,OAAO,CAAC,SAAS,CAAC,cAAc,CAAW,CAAC;YAExE,QAAQ,WAAW,CAAC,WAAW,EAAE,EAAE;gBAC/B,KAAK,kBAAkB;oBAGnB,QAAQ,OAAO,OAAO,CAAC,IAAI,EAAE;wBACzB,KAAK,WAAW;4BACZ,OAAO,OAAO,CAAC;wBACnB,KAAK,QAAQ;4BACT,IAAG,OAAO,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE;gCAClC,MAAM,YAAY,GAAG,kHAAkH,CAAC;gCACxI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gCAEpC,MAAM,IAAI,oBAAoB,CAAC,YAAY,CAAC,CAAC;6BAChD;4BACD,OAAO,OAAO,CAAC;wBAEnB,KAAK,QAAQ;4BACT,IAAI;gCACA,IAAG,OAAO,CAAC,IAAI,EAAE;oCACb,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iCAC3C;6BACJ;4BACD,OAAO,CAAC,EAAE;gCACN,MAAM,YAAY,GAAG,kIAAkI,CAAC;gCACxJ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gCAEpC,MAAM,IAAI,oBAAoB,CAAC,YAAY,CAAC,CAAC;6BAChD;4BACD,MAAM;wBAEV;4BACI,MAAM,YAAY,GAAG,iGAAiG,CAAC;4BACvH,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;4BAEpC,MAAM,IAAI,oBAAoB,CAAC,YAAY,CAAC,CAAC;qBACpD;aAGR;YAED,OAAO,OAAO,CAAC;QACnB,CAAC;KAAA;CAEJ,CAAA;AA3DY,+BAA+B;IAH3C,GAAG,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;IAChD,YAAY,CAAC,uBAAuB,CAAC;IACrC,UAAU,EAAE;IAEI,WAAA,MAAM,CAAC,GAAG,GAAG,uBAAuB,GAAG,oCAAoC,CAAC,CAAA;IAC5E,WAAA,MAAM,CAAC,qBAAqB,CAAC,CAAA;;GAFjC,+BAA+B,CA2D3C;SA3DY,+BAA+B"}
|
|
@@ -24,7 +24,7 @@ let ResponseHeadersInterceptor = class ResponseHeadersInterceptor {
|
|
|
24
24
|
interceptResponse(response, request, methodNode) {
|
|
25
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26
26
|
if (methodNode && methodNode.route.context && methodNode.route.context.hasOwnProperty("responseHeaders")) {
|
|
27
|
-
response.
|
|
27
|
+
response.setHeaders(Object.assign(Object.assign({}, response.headers), methodNode.route.context.responseHeaders));
|
|
28
28
|
}
|
|
29
29
|
return response;
|
|
30
30
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-headers.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/response-headers.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,OAAO,EAAC,YAAY,EAAqB,wBAAwB,EAAE,GAAG,EAAC,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAGrE,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACpC;;;GAGG;AAIH,IAAa,0BAA0B,GAAvC,MAAa,0BAA0B;IAC7B,iBAAiB,CAAC,QAAkB,EAAE,OAAgB,EAAE,UAA6B;;YACvF,IAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAC;gBACpG,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"response-headers.interceptor.js","sourceRoot":"","sources":["../../../../src/interceptors/response-headers.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,OAAO,EAAC,YAAY,EAAqB,wBAAwB,EAAE,GAAG,EAAC,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAGrE,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACpC;;;GAGG;AAIH,IAAa,0BAA0B,GAAvC,MAAa,0BAA0B;IAC7B,iBAAiB,CAAC,QAAkB,EAAE,OAAgB,EAAE,UAA6B;;YACvF,IAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAC;gBACpG,QAAQ,CAAC,UAAU,iCAAK,QAAQ,CAAC,OAAO,GAAK,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;aAC3F;YAED,OAAO,QAAQ,CAAC;QACpB,CAAC;KAAA;CACJ,CAAA;AARY,0BAA0B;IAHtC,GAAG,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;IAChD,YAAY,CAAC,uBAAuB,CAAC;IACrC,UAAU,EAAE;GACA,0BAA0B,CAQtC;SARY,0BAA0B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pristine-ts/networking",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.192",
|
|
4
4
|
"description": "",
|
|
5
5
|
"module": "dist/lib/esm/networking.module.js",
|
|
6
6
|
"main": "dist/lib/cjs/networking.module.js",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json",
|
|
10
10
|
"prepublish": "npm run build",
|
|
11
|
-
"test": "jest"
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"test:cov": "jest --coverage"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"dist"
|
|
@@ -19,10 +20,10 @@
|
|
|
19
20
|
"access": "public"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"@pristine-ts/common": "^0.0.
|
|
23
|
-
"@pristine-ts/core": "^0.0.
|
|
24
|
-
"@pristine-ts/security": "^0.0.
|
|
25
|
-
"@pristine-ts/telemetry": "^0.0.
|
|
23
|
+
"@pristine-ts/common": "^0.0.192",
|
|
24
|
+
"@pristine-ts/core": "^0.0.192",
|
|
25
|
+
"@pristine-ts/security": "^0.0.192",
|
|
26
|
+
"@pristine-ts/telemetry": "^0.0.192",
|
|
26
27
|
"lodash": "^4.17.21",
|
|
27
28
|
"url-parse": "^1.4.7"
|
|
28
29
|
},
|
|
@@ -60,5 +61,5 @@
|
|
|
60
61
|
"src/*.{js,ts}"
|
|
61
62
|
]
|
|
62
63
|
},
|
|
63
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "3f78bc1ae1441441fb9b57fd98b9fd6667a4d28a"
|
|
64
65
|
}
|