appwrite-cli 13.0.0 → 13.0.1

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 (54) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +3 -3
  3. package/dist/bundle.cjs +49824 -48429
  4. package/dist/lib/client.d.ts.map +1 -1
  5. package/dist/lib/client.js +3 -4
  6. package/dist/lib/client.js.map +1 -1
  7. package/dist/lib/commands/config.d.ts +90 -1
  8. package/dist/lib/commands/config.d.ts.map +1 -1
  9. package/dist/lib/commands/config.js +5 -4
  10. package/dist/lib/commands/config.js.map +1 -1
  11. package/dist/lib/commands/pull.d.ts.map +1 -1
  12. package/dist/lib/commands/pull.js +15 -9
  13. package/dist/lib/commands/pull.js.map +1 -1
  14. package/dist/lib/commands/push.d.ts.map +1 -1
  15. package/dist/lib/commands/push.js +8 -5
  16. package/dist/lib/commands/push.js.map +1 -1
  17. package/dist/lib/commands/services/projects.js +7 -1
  18. package/dist/lib/commands/services/projects.js.map +1 -1
  19. package/dist/lib/commands/services/storage.js +2 -2
  20. package/dist/lib/commands/services/storage.js.map +1 -1
  21. package/dist/lib/commands/utils/attributes.d.ts +5 -2
  22. package/dist/lib/commands/utils/attributes.d.ts.map +1 -1
  23. package/dist/lib/commands/utils/attributes.js +16 -7
  24. package/dist/lib/commands/utils/attributes.js.map +1 -1
  25. package/dist/lib/config.d.ts.map +1 -1
  26. package/dist/lib/config.js +9 -10
  27. package/dist/lib/config.js.map +1 -1
  28. package/dist/lib/constants.d.ts +1 -1
  29. package/dist/lib/constants.js +1 -1
  30. package/dist/lib/json.d.ts +8 -0
  31. package/dist/lib/json.d.ts.map +1 -0
  32. package/dist/lib/json.js +25 -0
  33. package/dist/lib/json.js.map +1 -0
  34. package/dist/lib/utils.d.ts +10 -1
  35. package/dist/lib/utils.d.ts.map +1 -1
  36. package/dist/lib/utils.js +19 -177
  37. package/dist/lib/utils.js.map +1 -1
  38. package/dist/package.json +3 -2
  39. package/docs/examples/projects/update-labels.md +3 -0
  40. package/install.ps1 +2 -2
  41. package/install.sh +1 -1
  42. package/lib/client.ts +3 -5
  43. package/lib/commands/config.ts +36 -32
  44. package/lib/commands/pull.ts +30 -9
  45. package/lib/commands/push.ts +9 -5
  46. package/lib/commands/services/projects.ts +13 -1
  47. package/lib/commands/services/storage.ts +2 -2
  48. package/lib/commands/utils/attributes.ts +19 -8
  49. package/lib/config.ts +9 -11
  50. package/lib/constants.ts +1 -1
  51. package/lib/json.ts +28 -0
  52. package/lib/utils.ts +25 -232
  53. package/package.json +3 -2
  54. package/scoop/appwrite.config.json +3 -3
