proca 1.7.4 → 1.7.6

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
@@ -445,20 +445,23 @@ set the mail to target (mtt) params
445
445
 
446
446
  ```
447
447
  USAGE
448
- $ proca campaign mtt [ID_NAME_DXID] --from <value> --to <value> [--json | --human |
449
- --csv] [--env <value>] [--simplify] [-i <value> | -n <the_short_name> | -x <value>] [--template <value>] [--period
450
- <value>] [--email <value>]
448
+ $ proca campaign mtt [ID_NAME_DXID] [--json | --human | --csv] [--env <value>]
449
+ [--simplify] [-i <value> | -n <the_short_name> | -x <value>] [--from <value>] [--to <value>] [--template <value>]
450
+ [--period <value>] [--email <value>] [--cc <value>] [--sender] [--drip]
451
451
 
452
452
  FLAGS
453
453
  -i, --id=<value>
454
454
  -n, --name=<the_short_name> name
455
455
  -x, --dxid=<value> dxid
456
+ --cc=<value> comma-separated list of CC email addresses
457
+ --drip drip delivery or deliver as fast as possible
456
458
  --email=<value> test email address
457
459
  --env=<value> [default: default] allow to switch between configurations (server or users)
458
- --from=<value> (required) start date (yyyy-mm-dd)
460
+ --from=<value> start date (yyyy-mm-dd)
459
461
  --period=<value> [default: 09:09-18:18] period of the day (HH:HH-HH:HH)
462
+ --sender add sender to CC
460
463
  --template=<value> mtt template to use
461
- --to=<value> (required) end date (yyyy-mm-dd)
464
+ --to=<value> end date (yyyy-mm-dd)
462
465
 
463
466
  OUTPUT FLAGS
464
467
  --csv Format output as csv
@@ -925,14 +928,16 @@ view a org
925
928
  ```
926
929
  USAGE
927
930
  $ proca org get [ID_NAME_DXID] [--json | --human | --csv] [--env <value>]
928
- [--simplify] [-n <org name>] [--config] [--keys] [--campaigns] [--users]
931
+ [--simplify] [-n <org name>] [--config] [--personaldata] [--processing] [--keys] [--campaigns] [--users]
929
932
 
930
933
  FLAGS
931
- -n, --name=<org name> name of the org
934
+ -n, --name=<org name> name of the org
932
935
  --[no-]campaigns
933
- --[no-]config display the config
934
- --env=<value> [default: default] allow to switch between configurations (server or users)
936
+ --[no-]config display the config
937
+ --env=<value> [default: default] allow to switch between configurations (server or users)
935
938
  --[no-]keys
939
+ --[no-]personaldata how are the personal data of the supporter processed
940
+ --[no-]processing additional processing workflows on the actions
936
941
  --[no-]users
937
942
 
938
943
  OUTPUT FLAGS
