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.
@@ -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
- project: pushProject,
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 pushProject = async () => {
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('Updating service statuses');
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('Updating auth security settings');
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('Updating auth login methods');
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("Project configuration updated.");
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
- if (returnOnZero) {
810
- log('No functions found, skipping');
811
- return;
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} does not have an endpoint`);
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.updateFunction(func['$id'], func);
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 || 'unique()',
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 (successfullyDeployed < successfullyPushed) {
1098
- message = `${chalk.green(`Pushed and deployed ${successfullyPushed} functions.`)} ${chalk.red(`${successfullyPushed - successfullyDeployed} failed to deploy`)}`;
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
- if (successfullyPushed === 0) {
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
- if (returnOnZero) {
1115
- log('No collections found, skipping');
1116
- return;
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
- log('Checking for databases and collection changes');
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
- if (returnOnZero) {
1247
- log('No buckets found, skipping');
1248
- return;
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 ${bucket.name} ( ${bucket['$id']} )`)
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
- if (returnOnZero) {
1329
- log('No teams found, skipping');
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 ${team.name} ( ${team['$id']} )`)
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
- if (returnOnZero) {
1396
- log('No topics found, skipping');
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 ${topic.name} ( ${topic['$id']} )`)
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("project")
1396
+ .command("settings")
1481
1397
  .description("Push project name, services and auth settings")
1482
- .action(actionRunner(pushProject));
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
  }
@@ -1,10 +1,8 @@
1
1
  const Tail = require('tail').Tail;
2
- const EventEmitter = require('node:events');
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 { openRuntimesVersion, runtimeNames, systemTools, JwtManager, Queue } = require('../emulation/utils');
21
- const { dockerStop, dockerCleanup, dockerStart, dockerBuild, dockerPull, dockerStopActive } = require('../emulation/docker');
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('Could not find an available port. Please select a port with `appwrite run --port YOUR_PORT` command.');
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('If you wish to change your local settings, update the appwrite.json file and rerun the `appwrite run` command.');
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
- if (globalConfig.getEndpoint() === '' || globalConfig.getCookie() === '') {
120
- error("No user is signed in. To sign in, run: appwrite login. Function will run locally, but will not have your function's environment variables set.");
121
- } else {
122
- try {
123
- const { variables: remoteVariables } = await paginate(functionsListVariables, {
124
- functionId: func['$id'],
125
- parseOutput: false
126
- }, 100, 'variables');
127
-
128
- remoteVariables.forEach((v) => {
129
- variables[v.key] = v.value;
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
- await JwtManager.setup(userId);
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
- console.log(data);
160
+ process.stdout.write(chalk.blackBright(`${data}\n`));
162
161
  });
163
162
  new Tail(errorsPath).on("line", function(data) {
164
- console.log(data);
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
- log('Stopping the function ...');
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 due to cange in ${dependencyFile} ...`);
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');