@shopify/shopify-api 4.1.0 → 5.0.1
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 +26 -5
- package/dist/auth/oauth/oauth.d.ts.map +1 -1
- package/dist/auth/oauth/oauth.js +7 -5
- package/dist/auth/session/session_storage.d.ts +12 -0
- package/dist/auth/session/session_storage.d.ts.map +1 -1
- package/dist/auth/session/storage/custom.d.ts +5 -1
- package/dist/auth/session/storage/custom.d.ts.map +1 -1
- package/dist/auth/session/storage/custom.js +59 -1
- package/dist/auth/session/storage/memory.d.ts +2 -0
- package/dist/auth/session/storage/memory.d.ts.map +1 -1
- package/dist/auth/session/storage/memory.js +20 -0
- package/dist/auth/session/storage/mongodb.d.ts +2 -0
- package/dist/auth/session/storage/mongodb.d.ts.map +1 -1
- package/dist/auth/session/storage/mongodb.js +41 -6
- package/dist/auth/session/storage/mysql.d.ts +2 -0
- package/dist/auth/session/storage/mysql.d.ts.map +1 -1
- package/dist/auth/session/storage/mysql.js +41 -0
- package/dist/auth/session/storage/postgresql.d.ts +2 -0
- package/dist/auth/session/storage/postgresql.d.ts.map +1 -1
- package/dist/auth/session/storage/postgresql.js +41 -0
- package/dist/auth/session/storage/redis.d.ts +4 -1
- package/dist/auth/session/storage/redis.d.ts.map +1 -1
- package/dist/auth/session/storage/redis.js +68 -3
- package/dist/auth/session/storage/sqlite.d.ts +2 -0
- package/dist/auth/session/storage/sqlite.d.ts.map +1 -1
- package/dist/auth/session/storage/sqlite.js +42 -0
- package/dist/base-types.d.ts +1 -0
- package/dist/base-types.d.ts.map +1 -1
- package/dist/clients/graphql/graphql_client.d.ts.map +1 -1
- package/dist/clients/graphql/graphql_client.js +25 -14
- package/dist/clients/http_client/http_client.d.ts.map +1 -1
- package/dist/clients/http_client/http_client.js +5 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +3 -0
- package/dist/error.d.ts +13 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +20 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/utils/delete-offline-session.d.ts.map +1 -1
- package/dist/utils/delete-offline-session.js +4 -2
- package/dist/utils/get-embedded-app-url.d.ts.map +1 -1
- package/dist/utils/get-embedded-app-url.js +2 -1
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/load-offline-session.d.ts.map +1 -1
- package/dist/utils/load-offline-session.js +4 -2
- package/dist/utils/setup-jest.d.ts.map +1 -1
- package/dist/utils/setup-jest.js +1 -0
- package/dist/utils/shop-validator.d.ts +12 -3
- package/dist/utils/shop-validator.d.ts.map +1 -1
- package/dist/utils/shop-validator.js +39 -7
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webhooks/registry.d.ts.map +1 -1
- package/dist/webhooks/registry.js +23 -20
- package/package.json +1 -1
- package/dist/__tests__/fake-resource-with-custom-prefix.d.ts +0 -21
- package/dist/__tests__/fake-resource-with-custom-prefix.d.ts.map +0 -1
- package/dist/__tests__/fake-resource-with-custom-prefix.js +0 -46
- package/dist/__tests__/fake-resource.d.ts +0 -41
- package/dist/__tests__/fake-resource.d.ts.map +0 -1
- package/dist/__tests__/fake-resource.js +0 -122
- package/dist/auth/session/storage/__tests__/battery-of-tests.d.ts +0 -3
- package/dist/auth/session/storage/__tests__/battery-of-tests.d.ts.map +0 -1
- package/dist/auth/session/storage/__tests__/battery-of-tests.js +0 -191
- package/dist/auth/session/storage/__tests__/utils.d.ts +0 -10
- package/dist/auth/session/storage/__tests__/utils.d.ts.map +0 -1
- package/dist/auth/session/storage/__tests__/utils.js +0 -87
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/webhooks/registry.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AAUxB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,oBAAoB,EAEpB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,UAAU,gBAAgB;IACxB,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACvC;AAED,UAAU,iBAAiB;IACzB,eAAe,EAAE;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAA;KAAC,CAAC;IAEzD;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAE/D;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE9C;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAAC;IAEvD;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAExE;;;;;OAKG;IACH,OAAO,CACL,OAAO,EAAE,IAAI,CAAC,eAAe,EAC7B,QAAQ,EAAE,IAAI,CAAC,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAiCD,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAuB9C;AAED,iBAAS,UAAU,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,cAAoC,EACpD,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAmDR;AAED,QAAA,MAAM,UAAU,EAAE,MAAM,EAIvB,CAAC;AAEF,QAAA,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/webhooks/registry.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AAUxB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,oBAAoB,EAEpB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,UAAU,gBAAgB;IACxB,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACvC;AAED,UAAU,iBAAiB;IACzB,eAAe,EAAE;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAA;KAAC,CAAC;IAEzD;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAE/D;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE9C;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAAC;IAEvD;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAExE;;;;;OAKG;IACH,OAAO,CACL,OAAO,EAAE,IAAI,CAAC,eAAe,EAC7B,QAAQ,EAAE,IAAI,CAAC,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAiCD,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAuB9C;AAED,iBAAS,UAAU,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,cAAoC,EACpD,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAmDR;AAED,QAAA,MAAM,UAAU,EAAE,MAAM,EAIvB,CAAC;AAEF,QAAA,MAAM,gBAAgB,EAAE,iBA4PvB,CAAC;AAEF,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,UAAU,GACX,CAAC"}
|
|
@@ -107,7 +107,7 @@ var WebhooksRegistry = {
|
|
|
107
107
|
register: function (_a) {
|
|
108
108
|
var path = _a.path, topic = _a.topic, accessToken = _a.accessToken, shop = _a.shop, _b = _a.deliveryMethod, deliveryMethod = _b === void 0 ? types_1.DeliveryMethod.Http : _b;
|
|
109
109
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
110
|
-
var registerReturn, client, address, checkResult, webhookId, mustRegister, node, endpointAddress, result;
|
|
110
|
+
var registerReturn, client, address, checkResult, error_1, result, webhookId, mustRegister, node, endpointAddress, result;
|
|
111
111
|
return tslib_1.__generator(this, function (_c) {
|
|
112
112
|
switch (_c.label) {
|
|
113
113
|
case 0:
|
|
@@ -130,19 +130,22 @@ var WebhooksRegistry = {
|
|
|
130
130
|
address = deliveryMethod === types_1.DeliveryMethod.Http
|
|
131
131
|
? "".concat(context_1.Context.HOST_SCHEME, "://").concat(context_1.Context.HOST_NAME).concat(path)
|
|
132
132
|
: path;
|
|
133
|
+
_c.label = 1;
|
|
134
|
+
case 1:
|
|
135
|
+
_c.trys.push([1, 3, , 4]);
|
|
133
136
|
return [4 /*yield*/, client.query({
|
|
134
137
|
data: buildCheckQuery(topic),
|
|
135
138
|
})];
|
|
136
|
-
case
|
|
139
|
+
case 2:
|
|
137
140
|
checkResult = (_c.sent());
|
|
141
|
+
return [3 /*break*/, 4];
|
|
142
|
+
case 3:
|
|
143
|
+
error_1 = _c.sent();
|
|
144
|
+
result = error_1 instanceof ShopifyErrors.GraphqlQueryError ? error_1.response : {};
|
|
145
|
+
registerReturn[topic] = { success: false, result: result };
|
|
146
|
+
return [2 /*return*/, registerReturn];
|
|
147
|
+
case 4:
|
|
138
148
|
mustRegister = true;
|
|
139
|
-
if ('errors' in checkResult.body) {
|
|
140
|
-
registerReturn[topic] = {
|
|
141
|
-
success: false,
|
|
142
|
-
result: checkResult.body,
|
|
143
|
-
};
|
|
144
|
-
return [2 /*return*/, registerReturn];
|
|
145
|
-
}
|
|
146
149
|
if (checkResult.body.data.webhookSubscriptions.edges.length) {
|
|
147
150
|
node = checkResult.body.data.webhookSubscriptions.edges[0].node;
|
|
148
151
|
endpointAddress = '';
|
|
@@ -157,24 +160,24 @@ var WebhooksRegistry = {
|
|
|
157
160
|
mustRegister = false;
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
|
-
if (!mustRegister) return [3 /*break*/,
|
|
163
|
+
if (!mustRegister) return [3 /*break*/, 6];
|
|
161
164
|
return [4 /*yield*/, client.query({
|
|
162
165
|
data: buildQuery(topic, address, deliveryMethod, webhookId),
|
|
163
166
|
})];
|
|
164
|
-
case
|
|
167
|
+
case 5:
|
|
165
168
|
result = _c.sent();
|
|
166
169
|
registerReturn[topic] = {
|
|
167
170
|
success: isSuccess(result.body, deliveryMethod, webhookId),
|
|
168
171
|
result: result.body,
|
|
169
172
|
};
|
|
170
|
-
return [3 /*break*/,
|
|
171
|
-
case
|
|
173
|
+
return [3 /*break*/, 7];
|
|
174
|
+
case 6:
|
|
172
175
|
registerReturn[topic] = {
|
|
173
176
|
success: true,
|
|
174
177
|
result: {},
|
|
175
178
|
};
|
|
176
|
-
_c.label =
|
|
177
|
-
case
|
|
179
|
+
_c.label = 7;
|
|
180
|
+
case 7: return [2 /*return*/, registerReturn];
|
|
178
181
|
}
|
|
179
182
|
});
|
|
180
183
|
});
|
|
@@ -242,7 +245,7 @@ var WebhooksRegistry = {
|
|
|
242
245
|
reqBody += chunk;
|
|
243
246
|
});
|
|
244
247
|
request.on('end', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
245
|
-
var hmac, topic, domain, missingHeaders, statusCode, responseError, headers, generatedHash, graphqlTopic, webhookEntry,
|
|
248
|
+
var hmac, topic, domain, missingHeaders, statusCode, responseError, headers, generatedHash, graphqlTopic, webhookEntry, error_2;
|
|
246
249
|
return tslib_1.__generator(this, function (_a) {
|
|
247
250
|
switch (_a.label) {
|
|
248
251
|
case 0:
|
|
@@ -299,18 +302,18 @@ var WebhooksRegistry = {
|
|
|
299
302
|
statusCode = network_1.StatusCode.Ok;
|
|
300
303
|
return [3 /*break*/, 4];
|
|
301
304
|
case 3:
|
|
302
|
-
|
|
305
|
+
error_2 = _a.sent();
|
|
303
306
|
statusCode = network_1.StatusCode.InternalServerError;
|
|
304
|
-
responseError =
|
|
307
|
+
responseError = error_2;
|
|
305
308
|
return [3 /*break*/, 4];
|
|
306
309
|
case 4: return [3 /*break*/, 6];
|
|
307
310
|
case 5:
|
|
308
|
-
statusCode = network_1.StatusCode.
|
|
311
|
+
statusCode = network_1.StatusCode.NotFound;
|
|
309
312
|
responseError = new ShopifyErrors.InvalidWebhookError("No webhook is registered for topic ".concat(topic));
|
|
310
313
|
_a.label = 6;
|
|
311
314
|
case 6: return [3 /*break*/, 8];
|
|
312
315
|
case 7:
|
|
313
|
-
statusCode = network_1.StatusCode.
|
|
316
|
+
statusCode = network_1.StatusCode.Unauthorized;
|
|
314
317
|
responseError = new ShopifyErrors.InvalidWebhookError("Could not validate request for topic ".concat(topic));
|
|
315
318
|
_a.label = 8;
|
|
316
319
|
case 8:
|
package/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import Base, { ResourcePath } from '../base-rest-resource';
|
|
2
|
-
import { SessionInterface } from '../auth/session/types';
|
|
3
|
-
import { ApiVersion } from '../base-types';
|
|
4
|
-
interface FakeResourceWithCustomPrefixFindArgs {
|
|
5
|
-
session: SessionInterface;
|
|
6
|
-
id: string | number;
|
|
7
|
-
}
|
|
8
|
-
export default class FakeResourceWithCustomPrefix extends Base {
|
|
9
|
-
static API_VERSION: ApiVersion;
|
|
10
|
-
protected static NAME: string;
|
|
11
|
-
protected static PLURAL_NAME: string;
|
|
12
|
-
protected static CUSTOM_PREFIX: string;
|
|
13
|
-
protected static HAS_ONE: {};
|
|
14
|
-
protected static HAS_MANY: {};
|
|
15
|
-
protected static PATHS: ResourcePath[];
|
|
16
|
-
static find: ({ session, id, }: FakeResourceWithCustomPrefixFindArgs) => Promise<FakeResourceWithCustomPrefix | null>;
|
|
17
|
-
id?: number | string | null;
|
|
18
|
-
attribute?: string | null;
|
|
19
|
-
}
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=fake-resource-with-custom-prefix.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fake-resource-with-custom-prefix.d.ts","sourceRoot":"","sources":["../../src/__tests__/fake-resource-with-custom-prefix.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,UAAU,oCAAoC;IAC5C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED,MAAM,CAAC,OAAO,OAAO,4BAA6B,SAAQ,IAAI;IAC5D,OAAc,WAAW,aAAuB;IAChD,SAAS,CAAC,MAAM,CAAC,IAAI,SAAsC;IAC3D,SAAS,CAAC,MAAM,CAAC,WAAW,SAAwC;IACpE,SAAS,CAAC,MAAM,CAAC,aAAa,SAA0B;IAExD,SAAS,CAAC,MAAM,CAAC,OAAO,KAAM;IAC9B,SAAS,CAAC,MAAM,CAAC,QAAQ,KAAM;IAE/B,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,CAOpC;IAEF,OAAc,IAAI,qBAGf,oCAAoC,KAAG,QAAQ,4BAA4B,GAAG,IAAI,CAAC,CAMpF;IAEF,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var tslib_1 = require("tslib");
|
|
4
|
-
var base_rest_resource_1 = tslib_1.__importDefault(require("../base-rest-resource"));
|
|
5
|
-
var base_types_1 = require("../base-types");
|
|
6
|
-
var FakeResourceWithCustomPrefix = /** @class */ (function (_super) {
|
|
7
|
-
tslib_1.__extends(FakeResourceWithCustomPrefix, _super);
|
|
8
|
-
function FakeResourceWithCustomPrefix() {
|
|
9
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
10
|
-
}
|
|
11
|
-
var _a;
|
|
12
|
-
_a = FakeResourceWithCustomPrefix;
|
|
13
|
-
FakeResourceWithCustomPrefix.API_VERSION = base_types_1.ApiVersion.Unstable;
|
|
14
|
-
FakeResourceWithCustomPrefix.NAME = 'fake_resource_with_custom_prefix';
|
|
15
|
-
FakeResourceWithCustomPrefix.PLURAL_NAME = 'fake_resource_with_custom_prefixes';
|
|
16
|
-
FakeResourceWithCustomPrefix.CUSTOM_PREFIX = '/admin/custom_prefix';
|
|
17
|
-
FakeResourceWithCustomPrefix.HAS_ONE = {};
|
|
18
|
-
FakeResourceWithCustomPrefix.HAS_MANY = {};
|
|
19
|
-
FakeResourceWithCustomPrefix.PATHS = [
|
|
20
|
-
{
|
|
21
|
-
http_method: 'get',
|
|
22
|
-
operation: 'get',
|
|
23
|
-
ids: ['id'],
|
|
24
|
-
path: 'fake_resource_with_custom_prefix/<id>.json',
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
FakeResourceWithCustomPrefix.find = function (_b) {
|
|
28
|
-
var session = _b.session, id = _b.id;
|
|
29
|
-
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
30
|
-
var result;
|
|
31
|
-
return tslib_1.__generator(_a, function (_c) {
|
|
32
|
-
switch (_c.label) {
|
|
33
|
-
case 0: return [4 /*yield*/, FakeResourceWithCustomPrefix.baseFind({
|
|
34
|
-
session: session,
|
|
35
|
-
urlIds: { id: id },
|
|
36
|
-
})];
|
|
37
|
-
case 1:
|
|
38
|
-
result = _c.sent();
|
|
39
|
-
return [2 /*return*/, result ? result[0] : null];
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
return FakeResourceWithCustomPrefix;
|
|
45
|
-
}(base_rest_resource_1.default));
|
|
46
|
-
exports.default = FakeResourceWithCustomPrefix;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import Base, { ParamSet, ResourcePath } from '../base-rest-resource';
|
|
2
|
-
import { SessionInterface } from '../auth/session/types';
|
|
3
|
-
import { ApiVersion } from '../base-types';
|
|
4
|
-
interface FakeResourceFindArgs {
|
|
5
|
-
params?: ParamSet;
|
|
6
|
-
session: SessionInterface;
|
|
7
|
-
id: number;
|
|
8
|
-
other_resource_id?: number | null;
|
|
9
|
-
}
|
|
10
|
-
interface FakeResourceAllArgs {
|
|
11
|
-
params?: ParamSet;
|
|
12
|
-
session: SessionInterface;
|
|
13
|
-
}
|
|
14
|
-
interface FakeResourceCustomArgs {
|
|
15
|
-
session: SessionInterface;
|
|
16
|
-
id: number;
|
|
17
|
-
other_resource_id: number;
|
|
18
|
-
}
|
|
19
|
-
export default class FakeResource extends Base {
|
|
20
|
-
static API_VERSION: ApiVersion;
|
|
21
|
-
protected static NAME: string;
|
|
22
|
-
protected static PLURAL_NAME: string;
|
|
23
|
-
protected static READ_ONLY_ATTRIBUTES: string[];
|
|
24
|
-
protected static HAS_ONE: {
|
|
25
|
-
has_one_attribute: typeof FakeResource;
|
|
26
|
-
};
|
|
27
|
-
protected static HAS_MANY: {
|
|
28
|
-
has_many_attribute: typeof FakeResource;
|
|
29
|
-
};
|
|
30
|
-
protected static PATHS: ResourcePath[];
|
|
31
|
-
static find: ({ session, params, id, other_resource_id, ...otherArgs }: FakeResourceFindArgs) => Promise<FakeResource | null>;
|
|
32
|
-
static all: ({ session, params, }: FakeResourceAllArgs) => Promise<FakeResource[]>;
|
|
33
|
-
static custom: ({ session, id, other_resource_id, }: FakeResourceCustomArgs) => Promise<Body>;
|
|
34
|
-
id?: number | string | null;
|
|
35
|
-
attribute?: string | null;
|
|
36
|
-
has_one_attribute?: FakeResource | null;
|
|
37
|
-
has_many_attribute?: FakeResource[] | null;
|
|
38
|
-
other_resource_id?: number | null;
|
|
39
|
-
}
|
|
40
|
-
export {};
|
|
41
|
-
//# sourceMappingURL=fake-resource.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fake-resource.d.ts","sourceRoot":"","sources":["../../src/__tests__/fake-resource.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAC,QAAQ,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,UAAU,sBAAsB;IAC9B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,IAAI;IAC5C,OAAc,WAAW,aAAuB;IAChD,SAAS,CAAC,MAAM,CAAC,IAAI,SAAmB;IACxC,SAAS,CAAC,MAAM,CAAC,WAAW,SAAoB;IAEhD,SAAS,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,EAAE,CAA4B;IAE3E,SAAS,CAAC,MAAM,CAAC,OAAO;;MAEtB;IAEF,SAAS,CAAC,MAAM,CAAC,QAAQ;;MAEvB;IAEF,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,CAiDpC;IAEF,OAAc,IAAI,6DAMf,oBAAoB,KAAG,QAAQ,YAAY,GAAG,IAAI,CAAC,CAOpD;IAEF,OAAc,GAAG,yBAGd,mBAAmB,KAAG,QAAQ,YAAY,EAAE,CAAC,CAM9C;IAEF,OAAc,MAAM,wCAIjB,sBAAsB,KAAG,QAAQ,IAAI,CAAC,CASvC;IAEF,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACxC,kBAAkB,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC3C,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC"}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var tslib_1 = require("tslib");
|
|
4
|
-
var base_rest_resource_1 = tslib_1.__importDefault(require("../base-rest-resource"));
|
|
5
|
-
var base_types_1 = require("../base-types");
|
|
6
|
-
var FakeResource = /** @class */ (function (_super) {
|
|
7
|
-
tslib_1.__extends(FakeResource, _super);
|
|
8
|
-
function FakeResource() {
|
|
9
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
10
|
-
}
|
|
11
|
-
var _a;
|
|
12
|
-
_a = FakeResource;
|
|
13
|
-
FakeResource.API_VERSION = base_types_1.ApiVersion.Unstable;
|
|
14
|
-
FakeResource.NAME = 'fake_resource';
|
|
15
|
-
FakeResource.PLURAL_NAME = 'fake_resources';
|
|
16
|
-
FakeResource.READ_ONLY_ATTRIBUTES = ['unsaveable_attribute'];
|
|
17
|
-
FakeResource.HAS_ONE = {
|
|
18
|
-
has_one_attribute: FakeResource,
|
|
19
|
-
};
|
|
20
|
-
FakeResource.HAS_MANY = {
|
|
21
|
-
has_many_attribute: FakeResource,
|
|
22
|
-
};
|
|
23
|
-
FakeResource.PATHS = [
|
|
24
|
-
{
|
|
25
|
-
http_method: 'get',
|
|
26
|
-
operation: 'get',
|
|
27
|
-
ids: ['id'],
|
|
28
|
-
path: 'fake_resources/<id>.json',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
http_method: 'get',
|
|
32
|
-
operation: 'get',
|
|
33
|
-
ids: [],
|
|
34
|
-
path: 'fake_resources.json',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
http_method: 'post',
|
|
38
|
-
operation: 'post',
|
|
39
|
-
ids: [],
|
|
40
|
-
path: 'fake_resources.json',
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
http_method: 'put',
|
|
44
|
-
operation: 'put',
|
|
45
|
-
ids: ['id'],
|
|
46
|
-
path: 'fake_resources/<id>.json',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
http_method: 'delete',
|
|
50
|
-
operation: 'delete',
|
|
51
|
-
ids: ['id'],
|
|
52
|
-
path: 'fake_resources/<id>.json',
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
http_method: 'get',
|
|
56
|
-
operation: 'get',
|
|
57
|
-
ids: ['id', 'other_resource_id'],
|
|
58
|
-
path: 'other_resources/<other_resource_id>/fake_resources/<id>.json',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
http_method: 'get',
|
|
62
|
-
operation: 'custom',
|
|
63
|
-
ids: ['id', 'other_resource_id'],
|
|
64
|
-
path: 'other_resources/<other_resource_id>/fake_resources/<id>/custom.json',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
http_method: 'delete',
|
|
68
|
-
operation: 'delete',
|
|
69
|
-
ids: ['id', 'other_resource_id'],
|
|
70
|
-
path: 'other_resources/<other_resource_id>/fake_resources/<id>.json',
|
|
71
|
-
},
|
|
72
|
-
];
|
|
73
|
-
FakeResource.find = function (_b) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
74
|
-
var result;
|
|
75
|
-
var session = _b.session, params = _b.params, id = _b.id, _c = _b.other_resource_id, other_resource_id = _c === void 0 ? null : _c, otherArgs = tslib_1.__rest(_b, ["session", "params", "id", "other_resource_id"]);
|
|
76
|
-
return tslib_1.__generator(_a, function (_d) {
|
|
77
|
-
switch (_d.label) {
|
|
78
|
-
case 0: return [4 /*yield*/, FakeResource.baseFind({
|
|
79
|
-
session: session,
|
|
80
|
-
urlIds: { id: id, other_resource_id: other_resource_id },
|
|
81
|
-
params: tslib_1.__assign(tslib_1.__assign({}, params), otherArgs),
|
|
82
|
-
})];
|
|
83
|
-
case 1:
|
|
84
|
-
result = _d.sent();
|
|
85
|
-
return [2 /*return*/, result ? result[0] : null];
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}); };
|
|
89
|
-
FakeResource.all = function (_b) {
|
|
90
|
-
var session = _b.session, params = _b.params;
|
|
91
|
-
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
92
|
-
return tslib_1.__generator(_a, function (_c) {
|
|
93
|
-
return [2 /*return*/, FakeResource.baseFind({
|
|
94
|
-
session: session,
|
|
95
|
-
params: params,
|
|
96
|
-
urlIds: {},
|
|
97
|
-
})];
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
FakeResource.custom = function (_b) {
|
|
102
|
-
var session = _b.session, id = _b.id, other_resource_id = _b.other_resource_id;
|
|
103
|
-
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
104
|
-
var response;
|
|
105
|
-
return tslib_1.__generator(_a, function (_c) {
|
|
106
|
-
switch (_c.label) {
|
|
107
|
-
case 0: return [4 /*yield*/, FakeResource.request({
|
|
108
|
-
http_method: 'get',
|
|
109
|
-
operation: 'custom',
|
|
110
|
-
session: session,
|
|
111
|
-
urlIds: { id: id, other_resource_id: other_resource_id },
|
|
112
|
-
})];
|
|
113
|
-
case 1:
|
|
114
|
-
response = _c.sent();
|
|
115
|
-
return [2 /*return*/, response.body];
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
};
|
|
120
|
-
return FakeResource;
|
|
121
|
-
}(base_rest_resource_1.default));
|
|
122
|
-
exports.default = FakeResource;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"battery-of-tests.d.ts","sourceRoot":"","sources":["../../../../../src/auth/session/storage/__tests__/battery-of-tests.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAErD,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,QA+F3E"}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.batteryOfTests = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var context_1 = require("../../../../context");
|
|
6
|
-
var session_1 = require("../../session");
|
|
7
|
-
var session_utils_1 = require("../../session-utils");
|
|
8
|
-
function batteryOfTests(storageFactory) {
|
|
9
|
-
var _this = this;
|
|
10
|
-
it('can store and delete all kinds of sessions', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
11
|
-
var sessionFactories, sessionId, storage, sessionFactories_1, sessionFactories_1_1, factory, session, _a, _b, loadedSession, e_1_1;
|
|
12
|
-
var e_1, _c;
|
|
13
|
-
var _this = this;
|
|
14
|
-
return tslib_1.__generator(this, function (_d) {
|
|
15
|
-
switch (_d.label) {
|
|
16
|
-
case 0:
|
|
17
|
-
sessionFactories = [
|
|
18
|
-
function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
19
|
-
var session;
|
|
20
|
-
return tslib_1.__generator(this, function (_a) {
|
|
21
|
-
session = new session_1.Session(sessionId, 'shop', 'state', false);
|
|
22
|
-
session.scope = context_1.Context.SCOPES.toString();
|
|
23
|
-
session.accessToken = '123';
|
|
24
|
-
return [2 /*return*/, session];
|
|
25
|
-
});
|
|
26
|
-
}); },
|
|
27
|
-
function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
28
|
-
var session, expiryDate;
|
|
29
|
-
return tslib_1.__generator(this, function (_a) {
|
|
30
|
-
session = new session_1.Session(sessionId, 'shop', 'state', false);
|
|
31
|
-
expiryDate = new Date();
|
|
32
|
-
expiryDate.setMinutes(expiryDate.getMinutes() + 60);
|
|
33
|
-
session.expires = expiryDate;
|
|
34
|
-
session.accessToken = '123';
|
|
35
|
-
session.scope = context_1.Context.SCOPES.toString();
|
|
36
|
-
return [2 /*return*/, session];
|
|
37
|
-
});
|
|
38
|
-
}); },
|
|
39
|
-
function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
40
|
-
var session;
|
|
41
|
-
return tslib_1.__generator(this, function (_a) {
|
|
42
|
-
session = new session_1.Session(sessionId, 'shop', 'state', false);
|
|
43
|
-
session.expires = null;
|
|
44
|
-
session.scope = context_1.Context.SCOPES.toString();
|
|
45
|
-
session.accessToken = '123';
|
|
46
|
-
return [2 /*return*/, session];
|
|
47
|
-
});
|
|
48
|
-
}); },
|
|
49
|
-
function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
50
|
-
var session;
|
|
51
|
-
return tslib_1.__generator(this, function (_a) {
|
|
52
|
-
session = new session_1.Session(sessionId, 'shop', 'state', false);
|
|
53
|
-
session.expires = undefined;
|
|
54
|
-
session.scope = context_1.Context.SCOPES.toString();
|
|
55
|
-
session.accessToken = '123';
|
|
56
|
-
return [2 /*return*/, session];
|
|
57
|
-
});
|
|
58
|
-
}); },
|
|
59
|
-
function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
60
|
-
var session;
|
|
61
|
-
return tslib_1.__generator(this, function (_a) {
|
|
62
|
-
session = new session_1.Session(sessionId, 'shop', 'state', false);
|
|
63
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
64
|
-
session.onlineAccessInfo = { associated_user: {} };
|
|
65
|
-
session.onlineAccessInfo.associated_user.id = 123;
|
|
66
|
-
session.scope = context_1.Context.SCOPES.toString();
|
|
67
|
-
session.accessToken = '123';
|
|
68
|
-
return [2 /*return*/, session];
|
|
69
|
-
});
|
|
70
|
-
}); },
|
|
71
|
-
];
|
|
72
|
-
sessionId = 'test_session';
|
|
73
|
-
return [4 /*yield*/, storageFactory()];
|
|
74
|
-
case 1:
|
|
75
|
-
storage = _d.sent();
|
|
76
|
-
_d.label = 2;
|
|
77
|
-
case 2:
|
|
78
|
-
_d.trys.push([2, 14, 15, 16]);
|
|
79
|
-
sessionFactories_1 = tslib_1.__values(sessionFactories), sessionFactories_1_1 = sessionFactories_1.next();
|
|
80
|
-
_d.label = 3;
|
|
81
|
-
case 3:
|
|
82
|
-
if (!!sessionFactories_1_1.done) return [3 /*break*/, 13];
|
|
83
|
-
factory = sessionFactories_1_1.value;
|
|
84
|
-
return [4 /*yield*/, factory()];
|
|
85
|
-
case 4:
|
|
86
|
-
session = _d.sent();
|
|
87
|
-
return [4 /*yield*/, expect(storage.storeSession(session)).resolves.toBe(true)];
|
|
88
|
-
case 5:
|
|
89
|
-
_d.sent();
|
|
90
|
-
_a = expect;
|
|
91
|
-
_b = session_utils_1.sessionEqual;
|
|
92
|
-
return [4 /*yield*/, storage.loadSession(sessionId)];
|
|
93
|
-
case 6:
|
|
94
|
-
_a.apply(void 0, [_b.apply(void 0, [_d.sent(), session])]).toBe(true);
|
|
95
|
-
return [4 /*yield*/, expect(storage.storeSession(session)).resolves.toBe(true)];
|
|
96
|
-
case 7:
|
|
97
|
-
_d.sent();
|
|
98
|
-
return [4 /*yield*/, storage.loadSession(sessionId)];
|
|
99
|
-
case 8:
|
|
100
|
-
loadedSession = _d.sent();
|
|
101
|
-
expect((0, session_utils_1.sessionEqual)(loadedSession, session)).toBe(true);
|
|
102
|
-
expect(loadedSession === null || loadedSession === void 0 ? void 0 : loadedSession.isActive()).toBe(true);
|
|
103
|
-
return [4 /*yield*/, expect(storage.deleteSession(sessionId)).resolves.toBe(true)];
|
|
104
|
-
case 9:
|
|
105
|
-
_d.sent();
|
|
106
|
-
return [4 /*yield*/, expect(storage.loadSession(sessionId)).resolves.toBeUndefined()];
|
|
107
|
-
case 10:
|
|
108
|
-
_d.sent();
|
|
109
|
-
// Deleting a non-existing session should work
|
|
110
|
-
return [4 /*yield*/, expect(storage.deleteSession(sessionId)).resolves.toBe(true)];
|
|
111
|
-
case 11:
|
|
112
|
-
// Deleting a non-existing session should work
|
|
113
|
-
_d.sent();
|
|
114
|
-
_d.label = 12;
|
|
115
|
-
case 12:
|
|
116
|
-
sessionFactories_1_1 = sessionFactories_1.next();
|
|
117
|
-
return [3 /*break*/, 3];
|
|
118
|
-
case 13: return [3 /*break*/, 16];
|
|
119
|
-
case 14:
|
|
120
|
-
e_1_1 = _d.sent();
|
|
121
|
-
e_1 = { error: e_1_1 };
|
|
122
|
-
return [3 /*break*/, 16];
|
|
123
|
-
case 15:
|
|
124
|
-
try {
|
|
125
|
-
if (sessionFactories_1_1 && !sessionFactories_1_1.done && (_c = sessionFactories_1.return)) _c.call(sessionFactories_1);
|
|
126
|
-
}
|
|
127
|
-
finally { if (e_1) throw e_1.error; }
|
|
128
|
-
return [7 /*endfinally*/];
|
|
129
|
-
case 16: return [2 /*return*/];
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}); });
|
|
133
|
-
it('can store sessions with unexpected fields', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
134
|
-
var storage, sessionId, session, _a, _b;
|
|
135
|
-
return tslib_1.__generator(this, function (_c) {
|
|
136
|
-
switch (_c.label) {
|
|
137
|
-
case 0: return [4 /*yield*/, storageFactory()];
|
|
138
|
-
case 1:
|
|
139
|
-
storage = _c.sent();
|
|
140
|
-
sessionId = 'test_session';
|
|
141
|
-
session = new session_1.Session(sessionId, 'shop', 'state', true);
|
|
142
|
-
session.someField = 'lol';
|
|
143
|
-
return [4 /*yield*/, expect(storage.storeSession(session)).resolves.toBe(true)];
|
|
144
|
-
case 2:
|
|
145
|
-
_c.sent();
|
|
146
|
-
_a = expect;
|
|
147
|
-
_b = session_utils_1.sessionEqual;
|
|
148
|
-
return [4 /*yield*/, storage.loadSession(sessionId)];
|
|
149
|
-
case 3:
|
|
150
|
-
_a.apply(void 0, [_b.apply(void 0, [_c.sent(), session])]).toBe(true);
|
|
151
|
-
return [2 /*return*/];
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}); });
|
|
155
|
-
it('can store and delete sessions with online tokens', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
156
|
-
var storage, sessionId, session, _a, _b;
|
|
157
|
-
return tslib_1.__generator(this, function (_c) {
|
|
158
|
-
switch (_c.label) {
|
|
159
|
-
case 0: return [4 /*yield*/, storageFactory()];
|
|
160
|
-
case 1:
|
|
161
|
-
storage = _c.sent();
|
|
162
|
-
sessionId = 'test_session';
|
|
163
|
-
session = new session_1.Session(sessionId, 'shop', 'state', true);
|
|
164
|
-
return [4 /*yield*/, expect(storage.storeSession(session)).resolves.toBe(true)];
|
|
165
|
-
case 2:
|
|
166
|
-
_c.sent();
|
|
167
|
-
_a = expect;
|
|
168
|
-
_b = session_utils_1.sessionEqual;
|
|
169
|
-
return [4 /*yield*/, storage.loadSession(sessionId)];
|
|
170
|
-
case 3:
|
|
171
|
-
_a.apply(void 0, [_b.apply(void 0, [_c.sent(), session])]).toBe(true);
|
|
172
|
-
return [2 /*return*/];
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
}); });
|
|
176
|
-
it('wrong ids return null sessions', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
177
|
-
var storage;
|
|
178
|
-
return tslib_1.__generator(this, function (_a) {
|
|
179
|
-
switch (_a.label) {
|
|
180
|
-
case 0: return [4 /*yield*/, storageFactory()];
|
|
181
|
-
case 1:
|
|
182
|
-
storage = _a.sent();
|
|
183
|
-
return [4 /*yield*/, expect(storage.loadSession('not_a_session_id')).resolves.toBeUndefined()];
|
|
184
|
-
case 2:
|
|
185
|
-
_a.sent();
|
|
186
|
-
return [2 /*return*/];
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}); });
|
|
190
|
-
}
|
|
191
|
-
exports.batteryOfTests = batteryOfTests;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { Socket, SocketConnectOpts } from 'net';
|
|
3
|
-
export declare function wait(ms: number): Promise<void>;
|
|
4
|
-
export declare function poll(func: () => Promise<boolean>, { interval, timeout }?: {
|
|
5
|
-
interval?: number | undefined;
|
|
6
|
-
timeout?: number | undefined;
|
|
7
|
-
}): Promise<void>;
|
|
8
|
-
export declare function waitForData(socket: Socket): Promise<string>;
|
|
9
|
-
export declare function connectSocket(socket: Socket, opts: SocketConnectOpts): Promise<void>;
|
|
10
|
-
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/auth/session/storage/__tests__/utils.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAE,iBAAiB,EAAC,MAAM,KAAK,CAAC;AAE9C,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9C;AAED,wBAAsB,IAAI,CACxB,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC5B,EAAC,QAAc,EAAE,OAAc,EAAC;;;CAAK,iBAiBtC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB3D;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,IAAI,CAAC,CAef"}
|