package/package.json CHANGED
@@ -1,98 +1,98 @@
1
1
  {
2
- "name": "proca",
3
- "description": "Access the proca api",
4
- "version": "1.7.4",
5
- "author": "Xavier",
6
- "bin": {
7
- "proca": "proca-cli"
8
- },
9
- "bugs": "https://github.com/fixthestatusquo/git@github.com:fixthestatusquo/proca-cli.git/issues",
10
- "dependencies": {
11
- "@oclif/core": "^4.2.10",
12
- "@oclif/plugin-help": "^6",
13
- "@oclif/plugin-plugins": "^5",
14
- "@urql/exchange-auth": "^2.2.0",
15
- "date-fns": "^4.1.0",
16
- "dotenv": "^16.4.5",
17
- "dxid": "^2.2.1",
18
- "easy-table": "^1.2.0",
19
- "fast-csv": "^5.0.1",
20
- "graphql": "^16.10.0",
21
- "typescript": "^5.7.3",
22
- "urql": "^4.1.0",
23
- "prompts": "^2.4.2"
24
- },
25
- "devDependencies": {
26
- "@biomejs/biome": "^1.9.3",
27
- "@graphql-codegen/cli": "^2.x.x",
28
- "@graphql-codegen/introspection": "^2.x.x",
29
- "@graphql-codegen/typescript-operations": "^4.2.3",
30
- "@graphql-codegen/typescript-urql": "^4.0.0",
31
- "@oclif/plugin-autocomplete": "^3.2.5",
32
- "@oclif/plugin-commands": "^4.1.3",
33
- "@oclif/plugin-not-found": "^3.2.22",
34
- "lefthook": "^1.7.18",
35
- "oclif": "^4.17.46"
36
- },
37
- "engines": {
38
- "node": ">=18.0.0"
39
- },
40
- "files": ["/proca-cli", "/src", "/theme.json"],
41
- "homepage": "https://github.com/fixthestatusquo/git@github.com:fixthestatusquo/proca-cli.git",
42
- "keywords": [
43
- "cli",
44
- "petition",
45
- "proca",
46
- "campaigning",
47
- "digital-engagement",
48
- "social-change",
49
- "nonprofit",
50
- "civic-tech",
51
- "mobilisation",
52
- "advocacy",
53
- "activism",
54
- "email-campaign",
55
- "grassroots",
56
- "gdpr"
57
- ],
58
- "imports": {
59
- "#src/*": "./src/*"
60
- },
61
- "license": "aGPL3",
62
- "main": "./proca-cli",
63
- "oclif": {
64
- "repository": "github:fixthestatusquo/proca-cli",
65
- "bin": "proca",
66
- "theme": "theme.json",
67
- "topicSeparator": " ",
68
- "commands": "./src/commands",
69
- "helpClass": "./src/hooks/help.mjs",
70
- "topics": {
71
- "widget": {
72
- "description": "widgets (actionPages in the API)"
73
- },
74
- "campaign": {
75
- "description": "campaigns"
76
- },
77
- "user": {
78
- "description": "campaigners and other users"
79
- }
80
- },
81
- "plugins": [
82
- "@oclif/plugin-plugins",
83
- "@oclif/plugin-help",
84
- "@oclif/plugin-commands"
85
- ]
86
- },
87
- "repository": {
88
- "type": "git",
89
- "url": "git+ssh://git@github.com/fixthestatusquo/proca-cli.git"
90
- },
91
- "scripts": {
92
- "check": "npx @biomejs/biome check --write",
93
- "format": "npx @biomejs/biome format --write",
94
- "lint": "npx @biomejs/biome lint --write",
95
- "prepack": "oclif manifest && oclif readme",
96
- "version": "oclif readme && git add README.md"
97
- }
2
+ "name": "proca",
3
+ "description": "Access the proca api",
4
+ "version": "1.7.6",
5
+ "author": "Xavier",
6
+ "bin": {
7
+ "proca": "proca-cli"
8
+ },
9
+ "bugs": "https://github.com/fixthestatusquo/git@github.com:fixthestatusquo/proca-cli.git/issues",
10
+ "dependencies": {
11
+ "@oclif/core": "^4.2.10",
12
+ "@oclif/plugin-help": "^6",
13
+ "@oclif/plugin-plugins": "^5",
14
+ "@urql/exchange-auth": "^2.2.0",
15
+ "date-fns": "^4.1.0",
16
+ "dotenv": "^16.4.5",
17
+ "dxid": "^2.2.1",
18
+ "easy-table": "^1.2.0",
19
+ "fast-csv": "^5.0.1",
20
+ "graphql": "^16.10.0",
21
+ "typescript": "^5.7.3",
22
+ "urql": "^4.1.0",
23
+ "prompts": "^2.4.2"
24
+ },
25
+ "devDependencies": {
26
+ "@biomejs/biome": "^1.9.3",
27
+ "@graphql-codegen/cli": "^2.x.x",
28
+ "@graphql-codegen/introspection": "^2.x.x",
29
+ "@graphql-codegen/typescript-operations": "^4.2.3",
30
+ "@graphql-codegen/typescript-urql": "^4.0.0",
31
+ "@oclif/plugin-autocomplete": "^3.2.5",
32
+ "@oclif/plugin-commands": "^4.1.3",
33
+ "@oclif/plugin-not-found": "^3.2.22",
34
+ "lefthook": "^1.7.18",
35
+ "oclif": "^4.17.46"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "files": ["/proca-cli", "/src", "/theme.json"],
41
+ "homepage": "https://github.com/fixthestatusquo/git@github.com:fixthestatusquo/proca-cli.git",
42
+ "keywords": [
43
+ "cli",
44
+ "petition",
45
+ "proca",
46
+ "campaigning",
47
+ "digital-engagement",
48
+ "social-change",
49
+ "nonprofit",
50
+ "civic-tech",
51
+ "mobilisation",
52
+ "advocacy",
53
+ "activism",
54
+ "email-campaign",
55
+ "grassroots",
56
+ "gdpr"
57
+ ],
58
+ "imports": {
59
+ "#src/*": "./src/*"
60
+ },
61
+ "license": "aGPL3",
62
+ "main": "./proca-cli",
63
+ "oclif": {
64
+ "repository": "github:fixthestatusquo/proca-cli",
65
+ "bin": "proca",
66
+ "theme": "theme.json",
67
+ "topicSeparator": " ",
68
+ "commands": "./src/commands",
69
+ "helpClass": "./src/hooks/help.mjs",
70
+ "topics": {
71
+ "widget": {
72
+ "description": "widgets (actionPages in the API)"
73
+ },
74
+ "campaign": {
75
+ "description": "campaigns"
76
+ },
77
+ "user": {
78
+ "description": "campaigners and other users"
79
+ }
80
+ },
81
+ "plugins": [
82
+ "@oclif/plugin-plugins",
83
+ "@oclif/plugin-help",
84
+ "@oclif/plugin-commands"
85
+ ]
86
+ },
87
+ "repository": {
88
+ "type": "git",
89
+ "url": "git+ssh://git@github.com/fixthestatusquo/proca-cli.git"
90
+ },
91
+ "scripts": {
92
+ "check": "npx @biomejs/biome check --write",
93
+ "format": "npx @biomejs/biome format --write",
94
+ "lint": "npx @biomejs/biome lint --write",
95
+ "prepack": "oclif manifest && oclif readme",
96
+ "version": "oclif readme && git add README.md"
97
+ }
98
98
  }
@@ -2,42 +2,42 @@ 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,
6
- FragmentOrg,
7
- FragmentStats,
8
- FragmentSummary,
5
+ FragmentMtt,
6
+ FragmentOrg,
7
+ FragmentStats,
8
+ FragmentSummary,
9
9
  } from "#src/queries/campaign.mjs";
