@prismatic-io/components-duro-plm 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -2
- package/dist/icon.png +0 -0
- package/dist/index.js +672 -0
- package/npm-dist/icon.png +0 -0
- package/npm-dist/index.cjs +1132 -0
- package/npm-dist/index.d.cts +334 -0
- package/package.json +51 -4
|
@@ -0,0 +1,1132 @@
|
|
|
1
|
+
let _prismatic_io_spectral = require("@prismatic-io/spectral");
|
|
2
|
+
let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
|
|
3
|
+
let graphql_request = require("graphql-request");
|
|
4
|
+
var connections_default = [(0, _prismatic_io_spectral.connection)({
|
|
5
|
+
key: "duroApiKey",
|
|
6
|
+
display: {
|
|
7
|
+
label: "API Key",
|
|
8
|
+
description: "Authenticate requests using an API key."
|
|
9
|
+
},
|
|
10
|
+
inputs: {
|
|
11
|
+
username: {
|
|
12
|
+
label: "API Key",
|
|
13
|
+
placeholder: "Enter Duro API Key",
|
|
14
|
+
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0",
|
|
15
|
+
comments: "The API key for the Duro account. Generate an API key in Duro account settings under the Integrations tab.",
|
|
16
|
+
type: "password",
|
|
17
|
+
required: true
|
|
18
|
+
},
|
|
19
|
+
duroEnvironment: {
|
|
20
|
+
label: "Duro Environment",
|
|
21
|
+
placeholder: "Select Duro Environment",
|
|
22
|
+
comments: "The Duro GraphQL endpoint. Select based on data residency requirements: Main (MFG) for standard accounts, ITAR for US government compliance, or EU for European data residency.",
|
|
23
|
+
type: "string",
|
|
24
|
+
required: true,
|
|
25
|
+
model: [
|
|
26
|
+
{
|
|
27
|
+
label: "Main (MFG)",
|
|
28
|
+
value: "https://mfg.duro.app/graphql"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
label: "ITAR",
|
|
32
|
+
value: "https://gov.duro.us/graphql"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: "EU",
|
|
36
|
+
value: "https://eu.duro.app/graphql"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
example: "https://mfg.duro.app/graphql"
|
|
40
|
+
},
|
|
41
|
+
customDuroEnvironment: {
|
|
42
|
+
label: "Custom Duro Environment",
|
|
43
|
+
type: "string",
|
|
44
|
+
required: false,
|
|
45
|
+
placeholder: "Enter custom GraphQL endpoint URL",
|
|
46
|
+
comments: "If provided, this will override the selected Duro Environment. Use for private Duro instances or custom deployments.",
|
|
47
|
+
example: "https://custom-instance.duro.app/graphql"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})];
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/constants.ts
|
|
53
|
+
const GRAPHQL_EXAMPLE = `{
|
|
54
|
+
components(libraryType: GENERAL) {
|
|
55
|
+
connection(
|
|
56
|
+
first: 10
|
|
57
|
+
) {
|
|
58
|
+
totalCount
|
|
59
|
+
edges {
|
|
60
|
+
cursor
|
|
61
|
+
node {
|
|
62
|
+
id
|
|
63
|
+
name
|
|
64
|
+
created
|
|
65
|
+
lastModified
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}`;
|
|
71
|
+
const LOOK_BACK_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
72
|
+
const POLL_RESOURCE_CONFIG = {
|
|
73
|
+
components: {
|
|
74
|
+
query: `
|
|
75
|
+
query PollComponents($first: Int, $after: String, $libraryType: LibraryType, $orderBy: [ComponentsOrderByInput]) {
|
|
76
|
+
components(libraryType: $libraryType, orderBy: $orderBy) {
|
|
77
|
+
connection(first: $first, after: $after) {
|
|
78
|
+
edges {
|
|
79
|
+
cursor
|
|
80
|
+
node {
|
|
81
|
+
id
|
|
82
|
+
name
|
|
83
|
+
created
|
|
84
|
+
lastModified
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
pageInfo {
|
|
88
|
+
hasNextPage
|
|
89
|
+
endCursor
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
`,
|
|
95
|
+
dataPath: ["components", "connection"],
|
|
96
|
+
buildVariables: (first, after) => ({
|
|
97
|
+
first,
|
|
98
|
+
after,
|
|
99
|
+
libraryType: "GENERAL",
|
|
100
|
+
orderBy: [{ lastModified: "desc" }]
|
|
101
|
+
}),
|
|
102
|
+
earlyStop: true
|
|
103
|
+
},
|
|
104
|
+
changeOrders: {
|
|
105
|
+
query: `
|
|
106
|
+
query PollChangeOrders($first: Int, $after: String, $orderBy: [ChangeOrdersOrderByInput]) {
|
|
107
|
+
changeOrders(orderBy: $orderBy) {
|
|
108
|
+
connection(first: $first, after: $after) {
|
|
109
|
+
edges {
|
|
110
|
+
cursor
|
|
111
|
+
node {
|
|
112
|
+
id
|
|
113
|
+
name
|
|
114
|
+
status
|
|
115
|
+
type
|
|
116
|
+
created
|
|
117
|
+
lastModified
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
pageInfo {
|
|
121
|
+
hasNextPage
|
|
122
|
+
endCursor
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
`,
|
|
128
|
+
dataPath: ["changeOrders", "connection"],
|
|
129
|
+
buildVariables: (first, after) => ({
|
|
130
|
+
first,
|
|
131
|
+
after,
|
|
132
|
+
orderBy: [{ lastModified: "desc" }]
|
|
133
|
+
}),
|
|
134
|
+
earlyStop: true
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/util/index.ts
|
|
139
|
+
const validateConnection = (connection) => {
|
|
140
|
+
if (!connections_default.map((c) => c.key).includes(connection.key)) throw new _prismatic_io_spectral.ConnectionError(connection, `Unsupported connection ${connection.key}.`);
|
|
141
|
+
};
|
|
142
|
+
const cleanStringInput = (value) => value ? _prismatic_io_spectral.util.types.toString(value) : void 0;
|
|
143
|
+
const cleanNumberInput = (value) => value ? _prismatic_io_spectral.util.types.toNumber(value) : void 0;
|
|
144
|
+
const getCredentials = (connection) => {
|
|
145
|
+
const url = _prismatic_io_spectral.util.types.toString(connection.fields.customDuroEnvironment).trim() || _prismatic_io_spectral.util.types.toString(connection.fields.duroEnvironment);
|
|
146
|
+
return {
|
|
147
|
+
apiKey: _prismatic_io_spectral.util.types.toString(connection.fields.username),
|
|
148
|
+
url
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
const cleanCodeInput = (value) => value ? _prismatic_io_spectral.util.types.toObject(value) : {};
|
|
152
|
+
const cleanKeyValueListInput = (value) => {
|
|
153
|
+
if (Array.isArray(value)) return _prismatic_io_spectral.util.types.keyValPairListToObject(value);
|
|
154
|
+
return {};
|
|
155
|
+
};
|
|
156
|
+
const parseJsonArray = (value) => {
|
|
157
|
+
if (value) {
|
|
158
|
+
const json = _prismatic_io_spectral.util.types.toObject(value);
|
|
159
|
+
if (!Array.isArray(json)) throw new Error("Expected a JSON array");
|
|
160
|
+
return json;
|
|
161
|
+
}
|
|
162
|
+
return [];
|
|
163
|
+
};
|
|
164
|
+
const mapComponentEdges = (edges) => edges.map((edge) => edge.node);
|
|
165
|
+
const getComponentsList = async (client, query, first, libraryType) => {
|
|
166
|
+
const variables = {
|
|
167
|
+
first,
|
|
168
|
+
libraryType
|
|
169
|
+
};
|
|
170
|
+
const edges = (await client.request(query, variables))?.components?.connection?.edges ?? [];
|
|
171
|
+
return mapComponentEdges(edges);
|
|
172
|
+
};
|
|
173
|
+
const toResourceLabel = (key) => key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, (char) => char.toUpperCase());
|
|
174
|
+
const pollResourceModel = Object.entries(POLL_RESOURCE_CONFIG).map(([value]) => ({
|
|
175
|
+
label: toResourceLabel(value),
|
|
176
|
+
value
|
|
177
|
+
}));
|
|
178
|
+
const readConnection = (data, dataPath) => {
|
|
179
|
+
let current = data;
|
|
180
|
+
for (const key of dataPath) if (current && typeof current === "object") current = current[key];
|
|
181
|
+
else return;
|
|
182
|
+
return current;
|
|
183
|
+
};
|
|
184
|
+
const fetchAllSince = async (client, resourceType, lastPolledAt, options = {}) => {
|
|
185
|
+
const config = POLL_RESOURCE_CONFIG[resourceType];
|
|
186
|
+
if (!config) throw new Error(`Unsupported resource type: ${resourceType}`);
|
|
187
|
+
const { debug, logger } = options;
|
|
188
|
+
const lastPolledAtDate = new Date(lastPolledAt);
|
|
189
|
+
const records = [];
|
|
190
|
+
let after = options.after;
|
|
191
|
+
let page = 0;
|
|
192
|
+
while (page < 50) {
|
|
193
|
+
page += 1;
|
|
194
|
+
const variables = config.buildVariables(100, after);
|
|
195
|
+
const data = await client.request(config.query, variables);
|
|
196
|
+
const connection = readConnection(data, config.dataPath);
|
|
197
|
+
const edges = connection?.edges ?? [];
|
|
198
|
+
let stop = false;
|
|
199
|
+
for (const edge of edges) {
|
|
200
|
+
const node = edge?.node;
|
|
201
|
+
if (!node) continue;
|
|
202
|
+
records.push(node);
|
|
203
|
+
if (config.earlyStop && typeof node.lastModified === "string" && new Date(node.lastModified) <= lastPolledAtDate) {
|
|
204
|
+
stop = true;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (stop) return {
|
|
209
|
+
records,
|
|
210
|
+
truncated: false
|
|
211
|
+
};
|
|
212
|
+
const pageInfo = connection?.pageInfo;
|
|
213
|
+
if (!pageInfo?.hasNextPage || !pageInfo.endCursor) return {
|
|
214
|
+
records,
|
|
215
|
+
truncated: false
|
|
216
|
+
};
|
|
217
|
+
after = pageInfo.endCursor;
|
|
218
|
+
}
|
|
219
|
+
if (debug && logger) logger.warn(`Reached MAX_POLL_PAGES (50) while polling ${resourceType}; results truncated. The next poll resumes from the held cursor.`);
|
|
220
|
+
return {
|
|
221
|
+
records,
|
|
222
|
+
truncated: true,
|
|
223
|
+
endCursor: after
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
const resolvePollingStart = (state, lookBackDate, now) => ({
|
|
227
|
+
since: state?.lastPolledAt ?? (lookBackDate || now),
|
|
228
|
+
isBackfill: state?.backfillActive === true || !state?.lastPolledAt && Boolean(lookBackDate)
|
|
229
|
+
});
|
|
230
|
+
const resolvePollingStream = (state, resourceType, now) => {
|
|
231
|
+
return Boolean(state?.endCursor) && Boolean(state?.streamStartedAt) && state?.pollResourceType === resourceType ? {
|
|
232
|
+
streamStartedAt: state?.streamStartedAt,
|
|
233
|
+
endCursor: state?.endCursor
|
|
234
|
+
} : { streamStartedAt: now };
|
|
235
|
+
};
|
|
236
|
+
const nextPollingState = (round, endCursor) => endCursor ? {
|
|
237
|
+
lastPolledAt: round.lastPolledAt,
|
|
238
|
+
endCursor,
|
|
239
|
+
streamStartedAt: round.stream.streamStartedAt,
|
|
240
|
+
pollResourceType: round.resourceType,
|
|
241
|
+
...round.isBackfill ? { backfillActive: true } : {}
|
|
242
|
+
} : { lastPolledAt: round.stream.streamStartedAt };
|
|
243
|
+
const lookBackDateClean = (value) => {
|
|
244
|
+
if (value === void 0 || value === null || typeof value === "string" && value.trim() === "") return "";
|
|
245
|
+
const raw = typeof value === "string" ? value.trim() : String(value);
|
|
246
|
+
const match = typeof value === "string" ? raw.match(LOOK_BACK_DATE_PATTERN) : null;
|
|
247
|
+
if (!match) throw new Error(`Look-back Date must be a date in YYYY-MM-DD format. Received: ${raw}`);
|
|
248
|
+
const [, yearStr, monthStr, dayStr] = match;
|
|
249
|
+
const year = Number(yearStr);
|
|
250
|
+
const month = Number(monthStr);
|
|
251
|
+
const day = Number(dayStr);
|
|
252
|
+
const parsed = new Date(Date.UTC(year, month - 1, day));
|
|
253
|
+
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}`);
|
|
254
|
+
if (parsed.getTime() > Date.now()) throw new Error(`Look-back Date cannot be a future date. Received: ${raw}`);
|
|
255
|
+
return parsed.toISOString();
|
|
256
|
+
};
|
|
257
|
+
const classifyRecords = (records, lastPolledAt, options) => {
|
|
258
|
+
const lastPolledAtDate = new Date(lastPolledAt);
|
|
259
|
+
const created = [];
|
|
260
|
+
const updated = [];
|
|
261
|
+
for (const record of records) {
|
|
262
|
+
const createdDate = typeof record.created === "string" ? new Date(record.created) : null;
|
|
263
|
+
const lastModifiedDate = typeof record.lastModified === "string" ? new Date(record.lastModified) : null;
|
|
264
|
+
const isNew = createdDate !== null && createdDate > lastPolledAtDate;
|
|
265
|
+
const isUpdated = !isNew && lastModifiedDate !== null && lastModifiedDate > lastPolledAtDate;
|
|
266
|
+
if (isNew && (options.isBackfill || options.showNewRecords)) created.push(record);
|
|
267
|
+
else if (isUpdated && (options.isBackfill || options.showUpdatedRecords)) updated.push(record);
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
created,
|
|
271
|
+
updated
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
const resolveRecordChanges = (data) => {
|
|
275
|
+
const changesObject = data ?? {};
|
|
276
|
+
return [...(changesObject.created ?? []).map((record) => ({
|
|
277
|
+
changeType: "created",
|
|
278
|
+
record
|
|
279
|
+
})), ...(changesObject.updated ?? []).map((record) => ({
|
|
280
|
+
changeType: "updated",
|
|
281
|
+
record
|
|
282
|
+
}))];
|
|
283
|
+
};
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region src/client.ts
|
|
286
|
+
const createDuroClient = (connection, debug) => {
|
|
287
|
+
validateConnection(connection);
|
|
288
|
+
const { apiKey, url } = getCredentials(connection);
|
|
289
|
+
return new graphql_request.GraphQLClient(url, {
|
|
290
|
+
headers: { apiToken: apiKey },
|
|
291
|
+
requestMiddleware: (request) => {
|
|
292
|
+
if (debug) console.log(JSON.stringify(request));
|
|
293
|
+
return request;
|
|
294
|
+
},
|
|
295
|
+
responseMiddleware: (response) => {
|
|
296
|
+
if (debug) console.log(JSON.stringify(response));
|
|
297
|
+
return response;
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
};
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/inputs/common.ts
|
|
303
|
+
const connection = (0, _prismatic_io_spectral.input)({
|
|
304
|
+
label: "Connection",
|
|
305
|
+
type: "connection",
|
|
306
|
+
required: true,
|
|
307
|
+
comments: "The Duro PLM connection to use."
|
|
308
|
+
});
|
|
309
|
+
const first = (0, _prismatic_io_spectral.input)({
|
|
310
|
+
label: "First N Items",
|
|
311
|
+
comments: "The number of items to return.",
|
|
312
|
+
example: "10",
|
|
313
|
+
placeholder: "Enter number of items",
|
|
314
|
+
type: "string",
|
|
315
|
+
required: false,
|
|
316
|
+
clean: cleanNumberInput
|
|
317
|
+
});
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/inputs/company.ts
|
|
320
|
+
const listCompanyUsersInputs = { connection };
|
|
321
|
+
//#endregion
|
|
322
|
+
//#region src/examplePayloads.ts
|
|
323
|
+
const getCurrentUserExamplePayload = { data: { userById: {
|
|
324
|
+
lastName: "Smith",
|
|
325
|
+
email: "john.smith@example.com",
|
|
326
|
+
firstName: "John",
|
|
327
|
+
id: "1234567890abcdef12345678",
|
|
328
|
+
primaryCompany: {
|
|
329
|
+
id: "abcdef1234567890abcdef12",
|
|
330
|
+
name: "ExampleCorp"
|
|
331
|
+
}
|
|
332
|
+
} } };
|
|
333
|
+
const listCompanyUsersExamplePayload = { data: {
|
|
334
|
+
id: "abcdef1234567890abcdef12",
|
|
335
|
+
name: "ExampleCorp",
|
|
336
|
+
users: [{
|
|
337
|
+
email: "john.doe@example.com",
|
|
338
|
+
id: "1234567890abcdef12345678",
|
|
339
|
+
firstName: "John",
|
|
340
|
+
lastName: "Doe",
|
|
341
|
+
created: "2024-06-14T14:57:37.227Z",
|
|
342
|
+
role: "ADMINISTRATOR",
|
|
343
|
+
title: "CEO",
|
|
344
|
+
lastLogin: "2024-06-24T16:11:02.889Z"
|
|
345
|
+
}]
|
|
346
|
+
} };
|
|
347
|
+
const getComponentByIdExamplePayload = { data: { componentsByIds: [{
|
|
348
|
+
id: "abcdef1234567890abcdef12",
|
|
349
|
+
cpn: { displayValue: "123-45678" },
|
|
350
|
+
created: "2024-06-14T14:58:29.791Z",
|
|
351
|
+
category: "Integrated Circuit",
|
|
352
|
+
archived: false,
|
|
353
|
+
customSpecs: [],
|
|
354
|
+
description: "A high-performance integrated circuit for advanced applications.",
|
|
355
|
+
documentLinks: [],
|
|
356
|
+
eid: "20-4567-B2",
|
|
357
|
+
family: "IC",
|
|
358
|
+
images: [{
|
|
359
|
+
mime: "JPEG",
|
|
360
|
+
creator: { email: "john.doe@example.com" },
|
|
361
|
+
name: "ic_image.jpg",
|
|
362
|
+
src: "https://example.com/ic_image.jpg"
|
|
363
|
+
}],
|
|
364
|
+
legacyCpn: "123-45678",
|
|
365
|
+
lastModified: "2024-06-14T14:58:30.229Z",
|
|
366
|
+
manufacturers: [],
|
|
367
|
+
name: "High-Performance IC",
|
|
368
|
+
primarySource: {
|
|
369
|
+
dpn: "DP1234",
|
|
370
|
+
distributor: "Distributor Inc.",
|
|
371
|
+
manufacturer: "IC Manufacturer Ltd.",
|
|
372
|
+
minQuantity: 10,
|
|
373
|
+
mpn: "MP1234",
|
|
374
|
+
unitPrice: 5.99
|
|
375
|
+
},
|
|
376
|
+
specs: [],
|
|
377
|
+
status: "PRODUCTION",
|
|
378
|
+
revisionValue: "1",
|
|
379
|
+
workflowState: "Approved",
|
|
380
|
+
vendorId: "V1234",
|
|
381
|
+
creator: {
|
|
382
|
+
id: "1234567890abcdef12345678",
|
|
383
|
+
email: "john.doe@example.com",
|
|
384
|
+
firstName: "John",
|
|
385
|
+
lastName: "Doe"
|
|
386
|
+
},
|
|
387
|
+
revisionHistory: [{
|
|
388
|
+
id: "abcdef1234567890abcdef34",
|
|
389
|
+
cpn: { displayValue: "123-45678" },
|
|
390
|
+
revisionValue: "1"
|
|
391
|
+
}],
|
|
392
|
+
children: [{ component: { id: "abcdef1234567890abcdef56" } }, { component: { id: "abcdef1234567890abcdef78" } }],
|
|
393
|
+
modified: false,
|
|
394
|
+
imageIds: ["abcdef1234567890abcdef90"]
|
|
395
|
+
}] } };
|
|
396
|
+
const createChangeOrderExamplePayload = { data: { createChangeOrder: {
|
|
397
|
+
id: "abcdef1234567890abcdef12",
|
|
398
|
+
con: { displayValue: "ECO-12345" },
|
|
399
|
+
description: "Initial creation of the change order for testing purposes.",
|
|
400
|
+
name: "Initial Change Order",
|
|
401
|
+
status: "DRAFT",
|
|
402
|
+
type: "ECO",
|
|
403
|
+
created: "2024-06-24T22:31:27.808Z",
|
|
404
|
+
creator: {
|
|
405
|
+
email: "john.doe@example.com",
|
|
406
|
+
id: "1234567890abcdef12345678",
|
|
407
|
+
firstName: "John",
|
|
408
|
+
lastName: "Doe"
|
|
409
|
+
}
|
|
410
|
+
} } };
|
|
411
|
+
const listChangeOrdersExamplePayload = { data: { changeOrders: { connection: { edges: [{ node: {
|
|
412
|
+
con: {
|
|
413
|
+
id: "abcdef1234567890abcdef12",
|
|
414
|
+
displayValue: "ECO-12345"
|
|
415
|
+
},
|
|
416
|
+
id: "abcdef1234567890abcdef34",
|
|
417
|
+
name: "PCB Revision for Rev B Release",
|
|
418
|
+
type: "ECO",
|
|
419
|
+
description: "Engineering change order to update PCB layout for Rev B manufacturing release.",
|
|
420
|
+
documentLinks: [],
|
|
421
|
+
status: "DRAFT",
|
|
422
|
+
resolution: "NONE",
|
|
423
|
+
erpOptions: null,
|
|
424
|
+
created: "2024-06-24T22:31:27.808Z",
|
|
425
|
+
creator: {
|
|
426
|
+
email: "john.doe@example.com",
|
|
427
|
+
id: "1234567890abcdef12345678",
|
|
428
|
+
firstName: "John",
|
|
429
|
+
lastName: "Doe"
|
|
430
|
+
},
|
|
431
|
+
approvalType: "FIRST_IN",
|
|
432
|
+
lastModified: "2024-06-24T22:31:27.808Z"
|
|
433
|
+
} }] } } } };
|
|
434
|
+
const listComponentsExamplePayload = { data: [{
|
|
435
|
+
id: "666c5a8828e82100081595b0",
|
|
436
|
+
name: "CONN HEADER 10POS DUAL .05\", Keying Shroud, SMD",
|
|
437
|
+
mass: null,
|
|
438
|
+
created: "2024-06-14T14:58:16.638Z",
|
|
439
|
+
lastModified: "2024-06-14T14:58:18.069Z"
|
|
440
|
+
}] };
|
|
441
|
+
const rawRequestExamplePayload = { data: { componentsByIds: [{
|
|
442
|
+
id: "abcdef1234567890abcdef12",
|
|
443
|
+
name: "High-Performance IC"
|
|
444
|
+
}] } };
|
|
445
|
+
const pollChangesExamplePayload = {
|
|
446
|
+
payload: {
|
|
447
|
+
headers: {},
|
|
448
|
+
queryParameters: {},
|
|
449
|
+
rawBody: {
|
|
450
|
+
data: "",
|
|
451
|
+
contentType: "application/json"
|
|
452
|
+
},
|
|
453
|
+
body: { data: {
|
|
454
|
+
created: [{
|
|
455
|
+
id: "666c5a8828e82100081595b0",
|
|
456
|
+
name: "High-Performance IC",
|
|
457
|
+
created: "2024-06-14T14:58:16.638Z",
|
|
458
|
+
lastModified: "2024-06-14T14:58:16.638Z"
|
|
459
|
+
}],
|
|
460
|
+
updated: [{
|
|
461
|
+
id: "666c5a9528e821000815990e",
|
|
462
|
+
name: "Precision Resistor 10k",
|
|
463
|
+
created: "2024-06-10T09:12:04.118Z",
|
|
464
|
+
lastModified: "2024-06-14T14:58:18.069Z"
|
|
465
|
+
}]
|
|
466
|
+
} },
|
|
467
|
+
pathFragment: "",
|
|
468
|
+
webhookUrls: { "Polling Flow": "https://hooks.example.com/trigger/EXAMPLE" },
|
|
469
|
+
webhookApiKeys: { "Polling Flow": ["example-api-key"] },
|
|
470
|
+
invokeUrl: "https://hooks.example.com/trigger/EXAMPLE",
|
|
471
|
+
executionId: "SW5zdGFuY2VFeGVjdXRpb246MTIzNDU=",
|
|
472
|
+
customer: {
|
|
473
|
+
id: "Q3VzdG9tZXI6MTIzNDU=",
|
|
474
|
+
externalId: "example-customer-external-id",
|
|
475
|
+
name: "Example Customer"
|
|
476
|
+
},
|
|
477
|
+
instance: {
|
|
478
|
+
id: "SW5zdGFuY2U6MTIzNDU=",
|
|
479
|
+
name: "Example Instance"
|
|
480
|
+
},
|
|
481
|
+
user: {
|
|
482
|
+
id: "VXNlcjoxMjM0NQ==",
|
|
483
|
+
externalId: "example-user-external-id",
|
|
484
|
+
name: "Example User",
|
|
485
|
+
email: "user@example.com"
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
polledNoChanges: false
|
|
489
|
+
};
|
|
490
|
+
//#endregion
|
|
491
|
+
//#region src/actions/company/index.ts
|
|
492
|
+
var company_default = { listCompanyUsers: (0, _prismatic_io_spectral.action)({
|
|
493
|
+
display: {
|
|
494
|
+
label: "List Company Users",
|
|
495
|
+
description: "Retrieves account information for each user in the company library."
|
|
496
|
+
},
|
|
497
|
+
inputs: listCompanyUsersInputs,
|
|
498
|
+
perform: async (context, { connection }) => {
|
|
499
|
+
const client = createDuroClient(connection, context.debug.enabled);
|
|
500
|
+
const query = graphql_request.gql`
|
|
501
|
+
query UserById {
|
|
502
|
+
userById {
|
|
503
|
+
primaryCompany {
|
|
504
|
+
id
|
|
505
|
+
name
|
|
506
|
+
users {
|
|
507
|
+
email
|
|
508
|
+
id
|
|
509
|
+
firstName
|
|
510
|
+
lastName
|
|
511
|
+
created
|
|
512
|
+
role
|
|
513
|
+
title
|
|
514
|
+
lastLogin
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
`;
|
|
520
|
+
return { data: (await client.request(query)).userById.primaryCompany };
|
|
521
|
+
},
|
|
522
|
+
examplePayload: listCompanyUsersExamplePayload
|
|
523
|
+
}) };
|
|
524
|
+
//#endregion
|
|
525
|
+
//#region src/inputs/components.ts
|
|
526
|
+
const libraryType = (0, _prismatic_io_spectral.input)({
|
|
527
|
+
label: "Library Type",
|
|
528
|
+
comments: "The type of library to query. Company (GENERAL) contains shared production components, while Sandbox (PERSONAL) contains personal or test components.",
|
|
529
|
+
example: "GENERAL",
|
|
530
|
+
placeholder: "Select Library Type",
|
|
531
|
+
type: "string",
|
|
532
|
+
required: true,
|
|
533
|
+
clean: cleanStringInput,
|
|
534
|
+
model: [{
|
|
535
|
+
label: "Company",
|
|
536
|
+
value: "GENERAL"
|
|
537
|
+
}, {
|
|
538
|
+
label: "Sandbox",
|
|
539
|
+
value: "PERSONAL"
|
|
540
|
+
}]
|
|
541
|
+
});
|
|
542
|
+
const componentId = (0, _prismatic_io_spectral.input)({
|
|
543
|
+
label: "Component ID",
|
|
544
|
+
comments: "The unique identifier for the component to retrieve.",
|
|
545
|
+
type: "string",
|
|
546
|
+
required: true,
|
|
547
|
+
example: "666c5a9528e821000815990e",
|
|
548
|
+
placeholder: "Enter Component ID",
|
|
549
|
+
clean: cleanStringInput,
|
|
550
|
+
dataSource: "selectComponent"
|
|
551
|
+
});
|
|
552
|
+
const listComponentsInputs = {
|
|
553
|
+
connection,
|
|
554
|
+
libraryType,
|
|
555
|
+
first
|
|
556
|
+
};
|
|
557
|
+
const getComponentByIdInputs = {
|
|
558
|
+
connection,
|
|
559
|
+
componentId
|
|
560
|
+
};
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/actions/components/index.ts
|
|
563
|
+
var components_default$1 = {
|
|
564
|
+
getComponentById: (0, _prismatic_io_spectral.action)({
|
|
565
|
+
display: {
|
|
566
|
+
label: "Get Component by ID",
|
|
567
|
+
description: "Get a specific component by a unique identifier"
|
|
568
|
+
},
|
|
569
|
+
inputs: getComponentByIdInputs,
|
|
570
|
+
perform: async (context, { connection, componentId }) => {
|
|
571
|
+
const client = createDuroClient(connection, context.debug.enabled);
|
|
572
|
+
const query = graphql_request.gql`
|
|
573
|
+
query ComponentsByIds($ids: [ID]) {
|
|
574
|
+
componentsByIds(ids: $ids) {
|
|
575
|
+
id
|
|
576
|
+
cpn {
|
|
577
|
+
displayValue
|
|
578
|
+
}
|
|
579
|
+
created
|
|
580
|
+
category
|
|
581
|
+
archived
|
|
582
|
+
customSpecs {
|
|
583
|
+
key
|
|
584
|
+
specId
|
|
585
|
+
value
|
|
586
|
+
}
|
|
587
|
+
description
|
|
588
|
+
documentLinks {
|
|
589
|
+
document {
|
|
590
|
+
src
|
|
591
|
+
name
|
|
592
|
+
mime
|
|
593
|
+
id
|
|
594
|
+
archived
|
|
595
|
+
url
|
|
596
|
+
}
|
|
597
|
+
specs {
|
|
598
|
+
status
|
|
599
|
+
type
|
|
600
|
+
revision
|
|
601
|
+
lastModified
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
eid
|
|
605
|
+
family
|
|
606
|
+
images {
|
|
607
|
+
mime
|
|
608
|
+
creator {
|
|
609
|
+
email
|
|
610
|
+
}
|
|
611
|
+
name
|
|
612
|
+
src
|
|
613
|
+
}
|
|
614
|
+
legacyCpn
|
|
615
|
+
lastModified
|
|
616
|
+
manufacturers {
|
|
617
|
+
name
|
|
618
|
+
description
|
|
619
|
+
mpn {
|
|
620
|
+
key
|
|
621
|
+
src
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
name
|
|
625
|
+
primarySource {
|
|
626
|
+
dpn
|
|
627
|
+
distributor
|
|
628
|
+
manufacturer
|
|
629
|
+
minQuantity
|
|
630
|
+
mpn
|
|
631
|
+
unitPrice
|
|
632
|
+
}
|
|
633
|
+
specs {
|
|
634
|
+
key
|
|
635
|
+
value
|
|
636
|
+
}
|
|
637
|
+
status
|
|
638
|
+
revisionValue
|
|
639
|
+
workflowState
|
|
640
|
+
vendorId
|
|
641
|
+
creator {
|
|
642
|
+
id
|
|
643
|
+
email
|
|
644
|
+
firstName
|
|
645
|
+
lastName
|
|
646
|
+
}
|
|
647
|
+
revisionHistory {
|
|
648
|
+
id
|
|
649
|
+
cpn {
|
|
650
|
+
displayValue
|
|
651
|
+
}
|
|
652
|
+
revisionValue
|
|
653
|
+
}
|
|
654
|
+
children {
|
|
655
|
+
component {
|
|
656
|
+
id
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
modified
|
|
660
|
+
imageIds
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
`;
|
|
664
|
+
const variables = { ids: [componentId] };
|
|
665
|
+
return { data: await client.request(query, variables) };
|
|
666
|
+
},
|
|
667
|
+
examplePayload: getComponentByIdExamplePayload
|
|
668
|
+
}),
|
|
669
|
+
listComponents: (0, _prismatic_io_spectral.action)({
|
|
670
|
+
display: {
|
|
671
|
+
label: "List Components",
|
|
672
|
+
description: "Retrieves a list of components."
|
|
673
|
+
},
|
|
674
|
+
inputs: listComponentsInputs,
|
|
675
|
+
perform: async (context, { connection, libraryType, first }) => {
|
|
676
|
+
return { data: await getComponentsList(createDuroClient(connection, context.debug.enabled), graphql_request.gql`
|
|
677
|
+
query Components($first: Int, $libraryType: LibraryType) {
|
|
678
|
+
components(libraryType: $libraryType) {
|
|
679
|
+
connection(first: $first) {
|
|
680
|
+
edges {
|
|
681
|
+
node {
|
|
682
|
+
id
|
|
683
|
+
name
|
|
684
|
+
mass
|
|
685
|
+
created
|
|
686
|
+
lastModified
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
`, first ?? 100, libraryType ?? "GENERAL") };
|
|
693
|
+
},
|
|
694
|
+
examplePayload: listComponentsExamplePayload
|
|
695
|
+
})
|
|
696
|
+
};
|
|
697
|
+
const rawRequestInputs = {
|
|
698
|
+
connection,
|
|
699
|
+
query: (0, _prismatic_io_spectral.input)({
|
|
700
|
+
label: "Query or Mutation",
|
|
701
|
+
type: "code",
|
|
702
|
+
required: true,
|
|
703
|
+
language: "graphql",
|
|
704
|
+
comments: "GraphQL query or mutation to execute against the Duro API. See the Duro GraphQL API documentation for available queries and mutations.",
|
|
705
|
+
placeholder: "Enter GraphQL query or mutation",
|
|
706
|
+
default: GRAPHQL_EXAMPLE,
|
|
707
|
+
example: GRAPHQL_EXAMPLE,
|
|
708
|
+
clean: cleanStringInput
|
|
709
|
+
}),
|
|
710
|
+
variables: (0, _prismatic_io_spectral.input)({
|
|
711
|
+
label: "Variables",
|
|
712
|
+
type: "string",
|
|
713
|
+
required: false,
|
|
714
|
+
collection: "keyvaluelist",
|
|
715
|
+
comments: "GraphQL variables to pass to the query or mutation. Each variable should be a key-value pair.",
|
|
716
|
+
example: "{\"userId\": \"12345\", \"status\": \"active\"}",
|
|
717
|
+
placeholder: "Enter key-value pairs",
|
|
718
|
+
clean: cleanKeyValueListInput
|
|
719
|
+
}),
|
|
720
|
+
variablesObject: (0, _prismatic_io_spectral.input)({
|
|
721
|
+
label: "Variables Object",
|
|
722
|
+
type: "code",
|
|
723
|
+
comments: "Alternative way to provide GraphQL variables as a JSON object. Use this instead of the Variables field for complex nested variables.",
|
|
724
|
+
placeholder: "Enter GraphQL variables as JSON",
|
|
725
|
+
example: JSON.stringify({
|
|
726
|
+
key1: "value1",
|
|
727
|
+
key2: "value2"
|
|
728
|
+
}, null, 2),
|
|
729
|
+
language: "json",
|
|
730
|
+
required: false,
|
|
731
|
+
clean: cleanCodeInput
|
|
732
|
+
})
|
|
733
|
+
};
|
|
734
|
+
//#endregion
|
|
735
|
+
//#region src/actions/misc/index.ts
|
|
736
|
+
var misc_default = { rawRequest: (0, _prismatic_io_spectral.action)({
|
|
737
|
+
display: {
|
|
738
|
+
label: "Raw Request",
|
|
739
|
+
description: "Make a generic request to the Duro API"
|
|
740
|
+
},
|
|
741
|
+
inputs: rawRequestInputs,
|
|
742
|
+
perform: async (context, { connection, query, variables, variablesObject }) => {
|
|
743
|
+
return { data: await createDuroClient(connection, context.debug.enabled).request(query ?? "", {
|
|
744
|
+
...variables,
|
|
745
|
+
...variablesObject
|
|
746
|
+
}) };
|
|
747
|
+
},
|
|
748
|
+
examplePayload: rawRequestExamplePayload
|
|
749
|
+
}) };
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region src/inputs/orders.ts
|
|
752
|
+
const name = (0, _prismatic_io_spectral.input)({
|
|
753
|
+
label: "Name",
|
|
754
|
+
type: "string",
|
|
755
|
+
comments: "The name of the change order to create.",
|
|
756
|
+
example: "ECO-2024-001: Update Component Materials",
|
|
757
|
+
placeholder: "Enter change order name",
|
|
758
|
+
required: true,
|
|
759
|
+
clean: cleanStringInput
|
|
760
|
+
});
|
|
761
|
+
const description = (0, _prismatic_io_spectral.input)({
|
|
762
|
+
label: "Description",
|
|
763
|
+
type: "text",
|
|
764
|
+
required: false,
|
|
765
|
+
comments: "A detailed description of the change order, including the reason for the change and expected impact.",
|
|
766
|
+
example: "Replace aluminum housing with stainless steel to improve corrosion resistance in marine environments.",
|
|
767
|
+
placeholder: "Enter change order description",
|
|
768
|
+
clean: cleanStringInput
|
|
769
|
+
});
|
|
770
|
+
const type = (0, _prismatic_io_spectral.input)({
|
|
771
|
+
label: "Type",
|
|
772
|
+
type: "string",
|
|
773
|
+
required: true,
|
|
774
|
+
comments: "The type of change order to create. ECO (Engineering Change Order), MCO (Manufacturing Change Order), or DCO (Document Change Order).",
|
|
775
|
+
clean: cleanStringInput,
|
|
776
|
+
default: "ECO",
|
|
777
|
+
placeholder: "Select change order type",
|
|
778
|
+
model: [
|
|
779
|
+
{
|
|
780
|
+
label: "ECO (Engineering Change Order)",
|
|
781
|
+
value: "ECO"
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
label: "MCO (Manufacturing Change Order)",
|
|
785
|
+
value: "MCO"
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
label: "DCO (Document Change Order)",
|
|
789
|
+
value: "DCO"
|
|
790
|
+
}
|
|
791
|
+
],
|
|
792
|
+
example: "ECO"
|
|
793
|
+
});
|
|
794
|
+
const orderBy = (0, _prismatic_io_spectral.input)({
|
|
795
|
+
label: "Order By",
|
|
796
|
+
comments: "The field and direction to sort the change orders by. Results will be returned in the specified order.",
|
|
797
|
+
example: "[{\"con\": \"asc\"}]",
|
|
798
|
+
placeholder: "Select sort order",
|
|
799
|
+
type: "string",
|
|
800
|
+
required: false,
|
|
801
|
+
clean: parseJsonArray,
|
|
802
|
+
model: [
|
|
803
|
+
{
|
|
804
|
+
label: "ID: Ascending",
|
|
805
|
+
value: "[{\"con\": \"asc\"}]"
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
label: "ID: Descending",
|
|
809
|
+
value: "[{\"con\": \"desc\"}]"
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
label: "Last Modified: Ascending",
|
|
813
|
+
value: "[{\"lastModified\": \"asc\"}]"
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
label: "Last Modified: Descending",
|
|
817
|
+
value: "[{\"lastModified\": \"desc\"}]"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
label: "Name: Ascending",
|
|
821
|
+
value: "[{\"name\": \"asc\"}]"
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
label: "Name: Descending",
|
|
825
|
+
value: "[{\"name\": \"desc\"}]"
|
|
826
|
+
}
|
|
827
|
+
]
|
|
828
|
+
});
|
|
829
|
+
const createChangeOrderInputs = {
|
|
830
|
+
connection,
|
|
831
|
+
name,
|
|
832
|
+
description,
|
|
833
|
+
type
|
|
834
|
+
};
|
|
835
|
+
const listChangeOrdersInputs = {
|
|
836
|
+
connection,
|
|
837
|
+
orderBy,
|
|
838
|
+
first
|
|
839
|
+
};
|
|
840
|
+
//#endregion
|
|
841
|
+
//#region src/actions/orders/createChangeOrder.ts
|
|
842
|
+
const createChangeOrder = (0, _prismatic_io_spectral.action)({
|
|
843
|
+
display: {
|
|
844
|
+
label: "Create Change Order",
|
|
845
|
+
description: "Creates a draft change order."
|
|
846
|
+
},
|
|
847
|
+
inputs: createChangeOrderInputs,
|
|
848
|
+
perform: async (context, { connection, name, description, type }) => {
|
|
849
|
+
const client = createDuroClient(connection, context.debug.enabled);
|
|
850
|
+
const query = graphql_request.gql`
|
|
851
|
+
mutation CreateChangeOrder($input: CreateChangeOrderInput) {
|
|
852
|
+
createChangeOrder(input: $input) {
|
|
853
|
+
id
|
|
854
|
+
con {
|
|
855
|
+
displayValue
|
|
856
|
+
}
|
|
857
|
+
description
|
|
858
|
+
name
|
|
859
|
+
status
|
|
860
|
+
type
|
|
861
|
+
created
|
|
862
|
+
creator {
|
|
863
|
+
email
|
|
864
|
+
id
|
|
865
|
+
firstName
|
|
866
|
+
lastName
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
`;
|
|
871
|
+
const variables = { input: {
|
|
872
|
+
name,
|
|
873
|
+
description,
|
|
874
|
+
type
|
|
875
|
+
} };
|
|
876
|
+
return { data: await client.request(query, variables) };
|
|
877
|
+
},
|
|
878
|
+
examplePayload: createChangeOrderExamplePayload
|
|
879
|
+
});
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/actions/orders/index.ts
|
|
882
|
+
var orders_default = {
|
|
883
|
+
listChangeOrders: (0, _prismatic_io_spectral.action)({
|
|
884
|
+
display: {
|
|
885
|
+
label: "List Change Orders",
|
|
886
|
+
description: "Retrieves a list of change orders."
|
|
887
|
+
},
|
|
888
|
+
inputs: listChangeOrdersInputs,
|
|
889
|
+
perform: async (context, { connection, orderBy, first }) => {
|
|
890
|
+
const client = createDuroClient(connection, context.debug.enabled);
|
|
891
|
+
const query = graphql_request.gql`
|
|
892
|
+
query ChangeOrders($first: Int, $orderBy: [ChangeOrdersOrderByInput]) {
|
|
893
|
+
changeOrders(orderBy: $orderBy) {
|
|
894
|
+
connection(first: $first) {
|
|
895
|
+
edges {
|
|
896
|
+
node {
|
|
897
|
+
con {
|
|
898
|
+
id
|
|
899
|
+
displayValue
|
|
900
|
+
}
|
|
901
|
+
id
|
|
902
|
+
name
|
|
903
|
+
type
|
|
904
|
+
description
|
|
905
|
+
documentLinks {
|
|
906
|
+
document {
|
|
907
|
+
id
|
|
908
|
+
size
|
|
909
|
+
src
|
|
910
|
+
name
|
|
911
|
+
url
|
|
912
|
+
status
|
|
913
|
+
created
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
status
|
|
917
|
+
resolution
|
|
918
|
+
erpOptions {
|
|
919
|
+
effectivity {
|
|
920
|
+
endDate
|
|
921
|
+
startDate
|
|
922
|
+
}
|
|
923
|
+
itemType {
|
|
924
|
+
value
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
created
|
|
928
|
+
creator {
|
|
929
|
+
email
|
|
930
|
+
id
|
|
931
|
+
firstName
|
|
932
|
+
lastName
|
|
933
|
+
}
|
|
934
|
+
approvalType
|
|
935
|
+
lastModified
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
`;
|
|
942
|
+
const variables = {
|
|
943
|
+
first: first ?? 100,
|
|
944
|
+
orderBy
|
|
945
|
+
};
|
|
946
|
+
return { data: await client.request(query, variables) };
|
|
947
|
+
},
|
|
948
|
+
examplePayload: listChangeOrdersExamplePayload
|
|
949
|
+
}),
|
|
950
|
+
createChangeOrder
|
|
951
|
+
};
|
|
952
|
+
//#endregion
|
|
953
|
+
//#region src/inputs/users.ts
|
|
954
|
+
const getCurrentUserInputs = { connection };
|
|
955
|
+
//#endregion
|
|
956
|
+
//#region src/actions/users/index.ts
|
|
957
|
+
var users_default = { getCurrentUser: (0, _prismatic_io_spectral.action)({
|
|
958
|
+
display: {
|
|
959
|
+
label: "Get Current User",
|
|
960
|
+
description: "Get information about the currently authenticated user"
|
|
961
|
+
},
|
|
962
|
+
inputs: getCurrentUserInputs,
|
|
963
|
+
perform: async (context, { connection }) => {
|
|
964
|
+
const client = createDuroClient(connection, context.debug.enabled);
|
|
965
|
+
const query = graphql_request.gql`
|
|
966
|
+
query UserById {
|
|
967
|
+
userById {
|
|
968
|
+
lastName
|
|
969
|
+
email
|
|
970
|
+
firstName
|
|
971
|
+
id
|
|
972
|
+
primaryCompany {
|
|
973
|
+
id
|
|
974
|
+
name
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
`;
|
|
979
|
+
return { data: await client.request(query) };
|
|
980
|
+
},
|
|
981
|
+
examplePayload: getCurrentUserExamplePayload
|
|
982
|
+
}) };
|
|
983
|
+
//#endregion
|
|
984
|
+
//#region src/actions/index.ts
|
|
985
|
+
var actions_default = {
|
|
986
|
+
...company_default,
|
|
987
|
+
...components_default$1,
|
|
988
|
+
...misc_default,
|
|
989
|
+
...orders_default,
|
|
990
|
+
...users_default
|
|
991
|
+
};
|
|
992
|
+
//#endregion
|
|
993
|
+
//#region src/inputs/dataSources.ts
|
|
994
|
+
const selectComponentInputs = listComponentsInputs;
|
|
995
|
+
//#endregion
|
|
996
|
+
//#region src/dataSources/index.ts
|
|
997
|
+
var dataSources_default = { selectComponent: (0, _prismatic_io_spectral.dataSource)({
|
|
998
|
+
display: {
|
|
999
|
+
label: "Select Component",
|
|
1000
|
+
description: "A picklist of components in your library."
|
|
1001
|
+
},
|
|
1002
|
+
inputs: selectComponentInputs,
|
|
1003
|
+
dataSourceType: "picklist",
|
|
1004
|
+
perform: async (_context, { connection, libraryType, first }) => {
|
|
1005
|
+
return { result: (await getComponentsList(createDuroClient(connection, false), graphql_request.gql`
|
|
1006
|
+
query Components($first: Int, $libraryType: LibraryType) {
|
|
1007
|
+
components(libraryType: $libraryType) {
|
|
1008
|
+
connection(first: $first) {
|
|
1009
|
+
edges {
|
|
1010
|
+
node {
|
|
1011
|
+
id
|
|
1012
|
+
name
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
`, first ?? 100, libraryType ?? "GENERAL")).map((component) => ({
|
|
1019
|
+
key: component.id,
|
|
1020
|
+
label: component.name
|
|
1021
|
+
})) };
|
|
1022
|
+
}
|
|
1023
|
+
}) };
|
|
1024
|
+
const pollChangesInputs = {
|
|
1025
|
+
connection,
|
|
1026
|
+
pollResourceType: (0, _prismatic_io_spectral.input)({
|
|
1027
|
+
label: "Resource Type",
|
|
1028
|
+
type: "string",
|
|
1029
|
+
required: true,
|
|
1030
|
+
model: pollResourceModel,
|
|
1031
|
+
comments: "The type of resource to poll for changes.",
|
|
1032
|
+
example: "components",
|
|
1033
|
+
placeholder: "Select resource type",
|
|
1034
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
1035
|
+
}),
|
|
1036
|
+
lookBackDate: (0, _prismatic_io_spectral.input)({
|
|
1037
|
+
label: "Look-back Date",
|
|
1038
|
+
placeholder: "Enter look-back date (YYYY-MM-DD)",
|
|
1039
|
+
type: "string",
|
|
1040
|
+
required: false,
|
|
1041
|
+
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 visibility filters.",
|
|
1042
|
+
example: "2026-01-01",
|
|
1043
|
+
clean: lookBackDateClean
|
|
1044
|
+
}),
|
|
1045
|
+
showNewRecords: (0, _prismatic_io_spectral.input)({
|
|
1046
|
+
label: "Show New Records",
|
|
1047
|
+
type: "boolean",
|
|
1048
|
+
required: false,
|
|
1049
|
+
default: "true",
|
|
1050
|
+
comments: "When true, newly created records are included in the trigger output.",
|
|
1051
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
1052
|
+
}),
|
|
1053
|
+
showUpdatedRecords: (0, _prismatic_io_spectral.input)({
|
|
1054
|
+
label: "Show Updated Records",
|
|
1055
|
+
type: "boolean",
|
|
1056
|
+
required: false,
|
|
1057
|
+
default: "true",
|
|
1058
|
+
comments: "When true, records updated after the last poll are included in the trigger output.",
|
|
1059
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
1060
|
+
})
|
|
1061
|
+
};
|
|
1062
|
+
//#endregion
|
|
1063
|
+
//#region src/triggers/index.ts
|
|
1064
|
+
var triggers_default = { pollChangesTrigger: (0, _prismatic_io_spectral.pollingTrigger)({
|
|
1065
|
+
display: {
|
|
1066
|
+
label: "New and Updated Records",
|
|
1067
|
+
description: "Retrieves existing and ongoing components or change orders in Duro. Load history once, check for changes on a schedule, or both."
|
|
1068
|
+
},
|
|
1069
|
+
inputs: pollChangesInputs,
|
|
1070
|
+
examplePayload: pollChangesExamplePayload,
|
|
1071
|
+
triggerResolverSupport: "valid",
|
|
1072
|
+
batchConfig: { batchSize: 50 },
|
|
1073
|
+
triggerResolver: { resolveItems: (_context, { payload }) => resolveRecordChanges(payload.body.data) },
|
|
1074
|
+
perform: async (context, payload, params) => {
|
|
1075
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1076
|
+
const pollState = context.polling.getState();
|
|
1077
|
+
const { since: lastPolledAt, isBackfill } = resolvePollingStart(pollState, params.lookBackDate, now);
|
|
1078
|
+
const stream = resolvePollingStream(pollState, params.pollResourceType, now);
|
|
1079
|
+
if (!POLL_RESOURCE_CONFIG[params.pollResourceType]) throw new Error(`Unsupported resource type: ${params.pollResourceType}`);
|
|
1080
|
+
const { records, truncated, endCursor } = await fetchAllSince(createDuroClient(params.connection, context.debug.enabled), params.pollResourceType, lastPolledAt, {
|
|
1081
|
+
after: stream.endCursor,
|
|
1082
|
+
debug: context.debug.enabled,
|
|
1083
|
+
logger: context.logger
|
|
1084
|
+
});
|
|
1085
|
+
const { created, updated } = classifyRecords(records, lastPolledAt, {
|
|
1086
|
+
...params,
|
|
1087
|
+
isBackfill
|
|
1088
|
+
});
|
|
1089
|
+
const totalMatched = created.length + updated.length;
|
|
1090
|
+
context.polling.setState(nextPollingState({
|
|
1091
|
+
lastPolledAt,
|
|
1092
|
+
stream,
|
|
1093
|
+
resourceType: params.pollResourceType,
|
|
1094
|
+
isBackfill
|
|
1095
|
+
}, truncated ? endCursor : void 0));
|
|
1096
|
+
if (truncated) context.logger.warn(`Polling truncated at the page cap for ${params.pollResourceType}. Holding cursor at ${lastPolledAt}; the next poll resumes from the stored cursor.`);
|
|
1097
|
+
if (context.debug.enabled) context.logger.debug(`Polled ${params.pollResourceType}: ${records.length} fetched, ${created.length} created, ${updated.length} updated, truncated=${truncated}`);
|
|
1098
|
+
return {
|
|
1099
|
+
payload: {
|
|
1100
|
+
...payload,
|
|
1101
|
+
body: { data: {
|
|
1102
|
+
created,
|
|
1103
|
+
updated
|
|
1104
|
+
} }
|
|
1105
|
+
},
|
|
1106
|
+
polledNoChanges: totalMatched === 0
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
}) };
|
|
1110
|
+
//#endregion
|
|
1111
|
+
//#region src/index.ts
|
|
1112
|
+
var src_default = (0, _prismatic_io_spectral.component)({
|
|
1113
|
+
key: "duro-plm",
|
|
1114
|
+
public: true,
|
|
1115
|
+
documentationUrl: "https://prismatic.io/docs/components/duro-plm/",
|
|
1116
|
+
display: {
|
|
1117
|
+
label: "Duro PLM",
|
|
1118
|
+
description: "Manage products, components, and change orders in Duro PLM.",
|
|
1119
|
+
iconPath: "icon.png",
|
|
1120
|
+
category: "Application Connectors"
|
|
1121
|
+
},
|
|
1122
|
+
hooks: { error: _prismatic_io_spectral_http.handleErrors },
|
|
1123
|
+
actions: actions_default,
|
|
1124
|
+
triggers: triggers_default,
|
|
1125
|
+
connections: connections_default,
|
|
1126
|
+
dataSources: dataSources_default
|
|
1127
|
+
});
|
|
1128
|
+
//#endregion
|
|
1129
|
+
//#region npm-dist/.entry.ts
|
|
1130
|
+
var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
|
|
1131
|
+
//#endregion
|
|
1132
|
+
module.exports = _entry_default;
|