@prismatic-io/components-expensify 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.
@@ -0,0 +1,2079 @@
1
+ let _prismatic_io_spectral = require("@prismatic-io/spectral");
2
+ let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
3
+ let node_url = require("node:url");
4
+ //#region src/connections/basicConnection.ts
5
+ const basicConnection = (0, _prismatic_io_spectral.connection)({
6
+ key: "basic",
7
+ display: {
8
+ label: "Basic Connection",
9
+ description: "Basic connection for Expensify"
10
+ },
11
+ inputs: {
12
+ partnerUserID: {
13
+ label: "Partner User ID",
14
+ placeholder: "partnerUserID",
15
+ type: "string",
16
+ required: true,
17
+ shown: true,
18
+ comments: "The partnerUserID generated on the Expensify Integrations page. See the [Integration Server documentation](https://integrations.expensify.com/Integration-Server/doc/) for how to generate it.",
19
+ example: "_REPLACE_"
20
+ },
21
+ partnerUserSecret: {
22
+ label: "Partner User Secret",
23
+ placeholder: "partnerUserSecret",
24
+ type: "string",
25
+ required: true,
26
+ shown: true,
27
+ comments: "The partnerUserSecret generated together with the Partner User ID. Expensify shows it only once, so store it securely when it is generated.",
28
+ example: "_REPLACE_"
29
+ }
30
+ }
31
+ });
32
+ //#endregion
33
+ //#region src/connections/index.ts
34
+ var connections_default = [basicConnection];
35
+ //#endregion
36
+ //#region src/constants.ts
37
+ const BASE_URL = "https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations";
38
+ const JOB_TYPES = {
39
+ GET: "get",
40
+ CREATE: "create",
41
+ UPDATE: "update",
42
+ DOWNLOAD: "download",
43
+ FILE: "file"
44
+ };
45
+ const INPUT_SETTINGS_TYPES = {
46
+ POLICY_LIST: "policyList",
47
+ POLICY: "policy",
48
+ DOMAIN_CARD_LIST: "domainCardList",
49
+ EMPLOYEES: "employees",
50
+ EXPENSE_RULES: "expenseRules",
51
+ EXPENSES: "expenses",
52
+ REPORT: "report",
53
+ REPORT_STATUS: "reportStatus",
54
+ COMBINED_REPORT_DATA: "combinedReportData"
55
+ };
56
+ const FORM_FIELDS = {
57
+ REQUEST_JOB_DESCRIPTION: "requestJobDescription",
58
+ TEMPLATE: "template"
59
+ };
60
+ const RETURN_RANDOM_FILE_NAME = "returnRandomFileName";
61
+ const EMPLOYEE_UPDATE_SETTINGS = {
62
+ ENTITY: "generic",
63
+ DATA_SOURCE: "request"
64
+ };
65
+ //#endregion
66
+ //#region src/client.ts
67
+ const validateConnection = (connection) => {
68
+ if (connection.key !== basicConnection.key) throw new _prismatic_io_spectral.ConnectionError(connection, `The Connection you provided (${connection.key}) is not supported for this component`);
69
+ if (!connection.fields.partnerUserID || !connection.fields.partnerUserSecret) throw new _prismatic_io_spectral.ConnectionError(connection, `The Connection you provided is missing the required fields`);
70
+ };
71
+ const assertJobSucceeded = (response) => {
72
+ const body = response.data;
73
+ if (body && typeof body === "object" && typeof body.responseCode === "number" && body.responseCode !== 200) {
74
+ const message = body.responseMessage ? `: ${body.responseMessage}` : "";
75
+ throw new Error(`Expensify request failed with responseCode ${body.responseCode}${message}`);
76
+ }
77
+ return response;
78
+ };
79
+ const createClient = (connection, debug = false) => {
80
+ validateConnection(connection);
81
+ const client = (0, _prismatic_io_spectral_http.createClient)({
82
+ baseUrl: BASE_URL,
83
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
84
+ debug
85
+ });
86
+ client.interceptors.response.use(assertJobSucceeded);
87
+ return client;
88
+ };
89
+ //#endregion
90
+ //#region src/examplePayloads/cards.ts
91
+ const listCardsExamplePayload = { data: {
92
+ responseCode: 200,
93
+ domainCardList: [{
94
+ bank: "vcf",
95
+ cardID: 5198273,
96
+ cardName: "Visa - 4242",
97
+ cardNumber: "XXXXXXXXXXXX4242",
98
+ created: "2024-03-12 09:14:05",
99
+ email: "jane.doe@acmecorp.com",
100
+ externalEmployeeID: "EMP-1042",
101
+ lastImport: "2026-10-28 02:00:11",
102
+ lastImportResult: 200,
103
+ reimbursable: false,
104
+ scrapeMinDate: "2024-03-01"
105
+ }, {
106
+ bank: "stripe",
107
+ cardID: 5198304,
108
+ cardName: "Corporate Card - 1881",
109
+ cardNumber: "XXXXXXXXXXXX1881",
110
+ created: "2025-01-20 16:42:37",
111
+ email: "john.smith@acmecorp.com",
112
+ externalEmployeeID: "EMP-2217",
113
+ lastImport: "2026-10-28 02:00:14",
114
+ lastImportResult: 200,
115
+ reimbursable: true,
116
+ scrapeMinDate: "2025-01-01"
117
+ }]
118
+ } };
119
+ //#endregion
120
+ //#region src/examplePayloads/dataSources.ts
121
+ const listPoliciesDataSourceExamplePayload = { result: [
122
+ {
123
+ label: "Acme Corp USA Policy",
124
+ key: "DEADBEEF12345678"
125
+ },
126
+ {
127
+ label: "Acme Corp France Policy",
128
+ key: "BA5EBA1187654321"
129
+ },
130
+ {
131
+ label: "ACME Corp Candidate Policy",
132
+ key: "F005BA1100009999"
133
+ }
134
+ ] };
135
+ const listCardsDataSourceExamplePayload = { result: [{
136
+ label: "Visa - 4242",
137
+ key: "5198273"
138
+ }, {
139
+ label: "Corporate Card - 1881",
140
+ key: "5198304"
141
+ }] };
142
+ //#endregion
143
+ //#region src/examplePayloads/employees.ts
144
+ const updateEmployeeExamplePayload = { data: {
145
+ responseCode: 200,
146
+ "dry-run": false,
147
+ updatedEmployeesCount: 3,
148
+ diff: {
149
+ diffToAdd: {
150
+ "0123456789ABCDEF": ["employee1@domain.com", "employee2@domain.com"],
151
+ ABCDEF0123456789: ["employee3@domain.com"]
152
+ },
153
+ diffToRemove: { B1C7903C636F4A51: ["terminatedEmployee@domain.com"] }
154
+ },
155
+ securityGroupEmployeesMap: {
156
+ "407184": ["employee1@domain.com", "employee2@domain.com"],
157
+ "830936": ["employee3@domain.com"]
158
+ },
159
+ skippedEmployees: [{
160
+ email: "employee6@domain.com",
161
+ reason: "No policy found for 'Marketing'"
162
+ }, {
163
+ email: "employee7@domain.com",
164
+ reason: "Invalid manager email address 'manager@domain '"
165
+ }]
166
+ } };
167
+ //#endregion
168
+ //#region src/examplePayloads/expenses.ts
169
+ const createExpenseExamplePayload = { data: {
170
+ responseCode: 200,
171
+ transactionList: [{
172
+ amount: 1234,
173
+ merchant: "Name Of Merchant 1",
174
+ created: "2016-01-01",
175
+ transactionID: "6720309558248016",
176
+ currency: "USD"
177
+ }, {
178
+ amount: 2211,
179
+ merchant: "Name Of Merchant 2",
180
+ created: "2016-01-31",
181
+ transactionID: "6720309558248017",
182
+ currency: "CAD"
183
+ }]
184
+ } };
185
+ //#endregion
186
+ //#region src/examplePayloads/policies.ts
187
+ const getPolicyExamplePayload = { data: {
188
+ responseCode: 200,
189
+ policyInfo: {
190
+ "4C6722D4BD2BD941": {
191
+ reportFields: [
192
+ {
193
+ values: [],
194
+ name: "title",
195
+ type: "formula"
196
+ },
197
+ {
198
+ values: [
199
+ "Class 1",
200
+ "Class 2",
201
+ "Class 2:Sub class 2"
202
+ ],
203
+ name: "Classes",
204
+ type: "dropdown"
205
+ },
206
+ {
207
+ values: [
208
+ "Donatello",
209
+ "Leonardo",
210
+ "Michelangelo",
211
+ "Rafael"
212
+ ],
213
+ name: "Customers/Jobs",
214
+ type: "dropdown"
215
+ }
216
+ ],
217
+ categories: [
218
+ {
219
+ name: "Entertainment",
220
+ enabled: true
221
+ },
222
+ {
223
+ name: "Transportation",
224
+ enabled: true
225
+ },
226
+ {
227
+ name: "Phone",
228
+ enabled: true
229
+ },
230
+ {
231
+ name: "Fuel/Mileage",
232
+ enabled: true
233
+ },
234
+ {
235
+ name: "Lodging",
236
+ enabled: true
237
+ },
238
+ {
239
+ name: "Meals",
240
+ enabled: true
241
+ },
242
+ {
243
+ name: "Other",
244
+ enabled: false
245
+ }
246
+ ],
247
+ tags: [
248
+ {
249
+ glCode: "",
250
+ name: "Enterprise",
251
+ enabled: true
252
+ },
253
+ {
254
+ glCode: "",
255
+ name: "Enterprise:Jean-Luc Picard",
256
+ enabled: true
257
+ },
258
+ {
259
+ glCode: "",
260
+ name: "Enterprise:Lt. Commander Data",
261
+ enabled: true
262
+ },
263
+ {
264
+ glCode: "",
265
+ name: "Enterprise:William Riker",
266
+ enabled: true
267
+ }
268
+ ],
269
+ tax: {
270
+ default: "4",
271
+ rates: [
272
+ {
273
+ rate: 0,
274
+ name: "EC Goods Zero-rated",
275
+ rateID: "5"
276
+ },
277
+ {
278
+ rate: 0,
279
+ name: "EC Services Standard",
280
+ rateID: "4"
281
+ },
282
+ {
283
+ rate: 20,
284
+ name: "Standard",
285
+ rateID: "2"
286
+ },
287
+ {
288
+ rate: 5,
289
+ name: "Reduced",
290
+ rateID: "9"
291
+ }
292
+ ],
293
+ name: "Tax"
294
+ }
295
+ },
296
+ "3F329EA1C3809E6C": {
297
+ categories: [
298
+ {
299
+ name: "Phone Costs",
300
+ areCommentsRequired: false,
301
+ enabled: false
302
+ },
303
+ {
304
+ name: "Legal",
305
+ areCommentsRequired: false,
306
+ enabled: false
307
+ },
308
+ {
309
+ name: "Agency Expense",
310
+ areCommentsRequired: false,
311
+ enabled: false
312
+ }
313
+ ],
314
+ reportFields: [{
315
+ values: [],
316
+ name: "title",
317
+ type: "formula"
318
+ }],
319
+ tags: [{
320
+ name: "Tags",
321
+ tags: []
322
+ }],
323
+ tax: {},
324
+ employees: [{
325
+ email: "admin@domain.com",
326
+ role: "admin",
327
+ submitsTo: "user@domain.com"
328
+ }, {
329
+ email: "user@domain.com",
330
+ role: "user",
331
+ submitsTo: "admin@domain.com",
332
+ employeeID: "Emp1",
333
+ customField2: "custom information"
334
+ }]
335
+ }
336
+ }
337
+ } };
338
+ const listPoliciesExamplePayload = { data: {
339
+ policyList: [
340
+ {
341
+ outputCurrency: "USD",
342
+ owner: "admin@acmecorp.com",
343
+ role: "user",
344
+ name: "Acme Corp USA Policy",
345
+ id: "DEADBEEF12345678",
346
+ type: "corporate"
347
+ },
348
+ {
349
+ outputCurrency: "EUR",
350
+ owner: "admin@acmecorp.com",
351
+ role: "auditor",
352
+ name: "Acme Corp France Policy",
353
+ id: "BA5EBA1187654321",
354
+ type: "corporate"
355
+ },
356
+ {
357
+ outputCurrency: "USD",
358
+ owner: "hr@acmecorp.com",
359
+ role: "admin",
360
+ name: "ACME Corp Candidate Policy",
361
+ id: "F005BA1100009999",
362
+ type: "corporate"
363
+ }
364
+ ],
365
+ responseCode: 200
366
+ } };
367
+ const createPolicyExamplePayload = { data: {
368
+ responseCode: 200,
369
+ policyID: "0123456789ABCDEF",
370
+ policyName: "My New Policy"
371
+ } };
372
+ const updatePolicyExamplePayload = { data: { responseCode: 200 } };
373
+ //#endregion
374
+ //#region src/examplePayloads/reports.ts
375
+ const createReportExamplePayload = { data: {
376
+ responseCode: 200,
377
+ reportName: "Name of the report",
378
+ reportID: "R006AseGxMka"
379
+ } };
380
+ const updateReportStatusExamplePayload = { data: {
381
+ responseCode: 200,
382
+ reportIDs: ["R006AseGxMka", "R00bCluvcO4T"]
383
+ } };
384
+ const exportReportExamplePayload = { data: "exporteba3c95b-f302-4d74-a41a-6127c9088551-5650745444954548.pdf,exporteba3c95b-f302-4d74-a41a-6127c9088551-2050520975381833.pdf" };
385
+ //#endregion
386
+ //#region src/examplePayloads/triggers.ts
387
+ const pollChangesTriggerExamplePayload = { payload: {
388
+ headers: {},
389
+ queryParameters: {},
390
+ rawBody: { data: null },
391
+ body: { data: {
392
+ created: [{
393
+ outputCurrency: "USD",
394
+ owner: "admin@acmecorp.com",
395
+ role: "user",
396
+ name: "Acme Corp USA Policy",
397
+ id: "DEADBEEF12345678",
398
+ type: "corporate"
399
+ }],
400
+ updated: []
401
+ } },
402
+ pathFragment: "",
403
+ webhookUrls: {},
404
+ webhookApiKeys: {},
405
+ invokeUrl: "",
406
+ executionId: "RXhhbXBsZUV4ZWN1dGlvblJlc3VsdElk",
407
+ customer: {
408
+ id: "testCustomerId",
409
+ name: "Test Customer",
410
+ externalId: "testExternalId"
411
+ },
412
+ instance: {
413
+ id: "testInstanceId",
414
+ name: "Test Instance"
415
+ },
416
+ user: {
417
+ id: "testUserId",
418
+ email: "user@example.com",
419
+ name: "Test User",
420
+ externalId: "testUserExternalId"
421
+ },
422
+ integration: {
423
+ id: "testIntegrationId",
424
+ name: "Test Integration",
425
+ versionSequenceId: "1",
426
+ externalVersion: ""
427
+ },
428
+ flow: {
429
+ id: "testFlowId",
430
+ name: "Test Flow",
431
+ stableId: "testFlowStableId"
432
+ },
433
+ startedAt: "2024-01-15T00:00:00.000Z",
434
+ globalDebug: false
435
+ } };
436
+ //#endregion
437
+ //#region src/util/clean.ts
438
+ const toOptionalString = (value) => value ? _prismatic_io_spectral.util.types.toString(value) : void 0;
439
+ const toOptionalObject = (value) => {
440
+ if (typeof value === "string" && value.trim() === "") return;
441
+ return value ? _prismatic_io_spectral.util.types.toObject(value) : void 0;
442
+ };
443
+ const valueListInputClean = (value) => {
444
+ if (Array.isArray(value) && value.length >= 1 && value[0].trim() !== "") return value;
445
+ };
446
+ const toOptionalBool = (value) => value === void 0 || value === null || value === "" ? void 0 : _prismatic_io_spectral.util.types.toBool(value);
447
+ //#endregion
448
+ //#region src/util/payload.ts
449
+ const generatePayload = (data, connection) => {
450
+ const { partnerUserID, partnerUserSecret } = connection.fields;
451
+ const json = {
452
+ credentials: {
453
+ partnerUserID: _prismatic_io_spectral.util.types.toString(partnerUserID),
454
+ partnerUserSecret: _prismatic_io_spectral.util.types.toString(partnerUserSecret)
455
+ },
456
+ type: JOB_TYPES.GET,
457
+ ...data
458
+ };
459
+ const params = new node_url.URLSearchParams();
460
+ params.append(FORM_FIELDS.REQUEST_JOB_DESCRIPTION, JSON.stringify(json));
461
+ return params;
462
+ };
463
+ //#endregion
464
+ //#region src/inputs/common.ts
465
+ const connectionInput = (0, _prismatic_io_spectral.input)({
466
+ label: "Connection",
467
+ type: "connection",
468
+ required: true
469
+ });
470
+ const type = (0, _prismatic_io_spectral.input)({
471
+ label: "Type",
472
+ type: "string",
473
+ required: true,
474
+ comments: "Specifies to the job that it has to get a policy summary list.",
475
+ placeholder: "Enter job type",
476
+ default: INPUT_SETTINGS_TYPES.POLICY_LIST,
477
+ clean: _prismatic_io_spectral.util.types.toString
478
+ });
479
+ const employeeEmail = (0, _prismatic_io_spectral.input)({
480
+ label: "Employee Email",
481
+ type: "string",
482
+ required: true,
483
+ comments: "The email address of the Expensify user whose account the job runs against.",
484
+ placeholder: "Enter employee email address",
485
+ example: "employee@domain.com",
486
+ clean: _prismatic_io_spectral.util.types.toString
487
+ });
488
+ const policyId = (0, _prismatic_io_spectral.input)({
489
+ label: "Policy ID",
490
+ type: "string",
491
+ required: true,
492
+ comments: "The unique identifier for the policy (workspace) the job runs against. The policy must be owned or shared by the user.",
493
+ placeholder: "Enter policy ID",
494
+ example: "E40D9B8DF456E233",
495
+ clean: _prismatic_io_spectral.util.types.toString
496
+ });
497
+ const domain = (0, _prismatic_io_spectral.input)({
498
+ label: "Domain",
499
+ type: "string",
500
+ required: true,
501
+ comments: "The name of the domain to get the cards for.",
502
+ placeholder: "Enter domain name",
503
+ example: "domain.com",
504
+ clean: _prismatic_io_spectral.util.types.toString
505
+ });
506
+ const policyIDList = (0, _prismatic_io_spectral.input)({
507
+ label: "Policy ID List",
508
+ type: "string",
509
+ collection: "valuelist",
510
+ required: true,
511
+ comments: "The IDs of the policies to get information for.",
512
+ placeholder: "Enter policy ID",
513
+ example: "E40D9B8DF456E233",
514
+ clean: valueListInputClean
515
+ });
516
+ const onFinish = (0, _prismatic_io_spectral.input)({
517
+ label: "On Finish",
518
+ type: "code",
519
+ language: "json",
520
+ comments: "The actions Expensify runs when the job finishes, such as emailing a summary of the changes to a list of recipients.",
521
+ placeholder: "Enter on-finish actions as JSON",
522
+ example: JSON.stringify([{
523
+ actionName: "email",
524
+ recipients: "admin1@domain.com,admin2@domain.com"
525
+ }], null, 2),
526
+ clean: toOptionalObject,
527
+ required: false
528
+ });
529
+ //#endregion
530
+ //#region src/inputs/cards.ts
531
+ const listCardsInputs = {
532
+ connectionInput,
533
+ type: {
534
+ ...type,
535
+ default: INPUT_SETTINGS_TYPES.DOMAIN_CARD_LIST,
536
+ comments: "Specifies to the job that it has to list the cards of a domain."
537
+ },
538
+ domain
539
+ };
540
+ //#endregion
541
+ //#region src/inputs/dataSources.ts
542
+ const listCardsDataSourceInputs = {
543
+ connectionInput,
544
+ type: {
545
+ ...type,
546
+ default: INPUT_SETTINGS_TYPES.DOMAIN_CARD_LIST,
547
+ comments: "Specifies to the job that it has to list the Cards of a domain."
548
+ },
549
+ domain: {
550
+ ...domain,
551
+ default: "domain",
552
+ comments: "The name of the domain to list the Cards for."
553
+ }
554
+ };
555
+ const listPoliciesDataSourceInputs = {
556
+ connectionInput,
557
+ type
558
+ };
559
+ //#endregion
560
+ //#region src/inputs/employees.ts
561
+ const dryRun = (0, _prismatic_io_spectral.input)({
562
+ label: "Dry Run",
563
+ type: "boolean",
564
+ required: false,
565
+ comments: "When true, employees are not actually provisioned or updated. Use this for development.",
566
+ default: "false",
567
+ clean: toOptionalBool
568
+ });
569
+ const shouldFixApprovalChains = (0, _prismatic_io_spectral.input)({
570
+ label: "Fix Approval Chains",
571
+ type: "boolean",
572
+ required: false,
573
+ comments: "When true, Expensify automatically invites managers (submitsTo), managers’ managers, and so on to policies where they approve reports, if it is not their primary policy.",
574
+ default: "true",
575
+ clean: toOptionalBool
576
+ });
577
+ const setEmployeePrimaryPolicy = (0, _prismatic_io_spectral.input)({
578
+ label: "Set Employee Primary Policy",
579
+ type: "string",
580
+ required: false,
581
+ comments: "Specifies the policy to set as the primary policy for the employee. If not specified, the employee will not have a primary policy.",
582
+ model: [
583
+ {
584
+ label: "none",
585
+ value: "none"
586
+ },
587
+ {
588
+ label: "new_employees",
589
+ value: "new_employees"
590
+ },
591
+ {
592
+ label: "all_employees",
593
+ value: "all_employees"
594
+ }
595
+ ],
596
+ default: "none",
597
+ clean: toOptionalString
598
+ });
599
+ const employees = (0, _prismatic_io_spectral.input)({
600
+ label: "Employees",
601
+ type: "code",
602
+ language: "json",
603
+ comments: "Replace or update the existing employees of the policy with the ones provided. If the employee does not exist, it will be created.",
604
+ placeholder: "Enter employees as JSON",
605
+ example: JSON.stringify([{
606
+ employeeEmail: "employee@domain.com",
607
+ managerEmail: "manager@domain.com",
608
+ policyID: "0123456789ABCDEF",
609
+ employeeID: "12345",
610
+ firstName: "John",
611
+ lastName: "Doe",
612
+ customField2: "ABC123",
613
+ approvalLimit: 12300,
614
+ overLimitApprover: "audit@domain.com",
615
+ isTerminated: false,
616
+ additionalPolicyIDs: ["ABCDEF0123456789", "456789ABCDEF0123"]
617
+ }, {
618
+ employeeEmail: "manager@domain.com",
619
+ managerEmail: "ceo@domain.com",
620
+ policyID: "0123456789ABCDEF",
621
+ employeeID: "34567",
622
+ firstName: "Michael",
623
+ lastName: "Scott",
624
+ customField1: "ZZZ333",
625
+ customField2: "BCD345",
626
+ isTerminated: false
627
+ }], null, 2),
628
+ clean: toOptionalObject,
629
+ required: false
630
+ });
631
+ const provisioningOptions = (0, _prismatic_io_spectral.structuredObjectInput)({
632
+ label: "Provisioning Options",
633
+ required: false,
634
+ comments: "Options that control how the employee update is applied: dry run, primary policy assignment, and approval chain fixes.",
635
+ inputs: {
636
+ dryRun,
637
+ setEmployeePrimaryPolicy,
638
+ shouldFixApprovalChains
639
+ }
640
+ });
641
+ const updateEmployeeInputs = {
642
+ connectionInput,
643
+ type: {
644
+ ...type,
645
+ default: INPUT_SETTINGS_TYPES.EMPLOYEES,
646
+ comments: "Specifies to the job that it has to update an employee"
647
+ },
648
+ employees,
649
+ provisioningOptions,
650
+ onFinish
651
+ };
652
+ //#endregion
653
+ //#region src/inputs/expenseRules.ts
654
+ const ruleId = (0, _prismatic_io_spectral.input)({
655
+ label: "Rule ID",
656
+ type: "string",
657
+ required: true,
658
+ comments: "The rule to update.",
659
+ placeholder: "Enter rule ID",
660
+ example: "Any valid Expensify rule ID, owned or shared by the user",
661
+ clean: _prismatic_io_spectral.util.types.toInt
662
+ });
663
+ const actions = (0, _prismatic_io_spectral.input)({
664
+ label: "Actions",
665
+ type: "code",
666
+ language: "json",
667
+ comments: "The actions to perform on the expense rule.",
668
+ placeholder: "Enter rule actions as JSON",
669
+ example: JSON.stringify({
670
+ tag: "Tag Name",
671
+ defaultBillable: true
672
+ }, null, 2),
673
+ clean: _prismatic_io_spectral.util.types.toObject,
674
+ required: true
675
+ });
676
+ const createExpenseRuleInputs = {
677
+ connectionInput,
678
+ type: {
679
+ ...type,
680
+ default: INPUT_SETTINGS_TYPES.EXPENSE_RULES,
681
+ comments: "Specifies to the job that it has to create an expense rule."
682
+ },
683
+ employeeEmail,
684
+ policyId,
685
+ actions
686
+ };
687
+ const updateExpenseRuleInputs = {
688
+ connectionInput,
689
+ type: {
690
+ ...type,
691
+ default: INPUT_SETTINGS_TYPES.EXPENSE_RULES,
692
+ comments: "Specifies to the job that it has to update an expense rule."
693
+ },
694
+ employeeEmail,
695
+ policyId,
696
+ ruleId,
697
+ actions
698
+ };
699
+ //#endregion
700
+ //#region src/inputs/expenses.ts
701
+ const transactionList = (0, _prismatic_io_spectral.input)({
702
+ label: "Transaction List",
703
+ type: "code",
704
+ language: "json",
705
+ comments: "The transactions to add to the report.",
706
+ placeholder: "Enter transactions as JSON",
707
+ example: JSON.stringify([
708
+ {
709
+ created: "2016-01-01",
710
+ currency: "USD",
711
+ merchant: "Name of merchant 1",
712
+ amount: 1234
713
+ },
714
+ {
715
+ created: "2016-01-21",
716
+ currency: "EUR",
717
+ merchant: "Name of merchant 2",
718
+ amount: 2211,
719
+ policyID: "E40D9B8DF456E233",
720
+ tax: { rateID: "id_TAX_OPTION_16" }
721
+ },
722
+ {
723
+ created: "2016-01-31",
724
+ currency: "CAD",
725
+ merchant: "Name of merchant 3",
726
+ amount: 2211,
727
+ reportID: "R006AseGxMka",
728
+ tax: {
729
+ rateID: "id_TAX_OPTION_16",
730
+ amount: 600
731
+ }
732
+ }
733
+ ], null, 2),
734
+ clean: _prismatic_io_spectral.util.types.toObject,
735
+ required: true
736
+ });
737
+ const createExpenseInputs = {
738
+ connectionInput,
739
+ type: {
740
+ ...type,
741
+ default: INPUT_SETTINGS_TYPES.EXPENSES,
742
+ comments: "Specifies to the job that it has to create expenses."
743
+ },
744
+ employeeEmail,
745
+ transactionList
746
+ };
747
+ //#endregion
748
+ //#region src/inputs/misc.ts
749
+ const { debugRequest: _, ...httpRequestInputs } = _prismatic_io_spectral_http.inputs;
750
+ const rawRequestInputs = {
751
+ connectionInput,
752
+ ...httpRequestInputs,
753
+ url: {
754
+ ...httpRequestInputs.url,
755
+ comments: "This input is not required as the Expensify API is a single endpoint.",
756
+ example: "",
757
+ required: false
758
+ }
759
+ };
760
+ //#endregion
761
+ //#region src/inputs/policies.ts
762
+ const adminOnly = (0, _prismatic_io_spectral.input)({
763
+ label: "Admin Only",
764
+ type: "boolean",
765
+ required: false,
766
+ comments: "When true, only returns the policies the user is an admin of.",
767
+ default: "false",
768
+ clean: toOptionalBool
769
+ });
770
+ const userEmail = (0, _prismatic_io_spectral.input)({
771
+ label: "User Email",
772
+ type: "string",
773
+ required: false,
774
+ comments: "Specifies the user to gather the policy list for. Third-party access must have been granted by that user/company domain beforehand.",
775
+ placeholder: "Enter user email address",
776
+ example: "employee@domain.com",
777
+ clean: toOptionalString
778
+ });
779
+ const policyName = (0, _prismatic_io_spectral.input)({
780
+ label: "Policy Name",
781
+ type: "string",
782
+ required: true,
783
+ comments: "The name of the policy to create.",
784
+ placeholder: "Enter policy name",
785
+ example: "Marketing Team",
786
+ clean: _prismatic_io_spectral.util.types.toString
787
+ });
788
+ const fields = (0, _prismatic_io_spectral.input)({
789
+ label: "Fields",
790
+ type: "string",
791
+ collection: "valuelist",
792
+ required: true,
793
+ comments: "Specifies the fields of the policy to gather information for.",
794
+ model: [
795
+ {
796
+ label: "categories",
797
+ value: "categories"
798
+ },
799
+ {
800
+ label: "reportFields",
801
+ value: "reportFields"
802
+ },
803
+ {
804
+ label: "tags",
805
+ value: "tags"
806
+ },
807
+ {
808
+ label: "tax",
809
+ value: "tax"
810
+ },
811
+ {
812
+ label: "employees",
813
+ value: "employees"
814
+ }
815
+ ],
816
+ clean: valueListInputClean
817
+ });
818
+ const plan = (0, _prismatic_io_spectral.input)({
819
+ label: "Plan",
820
+ type: "string",
821
+ required: false,
822
+ comments: "Specifies the plan of the policy. If not specified, the new policy will be created under the team plan.",
823
+ model: [{
824
+ label: "team",
825
+ value: "team"
826
+ }, {
827
+ label: "corporate",
828
+ value: "corporate"
829
+ }],
830
+ clean: toOptionalString
831
+ });
832
+ const categories = (0, _prismatic_io_spectral.input)({
833
+ label: "Categories",
834
+ type: "code",
835
+ language: "json",
836
+ comments: "Replace or update the existing categories of the policy with the ones provided.",
837
+ placeholder: "Enter categories as JSON",
838
+ example: JSON.stringify({
839
+ action: "merge",
840
+ data: [{
841
+ name: "Category 1",
842
+ enabled: true,
843
+ payrollCode: "Payroll Code 1",
844
+ glCode: "GL Code 1",
845
+ commentHint: "Comment hint 1",
846
+ areCommentsRequired: true,
847
+ maxExpenseAmount: 2500
848
+ }, {
849
+ name: "Category 2",
850
+ enabled: false
851
+ }]
852
+ }, null, 2),
853
+ clean: toOptionalObject,
854
+ required: false
855
+ });
856
+ const tags = (0, _prismatic_io_spectral.input)({
857
+ label: "Tags",
858
+ type: "code",
859
+ language: "json",
860
+ comments: "Replace the existing tags of the policy with the ones provided.",
861
+ placeholder: "Enter tags as JSON",
862
+ example: JSON.stringify({ data: [{
863
+ name: "Tag",
864
+ tags: [{
865
+ name: "Tag 1",
866
+ glCode: "Tag 1 GL Code"
867
+ }, {
868
+ name: "Tag 2",
869
+ enabled: false
870
+ }]
871
+ }] }, null, 2),
872
+ clean: toOptionalObject,
873
+ required: false
874
+ });
875
+ const reportFields = (0, _prismatic_io_spectral.input)({
876
+ label: "Report Fields",
877
+ type: "code",
878
+ language: "json",
879
+ comments: "Replace or update the existing report fields of the policy with the ones provided.",
880
+ placeholder: "Enter report fields as JSON",
881
+ example: JSON.stringify({
882
+ action: "merge",
883
+ data: [{
884
+ name: "Report field 1",
885
+ type: "dropdown",
886
+ values: [
887
+ "value 1",
888
+ "value 2",
889
+ "value 3"
890
+ ]
891
+ }]
892
+ }, null, 2),
893
+ clean: toOptionalObject,
894
+ required: false
895
+ });
896
+ const createPolicyInputs = {
897
+ connectionInput,
898
+ type: {
899
+ ...type,
900
+ default: INPUT_SETTINGS_TYPES.POLICY,
901
+ comments: "Specifies to the job that it has to create a policy."
902
+ },
903
+ policyName,
904
+ plan
905
+ };
906
+ const getPolicyInputs = {
907
+ connectionInput,
908
+ type: {
909
+ ...type,
910
+ default: INPUT_SETTINGS_TYPES.POLICY,
911
+ comments: "Specifies to the job that it has to get information specific to policies."
912
+ },
913
+ policyIDList,
914
+ fields,
915
+ userEmail
916
+ };
917
+ const listPoliciesInputs = {
918
+ connectionInput,
919
+ type,
920
+ adminOnly,
921
+ userEmail
922
+ };
923
+ const updatePolicyInputs = {
924
+ connectionInput,
925
+ type: {
926
+ ...type,
927
+ default: INPUT_SETTINGS_TYPES.POLICY,
928
+ comments: "Specifies to the job that it has to update a policy."
929
+ },
930
+ policyId,
931
+ policyIDList: {
932
+ ...policyIDList,
933
+ required: false
934
+ },
935
+ categories,
936
+ tags,
937
+ reportFields
938
+ };
939
+ //#endregion
940
+ //#region src/inputs/reports.ts
941
+ const fileName = (0, _prismatic_io_spectral.input)({
942
+ label: "File Name",
943
+ type: "string",
944
+ required: true,
945
+ comments: "The name of a file generated from the exporter job.",
946
+ placeholder: "Enter file name",
947
+ example: "exporteba3c95b-f302-4d74-a41a-6127c9088551-5650745444954548.pdf",
948
+ clean: _prismatic_io_spectral.util.types.toString
949
+ });
950
+ const fileSystem = (0, _prismatic_io_spectral.input)({
951
+ label: "File System",
952
+ type: "string",
953
+ required: false,
954
+ comments: "The file system the exporter job stored the file on. Use the same value the file was generated with.",
955
+ clean: toOptionalString,
956
+ default: "integrationServer",
957
+ model: [{
958
+ label: "reconciliation",
959
+ value: "reconciliation"
960
+ }, {
961
+ label: "integrationServer",
962
+ value: "integrationServer"
963
+ }]
964
+ });
965
+ const status = (0, _prismatic_io_spectral.input)({
966
+ label: "Status",
967
+ type: "string",
968
+ required: true,
969
+ comments: "The status to change the reports to. At the moment, only Reimbursed is supported. Only reports in the Approved status can be updated to Reimbursed. All other reports will be ignored.",
970
+ placeholder: "Enter report status",
971
+ example: "REIMBURSED",
972
+ clean: _prismatic_io_spectral.util.types.toString,
973
+ default: "REIMBURSED"
974
+ });
975
+ const limit = (0, _prismatic_io_spectral.input)({
976
+ label: "Limit",
977
+ type: "string",
978
+ required: false,
979
+ comments: "Maximum number of reports to export.",
980
+ placeholder: "Enter maximum number of reports",
981
+ example: "10",
982
+ clean: toOptionalString
983
+ });
984
+ const test = (0, _prismatic_io_spectral.input)({
985
+ label: "Test",
986
+ type: "boolean",
987
+ required: false,
988
+ comments: "When true, the actions defined in On Finish are not executed.",
989
+ clean: _prismatic_io_spectral.util.types.toBool,
990
+ default: "false"
991
+ });
992
+ const expenses = (0, _prismatic_io_spectral.input)({
993
+ label: "Expenses",
994
+ type: "code",
995
+ language: "json",
996
+ comments: "The expenses to add to the report.",
997
+ placeholder: "Enter expenses as JSON",
998
+ example: JSON.stringify([{
999
+ date: "yyyy-mm-dd",
1000
+ currency: "USD",
1001
+ merchant: "Name of merchant",
1002
+ amount: 1234
1003
+ }, {
1004
+ date: "yyyy-mm-dd",
1005
+ currency: "CAD",
1006
+ merchant: "Name of merchant",
1007
+ amount: 2211
1008
+ }], null, 2),
1009
+ clean: _prismatic_io_spectral.util.types.toObject,
1010
+ required: true
1011
+ });
1012
+ const report = (0, _prismatic_io_spectral.input)({
1013
+ label: "Report",
1014
+ type: "code",
1015
+ language: "json",
1016
+ comments: "The report to create.",
1017
+ placeholder: "Enter report as JSON",
1018
+ example: JSON.stringify({
1019
+ title: "Name of the report",
1020
+ fields: {
1021
+ reason_of_trip: "Business trip",
1022
+ employees: "3"
1023
+ }
1024
+ }, null, 2),
1025
+ clean: _prismatic_io_spectral.util.types.toObject,
1026
+ required: true
1027
+ });
1028
+ const filters = (0, _prismatic_io_spectral.input)({
1029
+ label: "Filters",
1030
+ type: "code",
1031
+ language: "json",
1032
+ comments: "The filters to apply to the report list.",
1033
+ placeholder: "Enter filters as JSON",
1034
+ example: JSON.stringify({
1035
+ type: "reportStatus",
1036
+ status: "REIMBURSED",
1037
+ filters: { reportIDList: "R006AseGxMka,R00bCluvcO4T" }
1038
+ }, null, 2),
1039
+ clean: toOptionalObject,
1040
+ required: false
1041
+ });
1042
+ const startDate = (0, _prismatic_io_spectral.input)({
1043
+ label: "Start Date",
1044
+ type: "string",
1045
+ required: true,
1046
+ comments: "Filters out all reports submitted or created before the given date, whichever occurred last (inclusive). yyyy-mm-dd formatted date.",
1047
+ placeholder: "Enter start date (yyyy-mm-dd)",
1048
+ example: "2016-01-01",
1049
+ clean: _prismatic_io_spectral.util.types.toString,
1050
+ default: "2016-01-01"
1051
+ });
1052
+ const endDate = (0, _prismatic_io_spectral.input)({
1053
+ label: "End Date",
1054
+ type: "string",
1055
+ required: false,
1056
+ comments: "Filters out all reports submitted or created after the given date, whichever occurred last (inclusive). yyyy-mm-dd formatted date.",
1057
+ placeholder: "Enter end date (yyyy-mm-dd)",
1058
+ example: "2016-12-31",
1059
+ clean: toOptionalString,
1060
+ default: "2016-01-01"
1061
+ });
1062
+ const fileExtension = (0, _prismatic_io_spectral.input)({
1063
+ label: "File Extension",
1064
+ type: "string",
1065
+ required: true,
1066
+ comments: "Specifies the format of the generated report. Note: if the 'pdf' option is chosen, one PDF file will be generated for each report exported.",
1067
+ clean: _prismatic_io_spectral.util.types.toString,
1068
+ model: [
1069
+ {
1070
+ label: "csv",
1071
+ value: "csv"
1072
+ },
1073
+ {
1074
+ label: "pdf",
1075
+ value: "pdf"
1076
+ },
1077
+ {
1078
+ label: "xls",
1079
+ value: "xls"
1080
+ },
1081
+ {
1082
+ label: "xlsx",
1083
+ value: "xlsx"
1084
+ },
1085
+ {
1086
+ label: "txt",
1087
+ value: "txt"
1088
+ },
1089
+ {
1090
+ label: "json",
1091
+ value: "json"
1092
+ },
1093
+ {
1094
+ label: "xml",
1095
+ value: "xml"
1096
+ }
1097
+ ],
1098
+ default: "json"
1099
+ });
1100
+ const fileBasename = (0, _prismatic_io_spectral.input)({
1101
+ label: "File Basename",
1102
+ type: "string",
1103
+ required: false,
1104
+ comments: "The name of the generated file(s) will start with this value, and a random part will be added to make each filename globally unique. If not specified, the default value export is used.",
1105
+ placeholder: "Enter file basename",
1106
+ example: "expensify_export",
1107
+ clean: toOptionalString
1108
+ });
1109
+ const includeFullPageReceiptsPdf = (0, _prismatic_io_spectral.input)({
1110
+ label: "Include Full Page Receipts PDF",
1111
+ type: "boolean",
1112
+ required: false,
1113
+ comments: "When true, generated PDFs include full page receipts. This parameter is used only if fileExtension contains pdf.",
1114
+ clean: _prismatic_io_spectral.util.types.toBool,
1115
+ default: "false"
1116
+ });
1117
+ const templateName = (0, _prismatic_io_spectral.input)({
1118
+ label: "Template",
1119
+ type: "code",
1120
+ language: "json",
1121
+ required: false,
1122
+ comments: "The template parameter is used to format the Expensify data as you wish. It is based on the Freemarker language's syntax.",
1123
+ placeholder: "Enter Freemarker template",
1124
+ clean: _prismatic_io_spectral.util.types.toString,
1125
+ default: `
1126
+ <#if addHeader == true>
1127
+ Merchant,Original Amount,Category,Report number,Expense number<#lt>
1128
+ </#if>
1129
+ <#assign reportNumber = 1>
1130
+ <#assign expenseNumber = 1>
1131
+ <#list reports as report>
1132
+ <#list report.transactionList as expense>
1133
+ \${expense.merchant},<#t>
1134
+ <#-- note: expense.amount prints the original amount only -->
1135
+ \${expense.amount},<#t>
1136
+ \${expense.category},<#t>
1137
+ \${reportNumber},<#t>
1138
+ \${expenseNumber}<#lt>
1139
+ <#assign expenseNumber = expenseNumber + 1>
1140
+ </#list>
1141
+ <#assign reportNumber = reportNumber + 1>
1142
+ </#list>`
1143
+ });
1144
+ const approvedAfter = (0, _prismatic_io_spectral.input)({
1145
+ label: "Approved After",
1146
+ type: "string",
1147
+ required: false,
1148
+ comments: "Filters out all reports approved before, or on, the given date. Only applies to reports that have been approved. yyyy-mm-dd formatted date.",
1149
+ placeholder: "Enter approval date (yyyy-mm-dd)",
1150
+ example: "2016-01-01",
1151
+ clean: toOptionalString
1152
+ });
1153
+ const markAsExportedFilter = (0, _prismatic_io_spectral.input)({
1154
+ label: "Mark as Exported Label Filter",
1155
+ type: "string",
1156
+ required: false,
1157
+ comments: "Filters out reports that have already been exported with this label.",
1158
+ placeholder: "Enter export label",
1159
+ example: "Expensify Export",
1160
+ clean: toOptionalString
1161
+ });
1162
+ const reportIdList = (0, _prismatic_io_spectral.input)({
1163
+ label: "Report ID List",
1164
+ type: "string",
1165
+ collection: "valuelist",
1166
+ required: false,
1167
+ comments: "The IDs of the reports to get information for.",
1168
+ placeholder: "Enter report ID",
1169
+ example: "R006AseGxMka",
1170
+ clean: valueListInputClean
1171
+ });
1172
+ const createReportInputs = {
1173
+ connectionInput,
1174
+ type: {
1175
+ ...type,
1176
+ default: INPUT_SETTINGS_TYPES.REPORT,
1177
+ comments: "Specifies to the job that it has to create a report."
1178
+ },
1179
+ employeeEmail,
1180
+ report,
1181
+ expenses,
1182
+ policyId
1183
+ };
1184
+ const downloadReportInputs = {
1185
+ connectionInput,
1186
+ fileName,
1187
+ fileSystem
1188
+ };
1189
+ const exportReportAdditionalFields = (0, _prismatic_io_spectral.structuredObjectInput)({
1190
+ label: "Additional Fields",
1191
+ required: false,
1192
+ comments: "Additional optional fields: includes File Basename, Include Full Page Receipts PDF, Limit, and Test.",
1193
+ inputs: {
1194
+ fileBasename,
1195
+ includeFullPageReceiptsPdf,
1196
+ limit,
1197
+ test
1198
+ }
1199
+ });
1200
+ const exportReportInputs = {
1201
+ connectionInput,
1202
+ fileExtension,
1203
+ startDate: {
1204
+ ...startDate,
1205
+ required: false,
1206
+ clean: toOptionalString
1207
+ },
1208
+ endDate: {
1209
+ ...endDate,
1210
+ required: false
1211
+ },
1212
+ approvedAfter,
1213
+ markAsExportedFilter,
1214
+ policyIDList: {
1215
+ ...policyIDList,
1216
+ required: false
1217
+ },
1218
+ reportIdList,
1219
+ additionalFields: exportReportAdditionalFields,
1220
+ status: {
1221
+ ...status,
1222
+ label: "Report State",
1223
+ comments: "The report state to filter on. Only reports in this state are exported.",
1224
+ required: false,
1225
+ clean: toOptionalString
1226
+ },
1227
+ employeeEmail: {
1228
+ ...employeeEmail,
1229
+ required: false,
1230
+ clean: toOptionalString
1231
+ },
1232
+ onFinish: {
1233
+ ...onFinish,
1234
+ example: JSON.stringify([{
1235
+ actionName: "markAsExported",
1236
+ label: "Expensify Export"
1237
+ }, {
1238
+ actionName: "email",
1239
+ recipients: "manager@domain.com,finances@domain.com",
1240
+ message: "Report is ready."
1241
+ }], null, 2)
1242
+ },
1243
+ templateName
1244
+ };
1245
+ const updateReportStatusInputs = {
1246
+ connectionInput,
1247
+ type: {
1248
+ ...type,
1249
+ default: INPUT_SETTINGS_TYPES.REPORT_STATUS,
1250
+ comments: "Specifies to the job that it has to update the status of a list of reports."
1251
+ },
1252
+ status,
1253
+ filters
1254
+ };
1255
+ const pollChangesTriggerInputs = {
1256
+ connection: connectionInput,
1257
+ showNewRecords: (0, _prismatic_io_spectral.input)({
1258
+ label: "Show New Records",
1259
+ type: "boolean",
1260
+ required: true,
1261
+ default: "true",
1262
+ comments: "When true, newly created records are included in trigger results.",
1263
+ clean: _prismatic_io_spectral.util.types.toBool
1264
+ })
1265
+ };
1266
+ //#endregion
1267
+ //#region src/outputSchemas/common.ts
1268
+ const responseEnvelopeSchema = {
1269
+ type: "object",
1270
+ properties: {
1271
+ responseCode: { type: "number" },
1272
+ responseMessage: { type: "string" }
1273
+ },
1274
+ required: ["responseCode"]
1275
+ };
1276
+ const reportIssueSchema = {
1277
+ type: "object",
1278
+ properties: {
1279
+ reason: { type: "string" },
1280
+ reportID: { type: "string" }
1281
+ }
1282
+ };
1283
+ const emailsByIdSchema = {
1284
+ type: "object",
1285
+ additionalProperties: {
1286
+ type: "array",
1287
+ items: {
1288
+ type: "string",
1289
+ format: "email"
1290
+ }
1291
+ }
1292
+ };
1293
+ //#endregion
1294
+ //#region src/outputSchemas/cards.ts
1295
+ const listCardsOutputSchema = {
1296
+ type: "object",
1297
+ properties: {
1298
+ ...responseEnvelopeSchema.properties,
1299
+ domainCardList: {
1300
+ type: "array",
1301
+ items: {
1302
+ type: "object",
1303
+ properties: {
1304
+ bank: { type: "string" },
1305
+ cardID: { type: "number" },
1306
+ cardName: { type: "string" },
1307
+ cardNumber: { type: "string" },
1308
+ created: { type: "string" },
1309
+ email: { type: "string" },
1310
+ externalEmployeeID: { type: "string" },
1311
+ lastImport: { type: "string" },
1312
+ lastImportResult: { type: "number" },
1313
+ reimbursable: { type: "boolean" },
1314
+ scrapeMinDate: { type: "string" }
1315
+ }
1316
+ }
1317
+ }
1318
+ },
1319
+ required: ["responseCode"]
1320
+ };
1321
+ //#endregion
1322
+ //#region src/outputSchemas/employees.ts
1323
+ const updateEmployeeOutputSchema = {
1324
+ type: "object",
1325
+ properties: {
1326
+ ...responseEnvelopeSchema.properties,
1327
+ "dry-run": { type: "boolean" },
1328
+ updatedEmployeesCount: { type: "number" },
1329
+ diff: {
1330
+ type: "object",
1331
+ properties: {
1332
+ diffToAdd: emailsByIdSchema,
1333
+ diffToRemove: emailsByIdSchema
1334
+ }
1335
+ },
1336
+ securityGroupEmployeesMap: emailsByIdSchema,
1337
+ skippedEmployees: {
1338
+ type: "array",
1339
+ items: {
1340
+ type: "object",
1341
+ properties: {
1342
+ email: { type: "string" },
1343
+ reason: { type: "string" }
1344
+ }
1345
+ }
1346
+ }
1347
+ },
1348
+ required: ["responseCode"]
1349
+ };
1350
+ //#endregion
1351
+ //#region src/outputSchemas/expenses.ts
1352
+ const createExpenseOutputSchema = {
1353
+ type: "object",
1354
+ properties: {
1355
+ ...responseEnvelopeSchema.properties,
1356
+ transactionList: {
1357
+ type: "array",
1358
+ items: {
1359
+ type: "object",
1360
+ properties: {
1361
+ transactionID: { type: "string" },
1362
+ amount: { type: "number" },
1363
+ merchant: { type: "string" },
1364
+ created: { type: "string" },
1365
+ currency: { type: "string" }
1366
+ }
1367
+ }
1368
+ }
1369
+ },
1370
+ required: ["responseCode"]
1371
+ };
1372
+ //#endregion
1373
+ //#region src/outputSchemas/policies.ts
1374
+ const policySummarySchema = {
1375
+ type: "object",
1376
+ properties: {
1377
+ id: { type: "string" },
1378
+ name: { type: "string" },
1379
+ type: { type: "string" },
1380
+ role: { type: "string" },
1381
+ owner: {
1382
+ type: "string",
1383
+ format: "email"
1384
+ },
1385
+ outputCurrency: { type: "string" }
1386
+ }
1387
+ };
1388
+ const policyInfoSchema = {
1389
+ type: "object",
1390
+ properties: {
1391
+ categories: {
1392
+ type: "array",
1393
+ items: {
1394
+ type: "object",
1395
+ properties: {
1396
+ name: { type: "string" },
1397
+ enabled: { type: "boolean" },
1398
+ areCommentsRequired: { type: "boolean" }
1399
+ }
1400
+ }
1401
+ },
1402
+ reportFields: {
1403
+ type: "array",
1404
+ items: {
1405
+ type: "object",
1406
+ properties: {
1407
+ name: { type: "string" },
1408
+ type: { type: "string" },
1409
+ values: {
1410
+ type: "array",
1411
+ items: { type: "string" }
1412
+ }
1413
+ }
1414
+ }
1415
+ },
1416
+ tags: {
1417
+ type: "array",
1418
+ items: {
1419
+ type: "object",
1420
+ properties: {
1421
+ name: { type: "string" },
1422
+ enabled: { type: "boolean" },
1423
+ glCode: { type: "string" },
1424
+ tags: { type: "array" }
1425
+ }
1426
+ }
1427
+ },
1428
+ tax: {
1429
+ type: "object",
1430
+ properties: {
1431
+ name: { type: "string" },
1432
+ default: { type: "string" },
1433
+ rates: {
1434
+ type: "array",
1435
+ items: {
1436
+ type: "object",
1437
+ properties: {
1438
+ rateID: { type: "string" },
1439
+ name: { type: "string" },
1440
+ rate: { type: "number" }
1441
+ }
1442
+ }
1443
+ }
1444
+ }
1445
+ },
1446
+ employees: {
1447
+ type: "array",
1448
+ items: {
1449
+ type: "object",
1450
+ properties: {
1451
+ email: {
1452
+ type: "string",
1453
+ format: "email"
1454
+ },
1455
+ role: { type: "string" },
1456
+ submitsTo: {
1457
+ type: "string",
1458
+ format: "email"
1459
+ },
1460
+ employeeID: { type: "string" }
1461
+ },
1462
+ additionalProperties: true
1463
+ }
1464
+ }
1465
+ },
1466
+ required: [],
1467
+ additionalProperties: true
1468
+ };
1469
+ const listPoliciesOutputSchema = {
1470
+ type: "object",
1471
+ properties: {
1472
+ ...responseEnvelopeSchema.properties,
1473
+ policyList: {
1474
+ type: "array",
1475
+ items: policySummarySchema
1476
+ }
1477
+ },
1478
+ required: ["responseCode"]
1479
+ };
1480
+ const getPolicyOutputSchema = {
1481
+ type: "object",
1482
+ properties: {
1483
+ ...responseEnvelopeSchema.properties,
1484
+ policyInfo: {
1485
+ type: "object",
1486
+ additionalProperties: policyInfoSchema
1487
+ }
1488
+ },
1489
+ required: ["responseCode"]
1490
+ };
1491
+ const createPolicyOutputSchema = {
1492
+ type: "object",
1493
+ properties: {
1494
+ ...responseEnvelopeSchema.properties,
1495
+ policyID: { type: "string" },
1496
+ policyName: { type: "string" }
1497
+ },
1498
+ required: ["responseCode"]
1499
+ };
1500
+ const updatePolicyOutputSchema = {
1501
+ type: "object",
1502
+ properties: { ...responseEnvelopeSchema.properties },
1503
+ required: ["responseCode"]
1504
+ };
1505
+ //#endregion
1506
+ //#region src/outputSchemas/reports.ts
1507
+ const createReportOutputSchema = {
1508
+ type: "object",
1509
+ properties: {
1510
+ ...responseEnvelopeSchema.properties,
1511
+ reportID: { type: "string" },
1512
+ reportName: { type: "string" }
1513
+ },
1514
+ required: ["responseCode"]
1515
+ };
1516
+ const updateReportStatusOutputSchema = {
1517
+ type: "object",
1518
+ properties: {
1519
+ ...responseEnvelopeSchema.properties,
1520
+ reportIDs: {
1521
+ type: "array",
1522
+ items: { type: "string" }
1523
+ },
1524
+ skippedReports: {
1525
+ type: "array",
1526
+ items: reportIssueSchema
1527
+ },
1528
+ failedReports: {
1529
+ type: "array",
1530
+ items: reportIssueSchema
1531
+ }
1532
+ },
1533
+ required: ["responseCode"]
1534
+ };
1535
+ const exportReportOutputSchema = {
1536
+ type: ["string", "object"],
1537
+ properties: { ...responseEnvelopeSchema.properties },
1538
+ required: ["responseCode"]
1539
+ };
1540
+ //#endregion
1541
+ //#region src/actions/cards/index.ts
1542
+ var cards_default = { listCards: (0, _prismatic_io_spectral.action)({
1543
+ display: {
1544
+ description: "Gets the list of credit cards that are assigned at the domain level.",
1545
+ label: "List Cards"
1546
+ },
1547
+ inputs: listCardsInputs,
1548
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1549
+ type: "actionOutput",
1550
+ schema: listCardsOutputSchema
1551
+ }),
1552
+ performSafety: "notAllowed",
1553
+ perform: async (context, { connectionInput, type, domain }) => {
1554
+ const client = createClient(connectionInput, context.debug.enabled);
1555
+ const generatedJson = generatePayload({ inputSettings: {
1556
+ type,
1557
+ domain
1558
+ } }, connectionInput);
1559
+ const { data } = await client.post("", generatedJson);
1560
+ return { data };
1561
+ },
1562
+ examplePerform: async () => listCardsExamplePayload,
1563
+ examplePayload: listCardsExamplePayload
1564
+ }) };
1565
+ //#endregion
1566
+ //#region src/actions/employees/index.ts
1567
+ var employees_default = { updateEmployee: (0, _prismatic_io_spectral.action)({
1568
+ display: {
1569
+ description: "Add, update or remove policy members.",
1570
+ label: "Update Employee"
1571
+ },
1572
+ inputs: updateEmployeeInputs,
1573
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1574
+ type: "actionOutput",
1575
+ schema: updateEmployeeOutputSchema
1576
+ }),
1577
+ performSafety: "notAllowed",
1578
+ perform: async (context, { connectionInput, type, provisioningOptions, onFinish, employees }) => {
1579
+ const client = createClient(connectionInput, context.debug.enabled);
1580
+ const generatedJson = generatePayload({
1581
+ type: JOB_TYPES.UPDATE,
1582
+ inputSettings: {
1583
+ type,
1584
+ entity: EMPLOYEE_UPDATE_SETTINGS.ENTITY
1585
+ },
1586
+ dataSource: EMPLOYEE_UPDATE_SETTINGS.DATA_SOURCE,
1587
+ "dry-run": provisioningOptions.dryRun,
1588
+ onFinish,
1589
+ setEmployeePrimaryPolicy: provisioningOptions.setEmployeePrimaryPolicy,
1590
+ shouldFixApprovalChains: provisioningOptions.shouldFixApprovalChains,
1591
+ employees
1592
+ }, connectionInput);
1593
+ const { data } = await client.post("", generatedJson);
1594
+ return { data };
1595
+ },
1596
+ examplePerform: async () => updateEmployeeExamplePayload,
1597
+ examplePayload: updateEmployeeExamplePayload
1598
+ }) };
1599
+ //#endregion
1600
+ //#region src/actions/expenseRules/index.ts
1601
+ var expenseRules_default = {
1602
+ createExpenseRule: (0, _prismatic_io_spectral.action)({
1603
+ display: {
1604
+ description: "Create expense rules for a given employee on a given policy.",
1605
+ label: "Create Expense Rule"
1606
+ },
1607
+ inputs: createExpenseRuleInputs,
1608
+ performSafety: "notAllowed",
1609
+ perform: async (context, { connectionInput, type, employeeEmail, actions, policyId }) => {
1610
+ const client = createClient(connectionInput, context.debug.enabled);
1611
+ const generatedJson = generatePayload({
1612
+ type: JOB_TYPES.CREATE,
1613
+ inputSettings: {
1614
+ type,
1615
+ employeeEmail,
1616
+ actions,
1617
+ policyID: policyId
1618
+ }
1619
+ }, connectionInput);
1620
+ const { data } = await client.post("", generatedJson);
1621
+ return { data };
1622
+ }
1623
+ }),
1624
+ updateExpenseRule: (0, _prismatic_io_spectral.action)({
1625
+ display: {
1626
+ description: "Update a preexisting expense rule for a given employee on a given policy.",
1627
+ label: "Update Expense Rules"
1628
+ },
1629
+ inputs: updateExpenseRuleInputs,
1630
+ performSafety: "notAllowed",
1631
+ perform: async (context, { connectionInput, type, employeeEmail, actions, policyId, ruleId }) => {
1632
+ const client = createClient(connectionInput, context.debug.enabled);
1633
+ const generatedJson = generatePayload({
1634
+ type: JOB_TYPES.UPDATE,
1635
+ inputSettings: {
1636
+ type,
1637
+ employeeEmail,
1638
+ actions,
1639
+ policyID: policyId,
1640
+ ruleID: ruleId
1641
+ }
1642
+ }, connectionInput);
1643
+ const { data } = await client.post("", generatedJson);
1644
+ return { data };
1645
+ }
1646
+ })
1647
+ };
1648
+ //#endregion
1649
+ //#region src/actions/expenses/index.ts
1650
+ var expenses_default = { createExpense: (0, _prismatic_io_spectral.action)({
1651
+ display: {
1652
+ description: "Create expenses in a user’s account.",
1653
+ label: "Create Expense"
1654
+ },
1655
+ inputs: createExpenseInputs,
1656
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1657
+ type: "actionOutput",
1658
+ schema: createExpenseOutputSchema
1659
+ }),
1660
+ performSafety: "notAllowed",
1661
+ perform: async (context, { connectionInput, type, employeeEmail, transactionList }) => {
1662
+ const client = createClient(connectionInput, context.debug.enabled);
1663
+ const generatedJson = generatePayload({
1664
+ type: JOB_TYPES.CREATE,
1665
+ inputSettings: {
1666
+ type,
1667
+ employeeEmail,
1668
+ transactionList
1669
+ }
1670
+ }, connectionInput);
1671
+ const { data } = await client.post("", generatedJson);
1672
+ return { data };
1673
+ },
1674
+ examplePerform: async () => createExpenseExamplePayload,
1675
+ examplePayload: createExpenseExamplePayload
1676
+ }) };
1677
+ //#endregion
1678
+ //#region src/actions/misc/index.ts
1679
+ var misc_default = { rawRequest: (0, _prismatic_io_spectral.action)({
1680
+ display: {
1681
+ label: "Raw Request",
1682
+ description: "Send a raw HTTP request to the Expensify API."
1683
+ },
1684
+ inputs: rawRequestInputs,
1685
+ performSafety: "notAllowed",
1686
+ perform: async (context, { connectionInput, ...rawRequestInputs }) => {
1687
+ validateConnection(connectionInput);
1688
+ const { data: inputData } = rawRequestInputs;
1689
+ const generatedJson = generatePayload(typeof inputData === "string" ? inputData.trim() ? JSON.parse(inputData) : {} : inputData ?? {}, connectionInput);
1690
+ const { data } = await (0, _prismatic_io_spectral_http.sendRawRequest)(BASE_URL, {
1691
+ ...rawRequestInputs,
1692
+ data: generatedJson,
1693
+ debugRequest: context.debug.enabled
1694
+ }, { Accept: "application/json" });
1695
+ return { data };
1696
+ }
1697
+ }) };
1698
+ //#endregion
1699
+ //#region src/actions/policies/createPolicy.ts
1700
+ const createPolicy = (0, _prismatic_io_spectral.action)({
1701
+ display: {
1702
+ description: "Creates a policy.",
1703
+ label: "Create Policy"
1704
+ },
1705
+ inputs: createPolicyInputs,
1706
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1707
+ type: "actionOutput",
1708
+ schema: createPolicyOutputSchema
1709
+ }),
1710
+ performSafety: "notAllowed",
1711
+ perform: async (context, { connectionInput, type, policyName, plan }) => {
1712
+ const client = createClient(connectionInput, context.debug.enabled);
1713
+ const generatedJson = generatePayload({
1714
+ type: JOB_TYPES.CREATE,
1715
+ inputSettings: {
1716
+ type,
1717
+ policyName,
1718
+ plan
1719
+ }
1720
+ }, connectionInput);
1721
+ const { data } = await client.post("", generatedJson);
1722
+ return { data };
1723
+ },
1724
+ examplePerform: async () => createPolicyExamplePayload,
1725
+ examplePayload: createPolicyExamplePayload
1726
+ });
1727
+ //#endregion
1728
+ //#region src/actions/policies/index.ts
1729
+ var policies_default = {
1730
+ getPolicy: (0, _prismatic_io_spectral.action)({
1731
+ display: {
1732
+ description: "Gets specific information about listed policies.",
1733
+ label: "Get Policy"
1734
+ },
1735
+ inputs: getPolicyInputs,
1736
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1737
+ type: "actionOutput",
1738
+ schema: getPolicyOutputSchema
1739
+ }),
1740
+ performSafety: "notAllowed",
1741
+ perform: async (context, { connectionInput, fields, policyIDList, type, userEmail }) => {
1742
+ const client = createClient(connectionInput, context.debug.enabled);
1743
+ const generatedJson = generatePayload({ inputSettings: {
1744
+ type,
1745
+ fields,
1746
+ policyIDList,
1747
+ userEmail
1748
+ } }, connectionInput);
1749
+ const { data } = await client.post("", generatedJson);
1750
+ return { data };
1751
+ },
1752
+ examplePerform: async () => getPolicyExamplePayload,
1753
+ examplePayload: getPolicyExamplePayload
1754
+ }),
1755
+ listPolicies: (0, _prismatic_io_spectral.action)({
1756
+ display: {
1757
+ description: "Gets a list of policies with some relevant information about them.",
1758
+ label: "List Policies"
1759
+ },
1760
+ inputs: listPoliciesInputs,
1761
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1762
+ type: "actionOutput",
1763
+ schema: listPoliciesOutputSchema
1764
+ }),
1765
+ performSafety: "notAllowed",
1766
+ perform: async (context, { connectionInput, adminOnly, type, userEmail }) => {
1767
+ const client = createClient(connectionInput, context.debug.enabled);
1768
+ const generatedJson = generatePayload({ inputSettings: {
1769
+ type,
1770
+ adminOnly,
1771
+ userEmail
1772
+ } }, connectionInput);
1773
+ const { data } = await client.post("", generatedJson);
1774
+ return { data };
1775
+ },
1776
+ examplePerform: async () => listPoliciesExamplePayload,
1777
+ examplePayload: listPoliciesExamplePayload
1778
+ }),
1779
+ createPolicy,
1780
+ updatePolicy: (0, _prismatic_io_spectral.action)({
1781
+ display: {
1782
+ description: "Manage categories, tags and report fields on a policy.",
1783
+ label: "Update Policy"
1784
+ },
1785
+ inputs: updatePolicyInputs,
1786
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1787
+ type: "actionOutput",
1788
+ schema: updatePolicyOutputSchema
1789
+ }),
1790
+ performSafety: "notAllowed",
1791
+ perform: async (context, { connectionInput, type, categories, policyIDList, policyId, reportFields, tags }) => {
1792
+ const client = createClient(connectionInput, context.debug.enabled);
1793
+ const generatedJson = generatePayload({
1794
+ type: JOB_TYPES.UPDATE,
1795
+ inputSettings: {
1796
+ type,
1797
+ policyID: policyId,
1798
+ policyIDList
1799
+ },
1800
+ categories,
1801
+ tags,
1802
+ reportFields
1803
+ }, connectionInput);
1804
+ const { data } = await client.post("", generatedJson);
1805
+ return { data };
1806
+ },
1807
+ examplePerform: async () => updatePolicyExamplePayload,
1808
+ examplePayload: updatePolicyExamplePayload
1809
+ })
1810
+ };
1811
+ //#endregion
1812
+ //#region src/actions/reports/createReport.ts
1813
+ const createReport = (0, _prismatic_io_spectral.action)({
1814
+ display: {
1815
+ description: "Creates a report, with transactions, in a user’s account.",
1816
+ label: "Create Report"
1817
+ },
1818
+ inputs: createReportInputs,
1819
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1820
+ type: "actionOutput",
1821
+ schema: createReportOutputSchema
1822
+ }),
1823
+ performSafety: "notAllowed",
1824
+ perform: async (context, { connectionInput, type, employeeEmail, expenses, policyId, report }) => {
1825
+ const client = createClient(connectionInput, context.debug.enabled);
1826
+ const generatedJson = generatePayload({
1827
+ type: JOB_TYPES.CREATE,
1828
+ inputSettings: {
1829
+ type,
1830
+ employeeEmail,
1831
+ expenses,
1832
+ policyID: policyId,
1833
+ report
1834
+ }
1835
+ }, connectionInput);
1836
+ const { data } = await client.post("", generatedJson);
1837
+ return { data };
1838
+ },
1839
+ examplePerform: async () => createReportExamplePayload,
1840
+ examplePayload: createReportExamplePayload
1841
+ });
1842
+ //#endregion
1843
+ //#region src/actions/reports/downloadReport.ts
1844
+ const downloadReport = (0, _prismatic_io_spectral.action)({
1845
+ display: {
1846
+ description: "Download reports that were generated with the Report Exporter job.",
1847
+ label: "Download Report"
1848
+ },
1849
+ inputs: downloadReportInputs,
1850
+ performSafety: "safe",
1851
+ perform: async (context, { connectionInput, fileName, fileSystem }) => {
1852
+ const client = createClient(connectionInput, context.debug.enabled);
1853
+ const generatedJson = generatePayload({
1854
+ type: JOB_TYPES.DOWNLOAD,
1855
+ fileName,
1856
+ fileSystem
1857
+ }, connectionInput);
1858
+ const { data } = await client.post("", generatedJson);
1859
+ return { data };
1860
+ }
1861
+ });
1862
+ //#endregion
1863
+ //#region src/actions/reports/exportReport.ts
1864
+ const exportReport = (0, _prismatic_io_spectral.action)({
1865
+ display: {
1866
+ description: "Export expense or report data in a configurable format for analysis or insertion into an accounting package.",
1867
+ label: "Export Report"
1868
+ },
1869
+ inputs: exportReportInputs,
1870
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1871
+ type: "actionOutput",
1872
+ schema: exportReportOutputSchema
1873
+ }),
1874
+ performSafety: "notAllowed",
1875
+ perform: async (context, { connectionInput, status, employeeEmail, fileExtension, additionalFields, onFinish, templateName, approvedAfter, endDate, markAsExportedFilter, policyIDList, reportIdList, startDate }) => {
1876
+ const client = createClient(connectionInput, context.debug.enabled);
1877
+ const generatedJson = generatePayload({
1878
+ type: JOB_TYPES.FILE,
1879
+ onReceive: { immediateResponse: [RETURN_RANDOM_FILE_NAME] },
1880
+ inputSettings: {
1881
+ type: INPUT_SETTINGS_TYPES.COMBINED_REPORT_DATA,
1882
+ filters: {
1883
+ startDate,
1884
+ endDate,
1885
+ approvedAfter,
1886
+ markAsExportedFilter,
1887
+ policyIDList: policyIDList?.join(","),
1888
+ reportIDList: reportIdList?.join(",")
1889
+ },
1890
+ reportState: status,
1891
+ limit: additionalFields.limit,
1892
+ employeeEmail
1893
+ },
1894
+ outputSettings: {
1895
+ fileExtension,
1896
+ fileBasename: additionalFields.fileBasename,
1897
+ includeFullPageReceiptsPdf: additionalFields.includeFullPageReceiptsPdf
1898
+ },
1899
+ test: additionalFields.test,
1900
+ onFinish
1901
+ }, connectionInput);
1902
+ generatedJson.append(FORM_FIELDS.TEMPLATE, templateName);
1903
+ const { data } = await client.post("", generatedJson);
1904
+ return { data };
1905
+ },
1906
+ examplePerform: async () => exportReportExamplePayload,
1907
+ examplePayload: exportReportExamplePayload
1908
+ });
1909
+ //#endregion
1910
+ //#region src/actions/reports/index.ts
1911
+ var reports_default = {
1912
+ createReport,
1913
+ updateReportStatus: (0, _prismatic_io_spectral.action)({
1914
+ display: {
1915
+ description: "Update the status of a report.",
1916
+ label: "Update Report Status"
1917
+ },
1918
+ inputs: updateReportStatusInputs,
1919
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
1920
+ type: "actionOutput",
1921
+ schema: updateReportStatusOutputSchema
1922
+ }),
1923
+ performSafety: "notAllowed",
1924
+ perform: async (context, { connectionInput, type, filters, status }) => {
1925
+ const client = createClient(connectionInput, context.debug.enabled);
1926
+ const generatedJson = generatePayload({
1927
+ type: JOB_TYPES.UPDATE,
1928
+ inputSettings: {
1929
+ type,
1930
+ filters,
1931
+ status
1932
+ }
1933
+ }, connectionInput);
1934
+ const { data } = await client.post("", generatedJson);
1935
+ return { data };
1936
+ },
1937
+ examplePerform: async () => updateReportStatusExamplePayload,
1938
+ examplePayload: updateReportStatusExamplePayload
1939
+ }),
1940
+ downloadReport,
1941
+ exportReport
1942
+ };
1943
+ //#endregion
1944
+ //#region src/actions/index.ts
1945
+ var actions_default = {
1946
+ ...expenseRules_default,
1947
+ ...policies_default,
1948
+ ...reports_default,
1949
+ ...expenses_default,
1950
+ ...cards_default,
1951
+ ...employees_default,
1952
+ ...misc_default
1953
+ };
1954
+ //#endregion
1955
+ //#region src/dataSources/listCards.ts
1956
+ const listCards = (0, _prismatic_io_spectral.dataSource)({
1957
+ display: {
1958
+ label: "List Cards",
1959
+ description: "Returns all Cards."
1960
+ },
1961
+ inputs: listCardsDataSourceInputs,
1962
+ perform: async (_context, { connectionInput, domain, type }) => {
1963
+ const client = createClient(connectionInput, false);
1964
+ const generatedJson = generatePayload({ inputSettings: {
1965
+ type,
1966
+ domain
1967
+ } }, connectionInput);
1968
+ const { data } = await client.post("", generatedJson);
1969
+ if (data?.domainCardList?.length > 0) {
1970
+ const { domainCardList } = data;
1971
+ return { result: domainCardList.map(({ cardName, cardID }) => ({
1972
+ label: cardName,
1973
+ key: cardID
1974
+ })) };
1975
+ }
1976
+ return { result: [] };
1977
+ },
1978
+ dataSourceType: "picklist",
1979
+ examplePayload: listCardsDataSourceExamplePayload
1980
+ });
1981
+ //#endregion
1982
+ //#region src/dataSources/index.ts
1983
+ var dataSources_default = {
1984
+ listPolicies: (0, _prismatic_io_spectral.dataSource)({
1985
+ display: {
1986
+ label: "List Policies",
1987
+ description: "Returns all Policies."
1988
+ },
1989
+ inputs: listPoliciesDataSourceInputs,
1990
+ perform: async (_context, { connectionInput, type }) => {
1991
+ const client = createClient(connectionInput, false);
1992
+ const generatedJson = generatePayload({ inputSettings: {
1993
+ type,
1994
+ adminOnly: false
1995
+ } }, connectionInput);
1996
+ const { data } = await client.post("", generatedJson);
1997
+ if (data?.policyList?.length > 0) {
1998
+ const { policyList } = data;
1999
+ return { result: policyList.map(({ name, id }) => ({
2000
+ label: name,
2001
+ key: id
2002
+ })) };
2003
+ }
2004
+ return { result: [] };
2005
+ },
2006
+ dataSourceType: "picklist",
2007
+ examplePayload: listPoliciesDataSourceExamplePayload
2008
+ }),
2009
+ listCards
2010
+ };
2011
+ //#endregion
2012
+ //#region src/triggers/index.ts
2013
+ var triggers_default = { pollChangesTrigger: (0, _prismatic_io_spectral.pollingTrigger)({
2014
+ display: {
2015
+ label: "New Policies",
2016
+ description: "Checks for new policies in Expensify on a configured schedule."
2017
+ },
2018
+ inputs: pollChangesTriggerInputs,
2019
+ perform: async (context, payload, { connection, showNewRecords }) => {
2020
+ const client = createClient(connection, context.debug.enabled);
2021
+ const body = generatePayload({ inputSettings: { type: INPUT_SETTINGS_TYPES.POLICY_LIST } }, connection);
2022
+ const { data } = await client.post("", body);
2023
+ const policies = data.policyList ?? [];
2024
+ const lastState = context.polling.getState();
2025
+ const currentIds = policies.map((p) => p.id);
2026
+ if (lastState?.knownIds === void 0) {
2027
+ context.polling.setState({ knownIds: currentIds });
2028
+ return {
2029
+ payload: {
2030
+ ...payload,
2031
+ body: { data: {
2032
+ created: [],
2033
+ updated: []
2034
+ } }
2035
+ },
2036
+ polledNoChanges: true
2037
+ };
2038
+ }
2039
+ const knownSet = new Set(lastState.knownIds);
2040
+ const created = policies.filter((p) => !knownSet.has(p.id));
2041
+ context.polling.setState({ knownIds: currentIds });
2042
+ const filteredCreated = showNewRecords ? created : [];
2043
+ if (context.debug.enabled) context.logger.debug(`Polled policies: ${policies.length} total, ${filteredCreated.length} new`);
2044
+ return {
2045
+ payload: {
2046
+ ...payload,
2047
+ body: { data: {
2048
+ created: filteredCreated,
2049
+ updated: []
2050
+ } }
2051
+ },
2052
+ polledNoChanges: filteredCreated.length === 0
2053
+ };
2054
+ },
2055
+ examplePayload: pollChangesTriggerExamplePayload
2056
+ }) };
2057
+ //#endregion
2058
+ //#region src/index.ts
2059
+ var src_default = (0, _prismatic_io_spectral.component)({
2060
+ key: "Expensify",
2061
+ public: true,
2062
+ documentationUrl: "https://prismatic.io/docs/components/Expensify/",
2063
+ display: {
2064
+ label: "Expensify",
2065
+ description: "Expensify provides an industry leading expense management system. Use the Expensify component to programmatically download expense report data for analysis or insertion into an accounting package, provision accounts for new hires, and much more.",
2066
+ iconPath: "icon.png",
2067
+ category: "Application Connectors"
2068
+ },
2069
+ actions: actions_default,
2070
+ triggers: triggers_default,
2071
+ connections: connections_default,
2072
+ dataSources: dataSources_default,
2073
+ hooks: { error: _prismatic_io_spectral_http.handleErrors }
2074
+ });
2075
+ //#endregion
2076
+ //#region npm-dist/.entry.ts
2077
+ var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
2078
+ //#endregion
2079
+ module.exports = _entry_default;