@foxtware/mineral 0.1.28 → 0.1.29

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 (63) hide show
  1. package/.creds.yml.sample +14 -2
  2. package/AGENTS.md +7 -0
  3. package/_build_scripts/createNewFunction.js +26 -3
  4. package/api/dropbox/docs.md +7 -0
  5. package/api/dropbox/dropbox.constants.js +10 -0
  6. package/api/dropbox/dropbox.utils.js +67 -0
  7. package/api/dropbox/dropboxAccountGet.js +64 -0
  8. package/api/dropbox/dropboxFileCopy.js +67 -0
  9. package/api/dropbox/dropboxFileDelete.js +89 -0
  10. package/api/dropbox/dropboxFileDownload.js +139 -0
  11. package/api/dropbox/dropboxFileMetadataGet.js +100 -0
  12. package/api/dropbox/dropboxFileMove.js +67 -0
  13. package/api/dropbox/dropboxFileUpload.js +129 -0
  14. package/api/dropbox/dropboxFolderCreate.js +68 -0
  15. package/api/dropbox/dropboxFolderList.js +66 -0
  16. package/api/dropbox/dropboxGet.js +158 -0
  17. package/api/dropbox/dropboxSearch.js +161 -0
  18. package/api/dropbox/dropboxSharedLinkCreate.js +68 -0
  19. package/api/dropbox/dropboxSpaceUsageGet.js +55 -0
  20. package/api/dropbox/dropboxTemporaryLinkGet.js +75 -0
  21. package/api/google/docs.md +1 -0
  22. package/api/google/google.constants.js +1 -0
  23. package/api/google/google.utils.js +21 -0
  24. package/api/google/googleanalyticsMetadataGet.js +62 -0
  25. package/api/google/googleanalyticsRealtimeReportRun.js +103 -0
  26. package/api/google/googleanalyticsReportRun.js +114 -0
  27. package/api/shopify/shopify.utils.js +53 -4
  28. package/api/shopify/shopifyMetaobjectCreate.js +13 -6
  29. package/api/shopify/shopifyMetaobjectDelete.js +90 -0
  30. package/api/shopify/shopifyMetaobjectGet.js +80 -0
  31. package/api/shopify/shopifyMetaobjectUpdate.js +108 -0
  32. package/api/shopify/shopifyStorefrontSearch.js +158 -0
  33. package/api/spotify/docs.md +8 -0
  34. package/api/spotify/spotify.constants.js +12 -0
  35. package/api/spotify/spotify.utils.js +106 -0
  36. package/api/spotify/spotifyAlbumGet.js +76 -0
  37. package/api/spotify/spotifyAlbumTracksGet.js +49 -0
  38. package/api/spotify/spotifyArtistAlbumsGet.js +55 -0
  39. package/api/spotify/spotifyArtistGet.js +71 -0
  40. package/api/spotify/spotifyArtistTopTracksGet.js +56 -0
  41. package/api/spotify/spotifyGet.js +171 -0
  42. package/api/spotify/spotifyMeGet.js +48 -0
  43. package/api/spotify/spotifyPlayerCurrentlyPlayingGet.js +62 -0
  44. package/api/spotify/spotifyPlayerDevicesGet.js +51 -0
  45. package/api/spotify/spotifyPlayerGet.js +63 -0
  46. package/api/spotify/spotifyPlayerNext.js +55 -0
  47. package/api/spotify/spotifyPlayerPause.js +55 -0
  48. package/api/spotify/spotifyPlayerPlay.js +70 -0
  49. package/api/spotify/spotifyPlayerPrevious.js +55 -0
  50. package/api/spotify/spotifyPlaylistCreate.js +63 -0
  51. package/api/spotify/spotifyPlaylistGet.js +91 -0
  52. package/api/spotify/spotifyPlaylistItemsAdd.js +61 -0
  53. package/api/spotify/spotifyPlaylistItemsGet.js +58 -0
  54. package/api/spotify/spotifyPlaylistItemsRemove.js +67 -0
  55. package/api/spotify/spotifyPlaylistUpdate.js +64 -0
  56. package/api/spotify/spotifyPlaylistsGet.js +47 -0
  57. package/api/spotify/spotifySavedTracksGet.js +46 -0
  58. package/api/spotify/spotifySavedTracksRemove.js +59 -0
  59. package/api/spotify/spotifySavedTracksSave.js +59 -0
  60. package/api/spotify/spotifySearch.js +174 -0
  61. package/api/spotify/spotifyTrackGet.js +76 -0
  62. package/package.json +1 -1
  63. package/server.js +3 -1