10
10
  import { gql, query } from "#src/urql.mjs";
11
11
 
12
12
  export default class CampaignGet extends Command {
13
- actionTypes = new Set();
13
+ actionTypes = new Set();
14
14
 
15
- static args = this.multiid();
15
+ static args = this.multiid();
16
16
 
17
- static description = "view a campaign";
17
+ static description = "view a campaign";
18
18
 
19
- static examples = ["<%= config.bin %> <%= command.id %> -i 42"];
19
+ static examples = ["<%= config.bin %> <%= command.id %> -i 42"];
20
20
 
21
- static flags = {
22
- // flag with no value (-f, --force)
23
- ...this.flagify({ multiid: true }),
24
- config: Flags.boolean({
25
- description: "display the config",
26
- default: false,
27
- allowNo: true,
28
- }),
29
- stats: Flags.boolean({
30
- description: "display the stats",
31
- default: true,
32
- allowNo: true,
33
- }),
34
- locale: Flags.string({
35
- description: "display a locale",
36
- }),
37
- };
21
+ static flags = {
22
+ // flag with no value (-f, --force)
23
+ ...this.flagify({ multiid: true }),
24
+ config: Flags.boolean({
25
+ description: "display the config",
26
+ default: false,
27
+ allowNo: true,
28
+ }),
29
+ stats: Flags.boolean({
30
+ description: "display the stats",
31
+ default: true,
32
+ allowNo: true,
33
+ }),
34
+ locale: Flags.string({
35
+ description: "display a locale",
36
+ }),
37
+ };
38
38
 
39
- fetch = async ({ id, name }) => {
40
- const GetCampaignDocument = gql`
39
+ fetch = async ({ id, name }) => {
40
+ const GetCampaignDocument = gql`
41
41
  query GetCampaign($id: Int, $name: String, $withStats: Boolean = false) {
42
42
  campaign (name: $name, id: $id) {
43
43
  ...Summary
@@ -52,73 +52,76 @@ export default class CampaignGet extends Command {
52
52
  ${FragmentOrg}
53
53
  ${FragmentMtt}
54
54
  `;
55
- const result = await query(GetCampaignDocument, {
56
- id: id,
57
- name: name,
58
- withStats: this.flags.stats,
59
- });
60
- return result.campaign;
61
- };
55
+ const result = await query(GetCampaignDocument, {
56
+ id: id,
57
+ name: name,
58
+ withStats: this.flags.stats,
59
+ });
60
+ return result.campaign;
61
+ };
62
62
 
63
- simplify = (d) => {
64
- const result = {
65
- id: d.id,
66
- Name: d.name,
67
- Title: d.title,
68
- Org: d.org.name,
69
- Status: d.status,
70
- locales: d.config.locales && Object.keys(d.config.locales).join(" "),
71
- journey: d.config.journey?.join(" → "),
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
- }
87
- if (this.flags.stats) {
88
- result["#Supporters"] = d.stats.supporterCount;
63
+ simplify = (d) => {
64
+ const result = {
65
+ id: d.id,
66
+ Name: d.name,
67
+ Title: d.title,
68
+ Org: d.org.name,
69
+ Status: d.status,
70
+ locales: d.config.locales && Object.keys(d.config.locales).join(" "),
71
+ journey: d.config.journey?.join(" → "),
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
+ result["cc contacts"] = d.mtt.ccContacts?.join(", ");
87
+ result["cc sender"] = d.mtt.ccSender;
88
+ result["drip delivery"] = d.mtt.dripDelivery;
89
+ }
90
+ if (this.flags.stats) {
91
+ result["#Supporters"] = d.stats.supporterCount;
89
92
 
90
- this.actionTypes.forEach((type) => {
91
- const action = d.stats.actionCount.find(
92
- (action) => action.actionType === type,
93
- );
94
- if (action) result[`#${type}`] = action.count;
95
- });
96
- }
97
- return result;
98
- };
93
+ this.actionTypes.forEach((type) => {
94
+ const action = d.stats.actionCount.find(
95
+ (action) => action.actionType === type,
96
+ );
97
+ if (action) result[`#${type}`] = action.count;
98
+ });
99
+ }
100
+ return result;
101
+ };
99
102
 
