@foxtware/mineral 0.1.8 → 0.1.9

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 (55) hide show
  1. package/.creds.yml.sample +22 -1
  2. package/api/loop/loop.constants.js +7 -0
  3. package/api/loop/loop.utils.js +43 -0
  4. package/api/loop/loopAllowlistItemsGet.js +42 -0
  5. package/api/loop/loopBlocklistItemsGet.js +46 -0
  6. package/api/loop/loopDestinationsGet.js +42 -0
  7. package/api/loop/loopGet.js +143 -0
  8. package/api/loop/loopReturnGet.js +73 -0
  9. package/api/loop/loopReturnsGet.js +46 -0
  10. package/api/peoplevox/peoplevox.sessions.js +87 -0
  11. package/api/peoplevox/peoplevox.utils.js +7 -15
  12. package/api/shopify/shopifyCollectionGet.js +1 -1
  13. package/api/shopify/shopifyTagsAdd.js +1 -1
  14. package/api/shopify/shopifyTagsRemove.js +1 -1
  15. package/api/stripe/_example.js +48 -0
  16. package/api/stripe/stripe.constants.js +5 -0
  17. package/api/stripe/stripe.utils.js +47 -0
  18. package/api/stripe/stripeCardCharge.js +98 -0
  19. package/api/stripe/stripeCardTokenCreate.js +70 -0
  20. package/api/stripe/stripeChargeCapture.js +63 -0
  21. package/api/stripe/stripeChargeCreate.js +70 -0
  22. package/api/stripe/stripeChargeGet.js +51 -0
  23. package/api/stripe/stripeChargesGet.js +52 -0
  24. package/api/stripe/stripeRefundCreate.js +64 -0
  25. package/api/stripe/stripeRefundGet.js +51 -0
  26. package/api/stripe/stripeRefundsGet.js +52 -0
  27. package/api/stripe/stripeTokenGet.js +51 -0
  28. package/api/supabase/supabase.utils.js +52 -0
  29. package/api/supabase/supabaseRowDelete.js +95 -0
  30. package/api/supabase/supabaseRowGet.js +58 -0
  31. package/api/supabase/supabaseRowInsert.js +56 -0
  32. package/api/supabase/supabaseRowUpdate.js +58 -0
  33. package/api/supabase/supabaseRpc.js +61 -0
  34. package/api/supabase/supabaseTableGet.js +44 -0
  35. package/api/supabase/supabaseTableGetAll.js +86 -0
  36. package/api/upstash/upstash.utils.js +36 -0
  37. package/api/upstash/upstashDel.js +46 -0
  38. package/api/upstash/upstashExists.js +46 -0
  39. package/api/upstash/upstashGet.js +46 -0
  40. package/api/upstash/upstashSet.js +64 -0
  41. package/api/utils.js +47 -1
  42. package/api/workable/workable.constants.js +3 -0
  43. package/api/workable/workable.utils.js +46 -0
  44. package/api/workable/workableGet.js +146 -0
  45. package/api/workable/workableJobCandidateCreate.js +87 -0
  46. package/api/workable/workableJobGet.js +52 -0
  47. package/api/workable/workableJobMembersGet.js +52 -0
  48. package/api/workable/workableJobStagesGet.js +52 -0
  49. package/api/workable/workableJobsGet.js +78 -0
  50. package/hosting/.hosting.yml.sample +9 -11
  51. package/hosting/copyCredsToEnv.js +58 -2
  52. package/hosting/deployFromHostingYml.js +9 -2
  53. package/hosting/hosting.utils.js +3 -2
  54. package/package.json +3 -1
  55. package/server.utils.js +1 -0
