@agnostack/next-shopify 1.1.0-alpha.7 → 1.1.0-alpha.8
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 +7 -0
- package/dist/apiHandlers.d.ts +1 -1
- package/dist/apiHandlers.js +6 -10
- package/dist/apiHandlers.js.map +1 -1
- package/dist/utils/helpers.d.ts +8 -0
- package/dist/utils/helpers.js +30 -1
- package/dist/utils/helpers.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.1.0-alpha.8](https://github.com/agnostack/next-shopify/compare/v1.1.0-alpha.7...v1.1.0-alpha.8) (2022-11-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* updated uninstall route ([6f8462a](https://github.com/agnostack/next-shopify/commit/6f8462a7012d18c5205f1f9f22a7940b6b335329))
|
|
7
|
+
|
|
1
8
|
# [1.1.0-alpha.7](https://github.com/agnostack/next-shopify/compare/v1.1.0-alpha.6...v1.1.0-alpha.7) (2022-11-08)
|
|
2
9
|
|
|
3
10
|
|
package/dist/apiHandlers.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export function handleAuth(props: any): (req: any, res: any) => Promise<any>;
|
|
2
2
|
export function handleCallback(props: any): (req: any, res: any) => Promise<any>;
|
|
3
|
-
export function handleAppUninstalled(props: any): (
|
|
3
|
+
export function handleAppUninstalled(props: any): (req: any, res: any) => Promise<any>;
|
package/dist/apiHandlers.js
CHANGED
|
@@ -24,17 +24,13 @@ const handleCallback = (props) => async (req, res) => {
|
|
|
24
24
|
};
|
|
25
25
|
exports.handleCallback = handleCallback;
|
|
26
26
|
// NOTE: typically handling: "/api/webhooks/app/uninstalled"
|
|
27
|
-
const handleAppUninstalled = (props) => async (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const existingSessions = await ((_b = (_a = shopify.Context.SESSION_STORAGE) === null || _a === void 0 ? void 0 : _a.findSessionsByShop) === null || _b === void 0 ? void 0 : _b.call(_a, shop));
|
|
33
|
-
console.warn(`>>> > handleAppUninstalled > existingSessions`, existingSessions);
|
|
34
|
-
if (utils_1.arrayNotEmpty(existingSessions)) {
|
|
35
|
-
await ((_d = (_c = shopify.Context.SESSION_STORAGE) === null || _c === void 0 ? void 0 : _c.deleteSessions) === null || _d === void 0 ? void 0 : _d.call(_c, existingSessions.map((session) => session.id)));
|
|
27
|
+
const handleAppUninstalled = (props) => async (req, res) => {
|
|
28
|
+
const { PAGE_PATHS } = props;
|
|
29
|
+
const { message, statusCode = 302, redirectUrl = `${PAGE_PATHS[utils_1.PAGE_ROUTE_NAMES.ERROR]}?invalid_uninstall_response`, } = await utils_1.uninstallHelper(Object.assign({ req, res }, props));
|
|
30
|
+
if (statusCode >= 300 && statusCode < 400) {
|
|
31
|
+
return res.redirect(statusCode, redirectUrl);
|
|
36
32
|
}
|
|
37
|
-
return
|
|
33
|
+
return res.send(statusCode).send(message);
|
|
38
34
|
};
|
|
39
35
|
exports.handleAppUninstalled = handleAppUninstalled;
|
|
40
36
|
//# sourceMappingURL=apiHandlers.js.map
|
package/dist/apiHandlers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiHandlers.js","sourceRoot":"","sources":["../src/apiHandlers.js"],"names":[],"mappings":";;;AAAA,gDAAgD;AAChD,
|
|
1
|
+
{"version":3,"file":"apiHandlers.js","sourceRoot":"","sources":["../src/apiHandlers.js"],"names":[],"mappings":";;;AAAA,gDAAgD;AAChD,mCAKgB;AAEhB,wCAAwC;AACjC,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACtD,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAC5B,MAAM,EACJ,OAAO,EACP,UAAU,GAAG,GAAG,EAChB,WAAW,GAAG,GAAG,UAAU,CAAC,wBAAgB,CAAC,KAAK,CAAC,wBAAwB,GAC5E,GAAG,MAAM,kBAAU,iBAAG,GAAG,EAAE,GAAG,IAAK,KAAK,EAAG,CAAA;IAE5C,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG,EAAE;QACzC,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC7C;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC3C,CAAC,CAAA;AAbY,QAAA,UAAU,cAatB;AAED,iDAAiD;AAC1C,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC1D,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAC5B,MAAM,EACJ,OAAO,EACP,UAAU,GAAG,GAAG,EAChB,WAAW,GAAG,GAAG,UAAU,CAAC,wBAAgB,CAAC,KAAK,CAAC,4BAA4B,GAChF,GAAG,MAAM,sBAAc,iBAAG,GAAG,EAAE,GAAG,IAAK,KAAK,EAAG,CAAA;IAEhD,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG,EAAE;QACzC,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC7C;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC3C,CAAC,CAAA;AAbY,QAAA,cAAc,kBAa1B;AAED,4DAA4D;AACrD,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAChE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAC5B,MAAM,EACJ,OAAO,EACP,UAAU,GAAG,GAAG,EAChB,WAAW,GAAG,GAAG,UAAU,CAAC,wBAAgB,CAAC,KAAK,CAAC,6BAA6B,GACjF,GAAG,MAAM,uBAAe,iBAAG,GAAG,EAAE,GAAG,IAAK,KAAK,EAAG,CAAA;IAEjD,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG,EAAE;QACzC,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC7C;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC3C,CAAC,CAAA;AAbY,QAAA,oBAAoB,wBAahC"}
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -24,3 +24,11 @@ export function callbackHelper({ req, res, ...props }: {
|
|
|
24
24
|
message: string;
|
|
25
25
|
redirectUrl?: undefined;
|
|
26
26
|
}>;
|
|
27
|
+
export function uninstallHelper({ req, res, ...props }: {
|
|
28
|
+
[x: string]: any;
|
|
29
|
+
req: any;
|
|
30
|
+
res: any;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
statusCode: number;
|
|
33
|
+
message: string;
|
|
34
|
+
}>;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -11,7 +11,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.callbackHelper = exports.authHelper = void 0;
|
|
14
|
+
exports.uninstallHelper = exports.callbackHelper = exports.authHelper = void 0;
|
|
15
|
+
const display_1 = require("./display");
|
|
15
16
|
const shopify_1 = require("./shopify");
|
|
16
17
|
const authHelper = async (_a) => {
|
|
17
18
|
var { req, res } = _a, props = __rest(_a, ["req", "res"]);
|
|
@@ -91,4 +92,32 @@ const callbackHelper = async (_a) => {
|
|
|
91
92
|
}
|
|
92
93
|
};
|
|
93
94
|
exports.callbackHelper = callbackHelper;
|
|
95
|
+
const uninstallHelper = async (_a) => {
|
|
96
|
+
var _b, _c, _d, _e;
|
|
97
|
+
var { req, res } = _a, props = __rest(_a, ["req", "res"]);
|
|
98
|
+
try {
|
|
99
|
+
const { domain } = req.body;
|
|
100
|
+
console.warn(`>>> > handleAppUninstalled > props`, props);
|
|
101
|
+
console.warn(`>>> > handleAppUninstalled > domain`, domain);
|
|
102
|
+
const shopify = shopify_1.getInitializedShopify(props, domain);
|
|
103
|
+
const existingSessions = await ((_c = (_b = shopify.Context.SESSION_STORAGE) === null || _b === void 0 ? void 0 : _b.findSessionsByShop) === null || _c === void 0 ? void 0 : _c.call(_b, domain));
|
|
104
|
+
console.warn(`>>> > handleAppUninstalled > existingSessions`, existingSessions);
|
|
105
|
+
if (display_1.arrayNotEmpty(existingSessions)) {
|
|
106
|
+
await ((_e = (_d = shopify.Context.SESSION_STORAGE) === null || _d === void 0 ? void 0 : _d.deleteSessions) === null || _e === void 0 ? void 0 : _e.call(_d, existingSessions.map((session) => session.id)));
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
statusCode: 200,
|
|
110
|
+
message: 'true',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const errorMessage = 'Error handling uninstall route';
|
|
115
|
+
console.error(errorMessage, error);
|
|
116
|
+
return {
|
|
117
|
+
statusCode: 500,
|
|
118
|
+
message: errorMessage,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
exports.uninstallHelper = uninstallHelper;
|
|
94
123
|
//# sourceMappingURL=helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.js"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.js"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agnostack/next-shopify",
|
|
3
|
-
"version": "1.1.0-alpha.
|
|
3
|
+
"version": "1.1.0-alpha.8",
|
|
4
4
|
"author": "agnoStack Dev <developers@agnostack.com> (https://agnostack.com)",
|
|
5
5
|
"owner": "agnoStack",
|
|
6
6
|
"description": "Please contact agnoStack via info@agnostack.com for any questions",
|