Skip to content

Commit 5b60631

Browse files
committed
feat(cli): Adding messaging init & deploy
1 parent 36a37b8 commit 5b60631

File tree

4 files changed

+175
-9
lines changed

4 files changed

+175
-9
lines changed

templates/cli/lib/commands/deploy.js.twig

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const JSONbig = require("json-bigint")({ storeAsString: false });
33
const { Command } = require("commander");
44
const { localConfig } = require("../config");
55
const { paginate } = require('../paginate');
6-
const { questionsDeployBuckets, questionsDeployTeams, questionsDeployFunctions, questionsGetEntrypoint, questionsDeployCollections, questionsConfirmDeployCollections } = require("../questions");
6+
const { questionsDeployBuckets, questionsDeployTeams, questionsDeployFunctions, questionsGetEntrypoint, questionsDeployCollections, questionsDeployMessagingTopics, questionsConfirmDeployCollections } = require("../questions");
77
const { actionRunner, success, log, error, commandDescriptions } = require("../parser");
88
const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
99
const {
@@ -32,6 +32,9 @@ const {
3232
const {
3333
storageGetBucket, storageUpdateBucket, storageCreateBucket
3434
} = require("./storage");
35+
const {
36+
messagingGetTopic, messagingUpdateTopic, messagingCreateTopic
37+
} = require("./messaging");
3538
const {
3639
teamsGet,
3740
teamsUpdate,
@@ -353,15 +356,15 @@ const deployFunction = async ({ functionId, all, yes } = {}) => {
353356
functionId: func['$id'],
354357
parseOutput: false
355358
}, 100, 'variables');
356-
359+
357360
await Promise.all(variables.map(async variable => {
358361
await functionsDeleteVariable({
359362
functionId: func['$id'],
360363
variableId: variable['$id'],
361364
parseOutput: false
362365
});
363366
}));
364-
367+
365368
let result = await awaitPools.wipeVariables(func['$id']);
366369
if (!result) {
367370
throw new Error("Variable deletion timed out.");
@@ -907,6 +910,78 @@ const deployTeam = async ({ all, yes } = {}) => {
907910
}
908911
}
909912

913+
const deployMessagingTopic = async ({ all, yes } = {}) => {
914+
let response = {};
915+
916+
let topicsIds = [];
917+
const configTopics = localConfig.getMessagingTopics();
918+
919+
if (all) {
920+
if (configTopics.length === 0) {
921+
throw new Error("No topics found in the current directory. Run `appwrite init topics` to fetch all your messaging topics.");
922+
}
923+
topicsIds.push(...configTopics.map((b) => b.$id));
924+
}
925+
926+
if (topicsIds.length === 0) {
927+
const answers = await inquirer.prompt(questionsDeployMessagingTopics[0])
928+
topicsIds.push(...answers.topics);
929+
}
930+
931+
let topics = [];
932+
933+
for (const topicId of topicsIds) {
934+
const idTopic = configTopics.filter((b) => b.$id === topicId);
935+
topics.push(...idTopic);
936+
}
937+
938+
for (let topic of topics) {
939+
log(`Deploying topic ${topic.name} ( ${topic['$id']} )`)
940+
941+
try {
942+
response = await messagingGetTopic({
943+
topicId: topic['$id'],
944+
parseOutput: false
945+
})
946+
log(`Topic ${topic.name} ( ${topic['$id']} ) already exists.`);
947+
948+
if (!yes) {
949+
const answers = await inquirer.prompt(questionsDeployMessagingTopics[1])
950+
if (answers.override.toLowerCase() !== "yes") {
951+
log(`Received "${answers.override}". Skipping ${topic.name} ( ${topic['$id']} )`);
952+
continue;
953+
}
954+
}
955+
956+
log(`Updating Topic ...`)
957+
958+
await messagingUpdateTopic({
959+
topicId: topic['$id'],
960+
name: topic.name,
961+
subscribe: topic.subscribe,
962+
parseOutput: false
963+
});
964+
965+
success(`Deployed ${topic.name} ( ${topic['$id']} )`);
966+
} catch (e) {
967+
if (e.code == 404) {
968+
log(`Topic ${topic.name} does not exist in the project. Creating ... `);
969+
970+
response = await messagingCreateTopic({
971+
topicId: topic['$id'],
972+
name: topic.name,
973+
subscribe: topic.subscribe,
974+
parseOutput: false
975+
})
976+
977+
success(`Deployed ${topic.name} ( ${topic['$id']} )`);
978+
} else {
979+
throw e;
980+
}
981+
}
982+
}
983+
}
984+
910985
deploy
911986
.command("function")
912987
.description("Deploy functions in the current directory.")
@@ -936,6 +1011,13 @@ deploy
9361011
.option(`--yes`, `Flag to confirm all warnings`)
9371012
.action(actionRunner(deployTeam));
9381013

1014+
deploy
1015+
.command("topic")
1016+
.description("Deploy messaging topics in the current project.")
1017+
.option(`--all`, `Flag to deploy all topics`)
1018+
.option(`--yes`, `Flag to confirm all warnings`)
1019+
.action(actionRunner(deployMessagingTopic));
1020+
9391021
module.exports = {
9401022
deploy
941-
}
1023+
}

templates/cli/lib/commands/init.js.twig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const path = require("path");
33
const childProcess = require('child_process');
44
const { Command } = require("commander");
55
const inquirer = require("inquirer");
6+
const { messagingCreateTopic, messagingListTopics } = require("./messaging");
67
const { teamsCreate, teamsList } = require("./teams");
78
const { projectsCreate } = require("./projects");
89
const { functionsCreate } = require("./functions");
@@ -237,6 +238,19 @@ const initTeam = async () => {
237238
success();
238239
}
239240

241+
const initMessagingTopic = async () => {
242+
const { topics } = await paginate(messagingListTopics, { parseOutput: false }, 100, 'topics');
243+
244+
log(`Found ${topics.length} topics`);
245+
246+
topics.forEach(async topic => {
247+
log(`Fetching ${topic.name} ...`);
248+
localConfig.addMessagingTopic(topic);
249+
});
250+
251+
success();
252+
}
253+
240254
init
241255
.command("project")
242256
.description("Initialise your {{ spec.title|caseUcfirst }} project")
@@ -264,6 +278,11 @@ init
264278
.description("Initialise your Appwrite teams")
265279
.action(actionRunner(initTeam))
266280

281+
init
282+
.command("topic")
283+
.description("Initialise your Appwrite messaging topics")
284+
.action(actionRunner(initMessagingTopic))
285+
267286
module.exports = {
268287
init,
269288
};

templates/cli/lib/config.js.twig

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,45 @@ class Local extends Config {
204204
this.set("buckets", buckets);
205205
}
206206

207+
getMessagingTopics() {
208+
if (!this.has("topics")) {
209+
return [];
210+
}
211+
return this.get("topics");
212+
}
213+
214+
getMessagingTopic($id) {
215+
if (!this.has("topics")) {
216+
return {};
217+
}
218+
219+
let topic = this.get("topics");
220+
for (let i = 0; i < topic.length; i++) {
221+
if (topic[i]['$id'] == $id) {
222+
return topic[i];
223+
}
224+
}
225+
226+
return {};
227+
}
228+
229+
addMessagingTopic(props) {
230+
if (!this.has("topics")) {
231+
this.set("topics", []);
232+
}
233+
234+
let topics = this.get("topics");
235+
for (let i = 0; i < topics.length; i++) {
236+
if (topics[i]['$id'] == props['$id']) {
237+
topics[i] = props;
238+
this.set("topics", topics);
239+
return;
240+
}
241+
}
242+
topics.push(props);
243+
this.set("topics", topics);
244+
}
245+
207246
getDatabases() {
208247
if (!this.has("databases")) {
209248
return [];

templates/cli/lib/questions.js.twig

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,12 @@ const questionsInitFunction = [
209209
parseOutput: false
210210
})
211211
let runtimes = response["runtimes"]
212-
let choices = runtimes.map((runtime, idx) => {
212+
let choices = runtimes.map((runtime, idx) => {
213213
return {
214214
name: `${runtime.name} (${runtime['$id']})`,
215-
value: {
216-
id: runtime['$id'],
217-
entrypoint: getEntrypoint(runtime['$id']),
215+
value: {
216+
id: runtime['$id'],
217+
entrypoint: getEntrypoint(runtime['$id']),
218218
ignore: getIgnores(runtime['$id']),
219219
commands : getInstallCommand(runtime['$id'])
220220
},
@@ -352,6 +352,31 @@ const questionsDeployBuckets = [
352352
},
353353
]
354354

355+
const questionsDeployMessagingTopics = [
356+
{
357+
type: "checkbox",
358+
name: "topics",
359+
message: "Which messaging topic would you like to deploy?",
360+
choices: () => {
361+
let topics = localConfig.getMessagingTopics();
362+
if (topics.length === 0) {
363+
throw new Error("No topics found in the current directory. Run `appwrite init messaging` to fetch all your messaging topics.");
364+
}
365+
return topics.map(topic => {
366+
return {
367+
name: `${topic.name} (${topic['$id']})`,
368+
value: topic.$id
369+
}
370+
});
371+
}
372+
},
373+
{
374+
type: "input",
375+
name: "override",
376+
message: 'Are you sure you want to override this topic? This can lead to loss of data! Type "YES" to confirm.'
377+
}
378+
]
379+
355380
const questionsGetEntrypoint = [
356381
{
357382
type: "input",
@@ -403,7 +428,7 @@ const questionsListFactors = [
403428
sdk: client,
404429
parseOutput: false
405430
});
406-
431+
407432
const choices = [
408433
{
409434
name: `TOTP (Time-based One-time Password)`,
@@ -450,6 +475,7 @@ module.exports = {
450475
questionsDeployFunctions,
451476
questionsDeployCollections,
452477
questionsDeployBuckets,
478+
questionsDeployMessagingTopics,
453479
questionsDeployTeams,
454480
questionsGetEntrypoint,
455481
questionsListFactors,

0 commit comments

Comments
 (0)