100
- table = (r) => {
101
- r.config = JSON.parse(r.config);
102
- super.table(r, null, null);
103
- if (this.flags.locale) {
104
- this.prettyJson(r.config?.locales[this.flags.locale]);
105
- }
106
- if (this.flags.config) {
107
- r.config.locales = undefined;
108
- this.prettyJson(r.config);
109
- }
110
- };
103
+ table = (r) => {
104
+ r.config = JSON.parse(r.config);
105
+ super.table(r, null, null);
106
+ if (this.flags.locale) {
107
+ this.prettyJson(r.config?.locales[this.flags.locale]);
108
+ }
109
+ if (this.flags.config) {
110
+ r.config.locales = undefined;
111
+ this.prettyJson(r.config);
112
+ }
113
+ };
111
114
 
112
- async run() {
113
- const { args, flags } = await this.parse();
115
+ async run() {
116
+ const { args, flags } = await this.parse();
114
117
 
115
- const data = await this.fetch({ id: flags.id, name: flags.name });
116
- if (this.flags.stats) {
117
- data.stats.actionCount.forEach((d) => {
118
- //skip share_confirmed?
119
- this.actionTypes.add(d.actionType);
120
- });
121
- }
122
- return this.output(data);
123
- }
118
+ const data = await this.fetch({ id: flags.id, name: flags.name });
119
+ if (this.flags.stats) {
120
+ data.stats.actionCount.forEach((d) => {
121
+ //skip share_confirmed?
122
+ this.actionTypes.add(d.actionType);
123
+ });
124
+ }
125
+ return this.output(data);
126
+ }
124
127
  }
@@ -1,42 +1,52 @@
1
- import { Args, Flags } from "@oclif/core";
2
- import { error, stdout, ux } from "@oclif/core/ux";
1
+ import { Flags } from "@oclif/core";
3
2
  import Command from "#src/procaCommand.mjs";
4
3
  import { FragmentMtt } from "#src/queries/campaign.mjs";
5
4
  import { gql, mutation } from "#src/urql.mjs";
6
5
 
