appwrite-cli 6.0.0-rc.1 → 6.0.0-rc.2
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 +2 -2
- package/index.js +2 -1
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.js +2 -2
- package/lib/commands/generic.js +17 -5
- package/lib/commands/init.js +26 -15
- package/lib/commands/pull.js +126 -64
- package/lib/commands/push.js +64 -141
- package/lib/commands/run.js +32 -40
- package/lib/config.js +52 -20
- package/lib/emulation/docker.js +64 -36
- package/lib/emulation/utils.js +8 -3
- package/lib/parser.js +16 -6
- package/lib/questions.js +47 -21
- package/lib/sdks.js +0 -38
- package/package.json +1 -1
- package/scoop/appwrite.json +3 -3
package/lib/commands/push.js
CHANGED
|
@@ -6,7 +6,7 @@ const { localConfig, globalConfig } = require("../config");
|
|
|
6
6
|
const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
|
|
7
7
|
const { paginate } = require('../paginate');
|
|
8
8
|
const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionsConfirmPushCollections, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
|
|
9
|
-
const { cliConfig, actionRunner, success, log, error, commandDescriptions, drawTable } = require("../parser");
|
|
9
|
+
const { cliConfig, actionRunner, success, warn, log, error, commandDescriptions, drawTable } = require("../parser");
|
|
10
10
|
const { proxyListRules } = require('./proxy');
|
|
11
11
|
const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment, functionsGetDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
|
|
12
12
|
const {
|
|
@@ -714,7 +714,7 @@ const createAttributes = async (attributes, collection) => {
|
|
|
714
714
|
|
|
715
715
|
const pushResources = async () => {
|
|
716
716
|
const actions = {
|
|
717
|
-
|
|
717
|
+
settings: pushSettings,
|
|
718
718
|
functions: pushFunction,
|
|
719
719
|
collections: pushCollection,
|
|
720
720
|
buckets: pushBucket,
|
|
@@ -736,15 +736,16 @@ const pushResources = async () => {
|
|
|
736
736
|
}
|
|
737
737
|
};
|
|
738
738
|
|
|
739
|
-
const
|
|
739
|
+
const pushSettings = async () => {
|
|
740
740
|
try {
|
|
741
|
+
log("Pushing project settings ...");
|
|
742
|
+
|
|
741
743
|
const projectId = localConfig.getProject().projectId;
|
|
742
744
|
const projectName = localConfig.getProject().projectName;
|
|
743
745
|
const settings = localConfig.getProject().projectSettings ?? {};
|
|
744
746
|
|
|
745
|
-
log(`Updating project ${projectId}`);
|
|
746
|
-
|
|
747
747
|
if (projectName) {
|
|
748
|
+
log("Applying project name ...");
|
|
748
749
|
await projectsUpdate({
|
|
749
750
|
projectId,
|
|
750
751
|
name: projectName,
|
|
@@ -753,7 +754,7 @@ const pushProject = async () => {
|
|
|
753
754
|
}
|
|
754
755
|
|
|
755
756
|
if (settings.services) {
|
|
756
|
-
log(
|
|
757
|
+
log("Applying service statuses ...");
|
|
757
758
|
for (let [service, status] of Object.entries(settings.services)) {
|
|
758
759
|
await projectsUpdateServiceStatus({
|
|
759
760
|
projectId,
|
|
@@ -766,7 +767,7 @@ const pushProject = async () => {
|
|
|
766
767
|
|
|
767
768
|
if (settings.auth) {
|
|
768
769
|
if (settings.auth.security) {
|
|
769
|
-
log(
|
|
770
|
+
log("Applying auth security settings ...");
|
|
770
771
|
await projectsUpdateAuthDuration({ projectId, duration: settings.auth.security.duration, parseOutput: false });
|
|
771
772
|
await projectsUpdateAuthLimit({ projectId, limit: settings.auth.security.limit, parseOutput: false });
|
|
772
773
|
await projectsUpdateAuthSessionsLimit({ projectId, limit: settings.auth.security.sessionsLimit, parseOutput: false });
|
|
@@ -776,7 +777,7 @@ const pushProject = async () => {
|
|
|
776
777
|
}
|
|
777
778
|
|
|
778
779
|
if (settings.auth.methods) {
|
|
779
|
-
log(
|
|
780
|
+
log("Applying auth methods statuses ...");
|
|
780
781
|
|
|
781
782
|
for (let [method, status] of Object.entries(settings.auth.methods)) {
|
|
782
783
|
await projectsUpdateAuthStatus({
|
|
@@ -789,7 +790,7 @@ const pushProject = async () => {
|
|
|
789
790
|
}
|
|
790
791
|
}
|
|
791
792
|
|
|
792
|
-
success(
|
|
793
|
+
success(`Successfully pushed ${chalk.bold('all')} project settings.`);
|
|
793
794
|
} catch (e) {
|
|
794
795
|
throw e;
|
|
795
796
|
}
|
|
@@ -806,11 +807,9 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
|
|
|
806
807
|
checkDeployConditions(localConfig);
|
|
807
808
|
const functions = localConfig.getFunctions();
|
|
808
809
|
if (functions.length === 0) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
}
|
|
813
|
-
throw new Error("No functions found in the current directory. Use 'appwrite pull functions' to synchronize existing one, or use 'appwrite init function' to create a new one.");
|
|
810
|
+
log("No functions found.");
|
|
811
|
+
hint("Use 'appwrite pull functions' to synchronize existing one, or use 'appwrite init function' to create a new one.");
|
|
812
|
+
return;
|
|
814
813
|
}
|
|
815
814
|
functionIds.push(...functions.map((func) => {
|
|
816
815
|
return func.$id;
|
|
@@ -833,45 +832,19 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
|
|
|
833
832
|
return func;
|
|
834
833
|
});
|
|
835
834
|
|
|
836
|
-
log('Validating functions');
|
|
835
|
+
log('Validating functions ...');
|
|
837
836
|
// Validation is done BEFORE pushing so the deployment process can be run in async with progress update
|
|
838
837
|
for (let func of functions) {
|
|
839
838
|
|
|
840
839
|
if (!func.entrypoint) {
|
|
841
|
-
log(`Function ${func.name}
|
|
840
|
+
log(`Function ${func.name} is missing an entrypoint.`);
|
|
842
841
|
const answers = await inquirer.prompt(questionsGetEntrypoint)
|
|
843
842
|
func.entrypoint = answers.entrypoint;
|
|
844
|
-
localConfig.
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
if (func.variables) {
|
|
848
|
-
func.pushVariables = cliConfig.force;
|
|
849
|
-
|
|
850
|
-
try {
|
|
851
|
-
const { total } = await functionsListVariables({
|
|
852
|
-
functionId: func['$id'],
|
|
853
|
-
queries: [JSON.stringify({ method: 'limit', values: [1] })],
|
|
854
|
-
parseOutput: false
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
if (total === 0) {
|
|
858
|
-
func.pushVariables = true;
|
|
859
|
-
} else if (total > 0 && !func.pushVariables) {
|
|
860
|
-
log(`The function ${func.name} has remote variables setup`);
|
|
861
|
-
const variableAnswers = await inquirer.prompt(questionsPushFunctions[1])
|
|
862
|
-
func.pushVariables = variableAnswers.override.toLowerCase() === "yes";
|
|
863
|
-
}
|
|
864
|
-
} catch (e) {
|
|
865
|
-
if (e.code != 404) {
|
|
866
|
-
throw e.message;
|
|
867
|
-
}
|
|
868
|
-
}
|
|
843
|
+
localConfig.addFunction(func);
|
|
869
844
|
}
|
|
870
845
|
}
|
|
871
846
|
|
|
872
|
-
|
|
873
|
-
log('All functions are validated');
|
|
874
|
-
log('Pushing functions\n');
|
|
847
|
+
log('Pushing functions ...');
|
|
875
848
|
|
|
876
849
|
Spinner.start(false);
|
|
877
850
|
let successfullyPushed = 0;
|
|
@@ -934,7 +907,7 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
|
|
|
934
907
|
|
|
935
908
|
try {
|
|
936
909
|
response = await functionsCreate({
|
|
937
|
-
functionId: func.$id
|
|
910
|
+
functionId: func.$id,
|
|
938
911
|
name: func.name,
|
|
939
912
|
runtime: func.runtime,
|
|
940
913
|
execute: func.execute,
|
|
@@ -949,10 +922,6 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
|
|
|
949
922
|
parseOutput: false
|
|
950
923
|
});
|
|
951
924
|
|
|
952
|
-
localConfig.updateFunction(func['$id'], {
|
|
953
|
-
"$id": response['$id'],
|
|
954
|
-
});
|
|
955
|
-
func["$id"] = response['$id'];
|
|
956
925
|
updaterRow.update({ status: 'Created' });
|
|
957
926
|
} catch (e) {
|
|
958
927
|
updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
|
|
@@ -960,43 +929,6 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
|
|
|
960
929
|
}
|
|
961
930
|
}
|
|
962
931
|
|
|
963
|
-
if (func.variables) {
|
|
964
|
-
if (!func.pushVariables) {
|
|
965
|
-
updaterRow.update({ end: 'Skipping variables' });
|
|
966
|
-
} else {
|
|
967
|
-
updaterRow.update({ end: 'Pushing variables' });
|
|
968
|
-
|
|
969
|
-
const { variables } = await paginate(functionsListVariables, {
|
|
970
|
-
functionId: func['$id'],
|
|
971
|
-
parseOutput: false
|
|
972
|
-
}, 100, 'variables');
|
|
973
|
-
|
|
974
|
-
await Promise.all(variables.map(async variable => {
|
|
975
|
-
await functionsDeleteVariable({
|
|
976
|
-
functionId: func['$id'],
|
|
977
|
-
variableId: variable['$id'],
|
|
978
|
-
parseOutput: false
|
|
979
|
-
});
|
|
980
|
-
}));
|
|
981
|
-
|
|
982
|
-
let result = await awaitPools.wipeVariables(func['$id']);
|
|
983
|
-
if (!result) {
|
|
984
|
-
updaterRow.fail({ errorMessage: 'Variable deletion timed out' })
|
|
985
|
-
return;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
// Push local variables
|
|
989
|
-
await Promise.all(Object.keys(func.variables).map(async localVariableKey => {
|
|
990
|
-
await functionsCreateVariable({
|
|
991
|
-
functionId: func['$id'],
|
|
992
|
-
key: localVariableKey,
|
|
993
|
-
value: func.variables[localVariableKey],
|
|
994
|
-
parseOutput: false
|
|
995
|
-
});
|
|
996
|
-
}));
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
932
|
try {
|
|
1001
933
|
updaterRow.update({ status: 'Pushing' }).replaceSpinner(SPINNER_ARC);
|
|
1002
934
|
response = await functionsCreateDeployment({
|
|
@@ -1082,27 +1014,25 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
|
|
|
1082
1014
|
}));
|
|
1083
1015
|
|
|
1084
1016
|
Spinner.stop();
|
|
1085
|
-
console.log('\n');
|
|
1086
1017
|
|
|
1087
1018
|
failedDeployments.forEach((failed) => {
|
|
1088
1019
|
const { name, deployment, $id } = failed;
|
|
1089
1020
|
const failUrl = `${globalConfig.getEndpoint().replace('/v1', '')}/console/project-${localConfig.getProject().projectId}/functions/function-${$id}/deployment-${deployment}`;
|
|
1090
1021
|
|
|
1091
1022
|
error(`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`);
|
|
1092
|
-
})
|
|
1093
|
-
|
|
1094
|
-
let message = chalk.green(`Pushed and deployed ${successfullyPushed} functions`);
|
|
1023
|
+
});
|
|
1095
1024
|
|
|
1096
1025
|
if (!async) {
|
|
1097
|
-
if
|
|
1098
|
-
|
|
1026
|
+
if(successfullyPushed === 0) {
|
|
1027
|
+
error('No functions were pushed.');
|
|
1028
|
+
} else if(successfullyDeployed != successfullyPushed) {
|
|
1029
|
+
warn(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} functions`)
|
|
1099
1030
|
} else {
|
|
1100
|
-
|
|
1101
|
-
message = chalk.red(`Error pushing ${functions.length} functions`)
|
|
1102
|
-
}
|
|
1031
|
+
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
1103
1032
|
}
|
|
1033
|
+
} else {
|
|
1034
|
+
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
1104
1035
|
}
|
|
1105
|
-
log(message);
|
|
1106
1036
|
}
|
|
1107
1037
|
|
|
1108
1038
|
const pushCollection = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
@@ -1111,12 +1041,9 @@ const pushCollection = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1111
1041
|
if (cliConfig.all) {
|
|
1112
1042
|
checkDeployConditions(localConfig);
|
|
1113
1043
|
if (localConfig.getCollections().length === 0) {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
throw new Error("No collections found in the current directory. Use 'appwrite pull collections' to synchronize existing one, or use 'appwrite init collection' to create a new one.");
|
|
1044
|
+
log("No collections found.");
|
|
1045
|
+
hint("Use 'appwrite pull collections' to synchronize existing one, or use 'appwrite init collection' to create a new one.");
|
|
1046
|
+
return;
|
|
1120
1047
|
}
|
|
1121
1048
|
collections.push(...localConfig.getCollections());
|
|
1122
1049
|
} else {
|
|
@@ -1131,7 +1058,8 @@ const pushCollection = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1131
1058
|
})
|
|
1132
1059
|
}
|
|
1133
1060
|
const databases = Array.from(new Set(collections.map(collection => collection['databaseId'])));
|
|
1134
|
-
|
|
1061
|
+
|
|
1062
|
+
log('Checking for changes ...');
|
|
1135
1063
|
|
|
1136
1064
|
// Parallel db actions
|
|
1137
1065
|
await Promise.all(databases.map(async (databaseId) => {
|
|
@@ -1153,7 +1081,7 @@ const pushCollection = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1153
1081
|
success(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
|
|
1154
1082
|
}
|
|
1155
1083
|
} catch (err) {
|
|
1156
|
-
log(`Database ${databaseId} not found. Creating it now...`);
|
|
1084
|
+
log(`Database ${databaseId} not found. Creating it now ...`);
|
|
1157
1085
|
|
|
1158
1086
|
await databasesCreate({
|
|
1159
1087
|
databaseId: databaseId,
|
|
@@ -1243,11 +1171,9 @@ const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1243
1171
|
if (cliConfig.all) {
|
|
1244
1172
|
checkDeployConditions(localConfig);
|
|
1245
1173
|
if (configBuckets.length === 0) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
}
|
|
1250
|
-
throw new Error("No buckets found in the current directory. Use 'appwrite pull buckets' to synchronize existing one, or use 'appwrite init bucket' to create a new one.");
|
|
1174
|
+
log("No buckets found.");
|
|
1175
|
+
hint("Use 'appwrite pull buckets' to synchronize existing one, or use 'appwrite init bucket' to create a new one.");
|
|
1176
|
+
return;
|
|
1251
1177
|
}
|
|
1252
1178
|
bucketIds.push(...configBuckets.map((b) => b.$id));
|
|
1253
1179
|
}
|
|
@@ -1264,8 +1190,10 @@ const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1264
1190
|
buckets.push(...idBuckets);
|
|
1265
1191
|
}
|
|
1266
1192
|
|
|
1193
|
+
log('Pushing buckets ...');
|
|
1194
|
+
|
|
1267
1195
|
for (let bucket of buckets) {
|
|
1268
|
-
log(`Pushing bucket ${
|
|
1196
|
+
log(`Pushing bucket ${chalk.bold(bucket['name'])} ...`);
|
|
1269
1197
|
|
|
1270
1198
|
try {
|
|
1271
1199
|
response = await storageGetBucket({
|
|
@@ -1273,8 +1201,6 @@ const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1273
1201
|
parseOutput: false,
|
|
1274
1202
|
})
|
|
1275
1203
|
|
|
1276
|
-
log(`Updating bucket ...`)
|
|
1277
|
-
|
|
1278
1204
|
await storageUpdateBucket({
|
|
1279
1205
|
bucketId: bucket['$id'],
|
|
1280
1206
|
name: bucket.name,
|
|
@@ -1288,8 +1214,6 @@ const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1288
1214
|
compression: bucket.compression,
|
|
1289
1215
|
parseOutput: false
|
|
1290
1216
|
});
|
|
1291
|
-
|
|
1292
|
-
success(`Pushed ${bucket.name} ( ${bucket['$id']} )`);
|
|
1293
1217
|
} catch (e) {
|
|
1294
1218
|
if (Number(e.code) === 404) {
|
|
1295
1219
|
log(`Bucket ${bucket.name} does not exist in the project. Creating ... `);
|
|
@@ -1307,13 +1231,13 @@ const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1307
1231
|
antivirus: bucket.antivirus,
|
|
1308
1232
|
parseOutput: false
|
|
1309
1233
|
})
|
|
1310
|
-
|
|
1311
|
-
success(`Pushed ${bucket.name} ( ${bucket['$id']} )`);
|
|
1312
1234
|
} else {
|
|
1313
1235
|
throw e;
|
|
1314
1236
|
}
|
|
1315
1237
|
}
|
|
1316
1238
|
}
|
|
1239
|
+
|
|
1240
|
+
success(`Successfully pushed ${buckets.length} buckets.`);
|
|
1317
1241
|
}
|
|
1318
1242
|
|
|
1319
1243
|
const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
@@ -1325,11 +1249,8 @@ const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1325
1249
|
if (cliConfig.all) {
|
|
1326
1250
|
checkDeployConditions(localConfig);
|
|
1327
1251
|
if (configTeams.length === 0) {
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
return;
|
|
1331
|
-
}
|
|
1332
|
-
throw new Error("No teams found in the current directory. Use 'appwrite pull teams' to synchronize existing one, or use 'appwrite init team' to create a new one.");
|
|
1252
|
+
log("No teams found.");
|
|
1253
|
+
hint("Use 'appwrite pull teams' to synchronize existing one, or use 'appwrite init team' to create a new one.");
|
|
1333
1254
|
}
|
|
1334
1255
|
teamIds.push(...configTeams.map((t) => t.$id));
|
|
1335
1256
|
}
|
|
@@ -1346,8 +1267,10 @@ const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1346
1267
|
teams.push(...idTeams);
|
|
1347
1268
|
}
|
|
1348
1269
|
|
|
1270
|
+
log('Pushing teams ...');
|
|
1271
|
+
|
|
1349
1272
|
for (let team of teams) {
|
|
1350
|
-
log(`Pushing team ${
|
|
1273
|
+
log(`Pushing team ${chalk.bold(team['name'])} ...`);
|
|
1351
1274
|
|
|
1352
1275
|
try {
|
|
1353
1276
|
response = await teamsGet({
|
|
@@ -1355,15 +1278,11 @@ const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1355
1278
|
parseOutput: false,
|
|
1356
1279
|
})
|
|
1357
1280
|
|
|
1358
|
-
log(`Updating team ...`)
|
|
1359
|
-
|
|
1360
1281
|
await teamsUpdateName({
|
|
1361
1282
|
teamId: team['$id'],
|
|
1362
1283
|
name: team.name,
|
|
1363
1284
|
parseOutput: false
|
|
1364
1285
|
});
|
|
1365
|
-
|
|
1366
|
-
success(`Pushed ${team.name} ( ${team['$id']} )`);
|
|
1367
1286
|
} catch (e) {
|
|
1368
1287
|
if (Number(e.code) === 404) {
|
|
1369
1288
|
log(`Team ${team.name} does not exist in the project. Creating ... `);
|
|
@@ -1373,13 +1292,13 @@ const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
|
1373
1292
|
name: team.name,
|
|
1374
1293
|
parseOutput: false
|
|
1375
1294
|
})
|
|
1376
|
-
|
|
1377
|
-
success(`Pushed ${team.name} ( ${team['$id']} )`);
|
|
1378
1295
|
} else {
|
|
1379
1296
|
throw e;
|
|
1380
1297
|
}
|
|
1381
1298
|
}
|
|
1382
1299
|
}
|
|
1300
|
+
|
|
1301
|
+
success(`Successfully pushed ${teams.length} teams.`);
|
|
1383
1302
|
}
|
|
1384
1303
|
|
|
1385
1304
|
const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
@@ -1392,11 +1311,8 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1392
1311
|
if (cliConfig.all) {
|
|
1393
1312
|
checkDeployConditions(localConfig);
|
|
1394
1313
|
if (configTopics.length === 0) {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
return;
|
|
1398
|
-
}
|
|
1399
|
-
throw new Error("No topics found in the current directory. Use 'appwrite pull topics' to synchronize existing one, or use 'appwrite init topic' to create a new one.");
|
|
1314
|
+
log("No topics found.");
|
|
1315
|
+
hint("Use 'appwrite pull topics' to synchronize existing one, or use 'appwrite init topic' to create a new one.");
|
|
1400
1316
|
}
|
|
1401
1317
|
topicsIds.push(...configTopics.map((b) => b.$id));
|
|
1402
1318
|
}
|
|
@@ -1420,8 +1336,10 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1420
1336
|
}
|
|
1421
1337
|
}
|
|
1422
1338
|
|
|
1339
|
+
log('Pushing topics ...');
|
|
1340
|
+
|
|
1423
1341
|
for (let topic of topics) {
|
|
1424
|
-
log(`Pushing topic ${
|
|
1342
|
+
log(`Pushing topic ${chalk.bold(topic['name'])} ...`);
|
|
1425
1343
|
|
|
1426
1344
|
try {
|
|
1427
1345
|
response = await messagingGetTopic({
|
|
@@ -1435,16 +1353,12 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1435
1353
|
continue;
|
|
1436
1354
|
}
|
|
1437
1355
|
|
|
1438
|
-
log(`Updating Topic ...`)
|
|
1439
|
-
|
|
1440
1356
|
await messagingUpdateTopic({
|
|
1441
1357
|
topicId: topic['$id'],
|
|
1442
1358
|
name: topic.name,
|
|
1443
1359
|
subscribe: topic.subscribe,
|
|
1444
1360
|
parseOutput: false
|
|
1445
1361
|
});
|
|
1446
|
-
|
|
1447
|
-
success(`Pushed ${topic.name} ( ${topic['$id']} )`);
|
|
1448
1362
|
} catch (e) {
|
|
1449
1363
|
if (Number(e.code) === 404) {
|
|
1450
1364
|
log(`Topic ${topic.name} does not exist in the project. Creating ... `);
|
|
@@ -1462,6 +1376,8 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1462
1376
|
}
|
|
1463
1377
|
}
|
|
1464
1378
|
}
|
|
1379
|
+
|
|
1380
|
+
success(`Successfully pushed ${topics.length} topics.`);
|
|
1465
1381
|
}
|
|
1466
1382
|
|
|
1467
1383
|
const push = new Command("push")
|
|
@@ -1477,9 +1393,9 @@ push
|
|
|
1477
1393
|
}));
|
|
1478
1394
|
|
|
1479
1395
|
push
|
|
1480
|
-
.command("
|
|
1396
|
+
.command("settings")
|
|
1481
1397
|
.description("Push project name, services and auth settings")
|
|
1482
|
-
.action(actionRunner(
|
|
1398
|
+
.action(actionRunner(pushSettings));
|
|
1483
1399
|
|
|
1484
1400
|
push
|
|
1485
1401
|
.command("function")
|
|
@@ -1513,6 +1429,13 @@ push
|
|
|
1513
1429
|
.description("Push messaging topics in the current project.")
|
|
1514
1430
|
.action(actionRunner(pushMessagingTopic));
|
|
1515
1431
|
|
|
1432
|
+
const deploy = new Command("deploy")
|
|
1433
|
+
.description(commandDescriptions['push'])
|
|
1434
|
+
.action(actionRunner(async () => {
|
|
1435
|
+
warn("Did you mean to run 'appwrite push' command?");
|
|
1436
|
+
}));
|
|
1437
|
+
|
|
1516
1438
|
module.exports = {
|
|
1517
|
-
push
|
|
1439
|
+
push,
|
|
1440
|
+
deploy
|
|
1518
1441
|
}
|
package/lib/commands/run.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
const Tail = require('tail').Tail;
|
|
2
|
-
const
|
|
2
|
+
const chalk = require('chalk');
|
|
3
3
|
const ignore = require("ignore");
|
|
4
4
|
const tar = require("tar");
|
|
5
5
|
const fs = require("fs");
|
|
6
|
-
const ID = require("../id");
|
|
7
|
-
const childProcess = require('child_process');
|
|
8
6
|
const chokidar = require('chokidar');
|
|
9
7
|
const inquirer = require("inquirer");
|
|
10
8
|
const path = require("path");
|
|
@@ -12,13 +10,11 @@ const { Command } = require("commander");
|
|
|
12
10
|
const { localConfig, globalConfig } = require("../config");
|
|
13
11
|
const { paginate } = require('../paginate');
|
|
14
12
|
const { functionsListVariables } = require('./functions');
|
|
15
|
-
const { usersGet, usersCreateJWT } = require('./users');
|
|
16
|
-
const { projectsCreateJWT } = require('./projects');
|
|
17
13
|
const { questionsRunFunctions } = require("../questions");
|
|
18
|
-
const { actionRunner, success, log, error, commandDescriptions, drawTable } = require("../parser");
|
|
14
|
+
const { actionRunner, success, log, warn, error, hint, commandDescriptions, drawTable } = require("../parser");
|
|
19
15
|
const { systemHasCommand, isPortTaken, getAllFiles } = require('../utils');
|
|
20
|
-
const {
|
|
21
|
-
const { dockerStop, dockerCleanup, dockerStart, dockerBuild, dockerPull
|
|
16
|
+
const { runtimeNames, systemTools, JwtManager, Queue } = require('../emulation/utils');
|
|
17
|
+
const { dockerStop, dockerCleanup, dockerStart, dockerBuild, dockerPull } = require('../emulation/docker');
|
|
22
18
|
|
|
23
19
|
const runFunction = async ({ port, functionId, noVariables, noReload, userId } = {}) => {
|
|
24
20
|
// Selection
|
|
@@ -68,7 +64,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
if(!portFound) {
|
|
71
|
-
error(
|
|
67
|
+
error("Could not find an available port. Please select a port with 'appwrite run --port YOUR_PORT' command.");
|
|
72
68
|
return;
|
|
73
69
|
}
|
|
74
70
|
}
|
|
@@ -86,9 +82,9 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
86
82
|
commands: func.commands,
|
|
87
83
|
};
|
|
88
84
|
|
|
89
|
-
log("Local function configuration:");
|
|
90
85
|
drawTable([settings]);
|
|
91
|
-
log(
|
|
86
|
+
log("If you wish to change your local settings, update the appwrite.json file and rerun the 'appwrite run' command.");
|
|
87
|
+
hint("Permissions, events, CRON and timeouts dont apply when running locally.");
|
|
92
88
|
|
|
93
89
|
await dockerCleanup();
|
|
94
90
|
|
|
@@ -116,22 +112,17 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
116
112
|
|
|
117
113
|
const variables = {};
|
|
118
114
|
if(!noVariables) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
131
|
-
} catch(err) {
|
|
132
|
-
log("Could not fetch remote variables: " + err.message);
|
|
133
|
-
log("Function will run locally, but will not have your function's environment variables set.");
|
|
134
|
-
}
|
|
115
|
+
try {
|
|
116
|
+
const { variables: remoteVariables } = await paginate(functionsListVariables, {
|
|
117
|
+
functionId: func['$id'],
|
|
118
|
+
parseOutput: false
|
|
119
|
+
}, 100, 'variables');
|
|
120
|
+
|
|
121
|
+
remoteVariables.forEach((v) => {
|
|
122
|
+
variables[v.key] = v.value;
|
|
123
|
+
});
|
|
124
|
+
} catch(err) {
|
|
125
|
+
warn("Remote variables not fetched. Production environment variables will not be avaiable. Reason: " + err.message);
|
|
135
126
|
}
|
|
136
127
|
}
|
|
137
128
|
|
|
@@ -143,7 +134,11 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
143
134
|
variables['APPWRITE_FUNCTION_RUNTIME_NAME'] = runtimeNames[runtimeName] ?? '';
|
|
144
135
|
variables['APPWRITE_FUNCTION_RUNTIME_VERSION'] = func.runtime;
|
|
145
136
|
|
|
146
|
-
|
|
137
|
+
try {
|
|
138
|
+
await JwtManager.setup(userId);
|
|
139
|
+
} catch(err) {
|
|
140
|
+
warn("Dynamic API key not generated. Header x-appwrite-key will not be set. Reason: " + err.message);
|
|
141
|
+
}
|
|
147
142
|
|
|
148
143
|
const headers = {};
|
|
149
144
|
headers['x-appwrite-key'] = JwtManager.functionJwt ?? '';
|
|
@@ -155,13 +150,17 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
155
150
|
|
|
156
151
|
await dockerPull(func);
|
|
157
152
|
await dockerBuild(func, variables);
|
|
153
|
+
|
|
154
|
+
log('Starting function using Docker ...');
|
|
155
|
+
hint('Function automatically restarts when you edit your code.');
|
|
156
|
+
|
|
158
157
|
await dockerStart(func, variables, port);
|
|
159
158
|
|
|
160
159
|
new Tail(logsPath).on("line", function(data) {
|
|
161
|
-
|
|
160
|
+
process.stdout.write(chalk.blackBright(`${data}\n`));
|
|
162
161
|
});
|
|
163
162
|
new Tail(errorsPath).on("line", function(data) {
|
|
164
|
-
|
|
163
|
+
process.stdout.write(chalk.blackBright(`${data}\n`));
|
|
165
164
|
});
|
|
166
165
|
|
|
167
166
|
if(!noReload) {
|
|
@@ -177,23 +176,16 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
177
176
|
Queue.events.on('reload', async ({ files }) => {
|
|
178
177
|
Queue.lock();
|
|
179
178
|
|
|
180
|
-
log('Live-reloading due to file changes: ');
|
|
181
|
-
for(const file of files) {
|
|
182
|
-
log(`- ${file}`);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
179
|
try {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
await dockerStopActive();
|
|
180
|
+
await dockerStop(func.$id);
|
|
189
181
|
|
|
190
182
|
const dependencyFile = files.find((filePath) => tool.dependencyFiles.includes(filePath));
|
|
191
183
|
if(tool.isCompiled || dependencyFile) {
|
|
192
|
-
log(`Rebuilding the function
|
|
184
|
+
log(`Rebuilding the function ...`);
|
|
193
185
|
await dockerBuild(func, variables);
|
|
194
186
|
await dockerStart(func, variables, port);
|
|
195
187
|
} else {
|
|
196
|
-
log('Hot-swapping function files
|
|
188
|
+
log('Hot-swapping function.. Files with change are ' + files.join(', '));
|
|
197
189
|
|
|
198
190
|
const functionPath = path.join(process.cwd(), func.path);
|
|
199
191
|
const hotSwapPath = path.join(functionPath, '.appwrite/hot-swap');
|