package/.creds.yml.sample CHANGED
@@ -2,6 +2,7 @@ shopify:
2
2
  au:
3
3
  STORE_HANDLE: ________________________
4
4
  API_KEY: shpat________________________
5
+ STOREFRONT_API_KEY: __________________
5
6
 
6
7
  peoplevox:
7
8
  CLIENT_ID: _____________________________
@@ -141,5 +142,16 @@ salesforce:
141
142
 
142
143
  fastsimon:
143
144
  store: # instance name of your choice
144
- UUID: _______________________________ # Dashboard → Settings
145
- STORE_ID: ___________________________ # Dashboard → Settings
145
+ UUID: ________________________________ # Dashboard → Settings
146
+ STORE_ID: ____________________________ # Dashboard → Settings
147
+
148
+ dropbox:
149
+ ACCESS_TOKEN: __________________________
150
+
151
+ spotify:
152
+ # Option A — pre-issued user or client-credentials access token
153
+ ACCESS_TOKEN: __________________________
154
+
155
+ # Option B — app client credentials (catalog-only; auto-minted token)
156
+ CLIENT_ID: _____________________________
157
+ CLIENT_SECRET: _________________________
package/AGENTS.md CHANGED
@@ -41,4 +41,11 @@ This is the usual structure, but it can be altered per platform, if required. If
41
41
  - For functions which act on a single resource, e.g. `shopifyPageGet`, `actionSingleOrMultiple` is implemented as an enhancement to allow acting on multiple items in a one-by-one fashion.
42
42
  - `fetchClient` is implemented as an option, allowing implementations outside mineral core to use their own pipeline in making requests. This may include caching auth or utilising other platforms in the pipeline.
43
43
 
44
+ ## Doing things
45
+ - If you are being asked to do something that involves using a platform, use this repo's functionality as your first option.
46
+ - Try using curl commands based on the example curl commands documented in comments on the function files.
47
+ - If the server is not running, start one with `npm run dev` or `npm run serve`.
48
+ - Where an API functionality is not currently implemented, but fits this repo's mission, create functions for yourself to use, then use those.
44
49
 
50
+ ## .yml formatting
51
+ When you edit a YAML file, restore whitespaces afterwards.
@@ -22,6 +22,7 @@ const getContext = () => {
22
22
  inMineral,
23
23
  apiDirectory: inMineral ? mineralApiDirectory : path.join(process.cwd(), 'api'),
24
24
  mineralApiDirectory,
25
+ workspaceName: path.basename(process.cwd()),
25
26
  };
26
27
  };
27
28
 
@@ -390,7 +391,24 @@ const getExampleFilesForContext = async ({ context, dir }) => {
390
391
  return sortExampleFiles(await findExampleFiles(path.join(context.apiDirectory, dir)));
391
392
  }
392
393
 