@@ -482,14 +482,14 @@ export class Attributes {
482
482
 
483
483
  /**
484
484
  * Filter deleted and recreated attributes,
485
- * return list of attributes to create
485
+ * return list of attributes to create and whether any changes were made
486
486
  */
487
487
  public attributesToCreate = async (
488
488
  remoteAttributes: any[],
489
489
  localAttributes: any[],
490
490
  collection: Collection,
491
491
  isIndex: boolean = false,
492
- ): Promise<any[]> => {
492
+ ): Promise<{ attributes: any[]; hasChanges: boolean }> => {
493
493
  const deleting = remoteAttributes
494
494
  .filter(
495
495
  (attribute) => !this.attributesContains(attribute, localAttributes),
@@ -527,7 +527,7 @@ export class Attributes {
527
527
  let changedAttributes: any[] = [];
528
528
  const changing = [...deleting, ...adding, ...conflicts, ...changes];
529
529
  if (changing.length === 0) {
530
- return changedAttributes;
530
+ return { attributes: changedAttributes, hasChanges: false };
531
531
  }
532
532
 
533
533
  log(
@@ -573,7 +573,7 @@ export class Attributes {
573
573
  }
574
574
 
575
575
  if ((await this.getConfirmation()) !== true) {
576
- return changedAttributes;
576
+ return { attributes: changedAttributes, hasChanges: false };
577
577
  }
578
578
  }
579
579
 
@@ -631,9 +631,10 @@ export class Attributes {
631
631
  }
632
632
  }
633
633
 
634
- return localAttributes.filter(
634
+ const newAttributes = localAttributes.filter(
635
635
  (attribute) => !this.attributesContains(attribute, remoteAttributes),
636
636
  );
637
+ return { attributes: newAttributes, hasChanges: true };
637
638
  };
638
639
 
639
640
  public createIndexes = async (
@@ -664,13 +665,17 @@ export class Attributes {
664
665
  throw new Error("Index creation timed out.");
665
666
  }
666
667
 
667
- success(`Created ${indexes.length} indexes`);
668
+ if (indexes.length > 0) {
669
+ success(`Created ${indexes.length} indexes`);
670
+ }
668
671
  };
669
672
 
670
673
  public createAttributes = async (
671
674
  attributes: any[],
672
675
  collection: Collection,
673
676
  ): Promise<void> => {
677
+ log(`Creating attributes ...`);
678
+
674
679
  for (let attribute of attributes) {
675
680
  if (attribute.side !== "child") {
676
681
  await this.createAttribute(
@@ -694,13 +699,17 @@ export class Attributes {
694
699
  }
695
700
 
696
701
  const createdCount = attributes.filter((a) => a.side !== "child").length;
697
- success(`Created ${createdCount} attributes`);
702
+ if (createdCount > 0) {
703
+ success(`Created ${createdCount} attributes`);
704
+ }
698
705
  };
699
706
 
700
707
  public createColumns = async (
701
708
  columns: any[],
702
709
  table: Collection,
703
710
  ): Promise<void> => {
711
+ log(`Creating columns ...`);
712
+
704
713
  for (let column of columns) {
705
714
  if (column.side !== "child") {
706
715
  await this.createAttribute(table["databaseId"], table["$id"], column);
@@ -720,6 +729,8 @@ export class Attributes {
720
729
  }
721
730
 
722
731
  const createdCount = columns.filter((c) => c.side !== "child").length;
723
- success(`Created ${createdCount} columns`);
732
+ if (createdCount > 0) {
733
+ success(`Created ${createdCount} columns`);
734
+ }
724
735
  };
725
736
  }
package/lib/config.ts CHANGED
@@ -2,7 +2,6 @@ import os from "os";
2
2
  import fs from "fs";
3
3
  import _path from "path";
4
4
  import process from "process";
5
- import JSONbig from "json-bigint";
6
5
  import type { Models } from "@appwrite.io/console";
7
6
  import type {
8
7
  BucketType,
@@ -22,9 +21,8 @@ import type {
22
21
  GlobalConfigData,
23
22
  } from "./types.js";
24
23
  import { createSettingsObject } from "./utils.js";
25
- import { SDK_TITLE_LOWER } from "./constants.js";
26
-
27
- const JSONBigInt = JSONbig({ useNativeBigInt: true });
24
+ import { EXECUTABLE_NAME } from "./constants.js";
25
+ import { JSONBig } from "./json.js";
28
26
 
29
27
  const KeysVars = new Set(["key", "value"]);
30
28
  const KeysSite = new Set([
@@ -235,7 +233,7 @@ class Config<T extends ConfigData = ConfigData> {
235
233
  read(): void {
236
234
  try {
237
235
  const file = fs.readFileSync(this.path).toString();
238
- this.data = JSONBigInt.parse(file);
236
+ this.data = JSONBig.parse(file);
239
237
  } catch (e) {
240
238
  this.data = {} as T;
241
239
  }
@@ -246,7 +244,7 @@ class Config<T extends ConfigData = ConfigData> {
246
244
  if (!fs.existsSync(dir)) {
247
245
  fs.mkdirSync(dir, { recursive: true });
248
246
  }
249
- fs.writeFileSync(this.path, JSONBigInt.stringify(this.data, null, 4), {
247
+ fs.writeFileSync(this.path, JSONBig.stringify(this.data, null, 4), {
250
248
  mode: 0o600,
251
249
  });
252
250
  }
@@ -285,7 +283,7 @@ class Config<T extends ConfigData = ConfigData> {
285
283
  }
286
284
 
287
285
  toString(): string {
288
- return JSONBigInt.stringify(this.data, null, 4);
286
+ return JSONBig.stringify(this.data, null, 4);
289
287
  }
290
288
 
291
289
  protected _getDBEntities(entityType: string): Entity[] {
@@ -342,8 +340,8 @@ class Config<T extends ConfigData = ConfigData> {
342
340
  }
343
341
 
344
342
  class Local extends Config<ConfigType> {
345
- static CONFIG_FILE_PATH = `${SDK_TITLE_LOWER}.config.json`;
346
- static CONFIG_FILE_PATH_LEGACY = `${SDK_TITLE_LOWER}.json`;
343
+ static CONFIG_FILE_PATH = `${EXECUTABLE_NAME}.config.json`;
344
+ static CONFIG_FILE_PATH_LEGACY = `${EXECUTABLE_NAME}.json`;
347
345
  configDirectoryPath = "";
348
346
 
349
347
  constructor(
@@ -367,7 +365,7 @@ class Local extends Config<ConfigType> {
367
365
  fs.mkdirSync(dir, { recursive: true });
368
366
  }
369
367
  const orderedData = orderConfigKeys(this.data);
370
- fs.writeFileSync(this.path, JSONBigInt.stringify(orderedData, null, 4), {
368
+ fs.writeFileSync(this.path, JSONBig.stringify(orderedData, null, 4), {
371
369
  mode: 0o600,
372
370
  });
373
371
  }
@@ -774,7 +772,7 @@ class Local extends Config<ConfigType> {
774
772
  }
775
773
 
776
774
  class Global extends Config<GlobalConfigData> {
777
- static CONFIG_FILE_PATH = `.${SDK_TITLE_LOWER}/prefs.json`;
775
+ static CONFIG_FILE_PATH = `.${EXECUTABLE_NAME}/prefs.json`;
778
776
 
779
777
  static PREFERENCE_CURRENT = "current" as const;
780
778
  static PREFERENCE_ENDPOINT = "endpoint" as const;
package/lib/constants.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // SDK
2
2
  export const SDK_TITLE = 'Appwrite';
3
3
  export const SDK_TITLE_LOWER = 'appwrite';
4
- export const SDK_VERSION = '13.0.0';
4
+ export const SDK_VERSION = '13.0.1';
5
5
  export const SDK_NAME = 'Command Line';
6
6
  export const SDK_PLATFORM = 'console';
7
7
  export const SDK_LANGUAGE = 'cli';
package/lib/json.ts ADDED
@@ -0,0 +1,28 @@
1
+ import JSONbigModule from "json-bigint";
2
+ import { BigNumber } from "bignumber.js";
3
+
4
+ const JSONbigParser = JSONbigModule({ storeAsString: false });
5
+ const JSONbigSerializer = JSONbigModule({ useNativeBigInt: true });
6
+
7
+ const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);
8
+ const MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);
9
+
10
+ function reviver(_key: string, value: any): any {
11
+ if (BigNumber.isBigNumber(value)) {
12
+ if (value.isInteger()) {
13
+ const str = value.toFixed();
14
+ const bi = BigInt(str);
15
+ if (bi >= MIN_SAFE && bi <= MAX_SAFE) {
16
+ return Number(str);
17
+ }
18
+ return bi;
19
+ }
20
+ return value.toNumber();
21
+ }
22
+ return value;
23
+ }
24
+
25
+ export const JSONBig = {
26
+ parse: (text: string) => JSONbigParser.parse(text, reviver),
27
+ stringify: JSONbigSerializer.stringify,
28
+ };
package/lib/utils.ts CHANGED
@@ -5,6 +5,7 @@ import childProcess from "child_process";
5
5
  import chalk from "chalk";
6
6
  import { fetch } from "undici";
7
7
  import type { Models } from "@appwrite.io/console";
8
+ import { z } from "zod";
8
9
  import { localConfig, globalConfig } from "./config.js";
9
10
  import type { SettingsType } from "./commands/config.js";
10
11
  import { NPM_REGISTRY_URL, DEFAULT_ENDPOINT } from "./constants.js";
@@ -154,240 +155,32 @@ export const checkDeployConditions = (localConfig: any): void => {
154
155
  }
155
156
  };
156
157
 
157
- export function showConsoleLink(
158
- serviceName: string,
159
- action: string,
160
- ...ids: string[]
161
- ): void {
162
- const projectId = localConfig.getProject().projectId;
163
-
164
- const url = new URL(globalConfig.getEndpoint().replace("/v1", "/console"));
165
- url.pathname += `/project-${projectId}`;
166
- action = action.toLowerCase();
167
-
168
- switch (serviceName) {
169
- case "account":
170
- url.pathname = url.pathname.replace(`/project-${projectId}`, "");
171
- url.pathname += getAccountPath(action);
172
- break;
173
- case "databases":
174
- url.pathname += getDatabasePath(action, ids);
175
- break;
176
- case "functions":
177
- url.pathname += getFunctionsPath(action, ids);
178
- break;
179
- case "messaging":
180
- url.pathname += getMessagingPath(action, ids);
181
- break;
182
- case "projects":
183
- url.pathname = url.pathname.replace(`/project-${projectId}`, "");
184
- url.pathname += getProjectsPath(action, ids);
185
- break;
186
- case "storage":
187
- url.pathname += getBucketsPath(action, ids);
188
- break;
189
- case "teams":
190
- url.pathname += getTeamsPath(action, ids);
191
- break;
192
- case "organizations":
193
- url.pathname += getOrganizationsPath(action, ids);
194
- break;
195
- case "users":
196
- url.pathname += getUsersPath(action, ids);
197
- break;
198
- default:
199
- return;
200
- }
201
-
202
- console.log(
203
- `${chalk.green.bold("✓ Success:")} ${chalk.green(url.toString())}`,
204
- );
205
- }
206
-
207
- function getAccountPath(action: string): string {
208
- let path = "/account";
209
-
210
- if (action === "listsessions") {
211
- path += "/sessions";
212
- }
213
-
214
- return path;
215
- }
216
-
217
- function getDatabasePath(action: string, ids: string[]): string {
218
- let path = "/databases";
219
-
220
- if (
221
- [
222
- "get",
223
- "listcollections",
224
- "getcollection",
225
- "listattributes",
226
- "listdocuments",
227
- "getdocument",
228
- "listindexes",
229
- "getdatabaseusage",
230
- ].includes(action)
231
- ) {
232
- path += `/database-${ids[0]}`;
233
- }
234
-
235
- if (action === "getdatabaseusage") {
236
- path += `/usage`;
237
- }
238
-
239
- if (
240
- [
241
- "getcollection",
242
- "listattributes",
243
- "listdocuments",
244
- "getdocument",
245
- "listindexes",
246
- ].includes(action)
247
- ) {
248
- path += `/collection-${ids[1]}`;
249
- }
250
-
251
- if (action === "listattributes") {
252
- path += "/attributes";
253
- }
254
- if (action === "listindexes") {
255
- path += "/indexes";
256
- }
257
- if (action === "getdocument") {
258
- path += `/document-${ids[2]}`;
259
- }
260
-
261
- return path;
262
- }
263
-
264
- function getFunctionsPath(action: string, ids: string[]): string {
265
- let path = "/functions";
266
-
267
- if (action !== "list") {
268
- path += `/function-${ids[0]}`;
269
- }
270
-
271
- if (action === "getdeployment") {
272
- path += `/deployment-${ids[1]}`;
273
- }
274
-
275
- if (action === "getexecution" || action === "listexecution") {
276
- path += `/executions`;
277
- }
278
- if (action === "getfunctionusage") {
279
- path += `/usage`;
280
- }
281
-
282
- return path;
283
- }
284
-
285
- function getMessagingPath(action: string, ids: string[]): string {
286
- let path = "/messaging";
287
-
288
- if (["getmessage", "listmessagelogs"].includes(action)) {
289
- path += `/message-${ids[0]}`;
290
- }
291
-
292
- if (["listproviders", "getprovider"].includes(action)) {
293
- path += `/providers`;
294
- }
295
-
296
- if (action === "getprovider") {
297
- path += `/provider-${ids[0]}`;
298
- }
299
-
300
- if (["listtopics", "gettopic"].includes(action)) {
301
- path += `/topics`;
302
- }
303
-
304
- if (action === "gettopic") {
305
- path += `/topic-${ids[0]}`;
306
- }
307
-
308
- return path;
309
- }
310
-
311
- function getProjectsPath(action: string, ids: string[]): string {
312
- let path = "";
313
-
314
- if (action !== "list") {
315
- path += `/project-${ids[0]}`;
316
- }
317
-
318
- if (["listkeys", "getkey"].includes(action)) {
319
- path += "/overview/keys";
320
- }
321
-
322
- if (["listplatforms", "getplatform"].includes(action)) {
323
- path += "/overview/platforms";
324
- }
325
-
326
- if (["listwebhooks", "getwebhook"].includes(action)) {
327
- path += "/settings/webhooks";
328
- }
329
-
330
- if (["getplatform", "getkey", "getwebhook"].includes(action)) {
331
- path += `/${ids[1]}`;
332
- }
333
-
334
- return path;
335
- }
336
-
337
- function getBucketsPath(action: string, ids: string[]): string {
338
- let path = "/storage";
339
-
340
- if (action !== "listbuckets") {
341
- path += `/bucket-${ids[0]}`;
342
- }
343
-
344
- if (action === "getbucketusage") {
345
- path += `/usage`;
346
- }
347
-
348
- if (action === "getfile") {
349
- path += `/file-${ids[1]}`;
350
- }
351
-
352
- return path;
353
- }
354
-
355
- function getTeamsPath(action: string, ids: string[]): string {
356
- let path = "/auth/teams";
357
-
358
- if (action !== "list") {
359
- path += `/team-${ids[0]}`;
360
- }
361
-
362
- return path;
363
- }
364
-
365
- function getOrganizationsPath(action: string, ids: string[]): string {
366
- let path = `/organization-${ids[0]}`;
367
-
368
- if (action === "list") {
369
- path = "/account/organizations";
370
- }
371
-
372
- return path;
373
- }
374
-
375
- function getUsersPath(action: string, ids: string[]): string {
376
- let path = "/auth";
377
-
378
- if (action !== "list") {
379
- path += `/user-${ids[0]}`;
380
- }
381
-
382
- if (action === "listsessions") {
383
- path += "sessions";
384
- }
385
-
386
- return path;
387
- }
388
-
389
158
  export function isCloud(): boolean {
390
159
  const endpoint = globalConfig.getEndpoint() || DEFAULT_ENDPOINT;
391
160
  const hostname = new URL(endpoint).hostname;
392
161
  return hostname.endsWith("appwrite.io");
393
162
  }
163
+
164
+ /**
165
+ * Filters an object to only include fields defined in a Zod object schema.
166
+ * Uses the schema's shape to determine allowed keys.
167
+ *
168
+ * @param data - The data to filter
169
+ * @param schema - A Zod object schema with a shape property
170
+ * @returns The filtered data with only schema-defined fields
171
+ */
172
+ export function filterBySchema<T extends z.ZodObject<z.ZodRawShape>>(
173
+ data: Record<string, unknown>,
174
+ schema: T,
175
+ ): z.infer<T> {
176
+ const allowedKeys = Object.keys(schema.shape);
177
+ const result: Record<string, unknown> = {};
178
+
179
+ for (const key of allowedKeys) {
180
+ if (key in data) {
181
+ result[key] = data[key];
182
+ }
183
+ }
184
+
185
+ return result as z.infer<T>;
186
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "type": "module",
4
4
  "homepage": "https://appwrite.io/support",
5
5
  "description": "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API",
6
- "version": "13.0.0",
6
+ "version": "13.0.1",
7
7
  "license": "BSD-3-Clause",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -28,7 +28,8 @@
28
28
  "windows-arm64": "bun run build && esbuild dist/cli.js --bundle --platform=node --format=cjs --outfile=dist/bundle.cjs --external:@appwrite.io/console --external:fsevents && pkg dist/bundle.cjs -t node18-win-arm64 -o build/appwrite-cli-win-arm64.exe"
29
29
  },
30
30
  "dependencies": {
31
- "@appwrite.io/console": "^2.1.0",
31
+ "@appwrite.io/console": "^2.1.3",
32
+ "bignumber.js": "^9.0.0",
32
33
  "chalk": "4.1.2",
33
34
  "chokidar": "^3.6.0",
34
35
  "cli-progress": "^3.12.0",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
3
- "version": "13.0.0",
3
+ "version": "13.0.1",
4
4
  "description": "The Appwrite CLI is a command-line application that allows you to interact with Appwrite and perform server-side tasks using your terminal.",
5
5
  "homepage": "https://github.com/appwrite/sdk-for-cli",
6
6
  "license": "BSD-3-Clause",
7
7
  "architecture": {
8
8
  "64bit": {
9
- "url": "https://github.com/appwrite/sdk-for-cli/releases/download/13.0.0/appwrite-cli-win-x64.exe",
9
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/13.0.1/appwrite-cli-win-x64.exe",
10
10
  "bin": [
11
11
  [
12
12
  "appwrite-cli-win-x64.exe",
@@ -15,7 +15,7 @@
15
15
  ]
16
16
  },
17
17
  "arm64": {
18
- "url": "https://github.com/appwrite/sdk-for-cli/releases/download/13.0.0/appwrite-cli-win-arm64.exe",
18
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/13.0.1/appwrite-cli-win-arm64.exe",
19
19
  "bin": [
20
20
  [
21
21
  "appwrite-cli-win-arm64.exe",