Skip to content

Commit b54147d

Browse files
Merge pull request #839 from appwrite/feat-adding-messaging
feat(cli): Adding messaging push and pull
2 parents 3cee4c1 + 9515981 commit b54147d

File tree

4 files changed

+215
-9
lines changed

4 files changed

+215
-9
lines changed

templates/cli/lib/commands/pull.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 pullTeam = async () => {
237238
success();
238239
}
239240

241+
const pullMessagingTopic = 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(`Pulling ${topic.name} ...`);
248+
localConfig.addMessagingTopic(topic);
249+
});
250+
251+
success();
252+
}
253+
240254
pull
241255
.command("project")
242256
.description("Pulling your {{ spec.title|caseUcfirst }} project")
@@ -264,6 +278,11 @@ pull
264278
.description("Pulling your Appwrite teams")
265279
.action(actionRunner(pullTeam))
266280

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

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

Lines changed: 115 additions & 9 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 { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionsConfirmPushCollections } = require("../questions");
6+
const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionsConfirmPushCollections, questionsPushMessagingTopics } = 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,
@@ -227,14 +230,27 @@ const awaitPools = {
227230
},
228231
}
229232

230-
const push = new Command("push")
231-
.description(commandDescriptions['push'])
232-
.configureHelp({
233-
helpWidth: process.stdout.columns || 80
234-
})
235-
.action(actionRunner(async (_options, command) => {
236-
command.help()
237-
}));
233+
const pushResources = async ({ all, yes } = {}) => {
234+
const actions = {
235+
functions: pushFunction,
236+
collections: pushCollection,
237+
buckets: pushBucket,
238+
teams: pushTeam,
239+
messages: pushMessagingTopic
240+
}
241+
242+
if (all) {
243+
Object.values(actions).forEach(action => action({ all: true, yes }));
244+
} else {
245+
const answers = await inquirer.prompt(questionsPushResources[0]);
246+
answers.resources.forEach((resource) => {
247+
const action = actions[resource];
248+
if (action !== undefined) {
249+
action({ all: true, yes });
250+
}
251+
})
252+
}
253+
};
238254

239255
const pushFunction = async ({ functionId, all, yes } = {}) => {
240256
let response = {};
@@ -907,6 +923,89 @@ const pushTeam = async ({ all, yes } = {}) => {
907923
}
908924
}
909925

926+
const pushMessagingTopic = async ({ all, yes } = {}) => {
927+
let response = {};
928+
929+
let topicsIds = [];
930+
const configTopics = localConfig.getMessagingTopics();
931+
let overrideExisting = yes;
932+
933+
if (all) {
934+
if (configTopics.length === 0) {
935+
throw new Error("No topics found in the current directory. Run `appwrite pull topics` to pull all your messaging topics.");
936+
}
937+
topicsIds.push(...configTopics.map((b) => b.$id));
938+
}
939+
940+
if (topicsIds.length === 0) {
941+
const answers = await inquirer.prompt(questionsPushMessagingTopics[0])
942+
topicsIds.push(...answers.topics);
943+
}
944+
945+
let topics = [];
946+
947+
for (const topicId of topicsIds) {
948+
const idTopic = configTopics.filter((b) => b.$id === topicId);
949+
topics.push(...idTopic);
950+
}
951+
952+
if (!yes) {
953+
const answers = await inquirer.prompt(questionsPushMessagingTopics[1])
954+
if (answers.override.toLowerCase() === "yes") {
955+
overrideExisting = true;
956+
}
957+
}
958+
959+
for (let topic of topics) {
960+
log(`Pushing topic ${topic.name} ( ${topic['$id']} )`)
961+
962+
try {
963+
response = await messagingGetTopic({
964+
topicId: topic['$id'],
965+
parseOutput: false
966+
})
967+
log(`Topic ${topic.name} ( ${topic['$id']} ) already exists.`);
968+
969+
if (!overrideExisting) {
970+
log(`Skipping ${topic.name} ( ${topic['$id']} )`);
971+
continue;
972+
}
973+
974+
log(`Updating Topic ...`)
975+
976+
await messagingUpdateTopic({
977+
topicId: topic['$id'],
978+
name: topic.name,
979+
subscribe: topic.subscribe,
980+
parseOutput: false
981+
});
982+
983+
success(`Pushed ${topic.name} ( ${topic['$id']} )`);
984+
} catch (e) {
985+
if (e.code == 404) {
986+
log(`Topic ${topic.name} does not exist in the project. Creating ... `);
987+
988+
response = await messagingCreateTopic({
989+
topicId: topic['$id'],
990+
name: topic.name,
991+
subscribe: topic.subscribe,
992+
parseOutput: false
993+
})
994+
995+
success(`Created ${topic.name} ( ${topic['$id']} )`);
996+
} else {
997+
throw e;
998+
}
999+
}
1000+
}
1001+
}
1002+
1003+
const push = new Command("push")
1004+
.description(commandDescriptions['push'])
1005+
.option(`--all`, `Flag to push all resources`)
1006+
.option(`--yes`, `Flag to confirm all warnings`)
1007+
.action(actionRunner(pushResources));
1008+
9101009
push
9111010
.command("function")
9121011
.description("Push functions in the current directory.")
@@ -936,6 +1035,13 @@ push
9361035
.option(`--yes`, `Flag to confirm all warnings`)
9371036
.action(actionRunner(pushTeam));
9381037

