proca 0.1.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 +214 -0
- package/package.json +66 -0
- package/proca-cli +8 -0
- package/src/commands/campaign/get.mjs +121 -0
- package/src/commands/campaign/list.mjs +165 -0
- package/src/commands/campaign/queries.graphql +19 -0
- package/src/commands/config/add.mjs +108 -0
- package/src/commands/org/get.mjs +97 -0
- package/src/config.mjs +31 -0
- package/src/generated/schema.json +10677 -0
- package/src/index.mjs +1 -0
- package/src/procaCommand.mjs +158 -0
- package/src/queries/campaign.mjs +21 -0
- package/src/urql.mjs +46 -0
- package/src/util/flags.mjs +39 -0
- package/theme.json +29 -0
package/src/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from "@oclif/core";
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Command, Flags, ux } from "@oclif/core";
|
|
2
|
+
import debug from "debug";
|
|
3
|
+
import Table from "easy-table";
|
|
4
|
+
import fastcsv from "fast-csv";
|
|
5
|
+
|
|
6
|
+
import { getFilename as fileConfig, load as loadConfig } from "#src/config.mjs";
|
|
7
|
+
import { createClient } from "#src/urql.mjs";
|
|
8
|
+
|
|
9
|
+
export class ProcaCommand extends Command {
|
|
10
|
+
static enableJsonFlag = true;
|
|
11
|
+
procaConfig = { url: "https://api.proca.app/api" };
|
|
12
|
+
format = "table"; // the default formatting
|
|
13
|
+
flags = {};
|
|
14
|
+
|
|
15
|
+
static baseFlags = {
|
|
16
|
+
table: Flags.boolean({
|
|
17
|
+
helpGroup: "OUTPUT", // Optional, groups it under a specific help section if desired
|
|
18
|
+
description: "Format output as table [default]",
|
|
19
|
+
default: true,
|
|
20
|
+
exclusive: ["csv", "json"],
|
|
21
|
+
}),
|
|
22
|
+
json: Flags.boolean({
|
|
23
|
+
helpGroup: "OUTPUT", // Optional, groups it under a specific help section if desired
|
|
24
|
+
description: "Format output as json",
|
|
25
|
+
exclusive: ["csv", "table"],
|
|
26
|
+
}),
|
|
27
|
+
csv: Flags.boolean({
|
|
28
|
+
description: "Format output as csv",
|
|
29
|
+
helpGroup: "OUTPUT", // Optional, groups it under a specific help section if desired
|
|
30
|
+
exclusive: ["json", "table"],
|
|
31
|
+
}),
|
|
32
|
+
simplify: Flags.boolean({
|
|
33
|
+
helpGroup: "OUTPUT",
|
|
34
|
+
description:
|
|
35
|
+
"flatten and filter to output only the most important attributes",
|
|
36
|
+
dependsOn: ["json"],
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
async init() {
|
|
41
|
+
await super.init();
|
|
42
|
+
const { flags } = await this.parse();
|
|
43
|
+
this.flags = flags;
|
|
44
|
+
if (flags.json) this.format = "json";
|
|
45
|
+
if (flags.csv) this.format = "csv";
|
|
46
|
+
|
|
47
|
+
this.debug = debug("proca");
|
|
48
|
+
const userConfig = loadConfig(this.config.configDir);
|
|
49
|
+
if (userConfig) {
|
|
50
|
+
this.procaConfig = userConfig;
|
|
51
|
+
} else {
|
|
52
|
+
const file = fileConfig(this.config.configDir);
|
|
53
|
+
this.warn("missing config", file);
|
|
54
|
+
}
|
|
55
|
+
createClient(userConfig);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
simplify = (d) => {
|
|
59
|
+
const r = {};
|
|
60
|
+
for (const [key, value] of Object.entries(d)) {
|
|
61
|
+
if (key === "__typename") continue;
|
|
62
|
+
if (value === null) continue;
|
|
63
|
+
|
|
64
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
65
|
+
r[key] = value;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof value === "object" && value.name) {
|
|
70
|
+
r[key] = value.name;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return r;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
tlog(color, ...msg) {
|
|
78
|
+
const coloredMsg = msg.map((d) => ux.colorize(this.config.theme[color], d));
|
|
79
|
+
this.log(...coloredMsg);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
info(...msg) {
|
|
83
|
+
this.tlog("info", msg);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
prettyJson(obj) {
|
|
87
|
+
if (typeof obj === "string") {
|
|
88
|
+
obj = JSON.parse(obj);
|
|
89
|
+
}
|
|
90
|
+
this.log(ux.colorizeJson(obj, { theme: this.config.theme.json }));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
warn(...msg) {
|
|
94
|
+
this.tlog("warn", ...msg);
|
|
95
|
+
}
|
|
96
|
+
error(msg, options = {}) {
|
|
97
|
+
const colouredMessage = ux.colorize(this.config.theme.error, msg);
|
|
98
|
+
super.error(colouredMessage, options);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async csv(data) {
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
let d = null;
|
|
104
|
+
if (Array.isArray(data)) {
|
|
105
|
+
d = data.map(this.simplify);
|
|
106
|
+
} else {
|
|
107
|
+
d = [this.simplify(data)];
|
|
108
|
+
}
|
|
109
|
+
const stream = fastcsv
|
|
110
|
+
.write(d, { headers: true })
|
|
111
|
+
.on("finish", () => {
|
|
112
|
+
console.log();
|
|
113
|
+
resolve();
|
|
114
|
+
})
|
|
115
|
+
.on("error", reject);
|
|
116
|
+
|
|
117
|
+
stream.pipe(process.stdout);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
table(
|
|
122
|
+
data,
|
|
123
|
+
transformRow = (d, cell) => {
|
|
124
|
+
for (const [key, value] of Object.entries(this.simplify(d))) {
|
|
125
|
+
cell(key, value);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
print = (table) => table.toString(),
|
|
129
|
+
) {
|
|
130
|
+
const theme = this.config.theme;
|
|
131
|
+
Table.prototype.pushDelimeter = function (cols) {
|
|
132
|
+
// hack to change the formatting of the header
|
|
133
|
+
cols = cols || this.columns();
|
|
134
|
+
cols.forEach(function (col) {
|
|
135
|
+
this.cell(
|
|
136
|
+
col,
|
|
137
|
+
undefined,
|
|
138
|
+
Table.leftPadder(ux.colorize(theme.flagSeparator, "-")),
|
|
139
|
+
);
|
|
140
|
+
}, this);
|
|
141
|
+
return this.newRow();
|
|
142
|
+
};
|
|
143
|
+
this.log(Table.print(data, transformRow, print));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async output(data) {
|
|
147
|
+
if (this.format === "json") {
|
|
148
|
+
if (this.flags.simplify) return data.map(this.simplify);
|
|
149
|
+
return data;
|
|
150
|
+
}
|
|
151
|
+
if (this.format === "csv") {
|
|
152
|
+
return this.csv(data);
|
|
153
|
+
}
|
|
154
|
+
return this.table(data);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export default ProcaCommand;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { gql } from "#src/urql.mjs";
|
|
2
|
+
|
|
3
|
+
export const FragmentSummary = gql`fragment Summary on Campaign {id name title externalId status}`;
|
|
4
|
+
|
|
5
|
+
export const FragmentOrg = gql`
|
|
6
|
+
fragment Org on Campaign {
|
|
7
|
+
org {
|
|
8
|
+
name
|
|
9
|
+
title
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export const FragmentStats = gql`
|
|
15
|
+
fragment Stats on Campaign {
|
|
16
|
+
stats {
|
|
17
|
+
supporterCount
|
|
18
|
+
actionCount {actionType count}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
`;
|
package/src/urql.mjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { authExchange } from "@urql/exchange-auth";
|
|
2
|
+
import {
|
|
3
|
+
createClient as _createClient,
|
|
4
|
+
cacheExchange,
|
|
5
|
+
fetchExchange,
|
|
6
|
+
gql,
|
|
7
|
+
} from "urql";
|
|
8
|
+
|
|
9
|
+
export let client = {
|
|
10
|
+
query: () => {
|
|
11
|
+
throw new Error("urql graphql not initialised, call init first");
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Create a URQL client with your GraphQL API endpoint
|
|
16
|
+
export const createClient = (config) => {
|
|
17
|
+
client = _createClient({
|
|
18
|
+
url: config.url || "https://api.proca.app/api",
|
|
19
|
+
exchanges: [
|
|
20
|
+
// cacheExchange, // Handles caching
|
|
21
|
+
authExchange(async (utils) => {
|
|
22
|
+
const token = config.token;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
addAuthToOperation(operation) {
|
|
26
|
+
if (!token) return operation;
|
|
27
|
+
return utils.appendHeaders(operation, {
|
|
28
|
+
Authorization: `Bearer ${token}`,
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}),
|
|
33
|
+
fetchExchange, // Handles fetching
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const query = async (query, payload) => {
|
|
39
|
+
const result = await client.query(query, payload).toPromise();
|
|
40
|
+
if (result.error) {
|
|
41
|
+
throw new Error(result.error);
|
|
42
|
+
}
|
|
43
|
+
return result.data;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { gql };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* inspired by https://github.com/salesforcecli/cli/blob/main/src/flags.ts
|
|
3
|
+
* Copyright (c) 2020, salesforce.com, inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
* Licensed under the BSD 3-Clause license.
|
|
6
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// -------------------------------------------------------------------------------
|
|
10
|
+
// No requires or imports since this is loaded early in the cli lifecycle and we
|
|
11
|
+
// want to minimize the number of packages that load before enabling require
|
|
12
|
+
// instrumentation.
|
|
13
|
+
// -------------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
export type ProcessLike = {
|
|
16
|
+
argv: string[];
|
|
17
|
+
env: { [key: string]: string | undefined };
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function preprocessCliFlags(process: ProcessLike): void {
|
|
21
|
+
process.argv.map((arg) => {
|
|
22
|
+
if (arg === '--dev-debug') {
|
|
23
|
+
let debug = '*';
|
|
24
|
+
const filterIndex = process.argv.indexOf('--debug-filter');
|
|
25
|
+
if (filterIndex > 0) {
|
|
26
|
+
debug = process.argv[filterIndex + 1];
|
|
27
|
+
|
|
28
|
+
process.argv.splice(filterIndex, 2);
|
|
29
|
+
}
|
|
30
|
+
// convert --dev-debug into a set of environment variables
|
|
31
|
+
process.env.DEBUG = debug;
|
|
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
|
+
});
|
|
39
|
+
}
|
package/theme.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"info": "cyan",
|
|
3
|
+
"warn": "#FFAB40",
|
|
4
|
+
"error": "red",
|
|
5
|
+
"bin": "block",
|
|
6
|
+
"command": "cyan",
|
|
7
|
+
"commandSummary": "black",
|
|
8
|
+
"dollarSign": "white",
|
|
9
|
+
"flag": "blackBright",
|
|
10
|
+
"flagDefaultValue": "blue",
|
|
11
|
+
"flagOptions": "white",
|
|
12
|
+
"flagRequired": "red",
|
|
13
|
+
"flagSeparator": "white",
|
|
14
|
+
"json": {
|
|
15
|
+
"brace": "magenta",
|
|
16
|
+
"bracket": "magenta",
|
|
17
|
+
"colon": "dim",
|
|
18
|
+
"comma": "dim",
|
|
19
|
+
"key": "yellow",
|
|
20
|
+
"string": "green",
|
|
21
|
+
"number": "green",
|
|
22
|
+
"boolean": "green",
|
|
23
|
+
"null": "red"
|
|
24
|
+
},
|
|
25
|
+
"sectionDescription": "blackBright",
|
|
26
|
+
"sectionHeader": "underline",
|
|
27
|
+
"topic": "cyan",
|
|
28
|
+
"version": "white"
|
|
29
|
+
}
|