proca 1.5.0 → 1.7.0

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
@@ -12,19 +12,18 @@ One of Proca's standout features is its robust support for coalition campaigns,
12
12
 
13
13
  ### global installation
14
14
 
15
- <!-- usage -->
15
+ if you have or plan to have multiple servers (eg. production and staging) or multiple users, you can setup multiple environments. each proca command support a --env <environment> param (optional, 'default' if not specified.
16
+
17
+ All the examples are using the default environment, add --env=staging if you need to access another server than your default one. By convention, we keep default for production.
18
+
16
19
  ```sh-session
17
20
  $ npm install -g proca
18
- $ proca COMMAND
19
- running command...
20
- $ proca (--version)
21
- proca/1.5.0 linux-x64 node-v20.12.2
22
- $ proca --help [COMMAND]
23
- USAGE
24
- $ proca COMMAND
25
- ...
21
+ $# if you don't have your API token, generate one
22
+ $ proca user reset --email <your_email> --passowrd <your password>
23
+ $ proca config init --token=<API-token>
26
24
  ```
27
- <!-- usagestop -->
25
+ you can set up the config folder the widget builder will use to store the caches. skip unless you want a different one than the default (your/widget/folder/config).
26
+
28
27
 
29
28
  ### local development
30
29
 
@@ -36,27 +35,15 @@ USAGE
36
35
  $./proca-cli config add --env=local --url=http://localhost:4000/api
37
36
  $./proca-cli config server --env=local #check if the config is working
38
37
  $./proca-cli config user #check if the config is working
39
- ...
38
+ ````
40
39
 
41
40
  you should also use the local proca-api in your [widget generator](https://github.com/fixthestatusquo/proca)
42
41
 
43
- ```sh-session
42
+ ````sh-session
44
43
  $ cd /your/path/to/proca
45
- $ npm link proca-api
46
44
  $ npm link proca # use the local proca-cli repo
47
- ...
48
-
49
-
50
45
  ````
51
46
 
52
- ### TOPICS
53
-
54
- - campaign Handle campaigns
55
- - org
56
- - config create setting to access the server authentication
57
- - widget
58
- - supporters (counter)
59
-
60
47
  # Commands
61
48
 
62
49
  <!-- commands -->
@@ -69,6 +56,7 @@ you should also use the local proca-api in your [widget generator](https://githu
69
56
  * [`proca campaign delete`](#proca-campaign-delete)
70
57
  * [`proca campaign get`](#proca-campaign-get)
71
58
  * [`proca campaign list [TITLE]`](#proca-campaign-list-title)
59
+ * [`proca campaign mtt`](#proca-campaign-mtt)
72
60
  * [`proca campaign status`](#proca-campaign-status)
73
61
  * [`proca config add [ENV] [HUMAN] [JSON] [CSV] [SIMPLIFY]`](#proca-config-add-env-human-json-csv-simplify)
74
62
  * [`proca config folder`](#proca-config-folder)
@@ -95,6 +83,7 @@ you should also use the local proca-api in your [widget generator](https://githu
95
83
  * [`proca plugins uninstall [PLUGIN]`](#proca-plugins-uninstall-plugin)
96
84
  * [`proca plugins unlink [PLUGIN]`](#proca-plugins-unlink-plugin)
97
85
  * [`proca plugins update`](#proca-plugins-update)
86
+ * [`proca target add`](#proca-target-add)
98
87
  * [`proca user get`](#proca-user-get)
99
88
  * [`proca user leave`](#proca-user-leave)
100
89
  * [`proca user list`](#proca-user-list)
@@ -111,13 +100,14 @@ USAGE
111
100
  $ proca action add [ID_NAME_DXID...] -i <value> --firstname <value> --email <value>
112
101
  [--json | --human | --csv] [--env <value>] [--simplify] [-x <value>] [-n <the_short_name>] [--testing] [--optin]
113
102
  [--action_type <value>] [--lastname <value>] [--street <value>] [--locality <value>] [--region <value>] [--country
114
- <value>] [--utm <value>]
103
+ <value>] [--utm <value>] [--target <value>] [--subject <value>] [--body <value>]
115
104
 
116
105
  FLAGS
117
106
  -i, --id=<value> (required) widget's id
118
107
  -n, --name=<the_short_name> name
119
108
  -x, --dxid=<value> dxid
120
109
  --action_type=<value> [default: register]
110
+ --body=<value> [mtt] body of the email
121
111
  --country=<value> 2-letter country iso code
122
112
  --email=<value> (required) email
123
113
  --env=<value> [default: default] allow to switch between configurations (server or users)
@@ -127,6 +117,8 @@ FLAGS
127
117
  --optin
128
118
  --region=<value>
129
119
  --street=<value>
120
+ --subject=<value> [mtt] subject of the email
121
+ --target=<value> [mtt] uid of the target
130
122
  --testing
131
123
  --utm=<value> utm=campaign.source.medium
132
124
 
@@ -140,6 +132,8 @@ EXAMPLES
140
132
  $ proca action add -i <widget_id> --firstname=John --email=john@example.org
141
133
 
142
134
  $ proca action add -i <widget_id> --firstname=John --email=john@example.org --country=FR custom1=A custom2=B
135
+
136
+ $ proca action add -i <widget_id> --firstname=John --email=john@example.org target=715a9580-cfe6-4005-9e23-61a62ddecfea --subject='MTT subject' --body='message MTT'
143
137
  ```
144
138
 
145
139
  ## `proca action count`
@@ -369,6 +363,40 @@ EXAMPLES
369
363
  $ proca campaign list %pizza%
370
364
  ```
371
365
 
366
+ ## `proca campaign mtt`
367
+
368
+ set the mail to target (mtt) params
369
+
370
+ ```
371
+ USAGE
372
+ $ proca campaign mtt [ID_NAME_DXID] --from <value> --to <value> [--json | --human |
373
+ --csv] [--env <value>] [--simplify] [-i <value> | -n <the_short_name> | -x <value>] [--template <value>] [--period
374
+ <value>] [--email <value>]
375
+
376
+ FLAGS
377
+ -i, --id=<value>
378
+ -n, --name=<the_short_name> name
379
+ -x, --dxid=<value> dxid
380
+ --email=<value> test email address
381
+ --env=<value> [default: default] allow to switch between configurations (server or users)
382
+ --from=<value> (required) start date (yyyy-mm-dd)
383
+ --period=<value> [default: 09:09-18:18] period of the day (HH:HH-HH:HH)
384
+ --template=<value> mtt template to use
385
+ --to=<value> (required) end date (yyyy-mm-dd)
386
+
387
+ OUTPUT FLAGS
388
+ --csv Format output as csv
389
+ --human Format output to be read on screen by a human [default]
390
+ --json Format output as json
391
+ --[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
392
+
393
+ DESCRIPTION
394
+ set the mail to target (mtt) params
395
+
396
+ EXAMPLES
397
+ $ proca campaign mtt -n <test-mtt-campaign>
398
+ ```
399
+
372
400
  ## `proca campaign status`
373
401
 
374
402
  ```
@@ -403,7 +431,8 @@ create setting to access to a server
403
431
  ```
404
432
  USAGE
405
433
  $ proca config add [ENV] [HUMAN] [JSON] [CSV] [SIMPLIFY] [--json | --human | --csv]
406
- [--env <value>] [--simplify] [--url <url>] [--token <API-token>] [--folder /var/www/proca]
434
+ [--env <value>] [--simplify] [--url http://localhost:4000] [--token API-token>] [--email you@example.org] [--folder
435
+ /var/www/proca/config.example]
407
436
 
408
437
  ARGUMENTS
409
438
  ENV [default: default] allow to switch between configurations (server or users)
@@ -413,10 +442,11 @@ ARGUMENTS
413
442
  SIMPLIFY flatten and filter to output only the most important attributes, mostly relevant for json
414
443
 
415
444
  FLAGS
416
- --env=<value> [default: default] allow to switch between configurations (server or users)
417
- --folder=/var/www/proca config folder (in the proca widget generator)
418
- --token=<API-token> user token on proca server
419
- --url=<url> [default: https://api.proca.app/api] url of the proca server api
445
+ --email=you@example.org user email on proca server
446
+ --env=<value> [default: default] allow to switch between configurations (server or users)
447
+ --folder=/var/www/proca/config.example config folder (in the proca widget generator)
448
+ --token=API-token> user token on proca server
449
+ --url=http://localhost:4000 [default: https://api.proca.app/api] url of the proca server api
420
450
 
421
451
  OUTPUT FLAGS
422
452
  --csv Format output as csv
@@ -465,7 +495,8 @@ create setting to access to a server
465
495
  ```
466
496
  USAGE
467
497
  $ proca config init [ENV] [HUMAN] [JSON] [CSV] [SIMPLIFY] [--json | --human | --csv]
468
- [--env <value>] [--simplify] [--url <url>] [--token <API-token>] [--folder /var/www/proca]
498
+ [--env <value>] [--simplify] [--url http://localhost:4000] [--token API-token>] [--email you@example.org] [--folder
499
+ /var/www/proca/config.example]
469
500
 
470
501
  ARGUMENTS
471
502
  ENV [default: default] allow to switch between configurations (server or users)
@@ -475,10 +506,11 @@ ARGUMENTS
475
506
  SIMPLIFY flatten and filter to output only the most important attributes, mostly relevant for json
476
507
 
477
508
  FLAGS
478
- --env=<value> [default: default] allow to switch between configurations (server or users)
479
- --folder=/var/www/proca config folder (in the proca widget generator)
480
- --token=<API-token> user token on proca server
481
- --url=<url> [default: https://api.proca.app/api] url of the proca server api
509
+ --email=you@example.org user email on proca server
510
+ --env=<value> [default: default] allow to switch between configurations (server or users)
511
+ --folder=/var/www/proca/config.example config folder (in the proca widget generator)
512
+ --token=API-token> user token on proca server
513
+ --url=http://localhost:4000 [default: https://api.proca.app/api] url of the proca server api
482
514
 
483
515
  OUTPUT FLAGS
484
516
  --csv Format output as csv
@@ -562,7 +594,8 @@ create setting to access to a server
562
594
  ```
563
595
  USAGE
564
596
  $ proca config setup [ENV] [HUMAN] [JSON] [CSV] [SIMPLIFY] [--json | --human | --csv]
565
- [--env <value>] [--simplify] [--url <url>] [--token <API-token>] [--folder /var/www/proca]
597
+ [--env <value>] [--simplify] [--url http://localhost:4000] [--token API-token>] [--email you@example.org] [--folder
598
+ /var/www/proca/config.example]
566
599
 
567
600
  ARGUMENTS
568
601
  ENV [default: default] allow to switch between configurations (server or users)
@@ -572,10 +605,11 @@ ARGUMENTS
572
605
  SIMPLIFY flatten and filter to output only the most important attributes, mostly relevant for json
573
606
 
574
607
  FLAGS
575
- --env=<value> [default: default] allow to switch between configurations (server or users)
576
- --folder=/var/www/proca config folder (in the proca widget generator)
577
- --token=<API-token> user token on proca server
578
- --url=<url> [default: https://api.proca.app/api] url of the proca server api
608
+ --email=you@example.org user email on proca server
609
+ --env=<value> [default: default] allow to switch between configurations (server or users)
610
+ --folder=/var/www/proca/config.example config folder (in the proca widget generator)
611
+ --token=API-token> user token on proca server
612
+ --url=http://localhost:4000 [default: https://api.proca.app/api] url of the proca server api
579
613
 
580
614
  OUTPUT FLAGS
581
615
  --csv Format output as csv
@@ -1126,6 +1160,27 @@ DESCRIPTION
1126
1160
 
1127
1161
  _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.25/src/commands/plugins/update.ts)_
1128
1162
 
1163
+ ## `proca target add`
1164
+
1165
+ ```
1166
+ USAGE
1167
+ $ proca target add -c <value> --name <value> --email <value> [--json | --human |
1168
+ --csv] [--env <value>] [--simplify] [--external_id <value>]
1169
+
1170
+ FLAGS
1171
+ -c, --campaign=<value> (required) mtt campaign to add the target
1172
+ --email=<value> (required) email of the target
1173
+ --env=<value> [default: default] allow to switch between configurations (server or users)
1174
+ --external_id=<value> external id of the target
1175
+ --name=<value> (required) name of the target
1176
+
1177
+ OUTPUT FLAGS
1178
+ --csv Format output as csv
1179
+ --human Format output to be read on screen by a human [default]
1180
+ --json Format output as json
1181
+ --[no-]simplify flatten and filter to output only the most important attributes, mostly relevant for json
1182
+ ```
1183
+
1129
1184
  ## `proca user get`
1130
1185
 
1131
1186
  fetch the information about a user
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "proca",
3
3
  "description": "Access the proca api",
4
- "version": "1.5.0",
4
+ "version": "1.7.0",
5
5
  "author": "Xavier",
6
6
  "bin": {
7
7
  "proca": "proca-cli"
@@ -9,6 +9,7 @@ export default class ActionAdd extends Command {
9
9
  static examples = [
10
10
  "<%= config.bin %> <%= command.id %> -i <widget_id> --firstname=John --email=john@example.org",
11
11
  "<%= config.bin %> <%= command.id %> -i <widget_id> --firstname=John --email=john@example.org --country=FR custom1=A custom2=B",
12
+ "<%= config.bin %> <%= command.id %> -i <widget_id> --firstname=John --email=john@example.org target=715a9580-cfe6-4005-9e23-61a62ddecfea --subject='MTT subject' --body='message MTT'",
12
13
  ];
13
14
 
14
15
  static args = this.multiid();
@@ -50,6 +51,9 @@ export default class ActionAdd extends Command {
50
51
  description: "email",
51
52
  required: true,
52
53
  }),
54
+ target: Flags.string({ description: "[mtt] uid of the target" }),
55
+ subject: Flags.string({ description: "[mtt] subject of the email" }),
56
+ body: Flags.string({ description: "[mtt] body of the email" }),
53
57
  };
54
58
 
55
59
  create = async (flags) => {
@@ -95,6 +99,16 @@ export default class ActionAdd extends Command {
95
99
  },
96
100
  };
97
101
 
102
+ if (flags.target) {
103
+ values.action.mtt = {
104
+ targets: [flags.target],
105
+ subject: flags.subject || "Test MTT",
106
+ body: flags.body || "Please ignore, this is a test",
107
+ };
108
+ values.action.actionType = "mail2target";
109
+ }
110
+ console.log(values.action.mtt);
111
+
98
112
  const query = gql`
99
113
  mutation (
100
114
  $action: ActionInput!
@@ -2,6 +2,7 @@ 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
4
  import {
5
+ FragmentMtt,
5
6
  FragmentOrg,
6
7
  FragmentStats,
7
8
  FragmentSummary,
@@ -43,11 +44,13 @@ export default class CampaignGet extends Command {
43
44
  ...Org
44
45
  config
45
46
  ...Stats @include(if: $withStats)
47
+ ...Mtt
46
48
  }
47
49
  }
48
50
  ${FragmentStats}
49
51
  ${FragmentSummary}
50
52
  ${FragmentOrg}
53
+ ${FragmentMtt}
51
54
  `;
52
55
  const result = await query(GetCampaignDocument, {
53
56
  id: id,
@@ -67,6 +70,20 @@ export default class CampaignGet extends Command {
67
70
  locales: d.config.locales && Object.keys(d.config.locales).join(" "),
68
71
  journey: d.config.journey?.join(" → "),
69
72
  };
73
+ if (d.mtt) {
74
+ // we have an mtt
75
+ const hhmm = (date) =>
76
+ new Date(date).toLocaleTimeString(undefined, {
77
+ hour: "2-digit",
78
+ minute: "2-digit",
79
+ hour12: false,
80
+ });
81
+ result.from = d.mtt.startAt.substring(0, 10);
82
+ result.to = d.mtt.endAt.substring(0, 10);
83
+ result.period = `${hhmm(d.mtt.startAt)}↔${hhmm(d.mtt.endAt)}`;
84
+ result["test email"] = d.mtt.testEmail;
85
+ result["mtt template"] = d.mtt.template;
86
+ }
70
87
  if (this.flags.stats) {
71
88
  result["#Supporters"] = d.stats.supporterCount;
72
89
 
@@ -0,0 +1,108 @@
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 { FragmentMtt } from "#src/queries/campaign.mjs";
5
+ import { gql, mutation } from "#src/urql.mjs";
6
+
7
+ export default class CampaignMtt extends Command {
8
+ static args = this.multiid();
9
+
10
+ static description = "set the mail to target (mtt) params";
11
+
12
+ static examples = [
13
+ "<%= config.bin %> <%= command.id %> -n <test-mtt-campaign>",
14
+ ];
15
+
16
+ static flags = {
17
+ ...this.flagify({ multiid: true }),
18
+ from: Flags.string({
19
+ description: "start date (yyyy-mm-dd)",
20
+ required: true,
21
+ }),
22
+ to: Flags.string({
23
+ description: "end date (yyyy-mm-dd)",
24
+ required: true,
25
+ }),
26
+ template: Flags.string({
27
+ description: "mtt template to use",
28
+ }),
29
+ period: Flags.string({
30
+ description: "period of the day (HH:HH-HH:HH)",
31
+ default: "09:09-18:18",
32
+ }),
33
+ email: Flags.string({
34
+ description: "test email address",
35
+ }),
36
+ };
37
+
38
+ updateMtt = async (flags) => {
39
+ const Query = gql`
40
+ mutation (
41
+ $id: Int,
42
+ $name: String
43
+ $mtt: CampaignMttInput!
44
+ ) {
45
+ updateCampaign (id:$id, name: $name, input: { mtt: $mtt }) {
46
+ id, name
47
+ ...Mtt
48
+ }
49
+ ${FragmentMtt}
50
+ }
51
+ `;
52
+ const testEmail = flags.email || `campaign+${flags.name}@proca.app`;
53
+
54
+ const [startPeriod, endPeriod] = flags.period.split("-");
55
+ const [startHour, startMinute] = startPeriod.split(":");
56
+ const [endHour, endMinute] = endPeriod.split(":");
57
+
58
+ const startAt = new Date(flags.from);
59
+ startAt.setHours(startHour, startMinute, 0, 0);
60
+
61
+ const endAt = new Date(flags.to);
62
+ endAt.setHours(endHour, endMinute, 0, 0);
63
+
64
+ const result = await mutation(Query, {
65
+ // org: props.org,
66
+ id: flags.id,
67
+ name: flags.name,
68
+ mtt: {
69
+ startAt: startAt.toISOString(),
70
+ endAt: endAt.toISOString(),
71
+ messageTemplate: flags.template,
72
+ testEmail: testEmail,
73
+ },
74
+ });
75
+
76
+ return result.updateCampaign;
77
+ };
78
+
79
+ simplify = (d) => {
80
+ const result = {
81
+ id: d.id,
82
+ Name: d.name,
83
+ };
84
+ const hhmm = (date) =>
85
+ new Date(date).toLocaleTimeString(undefined, {
86
+ hour: "2-digit",
87
+ minute: "2-digit",
88
+ hour12: false,
89
+ });
90
+ result.from = d.mtt.startAt.substring(0, 10);
91
+ result.to = d.mtt.endAt.substring(0, 10);
92
+ result.period = `${hhmm(d.mtt.startAt)}↔${hhmm(d.mtt.endAt)}`;
93
+ result["test email"] = d.mtt.testEmail;
94
+ result["mtt template"] = d.mtt.template;
95
+ return result;
96
+ };
97
+
98
+ table = (r) => {
99
+ super.table(r, null, null);
100
+ };
101
+
102
+ async run() {
103
+ const { args, flags } = await this.parse();
104
+
105
+ const result = await this.updateMtt(flags);
106
+ this.output(result);
107
+ }
108
+ }
@@ -25,15 +25,19 @@ export default class ConfigAdd extends Command {
25
25
  url: Flags.string({
26
26
  description: "url of the proca server api",
27
27
  default: "https://api.proca.app/api",
28
- helpValue: "<url>",
28
+ helpValue: "http://localhost:4000",
29
29
  }),
30
30
  token: Flags.string({
31
31
  description: "user token on proca server",
32
- helpValue: "<API-token>",
32
+ helpValue: "API-token>",
33
+ }),
34
+ email: Flags.string({
35
+ description: "user email on proca server",
36
+ helpValue: "you@example.org",
33
37
  }),
34
38
  folder: Flags.string({
35
39
  description: "config folder (in the proca widget generator)",
36
- helpValue: "/var/www/proca",
40
+ helpValue: "/var/www/proca/config.example",
37
41
  }),
38
42
  // n8n: Flags.string({ description: "api access on the n8n server", helpValue: "<n8n api>", }),
39
43
  // supabase: Flags.string({description: "url of the supabase",helpValue: "<url>"}),
@@ -0,0 +1,94 @@
1
+ import fs from "node:fs";
2
+ import { Args, Flags } from "@oclif/core";
3
+ import { error, stdout, ux } from "@oclif/core/ux";
4
+ import Command from "#src/procaCommand.mjs";
5
+ import { gql, mutation, query } from "#src/urql.mjs";
6
+
7
+ export default class TargetAdd extends Command {
8
+ static flags = {
9
+ // flag with no value (-f, --force)
10
+ ...this.flagify({ multiid: false }),
11
+ campaign: Flags.string({
12
+ char: "c",
13
+ description: "mtt campaign to add the target",
14
+ required: true,
15
+ }),
16
+ name: Flags.string({
17
+ description: "name of the target",
18
+ required: true,
19
+ }),
20
+ email: Flags.string({
21
+ description: "email of the target",
22
+ required: true,
23
+ }),
24
+ external_id: Flags.string({
25
+ description: "external id of the target",
26
+ }),
27
+ };
28
+
29
+ getCampaignId = async (name) => {
30
+ const Document = gql`
31
+ query getCampaignId($campaign: String!) {
32
+ campaign (name:$campaign) { id
33
+ }
34
+ }`;
35
+
36
+ const result = await query(Document, {
37
+ campaign: name,
38
+ });
39
+ return result.campaign.id;
40
+ };
41
+
42
+ create = async (flags) => {
43
+ const id = await this.getCampaignId(flags.campaign);
44
+
45
+ const Document = gql`
46
+ mutation (
47
+ $campaignId: Int!
48
+ $outdatedTargets: OutdatedTargets
49
+ $targets: [TargetInput!]!
50
+ ) {
51
+ upsertTargets(
52
+ campaignId: $campaignId
53
+ outdatedTargets: $outdatedTargets
54
+ targets: $targets
55
+ ) {
56
+ area
57
+ emails {
58
+ email
59
+ emailStatus
60
+ error
61
+ }
62
+ externalId
63
+ fields
64
+ id
65
+ locale
66
+ name
67
+ }
68
+ }
69
+ `;
70
+ const result = await mutation(Document, {
71
+ campaignId: id,
72
+ outdatedTargets: "KEEP",
73
+ targets: [
74
+ {
75
+ name: flags.name,
76
+ externalId: flags.external_id,
77
+ emails: [{ email: flags.email }],
78
+ },
79
+ ],
80
+ });
81
+ return result.upsertTargets;
82
+ };
83
+
84
+ async run() {
85
+ //const { args, flags } = await this.parse(CampaignAdd);
86
+ const { args, flags } = await this.parse();
87
+ if (!flags.external_id) {
88
+ flags.external_id = `${flags.campaign}_${flags.email}`;
89
+ }
90
+
91
+ const data = await this.create(flags);
92
+ return this.output(data);
93
+ }
94
+ }
@@ -201,16 +201,20 @@ class ProcaCommand extends Command {
201
201
  table(data, transformRow, print = (table) => table.toString()) {
202
202
  if (!transformRow) {
203
203
  if (this.flags.simplify !== false) {
204
- transformRow = (d, cell) => {
205
- for (const [key, value] of Object.entries(this.simplify(d))) {
204
+ transformRow = (d, cell, idx) => {
205
+ const r = this.simplify(d);
206
+ if (r === null) return null;
207
+ for (const [key, value] of Object.entries(r)) {
206
208
  cell(key, value);
207
209
  }
210
+ return true;
208
211
  };
209
212
  } else {
210
- transformRow = (d, cell) => {
213
+ transformRow = (d, cell, idx) => {
211
214
  for (const [key, value] of Object.entries(this.flatten(d))) {
212
215
  cell(key, value);
213
216
  }
217
+ return true;
214
218
  };
215
219
  }
216
220
  }
@@ -227,6 +231,7 @@ class ProcaCommand extends Command {
227
231
  }, this);
228
232
  return this.newRow();
229
233
  };
234
+
230
235
  this.log(Table.print(data, transformRow, print));
231
236
  }
232
237
 
@@ -2,6 +2,17 @@ import { gql } from "#src/urql.mjs";
2
2
 
3
3
  export const FragmentSummary = gql`fragment Summary on Campaign {id name title externalId status}`;
4
4
 
5
+ export const FragmentMtt = gql`
6
+ fragment Mtt on PrivateCampaign {
7
+ mtt {
8
+ startAt
9
+ endAt
10
+ messageTemplate
11
+ testEmail
12
+ }
13
+ }
14
+ `;
15
+
5
16
  export const FragmentOrg = gql`
6
17
  fragment Org on Campaign {
7
18
  org {