393
- return sortExampleFiles(await collectMineralExampleFiles(context.mineralApiDirectory));
394
+ const localExampleFiles = (await findExampleFiles(path.join(context.apiDirectory, dir))).map(file => ({
395
+ ...file,
396
+ relativePath: file.filename,
397
+ displayName: file.filename,
398
+ sourceName: context.workspaceName,
399
+ }));
400
+ const mineralExampleFiles = (await collectMineralExampleFiles(context.mineralApiDirectory))
401
+ .map(file => ({
402
+ ...file,
403
+ sourceName: path.basename(mineralRoot),
404
+ }));
405
+ const exampleFilesByPath = new Map();
406
+
407
+ for (const file of [ ...mineralExampleFiles, ...localExampleFiles ]) {
408
+ exampleFilesByPath.set(file.relativePath, file);
409
+ }
410
+
411
+ return sortExampleFiles([ ...exampleFilesByPath.values() ]);
394
412
  };
395
413
 
396
414
  const formatTemplateLabel = (file, { inMineral }) => {
@@ -398,7 +416,7 @@ const formatTemplateLabel = (file, { inMineral }) => {
398
416
  return file.displayName;
399
417
  }
400
418
 
401
- return file.relativePath;
419
+ return `${ file.sourceName } > ${ file.relativePath }`;
402
420
  };
403
421
 
404
422
  const selectTemplateInteractive = async ({ exampleFiles, dir, inMineral }) => {
@@ -532,7 +550,12 @@ const createNewFunction = async () => {
532
550
  inMineral: context.inMineral,
533
551
  });
534
552
 
535
- const templateLabel = path.relative(mineralRoot, selectedTemplate);
553
+ const selectedTemplateFile = exampleFiles.find(file => file.fullPath === selectedTemplate);
554
+ const templateLabel = context.inMineral
555
+ ? path.relative(mineralRoot, selectedTemplate)
556
+ : selectedTemplateFile
557
+ ? formatTemplateLabel(selectedTemplateFile, { inMineral: false })
558
+ : path.relative(mineralRoot, selectedTemplate);
536
559
  console.log(`Using template: ${ templateLabel }`);
537
560
 
