@foxtware/mineral 0.1.8 → 0.1.10

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.
Files changed (186) hide show
  1. package/.creds.yml.sample +43 -1
  2. package/AGENTS.md +6 -1
  3. package/README.md +1 -1
  4. package/api/bleckmann/.gitkeep +0 -0
  5. package/api/bleckmann/bleckmann.constants.js +8 -0
  6. package/api/bleckmann/bleckmann.utils.js +32 -0
  7. package/api/bleckmann/bleckmannAsnGet.js +52 -0
  8. package/api/bleckmann/bleckmannAsnsGet.js +65 -0
  9. package/api/constants.js +2 -1
  10. package/api/github/github.constants.js +11 -0
  11. package/api/github/github.utils.js +65 -0
  12. package/api/github/githubGet.js +144 -0
  13. package/api/github/githubIssueCreate.js +71 -0
  14. package/api/github/githubIssueGet.js +65 -0
  15. package/api/github/githubIssueUpdate.js +71 -0
  16. package/api/github/githubIssuesGet.js +74 -0
  17. package/api/github/githubPullRequestCreate.js +74 -0
  18. package/api/github/githubPullRequestGet.js +65 -0
  19. package/api/github/githubPullRequestMerge.js +77 -0
  20. package/api/github/githubPullRequestUpdate.js +72 -0
  21. package/api/github/githubPullRequestsGet.js +74 -0
  22. package/api/github/githubRepoCreate.js +80 -0
  23. package/api/github/githubRepoDelete.js +60 -0
  24. package/api/github/githubRepoGet.js +61 -0
  25. package/api/github/githubRepoUpdate.js +68 -0
  26. package/api/github/githubReposGet.js +69 -0
  27. package/api/github/githubUserGet.js +64 -0
  28. package/api/linear/linear.utils.js +9 -14
  29. package/api/linear/linearIssuesGet.js +9 -9
  30. package/api/logiwa/logiwa.utils.js +27 -25
  31. package/api/logiwa/logiwaInventoriesGet.js +5 -3
  32. package/api/logiwa/logiwaOrderGet.js +4 -2
  33. package/api/logiwa/logiwaOrdersGet.js +5 -3
  34. package/api/logiwa/logiwaProductGet.js +4 -2
  35. package/api/logiwa/logiwaProductsGet.js +5 -3
  36. package/api/logiwa/logiwaReportGetAvailableToPromise.js +5 -3
  37. package/api/logiwa/logiwaReportGetInventoryCalculation.js +5 -3
  38. package/api/logiwa/logiwaReportGetInventorySnapshot.js +5 -3
  39. package/api/logiwa/logiwaReportGetTotalInventory.js +5 -3
  40. package/api/logiwa/logiwaWebhookStatusGet.js +4 -2
  41. package/api/logiwa/logiwaWebhookSubscribe.js +8 -6
  42. package/api/logiwa/logiwaWebhookUnsubscribe.js +4 -2
  43. package/api/logiwa/logiwaWebhooksGet.js +4 -2
  44. package/api/loop/loop.constants.js +7 -0
  45. package/api/loop/loop.utils.js +37 -0
  46. package/api/loop/loopAllowlistItemsGet.js +42 -0
  47. package/api/loop/loopBlocklistItemsGet.js +46 -0
  48. package/api/loop/loopDestinationsGet.js +42 -0
  49. package/api/loop/loopGet.js +139 -0
  50. package/api/loop/loopReturnGet.js +73 -0
  51. package/api/loop/loopReturnsGet.js +46 -0
  52. package/api/peoplevox/peoplevox.constants.js +1 -1
  53. package/api/peoplevox/peoplevox.sessions.js +54 -0
  54. package/api/peoplevox/peoplevox.utils.js +67 -31
  55. package/api/peoplevox/peoplevoxGetSingle.js +7 -5
  56. package/api/peoplevox/peoplevoxOrderEdit.js +7 -5
  57. package/api/peoplevox/peoplevoxReportGet.js +11 -9
  58. package/api/pipelineSteps.js +49 -0
  59. package/api/shopify/shopify.utils.js +18 -24
  60. package/api/shopify/shopifyBulkMutationDo.js +211 -0
  61. package/api/shopify/shopifyBulkOperationGet.js +86 -0
  62. package/api/shopify/shopifyBulkOperationRunMutation.js +83 -0
  63. package/api/shopify/shopifyCheckoutAndAccountsConfigurationUpdate.js +79 -0
  64. package/api/shopify/shopifyCollectionGet.js +7 -7
  65. package/api/shopify/shopifyCustomerGet.js +6 -6
  66. package/api/shopify/shopifyGet.js +18 -13
  67. package/api/shopify/shopifyGetSingle.js +9 -9
  68. package/api/shopify/shopifyMutationDo.js +6 -6
  69. package/api/shopify/shopifyOrdersGet.js +11 -11
  70. package/api/shopify/shopifyStagedUploadCreate.js +96 -0
  71. package/api/shopify/shopifyTagsAdd.js +1 -1
  72. package/api/shopify/shopifyTagsAddBulk.js +90 -0
  73. package/api/shopify/shopifyTagsRemove.js +1 -1
  74. package/api/slack/slack.utils.js +10 -19
  75. package/api/slack/slackMessagePost.js +11 -11
  76. package/api/starshipit/starshipit.constants.js +8 -0
  77. package/api/starshipit/starshipit.utils.js +71 -0
  78. package/api/starshipit/starshipitAddressCreate.js +77 -0
  79. package/api/starshipit/starshipitAddressDelete.js +55 -0
  80. package/api/starshipit/starshipitAddressUpdate.js +69 -0
  81. package/api/starshipit/starshipitAddressesGet.js +52 -0
  82. package/api/starshipit/starshipitGet.js +146 -0
  83. package/api/starshipit/starshipitOrderDelete.js +102 -0
  84. package/api/starshipit/starshipitOrderGet.js +74 -0
  85. package/api/starshipit/starshipitOrderUpdate.js +109 -0
  86. package/api/starshipit/starshipitOrdersListShipped.js +64 -0
  87. package/api/starshipit/starshipitProductAdd.js +100 -0
  88. package/api/starshipit/starshipitProductsDelete.js +57 -0
  89. package/api/starshipit/starshipitProductsGet.js +49 -0
  90. package/api/starshipit/starshipitTrackingGet.js +69 -0
  91. package/api/stripe/_example.js +48 -0
  92. package/api/stripe/stripe.constants.js +5 -0
  93. package/api/stripe/stripe.utils.js +42 -0
  94. package/api/stripe/stripeCardCharge.js +98 -0
  95. package/api/stripe/stripeCardTokenCreate.js +70 -0
  96. package/api/stripe/stripeChargeCapture.js +63 -0
  97. package/api/stripe/stripeChargeCreate.js +70 -0
  98. package/api/stripe/stripeChargeGet.js +51 -0
  99. package/api/stripe/stripeChargesGet.js +52 -0
  100. package/api/stripe/stripeRefundCreate.js +64 -0
  101. package/api/stripe/stripeRefundGet.js +51 -0
  102. package/api/stripe/stripeRefundsGet.js +52 -0
  103. package/api/stripe/stripeTokenGet.js +51 -0
  104. package/api/stylearcade/stylearcade.constants.js +5 -0
  105. package/api/stylearcade/stylearcade.utils.js +40 -0
  106. package/api/stylearcade/stylearcadeDataGet.js +62 -0
  107. package/api/stylearcade/stylearcadeGet.js +133 -0
  108. package/api/stylearcade/stylearcadeMetadataGet.js +47 -0
  109. package/api/supabase/supabase.utils.js +52 -0
  110. package/api/supabase/supabaseRowDelete.js +95 -0
  111. package/api/supabase/supabaseRowGet.js +58 -0
  112. package/api/supabase/supabaseRowInsert.js +56 -0
  113. package/api/supabase/supabaseRowUpdate.js +58 -0
  114. package/api/supabase/supabaseRpc.js +61 -0
  115. package/api/supabase/supabaseTableGet.js +44 -0
  116. package/api/supabase/supabaseTableGetAll.js +86 -0
  117. package/api/threeclicks/threeclicks.constants.js +8 -0
  118. package/api/threeclicks/threeclicks.utils.js +119 -0
  119. package/api/threeclicks/threeclicksCollectionsGet.js +40 -0
  120. package/api/threeclicks/threeclicksGet.js +138 -0
  121. package/api/threeclicks/threeclicksKeycodeCreate.js +55 -0
  122. package/api/threeclicks/threeclicksKeycodeGet.js +47 -0
  123. package/api/threeclicks/threeclicksPurchaseOrderCreate.js +34 -0
  124. package/api/threeclicks/threeclicksPurchaseOrderCreateBulk.js +34 -0
  125. package/api/threeclicks/threeclicksPurchaseOrderGet.js +33 -0
  126. package/api/threeclicks/threeclicksPurchaseOrderQuantitiesGet.js +33 -0
  127. package/api/threeclicks/threeclicksPurchaseOrderQuantityCreate.js +34 -0
  128. package/api/threeclicks/threeclicksPurchaseOrderQuantityCreateBulk.js +34 -0
  129. package/api/threeclicks/threeclicksPurchaseOrderQuantityUpdate.js +46 -0
  130. package/api/threeclicks/threeclicksPurchaseOrderQuantityUpdateBulk.js +46 -0
  131. package/api/threeclicks/threeclicksPurchaseOrderUpdate.js +35 -0
  132. package/api/threeclicks/threeclicksPurchaseOrdersGet.js +30 -0
  133. package/api/threeclicks/threeclicksShipmentCreate.js +34 -0
  134. package/api/threeclicks/threeclicksShipmentGet.js +33 -0
  135. package/api/threeclicks/threeclicksShipmentOrderAdd.js +38 -0
  136. package/api/threeclicks/threeclicksShipmentOrderQuantityCreate.js +35 -0
  137. package/api/threeclicks/threeclicksShipmentQuantityUpdate.js +35 -0
  138. package/api/threeclicks/threeclicksShipmentStatusUpdate.js +45 -0
  139. package/api/threeclicks/threeclicksShipmentsGet.js +52 -0
  140. package/api/threeclicks/threeclicksSignatureCalculate.js +73 -0
  141. package/api/threeclicks/threeclicksStyleCodesGet.js +46 -0
  142. package/api/threeclicks/threeclicksStyleColourCreate.js +47 -0
  143. package/api/threeclicks/threeclicksStyleColourDelete.js +34 -0
  144. package/api/threeclicks/threeclicksStyleCreate.js +44 -0
  145. package/api/threeclicks/threeclicksStyleDelete.js +33 -0
  146. package/api/threeclicks/threeclicksStyleGet.js +43 -0
  147. package/api/threeclicks/threeclicksStylePriceUpdate.js +70 -0
  148. package/api/threeclicks/threeclicksStyleUpdate.js +47 -0
  149. package/api/threeclicks/threeclicksStylesGet.js +45 -0
  150. package/api/upstash/upstash.utils.js +36 -0
  151. package/api/upstash/upstashDel.js +46 -0
  152. package/api/upstash/upstashExists.js +46 -0
  153. package/api/upstash/upstashGet.js +46 -0
  154. package/api/upstash/upstashSet.js +64 -0
  155. package/api/utils.js +90 -76
  156. package/api/validators.js +1 -1
  157. package/api/workable/workable.constants.js +3 -0
  158. package/api/workable/workable.utils.js +41 -0
  159. package/api/workable/workableGet.js +151 -0
  160. package/api/workable/workableJobCandidateCreate.js +87 -0
  161. package/api/workable/workableJobGet.js +52 -0
  162. package/api/workable/workableJobMembersGet.js +52 -0
  163. package/api/workable/workableJobStagesGet.js +52 -0
  164. package/api/workable/workableJobsGet.js +78 -0
  165. package/api/yotpo/yotpo.utils.js +17 -22
  166. package/api/yotpo/yotpoCampaignsGet.js +6 -6
  167. package/api/yotpo/yotpoCustomerActionRecord.js +7 -7
  168. package/api/yotpo/yotpoCustomerAnniversaryGet.js +7 -7
  169. package/api/yotpo/yotpoCustomerAnniversarySet.js +7 -7
  170. package/api/yotpo/yotpoCustomerBirthdaySet.js +7 -7
  171. package/api/yotpo/yotpoCustomerGet.js +6 -6
  172. package/api/yotpo/yotpoCustomerPointsAdjust.js +7 -7
  173. package/api/yotpo/yotpoCustomerUpsert.js +7 -7
  174. package/api/yotpo/yotpoCustomersRecentGet.js +6 -6
  175. package/api/yotpo/yotpoRedemptionCreate.js +7 -7
  176. package/api/yotpo/yotpoRedemptionOptionsGet.js +6 -6
  177. package/api/yotpo/yotpoVipTiersGet.js +5 -5
  178. package/api/youtube/youtube.constants.js +5 -0
  179. package/api/youtube/youtube.utils.js +77 -0
  180. package/api/youtube/youtubeChannelVideosGet.js +25 -70
  181. package/hosting/.hosting.yml.sample +9 -11
  182. package/hosting/copyCredsToEnv.js +58 -2
  183. package/hosting/deployFromHostingYml.js +9 -2
  184. package/hosting/hosting.utils.js +3 -2
  185. package/package.json +3 -1
  186. package/server.utils.js +1 -0
