appwrite-cli 6.2.3 → 8.0.0

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.
Files changed (118) hide show
  1. package/README.md +4 -4
  2. package/docs/examples/console/get-resource.md +3 -0
  3. package/docs/examples/databases/create-documents.md +4 -0
  4. package/docs/examples/databases/create-index.md +1 -0
  5. package/docs/examples/databases/delete-documents.md +4 -0
  6. package/docs/examples/databases/update-documents.md +5 -0
  7. package/docs/examples/databases/upsert-document.md +6 -0
  8. package/docs/examples/databases/upsert-documents.md +4 -0
  9. package/docs/examples/functions/{create-build.md → create-duplicate-deployment.md} +1 -1
  10. package/docs/examples/functions/create-template-deployment.md +7 -0
  11. package/docs/examples/functions/create-variable.md +2 -1
  12. package/docs/examples/functions/create-vcs-deployment.md +5 -0
  13. package/docs/examples/functions/create.md +0 -4
  14. package/docs/examples/functions/get-deployment-download.md +2 -1
  15. package/docs/examples/functions/get-usage.md +1 -0
  16. package/docs/examples/functions/list-executions.md +0 -1
  17. package/docs/examples/functions/list-usage.md +2 -0
  18. package/docs/examples/functions/{update-deployment.md → update-deployment-status.md} +1 -1
  19. package/docs/examples/functions/{update-deployment-build.md → update-function-deployment.md} +1 -1
  20. package/docs/examples/functions/update-variable.md +1 -0
  21. package/docs/examples/migrations/create-csv-migration.md +4 -0
  22. package/docs/examples/project/create-variable.md +2 -1
  23. package/docs/examples/project/update-variable.md +1 -0
  24. package/docs/examples/projects/create-dev-key.md +4 -0
  25. package/docs/examples/projects/delete-dev-key.md +3 -0
  26. package/docs/examples/projects/get-dev-key.md +3 -0
  27. package/docs/examples/projects/list-dev-keys.md +3 -0
  28. package/docs/examples/projects/update-dev-key.md +5 -0
  29. package/docs/examples/proxy/create-a-p-i-rule.md +2 -0
  30. package/docs/examples/proxy/create-function-rule.md +4 -0
  31. package/docs/examples/proxy/create-redirect-rule.md +4 -0
  32. package/docs/examples/proxy/create-site-rule.md +4 -0
  33. package/docs/examples/sites/create-deployment.md +7 -0
  34. package/docs/examples/sites/create-duplicate-deployment.md +3 -0
  35. package/docs/examples/sites/create-template-deployment.md +7 -0
  36. package/docs/examples/sites/create-variable.md +5 -0
  37. package/docs/examples/sites/create-vcs-deployment.md +5 -0
  38. package/docs/examples/sites/create.md +19 -0
  39. package/docs/examples/sites/delete-deployment.md +3 -0
  40. package/docs/examples/sites/delete-log.md +3 -0
  41. package/docs/examples/sites/delete-variable.md +3 -0
  42. package/docs/examples/sites/delete.md +2 -0
  43. package/docs/examples/sites/get-deployment-download.md +4 -0
  44. package/docs/examples/sites/get-deployment.md +3 -0
  45. package/docs/examples/sites/get-log.md +3 -0
  46. package/docs/examples/sites/get-template.md +2 -0
  47. package/docs/examples/sites/get-usage.md +3 -0
  48. package/docs/examples/sites/get-variable.md +3 -0
  49. package/docs/examples/sites/get.md +2 -0
  50. package/docs/examples/sites/list-deployments.md +4 -0
  51. package/docs/examples/sites/list-frameworks.md +1 -0
  52. package/docs/examples/sites/list-logs.md +3 -0
  53. package/docs/examples/sites/list-specifications.md +1 -0
  54. package/docs/examples/sites/list-templates.md +5 -0
  55. package/docs/examples/sites/list-usage.md +2 -0
  56. package/docs/examples/sites/list-variables.md +2 -0
  57. package/docs/examples/sites/list.md +3 -0
  58. package/docs/examples/sites/update-deployment-status.md +3 -0
  59. package/docs/examples/sites/update-site-deployment.md +3 -0
  60. package/docs/examples/sites/update-variable.md +6 -0
  61. package/docs/examples/sites/update.md +19 -0
  62. package/docs/examples/storage/get-file-download.md +2 -1
  63. package/docs/examples/storage/get-file-preview.md +1 -0
  64. package/docs/examples/storage/get-file-view.md +2 -1
  65. package/docs/examples/tokens/create-file-token.md +4 -0
  66. package/docs/examples/tokens/delete.md +2 -0
  67. package/docs/examples/tokens/get.md +2 -0
  68. package/docs/examples/tokens/list.md +4 -0
  69. package/docs/examples/tokens/update.md +3 -0
  70. package/docs/examples/users/list-memberships.md +3 -1
  71. package/docs/examples/vcs/create-repository-detection.md +1 -0
  72. package/docs/examples/vcs/list-repositories.md +1 -0
  73. package/index.js +6 -2
  74. package/install.ps1 +2 -2
  75. package/install.sh +1 -1
  76. package/lib/client.js +8 -4
  77. package/lib/commands/account.js +7 -17
  78. package/lib/commands/avatars.js +7 -14
  79. package/lib/commands/console.js +50 -1
  80. package/lib/commands/databases.js +287 -55
  81. package/lib/commands/functions.js +244 -146
  82. package/lib/commands/generic.js +1 -1
  83. package/lib/commands/health.js +0 -63
  84. package/lib/commands/init.js +191 -0
  85. package/lib/commands/locale.js +0 -8
  86. package/lib/commands/messaging.js +38 -51
  87. package/lib/commands/migrations.js +50 -5
  88. package/lib/commands/project.js +12 -5
  89. package/lib/commands/projects.js +246 -27
  90. package/lib/commands/proxy.js +160 -19
  91. package/lib/commands/pull.js +124 -1
  92. package/lib/commands/push.js +338 -5
  93. package/lib/commands/sites.js +1663 -0
  94. package/lib/commands/storage.js +28 -22
  95. package/lib/commands/teams.js +2 -8
  96. package/lib/commands/tokens.js +261 -0
  97. package/lib/commands/types.js +126 -0
  98. package/lib/commands/users.js +15 -17
  99. package/lib/commands/vcs.js +60 -53
  100. package/lib/config.js +50 -0
  101. package/lib/parser.js +2 -2
  102. package/lib/questions.js +110 -1
  103. package/lib/type-generation/attribute.js +16 -0
  104. package/lib/type-generation/languages/dart.js +152 -0
  105. package/lib/type-generation/languages/java.js +121 -0
  106. package/lib/type-generation/languages/javascript.js +84 -0
  107. package/lib/type-generation/languages/kotlin.js +75 -0
  108. package/lib/type-generation/languages/language.js +125 -0
  109. package/lib/type-generation/languages/php.js +100 -0
  110. package/lib/type-generation/languages/swift.js +156 -0
  111. package/lib/type-generation/languages/typescript.js +95 -0
  112. package/package.json +2 -1
  113. package/scoop/appwrite.json +3 -3
  114. package/docs/examples/assistant/chat.md +0 -2
  115. package/docs/examples/functions/get-function-usage.md +0 -3
  116. package/docs/examples/health/get-queue-stats-usage-dump.md +0 -2
  117. package/docs/examples/proxy/create-rule.md +0 -4
  118. package/lib/commands/assistant.js +0 -85