7
6
  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`
7
+ static args = this.multiid();
8
+
9
+ static description = "set the mail to target (mtt) params";
10
+
11
+ static examples = [
12
+ "<%= config.bin %> <%= command.id %> -n <test-mtt-campaign>",
13
+ ];
14
+
15
+ static flags = {
16
+ ...this.flagify({ multiid: true }),
17
+ from: Flags.string({
18
+ description: "start date (yyyy-mm-dd)",
19
+ required: false,
20
+ }),
21
+ to: Flags.string({
22
+ description: "end date (yyyy-mm-dd)",
23
+ required: false,
24
+ }),
25
+ template: Flags.string({
26
+ description: "mtt template to use",
27
+ }),
28
+ period: Flags.string({
29
+ description: "period of the day (HH:HH-HH:HH)",
30
+ default: "09:09-18:18",
31
+ }),
32
+ email: Flags.string({
33
+ description: "test email address",
34
+ }),
35
+ cc: Flags.string({
36
+ description: "comma-separated list of CC email addresses",
37
+ }),
38
+ sender: Flags.boolean({
39
+ description: "add sender to CC",
40
+ default: false,
41
+ }),
42
+ drip: Flags.boolean({
43
+ description: "drip delivery or deliver as fast as possible",
44
+ default: false,
45
+ }),
46
+ };
47
+
48
+ updateMtt = async (flags) => {
49
+ const Query = gql`
40
50
  mutation (
41
51
  $id: Int,
42
52
  $name: String
@@ -45,64 +55,77 @@ $mtt: CampaignMttInput!
45
55
  updateCampaign (id:$id, name: $name, input: { mtt: $mtt }) {
46
56
  id, name
47
57
  ...Mtt
48
- }
49
- ${FragmentMtt}
50
- }
58
+ }
59
+ ${FragmentMtt}
60
+ }
51
61
  `;
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
- }
62
+
63
+ const testEmail = flags.email || `campaign+${flags.name}@proca.app`;
64
+
65
+ const [startPeriod, endPeriod] = flags.period.split("-");
66
+ const [startHour, startMinute] = startPeriod.split(":");
67
+ const [endHour, endMinute] = endPeriod.split(":");
68
+
69
+ const mtt = {
70
+ testEmail,
71
+ };
72
+
73
+ if (flags.template) mtt.messageTemplate = flags.template;
74
+ if (flags.email) mtt.testEmail = testEmail;
75
+ if (flags.cc) mtt.ccContacts = flags.cc.split(",").map((e) => e.trim());
76
+ if (flags.sender) mtt.ccSender = flags.sender;
77
+
78
+ if (flags.from) {
79
+ const startAt = new Date(flags.from);
80
+ startAt.setHours(startHour, startMinute, 0, 0);
81
+ mtt.startAt = startAt.toISOString();
82
+ }
83
+
84
+ if (flags.to) {
85
+ const endAt = new Date(flags.to);
86
+ endAt.setHours(endHour, endMinute, 0, 0);
87
+ mtt.endAt = endAt.toISOString();
88
+ }
89
+
90
+ const result = await mutation(Query, {
91
+ id: flags.id,
92
+ name: flags.name,
93
+ mtt,
94
+ });
95
+ return result.updateCampaign;
96
+ };
97
+
98
+ simplify = (d) => {
99
+ const result = { id: d.id, Name: d.name };
100
+ const hhmm = (date) =>
101
+ new Date(date).toLocaleTimeString(undefined, {
102
+ hour: "2-digit",
103
+ minute: "2-digit",
104
+ hour12: false,
105
+ });
106
+ if (d.mtt.startAt && d.mtt.endAt) {
107
+ result.from = d.mtt.startAt.substring(0, 10);
108
+ result.to = d.mtt.endAt.substring(0, 10);
109
+ result.period = `${hhmm(d.mtt.startAt)}↔${hhmm(d.mtt.endAt)}`;
110
+ }
111
+ result["test email"] = d.mtt.testEmail;
112
+ result["mtt template"] = d.mtt.messageTemplate;
113
+ if (d.mtt.ccContacts?.length)
114
+ result["cc contacts"] = d.mtt.ccContacts.join(", ");
115
+ if (typeof d.mtt.ccSender !== "undefined") {
116
+ result["cc sender"] = d.mtt.ccSender ? "yes" : "no";
117
+ }
118
+
119
+ return result;
120
+ };
121
+
122
+ table = (r) => {
123
+ super.table(r, null, null);
124
+ };
125
+
126
+ async run() {
127
+ const { args, flags } = await this.parse();
128
+ const result = await this.updateMtt(flags);
129
+ this.output(result);
130
+ }
108
131
  }
@@ -5,50 +5,60 @@ import Command from "#src/procaCommand.mjs";
5
5
  import { gql, query } from "#src/urql.mjs";
6
6
 
7
7
  export default class OrgGet extends Command {
8
- static description = "view a org";
8
+ static description = "view a org";
9
9
 
10
- static examples = ["<%= config.bin %> <%= command.id %> <name of the ngo>"];
10
+ static examples = ["<%= config.bin %> <%= command.id %> <name of the ngo>"];
11
11
 
12
- static args = this.multiid();
12
+ static args = this.multiid();
13
13
 
14
- static flags = {
15
- // flag with no value (-f, --force)
16
- ...this.flagify({ multiid: false }),
17
- name: Flags.string({
18
- char: "n",
19
- charAliases: ["o"],
20
- description: "name of the org",
21
- helpValue: "<org name>",
22
- }),
23
- config: Flags.boolean({
24
- description: "display the config",
25
- default: false,
26
- allowNo: true,
27
- }),
28
- keys: Flags.boolean({
29
- default: true,
30
- allowNo: true,
31
- }),
32
- campaigns: Flags.boolean({
33
- default: false,
34
- allowNo: true,
35
- }),
36
- users: Flags.boolean({
37
- default: true,
38
- allowNo: true,
39
- }),
40
- };
14
+ static flags = {
15
+ // flag with no value (-f, --force)
16
+ ...this.flagify({ multiid: false }),
17
+ name: Flags.string({
18
+ char: "n",
19
+ charAliases: ["o"],
20
+ description: "name of the org",
21
+ helpValue: "<org name>",
22
+ }),
23
+ config: Flags.boolean({
24
+ description: "display the config",
25
+ default: false,
26
+ allowNo: true,
27
+ }),
28
+ personaldata: Flags.boolean({
29
+ description: "how are the personal data of the supporter processed",
30
+ default: true,
31
+ allowNo: true,
32
+ }),
33
+ processing: Flags.boolean({
34
+ description: "additional processing workflows on the actions",
35
+ default: true,
36
+ allowNo: true,
37
+ }),
38
+ keys: Flags.boolean({
39
+ default: true,
40
+ allowNo: true,
41
+ }),
42
+ campaigns: Flags.boolean({
43
+ default: false,
44
+ allowNo: true,
45
+ }),
46
+ users: Flags.boolean({
47
+ default: true,
48
+ allowNo: true,
49
+ }),
50
+ };
41
51
 
42
- fetch = async (params) => {
43
- const GetOrgDocument = gql`
44
- query GetOrg($name: String!, $withCampaigns: Boolean = true, $withKeys: Boolean = true) {
52
+ fetch = async (params) => {
53
+ const GetOrgDocument = gql`
54
+ query GetOrg($name: String!, $withCampaigns: Boolean = true, $withKeys: Boolean = true, $withPersonalData: Boolean = false, $withProcessing: Boolean= false ) {
45
55
  org (name: $name) {
46
56
  id name title
47
57
  config
48
58
  keys @include(if: $withKeys) {id, name, expired, expiredAt, public}
49
59
 
50
60
  campaigns @include(if: $withCampaigns) {id, name, title, org {name}}
51
- personalData {
61
+ personalData @include(if: $withPersonalData) {
52
62
  contactSchema
53
63
  doiThankYou
54
64
  highSecurity
@@ -56,7 +66,7 @@ export default class OrgGet extends Command {
56
66
  supporterConfirm
57
67
  supporterConfirmTemplate
58
68
  }
59
- processing {
69
+ processing @include(if: $withProcessing) {
60
70
  customActionConfirm
61
71
  customActionDeliver
62
72
  customEventDeliver
@@ -84,50 +94,54 @@ export default class OrgGet extends Command {
84
94
  }
85
95
  `;
86
96
 
87
- const result = await query(GetOrgDocument, {
88
- name: params.name,
89
- withCampaigns: params.campaigns,
90
- withKeys: params.keys || true,
91
- });
92
- // result.org.config = JSON.parse (result.org.config);
93
- return result.org;
94
- };
97
+ const result = await query(GetOrgDocument, {
98
+ name: params.name,
99
+ withCampaigns: params.campaigns,
100
+ withKeys: params.keys || true,
101
+ withPersonalData: params.personaldata,
102
+ $withProcessing: params.processing,
103
+ });
104
+ if (result.org.config) {
105
+ result.org.config = JSON.parse(result.org.config);
106
+ }
107
+ return result.org;
108
+ };
95
109
 
