@prismatic-io/components-fluent-commerce 0.0.0-stage → 0.1.0
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 +64 -2
- package/dist/icon.png +0 -0
- package/dist/index.js +541 -0
- package/npm-dist/icon.png +0 -0
- package/npm-dist/index.cjs +1240 -0
- package/npm-dist/index.d.cts +359 -0
- package/package.json +58 -4
|
@@ -0,0 +1,1240 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
let _prismatic_io_spectral = require("@prismatic-io/spectral");
|
|
24
|
+
let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
|
|
25
|
+
let graphql_request = require("graphql-request");
|
|
26
|
+
let url_join = require("url-join");
|
|
27
|
+
url_join = __toESM(url_join);
|
|
28
|
+
let lodash_merge = require("lodash.merge");
|
|
29
|
+
lodash_merge = __toESM(lodash_merge);
|
|
30
|
+
//#region src/connections/fluentCommerceOAuthPassword.ts
|
|
31
|
+
const fluentCommerceOAuthPassword = (0, _prismatic_io_spectral.connection)({
|
|
32
|
+
key: "fluent-password-grant",
|
|
33
|
+
display: {
|
|
34
|
+
description: "Authenticate requests to Fluent Commerce using a username and password",
|
|
35
|
+
label: "Fluent Commerce OAuth 2.0 Password Grant"
|
|
36
|
+
},
|
|
37
|
+
inputs: {
|
|
38
|
+
host: {
|
|
39
|
+
label: "Fluent Host",
|
|
40
|
+
placeholder: "https://REPLACE-ME.api.fluentretail.com",
|
|
41
|
+
type: "string",
|
|
42
|
+
required: true,
|
|
43
|
+
shown: true,
|
|
44
|
+
comments: "The retailer's Fluent API endpoint",
|
|
45
|
+
example: "https://REPLACE-ME.api.fluentretail.com"
|
|
46
|
+
},
|
|
47
|
+
username: {
|
|
48
|
+
label: "Retailer Username",
|
|
49
|
+
placeholder: "Enter username",
|
|
50
|
+
type: "string",
|
|
51
|
+
required: true,
|
|
52
|
+
shown: true,
|
|
53
|
+
comments: "The retailer's username",
|
|
54
|
+
example: "john_doe"
|
|
55
|
+
},
|
|
56
|
+
password: {
|
|
57
|
+
label: "Retailer Password",
|
|
58
|
+
placeholder: "Enter password",
|
|
59
|
+
type: "password",
|
|
60
|
+
required: true,
|
|
61
|
+
shown: true,
|
|
62
|
+
comments: "The retailer's password"
|
|
63
|
+
},
|
|
64
|
+
clientId: {
|
|
65
|
+
label: "OAuth 2.0 Client ID",
|
|
66
|
+
placeholder: "Enter client ID",
|
|
67
|
+
type: "string",
|
|
68
|
+
required: true,
|
|
69
|
+
shown: true,
|
|
70
|
+
comments: "A client ID obtained from Fluent support"
|
|
71
|
+
},
|
|
72
|
+
clientSecret: {
|
|
73
|
+
label: "OAuth 2.0 Client Secret",
|
|
74
|
+
placeholder: "Enter client secret",
|
|
75
|
+
type: "password",
|
|
76
|
+
required: true,
|
|
77
|
+
shown: true,
|
|
78
|
+
comments: "A client secret obtained from Fluent support"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/connections/index.ts
|
|
84
|
+
var connections_default = [fluentCommerceOAuthPassword];
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/client.ts
|
|
87
|
+
const createFluentClient = async (connection, debug = false, logger) => {
|
|
88
|
+
if (connection.key !== fluentCommerceOAuthPassword.key) throw new _prismatic_io_spectral.ConnectionError(connection, `Received unexpected connection type: ${connection.key}`);
|
|
89
|
+
const { clientId, clientSecret, host, password, username } = connection.fields;
|
|
90
|
+
let access_token;
|
|
91
|
+
const axiosClient = (0, _prismatic_io_spectral_http.createClient)({ debug: false });
|
|
92
|
+
try {
|
|
93
|
+
const oauthUrl = (0, url_join.default)(_prismatic_io_spectral.util.types.toString(host), "oauth/token");
|
|
94
|
+
const { data: authResponseData } = await axiosClient.post(oauthUrl, null, { params: {
|
|
95
|
+
client_id: clientId,
|
|
96
|
+
client_secret: clientSecret,
|
|
97
|
+
grant_type: "password",
|
|
98
|
+
scope: "api",
|
|
99
|
+
password,
|
|
100
|
+
username
|
|
101
|
+
} });
|
|
102
|
+
access_token = authResponseData.access_token;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
throw new Error(`An error occurred during authentication. Please ensure your username, password, client ID, client secret and endpoint URL are correct. Error: ${error}`);
|
|
105
|
+
}
|
|
106
|
+
if (!access_token) throw new Error("Fluent returned no access token. Please ensure your username, password, client ID, client secret and endpoint URL are correct.");
|
|
107
|
+
return new graphql_request.GraphQLClient((0, url_join.default)(_prismatic_io_spectral.util.types.toString(host), "graphql"), {
|
|
108
|
+
headers: { authorization: `bearer ${access_token}` },
|
|
109
|
+
...debug && logger ? { requestMiddleware: (request) => {
|
|
110
|
+
logger.debug(`Fluent GraphQL request: ${request.body}`);
|
|
111
|
+
return request;
|
|
112
|
+
} } : {}
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/examplePayloads.ts
|
|
117
|
+
const createProductExamplePayload = { data: { createStandardProduct: {
|
|
118
|
+
id: "03440122-ea39-499b-83aa-f08b2614daf3",
|
|
119
|
+
ref: "TESTPRD3"
|
|
120
|
+
} } };
|
|
121
|
+
const createCustomerExamplePayload = { data: { createCustomer: {
|
|
122
|
+
id: "744793",
|
|
123
|
+
username: "jdoe@email.com",
|
|
124
|
+
primaryEmail: "jdoe@email.com",
|
|
125
|
+
primaryPhone: "+123456789",
|
|
126
|
+
firstName: "John",
|
|
127
|
+
lastName: "Doe",
|
|
128
|
+
timezone: "Australia/Sydney",
|
|
129
|
+
country: "Australia",
|
|
130
|
+
promotionOptIn: true,
|
|
131
|
+
retailer: { id: "34" },
|
|
132
|
+
attributes: [{
|
|
133
|
+
name: "loyaltyTier",
|
|
134
|
+
type: "STRING",
|
|
135
|
+
value: "Gold"
|
|
136
|
+
}]
|
|
137
|
+
} } };
|
|
138
|
+
const getCustomerByEmailAddressExamplePayload = { data: { customers: { edges: [{ node: {
|
|
139
|
+
id: "744793",
|
|
140
|
+
ref: "CUST-744793",
|
|
141
|
+
firstName: "John",
|
|
142
|
+
lastName: "Doe",
|
|
143
|
+
username: "jdoe@email.com",
|
|
144
|
+
primaryEmail: "jdoe@email.com",
|
|
145
|
+
primaryPhone: "+123456789",
|
|
146
|
+
timezone: "Australia/Sydney",
|
|
147
|
+
attributes: [{
|
|
148
|
+
name: "loyaltyTier",
|
|
149
|
+
type: "STRING"
|
|
150
|
+
}]
|
|
151
|
+
} }] } } };
|
|
152
|
+
const getCurrentUserExamplePayload = { data: { me: {
|
|
153
|
+
id: "744793",
|
|
154
|
+
username: "admin@fluentretail.com",
|
|
155
|
+
title: "Administrator",
|
|
156
|
+
firstName: "Admin",
|
|
157
|
+
lastName: "User",
|
|
158
|
+
primaryEmail: "admin@fluentretail.com",
|
|
159
|
+
primaryPhone: "+61400000000",
|
|
160
|
+
type: "DEFAULT",
|
|
161
|
+
status: "ACTIVE",
|
|
162
|
+
attributes: [{
|
|
163
|
+
name: "defaultLanguage",
|
|
164
|
+
type: "STRING",
|
|
165
|
+
value: "en"
|
|
166
|
+
}],
|
|
167
|
+
department: "IT",
|
|
168
|
+
country: "Australia",
|
|
169
|
+
timezone: "Australia/Sydney",
|
|
170
|
+
language: {
|
|
171
|
+
value: "en",
|
|
172
|
+
label: "English"
|
|
173
|
+
},
|
|
174
|
+
promotionOptIn: false,
|
|
175
|
+
primaryRetailer: {
|
|
176
|
+
id: "34",
|
|
177
|
+
tradingName: "Fluent Retail"
|
|
178
|
+
},
|
|
179
|
+
primaryLocation: {
|
|
180
|
+
id: "1001",
|
|
181
|
+
type: "STORE",
|
|
182
|
+
status: "ACTIVE",
|
|
183
|
+
name: "Sydney CBD"
|
|
184
|
+
},
|
|
185
|
+
roles: [{ role: {
|
|
186
|
+
id: "1",
|
|
187
|
+
name: "ADMIN",
|
|
188
|
+
permissions: [{ name: "MANAGE_USERS" }]
|
|
189
|
+
} }],
|
|
190
|
+
apps: [{
|
|
191
|
+
id: "101",
|
|
192
|
+
name: "Fluent OMS",
|
|
193
|
+
version: {
|
|
194
|
+
major: 4,
|
|
195
|
+
minor: 2,
|
|
196
|
+
patch: 1
|
|
197
|
+
}
|
|
198
|
+
}]
|
|
199
|
+
} } };
|
|
200
|
+
const genericRequestExamplePayload = { data: { me: {
|
|
201
|
+
id: "744793",
|
|
202
|
+
username: "admin@fluentretail.com",
|
|
203
|
+
primaryEmail: "admin@fluentretail.com"
|
|
204
|
+
} } };
|
|
205
|
+
const pollChangesTriggerExamplePayload = { payload: {
|
|
206
|
+
headers: {},
|
|
207
|
+
queryParameters: {},
|
|
208
|
+
rawBody: { data: null },
|
|
209
|
+
body: { data: {
|
|
210
|
+
created: [{
|
|
211
|
+
id: "ORD-1042",
|
|
212
|
+
ref: "WEB-000142",
|
|
213
|
+
type: "STANDARD",
|
|
214
|
+
status: "CREATED",
|
|
215
|
+
createdOn: "2026-05-26T14:30:00.000Z",
|
|
216
|
+
updatedOn: "2026-05-26T14:30:00.000Z"
|
|
217
|
+
}],
|
|
218
|
+
updated: [{
|
|
219
|
+
id: "ORD-980",
|
|
220
|
+
ref: "WEB-000087",
|
|
221
|
+
type: "STANDARD",
|
|
222
|
+
status: "FULFILLED",
|
|
223
|
+
createdOn: "2026-04-12T09:00:00.000Z",
|
|
224
|
+
updatedOn: "2026-05-26T15:45:00.000Z"
|
|
225
|
+
}]
|
|
226
|
+
} },
|
|
227
|
+
pathFragment: "",
|
|
228
|
+
webhookUrls: {},
|
|
229
|
+
webhookApiKeys: {},
|
|
230
|
+
invokeUrl: "",
|
|
231
|
+
executionId: "RXhhbXBsZUV4ZWN1dGlvblJlc3VsdElk",
|
|
232
|
+
customer: {
|
|
233
|
+
id: "testCustomerId",
|
|
234
|
+
name: "Test Customer",
|
|
235
|
+
externalId: "testExternalId"
|
|
236
|
+
},
|
|
237
|
+
instance: {
|
|
238
|
+
id: "testInstanceId",
|
|
239
|
+
name: "Test Instance"
|
|
240
|
+
},
|
|
241
|
+
user: {
|
|
242
|
+
id: "testUserId",
|
|
243
|
+
email: "user@example.com",
|
|
244
|
+
name: "Test User",
|
|
245
|
+
externalId: "testUserExternalId"
|
|
246
|
+
},
|
|
247
|
+
integration: {
|
|
248
|
+
id: "testIntegrationId",
|
|
249
|
+
name: "Test Integration",
|
|
250
|
+
versionSequenceId: "1",
|
|
251
|
+
externalVersion: ""
|
|
252
|
+
},
|
|
253
|
+
flow: {
|
|
254
|
+
id: "testFlowId",
|
|
255
|
+
name: "Test Flow",
|
|
256
|
+
stableId: "testFlowStableId"
|
|
257
|
+
},
|
|
258
|
+
startedAt: "2024-01-15T00:00:00.000Z",
|
|
259
|
+
globalDebug: false
|
|
260
|
+
} };
|
|
261
|
+
//#endregion
|
|
262
|
+
//#region src/inputs/common.ts
|
|
263
|
+
const connectionInput = (0, _prismatic_io_spectral.input)({
|
|
264
|
+
label: "Connection",
|
|
265
|
+
type: "connection",
|
|
266
|
+
required: true,
|
|
267
|
+
comments: "The Fluent Commerce connection to use."
|
|
268
|
+
});
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/constants.ts
|
|
271
|
+
const LOOK_BACK_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
272
|
+
const POLL_ORDERS_QUERY = graphql_request.gql`
|
|
273
|
+
query PollOrders($from: DateTime!, $to: DateTime!, $first: Int!, $after: String, $retailerId: [Int!]) {
|
|
274
|
+
orders(updatedOn: { from: $from, to: $to }, first: $first, after: $after, retailerId: $retailerId) {
|
|
275
|
+
edges {
|
|
276
|
+
node {
|
|
277
|
+
id
|
|
278
|
+
ref
|
|
279
|
+
type
|
|
280
|
+
status
|
|
281
|
+
createdOn
|
|
282
|
+
updatedOn
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
pageInfo {
|
|
286
|
+
hasNextPage
|
|
287
|
+
endCursor
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
`;
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region src/util/clean.ts
|
|
294
|
+
const toOptionalString = (value) => _prismatic_io_spectral.util.types.toString(value) || void 0;
|
|
295
|
+
const toOptionalNumber = (value) => value ? _prismatic_io_spectral.util.types.toNumber(value) : void 0;
|
|
296
|
+
const toOptionalObject = (value) => value ? _prismatic_io_spectral.util.types.toObject(value) : void 0;
|
|
297
|
+
const lookBackDateClean = (value) => {
|
|
298
|
+
if (value === void 0 || value === null) return "";
|
|
299
|
+
const raw = typeof value === "string" ? value.trim() : String(value);
|
|
300
|
+
if (raw === "") return "";
|
|
301
|
+
const match = typeof value === "string" ? raw.match(LOOK_BACK_DATE_PATTERN) : null;
|
|
302
|
+
if (!match) throw new Error(`Look-back Date must be a date in YYYY-MM-DD format. Received: ${raw}`);
|
|
303
|
+
const [, yearStr, monthStr, dayStr] = match;
|
|
304
|
+
const year = Number(yearStr);
|
|
305
|
+
const month = Number(monthStr);
|
|
306
|
+
const day = Number(dayStr);
|
|
307
|
+
const parsed = new Date(Date.UTC(year, month - 1, day));
|
|
308
|
+
if (parsed.getUTCFullYear() !== year || parsed.getUTCMonth() !== month - 1 || parsed.getUTCDate() !== day) throw new Error(`Look-back Date must be a date in YYYY-MM-DD format. Received: ${raw}`);
|
|
309
|
+
if (parsed.getTime() > Date.now()) throw new Error(`Look-back Date cannot be a future date. Received: ${raw}`);
|
|
310
|
+
return parsed.toISOString();
|
|
311
|
+
};
|
|
312
|
+
const toStringAttributes = (attributes) => {
|
|
313
|
+
if (Array.isArray(attributes)) return attributes.map((attribute) => ({
|
|
314
|
+
name: attribute.key,
|
|
315
|
+
type: "STRING",
|
|
316
|
+
value: attribute.value
|
|
317
|
+
}));
|
|
318
|
+
return [];
|
|
319
|
+
};
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/util/polling.ts
|
|
322
|
+
const fetchFluentOrdersInWindow = async (connection, window, retailerId, maxPages) => {
|
|
323
|
+
const client = await createFluentClient(connection);
|
|
324
|
+
const records = [];
|
|
325
|
+
let after = window.after;
|
|
326
|
+
for (let page = 0; page < maxPages; page++) {
|
|
327
|
+
const variables = {
|
|
328
|
+
from: window.from,
|
|
329
|
+
to: window.to,
|
|
330
|
+
first: 50,
|
|
331
|
+
after,
|
|
332
|
+
retailerId: retailerId || null
|
|
333
|
+
};
|
|
334
|
+
const data = await client.request(POLL_ORDERS_QUERY, variables);
|
|
335
|
+
const edges = data?.orders?.edges ?? [];
|
|
336
|
+
for (const edge of edges) if (edge?.node) records.push(edge.node);
|
|
337
|
+
const pageInfo = data?.orders?.pageInfo;
|
|
338
|
+
if (!pageInfo?.hasNextPage) return {
|
|
339
|
+
records,
|
|
340
|
+
truncated: false,
|
|
341
|
+
after: null
|
|
342
|
+
};
|
|
343
|
+
if (!pageInfo.endCursor) throw new Error("Fluent reported more orders but returned no endCursor to continue from.");
|
|
344
|
+
after = pageInfo.endCursor;
|
|
345
|
+
}
|
|
346
|
+
return {
|
|
347
|
+
records,
|
|
348
|
+
truncated: true,
|
|
349
|
+
after
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
const resolveFluentOrderChanges = (data) => {
|
|
353
|
+
const changesObject = data ?? {
|
|
354
|
+
created: [],
|
|
355
|
+
updated: []
|
|
356
|
+
};
|
|
357
|
+
return [...(changesObject.created ?? []).map((record) => ({
|
|
358
|
+
changeType: "created",
|
|
359
|
+
record
|
|
360
|
+
})), ...(changesObject.updated ?? []).map((record) => ({
|
|
361
|
+
changeType: "updated",
|
|
362
|
+
record
|
|
363
|
+
}))];
|
|
364
|
+
};
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region src/inputs/customers.ts
|
|
367
|
+
const retailerId$1 = (0, _prismatic_io_spectral.input)({
|
|
368
|
+
label: "Retailer ID",
|
|
369
|
+
type: "string",
|
|
370
|
+
example: "34",
|
|
371
|
+
placeholder: "Enter retailer ID",
|
|
372
|
+
required: true,
|
|
373
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
374
|
+
comments: "The ID of the retailer (a number)"
|
|
375
|
+
});
|
|
376
|
+
const customerEmail = (0, _prismatic_io_spectral.input)({
|
|
377
|
+
label: "Customer Email",
|
|
378
|
+
type: "string",
|
|
379
|
+
example: "test@example.com",
|
|
380
|
+
placeholder: "Enter customer email",
|
|
381
|
+
required: true,
|
|
382
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
383
|
+
comments: "The email address of the customer"
|
|
384
|
+
});
|
|
385
|
+
const firstName = (0, _prismatic_io_spectral.input)({
|
|
386
|
+
label: "First Name",
|
|
387
|
+
type: "string",
|
|
388
|
+
example: "John",
|
|
389
|
+
placeholder: "Enter first name",
|
|
390
|
+
required: true,
|
|
391
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
392
|
+
comments: "The first name of the customer (required)"
|
|
393
|
+
});
|
|
394
|
+
const lastName = (0, _prismatic_io_spectral.input)({
|
|
395
|
+
label: "Last Name",
|
|
396
|
+
type: "string",
|
|
397
|
+
example: "Doe",
|
|
398
|
+
placeholder: "Enter last name",
|
|
399
|
+
required: false,
|
|
400
|
+
clean: toOptionalString,
|
|
401
|
+
comments: "The last name of the customer"
|
|
402
|
+
});
|
|
403
|
+
const phoneNumber = (0, _prismatic_io_spectral.input)({
|
|
404
|
+
label: "Phone Number",
|
|
405
|
+
type: "string",
|
|
406
|
+
example: "+61412345678",
|
|
407
|
+
placeholder: "Enter phone number",
|
|
408
|
+
required: false,
|
|
409
|
+
clean: toOptionalString,
|
|
410
|
+
comments: "The customer's phone number"
|
|
411
|
+
});
|
|
412
|
+
const country = (0, _prismatic_io_spectral.input)({
|
|
413
|
+
label: "Country",
|
|
414
|
+
type: "string",
|
|
415
|
+
example: "Australia",
|
|
416
|
+
placeholder: "Enter country",
|
|
417
|
+
required: false,
|
|
418
|
+
clean: toOptionalString,
|
|
419
|
+
comments: "The customer's country"
|
|
420
|
+
});
|
|
421
|
+
const timezone = (0, _prismatic_io_spectral.input)({
|
|
422
|
+
label: "Time Zone",
|
|
423
|
+
type: "string",
|
|
424
|
+
example: "UTC+5",
|
|
425
|
+
placeholder: "Enter time zone",
|
|
426
|
+
required: false,
|
|
427
|
+
clean: toOptionalString,
|
|
428
|
+
comments: "The customer's time zone"
|
|
429
|
+
});
|
|
430
|
+
const promotionOptIn = (0, _prismatic_io_spectral.input)({
|
|
431
|
+
label: "Promotion Opt In",
|
|
432
|
+
type: "boolean",
|
|
433
|
+
required: true,
|
|
434
|
+
clean: _prismatic_io_spectral.util.types.toBool,
|
|
435
|
+
comments: "When true, the customer is opted in to receive promotional communications."
|
|
436
|
+
});
|
|
437
|
+
const attributes = (0, _prismatic_io_spectral.input)({
|
|
438
|
+
label: "Attributes",
|
|
439
|
+
type: "string",
|
|
440
|
+
required: false,
|
|
441
|
+
collection: "keyvaluelist",
|
|
442
|
+
clean: toStringAttributes,
|
|
443
|
+
comments: "Custom attributes to apply to the customer. Each key becomes the attribute name, and each value is stored as a STRING attribute."
|
|
444
|
+
});
|
|
445
|
+
const emailAddress = (0, _prismatic_io_spectral.input)({
|
|
446
|
+
label: "Customer Email Address",
|
|
447
|
+
type: "string",
|
|
448
|
+
example: "test@example.com",
|
|
449
|
+
placeholder: "Enter customer email address",
|
|
450
|
+
required: true,
|
|
451
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
452
|
+
comments: "The customer's email address"
|
|
453
|
+
});
|
|
454
|
+
const createCustomerInputs = {
|
|
455
|
+
connection: connectionInput,
|
|
456
|
+
retailerId: retailerId$1,
|
|
457
|
+
customerEmail,
|
|
458
|
+
firstName,
|
|
459
|
+
promotionOptIn,
|
|
460
|
+
lastName,
|
|
461
|
+
phoneNumber,
|
|
462
|
+
country,
|
|
463
|
+
timezone,
|
|
464
|
+
attributes
|
|
465
|
+
};
|
|
466
|
+
const getCustomerByEmailAddressInputs = {
|
|
467
|
+
connection: connectionInput,
|
|
468
|
+
emailAddress
|
|
469
|
+
};
|
|
470
|
+
const genericRequestInputs = {
|
|
471
|
+
connection: connectionInput,
|
|
472
|
+
query: (0, _prismatic_io_spectral.input)({
|
|
473
|
+
label: "Query or Mutation",
|
|
474
|
+
type: "code",
|
|
475
|
+
required: true,
|
|
476
|
+
language: "graphql",
|
|
477
|
+
default: `{
|
|
478
|
+
me {
|
|
479
|
+
id
|
|
480
|
+
username
|
|
481
|
+
primaryEmail
|
|
482
|
+
}
|
|
483
|
+
}`,
|
|
484
|
+
placeholder: "Enter GraphQL query or mutation",
|
|
485
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
486
|
+
comments: "The GraphQL query or mutation to send to the Fluent Commerce API."
|
|
487
|
+
}),
|
|
488
|
+
variables: (0, _prismatic_io_spectral.input)({
|
|
489
|
+
label: "Variables",
|
|
490
|
+
type: "string",
|
|
491
|
+
required: false,
|
|
492
|
+
collection: "keyvaluelist",
|
|
493
|
+
clean: (val) => _prismatic_io_spectral.util.types.keyValPairListToObject(val),
|
|
494
|
+
comments: "Key-value pairs passed to the query as GraphQL variables."
|
|
495
|
+
}),
|
|
496
|
+
variablesObject: (0, _prismatic_io_spectral.input)({
|
|
497
|
+
label: "Variables Object",
|
|
498
|
+
type: "code",
|
|
499
|
+
language: "json",
|
|
500
|
+
required: false,
|
|
501
|
+
example: "{\"retailerId\": \"34\"}",
|
|
502
|
+
placeholder: "Enter GraphQL variables as JSON",
|
|
503
|
+
clean: toOptionalObject,
|
|
504
|
+
comments: "A JSON object of GraphQL variables, for values that are not strings. Merged with Variables; on a shared key, this value wins."
|
|
505
|
+
})
|
|
506
|
+
};
|
|
507
|
+
const getCurrentUserInputs = { connection: connectionInput };
|
|
508
|
+
const createProductInputs = {
|
|
509
|
+
connection: connectionInput,
|
|
510
|
+
productCatalogueRef: (0, _prismatic_io_spectral.input)({
|
|
511
|
+
label: "Product Catalogue Ref (ID)",
|
|
512
|
+
type: "string",
|
|
513
|
+
required: true,
|
|
514
|
+
example: "FCRG:PC:MASTER",
|
|
515
|
+
placeholder: "Enter product catalogue ref",
|
|
516
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
517
|
+
comments: "The reference ID (ref) of an existing product catalog"
|
|
518
|
+
}),
|
|
519
|
+
productRef: (0, _prismatic_io_spectral.input)({
|
|
520
|
+
label: "Product Ref ID",
|
|
521
|
+
type: "string",
|
|
522
|
+
required: true,
|
|
523
|
+
example: "TESTPRD",
|
|
524
|
+
placeholder: "Enter product ref",
|
|
525
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
526
|
+
comments: "The reference ID (ref) of the new product (must be unique)"
|
|
527
|
+
}),
|
|
528
|
+
productType: (0, _prismatic_io_spectral.input)({
|
|
529
|
+
label: "Product Type",
|
|
530
|
+
type: "string",
|
|
531
|
+
required: true,
|
|
532
|
+
example: "STANDARD",
|
|
533
|
+
default: "STANDARD",
|
|
534
|
+
placeholder: "Enter product type",
|
|
535
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
536
|
+
comments: "The type of the product"
|
|
537
|
+
}),
|
|
538
|
+
productName: (0, _prismatic_io_spectral.input)({
|
|
539
|
+
label: "Product Name",
|
|
540
|
+
type: "string",
|
|
541
|
+
required: true,
|
|
542
|
+
example: "Widget",
|
|
543
|
+
placeholder: "Enter product name",
|
|
544
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
545
|
+
comments: "The name of the product (not required to be unique)"
|
|
546
|
+
}),
|
|
547
|
+
productSummary: (0, _prismatic_io_spectral.input)({
|
|
548
|
+
label: "Product Summary / Description",
|
|
549
|
+
type: "string",
|
|
550
|
+
required: true,
|
|
551
|
+
example: "Widgets: the new whatsits",
|
|
552
|
+
placeholder: "Enter product summary",
|
|
553
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
554
|
+
comments: "A short description of the product, stored as the product's summary."
|
|
555
|
+
}),
|
|
556
|
+
gtin: (0, _prismatic_io_spectral.input)({
|
|
557
|
+
label: "Global Trade Item Number (GTIN)",
|
|
558
|
+
type: "string",
|
|
559
|
+
required: true,
|
|
560
|
+
example: "012345678905",
|
|
561
|
+
placeholder: "Enter GTIN",
|
|
562
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
563
|
+
comments: "The global trade number of the product"
|
|
564
|
+
}),
|
|
565
|
+
priceCurrency: (0, _prismatic_io_spectral.input)({
|
|
566
|
+
label: "Price Currency",
|
|
567
|
+
type: "string",
|
|
568
|
+
required: true,
|
|
569
|
+
example: "USD",
|
|
570
|
+
placeholder: "Enter price currency",
|
|
571
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
572
|
+
comments: "Type of currency the price is in (USD, YEN, GBP, etc)"
|
|
573
|
+
}),
|
|
574
|
+
priceValue: (0, _prismatic_io_spectral.input)({
|
|
575
|
+
label: "Price Value",
|
|
576
|
+
type: "string",
|
|
577
|
+
required: true,
|
|
578
|
+
example: "1300",
|
|
579
|
+
placeholder: "Enter price value",
|
|
580
|
+
clean: _prismatic_io_spectral.util.types.toNumber,
|
|
581
|
+
comments: "The price of the product (must be a floating-point number)"
|
|
582
|
+
})
|
|
583
|
+
};
|
|
584
|
+
const pollChangesInputs = {
|
|
585
|
+
connection: connectionInput,
|
|
586
|
+
lookBackDate: (0, _prismatic_io_spectral.input)({
|
|
587
|
+
label: "Look-back Date",
|
|
588
|
+
placeholder: "Enter look-back date (YYYY-MM-DD)",
|
|
589
|
+
type: "string",
|
|
590
|
+
required: false,
|
|
591
|
+
comments: "The date the initial sync starts from, in YYYY-MM-DD format. Cannot be a future date. Leave empty to start from the first recurrence with no backfill. When set, the initial sync seeds each record modified on or after this date once, ignoring the field and visibility filters.",
|
|
592
|
+
example: "2026-01-01",
|
|
593
|
+
clean: lookBackDateClean
|
|
594
|
+
}),
|
|
595
|
+
retailerId: (0, _prismatic_io_spectral.input)({
|
|
596
|
+
label: "Retailer ID",
|
|
597
|
+
type: "string",
|
|
598
|
+
required: false,
|
|
599
|
+
example: "34",
|
|
600
|
+
comments: "Optional Fluent retailer ID to scope the polling query. When omitted, the connection's default tenant scope applies.",
|
|
601
|
+
clean: toOptionalNumber
|
|
602
|
+
}),
|
|
603
|
+
showNewRecords: (0, _prismatic_io_spectral.input)({
|
|
604
|
+
label: "Show New Records",
|
|
605
|
+
type: "boolean",
|
|
606
|
+
required: false,
|
|
607
|
+
default: "true",
|
|
608
|
+
comments: "When enabled, orders whose `createdOn` falls after the last poll will be emitted in the `created` array.",
|
|
609
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
610
|
+
}),
|
|
611
|
+
showUpdatedRecords: (0, _prismatic_io_spectral.input)({
|
|
612
|
+
label: "Show Updated Records",
|
|
613
|
+
type: "boolean",
|
|
614
|
+
required: false,
|
|
615
|
+
default: "true",
|
|
616
|
+
comments: "When enabled, orders whose `updatedOn` falls after the last poll but were created earlier will be emitted in the `updated` array.",
|
|
617
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
618
|
+
})
|
|
619
|
+
};
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region src/outputSchemas.ts
|
|
622
|
+
const attributeItemSchema = {
|
|
623
|
+
type: ["object", "null"],
|
|
624
|
+
properties: {
|
|
625
|
+
name: { type: "string" },
|
|
626
|
+
type: { type: "string" },
|
|
627
|
+
value: { type: [
|
|
628
|
+
"string",
|
|
629
|
+
"number",
|
|
630
|
+
"boolean",
|
|
631
|
+
"object",
|
|
632
|
+
"array"
|
|
633
|
+
] }
|
|
634
|
+
},
|
|
635
|
+
required: [
|
|
636
|
+
"name",
|
|
637
|
+
"type",
|
|
638
|
+
"value"
|
|
639
|
+
]
|
|
640
|
+
};
|
|
641
|
+
const createCustomerOutputSchema = {
|
|
642
|
+
type: "object",
|
|
643
|
+
properties: { createCustomer: {
|
|
644
|
+
type: ["object", "null"],
|
|
645
|
+
properties: {
|
|
646
|
+
id: { type: "string" },
|
|
647
|
+
username: { type: ["string", "null"] },
|
|
648
|
+
primaryEmail: { type: ["string", "null"] },
|
|
649
|
+
primaryPhone: { type: ["string", "null"] },
|
|
650
|
+
firstName: { type: ["string", "null"] },
|
|
651
|
+
lastName: { type: ["string", "null"] },
|
|
652
|
+
timezone: { type: ["string", "null"] },
|
|
653
|
+
country: { type: ["string", "null"] },
|
|
654
|
+
promotionOptIn: { type: ["boolean", "null"] },
|
|
655
|
+
retailer: {
|
|
656
|
+
type: ["object", "null"],
|
|
657
|
+
properties: { id: { type: "string" } },
|
|
658
|
+
required: ["id"]
|
|
659
|
+
},
|
|
660
|
+
attributes: {
|
|
661
|
+
type: ["array", "null"],
|
|
662
|
+
items: attributeItemSchema
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
required: [
|
|
666
|
+
"id",
|
|
667
|
+
"username",
|
|
668
|
+
"primaryEmail",
|
|
669
|
+
"primaryPhone",
|
|
670
|
+
"firstName",
|
|
671
|
+
"lastName",
|
|
672
|
+
"timezone",
|
|
673
|
+
"country",
|
|
674
|
+
"promotionOptIn",
|
|
675
|
+
"retailer",
|
|
676
|
+
"attributes"
|
|
677
|
+
]
|
|
678
|
+
} },
|
|
679
|
+
required: ["createCustomer"]
|
|
680
|
+
};
|
|
681
|
+
const getCustomerByEmailAddressOutputSchema = {
|
|
682
|
+
type: "object",
|
|
683
|
+
properties: { customers: {
|
|
684
|
+
type: ["object", "null"],
|
|
685
|
+
properties: { edges: {
|
|
686
|
+
type: ["array", "null"],
|
|
687
|
+
items: {
|
|
688
|
+
type: ["object", "null"],
|
|
689
|
+
properties: { node: {
|
|
690
|
+
type: ["object", "null"],
|
|
691
|
+
properties: {
|
|
692
|
+
id: { type: "string" },
|
|
693
|
+
ref: { type: ["string", "null"] },
|
|
694
|
+
firstName: { type: ["string", "null"] },
|
|
695
|
+
lastName: { type: ["string", "null"] },
|
|
696
|
+
username: { type: ["string", "null"] },
|
|
697
|
+
primaryEmail: { type: ["string", "null"] },
|
|
698
|
+
primaryPhone: { type: ["string", "null"] },
|
|
699
|
+
timezone: { type: ["string", "null"] },
|
|
700
|
+
attributes: {
|
|
701
|
+
type: ["array", "null"],
|
|
702
|
+
items: {
|
|
703
|
+
type: ["object", "null"],
|
|
704
|
+
properties: {
|
|
705
|
+
name: { type: "string" },
|
|
706
|
+
type: { type: "string" }
|
|
707
|
+
},
|
|
708
|
+
required: ["name", "type"]
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
required: [
|
|
713
|
+
"id",
|
|
714
|
+
"ref",
|
|
715
|
+
"firstName",
|
|
716
|
+
"lastName",
|
|
717
|
+
"username",
|
|
718
|
+
"primaryEmail",
|
|
719
|
+
"primaryPhone",
|
|
720
|
+
"timezone",
|
|
721
|
+
"attributes"
|
|
722
|
+
]
|
|
723
|
+
} },
|
|
724
|
+
required: ["node"]
|
|
725
|
+
}
|
|
726
|
+
} },
|
|
727
|
+
required: ["edges"]
|
|
728
|
+
} },
|
|
729
|
+
required: ["customers"]
|
|
730
|
+
};
|
|
731
|
+
const getCurrentUserOutputSchema = {
|
|
732
|
+
type: "object",
|
|
733
|
+
properties: { me: {
|
|
734
|
+
type: ["object", "null"],
|
|
735
|
+
properties: {
|
|
736
|
+
id: { type: "string" },
|
|
737
|
+
username: { type: "string" },
|
|
738
|
+
title: { type: ["string", "null"] },
|
|
739
|
+
firstName: { type: ["string", "null"] },
|
|
740
|
+
lastName: { type: ["string", "null"] },
|
|
741
|
+
primaryEmail: { type: ["string", "null"] },
|
|
742
|
+
primaryPhone: { type: ["string", "null"] },
|
|
743
|
+
type: { type: "string" },
|
|
744
|
+
status: { type: ["string", "null"] },
|
|
745
|
+
attributes: {
|
|
746
|
+
type: ["array", "null"],
|
|
747
|
+
items: attributeItemSchema
|
|
748
|
+
},
|
|
749
|
+
department: { type: ["string", "null"] },
|
|
750
|
+
country: { type: ["string", "null"] },
|
|
751
|
+
timezone: { type: ["string", "null"] },
|
|
752
|
+
language: {
|
|
753
|
+
type: ["object", "null"],
|
|
754
|
+
properties: {
|
|
755
|
+
value: { type: ["string", "null"] },
|
|
756
|
+
label: { type: ["string", "null"] }
|
|
757
|
+
},
|
|
758
|
+
required: ["value", "label"]
|
|
759
|
+
},
|
|
760
|
+
promotionOptIn: { type: ["boolean", "null"] },
|
|
761
|
+
primaryRetailer: {
|
|
762
|
+
type: ["object", "null"],
|
|
763
|
+
properties: {
|
|
764
|
+
id: { type: "string" },
|
|
765
|
+
tradingName: { type: ["string", "null"] }
|
|
766
|
+
},
|
|
767
|
+
required: ["id", "tradingName"]
|
|
768
|
+
},
|
|
769
|
+
primaryLocation: {
|
|
770
|
+
type: ["object", "null"],
|
|
771
|
+
properties: {
|
|
772
|
+
id: { type: "string" },
|
|
773
|
+
type: { type: ["string", "null"] },
|
|
774
|
+
status: { type: ["string", "null"] },
|
|
775
|
+
name: { type: ["string", "null"] }
|
|
776
|
+
},
|
|
777
|
+
required: [
|
|
778
|
+
"id",
|
|
779
|
+
"type",
|
|
780
|
+
"status",
|
|
781
|
+
"name"
|
|
782
|
+
]
|
|
783
|
+
},
|
|
784
|
+
roles: {
|
|
785
|
+
type: ["array", "null"],
|
|
786
|
+
items: {
|
|
787
|
+
type: ["object", "null"],
|
|
788
|
+
properties: { role: {
|
|
789
|
+
type: "object",
|
|
790
|
+
properties: {
|
|
791
|
+
id: { type: "string" },
|
|
792
|
+
name: { type: "string" },
|
|
793
|
+
permissions: {
|
|
794
|
+
type: ["array", "null"],
|
|
795
|
+
items: {
|
|
796
|
+
type: ["object", "null"],
|
|
797
|
+
properties: { name: { type: "string" } },
|
|
798
|
+
required: ["name"]
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
required: [
|
|
803
|
+
"id",
|
|
804
|
+
"name",
|
|
805
|
+
"permissions"
|
|
806
|
+
]
|
|
807
|
+
} },
|
|
808
|
+
required: ["role"]
|
|
809
|
+
}
|
|
810
|
+
},
|
|
811
|
+
apps: {
|
|
812
|
+
type: ["array", "null"],
|
|
813
|
+
items: {
|
|
814
|
+
type: ["object", "null"],
|
|
815
|
+
properties: {
|
|
816
|
+
id: { type: "string" },
|
|
817
|
+
name: { type: "string" },
|
|
818
|
+
version: {
|
|
819
|
+
type: "object",
|
|
820
|
+
properties: {
|
|
821
|
+
major: { type: "integer" },
|
|
822
|
+
minor: { type: "integer" },
|
|
823
|
+
patch: { type: "integer" }
|
|
824
|
+
},
|
|
825
|
+
required: [
|
|
826
|
+
"major",
|
|
827
|
+
"minor",
|
|
828
|
+
"patch"
|
|
829
|
+
]
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
required: [
|
|
833
|
+
"id",
|
|
834
|
+
"name",
|
|
835
|
+
"version"
|
|
836
|
+
]
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
required: [
|
|
841
|
+
"id",
|
|
842
|
+
"username",
|
|
843
|
+
"title",
|
|
844
|
+
"firstName",
|
|
845
|
+
"lastName",
|
|
846
|
+
"primaryEmail",
|
|
847
|
+
"primaryPhone",
|
|
848
|
+
"type",
|
|
849
|
+
"status",
|
|
850
|
+
"attributes",
|
|
851
|
+
"department",
|
|
852
|
+
"country",
|
|
853
|
+
"timezone",
|
|
854
|
+
"language",
|
|
855
|
+
"promotionOptIn",
|
|
856
|
+
"primaryRetailer",
|
|
857
|
+
"primaryLocation",
|
|
858
|
+
"roles",
|
|
859
|
+
"apps"
|
|
860
|
+
]
|
|
861
|
+
} },
|
|
862
|
+
required: ["me"]
|
|
863
|
+
};
|
|
864
|
+
const createProductOutputSchema = {
|
|
865
|
+
type: "object",
|
|
866
|
+
properties: { createStandardProduct: {
|
|
867
|
+
type: ["object", "null"],
|
|
868
|
+
properties: {
|
|
869
|
+
id: { type: "string" },
|
|
870
|
+
ref: { type: "string" }
|
|
871
|
+
},
|
|
872
|
+
required: ["id", "ref"]
|
|
873
|
+
} },
|
|
874
|
+
required: ["createStandardProduct"]
|
|
875
|
+
};
|
|
876
|
+
//#endregion
|
|
877
|
+
//#region src/actions/customers/index.ts
|
|
878
|
+
var customers_default = {
|
|
879
|
+
createCustomer: (0, _prismatic_io_spectral.action)({
|
|
880
|
+
display: {
|
|
881
|
+
label: "Create Customer",
|
|
882
|
+
description: "Create a new customer"
|
|
883
|
+
},
|
|
884
|
+
inputs: createCustomerInputs,
|
|
885
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
886
|
+
type: "actionOutput",
|
|
887
|
+
schema: createCustomerOutputSchema
|
|
888
|
+
}),
|
|
889
|
+
performSafety: "notAllowed",
|
|
890
|
+
perform: async (context, params) => {
|
|
891
|
+
const client = await createFluentClient(params.connection, context.debug.enabled, context.logger);
|
|
892
|
+
const query = graphql_request.gql`
|
|
893
|
+
mutation createCustomer(
|
|
894
|
+
$retailerId: ID!
|
|
895
|
+
$customerEmail: String!
|
|
896
|
+
$firstName: String!
|
|
897
|
+
$lastName: String
|
|
898
|
+
$phoneNumber: String
|
|
899
|
+
$country: String
|
|
900
|
+
$timezone: String
|
|
901
|
+
$attributes: [AttributeInput]
|
|
902
|
+
$promotionOptIn: Boolean!
|
|
903
|
+
) {
|
|
904
|
+
createCustomer(
|
|
905
|
+
input: {
|
|
906
|
+
username: $customerEmail
|
|
907
|
+
firstName: $firstName
|
|
908
|
+
lastName: $lastName
|
|
909
|
+
primaryEmail: $customerEmail
|
|
910
|
+
primaryPhone: $phoneNumber
|
|
911
|
+
promotionOptIn: $promotionOptIn
|
|
912
|
+
timezone: $timezone
|
|
913
|
+
country: $country
|
|
914
|
+
retailer: { id: $retailerId }
|
|
915
|
+
attributes: $attributes
|
|
916
|
+
}
|
|
917
|
+
) {
|
|
918
|
+
id
|
|
919
|
+
username
|
|
920
|
+
primaryEmail
|
|
921
|
+
primaryPhone
|
|
922
|
+
firstName
|
|
923
|
+
lastName
|
|
924
|
+
timezone
|
|
925
|
+
country
|
|
926
|
+
promotionOptIn
|
|
927
|
+
retailer {
|
|
928
|
+
id
|
|
929
|
+
}
|
|
930
|
+
attributes {
|
|
931
|
+
name
|
|
932
|
+
type
|
|
933
|
+
value
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
`;
|
|
938
|
+
const variables = {
|
|
939
|
+
retailerId: params.retailerId,
|
|
940
|
+
customerEmail: params.customerEmail,
|
|
941
|
+
firstName: params.firstName,
|
|
942
|
+
lastName: params.lastName,
|
|
943
|
+
phoneNumber: params.phoneNumber,
|
|
944
|
+
promotionOptIn: params.promotionOptIn,
|
|
945
|
+
country: params.country,
|
|
946
|
+
timezone: params.timezone,
|
|
947
|
+
attributes: params.attributes
|
|
948
|
+
};
|
|
949
|
+
return { data: await client.request(query, variables) };
|
|
950
|
+
},
|
|
951
|
+
examplePerform: async () => createCustomerExamplePayload,
|
|
952
|
+
examplePayload: createCustomerExamplePayload
|
|
953
|
+
}),
|
|
954
|
+
getCustomerByEmailAddress: (0, _prismatic_io_spectral.action)({
|
|
955
|
+
display: {
|
|
956
|
+
label: "Get Customer by Email",
|
|
957
|
+
description: "Find a customer by their email address"
|
|
958
|
+
},
|
|
959
|
+
inputs: getCustomerByEmailAddressInputs,
|
|
960
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
961
|
+
type: "actionOutput",
|
|
962
|
+
schema: getCustomerByEmailAddressOutputSchema
|
|
963
|
+
}),
|
|
964
|
+
performSafety: "safe",
|
|
965
|
+
perform: async (context, params) => {
|
|
966
|
+
const client = await createFluentClient(params.connection, context.debug.enabled, context.logger);
|
|
967
|
+
const query = graphql_request.gql`
|
|
968
|
+
query GetCustomerByEmailAddress($emailAddress: String) {
|
|
969
|
+
customers(primaryEmail: [$emailAddress]) {
|
|
970
|
+
edges {
|
|
971
|
+
node {
|
|
972
|
+
id
|
|
973
|
+
ref
|
|
974
|
+
firstName
|
|
975
|
+
lastName
|
|
976
|
+
username
|
|
977
|
+
primaryEmail
|
|
978
|
+
primaryPhone
|
|
979
|
+
timezone
|
|
980
|
+
attributes {
|
|
981
|
+
name
|
|
982
|
+
type
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
`;
|
|
989
|
+
const variables = { emailAddress: params.emailAddress };
|
|
990
|
+
return { data: await client.request(query, variables) };
|
|
991
|
+
},
|
|
992
|
+
examplePayload: getCustomerByEmailAddressExamplePayload
|
|
993
|
+
})
|
|
994
|
+
};
|
|
995
|
+
//#endregion
|
|
996
|
+
//#region src/actions/misc/index.ts
|
|
997
|
+
var misc_default = {
|
|
998
|
+
genericRequest: (0, _prismatic_io_spectral.action)({
|
|
999
|
+
display: {
|
|
1000
|
+
label: "Generic GraphQL Request",
|
|
1001
|
+
description: "Issue any GraphQL query or mutation with variables"
|
|
1002
|
+
},
|
|
1003
|
+
inputs: genericRequestInputs,
|
|
1004
|
+
performSafety: "notAllowed",
|
|
1005
|
+
perform: async (context, params) => {
|
|
1006
|
+
return { data: await (await createFluentClient(params.connection, context.debug.enabled, context.logger)).request(params.query, (0, lodash_merge.default)(params.variables, params.variablesObject)) };
|
|
1007
|
+
},
|
|
1008
|
+
examplePayload: genericRequestExamplePayload
|
|
1009
|
+
}),
|
|
1010
|
+
getCurrentUser: (0, _prismatic_io_spectral.action)({
|
|
1011
|
+
display: {
|
|
1012
|
+
label: "Get Current User",
|
|
1013
|
+
description: "Get information about the currently authenticated user"
|
|
1014
|
+
},
|
|
1015
|
+
inputs: getCurrentUserInputs,
|
|
1016
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
1017
|
+
type: "actionOutput",
|
|
1018
|
+
schema: getCurrentUserOutputSchema
|
|
1019
|
+
}),
|
|
1020
|
+
performSafety: "safe",
|
|
1021
|
+
perform: async (context, params) => {
|
|
1022
|
+
const client = await createFluentClient(params.connection, context.debug.enabled, context.logger);
|
|
1023
|
+
const query = graphql_request.gql`
|
|
1024
|
+
{
|
|
1025
|
+
me {
|
|
1026
|
+
id
|
|
1027
|
+
username
|
|
1028
|
+
title
|
|
1029
|
+
firstName
|
|
1030
|
+
lastName
|
|
1031
|
+
primaryEmail
|
|
1032
|
+
primaryPhone
|
|
1033
|
+
type
|
|
1034
|
+
status
|
|
1035
|
+
attributes {
|
|
1036
|
+
name
|
|
1037
|
+
type
|
|
1038
|
+
value
|
|
1039
|
+
}
|
|
1040
|
+
department
|
|
1041
|
+
country
|
|
1042
|
+
timezone
|
|
1043
|
+
language {
|
|
1044
|
+
value
|
|
1045
|
+
label
|
|
1046
|
+
}
|
|
1047
|
+
promotionOptIn
|
|
1048
|
+
primaryRetailer {
|
|
1049
|
+
id
|
|
1050
|
+
tradingName
|
|
1051
|
+
}
|
|
1052
|
+
primaryLocation {
|
|
1053
|
+
id
|
|
1054
|
+
type
|
|
1055
|
+
status
|
|
1056
|
+
name
|
|
1057
|
+
}
|
|
1058
|
+
roles {
|
|
1059
|
+
role {
|
|
1060
|
+
id
|
|
1061
|
+
name
|
|
1062
|
+
permissions {
|
|
1063
|
+
name
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
apps {
|
|
1068
|
+
id
|
|
1069
|
+
name
|
|
1070
|
+
version {
|
|
1071
|
+
major
|
|
1072
|
+
minor
|
|
1073
|
+
patch
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
`;
|
|
1079
|
+
return { data: await client.request(query) };
|
|
1080
|
+
},
|
|
1081
|
+
examplePayload: getCurrentUserExamplePayload
|
|
1082
|
+
})
|
|
1083
|
+
};
|
|
1084
|
+
//#endregion
|
|
1085
|
+
//#region src/actions/products/index.ts
|
|
1086
|
+
var products_default = { createProduct: (0, _prismatic_io_spectral.action)({
|
|
1087
|
+
display: {
|
|
1088
|
+
label: "Create Product",
|
|
1089
|
+
description: "Create a new standard product"
|
|
1090
|
+
},
|
|
1091
|
+
inputs: createProductInputs,
|
|
1092
|
+
outputSchema: (0, _prismatic_io_spectral.outputSchema)({
|
|
1093
|
+
type: "actionOutput",
|
|
1094
|
+
schema: createProductOutputSchema
|
|
1095
|
+
}),
|
|
1096
|
+
performSafety: "notAllowed",
|
|
1097
|
+
perform: async (context, params) => {
|
|
1098
|
+
const client = await createFluentClient(params.connection, context.debug.enabled, context.logger);
|
|
1099
|
+
const query = graphql_request.gql`
|
|
1100
|
+
mutation createProduct(
|
|
1101
|
+
$productCatalogueRef: String!
|
|
1102
|
+
$productRef: String!
|
|
1103
|
+
$productType: String!
|
|
1104
|
+
$productName: String!
|
|
1105
|
+
$productSummary: String!
|
|
1106
|
+
$gtin: String!
|
|
1107
|
+
$priceCurrency: String!
|
|
1108
|
+
$priceValue: Float!
|
|
1109
|
+
) {
|
|
1110
|
+
createStandardProduct(
|
|
1111
|
+
input: {
|
|
1112
|
+
ref: $productRef
|
|
1113
|
+
catalogue: { ref: $productCatalogueRef }
|
|
1114
|
+
type: $productType
|
|
1115
|
+
name: $productName
|
|
1116
|
+
summary: $productSummary
|
|
1117
|
+
gtin: $gtin
|
|
1118
|
+
prices: [
|
|
1119
|
+
{ currency: $priceCurrency, type: "RRP", value: $priceValue }
|
|
1120
|
+
]
|
|
1121
|
+
}
|
|
1122
|
+
) {
|
|
1123
|
+
id
|
|
1124
|
+
ref
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
`;
|
|
1128
|
+
const variables = {
|
|
1129
|
+
productCatalogueRef: params.productCatalogueRef,
|
|
1130
|
+
productRef: params.productRef,
|
|
1131
|
+
productType: params.productType,
|
|
1132
|
+
productName: params.productName,
|
|
1133
|
+
productSummary: params.productSummary,
|
|
1134
|
+
gtin: params.gtin,
|
|
1135
|
+
priceCurrency: params.priceCurrency,
|
|
1136
|
+
priceValue: params.priceValue
|
|
1137
|
+
};
|
|
1138
|
+
return { data: await client.request(query, variables) };
|
|
1139
|
+
},
|
|
1140
|
+
examplePerform: async () => createProductExamplePayload,
|
|
1141
|
+
examplePayload: createProductExamplePayload
|
|
1142
|
+
}) };
|
|
1143
|
+
//#endregion
|
|
1144
|
+
//#region src/actions/index.ts
|
|
1145
|
+
var actions_default = {
|
|
1146
|
+
...customers_default,
|
|
1147
|
+
...misc_default,
|
|
1148
|
+
...products_default
|
|
1149
|
+
};
|
|
1150
|
+
//#endregion
|
|
1151
|
+
//#region src/triggers/index.ts
|
|
1152
|
+
var triggers_default = { pollChangesTrigger: (0, _prismatic_io_spectral.pollingTrigger)({
|
|
1153
|
+
display: {
|
|
1154
|
+
label: "New and Updated Records",
|
|
1155
|
+
description: "Retrieves existing and ongoing orders from Fluent Commerce. Load history once, check for changes on a schedule, or both."
|
|
1156
|
+
},
|
|
1157
|
+
examplePayload: pollChangesTriggerExamplePayload,
|
|
1158
|
+
inputs: pollChangesInputs,
|
|
1159
|
+
triggerResolverSupport: "valid",
|
|
1160
|
+
batchConfig: { batchSize: 50 },
|
|
1161
|
+
triggerResolver: {
|
|
1162
|
+
resolveItems: (_context, { payload }) => resolveFluentOrderChanges(payload.body.data),
|
|
1163
|
+
getNextPaginationState: (_context, { payload }) => payload.paginationState ?? null
|
|
1164
|
+
},
|
|
1165
|
+
perform: async (context, payload, params) => {
|
|
1166
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1167
|
+
const pollState = context.polling.getState() ?? {};
|
|
1168
|
+
const incoming = payload.paginationState;
|
|
1169
|
+
const lastPolledAt = pollState.lastPolledAt || params.lookBackDate || now;
|
|
1170
|
+
const isBackfill = pollState.backfillActive === true || !pollState.lastPolledAt && Boolean(params.lookBackDate);
|
|
1171
|
+
const showNew = isBackfill || params.showNewRecords !== false;
|
|
1172
|
+
const showUpdated = isBackfill || params.showUpdatedRecords !== false;
|
|
1173
|
+
const windowTo = incoming?.windowTo ?? pollState.windowTo ?? now;
|
|
1174
|
+
const cursor = incoming?.after ?? pollState.after ?? null;
|
|
1175
|
+
const isBatching = context.batch?.enabled === true;
|
|
1176
|
+
const { records, truncated, after } = await fetchFluentOrdersInWindow(params.connection, {
|
|
1177
|
+
from: lastPolledAt,
|
|
1178
|
+
to: windowTo,
|
|
1179
|
+
after: cursor
|
|
1180
|
+
}, params.retailerId, isBatching ? 1 : 20);
|
|
1181
|
+
const lastPolledAtDate = new Date(lastPolledAt);
|
|
1182
|
+
const created = [];
|
|
1183
|
+
const updated = [];
|
|
1184
|
+
for (const record of records) {
|
|
1185
|
+
const createValue = record.createdOn;
|
|
1186
|
+
const createdAtDate = typeof createValue === "string" ? new Date(createValue) : null;
|
|
1187
|
+
const isNew = createdAtDate !== null && createdAtDate > lastPolledAtDate;
|
|
1188
|
+
if (isNew && showNew) created.push(record);
|
|
1189
|
+
else if (!isNew && showUpdated) updated.push(record);
|
|
1190
|
+
}
|
|
1191
|
+
if (truncated) {
|
|
1192
|
+
context.polling.setState({
|
|
1193
|
+
lastPolledAt,
|
|
1194
|
+
windowTo,
|
|
1195
|
+
after,
|
|
1196
|
+
...isBackfill ? { backfillActive: true } : {}
|
|
1197
|
+
});
|
|
1198
|
+
if (!isBatching) context.logger.warn(`Polling truncated at the page cap for Fluent orders. The next poll resumes the window ${lastPolledAt} to ${windowTo} from the stored cursor.`);
|
|
1199
|
+
} else context.polling.setState({ lastPolledAt: windowTo });
|
|
1200
|
+
if (context.debug.enabled) context.logger.debug(`Polled Fluent orders: ${records.length} fetched, ${created.length} created, ${updated.length} updated, truncated=${truncated}`);
|
|
1201
|
+
const nextCursor = truncated && after ? {
|
|
1202
|
+
windowTo,
|
|
1203
|
+
after
|
|
1204
|
+
} : null;
|
|
1205
|
+
const totalMatched = created.length + updated.length;
|
|
1206
|
+
return {
|
|
1207
|
+
payload: {
|
|
1208
|
+
...payload,
|
|
1209
|
+
paginationState: nextCursor ?? void 0,
|
|
1210
|
+
body: { data: {
|
|
1211
|
+
created,
|
|
1212
|
+
updated
|
|
1213
|
+
} }
|
|
1214
|
+
},
|
|
1215
|
+
polledNoChanges: totalMatched === 0 && !incoming && (nextCursor === null || !isBatching)
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
}) };
|
|
1219
|
+
//#endregion
|
|
1220
|
+
//#region src/index.ts
|
|
1221
|
+
var src_default = (0, _prismatic_io_spectral.component)({
|
|
1222
|
+
key: "fluent-commerce",
|
|
1223
|
+
documentationUrl: "https://prismatic.io/docs/components/fluent-commerce/",
|
|
1224
|
+
public: true,
|
|
1225
|
+
display: {
|
|
1226
|
+
label: "Fluent Commerce",
|
|
1227
|
+
description: "Manage orders within Fluent Commerce",
|
|
1228
|
+
iconPath: "icon.png",
|
|
1229
|
+
category: "Application Connectors"
|
|
1230
|
+
},
|
|
1231
|
+
actions: actions_default,
|
|
1232
|
+
connections: connections_default,
|
|
1233
|
+
triggers: triggers_default,
|
|
1234
|
+
hooks: { error: _prismatic_io_spectral_http.handleErrors }
|
|
1235
|
+
});
|
|
1236
|
+
//#endregion
|
|
1237
|
+
//#region npm-dist/.entry.ts
|
|
1238
|
+
var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
|
|
1239
|
+
//#endregion
|
|
1240
|
+
module.exports = _entry_default;
|