@unchainedshop/platform 2.12.2 → 3.0.0-alpha2
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/lib/bulk-importer/createBulkImporter.d.ts +1 -0
- package/lib/bulk-importer/createBulkImporter.d.ts.map +1 -1
- package/lib/bulk-importer/createBulkImporter.js +2 -2
- package/lib/bulk-importer/createBulkImporter.js.map +1 -1
- package/lib/bulk-importer/handlers/assortment/create.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/assortment/create.js +9 -7
- package/lib/bulk-importer/handlers/assortment/create.js.map +1 -1
- package/lib/bulk-importer/handlers/assortment/update.d.ts +3 -1
- package/lib/bulk-importer/handlers/assortment/update.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/assortment/update.js +5 -1
- package/lib/bulk-importer/handlers/assortment/update.js.map +1 -1
- package/lib/bulk-importer/handlers/filter/create.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/filter/create.js +10 -6
- package/lib/bulk-importer/handlers/filter/create.js.map +1 -1
- package/lib/bulk-importer/handlers/filter/update.d.ts +2 -1
- package/lib/bulk-importer/handlers/filter/update.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/filter/update.js +15 -7
- package/lib/bulk-importer/handlers/filter/update.js.map +1 -1
- package/lib/bulk-importer/handlers/product/create.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/product/create.js +9 -7
- package/lib/bulk-importer/handlers/product/create.js.map +1 -1
- package/lib/bulk-importer/handlers/product/update.d.ts +2 -1
- package/lib/bulk-importer/handlers/product/update.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/product/update.js +5 -1
- package/lib/bulk-importer/handlers/product/update.js.map +1 -1
- package/lib/bulk-importer/handlers/product/upsertVariations.d.ts.map +1 -1
- package/lib/bulk-importer/handlers/product/upsertVariations.js +17 -11
- package/lib/bulk-importer/handlers/product/upsertVariations.js.map +1 -1
- package/lib/context/index.d.ts +0 -1
- package/lib/context/index.d.ts.map +1 -1
- package/lib/context/index.js +0 -1
- package/lib/context/index.js.map +1 -1
- package/lib/context/setAccessToken.d.ts +1 -1
- package/lib/context/setAccessToken.d.ts.map +1 -1
- package/lib/context/setAccessToken.js +3 -1
- package/lib/context/setAccessToken.js.map +1 -1
- package/lib/platform-index.d.ts +4 -4
- package/lib/platform-index.d.ts.map +1 -1
- package/lib/setup/setupAccounts.d.ts +1 -1
- package/lib/setup/setupAccounts.d.ts.map +1 -1
- package/lib/setup/setupAccounts.js +8 -160
- package/lib/setup/setupAccounts.js.map +1 -1
- package/lib/startPlatform.d.ts +6 -9
- package/lib/startPlatform.d.ts.map +1 -1
- package/lib/startPlatform.js +4 -10
- package/lib/startPlatform.js.map +1 -1
- package/package.json +14 -14
- package/src/bulk-importer/createBulkImporter.ts +8 -2
- package/src/bulk-importer/handlers/assortment/create.ts +12 -10
- package/src/bulk-importer/handlers/assortment/update.ts +10 -1
- package/src/bulk-importer/handlers/filter/create.ts +13 -11
- package/src/bulk-importer/handlers/filter/update.ts +18 -12
- package/src/bulk-importer/handlers/product/create.ts +12 -10
- package/src/bulk-importer/handlers/product/update.ts +9 -1
- package/src/bulk-importer/handlers/product/upsertVariations.ts +24 -20
- package/src/context/index.ts +0 -1
- package/src/context/setAccessToken.ts +8 -1
- package/src/setup/setupAccounts.ts +8 -237
- package/src/startPlatform.ts +10 -25
- package/lib/context/withAccessToken.d.ts +0 -4
- package/lib/context/withAccessToken.d.ts.map +0 -1
- package/lib/context/withAccessToken.js +0 -37
- package/lib/context/withAccessToken.js.map +0 -1
- package/src/context/withAccessToken.ts +0 -40
|
@@ -1,167 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { accountsSettings } from '@unchainedshop/core-accountsjs';
|
|
3
|
-
import moniker from 'moniker';
|
|
1
|
+
import { subscribe } from '@unchainedshop/events';
|
|
4
2
|
export const setupAccounts = (unchainedAPI) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
accountsServer.options.prepareMail = (to, token, user, pathFragment) => {
|
|
8
|
-
return {
|
|
9
|
-
template: 'ACCOUNT_ACTION',
|
|
10
|
-
recipientEmail: to,
|
|
11
|
-
action: pathFragment,
|
|
12
|
-
userId: user.id || user._id,
|
|
13
|
-
token,
|
|
14
|
-
skipMessaging: !!user.guest && pathFragment === 'verify-email',
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
accountsServer.options.sendMail = (input) => {
|
|
18
|
-
if (!input)
|
|
19
|
-
return true;
|
|
20
|
-
if (input.skipMessaging)
|
|
21
|
-
return true;
|
|
22
|
-
return unchainedAPI.modules.worker.addWork({
|
|
3
|
+
subscribe('USER_ACCOUNT_ACTION', async ({ payload }) => {
|
|
4
|
+
await unchainedAPI.modules.worker.addWork({
|
|
23
5
|
type: 'MESSAGE',
|
|
24
6
|
retries: 0,
|
|
25
|
-
input
|
|
7
|
+
input: {
|
|
8
|
+
template: 'ACCOUNT_ACTION',
|
|
9
|
+
recipientEmail: payload.address,
|
|
10
|
+
...payload,
|
|
11
|
+
},
|
|
26
12
|
});
|
|
27
|
-
};
|
|
28
|
-
accountsServer.services.guest = {
|
|
29
|
-
async authenticate(params) {
|
|
30
|
-
const guestname = `${moniker.choose()}-${randomValueHex(5)}`;
|
|
31
|
-
const guestUserId = await unchainedAPI.modules.accounts.createUser({
|
|
32
|
-
email: params.email || `${guestname}@unchained.local`,
|
|
33
|
-
guest: true,
|
|
34
|
-
password: null,
|
|
35
|
-
initialPassword: true,
|
|
36
|
-
}, {});
|
|
37
|
-
return unchainedAPI.modules.users.findUserById(guestUserId);
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
accountsServer.services.webAuthn = {
|
|
41
|
-
async authenticate(params) {
|
|
42
|
-
const username = Buffer.from(params.webAuthnPublicKeyCredentials?.response?.userHandle, 'base64').toString() ||
|
|
43
|
-
'';
|
|
44
|
-
const user = await unchainedAPI.modules.users.findUser({ username });
|
|
45
|
-
if (!user)
|
|
46
|
-
throw new Error('User not found');
|
|
47
|
-
await unchainedAPI.modules.accounts.webAuthn.verifyCredentialRequest(user.services?.webAuthn, user.username, params.webAuthnPublicKeyCredentials);
|
|
48
|
-
return user;
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
accountsServer.services.oauth2 = {
|
|
52
|
-
async authenticate({ authorizationCode, provider, redirectUrl, }) {
|
|
53
|
-
if (!authorizationCode || !provider) {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
const { modules, services } = unchainedAPI;
|
|
57
|
-
const authorizationToken = await modules.accounts.oAuth2.getAuthorizationToken(provider, authorizationCode, redirectUrl);
|
|
58
|
-
if (!authorizationToken)
|
|
59
|
-
throw new Error('Unable to authorize user');
|
|
60
|
-
const data = await modules.accounts.oAuth2.getAccountData(provider, authorizationToken);
|
|
61
|
-
if (!data?.id) {
|
|
62
|
-
throw new Error('OAuth authentication failed or no id returned from service');
|
|
63
|
-
}
|
|
64
|
-
const user = await unchainedAPI.modules.users.findUser({
|
|
65
|
-
[`services.oauth.${provider}.id`]: data.id,
|
|
66
|
-
});
|
|
67
|
-
if (!user) {
|
|
68
|
-
const newUserId = await unchainedAPI.modules.accounts.createUser({
|
|
69
|
-
username: data.username || `${data.id}`,
|
|
70
|
-
email: data.email,
|
|
71
|
-
guest: false,
|
|
72
|
-
initialPassword: undefined,
|
|
73
|
-
password: undefined,
|
|
74
|
-
profile: {
|
|
75
|
-
address: {
|
|
76
|
-
firstName: data?.firstName,
|
|
77
|
-
lastName: data?.lastName,
|
|
78
|
-
addressLine: data?.address,
|
|
79
|
-
city: data?.city,
|
|
80
|
-
countryCode: data?.countryCode,
|
|
81
|
-
regionCode: data?.regionCode,
|
|
82
|
-
postalCode: data?.postalCode,
|
|
83
|
-
company: data?.company,
|
|
84
|
-
},
|
|
85
|
-
gender: data?.gender,
|
|
86
|
-
phoneMobile: data?.phoneNumber,
|
|
87
|
-
displayName: data?.displayName,
|
|
88
|
-
birthday: data?.birthDate,
|
|
89
|
-
},
|
|
90
|
-
}, { skipPasswordEnrollment: true });
|
|
91
|
-
await modules.users.updateUser({ _id: newUserId }, {
|
|
92
|
-
$push: {
|
|
93
|
-
[`services.oauth.${provider}`]: {
|
|
94
|
-
id: data.id,
|
|
95
|
-
authorizationToken,
|
|
96
|
-
authorizationCode,
|
|
97
|
-
data,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
}, { upsert: true });
|
|
101
|
-
if (data?.avatarUrl) {
|
|
102
|
-
const file = await services.files.uploadFileFromURL({
|
|
103
|
-
directoryName: 'user-avatars',
|
|
104
|
-
fileInput: {
|
|
105
|
-
fileLink: data.avatarUrl,
|
|
106
|
-
fileName: `${data.firstName}-avatar`,
|
|
107
|
-
},
|
|
108
|
-
meta: { userId: newUserId },
|
|
109
|
-
}, unchainedAPI);
|
|
110
|
-
if (user?.avatarId) {
|
|
111
|
-
await services.files.removeFiles({
|
|
112
|
-
fileIds: [user.avatarId],
|
|
113
|
-
}, unchainedAPI);
|
|
114
|
-
}
|
|
115
|
-
return modules.users.updateAvatar(newUserId, file._id);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return user;
|
|
119
|
-
},
|
|
120
|
-
};
|
|
121
|
-
accountsServer.on('LoginTokenCreated', async (props) => {
|
|
122
|
-
const { userId, connection = {} } = props;
|
|
123
|
-
// TODO: Doubt that there is countryContext etc. here?
|
|
124
|
-
const { userIdBeforeLogin, countryContext, remoteAddress, remotePort, userAgent, normalizedLocale } = connection;
|
|
125
|
-
await unchainedAPI.modules.users.updateHeartbeat(userId, {
|
|
126
|
-
remoteAddress,
|
|
127
|
-
remotePort,
|
|
128
|
-
userAgent,
|
|
129
|
-
locale: normalizedLocale,
|
|
130
|
-
countryCode: countryContext,
|
|
131
|
-
});
|
|
132
|
-
const user = await unchainedAPI.modules.users.findUserById(userId);
|
|
133
|
-
if (userIdBeforeLogin) {
|
|
134
|
-
const userBeforeLogin = await unchainedAPI.modules.users.findUserById(userIdBeforeLogin);
|
|
135
|
-
await unchainedAPI.services.orders.migrateOrderCarts({
|
|
136
|
-
fromUserId: userBeforeLogin._id,
|
|
137
|
-
toUserId: user._id,
|
|
138
|
-
shouldMerge: accountsSettings.mergeUserCartsOnLogin,
|
|
139
|
-
countryContext: countryContext || userBeforeLogin.lastLogin?.countryCode || user.lastLogin?.countryCode,
|
|
140
|
-
}, unchainedAPI);
|
|
141
|
-
await unchainedAPI.services.bookmarks.migrateBookmarks({
|
|
142
|
-
fromUserId: userBeforeLogin._id,
|
|
143
|
-
toUserId: user._id,
|
|
144
|
-
shouldMerge: accountsSettings.mergeUserCartsOnLogin,
|
|
145
|
-
countryContext: countryContext || userBeforeLogin.lastLogin?.countryCode || user.lastLogin?.countryCode,
|
|
146
|
-
}, unchainedAPI);
|
|
147
|
-
}
|
|
148
|
-
return unchainedAPI.services.orders.nextUserCart({
|
|
149
|
-
user,
|
|
150
|
-
countryCode: countryContext,
|
|
151
|
-
}, unchainedAPI);
|
|
152
|
-
});
|
|
153
|
-
accountsServer.on('ResetPasswordSuccess', async (user) => {
|
|
154
|
-
await unchainedAPI.modules.users.updateInitialPassword(user, false);
|
|
155
|
-
});
|
|
156
|
-
accountsServer.on('ChangePasswordSuccess', async (user) => {
|
|
157
|
-
await unchainedAPI.modules.users.updateInitialPassword(user, false);
|
|
158
|
-
});
|
|
159
|
-
accountsServer.on('ValidateLogin', async (params) => {
|
|
160
|
-
if (params.service !== 'guest' && params.user.guest) {
|
|
161
|
-
await unchainedAPI.modules.users.updateGuest(params.user, false);
|
|
162
|
-
}
|
|
163
|
-
return true;
|
|
164
13
|
});
|
|
165
|
-
return accountsServer;
|
|
166
14
|
};
|
|
167
15
|
//# sourceMappingURL=setupAccounts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupAccounts.js","sourceRoot":"","sources":["../../src/setup/setupAccounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"setupAccounts.js","sourceRoot":"","sources":["../../src/setup/setupAccounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,YAA2B,EAAE,EAAE;IAC3D,SAAS,CAAC,qBAAqB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAoB,EAAE,EAAE;QACvE,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;YACxC,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,KAAK,EAAE;gBACL,QAAQ,EAAE,gBAAgB;gBAC1B,cAAc,EAAE,OAAO,CAAC,OAAO;gBAC/B,GAAG,OAAO;aACX;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
package/lib/startPlatform.d.ts
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
|
+
import { GraphQLServerOptions } from '@unchainedshop/api';
|
|
1
2
|
import { UnchainedCore, UnchainedCoreOptions } from '@unchainedshop/types/core.js';
|
|
2
3
|
import { AdminUiConfig } from '@unchainedshop/types/api.js';
|
|
4
|
+
import { Db } from 'mongodb';
|
|
3
5
|
import { BulkImportHandler } from './bulk-importer/createBulkImporter.js';
|
|
4
6
|
import { SetupCartsOptions } from './setup/setupCarts.js';
|
|
5
7
|
import { MessageTypes } from './setup/setupTemplates.js';
|
|
6
8
|
import { SetupWorkqueueOptions } from './setup/setupWorkqueue.js';
|
|
7
9
|
export { MessageTypes };
|
|
8
10
|
export type PlatformOptions = {
|
|
9
|
-
typeDefs?: Array<string>;
|
|
10
|
-
resolvers?: any;
|
|
11
|
-
schema?: any;
|
|
12
|
-
plugins?: any[];
|
|
13
|
-
cache?: any;
|
|
14
11
|
bulkImporter?: {
|
|
15
12
|
handlers?: Record<string, BulkImportHandler>;
|
|
16
13
|
};
|
|
17
14
|
context?: any;
|
|
18
15
|
workQueueOptions?: SetupWorkqueueOptions & SetupCartsOptions;
|
|
19
|
-
introspection?: boolean;
|
|
20
16
|
adminUiConfig?: AdminUiConfig;
|
|
21
|
-
} & Partial<Pick<UnchainedCoreOptions, 'modules' | 'services' | 'options' | 'rolesOptions'
|
|
17
|
+
} & Partial<Pick<UnchainedCoreOptions, 'modules' | 'services' | 'options' | 'rolesOptions'>> & GraphQLServerOptions;
|
|
22
18
|
export declare const queueWorkers: Array<any>;
|
|
23
|
-
export declare const startPlatform: ({ modules, services,
|
|
19
|
+
export declare const startPlatform: ({ modules, services, options, adminUiConfig, rolesOptions, bulkImporter: bulkImporterOptions, workQueueOptions, ...arbitraryGraphQLServerOptions }: PlatformOptions) => Promise<{
|
|
24
20
|
unchainedAPI: UnchainedCore;
|
|
25
|
-
|
|
21
|
+
yogaServer: any;
|
|
22
|
+
db: Db;
|
|
26
23
|
}>;
|
|
27
24
|
//# sourceMappingURL=startPlatform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startPlatform.d.ts","sourceRoot":"","sources":["../src/startPlatform.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"startPlatform.d.ts","sourceRoot":"","sources":["../src/startPlatform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,oBAAoB,EAAS,MAAM,oBAAoB,CAAC;AAIjF,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGnF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAA6B,MAAM,uCAAuC,CAAC;AAGrG,OAAO,EAAE,iBAAiB,EAAc,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAkB,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAkB,MAAM,2BAA2B,CAAC;AAGlF,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;KAC9C,CAAC;IACF,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,gBAAgB,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;IAC7D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,GAAG,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC,GAC1F,oBAAoB,CAAC;AAqBvB,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,GAAG,CAAM,CAAC;AAE3C,eAAO,MAAM,aAAa,uJASvB,eAAe,KAAG,OAAO,CAAC;IAC3B,YAAY,EAAE,aAAa,CAAC;IAC5B,UAAU,EAAE,GAAG,CAAC;IAChB,EAAE,EAAE,EAAE,CAAC;CACR,CA2DA,CAAC"}
|
package/lib/startPlatform.js
CHANGED
|
@@ -28,7 +28,7 @@ const checkWorkQueueEnabled = (options) => {
|
|
|
28
28
|
return !UNCHAINED_DISABLE_WORKER;
|
|
29
29
|
};
|
|
30
30
|
export const queueWorkers = [];
|
|
31
|
-
export const startPlatform = async ({ modules = {}, services = {},
|
|
31
|
+
export const startPlatform = async ({ modules = {}, services = {}, options = {}, adminUiConfig = {}, rolesOptions = {}, bulkImporter: bulkImporterOptions, workQueueOptions, ...arbitraryGraphQLServerOptions }) => {
|
|
32
32
|
exitOnMissingEnvironmentVariables();
|
|
33
33
|
// Configure database
|
|
34
34
|
const db = await initDb();
|
|
@@ -57,19 +57,13 @@ export const startPlatform = async ({ modules = {}, services = {}, typeDefs = []
|
|
|
57
57
|
// Setup email templates
|
|
58
58
|
setupTemplates(unchainedAPI);
|
|
59
59
|
// Start the graphQL server
|
|
60
|
-
const
|
|
60
|
+
const yogaServer = await startAPIServer({
|
|
61
61
|
unchainedAPI,
|
|
62
62
|
roles: configuredRoles,
|
|
63
63
|
events: configuredEvents,
|
|
64
64
|
workTypes: configuredWorkTypes,
|
|
65
|
-
typeDefs,
|
|
66
|
-
resolvers,
|
|
67
|
-
schema,
|
|
68
|
-
plugins,
|
|
69
|
-
cache,
|
|
70
|
-
context,
|
|
71
|
-
introspection,
|
|
72
65
|
adminUiConfig,
|
|
66
|
+
...arbitraryGraphQLServerOptions,
|
|
73
67
|
});
|
|
74
68
|
// Setup work queues for scheduled work
|
|
75
69
|
if (isWorkQueueEnabled) {
|
|
@@ -81,6 +75,6 @@ export const startPlatform = async ({ modules = {}, services = {}, typeDefs = []
|
|
|
81
75
|
if (!options.filters?.skipInvalidationOnStartup) {
|
|
82
76
|
setImmediate(() => unchainedAPI.modules.filters.invalidateCache({}, unchainedAPI));
|
|
83
77
|
}
|
|
84
|
-
return { unchainedAPI,
|
|
78
|
+
return { unchainedAPI, yogaServer, db };
|
|
85
79
|
};
|
|
86
80
|
//# sourceMappingURL=startPlatform.js.map
|
package/lib/startPlatform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startPlatform.js","sourceRoot":"","sources":["../src/startPlatform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"startPlatform.js","sourceRoot":"","sources":["../src/startPlatform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAwB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAqB,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAqB,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAyB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,OAAO,EAAE,YAAY,EAAE,CAAC;AAYxB,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAEzC,MAAM,sBAAsB,GAAG,CAAC,oBAAoB,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAAC;AAEzF,MAAM,EAAE,wBAAwB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAEjD,MAAM,iCAAiC,GAAG,GAAG,EAAE;IAC7C,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,KAAK,CAAC,wDAAwD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,OAA8B,EAAE,EAAE;IAC/D,IAAI,OAAO,EAAE,aAAa;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,CAAC,wBAAwB,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAe,EAAE,CAAC;AAE3C,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,OAAO,GAAG,EAAE,EACZ,QAAQ,GAAG,EAAE,EACb,OAAO,GAAG,EAAE,EACZ,aAAa,GAAG,EAAE,EAClB,YAAY,GAAG,EAAE,EACjB,YAAY,EAAE,mBAAmB,EACjC,gBAAgB,EAChB,GAAG,6BAA6B,EAChB,EAIf,EAAE;IACH,iCAAiC,EAAE,CAAC;IAEpC,qBAAqB;IACrB,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;IAE1B,qBAAqB;IACrB,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,yBAAyB,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC;IAExE,yCAAyC;IACzC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC;QAClC,EAAE;QACF,mBAAmB;QACnB,YAAY;QACZ,OAAO;QACP,QAAQ;QACR,OAAO;QACP,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IACnE,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,aAAa,CAAC,EAAE,mBAAmB,EAAE,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAC/C,MAAM,mBAAmB,GAAG,cAAc,CAAC,oBAAoB,EAAE,CAAC;IAElE,0DAA0D;IAC1D,aAAa,CAAC,YAAY,CAAC,CAAC;IAE5B,wBAAwB;IACxB,cAAc,CAAC,YAAY,CAAC,CAAC;IAE7B,2BAA2B;IAC3B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC;QACtC,YAAY;QACZ,KAAK,EAAE,eAAe;QACtB,MAAM,EAAE,gBAAgB;QACxB,SAAS,EAAE,mBAAmB;QAC9B,aAAa;QACb,GAAG,6BAA6B;KACjC,CAAC,CAAC;IAEH,uCAAuC;IACvC,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,cAAc,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAChE,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1D,MAAM,UAAU,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACnD,CAAC;IAED,qBAAqB;IACrB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,yBAAyB,EAAE,CAAC;QAChD,YAAY,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AAC1C,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/platform",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha2",
|
|
4
4
|
"main": "lib/platform-index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/platform-index.js",
|
|
@@ -31,25 +31,25 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@unchainedshop/api": "^
|
|
35
|
-
"@unchainedshop/core": "^
|
|
36
|
-
"@unchainedshop/events": "^
|
|
37
|
-
"@unchainedshop/file-upload": "^
|
|
38
|
-
"@unchainedshop/logger": "^
|
|
39
|
-
"@unchainedshop/mongodb": "^
|
|
40
|
-
"@unchainedshop/plugins": "^
|
|
41
|
-
"@unchainedshop/roles": "^
|
|
42
|
-
"@unchainedshop/utils": "^
|
|
34
|
+
"@unchainedshop/api": "^3.0.0-alpha2",
|
|
35
|
+
"@unchainedshop/core": "^3.0.0-alpha2",
|
|
36
|
+
"@unchainedshop/events": "^3.0.0-alpha2",
|
|
37
|
+
"@unchainedshop/file-upload": "^3.0.0-alpha2",
|
|
38
|
+
"@unchainedshop/logger": "^3.0.0-alpha2",
|
|
39
|
+
"@unchainedshop/mongodb": "^3.0.0-alpha2",
|
|
40
|
+
"@unchainedshop/plugins": "^3.0.0-alpha2",
|
|
41
|
+
"@unchainedshop/roles": "^3.0.0-alpha2",
|
|
42
|
+
"@unchainedshop/utils": "^3.0.0-alpha2",
|
|
43
43
|
"event-iterator": "^2.0.0",
|
|
44
44
|
"JSONStream": "^1.3.5",
|
|
45
45
|
"moniker": "0.1.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/node": "^20.14.
|
|
49
|
-
"@unchainedshop/types": "^
|
|
48
|
+
"@types/node": "^20.14.12",
|
|
49
|
+
"@unchainedshop/types": "^3.0.0-alpha2",
|
|
50
50
|
"cross-env": "^7.0.3",
|
|
51
51
|
"jest": "^29.7.0",
|
|
52
|
-
"ts-jest": "^29.2.
|
|
53
|
-
"typescript": "^5.5.
|
|
52
|
+
"ts-jest": "^29.2.3",
|
|
53
|
+
"typescript": "^5.5.4"
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -14,6 +14,7 @@ export type BulkImportOperation = (
|
|
|
14
14
|
options: {
|
|
15
15
|
bulk: (collection: string) => typeof mongodb.BulkOperationBase;
|
|
16
16
|
createShouldUpsertIfIDExists?: boolean;
|
|
17
|
+
updateShouldUpsertIfIDNotExists?: boolean;
|
|
17
18
|
skipCacheInvalidation?: boolean;
|
|
18
19
|
logger?: any;
|
|
19
20
|
},
|
|
@@ -53,7 +54,12 @@ export const createBulkImporterFactory = (db, bulkImporterOptions: any): BulkImp
|
|
|
53
54
|
const bulkOperations = {};
|
|
54
55
|
const preparationIssues = [];
|
|
55
56
|
const processedOperations = {};
|
|
56
|
-
const {
|
|
57
|
+
const {
|
|
58
|
+
logger,
|
|
59
|
+
createShouldUpsertIfIDExists,
|
|
60
|
+
skipCacheInvalidation,
|
|
61
|
+
updateShouldUpsertIfIDNotExists,
|
|
62
|
+
} = options;
|
|
57
63
|
|
|
58
64
|
const bulk = (collectionName: string) => {
|
|
59
65
|
const Collection = db.collection(collectionName);
|
|
@@ -63,7 +69,7 @@ export const createBulkImporterFactory = (db, bulkImporterOptions: any): BulkImp
|
|
|
63
69
|
};
|
|
64
70
|
|
|
65
71
|
logger.info(
|
|
66
|
-
`Configure event import with options: createShouldUpsertIfIDExists=${createShouldUpsertIfIDExists} skipCacheInvalidation=${skipCacheInvalidation}`,
|
|
72
|
+
`Configure event import with options: createShouldUpsertIfIDExists=${createShouldUpsertIfIDExists} updateShouldUpsertIfIDNotExists=${updateShouldUpsertIfIDNotExists} skipCacheInvalidation=${skipCacheInvalidation}`,
|
|
67
73
|
);
|
|
68
74
|
|
|
69
75
|
return {
|
|
@@ -34,16 +34,18 @@ export default async function createAssortment(
|
|
|
34
34
|
throw new Error(`Can't create assortment ${_id}, fields missing?`);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
if (specification.content) {
|
|
38
|
+
logger.debug('create localized content for assortment', specification.content);
|
|
39
|
+
await modules.assortments.texts.updateTexts(
|
|
40
|
+
_id,
|
|
41
|
+
Object.entries(specification.content).map(([locale, localizedData]: [string, any]) => {
|
|
42
|
+
return {
|
|
43
|
+
locale,
|
|
44
|
+
...localizedData,
|
|
45
|
+
};
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
47
49
|
|
|
48
50
|
logger.debug('create assortment products', products);
|
|
49
51
|
await upsertAssortmentProducts(
|
|
@@ -4,12 +4,20 @@ import upsertAssortmentChildren from './upsertAssortmentChildren.js';
|
|
|
4
4
|
import upsertAssortmentFilters from './upsertAssortmentFilters.js';
|
|
5
5
|
import upsertMedia from './upsertMedia.js';
|
|
6
6
|
import convertTagsToLowerCase from '../utils/convertTagsToLowerCase.js';
|
|
7
|
+
import createAssortment from './create.js';
|
|
7
8
|
|
|
8
|
-
export default async function updateAssortment(
|
|
9
|
+
export default async function updateAssortment(
|
|
10
|
+
payload: any,
|
|
11
|
+
{ logger, createShouldUpsertIfIDExists, updateShouldUpsertIfIDNotExists },
|
|
12
|
+
unchainedAPI: UnchainedCore,
|
|
13
|
+
) {
|
|
9
14
|
const { modules } = unchainedAPI;
|
|
10
15
|
const { media, specification, products, children, filters, _id } = payload;
|
|
11
16
|
|
|
12
17
|
if (!(await modules.assortments.assortmentExists({ assortmentId: _id }))) {
|
|
18
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
19
|
+
return createAssortment(payload, { logger, createShouldUpsertIfIDExists }, unchainedAPI);
|
|
20
|
+
}
|
|
13
21
|
throw new Error(`Can't update non-existing assortment ${_id}`);
|
|
14
22
|
}
|
|
15
23
|
|
|
@@ -19,6 +27,7 @@ export default async function updateAssortment(payload: any, { logger }, unchain
|
|
|
19
27
|
specification.tags = convertTagsToLowerCase(specification?.tags);
|
|
20
28
|
|
|
21
29
|
await unchainedAPI.modules.assortments.update(_id, { ...specification });
|
|
30
|
+
|
|
22
31
|
if (specification.content) {
|
|
23
32
|
logger.debug('replace localized content for assortment', specification.content);
|
|
24
33
|
await modules.assortments.texts.updateTexts(
|
|
@@ -60,17 +60,19 @@ export default async function createFilter(
|
|
|
60
60
|
if (options) {
|
|
61
61
|
logger.debug('create localized content for filter options', content);
|
|
62
62
|
await Promise.all(
|
|
63
|
-
options.map(async ({ content: optionContent, value: optionValue }) =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
64
|
+
if (optionContent) {
|
|
65
|
+
await modules.filters.texts.updateTexts(
|
|
66
|
+
{ filterId: _id, filterOptionValue: optionValue },
|
|
67
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
68
|
+
return {
|
|
69
|
+
locale,
|
|
70
|
+
...localizedData,
|
|
71
|
+
};
|
|
72
|
+
}),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}),
|
|
74
76
|
);
|
|
75
77
|
}
|
|
76
78
|
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { UnchainedCore } from '@unchainedshop/types/core.js';
|
|
2
|
+
import createFilter from './create.js';
|
|
2
3
|
|
|
3
4
|
export default async function updateFilter(
|
|
4
5
|
payload: any,
|
|
5
|
-
{ logger }: { logger: any },
|
|
6
|
+
{ logger, updateShouldUpsertIfIDNotExists }: { logger: any; updateShouldUpsertIfIDNotExists: boolean },
|
|
6
7
|
unchainedAPI: UnchainedCore,
|
|
7
8
|
) {
|
|
8
9
|
const { modules } = unchainedAPI;
|
|
9
10
|
const { specification, _id } = payload;
|
|
10
11
|
|
|
11
12
|
if (!(await modules.filters.filterExists({ filterId: _id }))) {
|
|
13
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
14
|
+
return createFilter(payload, { logger, createShouldUpsertIfIDExists: false }, unchainedAPI);
|
|
15
|
+
}
|
|
12
16
|
throw new Error(`Can't update non-existing filter ${_id}`);
|
|
13
17
|
}
|
|
14
18
|
|
|
@@ -43,17 +47,19 @@ export default async function updateFilter(
|
|
|
43
47
|
if (options) {
|
|
44
48
|
logger.debug('replace localized content for filter options', content);
|
|
45
49
|
await Promise.all(
|
|
46
|
-
options.map(async ({ content: optionContent, value: optionValue }) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
51
|
+
if (optionContent) {
|
|
52
|
+
await modules.filters.texts.updateTexts(
|
|
53
|
+
{ filterId: _id, filterOptionValue: optionValue },
|
|
54
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
55
|
+
return {
|
|
56
|
+
locale,
|
|
57
|
+
...localizedData,
|
|
58
|
+
};
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}),
|
|
57
63
|
);
|
|
58
64
|
}
|
|
59
65
|
|
|
@@ -35,16 +35,18 @@ export default async function createProduct(
|
|
|
35
35
|
throw new Error(`Can't create product ${_id}, fields missing?`);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
if (specification.content) {
|
|
39
|
+
logger.debug('create localized content for product', specification.content);
|
|
40
|
+
await modules.products.texts.updateTexts(
|
|
41
|
+
_id,
|
|
42
|
+
Object.entries(specification.content).map(([locale, localizedData]: [string, any]) => {
|
|
43
|
+
return {
|
|
44
|
+
locale,
|
|
45
|
+
...localizedData,
|
|
46
|
+
};
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
48
50
|
|
|
49
51
|
logger.debug('create product variations', variations);
|
|
50
52
|
await upsertVariations(
|
|
@@ -2,12 +2,20 @@ import { UnchainedCore } from '@unchainedshop/types/core.js';
|
|
|
2
2
|
import upsertVariations from './upsertVariations.js';
|
|
3
3
|
import upsertMedia from './upsertMedia.js';
|
|
4
4
|
import transformSpecificationToProductStructure from './transformSpecificationToProductStructure.js';
|
|
5
|
+
import createProduct from './create.js';
|
|
5
6
|
|
|
6
|
-
export default async function
|
|
7
|
+
export default async function updateProduct(
|
|
8
|
+
payload: any,
|
|
9
|
+
{ logger, updateShouldUpsertIfIDNotExists },
|
|
10
|
+
unchainedAPI: UnchainedCore,
|
|
11
|
+
) {
|
|
7
12
|
const { modules } = unchainedAPI;
|
|
8
13
|
const { specification, media, variations, _id } = payload;
|
|
9
14
|
|
|
10
15
|
if (!(await modules.products.productExists({ productId: _id }))) {
|
|
16
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
17
|
+
return createProduct(payload, { logger, createShouldUpsertIfIDExists: false }, unchainedAPI);
|
|
18
|
+
}
|
|
11
19
|
throw new Error(`Can't update non-existing product ${_id}`);
|
|
12
20
|
}
|
|
13
21
|
|
|
@@ -26,28 +26,32 @@ export default async function upsertVariations({ variations, productId }, unchai
|
|
|
26
26
|
);
|
|
27
27
|
|
|
28
28
|
await Promise.all(
|
|
29
|
-
options.map(async ({ content: optionContent, value: optionValue }) =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
await modules.products.variations.texts.updateVariationTexts(
|
|
43
|
-
variation._id,
|
|
44
|
-
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
45
|
-
return {
|
|
46
|
-
locale,
|
|
47
|
-
...localizedData,
|
|
48
|
-
};
|
|
29
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
30
|
+
if (optionContent) {
|
|
31
|
+
await modules.products.variations.texts.updateVariationTexts(
|
|
32
|
+
variation._id,
|
|
33
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
34
|
+
return {
|
|
35
|
+
locale,
|
|
36
|
+
...localizedData,
|
|
37
|
+
};
|
|
38
|
+
}),
|
|
39
|
+
optionValue,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
49
42
|
}),
|
|
50
43
|
);
|
|
44
|
+
if (content) {
|
|
45
|
+
await modules.products.variations.texts.updateVariationTexts(
|
|
46
|
+
variation._id,
|
|
47
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
48
|
+
return {
|
|
49
|
+
locale,
|
|
50
|
+
...localizedData,
|
|
51
|
+
};
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
51
55
|
return variation._id;
|
|
52
56
|
}),
|
|
53
57
|
);
|
package/src/context/index.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { UnchainedCore } from '@unchainedshop/types/core.js';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
|
|
4
|
+
export default async (
|
|
5
|
+
unchainedAPI: UnchainedCore,
|
|
6
|
+
username: string,
|
|
7
|
+
plainSecret: string,
|
|
8
|
+
): Promise<void> => {
|
|
9
|
+
const secret = crypto.createHash('sha256').update(`${username}:${plainSecret}`).digest('hex');
|
|
2
10
|
|
|
3
|
-
export default async (unchainedAPI: UnchainedCore, username: string, secret: string): Promise<void> => {
|
|
4
11
|
await unchainedAPI.modules.users.updateUser(
|
|
5
12
|
{ username },
|
|
6
13
|
{
|