appwrite-cli 6.0.0-rc.5 → 6.0.0-rc.7
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 +3 -3
- package/docs/examples/functions/{download-deployment.md → get-deployment-download.md} +1 -1
- package/docs/examples/functions/get-template.md +2 -0
- package/docs/examples/functions/list-templates.md +5 -0
- package/index.js +4 -3
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.js +3 -3
- package/lib/commands/account.js +1 -49
- package/lib/commands/assistant.js +1 -2
- package/lib/commands/avatars.js +1 -8
- package/lib/commands/console.js +1 -2
- package/lib/commands/databases.js +1 -49
- package/lib/commands/functions.js +121 -35
- package/lib/commands/generic.js +11 -11
- package/lib/commands/graphql.js +1 -3
- package/lib/commands/health.js +1 -24
- package/lib/commands/init.js +7 -20
- package/lib/commands/locale.js +1 -9
- package/lib/commands/messaging.js +1 -47
- package/lib/commands/migrations.js +1 -17
- package/lib/commands/project.js +1 -7
- package/lib/commands/projects.js +1 -46
- package/lib/commands/proxy.js +1 -6
- package/lib/commands/pull.js +73 -35
- package/lib/commands/push.js +122 -55
- package/lib/commands/run.js +22 -22
- package/lib/commands/storage.js +1 -16
- package/lib/commands/teams.js +1 -15
- package/lib/commands/users.js +1 -44
- package/lib/commands/vcs.js +1 -11
- package/lib/config.js +11 -7
- package/lib/emulation/docker.js +29 -33
- package/lib/paginate.js +3 -1
- package/lib/parser.js +12 -15
- package/lib/questions.js +16 -31
- package/package.json +3 -2
- package/scoop/appwrite.json +3 -3
package/lib/commands/push.js
CHANGED
|
@@ -2,10 +2,10 @@ const chalk = require('chalk');
|
|
|
2
2
|
const inquirer = require("inquirer");
|
|
3
3
|
const JSONbig = require("json-bigint")({ storeAsString: false });
|
|
4
4
|
const { Command } = require("commander");
|
|
5
|
-
const { localConfig, globalConfig, KeysAttributes, KeysFunction, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, } = require("../config");
|
|
5
|
+
const { localConfig, globalConfig, KeysAttributes, KeysFunction, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection } = require("../config");
|
|
6
6
|
const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
|
|
7
7
|
const { paginate } = require('../paginate');
|
|
8
|
-
const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionPushChanges, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
|
|
8
|
+
const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionPushChanges, questionPushChangesConfirmation, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
|
|
9
9
|
const { cliConfig, actionRunner, success, warn, log, hint, error, commandDescriptions, drawTable } = require("../parser");
|
|
10
10
|
const { proxyListRules } = require('./proxy');
|
|
11
11
|
const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsGetDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
|
|
@@ -340,18 +340,56 @@ const awaitPools = {
|
|
|
340
340
|
},
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
const
|
|
344
|
-
|
|
343
|
+
const getConfirmation = async () => {
|
|
344
|
+
if (cliConfig.force) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
async function fixConfirmation() {
|
|
349
|
+
const answers = await inquirer.prompt(questionPushChangesConfirmation);
|
|
350
|
+
if (answers.changes !== 'YES' && answers.changes !== 'NO') {
|
|
351
|
+
return await fixConfirmation();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return answers.changes;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
let answers = await inquirer.prompt(questionPushChanges);
|
|
358
|
+
|
|
359
|
+
if (answers.changes !== 'YES' && answers.changes !== 'NO') {
|
|
360
|
+
answers.changes = await fixConfirmation();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (answers.changes === 'YES') {
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
warn('Skipping push action. Changes were not applied.');
|
|
368
|
+
return false;
|
|
369
|
+
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const approveChanges = async (resource, resourceGetFunction, keys, resourceName, resourcePlural, skipKeys = [], secondId = '', secondResourceName = '') => {
|
|
373
|
+
log('Checking for changes ...');
|
|
345
374
|
const changes = [];
|
|
346
375
|
|
|
347
376
|
await Promise.all(resource.map(async (localResource) => {
|
|
348
377
|
try {
|
|
349
|
-
const
|
|
378
|
+
const options = {
|
|
350
379
|
[resourceName]: localResource['$id'],
|
|
351
380
|
parseOutput: false,
|
|
352
|
-
}
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
if (secondId !== '' && secondResourceName !== '') {
|
|
384
|
+
options[secondResourceName] = localResource[secondId]
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const remoteResource = await resourceGetFunction(options);
|
|
353
388
|
|
|
354
389
|
for (let [key, value] of Object.entries(whitelistKeys(remoteResource, keys))) {
|
|
390
|
+
if (skipKeys.includes(key)) {
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
355
393
|
if (Array.isArray(value) && Array.isArray(localResource[key])) {
|
|
356
394
|
if (JSON.stringify(value) !== JSON.stringify(localResource[key])) {
|
|
357
395
|
changes.push({
|
|
@@ -382,11 +420,8 @@ const approveChanges = async (resource, resourceGetFunction, keys, resourceName,
|
|
|
382
420
|
}
|
|
383
421
|
|
|
384
422
|
drawTable(changes);
|
|
385
|
-
if (
|
|
386
|
-
|
|
387
|
-
if (answers.changes.toLowerCase() === 'yes') {
|
|
388
|
-
return true;
|
|
389
|
-
}
|
|
423
|
+
if ((await getConfirmation()) === true) {
|
|
424
|
+
return true;
|
|
390
425
|
}
|
|
391
426
|
|
|
392
427
|
success(`Successfully pushed 0 ${resourcePlural}.`);
|
|
@@ -399,7 +434,7 @@ const getObjectChanges = (remote, local, index, what) => {
|
|
|
399
434
|
if (remote[index] && local[index]) {
|
|
400
435
|
for (let [service, status] of Object.entries(remote[index])) {
|
|
401
436
|
if (status !== local[index][service]) {
|
|
402
|
-
changes.push({ group: what,setting: service, remote: chalk.red(status), local: chalk.green(local[index][service]) })
|
|
437
|
+
changes.push({ group: what, setting: service, remote: chalk.red(status), local: chalk.green(local[index][service]) })
|
|
403
438
|
}
|
|
404
439
|
}
|
|
405
440
|
}
|
|
@@ -661,6 +696,20 @@ const deleteAttribute = async (collection, attribute, isIndex = false) => {
|
|
|
661
696
|
});
|
|
662
697
|
}
|
|
663
698
|
|
|
699
|
+
const compareAttribute = (remote, local, reason, key) => {
|
|
700
|
+
if (Array.isArray(remote) && Array.isArray(local)) {
|
|
701
|
+
if (JSON.stringify(remote) !== JSON.stringify(local)) {
|
|
702
|
+
const bol = reason === '' ? '' : '\n';
|
|
703
|
+
reason += `${bol}${key} changed from ${chalk.red(remote)} to ${chalk.green(local)}`;
|
|
704
|
+
}
|
|
705
|
+
} else if (remote !== local) {
|
|
706
|
+
const bol = reason === '' ? '' : '\n';
|
|
707
|
+
reason += `${bol}${key} changed from ${chalk.red(remote)} to ${chalk.green(local)}`;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
return reason
|
|
711
|
+
}
|
|
712
|
+
|
|
664
713
|
|
|
665
714
|
/**
|
|
666
715
|
* Check if attribute non-changeable fields has been changed
|
|
@@ -688,11 +737,7 @@ const checkAttributeChanges = (remote, local, collection, recraeting = true) =>
|
|
|
688
737
|
|
|
689
738
|
if (changeableKeys.includes(key)) {
|
|
690
739
|
if (!recraeting) {
|
|
691
|
-
|
|
692
|
-
const bol = reason === '' ? '' : '\n';
|
|
693
|
-
reason += `${bol}${key} changed from ${chalk.red(remote[key])} to ${chalk.green(local[key])}`;
|
|
694
|
-
attribute = local;
|
|
695
|
-
}
|
|
740
|
+
reason += compareAttribute(remote[key], local[key], reason, key)
|
|
696
741
|
}
|
|
697
742
|
continue;
|
|
698
743
|
}
|
|
@@ -701,15 +746,7 @@ const checkAttributeChanges = (remote, local, collection, recraeting = true) =>
|
|
|
701
746
|
continue;
|
|
702
747
|
}
|
|
703
748
|
|
|
704
|
-
|
|
705
|
-
if (JSON.stringify(remote[key]) !== JSON.stringify(local[key])) {
|
|
706
|
-
const bol = reason === '' ? '' : '\n';
|
|
707
|
-
reason += `${bol}${key} changed from ${chalk.red(remote[key])} to ${chalk.green(local[key])}`;
|
|
708
|
-
}
|
|
709
|
-
} else if (remote[key] !== local[key]) {
|
|
710
|
-
const bol = reason === '' ? '' : '\n';
|
|
711
|
-
reason += `${bol}${key} changed from ${chalk.red(remote[key])} to ${chalk.green(local[key])}`;
|
|
712
|
-
}
|
|
749
|
+
reason += compareAttribute(remote[key], local[key], reason, key)
|
|
713
750
|
}
|
|
714
751
|
|
|
715
752
|
return reason === '' ? undefined : { key: keyName, attribute, reason, action };
|
|
@@ -766,9 +803,7 @@ const attributesToCreate = async (remoteAttributes, localAttributes, collection,
|
|
|
766
803
|
log(`Attribute recreation will cause ${chalk.red('loss of data')}`);
|
|
767
804
|
}
|
|
768
805
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
if (answers.changes.toLowerCase() !== 'yes') {
|
|
806
|
+
if ((await getConfirmation()) !== true) {
|
|
772
807
|
return changedAttributes;
|
|
773
808
|
}
|
|
774
809
|
}
|
|
@@ -881,7 +916,7 @@ const pushSettings = async () => {
|
|
|
881
916
|
const remoteSettings = localConfig.createSettingsObject(response ?? {});
|
|
882
917
|
const localSettings = localConfig.getProject().projectSettings ?? {};
|
|
883
918
|
|
|
884
|
-
log('Checking for changes');
|
|
919
|
+
log('Checking for changes ...');
|
|
885
920
|
const changes = [];
|
|
886
921
|
|
|
887
922
|
changes.push(...(getObjectChanges(remoteSettings, localSettings, 'services', 'Service')));
|
|
@@ -890,12 +925,9 @@ const pushSettings = async () => {
|
|
|
890
925
|
|
|
891
926
|
if (changes.length > 0) {
|
|
892
927
|
drawTable(changes);
|
|
893
|
-
if (
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
success(`Successfully pushed 0 project settings.`);
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
928
|
+
if ((await getConfirmation()) !== true) {
|
|
929
|
+
success(`Successfully pushed 0 project settings.`);
|
|
930
|
+
return;
|
|
899
931
|
}
|
|
900
932
|
}
|
|
901
933
|
} catch (e) {
|
|
@@ -960,7 +992,7 @@ const pushSettings = async () => {
|
|
|
960
992
|
}
|
|
961
993
|
}
|
|
962
994
|
|
|
963
|
-
const pushFunction = async ({ functionId, async, code } = { returnOnZero: false }) => {
|
|
995
|
+
const pushFunction = async ({ functionId, async, code, withVariables } = { returnOnZero: false }) => {
|
|
964
996
|
const functionIds = [];
|
|
965
997
|
|
|
966
998
|
if (functionId) {
|
|
@@ -1009,7 +1041,7 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1009
1041
|
}
|
|
1010
1042
|
}
|
|
1011
1043
|
|
|
1012
|
-
if (!(await approveChanges(functions, functionsGet, KeysFunction, 'functionId', 'functions'))) {
|
|
1044
|
+
if (!(await approveChanges(functions, functionsGet, KeysFunction, 'functionId', 'functions', ['vars']))) {
|
|
1013
1045
|
return;
|
|
1014
1046
|
}
|
|
1015
1047
|
|
|
@@ -1019,6 +1051,7 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1019
1051
|
let successfullyPushed = 0;
|
|
1020
1052
|
let successfullyDeployed = 0;
|
|
1021
1053
|
const failedDeployments = [];
|
|
1054
|
+
const errors = [];
|
|
1022
1055
|
|
|
1023
1056
|
await Promise.all(functions.map(async (func) => {
|
|
1024
1057
|
let response = {};
|
|
@@ -1068,6 +1101,7 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1068
1101
|
if (Number(e.code) === 404) {
|
|
1069
1102
|
functionExists = false;
|
|
1070
1103
|
} else {
|
|
1104
|
+
errors.push(e);
|
|
1071
1105
|
updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
|
|
1072
1106
|
return;
|
|
1073
1107
|
}
|
|
@@ -1095,11 +1129,45 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1095
1129
|
|
|
1096
1130
|
updaterRow.update({ status: 'Created' });
|
|
1097
1131
|
} catch (e) {
|
|
1132
|
+
errors.push(e)
|
|
1098
1133
|
updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
|
|
1099
1134
|
return;
|
|
1100
1135
|
}
|
|
1101
1136
|
}
|
|
1102
1137
|
|
|
1138
|
+
if (withVariables) {
|
|
1139
|
+
updaterRow.update({ status: 'Updating variables' }).replaceSpinner(SPINNER_ARC);
|
|
1140
|
+
|
|
1141
|
+
const { variables } = await paginate(functionsListVariables, {
|
|
1142
|
+
functionId: func['$id'],
|
|
1143
|
+
parseOutput: false
|
|
1144
|
+
}, 100, 'variables');
|
|
1145
|
+
|
|
1146
|
+
await Promise.all(variables.map(async variable => {
|
|
1147
|
+
await functionsDeleteVariable({
|
|
1148
|
+
functionId: func['$id'],
|
|
1149
|
+
variableId: variable['$id'],
|
|
1150
|
+
parseOutput: false
|
|
1151
|
+
});
|
|
1152
|
+
}));
|
|
1153
|
+
|
|
1154
|
+
let result = await awaitPools.wipeVariables(func['$id']);
|
|
1155
|
+
if (!result) {
|
|
1156
|
+
updaterRow.fail({ errorMessage: `Variable deletion timed out.` })
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// Deploy local variables
|
|
1161
|
+
await Promise.all((func['vars'] ?? []).map(async variable => {
|
|
1162
|
+
await functionsCreateVariable({
|
|
1163
|
+
functionId: func['$id'],
|
|
1164
|
+
key: variable['key'],
|
|
1165
|
+
value: variable['value'],
|
|
1166
|
+
parseOutput: false
|
|
1167
|
+
});
|
|
1168
|
+
}));
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1103
1171
|
if (code === false) {
|
|
1104
1172
|
successfullyPushed++;
|
|
1105
1173
|
successfullyDeployed++;
|
|
@@ -1123,6 +1191,8 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1123
1191
|
deploymentCreated = true;
|
|
1124
1192
|
successfullyPushed++;
|
|
1125
1193
|
} catch (e) {
|
|
1194
|
+
errors.push(e);
|
|
1195
|
+
|
|
1126
1196
|
switch (e.code) {
|
|
1127
1197
|
case 'ENOENT':
|
|
1128
1198
|
updaterRow.fail({ errorMessage: 'Not found in the current directory. Skipping...' })
|
|
@@ -1180,6 +1250,7 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1180
1250
|
await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE * 1.5));
|
|
1181
1251
|
}
|
|
1182
1252
|
} catch (e) {
|
|
1253
|
+
errors.push(e);
|
|
1183
1254
|
updaterRow.fail({ errorMessage: e.message ?? 'Unknown error occurred. Please try again' })
|
|
1184
1255
|
}
|
|
1185
1256
|
}
|
|
@@ -1207,6 +1278,12 @@ const pushFunction = async ({ functionId, async, code } = { returnOnZero: false
|
|
|
1207
1278
|
} else {
|
|
1208
1279
|
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
1209
1280
|
}
|
|
1281
|
+
|
|
1282
|
+
if (cliConfig.verbose) {
|
|
1283
|
+
errors.forEach(e => {
|
|
1284
|
+
console.error(e);
|
|
1285
|
+
})
|
|
1286
|
+
}
|
|
1210
1287
|
}
|
|
1211
1288
|
|
|
1212
1289
|
const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
|
|
@@ -1241,8 +1318,6 @@ const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false
|
|
|
1241
1318
|
|
|
1242
1319
|
const databases = Array.from(new Set(collections.map(collection => collection['databaseId'])));
|
|
1243
1320
|
|
|
1244
|
-
log('Checking for changes ...');
|
|
1245
|
-
|
|
1246
1321
|
// Parallel db actions
|
|
1247
1322
|
await Promise.all(databases.map(async (databaseId) => {
|
|
1248
1323
|
const localDatabase = localConfig.getDatabase(databaseId);
|
|
@@ -1273,6 +1348,10 @@ const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false
|
|
|
1273
1348
|
}
|
|
1274
1349
|
}));
|
|
1275
1350
|
|
|
1351
|
+
|
|
1352
|
+
if (!(await approveChanges(collections, databasesGetCollection, KeysCollection, 'collectionId', 'collections', ['attributes', 'indexes'], 'databaseId', 'databaseId',))) {
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1276
1355
|
// Parallel collection actions
|
|
1277
1356
|
await Promise.all(collections.map(async (collection) => {
|
|
1278
1357
|
try {
|
|
@@ -1343,10 +1422,10 @@ const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false
|
|
|
1343
1422
|
throw e;
|
|
1344
1423
|
}
|
|
1345
1424
|
numberOfCollections++;
|
|
1346
|
-
success(`
|
|
1425
|
+
success(`Successfully pushed ${collection.name} ( ${collection['$id']} )`);
|
|
1347
1426
|
}
|
|
1348
1427
|
|
|
1349
|
-
success(`
|
|
1428
|
+
success(`Successfully pushed ${numberOfCollections} collections`);
|
|
1350
1429
|
}
|
|
1351
1430
|
|
|
1352
1431
|
const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
|
|
@@ -1509,7 +1588,6 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1509
1588
|
|
|
1510
1589
|
let topicsIds = [];
|
|
1511
1590
|
const configTopics = localConfig.getMessagingTopics();
|
|
1512
|
-
let overrideExisting = cliConfig.force;
|
|
1513
1591
|
|
|
1514
1592
|
if (cliConfig.all) {
|
|
1515
1593
|
checkDeployConditions(localConfig);
|
|
@@ -1536,13 +1614,6 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1536
1614
|
topics.push(...idTopic);
|
|
1537
1615
|
}
|
|
1538
1616
|
|
|
1539
|
-
if (!cliConfig.force) {
|
|
1540
|
-
const answers = await inquirer.prompt(questionsPushMessagingTopics[1])
|
|
1541
|
-
if (answers.override.toLowerCase() === "yes") {
|
|
1542
|
-
overrideExisting = true;
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
1617
|
if (!(await approveChanges(topics, messagingGetTopic, KeysTopics, 'topicId', 'topics'))) {
|
|
1547
1618
|
return;
|
|
1548
1619
|
}
|
|
@@ -1559,11 +1630,6 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
|
|
|
1559
1630
|
})
|
|
1560
1631
|
log(`Topic ${topic.name} ( ${topic['$id']} ) already exists.`);
|
|
1561
1632
|
|
|
1562
|
-
if (!overrideExisting) {
|
|
1563
|
-
log(`Skipping ${topic.name} ( ${topic['$id']} )`);
|
|
1564
|
-
continue;
|
|
1565
|
-
}
|
|
1566
|
-
|
|
1567
1633
|
await messagingUpdateTopic({
|
|
1568
1634
|
topicId: topic['$id'],
|
|
1569
1635
|
name: topic.name,
|
|
@@ -1615,6 +1681,7 @@ push
|
|
|
1615
1681
|
.option(`-f, --function-id <function-id>`, `ID of function to run`)
|
|
1616
1682
|
.option(`-A, --async`, `Don't wait for functions deployments status`)
|
|
1617
1683
|
.option("--no-code", "Don't push the function's code")
|
|
1684
|
+
.option("--with-variables", `Push function variables.`)
|
|
1618
1685
|
.action(actionRunner(pushFunction));
|
|
1619
1686
|
|
|
1620
1687
|
push
|
package/lib/commands/run.js
CHANGED
|
@@ -17,7 +17,7 @@ const { systemHasCommand, isPortTaken, getAllFiles } = require('../utils');
|
|
|
17
17
|
const { runtimeNames, systemTools, JwtManager, Queue } = require('../emulation/utils');
|
|
18
18
|
const { dockerStop, dockerCleanup, dockerStart, dockerBuild, dockerPull } = require('../emulation/docker');
|
|
19
19
|
|
|
20
|
-
const runFunction = async ({ port, functionId,
|
|
20
|
+
const runFunction = async ({ port, functionId, withVariables, reload, userId } = {}) => {
|
|
21
21
|
// Selection
|
|
22
22
|
if(!functionId) {
|
|
23
23
|
const answers = await inquirer.prompt(questionsRunFunctions[0]);
|
|
@@ -113,9 +113,9 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
const userVariables = {};
|
|
116
|
-
const
|
|
116
|
+
const allVariables = {};
|
|
117
117
|
|
|
118
|
-
if(
|
|
118
|
+
if(withVariables) {
|
|
119
119
|
try {
|
|
120
120
|
const { variables: remoteVariables } = await paginate(functionsListVariables, {
|
|
121
121
|
functionId: func['$id'],
|
|
@@ -123,11 +123,11 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
123
123
|
}, 100, 'variables');
|
|
124
124
|
|
|
125
125
|
remoteVariables.forEach((v) => {
|
|
126
|
-
|
|
126
|
+
allVariables[v.key] = v.value;
|
|
127
127
|
userVariables[v.key] = v.value;
|
|
128
128
|
});
|
|
129
129
|
} catch(err) {
|
|
130
|
-
warn("Remote variables not fetched. Production environment variables will not be
|
|
130
|
+
warn("Remote variables not fetched. Production environment variables will not be available. Reason: " + err.message);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -137,18 +137,18 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
137
137
|
const env = parseDotenv(fs.readFileSync(envPath).toString() ?? '');
|
|
138
138
|
|
|
139
139
|
Object.keys(env).forEach((key) => {
|
|
140
|
-
|
|
140
|
+
allVariables[key] = env[key];
|
|
141
141
|
userVariables[key] = env[key];
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
allVariables['APPWRITE_FUNCTION_API_ENDPOINT'] = globalConfig.getFrom('endpoint');
|
|
146
|
+
allVariables['APPWRITE_FUNCTION_ID'] = func.$id;
|
|
147
|
+
allVariables['APPWRITE_FUNCTION_NAME'] = func.name;
|
|
148
|
+
allVariables['APPWRITE_FUNCTION_DEPLOYMENT'] = ''; // TODO: Implement when relevant
|
|
149
|
+
allVariables['APPWRITE_FUNCTION_PROJECT_ID'] = localConfig.getProject().projectId;
|
|
150
|
+
allVariables['APPWRITE_FUNCTION_RUNTIME_NAME'] = runtimeNames[runtimeName] ?? '';
|
|
151
|
+
allVariables['APPWRITE_FUNCTION_RUNTIME_VERSION'] = func.runtime;
|
|
152
152
|
|
|
153
153
|
try {
|
|
154
154
|
await JwtManager.setup(userId, func.scopes ?? []);
|
|
@@ -162,7 +162,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
162
162
|
headers['x-appwrite-event'] = '';
|
|
163
163
|
headers['x-appwrite-user-id'] = userId ?? '';
|
|
164
164
|
headers['x-appwrite-user-jwt'] = JwtManager.userJwt ?? '';
|
|
165
|
-
|
|
165
|
+
allVariables['OPEN_RUNTIMES_HEADERS'] = JSON.stringify(headers);
|
|
166
166
|
|
|
167
167
|
if(Object.keys(userVariables).length > 0) {
|
|
168
168
|
drawTable(Object.keys(userVariables).map((key) => ({
|
|
@@ -180,11 +180,11 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
180
180
|
process.stdout.write(chalk.white(`${data}\n`));
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
-
if(
|
|
183
|
+
if(reload) {
|
|
184
184
|
const ignorer = ignore();
|
|
185
185
|
ignorer.add('.appwrite');
|
|
186
186
|
ignorer.add('code.tar.gz');
|
|
187
|
-
|
|
187
|
+
|
|
188
188
|
if (func.ignore) {
|
|
189
189
|
ignorer.add(func.ignore);
|
|
190
190
|
} else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
|
|
@@ -216,14 +216,14 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
216
216
|
const dependencyFile = files.find((filePath) => tool.dependencyFiles.includes(filePath));
|
|
217
217
|
if(tool.isCompiled || dependencyFile) {
|
|
218
218
|
log(`Rebuilding the function due to file changes ...`);
|
|
219
|
-
await dockerBuild(func,
|
|
219
|
+
await dockerBuild(func, allVariables);
|
|
220
220
|
|
|
221
221
|
if(!Queue.isEmpty()) {
|
|
222
222
|
Queue.unlock();
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
await dockerStart(func,
|
|
226
|
+
await dockerStart(func, allVariables, port);
|
|
227
227
|
} else {
|
|
228
228
|
log('Hot-swapping function.. Files with change are ' + files.join(', '));
|
|
229
229
|
|
|
@@ -279,7 +279,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
279
279
|
file: buildPath
|
|
280
280
|
}, ['.']);
|
|
281
281
|
|
|
282
|
-
await dockerStart(func,
|
|
282
|
+
await dockerStart(func, allVariables, port);
|
|
283
283
|
}
|
|
284
284
|
} catch(err) {
|
|
285
285
|
console.error(err);
|
|
@@ -291,7 +291,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
291
291
|
Queue.lock();
|
|
292
292
|
|
|
293
293
|
log('Building function using Docker ...');
|
|
294
|
-
await dockerBuild(func,
|
|
294
|
+
await dockerBuild(func, allVariables);
|
|
295
295
|
|
|
296
296
|
if(!Queue.isEmpty()) {
|
|
297
297
|
Queue.unlock();
|
|
@@ -300,7 +300,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
|
|
|
300
300
|
|
|
301
301
|
log('Starting function using Docker ...');
|
|
302
302
|
hint('Function automatically restarts when you edit your code.');
|
|
303
|
-
await dockerStart(func,
|
|
303
|
+
await dockerStart(func, allVariables, port);
|
|
304
304
|
|
|
305
305
|
Queue.unlock();
|
|
306
306
|
}
|
|
@@ -321,7 +321,7 @@ run
|
|
|
321
321
|
.option(`--function-id <function-id>`, `ID of function to run`)
|
|
322
322
|
.option(`--port <port>`, `Local port`)
|
|
323
323
|
.option(`--user-id <user-id>`, `ID of user to impersonate`)
|
|
324
|
-
.option(`--
|
|
324
|
+
.option(`--with-variables`, `Run with function variables from function settings`)
|
|
325
325
|
.option(`--no-reload`, `Prevent live reloading of server when changes are made to function files`)
|
|
326
326
|
.action(actionRunner(runFunction));
|
|
327
327
|
|
package/lib/commands/storage.js
CHANGED
|
@@ -35,7 +35,7 @@ function convertReadStreamToReadableStream(readStream) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const storage = new Command("storage").description(commandDescriptions['storage']).configureHelp({
|
|
38
|
+
const storage = new Command("storage").description(commandDescriptions['storage'] ?? '').configureHelp({
|
|
39
39
|
helpWidth: process.stdout.columns || 80
|
|
40
40
|
})
|
|
41
41
|
|
|
@@ -74,7 +74,6 @@ const storageListBuckets = async ({queries,search,parseOutput = true, overrideFo
|
|
|
74
74
|
showConsoleLink('storage', 'listBuckets');
|
|
75
75
|
} else {
|
|
76
76
|
parse(response)
|
|
77
|
-
success()
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
|
|
@@ -148,7 +147,6 @@ const storageCreateBucket = async ({bucketId,name,permissions,fileSecurity,enabl
|
|
|
148
147
|
|
|
149
148
|
if (parseOutput) {
|
|
150
149
|
parse(response)
|
|
151
|
-
success()
|
|
152
150
|
}
|
|
153
151
|
|
|
154
152
|
return response;
|
|
@@ -183,7 +181,6 @@ const storageGetBucket = async ({bucketId,parseOutput = true, overrideForCli = f
|
|
|
183
181
|
showConsoleLink('storage', 'getBucket', bucketId);
|
|
184
182
|
} else {
|
|
185
183
|
parse(response)
|
|
186
|
-
success()
|
|
187
184
|
}
|
|
188
185
|
}
|
|
189
186
|
|
|
@@ -254,7 +251,6 @@ const storageUpdateBucket = async ({bucketId,name,permissions,fileSecurity,enabl
|
|
|
254
251
|
|
|
255
252
|
if (parseOutput) {
|
|
256
253
|
parse(response)
|
|
257
|
-
success()
|
|
258
254
|
}
|
|
259
255
|
|
|
260
256
|
return response;
|
|
@@ -286,7 +282,6 @@ const storageDeleteBucket = async ({bucketId,parseOutput = true, overrideForCli
|
|
|
286
282
|
|
|
287
283
|
if (parseOutput) {
|
|
288
284
|
parse(response)
|
|
289
|
-
success()
|
|
290
285
|
}
|
|
291
286
|
|
|
292
287
|
return response;
|
|
@@ -329,7 +324,6 @@ const storageListFiles = async ({bucketId,queries,search,parseOutput = true, ove
|
|
|
329
324
|
showConsoleLink('storage', 'listFiles', bucketId);
|
|
330
325
|
} else {
|
|
331
326
|
parse(response)
|
|
332
|
-
success()
|
|
333
327
|
}
|
|
334
328
|
}
|
|
335
329
|
|
|
@@ -465,7 +459,6 @@ const storageCreateFile = async ({bucketId,fileId,file,permissions,parseOutput =
|
|
|
465
459
|
|
|
466
460
|
if (parseOutput) {
|
|
467
461
|
parse(response)
|
|
468
|
-
success()
|
|
469
462
|
}
|
|
470
463
|
|
|
471
464
|
return response;
|
|
@@ -500,7 +493,6 @@ const storageGetFile = async ({bucketId,fileId,parseOutput = true, overrideForCl
|
|
|
500
493
|
showConsoleLink('storage', 'getFile', bucketId, fileId);
|
|
501
494
|
} else {
|
|
502
495
|
parse(response)
|
|
503
|
-
success()
|
|
504
496
|
}
|
|
505
497
|
}
|
|
506
498
|
|
|
@@ -543,7 +535,6 @@ const storageUpdateFile = async ({bucketId,fileId,name,permissions,parseOutput =
|
|
|
543
535
|
|
|
544
536
|
if (parseOutput) {
|
|
545
537
|
parse(response)
|
|
546
|
-
success()
|
|
547
538
|
}
|
|
548
539
|
|
|
549
540
|
return response;
|
|
@@ -576,7 +567,6 @@ const storageDeleteFile = async ({bucketId,fileId,parseOutput = true, overrideFo
|
|
|
576
567
|
|
|
577
568
|
if (parseOutput) {
|
|
578
569
|
parse(response)
|
|
579
|
-
success()
|
|
580
570
|
}
|
|
581
571
|
|
|
582
572
|
return response;
|
|
@@ -621,7 +611,6 @@ const storageGetFileDownload = async ({bucketId,fileId,parseOutput = true, overr
|
|
|
621
611
|
fs.writeFileSync(destination, response);
|
|
622
612
|
if (parseOutput) {
|
|
623
613
|
parse(response)
|
|
624
|
-
success()
|
|
625
614
|
}
|
|
626
615
|
|
|
627
616
|
return response;
|
|
@@ -710,7 +699,6 @@ const storageGetFilePreview = async ({bucketId,fileId,width,height,gravity,quali
|
|
|
710
699
|
fs.writeFileSync(destination, response);
|
|
711
700
|
if (parseOutput) {
|
|
712
701
|
parse(response)
|
|
713
|
-
success()
|
|
714
702
|
}
|
|
715
703
|
|
|
716
704
|
return response;
|
|
@@ -755,7 +743,6 @@ const storageGetFileView = async ({bucketId,fileId,parseOutput = true, overrideF
|
|
|
755
743
|
fs.writeFileSync(destination, response);
|
|
756
744
|
if (parseOutput) {
|
|
757
745
|
parse(response)
|
|
758
|
-
success()
|
|
759
746
|
}
|
|
760
747
|
|
|
761
748
|
return response;
|
|
@@ -790,7 +777,6 @@ const storageGetUsage = async ({range,parseOutput = true, overrideForCli = false
|
|
|
790
777
|
|
|
791
778
|
if (parseOutput) {
|
|
792
779
|
parse(response)
|
|
793
|
-
success()
|
|
794
780
|
}
|
|
795
781
|
|
|
796
782
|
return response;
|
|
@@ -829,7 +815,6 @@ const storageGetBucketUsage = async ({bucketId,range,parseOutput = true, overrid
|
|
|
829
815
|
showConsoleLink('storage', 'getBucketUsage', bucketId);
|
|
830
816
|
} else {
|
|
831
817
|
parse(response)
|
|
832
|
-
success()
|
|
833
818
|
}
|
|
834
819
|
}
|
|
835
820
|
|