@@ -0,0 +1,64 @@
1
+ const { ArgsWarden } = require('../utils');
2
+ const { credsValidator } = require('../validators');
3
+ const { getRedisInstance } = require('../upstash/upstash.utils');
4
+
5
+ const argsWarden = new ArgsWarden([
6
+ ['credsPayload', credsValidator],
7
+ ['key'],
8
+ ['value'],
9
+ ]);
10
+
11
+ const upstashSet = async (
12
+ credsPayload,
13
+ key,
14
+ value,
15
+ {
16
+ ex,
17
+ nx,
18
+ xx,
19
+ ...upstashSetOptions
20
+ } = {},
21
+ ) => {
22
+
23
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
24
+ credsPayload,
25
+ key,
26
+ value,
27
+ });
28
+ if (rejectResponse) {
29
+ return rejectResponse;
30
+ }
31
+
32
+ const redis = await getRedisInstance(credsPayload);
33
+
34
+ try {
35
+ const result = await redis.set(key, value, {
36
+ ...(ex !== undefined && { ex }),
37
+ ...(nx !== undefined && { nx }),
38
+ ...(xx !== undefined && { xx }),
39
+ ...upstashSetOptions,
40
+ });
41
+
42
+ return {
43
+ ok: true,
44
+ data: result,
45
+ };
46
+ } catch (error) {
47
+ console.error('upstashSet error', error);
48
+ return {
49
+ ok: false,
50
+ error: {
51
+ message: error.message,
52
+ },
53
+ };
54
+ }
55
+ };
56
+
57
+ const funcApiConfig = {
58
+ argsWarden,
59
+ };
60
+
61
+ module.exports = {
62
+ upstashSet,
63
+ funcApiConfig,
64
+ };
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
 
@@ -423,9 +427,10 @@ class FetchClient {
423
427
  this.context = context;
424
428
  this.requestPreparer = requestPreparer; // can be a Chain
425
429
  this.responseInterpreter = responseInterpreter; // can be a Chain
430
+ this.layers = [];
426
431
  }
427
432
 