96
- simplify = (d) => {
97
- const result = {
98
- id: d.id,
99
- Name: d.name,
100
- Title: d.title,
101
- "can targets reply?": d.replyEnabled ? true : undefined,
102
- "confirm actions?": d.supporterConfirm
103
- ? d.supporterConfirmTemplate
104
- : undefined,
105
- };
106
- if (this.flags.stats) {
107
- result["#Supporters"] = d.stats.supporterCount;
110
+ simplify = (d) => {
111
+ const result = {
112
+ id: d.id,
113
+ Name: d.name,
114
+ Title: d.title,
115
+ "can targets reply?": d.replyEnabled ? true : undefined,
116
+ "confirm actions?": d.supporterConfirm
117
+ ? d.supporterConfirmTemplate
118
+ : undefined,
119
+ };
120
+ if (this.flags.stats) {
121
+ result["#Supporters"] = d.stats.supporterCount;
108
122
 
109
- this.actionTypes.forEach((type) => {
110
- const action = d.stats.actionCount.find(
111
- (action) => action.actionType === type,
112
- );
113
- if (action) result[`#${type}`] = action.count;
114
- });
115
- }
116
- return result;
117
- };
123
+ this.actionTypes.forEach((type) => {
124
+ const action = d.stats.actionCount.find(
125
+ (action) => action.actionType === type,
126
+ );
127
+ if (action) result[`#${type}`] = action.count;
128
+ });
129
+ }
130
+ return result;
131
+ };
118
132
 
119
- table = (r) => {
120
- r.config = JSON.parse(r.config);
121
- super.table(r, null, null);
122
- if (this.flags.config) {
123
- r.config.locales = undefined;
124
- this.prettyJson(r.config);
125
- }
126
- };
133
+ table = (r) => {
134
+ r.config = JSON.parse(r.config);
135
+ super.table(r, null, null);
136
+ if (this.flags.config) {
137
+ r.config.locales = undefined;
138
+ this.prettyJson(r.config);
139
+ }
140
+ };
127
141
 
128
- async run() {
129
- const { args, flags } = await this.parse();
130
- const data = await this.fetch(flags);
131
- return this.output(data);
132
- }
142
+ async run() {
143
+ const { args, flags } = await this.parse();
144
+ const data = await this.fetch(flags);
145
+ return this.output(data);
146
+ }
133
147
  }
@@ -4,24 +4,24 @@ import Command from "#src/procaCommand.mjs";
4
4
  import { gql, query } from "#src/urql.mjs";
5
5
 
