@trycourier/cli 2.7.1 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/.gitkeep +0 -0
- package/install.js +115 -0
- package/package.json +22 -87
- package/LICENSE +0 -21
- package/README.md +0 -105
- package/dist/bulk.d.ts +0 -15
- package/dist/bulk.js +0 -53
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -24
- package/dist/commands/AudienceSearch.d.ts +0 -3
- package/dist/commands/AudienceSearch.js +0 -113
- package/dist/commands/AutomationInvokeBulk.d.ts +0 -3
- package/dist/commands/AutomationInvokeBulk.js +0 -139
- package/dist/commands/Config.d.ts +0 -4
- package/dist/commands/Config.js +0 -45
- package/dist/commands/DigestFlush.d.ts +0 -5
- package/dist/commands/DigestFlush.js +0 -28
- package/dist/commands/Help.d.ts +0 -16
- package/dist/commands/Help.js +0 -38
- package/dist/commands/Inbox/ArchiveAll.d.ts +0 -8
- package/dist/commands/Inbox/ArchiveAll.js +0 -180
- package/dist/commands/Inbox/ArchiveAllBulk.d.ts +0 -5
- package/dist/commands/Inbox/ArchiveAllBulk.js +0 -99
- package/dist/commands/Inbox/MarkAllRead.d.ts +0 -5
- package/dist/commands/Inbox/MarkAllRead.js +0 -110
- package/dist/commands/MessagesSearch.d.ts +0 -3
- package/dist/commands/MessagesSearch.js +0 -120
- package/dist/commands/NotYetImplemented.d.ts +0 -3
- package/dist/commands/NotYetImplemented.js +0 -5
- package/dist/commands/Send.d.ts +0 -5
- package/dist/commands/Send.js +0 -144
- package/dist/commands/Templates/List.d.ts +0 -3
- package/dist/commands/Templates/List.js +0 -114
- package/dist/commands/TenantsBulk.d.ts +0 -3
- package/dist/commands/TenantsBulk.js +0 -171
- package/dist/commands/TenantsGetMembership.d.ts +0 -3
- package/dist/commands/TenantsGetMembership.js +0 -127
- package/dist/commands/TenantsMembershipBulk.d.ts +0 -3
- package/dist/commands/TenantsMembershipBulk.js +0 -203
- package/dist/commands/Track.d.ts +0 -5
- package/dist/commands/Track.js +0 -40
- package/dist/commands/TrackBulk.d.ts +0 -3
- package/dist/commands/TrackBulk.js +0 -89
- package/dist/commands/TranslationsDownload.d.ts +0 -10
- package/dist/commands/TranslationsDownload.js +0 -30
- package/dist/commands/TranslationsUpload.d.ts +0 -9
- package/dist/commands/TranslationsUpload.js +0 -37
- package/dist/commands/Upgrade.d.ts +0 -3
- package/dist/commands/Upgrade.js +0 -38
- package/dist/commands/UserToken.d.ts +0 -3
- package/dist/commands/UserToken.js +0 -78
- package/dist/commands/UsersBulk.d.ts +0 -3
- package/dist/commands/UsersBulk.js +0 -205
- package/dist/commands/UsersGet.d.ts +0 -5
- package/dist/commands/UsersGet.js +0 -37
- package/dist/commands/UsersPreferences.d.ts +0 -3
- package/dist/commands/UsersPreferences.js +0 -73
- package/dist/commands/UsersSet.d.ts +0 -5
- package/dist/commands/UsersSet.js +0 -34
- package/dist/commands/UsersTokensBulk.d.ts +0 -3
- package/dist/commands/UsersTokensBulk.js +0 -215
- package/dist/commands/WhoAmI.d.ts +0 -3
- package/dist/commands/WhoAmI.js +0 -27
- package/dist/components/Context.d.ts +0 -55
- package/dist/components/Context.js +0 -94
- package/dist/components/Elemental.d.ts +0 -13
- package/dist/components/Elemental.js +0 -23
- package/dist/components/KVP.d.ts +0 -11
- package/dist/components/KVP.js +0 -12
- package/dist/components/Request.d.ts +0 -23
- package/dist/components/Request.js +0 -17
- package/dist/components/Response.d.ts +0 -16
- package/dist/components/Response.js +0 -29
- package/dist/components/Router.d.ts +0 -4
- package/dist/components/Router.js +0 -60
- package/dist/components/SdkResponse.d.ts +0 -9
- package/dist/components/SdkResponse.js +0 -21
- package/dist/components/Spinner.d.ts +0 -6
- package/dist/components/Spinner.js +0 -41
- package/dist/components/Table.d.ts +0 -19
- package/dist/components/Table.js +0 -62
- package/dist/components/UhOh.d.ts +0 -5
- package/dist/components/UhOh.js +0 -10
- package/dist/components/Version.d.ts +0 -3
- package/dist/components/Version.js +0 -53
- package/dist/constants.d.ts +0 -8
- package/dist/constants.js +0 -8
- package/dist/lib/api.d.ts +0 -17
- package/dist/lib/api.js +0 -39
- package/dist/lib/args.d.ts +0 -2
- package/dist/lib/args.js +0 -13
- package/dist/lib/courier.d.ts +0 -3
- package/dist/lib/courier.js +0 -7
- package/dist/lib/delay.d.ts +0 -2
- package/dist/lib/delay.js +0 -7
- package/dist/lib/load-env.d.ts +0 -2
- package/dist/lib/load-env.js +0 -16
- package/dist/lib/uuid.d.ts +0 -2
- package/dist/lib/uuid.js +0 -4
- package/dist/mappings.d.ts +0 -6
- package/dist/mappings.js +0 -559
- package/dist/version.d.ts +0 -2
- package/dist/version.js +0 -2
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { Alert } from '@inkjs/ui';
|
|
2
|
-
import { stringify } from 'csv-stringify/sync';
|
|
3
|
-
import fs from 'fs/promises';
|
|
4
|
-
import { Newline, Text } from 'ink';
|
|
5
|
-
import _ from 'lodash';
|
|
6
|
-
import React, { useEffect, useRef, useState } from 'react';
|
|
7
|
-
import { useBoolean, useCounter } from 'usehooks-ts';
|
|
8
|
-
import getDb from '../bulk.js';
|
|
9
|
-
import { useCliContext } from '../components/Context.js';
|
|
10
|
-
import Spinner from '../components/Spinner.js';
|
|
11
|
-
import UhOh from '../components/UhOh.js';
|
|
12
|
-
const FILENAME = 'invokes';
|
|
13
|
-
const AutomationInvokeBulk = () => {
|
|
14
|
-
const { parsedParams, courier } = useCliContext();
|
|
15
|
-
const processing = useBoolean(true);
|
|
16
|
-
const running = useBoolean(true);
|
|
17
|
-
const [data, setData] = useState();
|
|
18
|
-
const [data_errors, setDataError] = useState([]);
|
|
19
|
-
const counter = useCounter(0);
|
|
20
|
-
const invokes = useRef([]);
|
|
21
|
-
const addInvoke = (invoke) => invokes.current.push(invoke);
|
|
22
|
-
const { _: [template_id, infile], csv, filename: outfile, json, webhook, } = parsedParams;
|
|
23
|
-
const { db, filetype, sql } = getDb(infile || '');
|
|
24
|
-
const out_file = outfile || FILENAME + (csv ? '.csv' : '.json');
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (filetype) {
|
|
27
|
-
getData();
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
setDataError(p => [...p, 'File type not supported.']);
|
|
31
|
-
}
|
|
32
|
-
}, []);
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (data) {
|
|
35
|
-
processData();
|
|
36
|
-
}
|
|
37
|
-
}, [data]);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (data_errors?.length) {
|
|
40
|
-
running.setFalse();
|
|
41
|
-
processing.setFalse();
|
|
42
|
-
}
|
|
43
|
-
}, [data_errors]);
|
|
44
|
-
const getData = () => {
|
|
45
|
-
db.all(sql, (err, result) => {
|
|
46
|
-
if (err) {
|
|
47
|
-
setDataError(p => [...p, err.message]);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
setData(result);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
processing.setFalse();
|
|
54
|
-
};
|
|
55
|
-
const runExport = async () => {
|
|
56
|
-
if (csv) {
|
|
57
|
-
await fs.writeFile(out_file, stringify(invokes.current, { header: true }));
|
|
58
|
-
}
|
|
59
|
-
else if (json) {
|
|
60
|
-
await fs.writeFile(out_file, JSON.stringify(invokes.current, null, 2), {
|
|
61
|
-
encoding: 'utf-8',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
if (webhook?.length) {
|
|
65
|
-
try {
|
|
66
|
-
await fetch(webhook, {
|
|
67
|
-
method: 'POST',
|
|
68
|
-
headers: {
|
|
69
|
-
'Content-Type': 'application/json',
|
|
70
|
-
},
|
|
71
|
-
body: JSON.stringify(invokes.current),
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
catch (e) {
|
|
75
|
-
setDataError(p => [...p, e instanceof Error ? e.message : String(e)]);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
running.setFalse();
|
|
79
|
-
};
|
|
80
|
-
const processData = async () => {
|
|
81
|
-
if (data?.length) {
|
|
82
|
-
for (let i = 0; i < data.length; i++) {
|
|
83
|
-
let { user_id, recipient, ...rest } = data[i] || {};
|
|
84
|
-
let body = {
|
|
85
|
-
recipient: `${recipient ?? user_id}`,
|
|
86
|
-
data: {},
|
|
87
|
-
profile: {},
|
|
88
|
-
};
|
|
89
|
-
_.keys(rest).forEach(key => {
|
|
90
|
-
if (key.startsWith('profile.')) {
|
|
91
|
-
_.set(body, ['profile', key.replace('profile.', '')], rest[key]);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
_.set(body, ['data', key], rest[key]);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
const res = await courier.automations.invokeAutomationTemplate(template_id || '', body);
|
|
98
|
-
addInvoke({ ...body, runId: res.runId });
|
|
99
|
-
if (res instanceof Error) {
|
|
100
|
-
setDataError([res.message]);
|
|
101
|
-
}
|
|
102
|
-
counter.increment();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (csv || json) {
|
|
106
|
-
runExport();
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
running.setFalse();
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
if (data_errors?.length) {
|
|
113
|
-
return React.createElement(UhOh, { text: data_errors.join('\n') });
|
|
114
|
-
}
|
|
115
|
-
else if (processing.value) {
|
|
116
|
-
return React.createElement(Spinner, { text: "Processing data..." });
|
|
117
|
-
}
|
|
118
|
-
else if (running.value) {
|
|
119
|
-
return (React.createElement(Spinner, { text: `Processing ${counter.count} / ${data?.length} records` }));
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
return (React.createElement(Alert, { variant: !counter.count ? 'info' : 'success', title: `Invoke complete` },
|
|
123
|
-
React.createElement(Text, null,
|
|
124
|
-
"Sent ",
|
|
125
|
-
counter.count,
|
|
126
|
-
" automation invokes to ",
|
|
127
|
-
template_id),
|
|
128
|
-
csv ||
|
|
129
|
-
(json && (React.createElement(Text, null,
|
|
130
|
-
React.createElement(Newline, null),
|
|
131
|
-
"Saved to ",
|
|
132
|
-
out_file))),
|
|
133
|
-
webhook?.length && (React.createElement(Text, null,
|
|
134
|
-
React.createElement(Newline, null),
|
|
135
|
-
"Sent to ",
|
|
136
|
-
webhook))));
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
export default AutomationInvokeBulk;
|
package/dist/commands/Config.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import UhOh from '../components/UhOh.js';
|
|
3
|
-
import { Text } from 'ink';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
import { useCliContext } from '../components/Context.js';
|
|
6
|
-
import dotenv from 'dotenv';
|
|
7
|
-
export default ({}) => {
|
|
8
|
-
const { apikey, parsedParams, env_var } = useCliContext();
|
|
9
|
-
const FILE_PATH = `${process.cwd()}/.courier`;
|
|
10
|
-
const file_exists = fs.existsSync(FILE_PATH);
|
|
11
|
-
const overwrite = Boolean(parsedParams['overwrite']);
|
|
12
|
-
if (!apikey?.length) {
|
|
13
|
-
return (React.createElement(UhOh, { text: "You must specify your API key using --apikey <your-api-key>" }));
|
|
14
|
-
}
|
|
15
|
-
else if (!file_exists) {
|
|
16
|
-
fs.writeFileSync(FILE_PATH, `${env_var}=${apikey}\n`);
|
|
17
|
-
return (React.createElement(Text, { bold: true, color: "green" },
|
|
18
|
-
"Your API key (",
|
|
19
|
-
env_var,
|
|
20
|
-
") has been saved to ",
|
|
21
|
-
FILE_PATH,
|
|
22
|
-
". Run \"courier whoami\" to verify API credentials."));
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
// open file as buffer
|
|
26
|
-
const buffer = fs.readFileSync(FILE_PATH);
|
|
27
|
-
let parsed = dotenv.parse(buffer);
|
|
28
|
-
if (typeof parsed[env_var] !== 'undefined') {
|
|
29
|
-
if (!overwrite) {
|
|
30
|
-
return (React.createElement(UhOh, { text: `${env_var} already exists. Consider adding the --overwrite option` }));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
parsed[env_var] = apikey;
|
|
34
|
-
let new_file = Object.entries(parsed)
|
|
35
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
36
|
-
.join('\n');
|
|
37
|
-
fs.writeFileSync(FILE_PATH, new_file);
|
|
38
|
-
return (React.createElement(Text, { bold: true, color: "green" },
|
|
39
|
-
"Your API key (",
|
|
40
|
-
env_var,
|
|
41
|
-
") has been saved to ",
|
|
42
|
-
FILE_PATH,
|
|
43
|
-
". Run \"courier whoami\" to verify API credentials."));
|
|
44
|
-
}
|
|
45
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import UhOh from '../components/UhOh.js';
|
|
3
|
-
import Request from '../components/Request.js';
|
|
4
|
-
import Response from '../components/Response.js';
|
|
5
|
-
import api from '../lib/api.js';
|
|
6
|
-
import { useCliContext } from '../components/Context.js';
|
|
7
|
-
export default ({ params }) => {
|
|
8
|
-
const { apikey, url } = useCliContext();
|
|
9
|
-
const [resp, setResp] = useState();
|
|
10
|
-
const userId = params?._?.[0];
|
|
11
|
-
if (!userId) {
|
|
12
|
-
return (React.createElement(UhOh, { text: "You must specify the ID of the user whose digest you want to flush." }));
|
|
13
|
-
}
|
|
14
|
-
const topicId = params?._?.[1];
|
|
15
|
-
if (!topicId) {
|
|
16
|
-
return (React.createElement(UhOh, { text: "You must specify the ID of the Digest-enabled Subscription Topic you want to flush for the given user." }));
|
|
17
|
-
}
|
|
18
|
-
const request = {
|
|
19
|
-
method: 'POST',
|
|
20
|
-
url: `/users/${userId}/preferences/${topicId}/flush`,
|
|
21
|
-
};
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
api(request, url, apikey).then(res => setResp(res));
|
|
24
|
-
}, []);
|
|
25
|
-
return (React.createElement(React.Fragment, null,
|
|
26
|
-
React.createElement(Request, { request: request, response: resp }),
|
|
27
|
-
React.createElement(Response, { response: resp })));
|
|
28
|
-
};
|
package/dist/commands/Help.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
interface IMapping {
|
|
3
|
-
params?: string;
|
|
4
|
-
instructions?: string;
|
|
5
|
-
example?: string | string[];
|
|
6
|
-
options?: {
|
|
7
|
-
option: string;
|
|
8
|
-
value?: string;
|
|
9
|
-
instructions?: string;
|
|
10
|
-
}[];
|
|
11
|
-
component: (params?: any) => React.ReactElement;
|
|
12
|
-
}
|
|
13
|
-
declare const _default: ({ mappings }: {
|
|
14
|
-
mappings: Map<string, IMapping>;
|
|
15
|
-
}) => React.JSX.Element;
|
|
16
|
-
export default _default;
|
package/dist/commands/Help.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Box, Text, Newline } from 'ink';
|
|
3
|
-
import constants from '../constants.js';
|
|
4
|
-
import Table from '../components/Table.js';
|
|
5
|
-
import { COMMON_OPTIONS } from '../mappings.js';
|
|
6
|
-
// const Space = () => <>{' '}</>;
|
|
7
|
-
export default ({ mappings }) => {
|
|
8
|
-
const keys = [...mappings.keys()]; // convert to array
|
|
9
|
-
return (React.createElement(Box, { flexDirection: "column", paddingY: 2 },
|
|
10
|
-
React.createElement(Text, { bold: true }, "Usage"),
|
|
11
|
-
React.createElement(Text, null,
|
|
12
|
-
"$ ",
|
|
13
|
-
React.createElement(Text, { color: constants.colors.primary }, "courier"),
|
|
14
|
-
' ',
|
|
15
|
-
React.createElement(Text, { color: "gray" }, "<command>"),
|
|
16
|
-
React.createElement(Newline, null)),
|
|
17
|
-
React.createElement(Text, { bold: true }, "Common Flags"),
|
|
18
|
-
React.createElement(Table, { disableRowSeparators: true, disableBorders: true, data: COMMON_OPTIONS, headerLabels: { option: 'Flags', value: 'Description' }, rowStyles: { wrap: 'wrap' } }),
|
|
19
|
-
React.createElement(Newline, null),
|
|
20
|
-
React.createElement(Text, { bold: true }, "Commands"),
|
|
21
|
-
keys.map(k => {
|
|
22
|
-
const v = mappings.get(k);
|
|
23
|
-
if (!v || !v.instructions || !v.instructions.length) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
return (React.createElement(React.Fragment, { key: k },
|
|
27
|
-
React.createElement(Box, { paddingTop: 2 },
|
|
28
|
-
React.createElement(Text, null,
|
|
29
|
-
React.createElement(Text, { color: constants.colors.primary }, k),
|
|
30
|
-
v.params ? React.createElement(Text, { color: "gray" },
|
|
31
|
-
" ",
|
|
32
|
-
v.params) : null)),
|
|
33
|
-
React.createElement(Box, null,
|
|
34
|
-
React.createElement(Text, null, v.instructions)),
|
|
35
|
-
v.options?.length ? (React.createElement(Table, { disableRowSeparators: true, disableBorders: true, data: v.options, headerLabels: { option: 'Flags', value: 'Description' }, rowStyles: { wrap: 'wrap' } })) : (React.createElement(React.Fragment, null)),
|
|
36
|
-
v.example && Array.isArray(v.example) ? (v.example.map((e, i) => (React.createElement(Text, { color: "cyan", key: i }, e)))) : v.example ? (React.createElement(Text, { color: "cyan" }, v.example)) : null));
|
|
37
|
-
})));
|
|
38
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
interface IArchiveAll {
|
|
3
|
-
user_id_override?: string;
|
|
4
|
-
user_finished?: (messages: number) => void;
|
|
5
|
-
onError?: (text: string) => void;
|
|
6
|
-
}
|
|
7
|
-
declare const ArchiveAll: ({ user_id_override, user_finished, onError, }: IArchiveAll) => React.JSX.Element;
|
|
8
|
-
export default ArchiveAll;
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { Inbox } from '@trycourier/client-graphql';
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
import _ from 'lodash';
|
|
4
|
-
import React, { useEffect, useState } from 'react';
|
|
5
|
-
import { useBoolean, useCounter } from 'usehooks-ts';
|
|
6
|
-
import { useCliContext } from '../../components/Context.js';
|
|
7
|
-
import Spinner from '../../components/Spinner.js';
|
|
8
|
-
import UhOh from '../../components/UhOh.js';
|
|
9
|
-
import uuid from '../../lib/uuid.js';
|
|
10
|
-
// @ts-ignore
|
|
11
|
-
import ms from 'ms';
|
|
12
|
-
const LIMIT = 10;
|
|
13
|
-
const ArchiveAll = ({ user_id_override, user_finished, onError, }) => {
|
|
14
|
-
const [error, setError] = useState();
|
|
15
|
-
const [InboxClient, setInboxClient] = useState();
|
|
16
|
-
const [jwt, setJwt] = useState('');
|
|
17
|
-
const total_messages = useCounter(0);
|
|
18
|
-
const running = useBoolean(true);
|
|
19
|
-
const gathering_messages = useBoolean(true);
|
|
20
|
-
const pages = useCounter(0);
|
|
21
|
-
const { getJWT, parsedParams } = useCliContext();
|
|
22
|
-
const archived_messages = useCounter(0);
|
|
23
|
-
const [messages, setMessages] = useState([]);
|
|
24
|
-
const { tenant, tag, before, batchSize, includePinned, _: [userId, ...args], } = parsedParams;
|
|
25
|
-
const user_id = user_id_override || userId;
|
|
26
|
-
const tenant_id = tenant ? String(tenant) : undefined;
|
|
27
|
-
const until = before
|
|
28
|
-
? new Date(new Date().getTime() - Math.abs(ms(before)))
|
|
29
|
-
: undefined;
|
|
30
|
-
const limit = Number(batchSize) || LIMIT;
|
|
31
|
-
const handleError = (text) => {
|
|
32
|
-
const t = text + '\n' + JSON.stringify({ tenant, tag, user_id, args });
|
|
33
|
-
setError(t);
|
|
34
|
-
if (onError) {
|
|
35
|
-
onError(t);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
getInboxClient();
|
|
40
|
-
}, [user_id]);
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
if (jwt?.length && InboxClient) {
|
|
43
|
-
getAllMessages();
|
|
44
|
-
}
|
|
45
|
-
}, [jwt, InboxClient]);
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
if (!gathering_messages.value) {
|
|
48
|
-
handleMessageArchive();
|
|
49
|
-
}
|
|
50
|
-
}, [gathering_messages.value]);
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
if (error?.length) {
|
|
53
|
-
running.setFalse();
|
|
54
|
-
}
|
|
55
|
-
}, [error]);
|
|
56
|
-
const getInboxClient = async () => {
|
|
57
|
-
try {
|
|
58
|
-
if (user_id) {
|
|
59
|
-
const jwt = await getJWT(user_id, [
|
|
60
|
-
'inbox:read:messages',
|
|
61
|
-
'inbox:write:events',
|
|
62
|
-
]);
|
|
63
|
-
if (jwt.token) {
|
|
64
|
-
setJwt(jwt.token);
|
|
65
|
-
setInboxClient(Inbox({
|
|
66
|
-
authorization: jwt.token,
|
|
67
|
-
userId: user_id,
|
|
68
|
-
clientSourceId: uuid(),
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
handleError('No JWT token returned.');
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
handleError('No user ID provided.');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch (e) {
|
|
80
|
-
handleError(e instanceof Error ? e.message : String(e) || 'An error occurred.');
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
const handleMessageArchive = async () => {
|
|
84
|
-
if (messages.length) {
|
|
85
|
-
for (var i = 0; i < messages.length; i++) {
|
|
86
|
-
try {
|
|
87
|
-
const message = messages[i];
|
|
88
|
-
if (message?.messageId) {
|
|
89
|
-
await InboxClient?.markArchive(message.messageId);
|
|
90
|
-
}
|
|
91
|
-
archived_messages.increment();
|
|
92
|
-
}
|
|
93
|
-
catch (e) {
|
|
94
|
-
handleError(`Failed to archive message ${messages[i]?.messageId || 'unknown'}: ${e instanceof Error ? e.message : String(e) || 'An error occurred.'}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
running.setFalse();
|
|
99
|
-
if (user_finished) {
|
|
100
|
-
user_finished(messages.length);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
const getAllMessages = async () => {
|
|
104
|
-
let cursor;
|
|
105
|
-
let counter = -1;
|
|
106
|
-
if (jwt?.length && InboxClient) {
|
|
107
|
-
let params = {
|
|
108
|
-
archived: false,
|
|
109
|
-
limit,
|
|
110
|
-
};
|
|
111
|
-
if (tag) {
|
|
112
|
-
params.tags = Array.isArray(tag) ? tag : [tag];
|
|
113
|
-
}
|
|
114
|
-
if (tenant_id) {
|
|
115
|
-
params.tenantId = tenant_id;
|
|
116
|
-
}
|
|
117
|
-
while (counter < 0) {
|
|
118
|
-
counter++;
|
|
119
|
-
pages.increment();
|
|
120
|
-
let filtered_messages = [];
|
|
121
|
-
const r = await InboxClient.getMessages(params, cursor);
|
|
122
|
-
_.get(r, 'messages', []).forEach(m => {
|
|
123
|
-
if (until) {
|
|
124
|
-
if (new Date(m.created) < until) {
|
|
125
|
-
filtered_messages.push(m);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
filtered_messages.push(m);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
// handle pins on first iteration, ignore after
|
|
133
|
-
if (counter === 0 && Boolean(includePinned)) {
|
|
134
|
-
_.get(r, 'pinned', []).forEach(m => {
|
|
135
|
-
if (until) {
|
|
136
|
-
if (new Date(m.created) < until) {
|
|
137
|
-
filtered_messages.push(m);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
filtered_messages.push(m);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
if (filtered_messages.length) {
|
|
146
|
-
total_messages.setCount(c => c + filtered_messages.length);
|
|
147
|
-
setMessages(p => [...p, ...filtered_messages]);
|
|
148
|
-
}
|
|
149
|
-
if (!r?.startCursor) {
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
cursor = r.startCursor;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
handleError('No JWT generated, but GQL client called.');
|
|
159
|
-
}
|
|
160
|
-
gathering_messages.setFalse();
|
|
161
|
-
};
|
|
162
|
-
if (error?.length) {
|
|
163
|
-
return React.createElement(UhOh, { text: error });
|
|
164
|
-
}
|
|
165
|
-
else if (gathering_messages.value) {
|
|
166
|
-
return (React.createElement(Spinner, { text: `Finding messages: Found ${messages.length} in ${pages.count} pages for ${user_id}` }));
|
|
167
|
-
}
|
|
168
|
-
else if (running.value) {
|
|
169
|
-
return (React.createElement(Spinner, { text: `Archiving ${archived_messages.count} / ${messages.length} for ${user_id}` }));
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
return (React.createElement(Box, null,
|
|
173
|
-
React.createElement(Text, null,
|
|
174
|
-
"Marked ",
|
|
175
|
-
archived_messages.count,
|
|
176
|
-
" messages as archived for ",
|
|
177
|
-
user_id)));
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
export default ArchiveAll;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { Alert } from '@inkjs/ui';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import React, { useEffect, useState } from 'react';
|
|
4
|
-
import { useBoolean, useCounter } from 'usehooks-ts';
|
|
5
|
-
import getDb from '../../bulk.js';
|
|
6
|
-
import { useCliContext } from '../../components/Context.js';
|
|
7
|
-
import Spinner from '../../components/Spinner.js';
|
|
8
|
-
import UhOh from '../../components/UhOh.js';
|
|
9
|
-
import ArchiveAll from './ArchiveAll.js';
|
|
10
|
-
const ArchiveAllBulk = ({}) => {
|
|
11
|
-
const [error, setError] = useState();
|
|
12
|
-
const running = useBoolean(true);
|
|
13
|
-
const processing = useBoolean(false);
|
|
14
|
-
const { parsedParams } = useCliContext();
|
|
15
|
-
const [data, setData] = useState();
|
|
16
|
-
const current = useCounter(0);
|
|
17
|
-
const [finished, setFinished] = useState([]);
|
|
18
|
-
const { _: [filename], } = parsedParams;
|
|
19
|
-
const { db, filetype, sql } = getDb(filename || '');
|
|
20
|
-
const getData = () => {
|
|
21
|
-
db.all(sql, (err, result) => {
|
|
22
|
-
if (err) {
|
|
23
|
-
setError(err.message);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
setData(result);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (filetype) {
|
|
32
|
-
getData();
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
setError('File type not supported.');
|
|
36
|
-
}
|
|
37
|
-
}, []);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (data) {
|
|
40
|
-
processData();
|
|
41
|
-
}
|
|
42
|
-
}, [data]);
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
if (error?.length) {
|
|
45
|
-
running.setFalse();
|
|
46
|
-
}
|
|
47
|
-
}, [error]);
|
|
48
|
-
const processData = () => {
|
|
49
|
-
if (data?.length) {
|
|
50
|
-
processing.setTrue();
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
const getNext = () => {
|
|
54
|
-
if (data?.length && current.count < data.length - 1) {
|
|
55
|
-
current.increment();
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
running.setFalse();
|
|
59
|
-
processing.setFalse();
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
if (error?.length) {
|
|
63
|
-
return React.createElement(UhOh, { text: error });
|
|
64
|
-
}
|
|
65
|
-
else if (processing.value) {
|
|
66
|
-
const current_user = _.get(data, [current.count, 'user_id']);
|
|
67
|
-
if (!current_user) {
|
|
68
|
-
getNext();
|
|
69
|
-
return React.createElement(UhOh, { text: "No user_id found" });
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
return (React.createElement(React.Fragment, null,
|
|
73
|
-
finished.map((t, i) => (React.createElement(Alert, { key: i, variant: t.type }, t.message))),
|
|
74
|
-
React.createElement(Spinner, { text: `Processing ${current_user}` }),
|
|
75
|
-
React.createElement(ArchiveAll, { key: current_user, user_id_override: current_user, onError: (error) => {
|
|
76
|
-
const text = `user_id: ${current_user} | ${error}`;
|
|
77
|
-
setFinished(p => [...p, { type: 'error', message: text }]);
|
|
78
|
-
getNext();
|
|
79
|
-
}, user_finished: (messages) => {
|
|
80
|
-
const text = `user_id: ${current_user} | Archived ${messages} messages`;
|
|
81
|
-
setFinished(p => [
|
|
82
|
-
...p,
|
|
83
|
-
{ type: messages > 0 ? 'success' : 'info', message: text },
|
|
84
|
-
]);
|
|
85
|
-
getNext();
|
|
86
|
-
} })));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else if (running.value) {
|
|
90
|
-
return React.createElement(Spinner, { text: "Gathering data" });
|
|
91
|
-
}
|
|
92
|
-
else if (finished.length) {
|
|
93
|
-
return (React.createElement(React.Fragment, null, finished.map((t, i) => (React.createElement(Alert, { key: i, variant: t.type }, t.message)))));
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
return React.createElement(UhOh, { text: "No data found" });
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
export default ArchiveAllBulk;
|