428
- async fetch({
433
+ async #fetch({
429
434
  url,
430
435
 
431
436
  // customFetch payload
@@ -496,6 +501,47 @@ class FetchClient {
496
501
 
497
502
  return response;
498
503
  }
504
+
505
+ use(layer) {
506
+ this.layers.push(layer);
507
+ }
508
+
509
+ async fetch(fetchPayload) {
510
+ const coreFetch = (payload) => this.#fetch(payload);
511
+
512
+ let layeredFetch = coreFetch;
513
+ for (const layer of [...this.layers].reverse()) {
514
+ const currentNext = layeredFetch; // capture this iteration's `next`
515
+ layeredFetch = (payload) => layer(payload, currentNext);
516
+ }
517
+
518
+ return await layeredFetch(fetchPayload);
519
+ }
520
+
521
+ /* Example layer
522
+
523
+ const withDressColours = async (payload, next) => {
524
+
525
+ let response = await next({
526
+ ...payload,
527
+ headers: { ...payload.headers, dress: 'blue/white' },
528
+ });
529
+
530
+ if (!response.ok) {
531
+ console.warn('blue/white failed, retrying with black/gold');
532
+ response = await next({
533
+ ...payload,
534
+ headers: { ...payload.headers, dress: 'black/gold' },
535
+ });
536
+ }
537
+
538
+ return response;
539
+
540
+ };
541
+
542
+ client.use(withDressColours);
543
+
544
+ */
499
545
  }
500
546
 
501
547
  const fetchClientCommonSteps = {
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ MAX_PER_PAGE: 100,
3
+ };
@@ -0,0 +1,46 @@
1
+ const {
2
+ FetchClient,
3
+ Chain,
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 addUrlAndAuthHeaders = 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
+ 'Content-Type': 'application/json',
23
+ Accept: 'application/json',
24
+ Authorization: `Bearer ${ ACCESS_TOKEN }`,
25
+ ...requestPayload.headers,
26
+ },
27
+ },
28
+ };
29
+ };
30
+
31
+ const workableClientRequestPreparer = new Chain([
32
+ addUrlAndAuthHeaders,
33
+ ]);
34
+
35
+ const workableClientResponseInterpreter = new Chain([
36
+ fetchClientCommonSteps.exitEarlyOnNotOk,
37
+ ]);
38
+
39
+ const workableClient = new FetchClient({
40
+ requestPreparer: workableClientRequestPreparer,
41
+ responseInterpreter: workableClientResponseInterpreter,
42
+ });
43
+
44
+ module.exports = {
45
+ workableClient,
46
+ };
@@ -0,0 +1,146 @@
1
+ // https://workable.readme.io/reference/jobs
2
+
3
+ const { credsFromPayload, 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
+ creds,
24
+ url,
25
+ {
26
+ params,
27
+ perPage = MAX_PER_PAGE,
28
+ } = {},
29
+ ) => {
30
+ return workableClient.fetch({
31
+ url,
32
+ params: {
33
+ limit: Math.min(perPage, MAX_PER_PAGE),
34
+ ...params,
35
+ },
36
+ context: {
37
+ creds,
38
+ },
39
+ });
40
+ };
41
+
42
+ const workableGetPaginator = async (currentParams, response) => {
43
+ const { args, options } = currentParams;
44
+
45
+ if (!response?.ok) {
46
+ return [true];
47
+ }
48
+
49
+ const nextUrl = response?.data?.paging?.next;
50
+ if (!nextUrl) {
51
+ return [true];
52
+ }
53
+
54
+ const nextParams = Object.fromEntries(new URL(nextUrl).searchParams.entries());
55
+
56
+ return [false, {
57
+ args,
58
+ options: {
59
+ ...options,
60
+ params: nextParams,
61
+ },
62
+ }];
63
+ };
64
+
65
+ const workableGet = async (
66
+ returnGetter,
67
+
68
+ credsPayload,
69
+ url,
70
+ {
71
+ params,
72
+ perPage = MAX_PER_PAGE,
73
+ resultsKey,
74
+ ...getterOptions
75
+ } = {},
76
+ ) => {
77
+
78
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
79
+ credsPayload,
80
+ url,
81
+ });
82
+ if (rejectResponse) {
83
+ return rejectResponse;
84
+ }
85
+
86
+ const creds = await credsFromPayload(credsPayload);
87
+
88
+ const getter = new Getter(
89
+ {
90
+ args: [creds, 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
+ return getter.run({ returnAll: true });
115
+ };
116
+
117
+ const funcApiConfig = {
118
+ argsWarden,
119
+ };
120
+
121
+ module.exports = {
122
+ workableGet: (...args) => workableGet(false, ...args),
123
+ workableGetter: (...args) => workableGet(true, ...args),
124
+ funcApiConfig,
125
+ };
126
+
127
+ /*
128
+ curl -X POST "http://localhost:8000/workableGet" \
129
+ -H "Content-Type: application/json" \
130
+ -d '{
131
+ "credsPayload": { "credsPath": "workable" },
132
+ "url": "/jobs"
133
+ }'
134
+
135
+ curl -X POST "http://localhost:8000/workableGet" \
136
+ -H "Content-Type: application/json" \
137
+ -d '{
138
+ "credsPayload": { "credsPath": "workable" },
139
+ "url": "/jobs",
140
+ "options": {
141
+ "params": { "state": "published" },
142
+ "resultsKey": "jobs",
143
+ "limit": 10
144
+ }
145
+ }'
146
+ */
@@ -0,0 +1,87 @@
1
+ // https://workable.readme.io/reference/job-candidates-create
2
+
3
+ const { credsFromPayload, 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
+ const creds = await credsFromPayload(credsPayload);
37
+
38
+ return workableClient.fetch({
39
+ url: `/jobs/${ shortcode }/candidates`,
40
+ method: 'post',
41
+ body: {
42
+ sourced,
43
+ ...stage !== undefined && { stage },
44
+ candidate,
45
+ },
46
+ context: {
47
+ creds,
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 { credsFromPayload, 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
+ const creds = await credsFromPayload(credsPayload);
27
+
28
+ return workableClient.fetch({
29
+ url: `/jobs/${ shortcode }`,
30
+ context: {
31
+ creds,
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 { credsFromPayload, 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
+ const creds = await credsFromPayload(credsPayload);
27
+
28
+ return workableClient.fetch({
29
+ url: `/jobs/${ shortcode }/members`,
30
+ context: {
31
+ creds,
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 { credsFromPayload, 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
+ const creds = await credsFromPayload(credsPayload);
27
+
28
+ return workableClient.fetch({
29
+ url: `/jobs/${ shortcode }/stages`,
30
+ context: {
31
+ creds,
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
+ */
@@ -0,0 +1,78 @@
1
+ // https://workable.readme.io/reference/jobs
2
+
3
+ const { ArgsWarden } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { workableGet } = require('../workable/workableGet');
6
+ const { MAX_PER_PAGE } = require('../workable/workable.constants');
7
+
8
+ const argsWarden = new ArgsWarden([
9
+ ['credsPayload', credsValidator],
10
+ ]);
11
+
12
+ const workableJobsGet = async (
13
+ credsPayload,
14
+ {
15
+ state,
16
+ sinceId,
17
+ maxId,
18
+ createdAfter,
19
+ updatedAfter,
20
+ includeFields,
21
+ perPage,
22
+ ...getterOptions
23
+ } = {},
24
+ ) => {
25
+
26
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({ credsPayload });
27
+ if (rejectResponse) {
28
+ return rejectResponse;
29
+ }
30
+
31
+ const normalisedIncludeFields = Array.isArray(includeFields)
32
+ ? includeFields.join(',')
33
+ : includeFields;
34
+
35
+ const params = {
36
+ ...state !== undefined && { state },
37
+ ...sinceId !== undefined && { since_id: sinceId },
38
+ ...maxId !== undefined && { max_id: maxId },
39
+ ...createdAfter !== undefined && { created_after: createdAfter },
40
+ ...updatedAfter !== undefined && { updated_after: updatedAfter },
41
+ ...normalisedIncludeFields !== undefined && { include_fields: normalisedIncludeFields },
42
+ };
43
+
44
+ return workableGet(credsPayload, '/jobs', {
45
+ params,
46
+ perPage: perPage ?? MAX_PER_PAGE,
47
+ resultsKey: 'jobs',
48
+ ...getterOptions,
49
+ });
50
+ };
51
+
52
+ const funcApiConfig = {
53
+ argsWarden,
54
+ };
55
+
56
+ module.exports = {
57
+ workableJobsGet,
58
+ funcApiConfig,
59
+ };
60
+
61
+ /*
62
+ curl -X POST "http://localhost:8000/workableJobsGet" \
63
+ -H "Content-Type: application/json" \
64
+ -d '{
65
+ "credsPayload": { "credsPath": "workable" }
66
+ }'
67
+
68
+ curl -X POST "http://localhost:8000/workableJobsGet" \
69
+ -H "Content-Type: application/json" \
70
+ -d '{
71
+ "credsPayload": { "credsPath": "workable" },
72
+ "options": {
73
+ "state": "published",
74
+ "perPage": 10,
75
+ "includeFields": ["description", "requirements"]
76
+ }
77
+ }'
78
+ */
@@ -5,19 +5,17 @@ google_cloud_info:
5
5
  # TODO: consider credsPayload in google_cloud_info instead of workspace .creds.yml
6
6
 
7
7
  functions:
8
- exampleFunction:
9
- max_instances: 1
10
- timeout: 300s
11
- before_wrappers:
12
- - allowCrossOriginCallsAndHandleOptions
13
- - requireHostedApiKey
14
- # entry_point: otherHandlerName
15
-
16
8
  pokemonPokeballThrow:
9
+ entry_point: functionWithDifferentNameIfNeeded
17
10
  max_instances: 1
18
11
  before_wrappers:
19
- - checkTrainer
12
+ - checkPokeballInventory
13
+ after_wrappers:
14
+ - rethrowIfNotCaught
15
+ include_creds_paths:
16
+ - nintendo.pokemon
17
+ - platform
20
18
 
21
19
  groups:
22
- example_group:
23
- - exampleFunction
20
+ pokemon:
21
+ - pokemonPokeballThrow