proca 1.7.5 → 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 +8 -5
- package/package.json +96 -96
- package/src/commands/campaign/get.mjs +94 -93
- package/src/commands/campaign/mtt.mjs +112 -109
- package/src/commands/org/get.mjs +91 -77
- package/src/commands/user/list.mjs +41 -38
- package/src/commands/widget/add.mjs +96 -78
- package/src/queries/campaign.mjs +1 -0
package/README.md
CHANGED
|
@@ -447,13 +447,14 @@ set the mail to target (mtt) params
|
|
|
447
447
|
USAGE
|
|
448
448
|
$ proca campaign mtt [ID_NAME_DXID] [--json | --human | --csv] [--env <value>]
|
|
449
449
|
[--simplify] [-i <value> | -n <the_short_name> | -x <value>] [--from <value>] [--to <value>] [--template <value>]
|
|
450
|
-
[--period <value>] [--email <value>] [--cc <value>] [--sender]
|
|
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
456
|
--cc=<value> comma-separated list of CC email addresses
|
|
457
|
+
--drip drip delivery or deliver as fast as possible
|
|
457
458
|
--email=<value> test email address
|
|
458
459
|
--env=<value> [default: default] allow to switch between configurations (server or users)
|
|
459
460
|
--from=<value> start date (yyyy-mm-dd)
|
|
@@ -927,14 +928,16 @@ view a org
|
|
|
927
928
|
```
|
|
928
929
|
USAGE
|
|
929
930
|
$ proca org get [ID_NAME_DXID] [--json | --human | --csv] [--env <value>]
|
|
930
|
-
[--simplify] [-n <org name>] [--config] [--keys] [--campaigns] [--users]
|
|
931
|
+
[--simplify] [-n <org name>] [--config] [--personaldata] [--processing] [--keys] [--campaigns] [--users]
|
|
931
932
|
|
|
932
933
|
FLAGS
|
|
933
|
-
-n, --name=<org name>
|
|
934
|
+
-n, --name=<org name> name of the org
|
|
934
935
|
--[no-]campaigns
|
|
935
|
-
--[no-]config
|
|
936
|
-
--env=<value>
|
|
936
|
+
--[no-]config display the config
|
|
937
|
+
--env=<value> [default: default] allow to switch between configurations (server or users)
|
|
937
938
|
--[no-]keys
|
|
939
|
+
--[no-]personaldata how are the personal data of the supporter processed
|
|
940
|
+
--[no-]processing additional processing workflows on the actions
|
|
938
941
|
--[no-]users
|
|
939
942
|
|
|
940
943
|
OUTPUT FLAGS
|
package/package.json
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
13
|
+
actionTypes = new Set();
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
static args = this.multiid();
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
static description = "view a campaign";
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
static examples = ["<%= config.bin %> <%= command.id %> -i 42"];
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
40
|
-
|
|
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,75 +52,76 @@ export default class CampaignGet extends Command {
|
|
|
52
52
|
${FragmentOrg}
|
|
53
53
|
${FragmentMtt}
|
|
54
54
|
`;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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;
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
+
};
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
+
};
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
async run() {
|
|
116
|
+
const { args, flags } = await this.parse();
|
|
116
117
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
}
|
|
126
127
|
}
|
|
@@ -1,49 +1,52 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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`
|
|
47
50
|
mutation (
|
|
48
51
|
$id: Int,
|
|
49
52
|
$name: String
|
|
@@ -57,72 +60,72 @@ $mtt: CampaignMttInput!
|
|
|
57
60
|
}
|
|
58
61
|
`;
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
+
}
|
|
128
131
|
}
|
package/src/commands/org/get.mjs
CHANGED
|
@@ -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
|
-
|
|
8
|
+
static description = "view a org";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
static examples = ["<%= config.bin %> <%= command.id %> <name of the ngo>"];
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
static args = this.multiid();
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
7
|
+
actionTypes = new Set();
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
static description = "list all the users";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
static examples = ["<%= config.bin %> <%= command.id %> %pizza%"];
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
61
|
-
};
|
|
54
|
+
d.roles.filter((d) => d.org.name === this.flags.org)[0]?.role || "??";
|
|
62
55
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
66
|
+
async run() {
|
|
67
|
+
const { flags } = await this.parse(UserList);
|
|
68
|
+
let data = [];
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
data = await this.fetch(flags.org);
|
|
71
|
+
|
|
72
|
+
return this.output(data);
|
|
73
|
+
}
|
|
71
74
|
}
|
|
@@ -1,107 +1,125 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
8
|
+
//static args = { path: { description: "" } };
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
+
}
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
+
}
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
+
};
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
async run() {
|
|
118
|
+
const { args, flags } = await this.parse();
|
|
101
119
|
|
|
102
|
-
|
|
120
|
+
// const org = { name: flags.twitter || flags.name, config: {} };
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
const data = await this.create(flags);
|
|
123
|
+
return this.output(data);
|
|
124
|
+
}
|
|
107
125
|
}
|