proca 1.7.2 → 1.7.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/README.md CHANGED
@@ -52,6 +52,7 @@ you should also use the local proca-api in your [widget generator](https://githu
52
52
  * [`proca action count`](#proca-action-count)
53
53
  * [`proca action list [TITLE]`](#proca-action-list-title)
54
54
  * [`proca action replay`](#proca-action-replay)
55
+ * [`proca action requeue`](#proca-action-requeue)
55
56
  * [`proca campaign add [TITLE]`](#proca-campaign-add-title)
56
57
  * [`proca campaign close`](#proca-campaign-close)
57
58
  * [`proca campaign delete`](#proca-campaign-delete)
@@ -90,6 +91,7 @@ you should also use the local proca-api in your [widget generator](https://githu
90
91
  * [`proca template add`](#proca-template-add)
91
92
  * [`proca template list`](#proca-template-list)
92
93
  * [`proca user get`](#proca-user-get)
94
+ * [`proca user invite`](#proca-user-invite)
93
95
  * [`proca user join`](#proca-user-join)
94
96
  * [`proca user leave`](#proca-user-leave)
95
97
  * [`proca user list`](#proca-user-list)
@@ -97,6 +99,7 @@ you should also use the local proca-api in your [widget generator](https://githu
97
99
  * [`proca user reset [USER]`](#proca-user-reset-user)
98
100
  * [`proca user whoami`](#proca-user-whoami)
99
101
  * [`proca widget add`](#proca-widget-add)
102
+ * [`proca widget delete`](#proca-widget-delete)
100
103
  * [`proca widget get`](#proca-widget-get)
101
104
  * [`proca widget list`](#proca-widget-list)
102
105
 
@@ -206,24 +209,24 @@ EXAMPLES
206
209
  ```
207
210
  USAGE
208
211
  $ proca action list [TITLE] -o <organisation name> [--json | --human | --csv] [--env
209
- <value>] [-c <campaign title>] [--limit <value>] [--today | --after 2025-04-09] [--optin] [--testing] [--doi] [--utm
212
+ <value>] [-c <campaign name>] [--limit <value>] [--today | --after 2025-04-09] [--optin] [--testing] [--doi] [--utm
210
213
  | --simplify] [--comment | ]
211
214
 
212
215
  ARGUMENTS
213
216
  TITLE name of the campaign, % for wildchar
214
217
 
215
218
  FLAGS
216
- -c, --campaign=<campaign title> name of the campaign, % for wildchar
217
- -o, --org=<organisation name> (required) campaigns of the organisation (coordinator or partner)
218
- --after=2025-04-09 only actions after a date
219
- --[no-]comment display the comment
220
- --doi only export the double optin actions
221
- --env=<value> [default: default] allow to switch between configurations (server or users)
222
- --limit=<value> max number of actions
223
- --optin only export the optin actions
224
- --testing also export the test actions
225
- --today only actions today
226
- --[no-]utm display the utm tracking parameters
219
+ -c, --campaign=<campaign name> name of the campaign, % for wildchar
220
+ -o, --org=<organisation name> (required) campaigns of the organisation (coordinator or partner)
221
+ --after=2025-04-09 only actions after a date
222
+ --[no-]comment display the comment
223
+ --doi only export the double optin actions
224
+ --env=<value> [default: default] allow to switch between configurations (server or users)
225
+ --limit=<value> max number of actions
226
+ --optin only export the optin actions
227
+ --testing also export the test actions
228
+ --today only actions today
229
+ --[no-]utm display the utm tracking parameters
227
230
 
228
231
  OUTPUT FLAGS
229
232
  --csv Format output as csv
@@ -257,6 +260,44 @@ EXAMPLES
257
260
  $ proca action replay %pizza%
258
261
  ```
259
262
 
263
+ ## `proca action requeue`
264
+
265
+ requeue actions
266
+
267
+ ```
268
+ USAGE
269
+ $ proca action requeue -o <org name> -q
270
+ CUSTOM_ACTION_CONFIRM|CUSTOM_ACTION_DELIVER|CUSTOM_SUPPORTER_CONFIRM|EMAIL_SUPPORTER|SQS|WEBHOOK [--json | --human |
271
+ --csv] [--env <value>] [--simplify] [-c <campaign name>] [--limit <value>] [--today | --after 2025-04-09] [--optin]
272
+ [--testing] [--doi]
273
+
274
+ FLAGS
275
+ -c, --campaign=<campaign name> name of the campaign, % for wildchar
276
+ -o, --org=<org name> (required) name of the org
277
+ -q, --queue=<option> (required) [default: CUSTOM_ACTION_DELIVER] queue to redeliver to
278
+ <options: CUSTOM_ACTION_CONFIRM|CUSTOM_ACTION_DELIVER|CUSTOM_SUPPORTER_CONFIRM|EMAIL_S
279
+ UPPORTER|SQS|WEBHOOK>
280
+ --after=2025-04-09 only actions after a date
281
+ --doi only export the double optin actions
282
+ --env=<value> [default: default] allow to switch between configurations (server or users)
283
+ --limit=<value> [default: 1000] how many actions per page
284
+ --optin only export the optin actions
285
+ --testing also export the test actions
286
+ --today only actions today
287
+
288
+ OUTPUT FLAGS
289
+ --csv Format output as csv
290
+ --human Format output to be read on screen by a human [default]
291
+ --json Format output as json
292
+ --[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
293
+
294
+ DESCRIPTION
295
+ requeue actions
296
+
297
+ EXAMPLES
298
+ $ proca action requeue
299
+ ```
300
+
260
301
  ## `proca campaign add [TITLE]`
261
302
 
262
303
  ```
@@ -1346,6 +1387,35 @@ EXAMPLES
1346
1387
  $ proca user get
1347
1388
  ```
1348
1389
 
1390
+ ## `proca user invite`
1391
+
1392
+ invite a user to join an organisation with a role
1393
+
1394
+ ```
1395
+ USAGE
1396
+ $ proca user invite -o <org name> -u <user email> [--json | --human | --csv] [--env
1397
+ <value>] [--simplify] [--role owner|campaigner|coordinator|translator]
1398
+
1399
+ FLAGS
1400
+ -o, --org=<org name> (required) name of the org
1401
+ -u, --user=<user email> (required) email
1402
+ --env=<value> [default: default] allow to switch between configurations (server or users)
1403
+ --role=<option> [default: campaigner] permission level in that org
1404
+ <options: owner|campaigner|coordinator|translator>
1405
+
1406
+ OUTPUT FLAGS
1407
+ --csv Format output as csv
1408
+ --human Format output to be read on screen by a human [default]
1409
+ --json Format output as json
1410
+ --[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
1411
+
1412
+ DESCRIPTION
1413
+ invite a user to join an organisation with a role
1414
+
1415
+ EXAMPLES
1416
+ $ proca user invite
1417
+ ```
1418
+
1349
1419
  ## `proca user join`
1350
1420
 
1351
1421
  let a user join an organisation with a role
@@ -1533,6 +1603,31 @@ OUTPUT FLAGS
1533
1603
  --[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
1534
1604
  ```
1535
1605
 
1606
+ ## `proca widget delete`
1607
+
1608
+ Delete a widget
1609
+
1610
+ ```
1611
+ USAGE
1612
+ $ proca widget delete [ID_NAME_DXID] [--json | --human | --csv] [--env <value>]
1613
+ [--simplify] [-i <value> | -n <the_short_name> | -x <value>]
1614
+
1615
+ FLAGS
1616
+ -i, --id=<value>
1617
+ -n, --name=<the_short_name> name
1618
+ -x, --dxid=<value> dxid
1619
+ --env=<value> [default: default] allow to switch between configurations (server or users)
1620
+
1621
+ OUTPUT FLAGS
1622
+ --csv Format output as csv
1623
+ --human Format output to be read on screen by a human [default]
1624
+ --json Format output as json
1625
+ --[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
1626
+
1627
+ DESCRIPTION
1628
+ Delete a widget
1629
+ ```
1630
+
1536
1631
  ## `proca widget get`
1537
1632
 
1538
1633
  view a widget
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "proca",
3
3
  "description": "Access the proca api",
4
- "version": "1.7.2",
4
+ "version": "1.7.4",
5
5
  "author": "Xavier",
6
6
  "bin": {
7
7
  "proca": "proca-cli"
@@ -30,7 +30,7 @@ export default class List extends Command {
30
30
  campaign: Flags.string({
31
31
  char: "c",
32
32
  description: "name of the campaign, % for wildchar",
33
- helpValue: "<campaign title>",
33
+ helpValue: "<campaign name>",
34
34
  }),
35
35
  limit: Flags.string({
36
36
  description: "max number of actions",
@@ -48,6 +48,8 @@ options: [
48
48
  const { args, flags } = await this.parse();
49
49
  let data = [];
50
50
  const ids = [];
51
+ this.fatal("not implemented yet");
52
+ process.exit(1);
51
53
  data = await this.mutate(flags.org, ids, flags.queue);
52
54
  return this.output(data);
53
55
  }
@@ -0,0 +1,156 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { error, stdout, ux } from "@oclif/core/ux";
3
+ import Command from "#src/procaCommand.mjs";
4
+ import { gql, mutation, query } from "#src/urql.mjs";
5
+
6
+ export default class ActionRequeue extends Command {
7
+ static description = "requeue actions";
8
+
9
+ static examples = ["<%= config.bin %> <%= command.id %>"];
10
+
11
+ static flags = {
12
+ ...super.globalFlags,
13
+ org: Flags.string({
14
+ char: "o",
15
+ required: true,
16
+ description: "name of the org",
17
+ helpValue: "<org name>",
18
+ }),
19
+ campaign: Flags.string({
20
+ char: "c",
21
+ description: "name of the campaign, % for wildchar",
22
+ helpValue: "<campaign name>",
23
+ }),
24
+ queue: Flags.string({
25
+ char: "q",
26
+ required: true,
27
+ description: "queue to redeliver to",
28
+ default: "CUSTOM_ACTION_DELIVER",
29
+ options: [
30
+ "CUSTOM_ACTION_CONFIRM",
31
+ "CUSTOM_ACTION_DELIVER",
32
+ "CUSTOM_SUPPORTER_CONFIRM",
33
+ "EMAIL_SUPPORTER",
34
+ "SQS",
35
+ "WEBHOOK",
36
+ ],
37
+ }),
38
+ limit: Flags.string({
39
+ description: "how many actions per page",
40
+ default: 1000,
41
+ parse: (input) => Number.parseInt(input, 10),
42
+ }),
43
+ after: Flags.string({
44
+ description: "only actions after a date",
45
+ helpValue: "2025-04-09",
46
+ parse: (input) => new Date(input).toISOString(),
47
+ }),
48
+ today: Flags.boolean({
49
+ description: "only actions today",
50
+ exclusive: ["after"],
51
+ parse: (input) => `${new Date().toISOString().split("T")[0]}T00:00:00Z`,
52
+ }),
53
+ optin: Flags.boolean({
54
+ description: "only export the optin actions",
55
+ default: false,
56
+ }),
57
+ testing: Flags.boolean({
58
+ description: "also export the test actions",
59
+ default: false,
60
+ }),
61
+ doi: Flags.boolean({
62
+ description: "only export the double optin actions",
63
+ default: false,
64
+ }),
65
+ };
66
+
67
+ process = async (flags) => {
68
+ let page = 0;
69
+ let actions = 0;
70
+ let requeued = 0;
71
+ let error = 0;
72
+ while (true) {
73
+ const ids = await this.fetch(flags);
74
+ if (ids.length === 0) break;
75
+ const result = await this.requeue(flags.org, flags.queue, ids);
76
+ requeued += result.count;
77
+ error += result.failed;
78
+ flags.start = ids[ids.length - 1] + 1;
79
+ process.stdout.write(`\rrequeued ${requeued}, id> ${flags.start}`);
80
+ page += 1;
81
+ actions += ids.length;
82
+ }
83
+ process.stdout.write("\r\x1b[K");
84
+ return { pages: page, actions, requeued, error };
85
+ };
86
+
87
+ fetch = async (flags) => {
88
+ const Document = gql`
89
+ query (
90
+ $after: DateTime
91
+ $campaignId: Int
92
+ $campaignName: String
93
+ $includeTesting: Boolean
94
+ $limit: Int
95
+ $onlyDoubleOptIn: Boolean
96
+ $onlyOptIn: Boolean
97
+ $orgName: String!
98
+ $start: Int
99
+ ) {
100
+ actions (
101
+ after: $after
102
+ campaignId: $campaignId
103
+ campaignName: $campaignName
104
+ includeTesting: $includeTesting
105
+ limit: $limit
106
+ onlyDoubleOptIn: $onlyDoubleOptIn
107
+ onlyOptIn: $onlyOptIn
108
+ orgName: $orgName
109
+ start: $start
110
+ ) {
111
+ actionId
112
+ }
113
+ }
114
+ `;
115
+ const result = await query(Document, {
116
+ after: flags.after,
117
+ campaignName: flags.campaign,
118
+ includeTesting: flags.testing,
119
+ limit: flags.limit,
120
+ onlyDoubleOptIn: flags.doi,
121
+ onlyOptIn: flags.optin,
122
+ orgName: flags.org,
123
+ start: flags.start,
124
+ });
125
+ const ids = [];
126
+ result.actions.forEach((d) => ids.push(d.actionId));
127
+ return ids;
128
+ };
129
+
130
+ requeue = async (org, queue, ids) => {
131
+ const Document = gql`
132
+ mutation ($ids: [Int!], $org: String!, $queue: Queue!) {
133
+ requeueActions(ids: $ids, orgName: $org, queue: $queue) {
134
+ count
135
+ failed
136
+ }
137
+ }`;
138
+ const result = await mutation(Document, {
139
+ org,
140
+ queue,
141
+ ids,
142
+ });
143
+ //return result.users.map (d => {d.config = JSON.parse(d.config); return d});
144
+ return result.requeueActions;
145
+ };
146
+
147
+ table = (r) => {
148
+ super.table(r, null, null);
149
+ };
150
+
151
+ async run() {
152
+ const { args, flags } = await this.parse();
153
+ const data = await this.process(flags);
154
+ this.output(data);
155
+ }
156
+ }
@@ -0,0 +1,56 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { error, stdout, ux } from "@oclif/core/ux";
3
+ import Command from "#src/procaCommand.mjs";
4
+ import { gql, mutation } from "#src/urql.mjs";
5
+
6
+ export default class UserInviteOrg extends Command {
7
+ static description = "invite a user to join an organisation with a role";
8
+
9
+ static examples = ["<%= config.bin %> <%= command.id %>"];
10
+
11
+ static flags = {
12
+ ...super.globalFlags,
13
+ role: Flags.string({
14
+ description: "permission level in that org",
15
+ default: "campaigner",
16
+ options: ["owner", "campaigner", "coordinator", "translator"],
17
+ }),
18
+ org: Flags.string({
19
+ char: "o",
20
+ required: true,
21
+ description: "name of the org",
22
+ helpValue: "<org name>",
23
+ }),
24
+ user: Flags.string({
25
+ char: "u",
26
+ required: true,
27
+ description: "email",
28
+ helpValue: "<user email>",
29
+ }),
30
+ };
31
+
32
+ invite = async (params) => {
33
+ const Document = gql`
34
+ mutation ($user: String!, $role: String!, $org: String!, $message: String) {
35
+ inviteOrgUser(orgName: $org, message: $message, input: { email: $user, role: $role}) {
36
+ objectId
37
+ code
38
+ }
39
+ }
40
+ `;
41
+ const result = await mutation(Document, params);
42
+ //return result.users.map (d => {d.config = JSON.parse(d.config); return d});
43
+ console.log(result);
44
+ return result.inviteOrgUser;
45
+ };
46
+
47
+ table = (r) => {
48
+ super.table(r, null, null);
49
+ };
50
+
51
+ async run() {
52
+ const { args, flags } = await this.parse();
53
+ const data = await this.invite(flags);
54
+ this.output(data);
55
+ }
56
+ }
@@ -0,0 +1,45 @@
1
+ import { createInterface } from "node:readline";
2
+ import { Flags } from "@oclif/core";
3
+ import WidgetGet from "#src/commands/widget/get.mjs";
4
+ import Command from "#src/procaCommand.mjs";
5
+ import { gql, mutation } from "#src/urql.mjs";
6
+
7
+ export default class WidgetDelete extends Command {
8
+ static description = "Delete a widget";
9
+
10
+ static args = this.multiid();
11
+
12
+ static flags = {
13
+ ...this.flagify({ multiid: true }),
14
+ };
15
+
16
+ delete = async (flags) => {
17
+ const deletePageDocument = gql`
18
+ mutation delete( $name:String!) {
19
+ deleteActionPage(name: $name)
20
+ }
21
+ `;
22
+
23
+ const r = await mutation(deletePageDocument, { name: flags.name });
24
+ return { deleted: r.deleteActionPage };
25
+ };
26
+
27
+ table = (r) => {
28
+ super.table(r, null, null);
29
+ };
30
+
31
+ async run() {
32
+ const { flags } = await this.parse(WidgetDelete);
33
+ const wg = new WidgetGet([], this.config);
34
+ const widget = await wg.fetch(flags);
35
+ try {
36
+ const data = await this.delete({ name: widget.name });
37
+ widget.status = data.deleted;
38
+ } catch (e) {
39
+ widget.status = "can't delete widgets with actions";
40
+ this.output(widget);
41
+ this.error("a widget with actions can't be deleted");
42
+ }
43
+ return this.output(widget);
44
+ }
45
+ }
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { error, stdout, ux } from "@oclif/core/ux";
3
3
  import Command from "#src/procaCommand.mjs";
4
- import { FragmentSummary } from "#src/queries/widget.mjs";
4
+ import { FragmentSummary, FragmentSummaryOrg } from "#src/queries/widget.mjs";
5
5
  import { gql, query } from "#src/urql.mjs";
6
6
 
7
7
  export default class WidgetList extends Command {
@@ -68,7 +68,7 @@ query SearchWidgets($org: String!, $withConfig: Boolean!) {
68
68
  }
69
69
  }
70
70
  }
71
- ${FragmentSummary}
71
+ ${FragmentSummaryOrg}
72
72
  }`;
73
73
  const result = await query(Document, {
74
74
  org: name,
@@ -96,8 +96,13 @@ ${FragmentSummary}
96
96
  result.extra = d.extraSupporters;
97
97
  }
98
98
  // if (d.journey) result.journey = d.journey.join(" → ");
99
- result.org = d.org.name;
100
- result.org_id = d.org.id;
99
+ if (d.org) {
100
+ result.org = d.org.name;
101
+ result.org_id = d.org.id;
102
+ }
103
+ if (d.campaign) {
104
+ result.campaign = d.campaign.name;
105
+ }
101
106
  if (this.flags.config) {
102
107
  }
103
108
  return result;
@@ -11,3 +11,15 @@ location
11
11
  org {name, ... on PrivateOrg {id} }
12
12
  }
13
13
  `;
14
+
15
+ export const FragmentSummaryOrg = gql`fragment Summary on PrivateActionPage {
16
+ id
17
+ locale
18
+ name
19
+ journey
20
+ extraSupporters
21
+ status
22
+ location
23
+ campaign {name }
24
+ }
25
+ `;