proca 0.1.3 → 0.4.1
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 +795 -42
- package/package.json +18 -5
- package/src/commands/action/list.mjs +186 -0
- package/src/commands/action/replay.mjs +54 -0
- package/src/commands/campaign/add.mjs +64 -0
- package/src/commands/campaign/delete.mjs +61 -0
- package/src/commands/campaign/get.mjs +6 -20
- 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 +63 -0
- package/src/commands/org/crm.mjs +88 -0
- package/src/commands/org/get.mjs +7 -8
- package/src/commands/org/join.mjs +77 -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/add.mjs +113 -0
- package/src/commands/widget/get.mjs +59 -0
- package/src/commands/widget/list.mjs +116 -0
- package/src/config.mjs +1 -1
- package/src/hooks/help.mjs +14 -0
- package/src/hooks/init.mjs +12 -0
- package/src/procaCommand.mjs +90 -21
- package/src/queries/widget.mjs +12 -0
- package/src/urql.mjs +12 -1
- package/src/util/flags.mjs +16 -22
- package/src/util/twitter.mjs +23 -0
|
@@ -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
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Config, Help } from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
export default class CustomHelp extends Help {
|
|
4
|
+
showCommandHelp(command) {
|
|
5
|
+
// console.log("This will be displayed in single-command CLIs");
|
|
6
|
+
super.showCommandHelp(command);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async showHelp(argv) {
|
|
10
|
+
// console.log('This will be displayed in multi-command CLIs')
|
|
11
|
+
// Always include --all flag to show all commands
|
|
12
|
+
await super.showHelp([...argv, "--all"]);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import oclif from "@oclif/core";
|
|
2
|
+
import CustomHelp from "./help.mjs";
|
|
3
|
+
|
|
4
|
+
//console.log("hook init");
|
|
5
|
+
|
|
6
|
+
const hook = async (opts) => {
|
|
7
|
+
//console.log(opts);
|
|
8
|
+
//console.log(opts.config.helpClass, CustomHelp);
|
|
9
|
+
// opts.config.helpClass = CustomHelp;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default hook;
|
package/src/procaCommand.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Command, Flags, ux } from "@oclif/core";
|
|
1
|
+
import { Args, Command, Flags, ux } from "@oclif/core";
|
|
2
2
|
import debug from "debug";
|
|
3
|
+
import { parse as dxid, id } from "dxid";
|
|
3
4
|
import Table from "easy-table";
|
|
4
5
|
import fastcsv from "fast-csv";
|
|
5
6
|
|
|
@@ -9,37 +10,82 @@ import { createClient } from "#src/urql.mjs";
|
|
|
9
10
|
export class ProcaCommand extends Command {
|
|
10
11
|
static enableJsonFlag = true;
|
|
11
12
|
procaConfig = { url: "https://api.proca.app/api" };
|
|
12
|
-
format = "
|
|
13
|
+
format = "human"; // the default formatting
|
|
13
14
|
flags = {};
|
|
14
15
|
|
|
15
16
|
static baseFlags = {
|
|
16
|
-
|
|
17
|
+
human: Flags.boolean({
|
|
17
18
|
helpGroup: "OUTPUT", // Optional, groups it under a specific help section if desired
|
|
18
|
-
description: "Format output
|
|
19
|
+
description: "Format output to be read on screen by a human [default]",
|
|
19
20
|
default: true,
|
|
20
|
-
exclusive: ["csv", "json"],
|
|
21
21
|
}),
|
|
22
22
|
json: Flags.boolean({
|
|
23
23
|
helpGroup: "OUTPUT", // Optional, groups it under a specific help section if desired
|
|
24
24
|
description: "Format output as json",
|
|
25
|
-
exclusive: ["
|
|
25
|
+
exclusive: ["human", "json"],
|
|
26
26
|
}),
|
|
27
27
|
csv: Flags.boolean({
|
|
28
28
|
description: "Format output as csv",
|
|
29
29
|
helpGroup: "OUTPUT", // Optional, groups it under a specific help section if desired
|
|
30
|
-
exclusive: ["json", "table"],
|
|
31
30
|
}),
|
|
32
31
|
simplify: Flags.boolean({
|
|
33
32
|
helpGroup: "OUTPUT",
|
|
34
33
|
description:
|
|
35
|
-
"flatten and filter to output only the most important attributes",
|
|
34
|
+
"flatten and filter to output only the most important attributes, mostly relevant for json",
|
|
36
35
|
dependsOn: ["json"],
|
|
37
36
|
}),
|
|
38
37
|
};
|
|
39
38
|
|
|
39
|
+
static multiid() {
|
|
40
|
+
const args = {
|
|
41
|
+
id_name_dxid: Args.string({
|
|
42
|
+
ignoreStdin: true,
|
|
43
|
+
hidden: true,
|
|
44
|
+
description:
|
|
45
|
+
"it's better to use -i <id> or -x <dxid> or -n <name>, but you can for convenience",
|
|
46
|
+
}),
|
|
47
|
+
};
|
|
48
|
+
return args;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static flagify(params = {}) {
|
|
52
|
+
const flags = ProcaCommand.baseFlags;
|
|
53
|
+
if (params.multiid) {
|
|
54
|
+
flags.id = Flags.string({
|
|
55
|
+
char: "i",
|
|
56
|
+
parse: (input) => Number.parseInt(input, 10),
|
|
57
|
+
exclusive: ["name", "dxid"],
|
|
58
|
+
});
|
|
59
|
+
flags.dxid = Flags.string({
|
|
60
|
+
char: "x",
|
|
61
|
+
description: "dxid",
|
|
62
|
+
});
|
|
63
|
+
flags.name = Flags.string({
|
|
64
|
+
char: "n",
|
|
65
|
+
charAliases: ["o"],
|
|
66
|
+
description: "name",
|
|
67
|
+
helpValue: "<the_short_name>",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return flags;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async parse() {
|
|
74
|
+
const parsed = await super.parse();
|
|
75
|
+
const maybe = parsed.args.id_name_dxid;
|
|
76
|
+
if (maybe) {
|
|
77
|
+
const d = dxid(maybe, false);
|
|
78
|
+
if (d) parsed.flags.id = d;
|
|
79
|
+
else parsed.flags.name = maybe;
|
|
80
|
+
}
|
|
81
|
+
if (parsed.flags.dxid) {
|
|
82
|
+
parsed.flags.id = dxid(parsed.flags.dxid);
|
|
83
|
+
}
|
|
84
|
+
return parsed;
|
|
85
|
+
}
|
|
40
86
|
async init() {
|
|
41
87
|
await super.init();
|
|
42
|
-
const { flags } = await this.parse();
|
|
88
|
+
const { argv, flags } = await this.parse();
|
|
43
89
|
this.flags = flags;
|
|
44
90
|
if (flags.json) this.format = "json";
|
|
45
91
|
if (flags.csv) this.format = "csv";
|
|
@@ -55,21 +101,45 @@ export class ProcaCommand extends Command {
|
|
|
55
101
|
createClient(userConfig);
|
|
56
102
|
}
|
|
57
103
|
|
|
104
|
+
async catch(err) {
|
|
105
|
+
// Check if the error was caused by a missing flag or wrong argument format
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
err.message.includes("Unexpected argument") ||
|
|
109
|
+
err.message.includes("flag")
|
|
110
|
+
) {
|
|
111
|
+
// Try to adjust the argument as a flag
|
|
112
|
+
const argv = process.argv;
|
|
113
|
+
console.log(argv);
|
|
114
|
+
if (argv.includes("param")) {
|
|
115
|
+
// Adjusting the argument 'param' to be a flag `-id`
|
|
116
|
+
const paramIndex = argv.indexOf("param");
|
|
117
|
+
argv.splice(paramIndex, 0, "-id"); // Insert the flag `-id` before 'param'
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Re-run the command with modified arguments
|
|
121
|
+
await this.parse();
|
|
122
|
+
} else {
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
58
127
|
simplify = (d) => {
|
|
59
128
|
const r = {};
|
|
60
129
|
for (const [key, value] of Object.entries(d)) {
|
|
61
130
|
if (key === "__typename") continue;
|
|
131
|
+
if (key === "config" && typeof value === "string") continue; // it's just a giant mess if not processed, let's skipt
|
|
62
132
|
if (value === null) continue;
|
|
63
|
-
|
|
64
133
|
if (typeof value === "string" || typeof value === "number") {
|
|
65
134
|
r[key] = value;
|
|
66
135
|
continue;
|
|
67
136
|
}
|
|
68
137
|
|
|
69
|
-
if (typeof value === "object"
|
|
70
|
-
r[key] = value.name;
|
|
138
|
+
if (typeof value === "object") {
|
|
139
|
+
if (value?.name) r[key] = value.name;
|
|
71
140
|
continue;
|
|
72
141
|
}
|
|
142
|
+
r[key] = value;
|
|
73
143
|
}
|
|
74
144
|
return r;
|
|
75
145
|
};
|
|
@@ -118,15 +188,14 @@ export class ProcaCommand extends Command {
|
|
|
118
188
|
});
|
|
119
189
|
}
|
|
120
190
|
|
|
121
|
-
table(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
) {
|
|
191
|
+
table(data, transformRow, print = (table) => table.toString()) {
|
|
192
|
+
if (!transformRow) {
|
|
193
|
+
transformRow = (d, cell) => {
|
|
194
|
+
for (const [key, value] of Object.entries(this.simplify(d))) {
|
|
195
|
+
cell(key, value);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
130
199
|
const theme = this.config.theme;
|
|
131
200
|
Table.prototype.pushDelimeter = function (cols) {
|
|
132
201
|
// 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
|
};
|
package/src/util/flags.mjs
CHANGED
|
@@ -12,28 +12,22 @@
|
|
|
12
12
|
// instrumentation.
|
|
13
13
|
// -------------------------------------------------------------------------------
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export function _preprocessCliFlags(process) {
|
|
16
|
+
process.argv.map((arg) => {
|
|
17
|
+
if (arg === "--dev-debug") {
|
|
18
|
+
let debug = "*";
|
|
19
|
+
const filterIndex = process.argv.indexOf("--debug-filter");
|
|
20
|
+
if (filterIndex > 0) {
|
|
21
|
+
debug = process.argv[filterIndex + 1];
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (filterIndex > 0) {
|
|
26
|
-
debug = process.argv[filterIndex + 1];
|
|
23
|
+
process.argv.splice(filterIndex, 2);
|
|
24
|
+
}
|
|
25
|
+
// convert --dev-debug into a set of environment variables
|
|
26
|
+
process.env.DEBUG = debug;
|
|
27
|
+
process.env.PROCA_ENV = "development";
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
process.env.PROCA_ENV = 'development';
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// need to calculate indexOf --dev-debug here because it might've changed based on --debug-filter
|
|
36
|
-
process.argv.splice(process.argv.indexOf('--dev-debug'), 1);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
29
|
+
// need to calculate indexOf --dev-debug here because it might've changed based on --debug-filter
|
|
30
|
+
process.argv.splice(process.argv.indexOf("--dev-debug"), 1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
39
33
|
}
|
|
@@ -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
|
+
};
|