@proca/cli 3.4.5 → 3.8.3
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 +1991 -61
- package/package.json +88 -72
- package/proca-cli +8 -0
- package/src/commands/action/add.mjs +192 -0
- package/src/commands/action/confirm.mjs +93 -0
- package/src/commands/action/count.mjs +61 -0
- package/src/commands/action/list.mjs +204 -0
- package/src/commands/action/replay.mjs +56 -0
- package/src/commands/action/requeue.mjs +156 -0
- package/src/commands/campaign/add.mjs +113 -0
- package/src/commands/campaign/copy.mjs +91 -0
- package/src/commands/campaign/delete.mjs +41 -0
- package/src/commands/campaign/get.mjs +132 -0
- package/src/commands/campaign/list.mjs +161 -0
- package/src/commands/campaign/mtt.mjs +131 -0
- package/src/commands/campaign/queries.graphql +19 -0
- package/src/commands/campaign/status.mjs +63 -0
- package/src/commands/campaign/widget/archive.mjs +124 -0
- package/src/commands/campaign/widget/copy.mjs +175 -0
- package/src/commands/campaign/widget/get.mjs +19 -0
- package/src/commands/campaign/widget/index.mjs +17 -0
- package/src/commands/campaign/widget/rebuild.mjs +50 -0
- package/src/commands/config/add.mjs +97 -0
- package/src/commands/config/folder.mjs +42 -0
- package/src/commands/config/server.mjs +33 -0
- package/src/commands/config/set.mjs +103 -0
- package/src/commands/config/user.mjs +79 -0
- package/src/commands/contact/count.mjs +41 -0
- package/src/commands/contact/list.mjs +207 -0
- package/src/commands/org/add.mjs +75 -0
- package/src/commands/org/crm.mjs +88 -0
- package/src/commands/org/delete.mjs +48 -0
- package/src/commands/org/email.mjs +111 -0
- package/src/commands/org/get.mjs +152 -0
- package/src/commands/service/add.mjs +78 -0
- package/src/commands/service/list.mjs +24 -0
- package/src/commands/target/add.mjs +94 -0
- package/src/commands/template/add.mjs +97 -0
- package/src/commands/template/list.mjs +61 -0
- package/src/commands/user/get.mjs +91 -0
- package/src/commands/user/invite.mjs +56 -0
- package/src/commands/user/join.mjs +81 -0
- package/src/commands/user/leave.mjs +57 -0
- package/src/commands/user/list.mjs +80 -0
- package/src/commands/user/reset.mjs +83 -0
- package/src/commands/widget/add.mjs +116 -0
- package/src/commands/widget/delete.mjs +45 -0
- package/src/commands/widget/get.mjs +60 -0
- package/src/commands/widget/list.mjs +135 -0
- package/src/commands/widget/rebuild.mjs +64 -0
- package/src/commands/widget/update.mjs +174 -0
- package/src/config.mjs +49 -0
- package/src/generated/schema.json +10677 -0
- package/src/hooks/help.mjs +14 -0
- package/src/hooks/init.mjs +41 -0
- package/src/index.mjs +1 -0
- package/src/procaCommand.mjs +316 -0
- package/src/queries/campaign.mjs +35 -0
- package/src/queries/widget.mjs +25 -0
- package/src/urql.mjs +60 -0
- package/src/util/twitter.mjs +23 -0
- package/theme.json +29 -0
- package/bin/proca-cli +0 -4
- package/dist/browser.d.ts +0 -1
- package/dist/browser.js +0 -28
- package/dist/browser.js.map +0 -1
- package/dist/campaign.d.ts +0 -156
- package/dist/campaign.js +0 -192
- package/dist/campaign.js.map +0 -1
- package/dist/cli.d.ts +0 -40
- package/dist/cli.js +0 -416
- package/dist/cli.js.map +0 -1
- package/dist/client.d.ts +0 -2
- package/dist/client.js +0 -18
- package/dist/client.js.map +0 -1
- package/dist/config.d.ts +0 -35
- package/dist/config.js +0 -71
- package/dist/config.js.map +0 -1
- package/dist/crypto.d.ts +0 -40
- package/dist/crypto.js +0 -53
- package/dist/crypto.js.map +0 -1
- package/dist/export.d.ts +0 -15
- package/dist/export.js +0 -145
- package/dist/export.js.map +0 -1
- package/dist/format.d.ts +0 -37
- package/dist/format.js +0 -200
- package/dist/format.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -39
- package/dist/index.js.map +0 -1
- package/dist/keys.d.ts +0 -4
- package/dist/keys.js +0 -38
- package/dist/keys.js.map +0 -1
- package/dist/org.d.ts +0 -11
- package/dist/org.js +0 -97
- package/dist/org.js.map +0 -1
- package/dist/proca.d.ts +0 -2095
- package/dist/proca.js +0 -398
- package/dist/proca.js.map +0 -1
- package/dist/queue.d.ts +0 -8
- package/dist/queue.js +0 -126
- package/dist/queue.js.map +0 -1
- package/dist/queueMessage.d.ts +0 -102
- package/dist/queueMessage.js +0 -109
- package/dist/queueMessage.js.map +0 -1
- package/dist/service/actionnetwork.d.ts +0 -10
- package/dist/service/actionnetwork.js +0 -302
- package/dist/service/actionnetwork.js.map +0 -1
- package/dist/service/distance.d.ts +0 -3
- package/dist/service/distance.js +0 -96
- package/dist/service/distance.js.map +0 -1
- package/dist/service/echo.d.ts +0 -4
- package/dist/service/echo.js +0 -19
- package/dist/service/echo.js.map +0 -1
- package/dist/service/email.d.ts +0 -14
- package/dist/service/email.js +0 -67
- package/dist/service/email.js.map +0 -1
- package/dist/service/identity.d.ts +0 -58
- package/dist/service/identity.js +0 -190
- package/dist/service/identity.js.map +0 -1
- package/dist/service/index.d.ts +0 -14
- package/dist/service/index.js +0 -61
- package/dist/service/index.js.map +0 -1
- package/dist/setup.d.ts +0 -2
- package/dist/setup.js +0 -291
- package/dist/setup.js.map +0 -1
- package/dist/util.d.ts +0 -5
- package/dist/util.js +0 -30
- package/dist/util.js.map +0 -1
- package/dist/watch.d.ts +0 -9
- package/dist/watch.js +0 -80
- package/dist/watch.js.map +0 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import prompts from "prompts";
|
|
3
|
+
import CampaignGet from "#src/commands/campaign/get.mjs";
|
|
4
|
+
import WidgetAdd from "#src/commands/widget/add.mjs";
|
|
5
|
+
import WidgetList from "#src/commands/widget/list.mjs";
|
|
6
|
+
import Command from "#src/procaCommand.mjs";
|
|
7
|
+
|
|
8
|
+
export default class CampaignWidgetCopy extends Command {
|
|
9
|
+
static args = this.multiid();
|
|
10
|
+
|
|
11
|
+
static description = "Copy widgets from one campaign to another";
|
|
12
|
+
|
|
13
|
+
static examples = [
|
|
14
|
+
"<%= config.bin %> <%= command.id %> old_campaign --to new_campaign",
|
|
15
|
+
"<%= config.bin %> <%= command.id %> -n old_campaign --to new_campaign",
|
|
16
|
+
"<%= config.bin %> <%= command.id %> old_campaign --to new_campaign --suffix _archive",
|
|
17
|
+
"<%= config.bin %> <%= command.id %> old_campaign --to new_campaign --dry-run",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
static flags = {
|
|
21
|
+
...this.flagify({ multiid: true }),
|
|
22
|
+
to: Flags.string({
|
|
23
|
+
char: "t",
|
|
24
|
+
required: true,
|
|
25
|
+
description: "destination campaign name",
|
|
26
|
+
helpValue: "<campaign name>",
|
|
27
|
+
}),
|
|
28
|
+
suffix: Flags.string({
|
|
29
|
+
char: "s",
|
|
30
|
+
description: "suffix to remove from widget names (e.g., _archive, -v1)",
|
|
31
|
+
helpValue: "<suffix>",
|
|
32
|
+
default: "_archive",
|
|
33
|
+
}),
|
|
34
|
+
"dry-run": Flags.boolean({
|
|
35
|
+
description: "preview changes without executing",
|
|
36
|
+
default: false,
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
fetchCampaign = async ({ id, name }) => {
|
|
41
|
+
const campaignGet = new CampaignGet([], this.config);
|
|
42
|
+
return await campaignGet.fetch({ id, name });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
fetchWidgets = async (campaignName) => {
|
|
46
|
+
const widgetList = new WidgetList([], this.config);
|
|
47
|
+
widgetList.flags = { campaign: campaignName, config: true };
|
|
48
|
+
return await widgetList.fetchCampaign(campaignName);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
async run() {
|
|
52
|
+
const { flags } = await this.parse();
|
|
53
|
+
const { id, name, to, suffix, "dry-run": dryRun } = flags;
|
|
54
|
+
|
|
55
|
+
this.log(`Fetching source campaign: ${name || id}`);
|
|
56
|
+
const sourceCampaign = await this.fetchCampaign({ id, name });
|
|
57
|
+
|
|
58
|
+
if (!sourceCampaign) {
|
|
59
|
+
this.error(`Source campaign not found: ${name || id}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.log(`Fetching widgets from: ${sourceCampaign.name}`);
|
|
64
|
+
const sourceWidgets = await this.fetchWidgets(sourceCampaign.name);
|
|
65
|
+
|
|
66
|
+
if (!sourceWidgets || sourceWidgets.length === 0) {
|
|
67
|
+
this.warn("No widgets found in source campaign");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.log(`Found ${sourceWidgets.length} widgets`);
|
|
72
|
+
|
|
73
|
+
const widgets = sourceWidgets.map((widget) => {
|
|
74
|
+
const newName = widget.name.replace(suffix, "");
|
|
75
|
+
return {
|
|
76
|
+
newName,
|
|
77
|
+
lang: widget.locale,
|
|
78
|
+
org: widget.org.name,
|
|
79
|
+
|
|
80
|
+
config: widget.config ? JSON.stringify(widget.config) : undefined,
|
|
81
|
+
|
|
82
|
+
thankYouTemplate: widget.thankYouTemplateRef ?? widget.thankYouTemplate,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
this.log("\n=== WIDGET COPY PLAN ===");
|
|
87
|
+
this.log(`From: ${sourceCampaign.name}`);
|
|
88
|
+
this.log(`To: ${to}`);
|
|
89
|
+
this.log(`\nWidgets (${widgets.length}):`);
|
|
90
|
+
this.table(widgets);
|
|
91
|
+
|
|
92
|
+
if (dryRun) {
|
|
93
|
+
this.log("\n[DRY RUN] No changes made");
|
|
94
|
+
return widgets;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const response = await prompts({
|
|
98
|
+
type: "confirm",
|
|
99
|
+
name: "proceed",
|
|
100
|
+
message: `Copy ${widgets.length} widgets to campaign "${to}"?`,
|
|
101
|
+
initial: false,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (!response.proceed) {
|
|
105
|
+
this.log("Cancelled");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.log("\nCopying widgets...");
|
|
110
|
+
const widgetAdd = new WidgetAdd([], this.config);
|
|
111
|
+
const results = [];
|
|
112
|
+
|
|
113
|
+
for (const widget of widgets) {
|
|
114
|
+
try {
|
|
115
|
+
this.log(` Creating: ${widget.newName}`);
|
|
116
|
+
const created = await widgetAdd.create({
|
|
117
|
+
campaign: to,
|
|
118
|
+
org: widget.org,
|
|
119
|
+
name: widget.newName,
|
|
120
|
+
lang: widget.lang,
|
|
121
|
+
|
|
122
|
+
config: widget.config,
|
|
123
|
+
thankYouTemplate: widget.thankYouTemplate,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
results.push({
|
|
127
|
+
name: widget.newName,
|
|
128
|
+
id: created.id,
|
|
129
|
+
status: "success",
|
|
130
|
+
});
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if (error.message.includes("invalid name (already taken?)")) {
|
|
133
|
+
// Just log and continue for existing widgets
|
|
134
|
+
this.log(` ⚠ Skipped (already exists): ${widget.newName}`);
|
|
135
|
+
results.push({
|
|
136
|
+
name: widget.newName,
|
|
137
|
+
status: "skipped",
|
|
138
|
+
reason: "already exists",
|
|
139
|
+
});
|
|
140
|
+
} else if (
|
|
141
|
+
error.message.includes("User is not a member of organisation")
|
|
142
|
+
) {
|
|
143
|
+
// Skip widgets where user doesn't have permission
|
|
144
|
+
this.log(
|
|
145
|
+
` ⚠ Skipped (no permission): ${widget.newName} (org: ${widget.org})`,
|
|
146
|
+
);
|
|
147
|
+
results.push({
|
|
148
|
+
name: widget.newName,
|
|
149
|
+
status: "skipped",
|
|
150
|
+
reason: "no permission",
|
|
151
|
+
org: widget.org,
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
this.warn(` Failed to create ${widget.newName}: ${error.message}`);
|
|
155
|
+
results.push({
|
|
156
|
+
name: widget.newName,
|
|
157
|
+
status: "failed",
|
|
158
|
+
error: error.message,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.log("\n=== COPY COMPLETE ===");
|
|
165
|
+
const successful = results.filter((r) => r.status === "success").length;
|
|
166
|
+
const skipped = results.filter((r) => r.status === "skipped").length;
|
|
167
|
+
const failed = results.filter((r) => r.status === "failed").length;
|
|
168
|
+
|
|
169
|
+
this.log(`Widgets created: ${successful}`);
|
|
170
|
+
if (skipped > 0) this.log(`Widgets skipped: ${skipped}`);
|
|
171
|
+
if (failed > 0) this.warn(`Widgets failed: ${failed}`);
|
|
172
|
+
|
|
173
|
+
return this.output(results);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Command from "#src/procaCommand.mjs";
|
|
2
|
+
import WidgetList from "../../widget/list.mjs";
|
|
3
|
+
|
|
4
|
+
export default class CampaignWidgetList extends Command {
|
|
5
|
+
static description = "List widgets in a campaign";
|
|
6
|
+
static args = this.multiid();
|
|
7
|
+
|
|
8
|
+
static flags = {
|
|
9
|
+
// flag with no value (-f, --force)
|
|
10
|
+
...this.flagify({ multiid: true }),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags } = await this.parse();
|
|
15
|
+
|
|
16
|
+
// Delegate to widget list, but with campaign pre-filled
|
|
17
|
+
await WidgetList.run(["--campaign", flags.name], this.config);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
export default class CampaignWidget extends Command {
|
|
4
|
+
static description = "commands for multiple widgets in a campaign";
|
|
5
|
+
static aliases = ["campaign:widget"];
|
|
6
|
+
static hidden = true; // Hide from command list, only show as topic
|
|
7
|
+
|
|
8
|
+
static id = "campaign:widget";
|
|
9
|
+
|
|
10
|
+
async run() {
|
|
11
|
+
const { Help } = await import("@oclif/core");
|
|
12
|
+
const help = new Help(this.config, { all: true });
|
|
13
|
+
const formatted = help.formatCommand(this);
|
|
14
|
+
this.log(formatted);
|
|
15
|
+
// this.error("Please specify a subcommand, run with --help to list them");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import WidgetList from "#src/commands/widget/list.mjs";
|
|
2
|
+
import WidgetRebuild from "#src/commands/widget/rebuild.mjs";
|
|
3
|
+
import Command from "#src/procaCommand.mjs";
|
|
4
|
+
|
|
5
|
+
export default class CampaignWidgetRebuild extends Command {
|
|
6
|
+
static description = "(re)build all the widgets of a campaign";
|
|
7
|
+
|
|
8
|
+
static examples = ["$ proca-cli campaign widget rebuild climate-action"];
|
|
9
|
+
|
|
10
|
+
static args = this.multiid();
|
|
11
|
+
|
|
12
|
+
static flags = {
|
|
13
|
+
// flag with no value (-f, --force)
|
|
14
|
+
...this.flagify({ multiid: true }),
|
|
15
|
+
// dryRun: Flags.boolean({
|
|
16
|
+
// description: 'Show what would be rebuilt without actually doing it',
|
|
17
|
+
// }),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
simplify = (d) => {
|
|
21
|
+
d.location = undefined;
|
|
22
|
+
d.config = undefined;
|
|
23
|
+
d.org = d.org.name;
|
|
24
|
+
return d;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
table = (r) => {
|
|
28
|
+
super.table(r, null, null);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
rebuild = async (props) => {
|
|
32
|
+
const wapi = new WidgetList();
|
|
33
|
+
const rebuildapi = new WidgetRebuild();
|
|
34
|
+
wapi.flags.config = true; //we need to fetch each widget config
|
|
35
|
+
const widgets = await wapi.fetchCampaign(props.name); //list all widgets
|
|
36
|
+
const result = [];
|
|
37
|
+
for (const widget of widgets) {
|
|
38
|
+
// do not process all widgets in parallel but in sequence
|
|
39
|
+
const r = await rebuildapi.rebuild({ widget });
|
|
40
|
+
result.push(r);
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
async run() {
|
|
46
|
+
const { flags } = await this.parse();
|
|
47
|
+
const r = await this.rebuild(flags);
|
|
48
|
+
return this.output(r);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { error, stdout } from "@oclif/core/ux";
|
|
3
|
+
import prompts from "prompts";
|
|
4
|
+
import { format, get as getConfig, getFilename, write } from "#src/config.mjs";
|
|
5
|
+
import Command from "#src/procaCommand.mjs";
|
|
6
|
+
|
|
7
|
+
export default class ConfigAdd extends Command {
|
|
8
|
+
static enableJsonFlag = true;
|
|
9
|
+
static aliases = ["config:setup", "config:init"];
|
|
10
|
+
// static deprecateAliases = true;
|
|
11
|
+
|
|
12
|
+
static args = {
|
|
13
|
+
...this.flagify({ multiid: false }),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
static description = "create setting to access to a server";
|
|
17
|
+
|
|
18
|
+
static examples = [
|
|
19
|
+
"<%= config.bin %> <%= command.id %> --user=xavier@example.org --token=API-12345789",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
static flags = {
|
|
23
|
+
// flag with no value (-f, --force)
|
|
24
|
+
...super.globalFlags,
|
|
25
|
+
url: Flags.string({
|
|
26
|
+
description: "url of the proca server api",
|
|
27
|
+
default: "https://api.proca.app/api",
|
|
28
|
+
helpValue: "http://localhost:4000",
|
|
29
|
+
}),
|
|
30
|
+
token: Flags.string({
|
|
31
|
+
description: "user token on proca server",
|
|
32
|
+
helpValue: "API-token>",
|
|
33
|
+
}),
|
|
34
|
+
email: Flags.string({
|
|
35
|
+
description: "user email on proca server",
|
|
36
|
+
helpValue: "you@example.org",
|
|
37
|
+
}),
|
|
38
|
+
folder: Flags.string({
|
|
39
|
+
description: "config folder (in the proca widget generator)",
|
|
40
|
+
helpValue: "/var/www/proca/config.example",
|
|
41
|
+
}),
|
|
42
|
+
// n8n: Flags.string({ description: "api access on the n8n server", helpValue: "<n8n api>", }),
|
|
43
|
+
// supabase: Flags.string({description: "url of the supabase",helpValue: "<url>"}),
|
|
44
|
+
// "supabase-anon-key": Flags.string({ description: "anonymous key", }),
|
|
45
|
+
// "supabase-secrey-key": Flags.string({ description: "secret service key", }),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
generate = (flags) => {
|
|
49
|
+
const mapping = {
|
|
50
|
+
REACT_APP_NAME: "proca",
|
|
51
|
+
REACT_APP_API_URL: flags.url,
|
|
52
|
+
PROCA_TOKEN: flags.token,
|
|
53
|
+
PROCA_CONFIG_FOLDER: flags.folder,
|
|
54
|
+
N8N_TOKEN: flags.n8n,
|
|
55
|
+
REACT_APP_SUPABASE_URL: flags.supabase,
|
|
56
|
+
REACT_APP_SUPABASE_ANON_KEY: flags.supabase_anon_key,
|
|
57
|
+
SUPABASE_SECRET_KEY: flags.supabase_secret_key,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return format(mapping);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
async run() {
|
|
64
|
+
const { args, flags } = await this.parse(this.constructor);
|
|
65
|
+
|
|
66
|
+
const file = getFilename(this.config.configDir, flags.env);
|
|
67
|
+
const userConfig = getConfig(file, true) || {};
|
|
68
|
+
|
|
69
|
+
if (Object.keys(userConfig).length > 0) {
|
|
70
|
+
this.log(`Config file ${file} exists. Using it to pre-fill values.`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!flags.token) {
|
|
74
|
+
const response = await prompts({
|
|
75
|
+
type: "text",
|
|
76
|
+
name: "token",
|
|
77
|
+
message: this.constructor.flags.token.description,
|
|
78
|
+
initial: userConfig.PROCA_TOKEN || "API-",
|
|
79
|
+
});
|
|
80
|
+
flags.token = response.token;
|
|
81
|
+
}
|
|
82
|
+
if (!flags.folder) {
|
|
83
|
+
const response = await prompts({
|
|
84
|
+
type: "text",
|
|
85
|
+
name: "folder",
|
|
86
|
+
message: this.constructor.flags.folder.description,
|
|
87
|
+
initial: userConfig.PROCA_FOLDER,
|
|
88
|
+
});
|
|
89
|
+
flags.folder = response.folder;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!flags.token || !flags.token.startsWith("API-")) {
|
|
93
|
+
return error("Token must start with API-, config file not saved");
|
|
94
|
+
}
|
|
95
|
+
write(file, this.generate(flags));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { Command } from "#src/procaCommand.mjs";
|
|
4
|
+
|
|
5
|
+
export default class FolderConfig extends Command {
|
|
6
|
+
static summary = "Check and create config folders";
|
|
7
|
+
static description =
|
|
8
|
+
"Check if the PROCA_CONFIG_FOLDER is set up, if it is, check if the required subfolders exists and create if not";
|
|
9
|
+
|
|
10
|
+
async run() {
|
|
11
|
+
const configFolder = process.env.PROCA_CONFIG_FOLDER;
|
|
12
|
+
|
|
13
|
+
if (!configFolder) {
|
|
14
|
+
this.error("PROCA_CONFIG_FOLDER environment variable is not set.");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const subfolders = [
|
|
18
|
+
"org",
|
|
19
|
+
"target/source",
|
|
20
|
+
"target/server",
|
|
21
|
+
"target/public",
|
|
22
|
+
"campaign",
|
|
23
|
+
"email/actionpage",
|
|
24
|
+
"email/html",
|
|
25
|
+
"email/mjml",
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
this.log(`Checking config folder at ${configFolder}`);
|
|
29
|
+
|
|
30
|
+
subfolders.forEach((subfolder) => {
|
|
31
|
+
const fullPath = path.join(configFolder, subfolder);
|
|
32
|
+
if (!fs.existsSync(fullPath)) {
|
|
33
|
+
fs.mkdirSync(fullPath, { recursive: true });
|
|
34
|
+
this.log(`🆕 ${fullPath}`);
|
|
35
|
+
} else {
|
|
36
|
+
this.log(`✅ ${fullPath}`);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
this.log("Config folder check complete.");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 ConfigServer extends Command {
|
|
8
|
+
static description = "get the server config";
|
|
9
|
+
|
|
10
|
+
fetch = async () => {
|
|
11
|
+
const Document = gql`
|
|
12
|
+
query {
|
|
13
|
+
application {
|
|
14
|
+
logLevel
|
|
15
|
+
name
|
|
16
|
+
version
|
|
17
|
+
}
|
|
18
|
+
}`;
|
|
19
|
+
const result = await query(Document, {});
|
|
20
|
+
return result.application;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
table = (r) => {
|
|
24
|
+
super.table(r, null, null);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
async run() {
|
|
28
|
+
// const { args, flags } = await this.parse();
|
|
29
|
+
const data = await this.fetch();
|
|
30
|
+
data.url = this.procaConfig.url;
|
|
31
|
+
return this.output(data);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { error, stdout, ux } from "@oclif/core/ux";
|
|
3
|
+
import { get as getConfig, getFilename, load, write } from "#src/config.mjs";
|
|
4
|
+
import Command from "#src/procaCommand.mjs";
|
|
5
|
+
|
|
6
|
+
export default class CampaignList extends Command {
|
|
7
|
+
static enableJsonFlag = true;
|
|
8
|
+
static aliases = ["config:setup"];
|
|
9
|
+
static deprecateAliases = true;
|
|
10
|
+
|
|
11
|
+
static args = {
|
|
12
|
+
key: Args.string({
|
|
13
|
+
description: "variable name",
|
|
14
|
+
multiple: false,
|
|
15
|
+
}),
|
|
16
|
+
value: Args.string({
|
|
17
|
+
description: "value",
|
|
18
|
+
multiple: true,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
static description =
|
|
23
|
+
"update the setting used to authenticate to the servers and services";
|
|
24
|
+
|
|
25
|
+
static examples = [
|
|
26
|
+
"<%= config.bin %> <%= command.id %> --user=xavier@example.org --token=API-12345789",
|
|
27
|
+
"<%= config.bin %> <%= command.id %> VAR1 VALUE",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
static flags = {
|
|
31
|
+
// flag with no value (-f, --force)
|
|
32
|
+
...super.globalFlags,
|
|
33
|
+
environment: Flags.string({
|
|
34
|
+
description: "environment",
|
|
35
|
+
default: "default",
|
|
36
|
+
}),
|
|
37
|
+
url: Flags.string({
|
|
38
|
+
description: "url of the proca server api",
|
|
39
|
+
default: "https://api.proca.app/api",
|
|
40
|
+
helpValue: "<url>",
|
|
41
|
+
}),
|
|
42
|
+
token: Flags.string({
|
|
43
|
+
description: "user token on proca server",
|
|
44
|
+
helpValue: "<API-token>",
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
format = (obj) => {
|
|
49
|
+
const content = ["# generated by proca-api"];
|
|
50
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
51
|
+
if (value) {
|
|
52
|
+
content.push(`${key}='${value.replace(/'/g, "''")}'`);
|
|
53
|
+
} else {
|
|
54
|
+
content.push(`#${key}= `);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return content.join("\n");
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
generate = function () {
|
|
61
|
+
const mapping = {
|
|
62
|
+
...args,
|
|
63
|
+
REACT_APP_NAME: "proca",
|
|
64
|
+
REACT_APP_API_URL: this.flags.url,
|
|
65
|
+
PROCA_TOKEN: this.flags.token,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return this.format(mapping);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
regenerate = function (config, args) {
|
|
72
|
+
config[args.key] = args.value;
|
|
73
|
+
console.log(this.format(config));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
return this.format(config);
|
|
76
|
+
};
|
|
77
|
+
async run() {
|
|
78
|
+
const config = this.config;
|
|
79
|
+
const { args, flags, raw } = await this.parse();
|
|
80
|
+
const rawf = raw.filter((d) => d.type === "flag").map((d) => d.flag);
|
|
81
|
+
|
|
82
|
+
const file = getFilename(this.config.configDir);
|
|
83
|
+
|
|
84
|
+
const userConfig = getConfig(file, true);
|
|
85
|
+
|
|
86
|
+
this.info("config file", file);
|
|
87
|
+
|
|
88
|
+
if (userConfig) {
|
|
89
|
+
if (args.key && args.value) {
|
|
90
|
+
write(file, this.regenerate(userConfig, args));
|
|
91
|
+
} else {
|
|
92
|
+
console.log(userConfig);
|
|
93
|
+
this.error("config file exists already", {
|
|
94
|
+
code: "CONFIG_ERR",
|
|
95
|
+
_ref: "README.md#",
|
|
96
|
+
suggestions: ["add KEY VALUE to update or add new variables"],
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
write(file, this.generate());
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import Command from "#src/procaCommand.mjs";
|
|
2
|
+
import { gql, query } from "#src/urql.mjs";
|
|
3
|
+
|
|
4
|
+
export const getCurrentUser = () => {
|
|
5
|
+
const me = new WhoAmI([]);
|
|
6
|
+
return me.fetch();
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default class WhoAmI extends Command {
|
|
10
|
+
static aliases = ["user:whoami", "user:me"];
|
|
11
|
+
static description =
|
|
12
|
+
"fetch the information about the current user (based on the token)";
|
|
13
|
+
|
|
14
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
15
|
+
|
|
16
|
+
static flags = {
|
|
17
|
+
...super.globalFlags,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
fetch = async () => {
|
|
21
|
+
const Document = gql`
|
|
22
|
+
query {
|
|
23
|
+
currentUser {
|
|
24
|
+
apiToken {
|
|
25
|
+
expiresAt
|
|
26
|
+
}
|
|
27
|
+
email
|
|
28
|
+
id
|
|
29
|
+
isAdmin
|
|
30
|
+
jobTitle
|
|
31
|
+
phone
|
|
32
|
+
pictureUrl
|
|
33
|
+
roles {
|
|
34
|
+
role org {name}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
const result = await query(Document);
|
|
40
|
+
return result.currentUser;
|
|
41
|
+
//return result.users.map (d => {d.config = JSON.parse(d.config); return d});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
simplify = (d) => {
|
|
45
|
+
const result = {
|
|
46
|
+
id: d.id,
|
|
47
|
+
email: d.email,
|
|
48
|
+
};
|
|
49
|
+
if (d.apiToken) {
|
|
50
|
+
result.tokenExpire = d.apiToken.expiresAt;
|
|
51
|
+
}
|
|
52
|
+
if (d.isAdmin) {
|
|
53
|
+
result.admin = true;
|
|
54
|
+
}
|
|
55
|
+
const roles = d.roles.reduce((acc, item) => {
|
|
56
|
+
if (!acc[item.role]) {
|
|
57
|
+
acc[item.role] = [];
|
|
58
|
+
}
|
|
59
|
+
acc[item.role].push(item.org.name);
|
|
60
|
+
return acc;
|
|
61
|
+
}, {});
|
|
62
|
+
for (const role in roles) {
|
|
63
|
+
result[role] = roles[role].join(",");
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
table = (r) => {
|
|
69
|
+
super.table(r, null, null);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
async run() {
|
|
73
|
+
let data = [];
|
|
74
|
+
|
|
75
|
+
data = await this.fetch();
|
|
76
|
+
|
|
77
|
+
return this.output(data);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import Command from "#src/procaCommand.mjs";
|
|
3
|
+
import { gql, query } from "#src/urql.mjs";
|
|
4
|
+
|
|
5
|
+
export default class CounterGet extends Command {
|
|
6
|
+
static description = "counter of supporters";
|
|
7
|
+
|
|
8
|
+
static examples = [
|
|
9
|
+
"<%= config.bin %> <%= command.id %> --name <name of the campaign>",
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
static args = this.multiid();
|
|
13
|
+
static flags = {
|
|
14
|
+
// flag with no value (-f, --force)
|
|
15
|
+
...this.flagify({ multiid: true }),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
fetch = async (params) => {
|
|
19
|
+
const GetCounterDocument = gql`
|
|
20
|
+
query GetCounter($name: String, $id: Int) {
|
|
21
|
+
campaign(name: $name, id: $id) {
|
|
22
|
+
stats {
|
|
23
|
+
supporterCount
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
const result = await query(GetCounterDocument, params);
|
|
29
|
+
return result.campaign.stats;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
table = (r) => {
|
|
33
|
+
super.table(r, null, null);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
async run() {
|
|
37
|
+
const { args, flags } = await this.parse();
|
|
38
|
+
const data = await this.fetch(flags);
|
|
39
|
+
return this.output(data);
|
|
40
|
+
}
|
|
41
|
+
}
|