proca 0.1.3 → 0.2.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 +580 -2
- package/package.json +21 -6
- package/src/commands/action/list.mjs +186 -0
- package/src/commands/campaign/delete.mjs +61 -0
- package/src/commands/campaign/get.mjs +4 -4
- package/src/commands/campaign/list.mjs +3 -12
- package/src/commands/config/add.mjs +3 -10
- package/src/commands/config/get.mjs +33 -0
- package/src/commands/config/user.mjs +77 -0
- package/src/commands/org/add.mjs +64 -0
- package/src/commands/org/get.mjs +6 -8
- package/src/commands/org/join.mjs +50 -0
- package/src/commands/user/get.mjs +91 -0
- package/src/commands/user/leave.mjs +52 -0
- package/src/commands/user/list.mjs +71 -0
- package/src/commands/widget/list.mjs +116 -0
- package/src/config.mjs +1 -1
- package/src/hooks/help.mjs +10 -0
- package/src/hooks/init.mjs +10 -0
- package/src/procaCommand.mjs +10 -11
- package/src/queries/widget.mjs +12 -0
- package/src/urql.mjs +12 -1
- package/src/util/twitter.mjs +23 -0
|
@@ -0,0 +1,91 @@
|
|
|
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, query } from "#src/urql.mjs";
|
|
5
|
+
|
|
6
|
+
export default class UserList extends Command {
|
|
7
|
+
static description = "fetch the information about a user";
|
|
8
|
+
|
|
9
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
10
|
+
|
|
11
|
+
static flags = {
|
|
12
|
+
...super.globalFlags,
|
|
13
|
+
email: Flags.string({ description: "user email" }),
|
|
14
|
+
org: Flags.string({
|
|
15
|
+
char: "o",
|
|
16
|
+
description: "name of the org",
|
|
17
|
+
exactlyOne: ["email", "id", "org"],
|
|
18
|
+
helpValue: "<org name>",
|
|
19
|
+
}),
|
|
20
|
+
id: Flags.string({
|
|
21
|
+
char: "i",
|
|
22
|
+
parse: (input) => {
|
|
23
|
+
return Number.parseInt(input, 10);
|
|
24
|
+
},
|
|
25
|
+
description: "id of the user",
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
fetch = async (params) => {
|
|
30
|
+
const Document = gql`
|
|
31
|
+
query ($email: String, $org: String, $id: Int) {
|
|
32
|
+
users (select: {email: $email, orgName: $org, id: $id}) {
|
|
33
|
+
apiToken {
|
|
34
|
+
expiresAt
|
|
35
|
+
}
|
|
36
|
+
email
|
|
37
|
+
id
|
|
38
|
+
isAdmin
|
|
39
|
+
jobTitle
|
|
40
|
+
phone
|
|
41
|
+
pictureUrl
|
|
42
|
+
roles {
|
|
43
|
+
role org {name}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
const result = await query(Document, {
|
|
49
|
+
org: params.org,
|
|
50
|
+
id: params.id,
|
|
51
|
+
email: params.email,
|
|
52
|
+
});
|
|
53
|
+
return result.users[0];
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
simplify = (d) => {
|
|
57
|
+
const result = {
|
|
58
|
+
id: d.id,
|
|
59
|
+
email: d.email,
|
|
60
|
+
};
|
|
61
|
+
if (d.apiToken) {
|
|
62
|
+
result.tokenExpire = d.apiToken.expire;
|
|
63
|
+
}
|
|
64
|
+
if (d.isAdmin) {
|
|
65
|
+
result.admin = true;
|
|
66
|
+
}
|
|
67
|
+
const roles = d.roles.reduce((acc, item) => {
|
|
68
|
+
if (!acc[item.role]) {
|
|
69
|
+
acc[item.role] = [];
|
|
70
|
+
}
|
|
71
|
+
acc[item.role].push(item.org.name);
|
|
72
|
+
return acc;
|
|
73
|
+
}, {});
|
|
74
|
+
for (const role in roles) {
|
|
75
|
+
result[role] = roles[role].join(",");
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
table = (r) => {
|
|
81
|
+
super.table(r, null, null);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
async run() {
|
|
85
|
+
const { args, flags } = await this.parse();
|
|
86
|
+
let data = [];
|
|
87
|
+
|
|
88
|
+
data = await this.fetch(flags);
|
|
89
|
+
return this.output(data);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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 OrgLeave extends Command {
|
|
7
|
+
actionTypes = new Set();
|
|
8
|
+
|
|
9
|
+
static args = {};
|
|
10
|
+
|
|
11
|
+
static description = "leave a org";
|
|
12
|
+
|
|
13
|
+
static examples = ["<%= config.bin %> <%= command.id %> -i 42"];
|
|
14
|
+
|
|
15
|
+
static flags = {
|
|
16
|
+
// flag with no value (-f, --force)
|
|
17
|
+
...super.globalFlags,
|
|
18
|
+
email: Flags.string({
|
|
19
|
+
description: "email",
|
|
20
|
+
required: true,
|
|
21
|
+
helpValue: "<user email>",
|
|
22
|
+
}),
|
|
23
|
+
org: Flags.string({
|
|
24
|
+
char: "o",
|
|
25
|
+
description: "name of the org",
|
|
26
|
+
required: true,
|
|
27
|
+
helpValue: "<org name>",
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
mutate = async ({ email, org }) => {
|
|
32
|
+
const Document = gql`
|
|
33
|
+
mutation ($email: String!, $org: String!) {
|
|
34
|
+
deleteOrgUser(email: $email, orgName: $org) { status }
|
|
35
|
+
}`;
|
|
36
|
+
const result = await mutation(Document, {
|
|
37
|
+
email: email,
|
|
38
|
+
org: org,
|
|
39
|
+
});
|
|
40
|
+
return result.deleteOrgUser.status;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
table = (r) => {
|
|
44
|
+
super.table(r, null, null);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
async run() {
|
|
48
|
+
const { args, flags } = await this.parse();
|
|
49
|
+
const data = await this.mutate(flags);
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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, query } from "#src/urql.mjs";
|
|
5
|
+
|
|
6
|
+
export default class UserList extends Command {
|
|
7
|
+
actionTypes = new Set();
|
|
8
|
+
|
|
9
|
+
static description = "list all the users";
|
|
10
|
+
|
|
11
|
+
static examples = ["<%= config.bin %> <%= command.id %> %pizza%"];
|
|
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
|
+
};
|
|
22
|
+
|
|
23
|
+
fetch = async (org) => {
|
|
24
|
+
const SearchUsersDocument = gql`
|
|
25
|
+
query ($org: String!) {
|
|
26
|
+
users(select: {orgName: $org}) {
|
|
27
|
+
apiToken {
|
|
28
|
+
expiresAt
|
|
29
|
+
}
|
|
30
|
+
email
|
|
31
|
+
id
|
|
32
|
+
isAdmin
|
|
33
|
+
jobTitle
|
|
34
|
+
phone
|
|
35
|
+
pictureUrl
|
|
36
|
+
roles {
|
|
37
|
+
role org {name}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
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
|
+
};
|
|
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
|
+
}
|
|
59
|
+
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
async run() {
|
|
64
|
+
const { args, flags } = await this.parse(UserList);
|
|
65
|
+
let data = [];
|
|
66
|
+
|
|
67
|
+
data = await this.fetch(flags.org);
|
|
68
|
+
|
|
69
|
+
return this.output(data);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
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 { FragmentSummary } from "#src/queries/widget.mjs";
|
|
5
|
+
import { gql, query } from "#src/urql.mjs";
|
|
6
|
+
|
|
7
|
+
export default class WidgetList extends Command {
|
|
8
|
+
static description = "list all the widgets of an org or campaign";
|
|
9
|
+
|
|
10
|
+
static examples = ["<%= config.bin %> <%= command.id %> -o <organisation>"];
|
|
11
|
+
|
|
12
|
+
static flags = {
|
|
13
|
+
// flag with no value (-f, --force)
|
|
14
|
+
...super.globalFlags,
|
|
15
|
+
org: Flags.string({
|
|
16
|
+
char: "o",
|
|
17
|
+
exactlyOne: ["campaign", "org"],
|
|
18
|
+
description: "widgets of the organisation (coordinator or partner)",
|
|
19
|
+
helpValue: "<organisation name>",
|
|
20
|
+
// required: true,
|
|
21
|
+
}),
|
|
22
|
+
campaign: Flags.string({
|
|
23
|
+
char: "c",
|
|
24
|
+
description: "widgets of the campaign (coordinator or partner)",
|
|
25
|
+
helpValue: "<campaign name>",
|
|
26
|
+
// required: true,
|
|
27
|
+
}),
|
|
28
|
+
config: Flags.boolean({
|
|
29
|
+
description: "get the config",
|
|
30
|
+
default: false,
|
|
31
|
+
allowNo: true,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
fetchCampaign = async (name) => {
|
|
35
|
+
const Document = gql`
|
|
36
|
+
query SearchWidgets($campaign: String!, $withConfig: Boolean!) {
|
|
37
|
+
campaign (name:$campaign) { ...on PrivateCampaign {
|
|
38
|
+
actionPages {
|
|
39
|
+
...Summary
|
|
40
|
+
config @include(if: $withConfig)
|
|
41
|
+
thankYouTemplate
|
|
42
|
+
thankYouTemplateRef
|
|
43
|
+
...on PrivateActionPage {
|
|
44
|
+
supporterConfirmTemplate
|
|
45
|
+
}
|
|
46
|
+
}}
|
|
47
|
+
}
|
|
48
|
+
${FragmentSummary}
|
|
49
|
+
}`;
|
|
50
|
+
const result = await query(Document, {
|
|
51
|
+
campaign: name,
|
|
52
|
+
withConfig: this.flags.config,
|
|
53
|
+
});
|
|
54
|
+
return result.campaign.actionPages;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
fetchOrg = async (name) => {
|
|
58
|
+
const Document = gql`
|
|
59
|
+
query SearchWidgets($org: String!, $withConfig: Boolean!) {
|
|
60
|
+
org (name:$org) {
|
|
61
|
+
actionPages {
|
|
62
|
+
...Summary
|
|
63
|
+
config @include(if: $withConfig)
|
|
64
|
+
thankYouTemplate
|
|
65
|
+
thankYouTemplateRef
|
|
66
|
+
...on PrivateActionPage {
|
|
67
|
+
supporterConfirmTemplate
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
${FragmentSummary}
|
|
72
|
+
}`;
|
|
73
|
+
const result = await query(Document, {
|
|
74
|
+
org: name,
|
|
75
|
+
withConfig: this.flags.config,
|
|
76
|
+
});
|
|
77
|
+
return result.org.actionPages;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
simplify = (d) => {
|
|
81
|
+
const result = {
|
|
82
|
+
id: d.id,
|
|
83
|
+
name: d.name,
|
|
84
|
+
locale: d.locale,
|
|
85
|
+
status: d.status.toLowerCase(),
|
|
86
|
+
location: d.location?.startsWith("https://widget.proca.app")
|
|
87
|
+
? undefined
|
|
88
|
+
: d.location || undefined,
|
|
89
|
+
// live: d.live,
|
|
90
|
+
|
|
91
|
+
// thankYouTemplate: d.thankYouTemplate || undefined,
|
|
92
|
+
// thankYouTemplateRef: d.thankYouTemplateRef || undefined,
|
|
93
|
+
// supporterConfirmTemplate: d.supporterConfirmTemplate || undefined,
|
|
94
|
+
};
|
|
95
|
+
if (d.extraSupporters > 0) {
|
|
96
|
+
result.extra = d.extraSupporters;
|
|
97
|
+
}
|
|
98
|
+
if (d.journey) result.journey = d.journey.join(" → ");
|
|
99
|
+
|
|
100
|
+
if (this.flags.config) {
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
table = (r) => {
|
|
106
|
+
super.table(r, null, (table) => table.sort(["id|des"]).toString());
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
async run() {
|
|
110
|
+
const { flags, args } = await this.parse(WidgetList);
|
|
111
|
+
let data = [];
|
|
112
|
+
if (flags.org) data = await this.fetchOrg(flags.org);
|
|
113
|
+
if (flags.campaign) data = await this.fetchCampaign(flags.campaign);
|
|
114
|
+
return this.output(data);
|
|
115
|
+
}
|
|
116
|
+
}
|
package/src/config.mjs
CHANGED
package/src/procaCommand.mjs
CHANGED
|
@@ -66,8 +66,8 @@ export class ProcaCommand extends Command {
|
|
|
66
66
|
continue;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
if (typeof value === "object"
|
|
70
|
-
r[key] = value.name;
|
|
69
|
+
if (typeof value === "object") {
|
|
70
|
+
if (value?.name) r[key] = value.name;
|
|
71
71
|
continue;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -118,15 +118,14 @@ export class ProcaCommand extends Command {
|
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
table(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
) {
|
|
121
|
+
table(data, transformRow, print = (table) => table.toString()) {
|
|
122
|
+
if (!transformRow) {
|
|
123
|
+
transformRow = (d, cell) => {
|
|
124
|
+
for (const [key, value] of Object.entries(this.simplify(d))) {
|
|
125
|
+
cell(key, value);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
130
129
|
const theme = this.config.theme;
|
|
131
130
|
Table.prototype.pushDelimeter = function (cols) {
|
|
132
131
|
// hack to change the formatting of the header
|
package/src/urql.mjs
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
gql,
|
|
7
7
|
} from "urql";
|
|
8
8
|
|
|
9
|
+
import { GraphQLError, formatError } from "graphql";
|
|
10
|
+
|
|
9
11
|
export let client = {
|
|
10
12
|
query: () => {
|
|
11
13
|
throw new Error("urql graphql not initialised, call init first");
|
|
@@ -38,7 +40,16 @@ export const createClient = (config) => {
|
|
|
38
40
|
export const query = async (query, payload) => {
|
|
39
41
|
const result = await client.query(query, payload).toPromise();
|
|
40
42
|
if (result.error) {
|
|
41
|
-
|
|
43
|
+
console.log(formatError(result.error));
|
|
44
|
+
throw result.error;
|
|
45
|
+
}
|
|
46
|
+
return result.data;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const mutation = async (mutation, payload) => {
|
|
50
|
+
const result = await client.mutation(mutation, payload).toPromise();
|
|
51
|
+
if (result.error) {
|
|
52
|
+
throw result.error;
|
|
42
53
|
}
|
|
43
54
|
return result.data;
|
|
44
55
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const getTwitter = async (org) => {
|
|
2
|
+
const orgName = org.config.twitter?.screen_name || org.name;
|
|
3
|
+
try {
|
|
4
|
+
const res = await fetch(
|
|
5
|
+
`https://twitter.proca.app/?screen_name=${orgName}`,
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
if (res.status >= 400) {
|
|
9
|
+
throw new Error("Bad response from twitter.proca.app");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const twitter = await res.json();
|
|
13
|
+
twitter.picture = twitter.profile_image_url_https;
|
|
14
|
+
twitter.profile_image_url_https = undefined;
|
|
15
|
+
if (twitter) org.config.twitter = twitter;
|
|
16
|
+
if (!org.config.description) org.config.description = twitter.description;
|
|
17
|
+
if (!org.config.location) org.config.location = twitter.location;
|
|
18
|
+
if (!org.config.url) org.config.url = twitter.url;
|
|
19
|
+
if (!org.title) org.title = twitter.name;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error(err);
|
|
22
|
+
}
|
|
23
|
+
};
|