538
561
  await writeNewFunction({
@@ -0,0 +1,7 @@
1
+ # Dropbox
2
+
3
+ - [HTTP documentation](https://www.dropbox.com/developers/documentation/http/documentation)
4
+ - [OAuth guide](https://www.dropbox.com/developers/reference/oauth-guide)
5
+ - [API explorer](https://www.dropbox.com/developers/explorer)
6
+
7
+ RPC JSON over HTTPS at `https://api.dropboxapi.com/2/...` (most methods are POST with a JSON body). Content upload/download uses `https://content.dropboxapi.com/2/...` with arguments in the `Dropbox-API-Arg` header and binary body or response. Auth is OAuth 2 bearer access token (`Authorization: Bearer`). Paths are rooted at `""` (app or full Dropbox root depending on app permission); folder listing uses cursor pagination via `list_folder` / `list_folder/continue`.
@@ -0,0 +1,10 @@
1
+ const DROPBOX_API_BASE_URL = 'https://api.dropboxapi.com/2';
2
+ const DROPBOX_CONTENT_BASE_URL = 'https://content.dropboxapi.com/2';
3
+ // list_folder limit max is 2000
4
+ const MAX_PER_PAGE = 2000;
5
+
6
+ module.exports = {
7
+ DROPBOX_API_BASE_URL,
8
+ DROPBOX_CONTENT_BASE_URL,
9
+ MAX_PER_PAGE,
10
+ };
@@ -0,0 +1,67 @@
1
+ const {
2
+ DROPBOX_API_BASE_URL,
3
+ DROPBOX_CONTENT_BASE_URL,
4
+ } = require('../dropbox/dropbox.constants');
5
+ const { resolveCreds, useBaseUrl } = require('../pipelineSteps');
6
+ const {
7
+ FetchClient,
8
+ fetchClientCommonSteps,
9
+ } = require('../utils');
10
+
11
+ const useAuthHeaders = async (state) => {
12
+ const { requestPayload, context } = state;
13
+ const { creds } = context;
14
+ const { ACCESS_TOKEN } = creds;
15
+
16
+ return {
17
+ requestPayload: {
18
+ ...requestPayload,
19
+ headers: {
20
+ Authorization: `Bearer ${ ACCESS_TOKEN }`,
21
+ ...requestPayload.headers,
22
+ },
23
+ },
24
+ };
25
+ };
26
+
27
+ // Dropbox RPC endpoints are almost always POST with a JSON body.
28
+ const defaultPostMethod = async (state) => {
29
+ const { requestPayload } = state;
30
+ if (requestPayload.method) {
31
+ return {};
32
+ }
33
+
34
+ return {
35
+ requestPayload: {
36
+ ...requestPayload,
37
+ method: 'post',
38
+ },
39
+ };
40
+ };
41
+
42
+ const dropboxClient = new FetchClient({
43
+ pipeline: [
44
+ resolveCreds,
45
+ useBaseUrl(DROPBOX_API_BASE_URL),
46
+ useAuthHeaders,
47
+ defaultPostMethod,
48
+ 'fetch',
49
+ fetchClientCommonSteps.exitEarlyOnNotOk,
50
+ ],
51
+ });
52
+
53
+ const dropboxContentClient = new FetchClient({
54
+ pipeline: [
55
+ resolveCreds,
56
+ useBaseUrl(DROPBOX_CONTENT_BASE_URL),
57
+ useAuthHeaders,
58
+ defaultPostMethod,
59
+ 'fetch',
60
+ fetchClientCommonSteps.exitEarlyOnNotOk,
61
+ ],
62
+ });
63
+
64
+ module.exports = {
65
+ dropboxClient,
66
+ dropboxContentClient,
67
+ };
@@ -0,0 +1,64 @@
1
+ // https://www.dropbox.com/developers/documentation/http/documentation#users-get_current_account
2
+
3
+ const { ArgsWarden, logDeep } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { dropboxClient } = require('../dropbox/dropbox.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ]);
10
+
11
+ const dropboxAccountGet = async (
12
+ credsPayload,
13
+ {
14
+ fetchClient = dropboxClient,
15
+ } = {},
16
+ ) => {
17
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
18
+ credsPayload,
19
+ });
20
+ if (rejectResponse) {
21
+ return rejectResponse;
22
+ }
23
+
24
+ const response = await fetchClient.fetch({
25
+ context: { credsPayload },
26
+ requestPayload: {
27
+ method: 'post',
28
+ url: '/users/get_current_account',
29
+ // Dropbox expects the literal JSON null for no-arg endpoints.
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ },
33
+ body: 'null',
34
+ },
35
+ });
36
+
37
+ const { ok, data, error } = response;
38
+ if (!ok) {
39
+ logDeep({ error });
40
+ return { ok: false, error };
41
+ }
42
+
43
+ return {
44
+ ok: true,
45
+ data,
46
+ };
47
+ };
48
+
49
+ const funcApiConfig = {
50
+ argsWarden,
51
+ };
52
+
53
+ module.exports = {
54
+ dropboxAccountGet,
55
+ funcApiConfig,
56
+ };
57
+
58
+ /*
59
+ curl -X POST "http://localhost:8000/dropboxAccountGet" \
60
+ -H "Content-Type: application/json" \
61
+ -d '{
62
+ "credsPayload": { "credsPath": "dropbox" }
63
+ }'
64
+ */
@@ -0,0 +1,67 @@
1
+ // https://www.dropbox.com/developers/documentation/http/documentation#files-copy_v2
2
+
3
+ const { ArgsWarden, logDeep } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { dropboxClient } = require('../dropbox/dropbox.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ['fromPath'],
10
+ ['toPath'],
11
+ ]);
12
+
13
+ const dropboxFileCopy = async (
14
+ credsPayload,
15
+ fromPath,
16
+ toPath,
17
+ {
18
+ allowSharedFolder = false,
19
+ autorename = false,
20
+ allowOwnershipTransfer = false,
21
+ fetchClient = dropboxClient,
22
+ } = {},
23
+ ) => {
24
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
25
+ credsPayload,
26
+ fromPath,
27
+ toPath,
28
+ });
29
+ if (rejectResponse) {
30
+ return rejectResponse;
31
+ }
32
+
33
+ const response = await fetchClient.fetch({
34
+ context: { credsPayload },
35
+ requestPayload: {
36
+ method: 'post',
37
+ url: '/files/copy_v2',
38
+ body: {
39
+ from_path: fromPath,
40
+ to_path: toPath,
41
+ allow_shared_folder: allowSharedFolder,
42
+ autorename,
43
+ allow_ownership_transfer: allowOwnershipTransfer,
44
+ },
45
+ },
46
+ });
47
+
48
+ const { ok, data, error } = response;
49
+ if (!ok) {
50
+ logDeep({ error });
51
+ return { ok: false, error };
52
+ }
53
+
54
+ return {
55
+ ok: true,
56
+ data: data.metadata ?? data,
57
+ };
58
+ };
59
+
60
+ const funcApiConfig = {
61
+ argsWarden,
62
+ };
63
+
64
+ module.exports = {
65
+ dropboxFileCopy,
66
+ funcApiConfig,
67
+ };
@@ -0,0 +1,89 @@
1
+ // https://www.dropbox.com/developers/documentation/http/documentation#files-delete_v2
2
+
3
+ const { ArgsWarden, actionSingleOrMultiple, logDeep } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { dropboxClient } = require('../dropbox/dropbox.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ['path'],
10
+ ]);
11
+
12
+ const dropboxFileDeleteSingle = async (
13
+ credsPayload,
14
+ path,
15
+ {
16
+ parentRev,
17
+ fetchClient = dropboxClient,
18
+ } = {},
19
+ ) => {
20
+ const response = await fetchClient.fetch({
21
+ context: { credsPayload },
22
+ requestPayload: {
23
+ method: 'post',
24
+ url: '/files/delete_v2',
25
+ body: {
26
+ path,
27
+ ...(parentRev !== undefined && { parent_rev: parentRev }),
28
+ },
29
+ },
30
+ });
31
+
32
+ const { ok, data, error } = response;
33
+ if (!ok) {
34
+ logDeep({ error });
35
+ return { ok: false, error };
36
+ }
37
+
38
+ return {
39
+ ok: true,
40
+ data: data.metadata ?? data,
41
+ };
42
+ };
43
+
44
+ const dropboxFileDelete = async (
45
+ credsPayload,
46
+ path,
47
+ {
48
+ parentRev,
49
+ queueRunOptions,
50
+ fetchClient,
51
+ } = {},
52
+ ) => {
53
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
54
+ credsPayload,
55
+ path,
56
+ });
57
+ if (rejectResponse) {
58
+ return rejectResponse;
59
+ }
60
+
61
+ return actionSingleOrMultiple(
62
+ path,
63
+ dropboxFileDeleteSingle,
64
+ (pathItem) => ({
65
+ args: [credsPayload, pathItem, { parentRev, fetchClient }],
66
+ }),
67
+ {
68
+ ...(queueRunOptions ? { queueRunOptions } : {}),
69
+ },
70
+ );
71
+ };
72
+
73
+ const funcApiConfig = {
74
+ argsWarden,
75
+ };
76
+
77
+ module.exports = {
78
+ dropboxFileDelete,
79
+ funcApiConfig,
80
+ };
81
+
82
+ /*
83
+ curl -X POST "http://localhost:8000/dropboxFileDelete" \
84
+ -H "Content-Type: application/json" \
85
+ -d '{
86
+ "credsPayload": { "credsPath": "dropbox" },
87
+ "path": "/Homework/math/Prime_Numbers.txt"
88
+ }'
89
+ */
@@ -0,0 +1,139 @@
1
+ // https://www.dropbox.com/developers/documentation/http/documentation#files-download
2
+ // Returns file metadata plus contents as base64 (JSON-safe).
3
+
4
+ const { ArgsWarden, actionSingleOrMultiple, logDeep } = require('../utils');
5
+ const { credsValidator } = require('../validators');
6
+ const { customFetch, appendUrlToBase, credsFromPayload } = require('../utils');
7
+ const { DROPBOX_CONTENT_BASE_URL } = require('../dropbox/dropbox.constants');
8
+
9
+ const argsWarden = new ArgsWarden([
10
+ ['credsPayload', credsValidator],
11
+ ['path'],
12
+ ]);
13
+
14
+ const dropboxFileDownloadSingle = async (
15
+ credsPayload,
16
+ path,
17
+ {
18
+ rev,
19
+ // When true, return raw ArrayBuffer in data.contentsBuffer instead of base64
20
+ // (not useful over funcApi JSON; kept for in-process callers).
21
+ asBuffer = false,
22
+ } = {},
23
+ ) => {
24
+ const creds = await credsFromPayload(credsPayload);
25
+ const { ACCESS_TOKEN } = creds ?? {};
26
+
27
+ if (!ACCESS_TOKEN) {
28
+ return {
29
+ ok: false,
30
+ error: {
31
+ code: 'MISSING_DROPBOX_CREDS',
32
+ message: 'dropbox creds require ACCESS_TOKEN',
33
+ },
34
+ };
35
+ }
36
+
37
+ const arg = {
38
+ path,
39
+ ...(rev !== undefined && { rev }),
40
+ };
41
+
42
+ const url = appendUrlToBase(DROPBOX_CONTENT_BASE_URL, '/files/download');
43
+
44
+ // customFetch so we can read Dropbox-API-Result header + binary body.
45
+ const response = await customFetch(url, {
46
+ method: 'post',
47
+ headers: {
48
+ Authorization: `Bearer ${ ACCESS_TOKEN }`,
49
+ 'Dropbox-API-Arg': JSON.stringify(arg),
50
+ },
51
+ // Empty body; Dropbox still expects POST.
52
+ body: '',
53
+ responseParser: async (res) => {
54
+ const resultHeader = res.headers.get('dropbox-api-result');
55
+ let metadata = null;
56
+ if (resultHeader) {
57
+ try {
58
+ metadata = JSON.parse(resultHeader);
59
+ } catch {
60
+ metadata = { raw: resultHeader };
61
+ }
62
+ }
63
+
64
+ const buffer = Buffer.from(await res.arrayBuffer());
65
+ return {
66
+ metadata,
67
+ buffer,
68
+ };
69
+ },
70
+ });
71
+
72
+ if (!response.ok) {
73
+ logDeep({ error: response.error ?? response.data });
74
+ return {
75
+ ok: false,
76
+ error: response.error ?? response.data,
77
+ };
78
+ }
79
+
80
+ const { metadata, buffer } = response.data;
81
+
82
+ return {
83
+ ok: true,
84
+ data: {
85
+ ...(metadata || {}),
86
+ ...(asBuffer
87
+ ? { contentsBuffer: buffer }
88
+ : { contentsBase64: buffer.toString('base64') }),
89
+ size: buffer.length,
90
+ },
91
+ };
92
+ };
93
+
94
+ const dropboxFileDownload = async (
95
+ credsPayload,
96
+ path,
97
+ {
98
+ rev,
99
+ asBuffer,
100
+ queueRunOptions,
101
+ } = {},
102
+ ) => {
103
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
104
+ credsPayload,
105
+ path,
106
+ });
107
+ if (rejectResponse) {
108
+ return rejectResponse;
109
+ }
110
+
111
+ return actionSingleOrMultiple(
112
+ path,
113
+ dropboxFileDownloadSingle,
114
+ (pathItem) => ({
115
+ args: [credsPayload, pathItem, { rev, asBuffer }],
116
+ }),
117
+ {
118
+ ...(queueRunOptions ? { queueRunOptions } : {}),
119
+ },
120
+ );
121
+ };
122
+
123
+ const funcApiConfig = {
124
+ argsWarden,
125
+ };
126
+
127
+ module.exports = {
128
+ dropboxFileDownload,
129
+ funcApiConfig,
130
+ };
131
+
132
+ /*
133
+ curl -X POST "http://localhost:8000/dropboxFileDownload" \
134
+ -H "Content-Type: application/json" \
135
+ -d '{
136
+ "credsPayload": { "credsPath": "dropbox" },
137
+ "path": "/Homework/math/Prime_Numbers.txt"
138
+ }'
139
+ */
@@ -0,0 +1,100 @@
1
+ // https://www.dropbox.com/developers/documentation/http/documentation#files-get_metadata
2
+
3
+ const { ArgsWarden, actionSingleOrMultiple, logDeep } = require('../utils');
4
+ const { credsValidator } = require('../validators');
5
+ const { dropboxClient } = require('../dropbox/dropbox.utils');
6
+
7
+ const argsWarden = new ArgsWarden([
8
+ ['credsPayload', credsValidator],
9
+ ['path'],
10
+ ]);
11
+
12
+ const dropboxFileMetadataGetSingle = async (
13
+ credsPayload,
14
+ path,
15
+ {
16
+ includeMediaInfo = false,
17
+ includeDeleted = false,
18
+ includeHasExplicitSharedMembers = false,
19
+ fetchClient = dropboxClient,
20
+ } = {},
21
+ ) => {
22
+ const response = await fetchClient.fetch({
23
+ context: { credsPayload },
24
+ requestPayload: {
25
+ method: 'post',
26
+ url: '/files/get_metadata',
27
+ body: {
28
+ path,
29
+ include_media_info: includeMediaInfo,
30
+ include_deleted: includeDeleted,
31
+ include_has_explicit_shared_members: includeHasExplicitSharedMembers,
32
+ },
33
+ },
34
+ });
35
+
36
+ const { ok, data, error } = response;
37
+ if (!ok) {
38
+ logDeep({ error });
39
+ return { ok: false, error };
40
+ }
41
+
42
+ return {
43
+ ok: true,
44
+ data,
45
+ };
46
+ };
47
+
48
+ const dropboxFileMetadataGet = async (
49
+ credsPayload,
50
+ path,
51
+ {
52
+ includeMediaInfo,
53
+ includeDeleted,
54
+ includeHasExplicitSharedMembers,
55
+ queueRunOptions,
56
+ fetchClient,
57
+ } = {},
58
+ ) => {
59
+ const rejectResponse = await argsWarden.responseIfRejectingArgs({
60
+ credsPayload,
61
+ path,
62
+ });
63
+ if (rejectResponse) {
64
+ return rejectResponse;
65
+ }
66
+
67
+ return actionSingleOrMultiple(
68
+ path,
69
+ dropboxFileMetadataGetSingle,
70
+ (pathItem) => ({
71
+ args: [credsPayload, pathItem, {
72
+ includeMediaInfo,
73
+ includeDeleted,
74
+ includeHasExplicitSharedMembers,
75
+ fetchClient,
76
+ }],
77
+ }),
78
+ {
79
+ ...(queueRunOptions ? { queueRunOptions } : {}),
80
+ },
81
+ );
82
+ };
83
+
84
+ const funcApiConfig = {
85
+ argsWarden,
86
+ };
87
+
88
+ module.exports = {
89
+ dropboxFileMetadataGet,
90
+ funcApiConfig,
91
+ };
92
+
93
+ /*
94
+ curl -X POST "http://localhost:8000/dropboxFileMetadataGet" \
95
+ -H "Content-Type: application/json" \
96
+ -d '{
97
+ "credsPayload": { "credsPath": "dropbox" },
98
+ "path": "/Homework/math/Prime_Numbers.txt"
99
+ }'
100
+ */