1038+
push
1039+
.command("topic")
1040+
.description("Push messaging topics in the current project.")
1041+
.option(`--all`, `Flag to deploy all topics`)
1042+
.option(`--yes`, `Flag to confirm all warnings`)
1043+
.action(actionRunner(pushMessagingTopic));
1044+
9391045
module.exports = {
9401046
push
9411047
}

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: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,21 @@ const questionsLogin = [
305305
},
306306
];
307307

308+
const questionsPushResources = [
309+
{
310+
type: "checkbox",
311+
name: "resources",
312+
message: "Which resources would you like to push?",
313+
choices: [
314+
{ name: 'Functions', value: 'functions' },
315+
{ name: 'Collections', value: 'collections' },
316+
{ name: 'Buckets', value: 'buckets' },
317+
{ name: 'Teams', value: 'teams' },
318+
{ name: 'Topics', value: 'messages' }
319+
]
320+
}
321+
]
322+
308323
const questionsPushFunctions = [
309324
{
310325
type: "checkbox",
@@ -384,6 +399,31 @@ const questionsPushBuckets = [
384399
},
385400
]
386401

402+
const questionsPushMessagingTopics = [
403+
{
404+
type: "checkbox",
405+
name: "topics",
406+
message: "Which messaging topic would you like to push?",
407+
choices: () => {
408+
let topics = localConfig.getMessagingTopics();
409+
if (topics.length === 0) {
410+
throw new Error("No topics found in the current directory. Run `appwrite pull messaging` to fetch all your messaging topics.");
411+
}
412+
return topics.map(topic => {
413+
return {
414+
name: `${topic.name} (${topic['$id']})`,
415+
value: topic.$id
416+
}
417+
});
418+
}
419+
},
420+
{
421+
type: "input",
422+
name: "override",
423+
message: 'Would you like to override existing topics? This can lead to loss of data! Type "YES" to confirm.'
424+
}
425+
]
426+
387427
const questionsGetEntrypoint = [
388428
{
389429
type: "input",
@@ -480,9 +520,11 @@ module.exports = {
480520
questionsLogin,
481521
questionsPullFunction,
482522
questionsPullCollection,
523+
questionsPushResources,
483524
questionsPushFunctions,
484525
questionsPushCollections,
485526
questionsPushBuckets,
527+
questionsPushMessagingTopics,
486528
questionsPushTeams,
487529
questionsGetEntrypoint,
488530
questionsListFactors,

0 commit comments

Comments
 (0)