@unchainedshop/platform 5.0.0-alpha.10 → 5.0.0-alpha.11
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/README.md
CHANGED
|
@@ -114,6 +114,9 @@ The package also exports the [built-in template resolvers](src/templates/index.t
|
|
|
114
114
|
| `unchainedAPI` | Core modules, services, bulk importer/exporter, and options |
|
|
115
115
|
| `graphqlHandler` | GraphQL Yoga server instance |
|
|
116
116
|
| `db` | MongoDB database instance |
|
|
117
|
+
| `shutdown` | Stops the work queue, plugins, event emitter, GraphQL server, audit log and database without exiting the process; every call returns the same promise |
|
|
118
|
+
|
|
119
|
+
On `SIGTERM` / `SIGINT` the platform calls `shutdown()` and exits. Once `shutdown()` has started, these signals no longer exit the process, so exit it yourself after awaiting `shutdown()`.
|
|
117
120
|
|
|
118
121
|
## License
|
|
119
122
|
|
package/lib/startPlatform.d.ts
CHANGED
package/lib/startPlatform.js
CHANGED
|
@@ -83,13 +83,31 @@ export const startPlatform = async ({ modules, services, options, rolesOptions,
|
|
|
83
83
|
});
|
|
84
84
|
const version = UNCHAINED_API_VERSION || npm_package_version || 'n/a';
|
|
85
85
|
defaultLogger.info(`Unchained Engine running`, { version });
|
|
86
|
-
let
|
|
86
|
+
let shutdownPromise;
|
|
87
|
+
const shutdown = () => {
|
|
88
|
+
shutdownPromise ??= (async () => {
|
|
89
|
+
defaultLogger.debug('Stopping Workqueue');
|
|
90
|
+
stopWorkqueue();
|
|
91
|
+
defaultLogger.debug('Shutting down plugins');
|
|
92
|
+
await pluginRegistry.shutdown(unchainedAPI);
|
|
93
|
+
defaultLogger.debug('Shutting down event emitter');
|
|
94
|
+
await getEmitAdapter()?.shutdown?.();
|
|
95
|
+
defaultLogger.debug('Stopping GraphQL server');
|
|
96
|
+
await graphqlHandler.dispose();
|
|
97
|
+
if (auditLog) {
|
|
98
|
+
defaultLogger.debug('Closing audit log');
|
|
99
|
+
await auditLog.close();
|
|
100
|
+
}
|
|
101
|
+
defaultLogger.debug('Stopping DB Connection');
|
|
102
|
+
await stopDb();
|
|
103
|
+
})();
|
|
104
|
+
return shutdownPromise;
|
|
105
|
+
};
|
|
87
106
|
const cleanup = (signal) => async () => {
|
|
88
|
-
if (
|
|
107
|
+
if (shutdownPromise) {
|
|
89
108
|
defaultLogger.debug('Cleanup already in progress, ignoring signal', { signal });
|
|
90
109
|
return;
|
|
91
110
|
}
|
|
92
|
-
isCleaningUp = true;
|
|
93
111
|
defaultLogger.debug('Starting cleanup', { signal });
|
|
94
112
|
const forceExitTimeout = setTimeout(() => {
|
|
95
113
|
defaultLogger.error('Cleanup timeout exceeded, forcing exit');
|
|
@@ -97,20 +115,7 @@ export const startPlatform = async ({ modules, services, options, rolesOptions,
|
|
|
97
115
|
}, CLEANUP_FORCE_EXIT_TIMEOUT_MS);
|
|
98
116
|
forceExitTimeout.unref();
|
|
99
117
|
try {
|
|
100
|
-
|
|
101
|
-
stopWorkqueue();
|
|
102
|
-
defaultLogger.debug('Shutting down plugins', { signal });
|
|
103
|
-
await pluginRegistry.shutdown(unchainedAPI);
|
|
104
|
-
defaultLogger.debug('Shutting down event emitter', { signal });
|
|
105
|
-
await getEmitAdapter()?.shutdown?.();
|
|
106
|
-
defaultLogger.debug('Stopping GraphQL server', { signal });
|
|
107
|
-
await graphqlHandler.dispose();
|
|
108
|
-
if (auditLog) {
|
|
109
|
-
defaultLogger.debug('Closing audit log', { signal });
|
|
110
|
-
await auditLog.close();
|
|
111
|
-
}
|
|
112
|
-
defaultLogger.debug('Stopping DB Connection', { signal });
|
|
113
|
-
await stopDb();
|
|
118
|
+
await shutdown();
|
|
114
119
|
defaultLogger.debug(`Unchained Engine exiting gracefully`, { signal, version });
|
|
115
120
|
clearTimeout(forceExitTimeout);
|
|
116
121
|
process.exit(0);
|
|
@@ -138,5 +143,5 @@ export const startPlatform = async ({ modules, services, options, rolesOptions,
|
|
|
138
143
|
});
|
|
139
144
|
const end = performance.now();
|
|
140
145
|
defaultLogger.debug(`Unchained Engine started in ${(end - start).toFixed(0)} ms`);
|
|
141
|
-
return { unchainedAPI, graphqlHandler, db };
|
|
146
|
+
return { unchainedAPI, graphqlHandler, db, shutdown };
|
|
142
147
|
};
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
const { EMAIL_FROM, EMAIL_WEBSITE_NAME, EMAIL_WEBSITE_URL } = process.env;
|
|
2
|
-
export const resolveEnrollmentStatusTemplate = async ({ enrollmentId }, context) => {
|
|
2
|
+
export const resolveEnrollmentStatusTemplate = async ({ enrollmentId, locale }, context) => {
|
|
3
3
|
const { modules } = context;
|
|
4
4
|
const enrollment = await modules.enrollments.findEnrollment({ enrollmentId });
|
|
5
5
|
const user = await modules.users.findUserById(enrollment.userId);
|
|
6
|
-
const subject = `${EMAIL_WEBSITE_NAME}: Updated Enrollment / ${enrollment.enrollmentNumber}`;
|
|
6
|
+
const subject = `${EMAIL_WEBSITE_NAME}: Updated Enrollment / ${enrollment.enrollmentNumber || enrollment._id}`;
|
|
7
7
|
const url = `${EMAIL_WEBSITE_URL}/enrollment?_id=${enrollment._id}`;
|
|
8
|
+
const formatDate = (date) => new Date(date).toLocaleDateString(locale || 'en', { dateStyle: 'long' });
|
|
9
|
+
const scheduledDates = [
|
|
10
|
+
enrollment.expires && `Ends: ${formatDate(enrollment.expires)}`,
|
|
11
|
+
enrollment.resumeAt && `Resumes: ${formatDate(enrollment.resumeAt)}`,
|
|
12
|
+
enrollment.minimumCommitmentEnd &&
|
|
13
|
+
`Minimum commitment until: ${formatDate(enrollment.minimumCommitmentEnd)}`,
|
|
14
|
+
].filter(Boolean);
|
|
8
15
|
const text = `
|
|
9
16
|
${subject}\n
|
|
10
17
|
\n
|
|
11
18
|
Status: ${enrollment.status}
|
|
19
|
+
${scheduledDates.join('\n ')}
|
|
12
20
|
\n
|
|
13
21
|
-----------------\n
|
|
14
22
|
Show: ${url}\n
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/platform",
|
|
3
3
|
"description": "Complete e-commerce platform bundle for the Unchained Engine",
|
|
4
|
-
"version": "5.0.0-alpha.
|
|
4
|
+
"version": "5.0.0-alpha.11",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib",
|
|
7
7
|
"bin"
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"npm": ">=10.0.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@unchainedshop/api": "^5.0.0-alpha.
|
|
49
|
-
"@unchainedshop/core": "^5.0.0-alpha.
|
|
50
|
-
"@unchainedshop/events": "^5.0.0-alpha.
|
|
51
|
-
"@unchainedshop/logger": "^5.0.0-alpha.
|
|
52
|
-
"@unchainedshop/mongodb": "^5.0.0-alpha.
|
|
53
|
-
"@unchainedshop/plugins": "^5.0.0-alpha.
|
|
54
|
-
"@unchainedshop/roles": "^5.0.0-alpha.
|
|
55
|
-
"@unchainedshop/utils": "^5.0.0-alpha.
|
|
48
|
+
"@unchainedshop/api": "^5.0.0-alpha.11",
|
|
49
|
+
"@unchainedshop/core": "^5.0.0-alpha.11",
|
|
50
|
+
"@unchainedshop/events": "^5.0.0-alpha.11",
|
|
51
|
+
"@unchainedshop/logger": "^5.0.0-alpha.11",
|
|
52
|
+
"@unchainedshop/mongodb": "^5.0.0-alpha.11",
|
|
53
|
+
"@unchainedshop/plugins": "^5.0.0-alpha.11",
|
|
54
|
+
"@unchainedshop/roles": "^5.0.0-alpha.11",
|
|
55
|
+
"@unchainedshop/utils": "^5.0.0-alpha.11"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/node": "^26.2.0",
|