@@ -121,7 +121,7 @@ const whoami = new Command("whoami")
121
121
  sdk: client,
122
122
  parseOutput: false
123
123
  });
124
- } catch (error) {
124
+ } catch (_) {
125
125
  error("No user is signed in. To sign in, run 'appwrite login'");
126
126
  return;
127
127
  }
@@ -58,7 +58,6 @@ const healthGet = async ({parseOutput = true, overrideForCli = false, sdk = unde
58
58
  let response = undefined;
59
59
 
60
60
  response = await client.call('get', apiPath, {
61
- 'content-type': 'application/json',
62
61
  }, payload);
63
62
 
64
63
  if (parseOutput) {
@@ -88,7 +87,6 @@ const healthGetAntivirus = async ({parseOutput = true, overrideForCli = false, s
88
87
  let response = undefined;
89
88
 
90
89
  response = await client.call('get', apiPath, {
91
- 'content-type': 'application/json',
92
90
  }, payload);
93
91
 
94
92
  if (parseOutput) {
@@ -118,7 +116,6 @@ const healthGetCache = async ({parseOutput = true, overrideForCli = false, sdk =
118
116
  let response = undefined;
119
117
 
120
118
  response = await client.call('get', apiPath, {
121
- 'content-type': 'application/json',
122
119
  }, payload);
123
120
 
124
121
  if (parseOutput) {
@@ -152,7 +149,6 @@ const healthGetCertificate = async ({domain,parseOutput = true, overrideForCli =
152
149
  let response = undefined;
153
150
 
154
151
  response = await client.call('get', apiPath, {
155
- 'content-type': 'application/json',
156
152
  }, payload);
157
153
 
158
154
  if (parseOutput) {
@@ -182,7 +178,6 @@ const healthGetDB = async ({parseOutput = true, overrideForCli = false, sdk = un
182
178
  let response = undefined;
183
179
 
184
180
  response = await client.call('get', apiPath, {
185
- 'content-type': 'application/json',
186
181
  }, payload);
187
182
 
188
183
  if (parseOutput) {
@@ -212,7 +207,6 @@ const healthGetPubSub = async ({parseOutput = true, overrideForCli = false, sdk
212
207
  let response = undefined;
213
208
 
214
209
  response = await client.call('get', apiPath, {
215
- 'content-type': 'application/json',
216
210
  }, payload);
217
211
 
218
212
  if (parseOutput) {
@@ -246,7 +240,6 @@ const healthGetQueueBuilds = async ({threshold,parseOutput = true, overrideForCl
246
240
  let response = undefined;
247
241
 
248
242
  response = await client.call('get', apiPath, {
249
- 'content-type': 'application/json',
250
243
  }, payload);
251
244
 
252
245
  if (parseOutput) {
@@ -280,7 +273,6 @@ const healthGetQueueCertificates = async ({threshold,parseOutput = true, overrid
280
273
  let response = undefined;
281
274
 
282
275
  response = await client.call('get', apiPath, {
283
- 'content-type': 'application/json',
284
276
  }, payload);
285
277
 
286
278
  if (parseOutput) {
@@ -318,7 +310,6 @@ const healthGetQueueDatabases = async ({name,threshold,parseOutput = true, overr
318
310
  let response = undefined;
319
311
 
320
312
  response = await client.call('get', apiPath, {
321
- 'content-type': 'application/json',
322
313
  }, payload);
323
314
 
324
315
  if (parseOutput) {
@@ -352,7 +343,6 @@ const healthGetQueueDeletes = async ({threshold,parseOutput = true, overrideForC
352
343
  let response = undefined;
353
344
 
354
345
  response = await client.call('get', apiPath, {
355
- 'content-type': 'application/json',
356
346
  }, payload);
357
347
 
358
348
  if (parseOutput) {
@@ -387,7 +377,6 @@ const healthGetFailedJobs = async ({name,threshold,parseOutput = true, overrideF
387
377
  let response = undefined;
388
378
 
389
379
  response = await client.call('get', apiPath, {
390
- 'content-type': 'application/json',
391
380
  }, payload);
392
381
 
393
382
  if (parseOutput) {
@@ -421,7 +410,6 @@ const healthGetQueueFunctions = async ({threshold,parseOutput = true, overrideFo
421
410
  let response = undefined;
422
411
 
423
412
  response = await client.call('get', apiPath, {
424
- 'content-type': 'application/json',
425
413
  }, payload);
426
414
 
427
415
  if (parseOutput) {
@@ -455,7 +443,6 @@ const healthGetQueueLogs = async ({threshold,parseOutput = true, overrideForCli
455
443
  let response = undefined;
456
444
 
457
445
  response = await client.call('get', apiPath, {
458
- 'content-type': 'application/json',
459
446
  }, payload);
460
447
 
461
448
  if (parseOutput) {
@@ -489,7 +476,6 @@ const healthGetQueueMails = async ({threshold,parseOutput = true, overrideForCli
489
476
  let response = undefined;
490
477
 
491
478
  response = await client.call('get', apiPath, {
492
- 'content-type': 'application/json',
493
479
  }, payload);
494
480
 
495
481
  if (parseOutput) {
@@ -523,7 +509,6 @@ const healthGetQueueMessaging = async ({threshold,parseOutput = true, overrideFo
523
509
  let response = undefined;
524
510
 
525
511
  response = await client.call('get', apiPath, {
526
- 'content-type': 'application/json',
527
512
  }, payload);
528
513
 
529
514
  if (parseOutput) {
@@ -557,7 +542,6 @@ const healthGetQueueMigrations = async ({threshold,parseOutput = true, overrideF
557
542
  let response = undefined;
558
543
 
559
544
  response = await client.call('get', apiPath, {
560
- 'content-type': 'application/json',
561
545
  }, payload);
562
546
 
563
547
  if (parseOutput) {
@@ -591,7 +575,6 @@ const healthGetQueueStatsResources = async ({threshold,parseOutput = true, overr
591
575
  let response = undefined;
592
576
 
593
577
  response = await client.call('get', apiPath, {
594
- 'content-type': 'application/json',
595
578
  }, payload);
596
579
 
597
580
  if (parseOutput) {
@@ -625,41 +608,6 @@ const healthGetQueueUsage = async ({threshold,parseOutput = true, overrideForCli
625
608
  let response = undefined;
626
609
 
627
610
  response = await client.call('get', apiPath, {
628
- 'content-type': 'application/json',
629
- }, payload);
630
-
631
- if (parseOutput) {
632
- parse(response)
633
- }
634
-
635
- return response;
636
-
637
- }
638
-
639
- /**
640
- * @typedef {Object} HealthGetQueueStatsUsageDumpRequestParams
641
- * @property {number} threshold Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.
642
- * @property {boolean} overrideForCli
643
- * @property {boolean} parseOutput
644
- * @property {libClient | undefined} sdk
645
- */
646
-
647
- /**
648
- * @param {HealthGetQueueStatsUsageDumpRequestParams} params
649
- */
650
- const healthGetQueueStatsUsageDump = async ({threshold,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
651
- let client = !sdk ? await sdkForProject() :
652
- sdk;
653
- let apiPath = '/health/queue/stats-usage-dump';
654
- let payload = {};
655
- if (typeof threshold !== 'undefined') {
656
- payload['threshold'] = threshold;
657
- }
658
-
659
- let response = undefined;
660
-
661
- response = await client.call('get', apiPath, {
662
- 'content-type': 'application/json',
663
611
  }, payload);
664
612
 
665
613
  if (parseOutput) {
@@ -693,7 +641,6 @@ const healthGetQueueWebhooks = async ({threshold,parseOutput = true, overrideFor
693
641
  let response = undefined;
694
642
 
695
643
  response = await client.call('get', apiPath, {
696
- 'content-type': 'application/json',
697
644
  }, payload);
698
645
 
699
646
  if (parseOutput) {
@@ -723,7 +670,6 @@ const healthGetStorage = async ({parseOutput = true, overrideForCli = false, sdk
723
670
  let response = undefined;
724
671
 
725
672
  response = await client.call('get', apiPath, {
726
- 'content-type': 'application/json',
727
673
  }, payload);
728
674
 
729
675
  if (parseOutput) {
@@ -753,7 +699,6 @@ const healthGetStorageLocal = async ({parseOutput = true, overrideForCli = false
753
699
  let response = undefined;
754
700
 
755
701
  response = await client.call('get', apiPath, {
756
- 'content-type': 'application/json',
757
702
  }, payload);
758
703
 
759
704
  if (parseOutput) {
@@ -783,7 +728,6 @@ const healthGetTime = async ({parseOutput = true, overrideForCli = false, sdk =
783
728
  let response = undefined;
784
729
 
785
730
  response = await client.call('get', apiPath, {
786
- 'content-type': 'application/json',
787
731
  }, payload);
788
732
 
789
733
  if (parseOutput) {
@@ -899,12 +843,6 @@ health
899
843
  .option(`--threshold <threshold>`, `Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.`, parseInteger)
900
844
  .action(actionRunner(healthGetQueueUsage))
901
845
 
902
- health
903
- .command(`get-queue-stats-usage-dump`)
904
- .description(`Get the number of projects containing metrics that are waiting to be processed in the Appwrite internal queue server.`)
905
- .option(`--threshold <threshold>`, `Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.`, parseInteger)
906
- .action(actionRunner(healthGetQueueStatsUsageDump))
907
-
908
846
  health
909
847
  .command(`get-queue-webhooks`)
910
848
  .description(`Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server.`)
@@ -946,7 +884,6 @@ module.exports = {
946
884
  healthGetQueueMigrations,
947
885
  healthGetQueueStatsResources,
948
886
  healthGetQueueUsage,
949
- healthGetQueueStatsUsageDump,
950
887
  healthGetQueueWebhooks,
951
888
  healthGetStorage,
952
889
  healthGetStorageLocal,
@@ -15,6 +15,7 @@ const { localConfig, globalConfig } = require("../config");
15
15
  const {
16
16
  questionsCreateFunction,
17
17
  questionsCreateFunctionSelectTemplate,
18
+ questionsCreateSite,
18
19
  questionsCreateBucket,
19
20
  questionsCreateMessagingTopic,
20
21
  questionsCreateCollection,
@@ -25,11 +26,13 @@ const {
25
26
  } = require("../questions");
26
27
  const { cliConfig, success, log, hint, error, actionRunner, commandDescriptions } = require("../parser");
27
28
  const { accountGet } = require("./account");
29
+ const { sitesListTemplates } = require("./sites");
28
30
  const { sdkForConsole } = require("../sdks");
29
31
 
30
32
  const initResources = async () => {
31
33
  const actions = {
32
34
  function: initFunction,
35
+ site: initSite,
33
36
  collection: initCollection,
34
37
  bucket: initBucket,
35
38
  team: initTeam,
@@ -318,6 +321,188 @@ const initFunction = async () => {
318
321
  log("Next you can use 'appwrite run function' to develop a function locally. To deploy the function, use 'appwrite push function'");
319
322
  }
320
323
 
324
+ const initSite = async () => {
325
+ process.chdir(localConfig.configDirectoryPath)
326
+
327
+ const answers = await inquirer.prompt(questionsCreateSite);
328
+ const siteFolder = path.join(process.cwd(), 'sites');
329
+
330
+ if (!fs.existsSync(siteFolder)) {
331
+ fs.mkdirSync(siteFolder, {
332
+ recursive: true
333
+ });
334
+ }
335
+
336
+ const siteId = answers.id === 'unique()' ? ID.unique() : answers.id;
337
+ const siteName = answers.name;
338
+ const siteDir = path.join(siteFolder, siteName);
339
+ const templatesDir = path.join(siteFolder, `${siteId}-templates`);
340
+
341
+ if (fs.existsSync(siteDir)) {
342
+ throw new Error(`( ${siteName} ) already exists in the current directory. Please choose another name.`);
343
+ }
344
+
345
+ let templateDetails;
346
+ try {
347
+ const response = await sitesListTemplates({
348
+ frameworks: [answers.framework.key],
349
+ useCases: ['starter'],
350
+ limit: 1,
351
+ parseOutput: false
352
+ });
353
+ if (response.total == 0) {
354
+ throw new Error(`No starter template found for framework ${answers.framework.key}`);
355
+ }
356
+ templateDetails = response.templates[0];
357
+ } catch (error) {
358
+ throw new Error(`Failed to fetch template for framework ${answers.framework.key}: ${error.message}`);
359
+ }
360
+
361
+ fs.mkdirSync(siteDir, "777");
362
+ fs.mkdirSync(templatesDir, "777");
363
+ const repo = `https://github.com/${templateDetails.providerOwner}/${templateDetails.providerRepositoryId}`;
364
+ let selected = { template: templateDetails.frameworks[0].providerRootDirectory };
365
+
366
+ let gitCloneCommands = '';
367
+
368
+ const sparse = selected.template.startsWith('./') ? selected.template.substring(2) : selected.template;
369
+
370
+ log('Fetching site code ...');
371
+
372
+ if(selected.template === './') {
373
+ gitCloneCommands = `
374
+ mkdir -p .
375
+ cd .
376
+ git init
377
+ git remote add origin ${repo}
378
+ git config --global init.defaultBranch main
379
+ git fetch --depth=1 origin refs/tags/$(git ls-remote --tags origin "${templateDetails.providerVersion}" | tail -n 1 | awk -F '/' '{print $3}')
380
+ git checkout FETCH_HEAD
381
+ `.trim();
382
+ } else {
383
+ gitCloneCommands = `
384
+ mkdir -p .
385
+ cd .
386
+ git init
387
+ git remote add origin ${repo}
388
+ git config --global init.defaultBranch main
389
+ git config core.sparseCheckout true
390
+ echo "${sparse}" >> .git/info/sparse-checkout
391
+ git config --add remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
392
+ git config remote.origin.tagopt --no-tags
393
+ git fetch --depth=1 origin refs/tags/$(git ls-remote --tags origin "${templateDetails.providerVersion}" | tail -n 1 | awk -F '/' '{print $3}')
394
+ git checkout FETCH_HEAD
395
+ `.trim();
396
+ }
397
+
398
+ /* Force use CMD as powershell does not support && */
399
+ if (process.platform === 'win32') {
400
+ gitCloneCommands = 'cmd /c "' + gitCloneCommands + '"';
401
+ }
402
+
403
+ /* Execute the child process but do not print any std output */
404
+ try {
405
+ childProcess.execSync(gitCloneCommands, { stdio: 'pipe', cwd: templatesDir });
406
+ } catch (error) {
407
+ /* Specialised errors with recommended actions to take */
408
+ if (error.message.includes('error: unknown option')) {
409
+ throw new Error(`${error.message} \n\nSuggestion: Try updating your git to the latest version, then trying to run this command again.`)
410
+ } else if (error.message.includes('is not recognized as an internal or external command,') || error.message.includes('command not found')) {
411
+ throw new Error(`${error.message} \n\nSuggestion: It appears that git is not installed, try installing git then trying to run this command again.`)
412
+ } else {
413
+ throw error;
414
+ }
415
+ }
416
+
417
+ fs.rmSync(path.join(templatesDir, ".git"), { recursive: true });
418
+
419
+ const copyRecursiveSync = (src, dest) => {
420
+ let exists = fs.existsSync(src);
421
+ let stats = exists && fs.statSync(src);
422
+ let isDirectory = exists && stats.isDirectory();
423
+ if (isDirectory) {
424
+ if (!fs.existsSync(dest)) {
425
+ fs.mkdirSync(dest);
426
+ }
427
+
428
+ fs.readdirSync(src).forEach(function (childItemName) {
429
+ copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
430
+ });
431
+ } else {
432
+ fs.copyFileSync(src, dest);
433
+ }
434
+ };
435
+ copyRecursiveSync(selected.template === './' ? templatesDir : path.join(templatesDir, selected.template), siteDir);
436
+
437
+ fs.rmSync(templatesDir, { recursive: true, force: true });
438
+
439
+ const readmePath = path.join(process.cwd(), 'sites', siteName, 'README.md');
440
+ const readmeFile = fs.readFileSync(readmePath).toString();
441
+ const newReadmeFile = readmeFile.split('\n');
442
+ newReadmeFile[0] = `# ${answers.key}`;
443
+ newReadmeFile.splice(1, 2);
444
+ fs.writeFileSync(readmePath, newReadmeFile.join('\n'));
445
+
446
+ let vars = (templateDetails.variables ?? []).map(variable => {
447
+ let value = variable.value;
448
+ const replacements = {
449
+ '{apiEndpoint}': globalConfig.getEndpoint(),
450
+ '{projectId}': localConfig.getProject().projectId,
451
+ '{projectName}': localConfig.getProject().projectName,
452
+ };
453
+
454
+ for (const placeholder in replacements) {
455
+ if (value?.includes(placeholder)) {
456
+ value = value.replace(placeholder, replacements[placeholder]);
457
+ }
458
+ }
459
+
460
+ return {
461
+ key: variable.name,
462
+ value: value
463
+ };
464
+ });
465
+
466
+ let data = {
467
+ $id: siteId,
468
+ name: answers.name,
469
+ framework: answers.framework.key,
470
+ adapter: templateDetails.frameworks[0].adapter || '',
471
+ buildRuntime: templateDetails.frameworks[0].buildRuntime || '',
472
+ installCommand: templateDetails.frameworks[0].installCommand || '',
473
+ buildCommand: templateDetails.frameworks[0].buildCommand || '',
474
+ outputDirectory: templateDetails.frameworks[0].outputDirectory || '',
475
+ fallbackFile: templateDetails.frameworks[0].fallbackFile || '',
476
+ specification: answers.specification,
477
+ enabled: true,
478
+ timeout: 30,
479
+ logging: true,
480
+ ignore: answers.framework.ignore || null,
481
+ path: `sites/${siteName}`,
482
+ vars: vars
483
+ };
484
+
485
+ if (!data.buildRuntime) {
486
+ log(`Build runtime for this framework not found. You will be asked to configure build runtime when you first push the site.`);
487
+ }
488
+
489
+ if (!data.installCommand) {
490
+ log(`Installation command for this framework not found. You will be asked to configure the install command when you first push the site.`);
491
+ }
492
+
493
+ if (!data.buildCommand) {
494
+ log(`Build command for this framework not found. You will be asked to configure the build command when you first push the site.`);
495
+ }
496
+
497
+ if (!data.outputDirectory) {
498
+ log(`Output directory for this framework not found. You will be asked to configure the output directory when you first push the site.`);
499
+ }
500
+
501
+ localConfig.addSite(data);
502
+ success("Initializing site");
503
+ log("Next you can use 'appwrite push site' to deploy the changes.");
504
+ };
505
+
321
506
  const init = new Command("init")
322
507
  .description(commandDescriptions['init'])
323
508
  .action(actionRunner(initResources));
@@ -336,6 +521,12 @@ init
336
521
  .description("Init a new Appwrite function")
337
522
  .action(actionRunner(initFunction));
338
523
 
524
+ init
525
+ .command("site")
526
+ .alias("sites")
527
+ .description("Init a new Appwrite site")
528
+ .action(actionRunner(initSite));
529
+
339
530
  init
340
531
  .command("bucket")
341
532
  .alias("buckets")
@@ -58,7 +58,6 @@ const localeGet = async ({parseOutput = true, overrideForCli = false, sdk = unde
58
58
  let response = undefined;
59
59
 
60
60
  response = await client.call('get', apiPath, {
61
- 'content-type': 'application/json',
62
61
  }, payload);
63
62
 
64
63
  if (parseOutput) {
@@ -88,7 +87,6 @@ const localeListCodes = async ({parseOutput = true, overrideForCli = false, sdk
88
87
  let response = undefined;
89
88
 
90
89
  response = await client.call('get', apiPath, {
91
- 'content-type': 'application/json',
92
90
  }, payload);
93
91
 
94
92
  if (parseOutput) {
@@ -118,7 +116,6 @@ const localeListContinents = async ({parseOutput = true, overrideForCli = false,
118
116
  let response = undefined;
119
117
 
120
118
  response = await client.call('get', apiPath, {
121
- 'content-type': 'application/json',
122
119
  }, payload);
123
120
 
124
121
  if (parseOutput) {
@@ -148,7 +145,6 @@ const localeListCountries = async ({parseOutput = true, overrideForCli = false,
148
145
  let response = undefined;
149
146
 
150
147
  response = await client.call('get', apiPath, {
151
- 'content-type': 'application/json',
152
148
  }, payload);
153
149
 
154
150
  if (parseOutput) {
@@ -178,7 +174,6 @@ const localeListCountriesEU = async ({parseOutput = true, overrideForCli = false
178
174
  let response = undefined;
179
175
 
180
176
  response = await client.call('get', apiPath, {
181
- 'content-type': 'application/json',
182
177
  }, payload);
183
178
 
184
179
  if (parseOutput) {
@@ -208,7 +203,6 @@ const localeListCountriesPhones = async ({parseOutput = true, overrideForCli = f
208
203
  let response = undefined;
209
204
 
210
205
  response = await client.call('get', apiPath, {
211
- 'content-type': 'application/json',
212
206
  }, payload);
213
207
 
214
208
  if (parseOutput) {
@@ -238,7 +232,6 @@ const localeListCurrencies = async ({parseOutput = true, overrideForCli = false,
238
232
  let response = undefined;
239
233
 
240
234
  response = await client.call('get', apiPath, {
241
- 'content-type': 'application/json',
242
235
  }, payload);
243
236
 
244
237
  if (parseOutput) {
@@ -268,7 +261,6 @@ const localeListLanguages = async ({parseOutput = true, overrideForCli = false,
268
261
  let response = undefined;
269
262
 
270
263
  response = await client.call('get', apiPath, {
271
- 'content-type': 'application/json',
272
264
  }, payload);
273
265
 
274
266
  if (parseOutput) {