package/api/utils.js CHANGED
@@ -10,6 +10,10 @@ const { getWorkspace } = require('./workspace');
10
10
  const wait = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms));
11
11
 
12
12
  const objHasAny = (obj, keys) => {
13
+ if (obj == null || typeof obj !== 'object') {
14
+ return false;
15
+ }
16
+
13
17
  return keys.some((key) => obj[key] !== undefined);
14
18
  };
15
19
 
@@ -104,6 +108,30 @@ const getResponseParser = (contentType) => {
104
108
  return (res) => res.text(); // safe default
105
109
  };
106
110
 
111
+ const objectToFormData = (object) => {
112
+ const formData = new FormData();
113
+ for (const [key, value] of Object.entries(object)) {
114
+ formData.append(key, value);
115
+ }
116
+ return formData;
117
+ };
118
+
119
+ const bodyPassesThrough = (body) => {
120
+ if (body == null) {
121
+ return false;
122
+ }
123
+
124
+ if (typeof body === 'string') {
125
+ return true;
126
+ }
127
+
128
+ if (body instanceof FormData) {
129
+ return true;
130
+ }
131
+
132
+ return typeof body.getHeaders === 'function';
133
+ };
134
+
107
135
  const customFetch = async (url, {
108
136
  method = 'get',
109
137
  headers = {},
@@ -119,7 +147,11 @@ const customFetch = async (url, {
119
147
  headers['x-request-id'] = String(Date.now());
120
148
  }
121
149
 
122
- if (body && !headers['Content-Type']) {
150
+ if (body?.getHeaders) {
151
+ Object.assign(headers, body.getHeaders());
152
+ }
153
+
154
+ if (body && !headers['Content-Type'] && !bodyPassesThrough(body)) {
123
155
  headers['Content-Type'] = 'application/json';
124
156
  }
125
157
 
@@ -138,11 +170,11 @@ const customFetch = async (url, {
138
170
  const response = await fetch(url, {
139
171
  method,
140
172
  headers,
141
- ...body
142
- ? { body: typeof body === 'string'
143
- ? body
144
- : JSON.stringify(body)
145
- } : {},
173
+ ...body && {
174
+ body: bodyPassesThrough(body)
175
+ ? body
176
+ : JSON.stringify(body),
177
+ },
146
178
  });
147
179
 
148
180
  const responseContentType = response.headers.get('content-type');
@@ -412,89 +444,57 @@ class Chain {
412
444
  }
413
445
  }
414
446
 
415
- // TODO: client wrapper enabling auth and retrying with different auth
416
-
417
447
  class FetchClient {
418
448
  constructor({
419
- context, // necessary data for preparer and interpreters to refer to
420
- requestPreparer, // a function that updates requests before sending
421
- responseInterpreter, // a function that transforms responses to report back
449
+ pipeline = ['fetch'], // an array of functions that transform the request and response, including a string 'fetch' step.
422
450
  } = {}) {
423
- this.context = context;
424
- this.requestPreparer = requestPreparer; // can be a Chain
425
- this.responseInterpreter = responseInterpreter; // can be a Chain
451
+ if (!this.pipelineHasFetchStep(pipeline)) {
452
+ throw new Error('Pipeline must have a fetch step');
453
+ }
454
+ this.pipeline = pipeline;
455
+ }
456
+
457
+ pipelineHasFetchStep = (pipeline) => {
458
+ return pipeline.find(step => step === 'fetch');
459
+ }
460
+
461
+ async #fetch(state) {
462
+ const { requestPayload } = state;
463
+
464
+ return {
465
+ response: await customFetch(
466
+ requestPayload.url,
467
+ requestPayload,
468
+ ),
469
+ };
426
470
  }
427
471
 
428
472
  async fetch({
429
- url,
473
+ // url, body, etc.
474
+ requestPayload,
430
475
 
431
- // customFetch payload
432
- method,
433
- headers,
434
- params,
435
- body,
436
-
437
- responseInterpreter,
476
+ // additional information to inform behaviour
477
+ context,
438
478
 
439
- context = {},
479
+ // options for the fetch itself, as opposed to data it uses
440
480
  inspect = false,
441
481
  } = {}) {
442
482
 
443
- let mergedContext = {
444
- ...(this.context ?? {}),
445
- ...(context ?? {}),
446
- };
447
- inspect && logDeep({ mergedContext });
448
- inspect && await askQuestion('?');
449
-
450
- let requestPayload = {
451
- url,
452
- ...(method ? { method } : {}),
453
- ...(headers ? { headers } : {}),
454
- ...(params ? { params } : {}),
455
- ...(body ? { body } : {}),
456
- };
457
- inspect && logDeep({ requestPayload });
458
- inspect && await askQuestion('?');
459
-
460
- if (this.requestPreparer) {
461
- if (this.requestPreparer.run) {
462
- ({ requestPayload, context: mergedContext } = await this.requestPreparer.run(
463
- { requestPayload, context: mergedContext },
464
- { inspect },
465
- ));
466
- } else {
467
- const result = await this.requestPreparer(requestPayload, mergedContext);
468
- if (result) {
469
- requestPayload = result;
470
- }
471
- }
472
- }
473
- inspect && logDeep({ requestPayload, mergedContext });
474
- inspect && await askQuestion('?');
483
+ const { pipeline } = this;
484
+
485
+ const pipelineChain = new Chain(pipeline.map(step => {
486
+ return step === 'fetch'
487
+ ? this.#fetch
488
+ : step;
489
+ }));
475
490
 
476
- let response = await customFetch(
477
- requestPayload.url,
491
+ // fetch step will add response to this, for subsequent steps
492
+ const state = await pipelineChain.run({
478
493
  requestPayload,
479
- );
480
- inspect && logDeep({ response });
481
- inspect && await askQuestion('?');
482
-
483
- const usedResponseInterpreter = responseInterpreter || this.responseInterpreter;
484
- if (usedResponseInterpreter) {
485
- if (usedResponseInterpreter.run) {
486
- ({ response, context: mergedContext } = await usedResponseInterpreter.run(
487
- { response, context: mergedContext },
488
- { inspect },
489
- ));
490
- } else {
491
- response = await usedResponseInterpreter(response, mergedContext);
492
- }
493
- }
494
- inspect && logDeep({ response });
495
- inspect && await askQuestion('?');
494
+ context,
495
+ }, { inspect });
496
496
 
497
- return response;
497
+ return state.response;
498
498
  }
499
499
  }
500
500
 
@@ -606,6 +606,17 @@ const ensureArray = (value) => {
606
606
  return [value];
607
607
  };
608
608
 
609
+ const objectArrayToJsonl = (objects) => {
610
+ return objects.map((object) => JSON.stringify(object)).join('\n');
611
+ };
612
+
613
+ const jsonlToObjectArray = (jsonl) => {
614
+ return jsonl
615
+ .split('\n')
616
+ .filter((line) => line.trim())
617
+ .map((line) => JSON.parse(line));
618
+ };
619
+
609
620
  const everyIfArray = (func, value) => {
610
621
  if (Array.isArray(value)) {
611
622
  if (value.length === 0) {
@@ -1153,7 +1164,10 @@ module.exports = {
1153
1164
  Chain,
1154
1165
  FetchClient,
1155
1166
  fetchClientCommonSteps,
1167
+ objectToFormData,
1156
1168
  ensureArray,
1169
+ objectArrayToJsonl,
1170
+ jsonlToObjectArray,
1157
1171
  everyIfArray,
1158
1172
  simpleSort,
1159
1173
  arrayToChunks,
@@ -1167,4 +1181,4 @@ module.exports = {
1167
1181
  sentenceCaseString,
1168
1182
  ArgsWarden,
1169
1183
  gidToId,
1170
- };
1184
+ };
package/api/validators.js CHANGED
@@ -9,4 +9,4 @@ const credsValidator = (creds) => {
9
9
 
10
10
  module.exports = {
11
11
  credsValidator,
12
- };
12
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ MAX_PER_PAGE: 100,
3
+ };
@@ -0,0 +1,41 @@
1
+ const { resolveCreds } = require('../pipelineSteps');
2
+ const {
3
+ FetchClient,
4
+ appendUrlToBase,
5
+ fetchClientCommonSteps,
6
+ } = require('../utils');
7
+
8
+ // TODO: Allow creds failure (e.g. missing BASE_URL / ACCESS_TOKEN → INVALID_CREDS before fetch)
9
+ const useAuthHeaders = async (state) => {
10
+ const { requestPayload, context } = state;
11
+ const { creds } = context;
12
+ const {
13
+ BASE_URL,
14
+ ACCESS_TOKEN,
15
+ } = creds;
16
+
17
+ return {
18
+ requestPayload: {
19
+ ...requestPayload,
20
+ url: appendUrlToBase(BASE_URL, requestPayload.url),
21
+ headers: {
22
+ Accept: 'application/json',
23
+ Authorization: `Bearer ${ ACCESS_TOKEN }`,
24
+ ...requestPayload.headers,
25
+ },
26
+ },
27
+ };
28
+ };
29
+
30
+ const workableClient = new FetchClient({
31
+ pipeline: [
32
+ resolveCreds,
33
+ useAuthHeaders,
34
+ 'fetch',
35
+ fetchClientCommonSteps.exitEarlyOnNotOk,
36
+ ],
37
+ });
38
+
39
+ module.exports = {
40
+ workableClient,
41
+ };
@@ -0,0 +1,151 @@
1
+ // https://workable.readme.io/reference/jobs
2
+
3
+ const { ArgsWarden, Getter } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { workableClient } = require('../workable/workable.utils');
6
+ const { MAX_PER_PAGE } = require('../workable/workable.constants');
7
+
8
+ const argsWarden = new ArgsWarden([
9
+ ['credsPayload', credsValidator],
10
+ ['url'],
11
+ ]);
12
+
13
+ const digResults = (data, resultsKey) => {
14
+ if (resultsKey) {
15
+ return data?.[resultsKey] ?? [];
16
+ }
17
+
18
+ const arrayEntry = Object.entries(data || {}).find(([, value]) => Array.isArray(value));
19
+ return arrayEntry ? arrayEntry[1] : [];
20
+ };
21
+
22
+ const workableGetPacket = async (
23
+ credsPayload,
24
+ url,
25
+ {
26
+ params,
27
+ perPage = MAX_PER_PAGE,
28
+ } = {},
29
+ ) => {
30
+ return workableClient.fetch({
31
+ requestPayload: {
32
+ url,
33
+ params: {
34
+ limit: Math.min(perPage, MAX_PER_PAGE),
35
+ ...params,
36
+ },
37
+ },
38
+ context: {
39
+ credsPayload,
40
+ },
41
+ });
42
+ };
43
+
44
+ const workableGetPaginator = async (currentParams, response) => {
45
+ const { args, options } = currentParams;
46
+
47
+ if (!response?.ok) {
48
+ return [true];
49
+ }
50
+
51
+ const nextUrl = response?.data?.paging?.next;
52
+ if (!nextUrl) {
53
+ return [true];
54
+ }
55
+
56
+ const nextParams = Object.fromEntries(new URL(nextUrl).searchParams.entries());
57
+
58
+ return [false, {
59
+ args,
60
+ options: {
61
+ ...options,
62
+ params: nextParams,
63
+ },
64
+ }];
65
+ };
66
+
67
+ const workableGet = async (
68
+ returnGetter,
69
+
70
+ credsPayload,
71
+ url,
72
+ {
73
+ params,
74
+ perPage = MAX_PER_PAGE,
75
+ resultsKey,
76
+ ...getterOptions
77
+ } = {},
78
+ ) => {
79
+
80
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
81
+ credsPayload,
82
+ url,
83
+ });
84
+ if (rejectResponse) {
85
+ return rejectResponse;
86
+ }
87
+
88
+ const getter = new Getter(
89
+ {
90
+ args: [credsPayload, url],
91
+ options: {
92
+ params,
93
+ perPage,
94
+ },
95
+ },
96
+ {
97
+ func: workableGetPacket,
98
+ digester: (response) => {
99
+ if (!response?.ok) {
100
+ return [];
101
+ }
102
+
103
+ return digResults(response.data, resultsKey);
104
+ },
105
+ paginator: workableGetPaginator,
106
+ ...getterOptions,
107
+ },
108
+ );
109
+
110
+ if (returnGetter) {
111
+ return getter;
112
+ }
113
+
114
+ const data = await getter.run({ returnAll: true });
115
+
116
+ return {
117
+ ok: true,
118
+ data,
119
+ };
120
+ };
121
+
122
+ const funcApiConfig = {
123
+ argsWarden,
124
+ };
125
+
126
+ module.exports = {
127
+ workableGet: (...args) => workableGet(false, ...args),
128
+ workableGetter: (...args) => workableGet(true, ...args),
129
+ funcApiConfig,
130
+ };
131
+
132
+ /*
133
+ curl -X POST "http://localhost:8000/workableGet" \
134
+ -H "Content-Type: application/json" \
135
+ -d '{
136
+ "credsPayload": { "credsPath": "workable" },
137
+ "url": "/jobs"
138
+ }'
139
+
140
+ curl -X POST "http://localhost:8000/workableGet" \
141
+ -H "Content-Type: application/json" \
142
+ -d '{
143
+ "credsPayload": { "credsPath": "workable" },
144
+ "url": "/jobs",
145
+ "options": {
146
+ "params": { "state": "published" },
147
+ "resultsKey": "jobs",
148
+ "limit": 10
149
+ }
150
+ }'
151
+ */
@@ -0,0 +1,87 @@
1
+ // https://workable.readme.io/reference/job-candidates-create
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { workableClient } = require('../workable/workable.utils');
6
+
7
+ const candidateValidator = (candidate) => {
8
+ return Boolean(candidate) && typeof candidate === 'object';
9
+ };
10
+
11
+ const argsWarden = new ArgsWarden([
12
+ ['credsPayload', credsValidator],
13
+ ['shortcode'],
14
+ ['candidate', candidateValidator],
15
+ ]);
16
+
17
+ const workableJobCandidateCreate = async (
18
+ credsPayload,
19
+ shortcode,
20
+ candidate,
21
+ {
22
+ stage,
23
+ sourced = true,
24
+ } = {},
25
+ ) => {
26
+
27
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
28
+ credsPayload,
29
+ shortcode,
30
+ candidate,
31
+ });
32
+ if (rejectResponse) {
33
+ return rejectResponse;
34
+ }
35
+
36
+ return workableClient.fetch({
37
+ requestPayload: {
38
+ url: `/jobs/${ shortcode }/candidates`,
39
+ method: 'post',
40
+ body: {
41
+ sourced,
42
+ ...stage !== undefined && { stage },
43
+ candidate,
44
+ },
45
+ },
46
+ context: {
47
+ credsPayload,
48
+ },
49
+ });
50
+ };
51
+
52
+ const funcApiConfig = {
53
+ argsWarden,
54
+ };
55
+
56
+ module.exports = {
57
+ workableJobCandidateCreate,
58
+ funcApiConfig,
59
+ };
60
+
61
+ /*
62
+ curl -X POST "http://localhost:8000/workableJobCandidateCreate" \
63
+ -H "Content-Type: application/json" \
64
+ -d '{
65
+ "credsPayload": { "credsPath": "workable" },
66
+ "shortcode": "RKT001",
67
+ "candidate": {
68
+ "name": "Jessie",
69
+ "email": "jessie@teamrocket.org"
70
+ }
71
+ }'
72
+
73
+ curl -X POST "http://localhost:8000/workableJobCandidateCreate" \
74
+ -H "Content-Type: application/json" \
75
+ -d '{
76
+ "credsPayload": { "credsPath": "workable" },
77
+ "shortcode": "RKT001",
78
+ "candidate": {
79
+ "name": "James",
80
+ "email": "james@teamrocket.org"
81
+ },
82
+ "options": {
83
+ "sourced": false,
84
+ "stage": "applied"
85
+ }
86
+ }'
87
+ */
@@ -0,0 +1,52 @@
1
+ // https://workable.readme.io/reference/jobsshortcode
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { workableClient } = require('../workable/workable.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ['shortcode'],
10
+ ]);
11
+
12
+ const workableJobGet = async (
13
+ credsPayload,
14
+ shortcode,
15
+ options = {},
16
+ ) => {
17
+
18
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
19
+ credsPayload,
20
+ shortcode,
21
+ });
22
+ if (rejectResponse) {
23
+ return rejectResponse;
24
+ }
25
+
26
+ return workableClient.fetch({
27
+ requestPayload: {
28
+ url: `/jobs/${ shortcode }`,
29
+ },
30
+ context: {
31
+ credsPayload,
32
+ },
33
+ });
34
+ };
35
+
36
+ const funcApiConfig = {
37
+ argsWarden,
38
+ };
39
+
40
+ module.exports = {
41
+ workableJobGet,
42
+ funcApiConfig,
43
+ };
44
+
45
+ /*
46
+ curl -X POST "http://localhost:8000/workableJobGet" \
47
+ -H "Content-Type: application/json" \
48
+ -d '{
49
+ "credsPayload": { "credsPath": "workable" },
50
+ "shortcode": "RKT001"
51
+ }'
52
+ */
@@ -0,0 +1,52 @@
1
+ // https://workable.readme.io/reference/job-members
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { workableClient } = require('../workable/workable.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ['shortcode'],
10
+ ]);
11
+
12
+ const workableJobMembersGet = async (
13
+ credsPayload,
14
+ shortcode,
15
+ options = {},
16
+ ) => {
17
+
18
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
19
+ credsPayload,
20
+ shortcode,
21
+ });
22
+ if (rejectResponse) {
23
+ return rejectResponse;
24
+ }
25
+
26
+ return workableClient.fetch({
27
+ requestPayload: {
28
+ url: `/jobs/${ shortcode }/members`,
29
+ },
30
+ context: {
31
+ credsPayload,
32
+ },
33
+ });
34
+ };
35
+
36
+ const funcApiConfig = {
37
+ argsWarden,
38
+ };
39
+
40
+ module.exports = {
41
+ workableJobMembersGet,
42
+ funcApiConfig,
43
+ };
44
+
45
+ /*
46
+ curl -X POST "http://localhost:8000/workableJobMembersGet" \
47
+ -H "Content-Type: application/json" \
48
+ -d '{
49
+ "credsPayload": { "credsPath": "workable" },
50
+ "shortcode": "RKT001"
51
+ }'
52
+ */
@@ -0,0 +1,52 @@
1
+ // https://workable.readme.io/reference/job-stages
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { workableClient } = require('../workable/workable.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ['shortcode'],
10
+ ]);
11
+
12
+ const workableJobStagesGet = async (
13
+ credsPayload,
14
+ shortcode,
15
+ options = {},
16
+ ) => {
17
+
18
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
19
+ credsPayload,
20
+ shortcode,
21
+ });
22
+ if (rejectResponse) {
23
+ return rejectResponse;
24
+ }
25
+
26
+ return workableClient.fetch({
27
+ requestPayload: {
28
+ url: `/jobs/${ shortcode }/stages`,
29
+ },
30
+ context: {
31
+ credsPayload,
32
+ },
33
+ });
34
+ };
35
+
36
+ const funcApiConfig = {
37
+ argsWarden,
38
+ };
39
+
40
+ module.exports = {
41
+ workableJobStagesGet,
42
+ funcApiConfig,
43
+ };
44
+
45
+ /*
46
+ curl -X POST "http://localhost:8000/workableJobStagesGet" \
47
+ -H "Content-Type: application/json" \
48
+ -d '{
49
+ "credsPayload": { "credsPath": "workable" },
50
+ "shortcode": "RKT001"
51
+ }'
52
+ */