6
6
  export default class UserList extends Command {
7
- actionTypes = new Set();
7
+ actionTypes = new Set();
8
8
 
9
- static description = "list all the users";
9
+ static description = "list all the users";
10
10
 
11
- static examples = ["<%= config.bin %> <%= command.id %> %pizza%"];
11
+ static examples = ["<%= config.bin %> <%= command.id %> %pizza%"];
12
12
 
13
- static flags = {
14
- // flag with no value (-f, --force)
15
- ...super.globalFlags,
16
- org: Flags.string({
17
- char: "o",
18
- description: "organisation",
19
- required: true,
20
- }),
21
- };
13
+ static flags = {
14
+ // flag with no value (-f, --force)
15
+ ...super.globalFlags,
16
+ org: Flags.string({
17
+ char: "o",
18
+ description: "organisation",
19
+ required: true,
20
+ }),
21
+ };
22
22
 
23
- fetch = async (org) => {
24
- const SearchUsersDocument = gql`
23
+ fetch = async (org) => {
24
+ const SearchUsersDocument = gql`
25
25
  query ($org: String!) {
26
26
  users(select: {orgName: $org}) {
27
27
  apiToken {
@@ -39,33 +39,36 @@ query ($org: String!) {
39
39
  }
40
40
  }
41
41
  `;
42
- const result = await query(SearchUsersDocument, { org: org });
43
- return result.users;
44
- //return result.users.map (d => {d.config = JSON.parse(d.config); return d});
45
- };
42
+ const result = await query(SearchUsersDocument, { org: org });
43
+ return result.users;
44
+ //return result.users.map (d => {d.config = JSON.parse(d.config); return d});
45
+ };
46
46
 
47
- simplify = (d) => {
48
- const result = {
49
- id: d.id,
50
- email: d.email,
51
- };
52
- result.role = d.roles.filter((d) => d.org.name === this.flags.org)[0].role;
53
- if (d.isAdmin) {
54
- result.superadmin = true;
55
- }
56
- if (d.apiToken) {
57
- result.tokenExpire = d.apiToken.tokenExpire;
58
- }
47
+ simplify = (d) => {
48
+ const result = {
49
+ id: d.id,
50
+ email: d.email,
51
+ };
52
+ result.orgs = d.roles.map((d) => d.org.name).join(",");
59
53
 
60
- return result;
61
- };
54
+ d.roles.filter((d) => d.org.name === this.flags.org)[0]?.role || "??";
62
55
 
63
- async run() {
64
- const { args, flags } = await this.parse(UserList);
65
- let data = [];
56
+ if (d.isAdmin) {
57
+ result.superadmin = true;
58
+ }
59
+ if (d.apiToken) {
60
+ result.tokenExpire = d.apiToken.tokenExpire;
61
+ }
62
+
63
+ return result;
64
+ };
66
65
 
67
- data = await this.fetch(flags.org);
66
+ async run() {
67
+ const { flags } = await this.parse(UserList);
68
+ let data = [];
68
69
 
69
- return this.output(data);
70
- }
70
+ data = await this.fetch(flags.org);
71
+
72
+ return this.output(data);
73
+ }
71
74
  }
@@ -1,101 +1,125 @@
1
- import { Args, Flags } from "@oclif/core";
2
- import { error, stdout, ux } from "@oclif/core/ux";
1
+ import { Flags } from "@oclif/core";
3
2
  import CampaignGet from "#src/commands/campaign/get.mjs";
3
+ import OrgGet from "#src/commands/org/get.mjs";
4
4
  import Command from "#src/procaCommand.mjs";
5
5
  import { gql, mutation } from "#src/urql.mjs";
6
6
 
7
7
  export default class WidgetAdd extends Command {
8
- //static args = { path: { description: "" } };
8
+ //static args = { path: { description: "" } };
9
9
 
10
- static flags = {
11
- // flag with no value (-f, --force)
12
- ...super.globalFlags,
13
- campaign: Flags.string({
14
- char: "c",
15
- required: true,
16
- description: "name of the campaign",
17
- helpValue: "<campaign name>",
18
- }),
19
- org: Flags.string({
20
- char: "o",
21
- description: "organisation",
22
- helpValue: "<en>",
23
- }),
24
- lang: Flags.string({
25
- char: "l",
26
- description: "language",
27
- default: "en",
28
- helpValue: "<en>",
29
- }),
30
- name: Flags.string({
31
- char: "n",
32
- description: "url slug",
33
- helpValue: "by default <campaign>/<org>/<lang>",
34
- }),
35
- };
10
+ static flags = {
11
+ // flag with no value (-f, --force)
12
+ ...super.globalFlags,
13
+ campaign: Flags.string({
14
+ char: "c",
15
+ required: true,
16
+ description: "name of the campaign",
17
+ helpValue: "<campaign name>",
18
+ }),
19
+ org: Flags.string({
20
+ char: "o",
21
+ description: "organisation",
22
+ helpValue: "<en>",
23
+ }),
24
+ lang: Flags.string({
25
+ char: "l",
26
+ description: "language",
27
+ default: "en",
28
+ helpValue: "<en>",
29
+ }),
30
+ name: Flags.string({
31
+ char: "n",
32
+ description: "url slug",
33
+ helpValue: "by default <campaign>/<org>/<lang>",
34
+ }),
35
+ };
36
36
 
37
- create = async (flag) => {
38
- const orgName = flag.org;
39
- let campaign = { org: { name: orgName } }; // no need to fetch the campaign if the orgName is specified
37
+ create = async (flag) => {
38
+ const orgName = flag.org;
39
+ let campaign = { org: { name: orgName } }; // no need to fetch the campaign if the orgName is specified
40
+ let org = {}; // no need to fetch the campaign if the orgName is specified
40
41
 
41
- const addWidgetDocument = gql`
42
+ const addWidgetDocument = gql`
42
43
  mutation addPage(
43
44
  $campaign: String!
44
45
  $org: String!
45
46
  $name: String!
46
47
  $lang: String!
48
+ $config: Json
47
49
  ) {
48
50
  addActionPage(
49
51
  campaignName: $campaign
50
52
  orgName: $org
51
- input: { name: $name, locale: $lang }
53
+ input: { name: $name, locale: $lang, config: $config }
52
54
  ) {
53
55
  id
54
56
  }
55
57
  }
56
58
  `;
57
59
 
58
- if (!orgName) {
59
- try {
60
- const campapi = new CampaignGet();
61
- campaign = await campapi.fetch({ name: flag.campaign });
62
- flag.org = campaign.org.name;
63
- } catch (e) {
64
- console.log("error", e);
65
- throw e;
66
- }
67
- }
60
+ if (!orgName) {
61
+ try {
62
+ const campapi = new CampaignGet();
63
+ campaign = await campapi.fetch({ name: flag.campaign });
64
+ flag.org = campaign.org.name;
65
+ if (!flag.name) {
66
+ flag.name = `${campaign.name}/${flag.lang}`;
67
+ }
68
+ } catch (e) {
69
+ console.log("error", e);
70
+ throw e;
71
+ }
72
+ }
73
+
74
+ if (!campaign) {
75
+ throw new Error(`campaign not found: ${flag.campaign}`);
76
+ }
68
77
 
69
- if (!campaign) {
70
- throw new Error(`campaign not found: ${flag.campaign}`);
71
- }
78
+ try {
79
+ const orgapi = new OrgGet();
80
+ org = await orgapi.fetch({
81
+ name: flag.org,
82
+ campaigns: false,
83
+ keys: false,
84
+ });
85
+ if (org.config.layout) {
86
+ flag.config = JSON.stringify({ layout: org.config.layout });
87
+ }
88
+ } catch (e) {
89
+ console.log("error", e);
90
+ throw e;
91
+ }
72
92
 
73
- try {
74
- const r = await mutation(addWidgetDocument, flag);
75
- return { id: r.addActionPage.id };
76
- } catch (e) {
77
- const errors = e.graphQLErrors;
78
- console.log(errors, flag, addWidgetDocument);
79
- if (errors[0].path[1] === "name") {
80
- this.error(`invalid name (already taken?): ${flag.name}`);
81
- throw new Error(errors[0].message);
82
- }
83
- if (errors[0].extensions?.code === "permission_denied") {
84
- console.error("permission denied to create", name, campaign?.org.name);
85
- throw new Error(errors[0].message);
86
- }
87
- const page = await fetchByName(name);
88
- console.warn("duplicate of widget", page.id);
89
- throw new Error(errors[0].message);
90
- }
91
- };
93
+ if (!flag.name) {
94
+ flag.name = `${flag.campaign}/${flag.org}/${flag.lang}`;
95
+ }
96
+ try {
97
+ const r = await mutation(addWidgetDocument, flag);
98
+ return { id: r.addActionPage.id };
99
+ } catch (e) {
100
+ const errors = e.graphQLErrors;
101
+ console.log(JSON.stringify(errors, null, 2), flag);
102
+ if (errors[0].path[1] === "name") {
103
+ this.error(`invalid name (already taken?): ${flag.name}`);
104
+ throw new Error(errors[0].message);
105
+ }
106
+ if (errors[0].extensions?.code === "permission_denied") {
107
+ console.error("permission denied to create", name, campaign?.org.name);
108
+ throw new Error(errors[0].message);
109
+ }
110
+ console.log(flag);
111
+ // const page = await fetchByName(name);
112
+ // console.warn("duplicate of widget", page.id);
113
+ throw new Error(errors[0].message);
114
+ }
115
+ };
92
116
 
93
- async run() {
94
- const { args, flags } = await this.parse();
117
+ async run() {
118
+ const { args, flags } = await this.parse();
95
119
 
96
- // const org = { name: flags.twitter || flags.name, config: {} };
120
+ // const org = { name: flags.twitter || flags.name, config: {} };
97
121
 
98
- const data = await this.create(flags);
99
- return this.output(data);
100
- }
122
+ const data = await this.create(flags);
123
+ return this.output(data);
124
+ }
101
125
  }
@@ -9,6 +9,9 @@ export const FragmentMtt = gql`
9
9
  endAt
10
10
  messageTemplate
11
11
  testEmail
12
+ ccContacts
13
+ ccSender
14
+ dripDelivery
12
15
  }
13
16
  }
14
17
  `;