appwrite-cli 13.6.0 → 13.6.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 (75) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +2 -2
  3. package/cli.ts +3 -3
  4. package/dist/bundle-win-arm64.mjs +336 -212
  5. package/dist/cli.cjs +336 -212
  6. package/dist/index.cjs +156 -104
  7. package/dist/index.js +156 -104
  8. package/dist/lib/commands/config-validations.d.ts +1 -1
  9. package/dist/lib/commands/config-validations.d.ts.map +1 -1
  10. package/dist/lib/commands/errors.d.ts +4 -4
  11. package/dist/lib/commands/errors.d.ts.map +1 -1
  12. package/dist/lib/commands/generate.d.ts.map +1 -1
  13. package/dist/lib/commands/generators/base.d.ts +5 -0
  14. package/dist/lib/commands/generators/base.d.ts.map +1 -1
  15. package/dist/lib/commands/generic.d.ts.map +1 -1
  16. package/dist/lib/commands/init.d.ts.map +1 -1
  17. package/dist/lib/commands/run.d.ts.map +1 -1
  18. package/dist/lib/commands/types.d.ts.map +1 -1
  19. package/dist/lib/commands/update.d.ts.map +1 -1
  20. package/dist/lib/commands/utils/change-approval.d.ts +3 -3
  21. package/dist/lib/commands/utils/change-approval.d.ts.map +1 -1
  22. package/dist/lib/commands/utils/database-sync.d.ts.map +1 -1
  23. package/dist/lib/commands/utils/deployment.d.ts +16 -4
  24. package/dist/lib/commands/utils/deployment.d.ts.map +1 -1
  25. package/dist/lib/commands/utils/pools.d.ts.map +1 -1
  26. package/dist/lib/constants.d.ts +1 -1
  27. package/dist/lib/emulation/docker.d.ts.map +1 -1
  28. package/dist/lib/json.d.ts +1 -1
  29. package/dist/lib/json.d.ts.map +1 -1
  30. package/dist/lib/paginate.d.ts +5 -6
  31. package/dist/lib/paginate.d.ts.map +1 -1
  32. package/dist/lib/parser.d.ts +5 -4
  33. package/dist/lib/parser.d.ts.map +1 -1
  34. package/dist/lib/spinner.d.ts +1 -1
  35. package/dist/lib/spinner.d.ts.map +1 -1
  36. package/dist/lib/utils.d.ts +6 -1
  37. package/dist/lib/utils.d.ts.map +1 -1
  38. package/dist/lib/validations.d.ts +1 -1
  39. package/dist/lib/validations.d.ts.map +1 -1
  40. package/eslint.config.js +45 -0
  41. package/install.ps1 +2 -2
  42. package/install.sh +1 -1
  43. package/lib/client.ts +3 -3
  44. package/lib/commands/config-validations.ts +1 -1
  45. package/lib/commands/config.ts +2 -2
  46. package/lib/commands/errors.ts +2 -2
  47. package/lib/commands/generate.ts +8 -6
  48. package/lib/commands/generators/base.ts +6 -0
  49. package/lib/commands/generators/typescript/databases.ts +9 -9
  50. package/lib/commands/generators/typescript/templates/databases.ts.hbs +16 -16
  51. package/lib/commands/generic.ts +21 -16
  52. package/lib/commands/init.ts +147 -61
  53. package/lib/commands/pull.ts +1 -1
  54. package/lib/commands/push.ts +19 -19
  55. package/lib/commands/run.ts +15 -9
  56. package/lib/commands/types.ts +18 -8
  57. package/lib/commands/update.ts +24 -16
  58. package/lib/commands/utils/attributes.ts +6 -6
  59. package/lib/commands/utils/change-approval.ts +26 -19
  60. package/lib/commands/utils/database-sync.ts +58 -18
  61. package/lib/commands/utils/deployment.ts +22 -5
  62. package/lib/commands/utils/pools.ts +11 -5
  63. package/lib/config.ts +1 -1
  64. package/lib/constants.ts +1 -1
  65. package/lib/emulation/docker.ts +5 -6
  66. package/lib/emulation/utils.ts +2 -2
  67. package/lib/json.ts +15 -7
  68. package/lib/paginate.ts +30 -20
  69. package/lib/parser.ts +46 -15
  70. package/lib/questions.ts +38 -38
  71. package/lib/spinner.ts +5 -1
  72. package/lib/utils.ts +15 -3
  73. package/lib/validations.ts +1 -1
  74. package/package.json +7 -1
  75. package/scoop/appwrite.config.json +3 -3
@@ -1,4 +1,5 @@
1
1
  import chalk from "chalk";
2
+ import { AppwriteException } from "@appwrite.io/console";
2
3
  import { localConfig } from "../../config.js";
3
4
  import { log, success, error, drawTable } from "../../parser.js";
4
5
  import { paginate } from "../../paginate.js";
@@ -10,6 +11,39 @@ export interface TablesDBChangesResult {
10
11
  resyncNeeded: boolean;
11
12
  }
12
13
 
14
+ interface TablesDBResource {
15
+ $id: string;
16
+ name: string;
17
+ enabled: boolean;
18
+ }
19
+
20
+ const isTablesDBResource = (value: unknown): value is TablesDBResource => {
21
+ if (!value || typeof value !== "object") {
22
+ return false;
23
+ }
24
+
25
+ return (
26
+ "$id" in value &&
27
+ typeof value.$id === "string" &&
28
+ "name" in value &&
29
+ typeof value.name === "string" &&
30
+ "enabled" in value &&
31
+ typeof value.enabled === "boolean"
32
+ );
33
+ };
34
+
35
+ const getSyncErrorMessage = (err: unknown): string => {
36
+ if (err instanceof AppwriteException) {
37
+ return err.message;
38
+ }
39
+
40
+ if (err instanceof Error) {
41
+ return err.message;
42
+ }
43
+
44
+ return String(err);
45
+ };
46
+
13
47
  /**
14
48
  * Check for and apply changes to tablesDB (databases)
15
49
  * Handles creation, update, and deletion of databases
@@ -18,29 +52,37 @@ export const checkAndApplyTablesDBChanges =
18
52
  async (): Promise<TablesDBChangesResult> => {
19
53
  log("Checking for tablesDB changes ...");
20
54
 
21
- const localTablesDBs = localConfig.getTablesDBs();
22
- const { databases: remoteTablesDBs } = await paginate(
23
- async (args: any) => {
55
+ const localTablesDBs: TablesDBResource[] = localConfig.getTablesDBs();
56
+ const paginatedResult = await paginate(
57
+ async (args) => {
24
58
  const tablesDBService = await getTablesDBService();
25
- return await tablesDBService.list(args.queries || []);
59
+ const queries = Array.isArray(args.queries)
60
+ ? args.queries.filter(
61
+ (query): query is string => typeof query === "string",
62
+ )
63
+ : [];
64
+ return await tablesDBService.list(queries);
26
65
  },
27
66
  {},
28
67
  100,
29
68
  "databases",
30
69
  );
70
+ const remoteTablesDBs = Array.isArray(paginatedResult.databases)
71
+ ? paginatedResult.databases.filter(isTablesDBResource)
72
+ : [];
31
73
 
32
74
  if (localTablesDBs.length === 0 && remoteTablesDBs.length === 0) {
33
75
  return { applied: false, resyncNeeded: false };
34
76
  }
35
77
 
36
- const changes: any[] = [];
37
- const toCreate: any[] = [];
38
- const toUpdate: any[] = [];
39
- const toDelete: any[] = [];
78
+ const changes: Array<Record<string, unknown>> = [];
79
+ const toCreate: TablesDBResource[] = [];
80
+ const toUpdate: TablesDBResource[] = [];
81
+ const toDelete: TablesDBResource[] = [];
40
82
 
41
83
  // Check for deletions - remote DBs that aren't in local config
42
84
  for (const remoteDB of remoteTablesDBs) {
43
- const localDB = localTablesDBs.find((db: any) => db.$id === remoteDB.$id);
85
+ const localDB = localTablesDBs.find((db) => db.$id === remoteDB.$id);
44
86
  if (!localDB) {
45
87
  toDelete.push(remoteDB);
46
88
  changes.push({
@@ -55,9 +97,7 @@ export const checkAndApplyTablesDBChanges =
55
97
 
56
98
  // Check for additions and updates
57
99
  for (const localDB of localTablesDBs) {
58
- const remoteDB = remoteTablesDBs.find(
59
- (db: any) => db.$id === localDB.$id,
60
- );
100
+ const remoteDB = remoteTablesDBs.find((db) => db.$id === localDB.$id);
61
101
 
62
102
  if (!remoteDB) {
63
103
  toCreate.push(localDB);
@@ -132,9 +172,9 @@ export const checkAndApplyTablesDBChanges =
132
172
  await tablesDBService.delete(db.$id);
133
173
  success(`Deleted ${db.name} ( ${db.$id} )`);
134
174
  needsResync = true;
135
- } catch (e: any) {
175
+ } catch (e: unknown) {
136
176
  error(
137
- `Failed to delete database ${db.name} ( ${db.$id} ): ${e.message}`,
177
+ `Failed to delete database ${db.name} ( ${db.$id} ): ${getSyncErrorMessage(e)}`,
138
178
  );
139
179
  throw new Error(
140
180
  `Database sync failed during deletion of ${db.$id}. Some changes may have been applied.`,
@@ -149,9 +189,9 @@ export const checkAndApplyTablesDBChanges =
149
189
  const tablesDBService = await getTablesDBService();
150
190
  await tablesDBService.create(db.$id, db.name, db.enabled);
151
191
  success(`Created ${db.name} ( ${db.$id} )`);
152
- } catch (e: any) {
192
+ } catch (e: unknown) {
153
193
  error(
154
- `Failed to create database ${db.name} ( ${db.$id} ): ${e.message}`,
194
+ `Failed to create database ${db.name} ( ${db.$id} ): ${getSyncErrorMessage(e)}`,
155
195
  );
156
196
  throw new Error(
157
197
  `Database sync failed during creation of ${db.$id}. Some changes may have been applied.`,
@@ -166,9 +206,9 @@ export const checkAndApplyTablesDBChanges =
166
206
  const tablesDBService = await getTablesDBService();
167
207
  await tablesDBService.update(db.$id, db.name, db.enabled);
168
208
  success(`Updated ${db.name} ( ${db.$id} )`);
169
- } catch (e: any) {
209
+ } catch (e: unknown) {
170
210
  error(
171
- `Failed to update database ${db.name} ( ${db.$id} ): ${e.message}`,
211
+ `Failed to update database ${db.name} ( ${db.$id} ): ${getSyncErrorMessage(e)}`,
172
212
  );
173
213
  throw new Error(
174
214
  `Database sync failed during update of ${db.$id}. Some changes may have been applied.`,
@@ -6,6 +6,19 @@ import { error } from "../../parser.js";
6
6
 
7
7
  const POLL_DEBOUNCE = 2000; // Milliseconds
8
8
 
9
+ interface DeploymentListResult {
10
+ total: number;
11
+ deployments: Array<{
12
+ $id: string;
13
+ }>;
14
+ }
15
+
16
+ interface DeploymentDetails {
17
+ $id: string;
18
+ status: string;
19
+ [key: string]: unknown;
20
+ }
21
+
9
22
  /**
10
23
  * Package a directory into a tar.gz File object for deployment
11
24
  * @private - Only used internally by pushDeployment
@@ -38,7 +51,7 @@ export async function downloadDeploymentCode(params: {
38
51
  resourcePath: string;
39
52
  holdingVars: { key: string; value: string }[];
40
53
  withVariables?: boolean;
41
- listDeployments: () => Promise<any>;
54
+ listDeployments: () => Promise<DeploymentListResult>;
42
55
  getDownloadUrl: (deploymentId: string) => string;
43
56
  projectClient: Client;
44
57
  }): Promise<void> {
@@ -85,8 +98,12 @@ export async function downloadDeploymentCode(params: {
85
98
  "arrayBuffer",
86
99
  );
87
100
 
101
+ if (!(downloadBuffer instanceof ArrayBuffer)) {
102
+ throw new Error("Failed to download deployment archive as ArrayBuffer.");
103
+ }
104
+
88
105
  try {
89
- fs.writeFileSync(compressedFileName, Buffer.from(downloadBuffer as any));
106
+ fs.writeFileSync(compressedFileName, Buffer.from(downloadBuffer));
90
107
  } catch (err) {
91
108
  const message = err instanceof Error ? err.message : String(err);
92
109
  throw new Error(
@@ -118,14 +135,14 @@ export async function downloadDeploymentCode(params: {
118
135
 
119
136
  export interface PushDeploymentParams {
120
137
  resourcePath: string;
121
- createDeployment: (codeFile: File) => Promise<any>;
122
- getDeployment?: (deploymentId: string) => Promise<any>;
138
+ createDeployment: (codeFile: File) => Promise<DeploymentDetails>;
139
+ getDeployment?: (deploymentId: string) => Promise<DeploymentDetails>;
123
140
  pollForStatus?: boolean;
124
141
  onStatusUpdate?: (status: string) => void;
125
142
  }
126
143
 
127
144
  export interface PushDeploymentResult {
128
- deployment: any;
145
+ deployment: DeploymentDetails;
129
146
  wasPolled: boolean;
130
147
  finalStatus?: string;
131
148
  }
@@ -39,7 +39,7 @@ export class Pools {
39
39
  }
40
40
 
41
41
  if (this.pollMaxDebounces === this.POLL_DEFAULT_VALUE) {
42
- let steps = Math.max(1, Math.ceil(Number(total) / this.STEP_SIZE));
42
+ const steps = Math.max(1, Math.ceil(Number(total) / this.STEP_SIZE));
43
43
  if (steps > 1 && iteration === 1) {
44
44
  this.pollMaxDebounces *= steps;
45
45
 
@@ -78,7 +78,7 @@ export class Pools {
78
78
  }
79
79
 
80
80
  if (this.pollMaxDebounces === this.POLL_DEFAULT_VALUE) {
81
- let steps = Math.max(1, Math.ceil(Number(total) / this.STEP_SIZE));
81
+ const steps = Math.max(1, Math.ceil(Number(total) / this.STEP_SIZE));
82
82
  if (steps > 1 && iteration === 1) {
83
83
  this.pollMaxDebounces *= steps;
84
84
 
@@ -106,7 +106,10 @@ export class Pools {
106
106
  }
107
107
 
108
108
  if (this.pollMaxDebounces === this.POLL_DEFAULT_VALUE) {
109
- let steps = Math.max(1, Math.ceil(attributeKeys.length / this.STEP_SIZE));
109
+ const steps = Math.max(
110
+ 1,
111
+ Math.ceil(attributeKeys.length / this.STEP_SIZE),
112
+ );
110
113
  if (steps > 1 && iteration === 1) {
111
114
  this.pollMaxDebounces *= steps;
112
115
 
@@ -164,7 +167,10 @@ export class Pools {
164
167
  }
165
168
 
166
169
  if (this.pollMaxDebounces === this.POLL_DEFAULT_VALUE) {
167
- let steps = Math.max(1, Math.ceil(attributeKeys.length / this.STEP_SIZE));
170
+ const steps = Math.max(
171
+ 1,
172
+ Math.ceil(attributeKeys.length / this.STEP_SIZE),
173
+ );
168
174
  if (steps > 1 && iteration === 1) {
169
175
  this.pollMaxDebounces *= steps;
170
176
 
@@ -232,7 +238,7 @@ export class Pools {
232
238
  }
233
239
 
234
240
  if (this.pollMaxDebounces === this.POLL_DEFAULT_VALUE) {
235
- let steps = Math.max(1, Math.ceil(indexKeys.length / this.STEP_SIZE));
241
+ const steps = Math.max(1, Math.ceil(indexKeys.length / this.STEP_SIZE));
236
242
  if (steps > 1 && iteration === 1) {
237
243
  this.pollMaxDebounces *= steps;
238
244
 
package/lib/config.ts CHANGED
@@ -146,7 +146,7 @@ class Config<T extends ConfigData = ConfigData> {
146
146
  try {
147
147
  const file = fs.readFileSync(this.path).toString();
148
148
  this.data = JSONBig.parse(file);
149
- } catch (e) {
149
+ } catch (_e) {
150
150
  this.data = {} as T;
151
151
  }
152
152
  }
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.6.0';
4
+ export const SDK_VERSION = '13.6.1';
5
5
  export const SDK_NAME = 'Command Line';
6
6
  export const SDK_PLATFORM = 'console';
7
7
  export const SDK_LANGUAGE = 'cli';
@@ -1,6 +1,7 @@
1
1
  import ignoreModule from "ignore";
2
2
  const ignore: typeof ignoreModule =
3
- (ignoreModule as any).default ?? ignoreModule;
3
+ (ignoreModule as unknown as { default?: typeof ignoreModule }).default ??
4
+ ignoreModule;
4
5
  import net from "net";
5
6
  import chalk from "chalk";
6
7
  import childProcess from "child_process";
@@ -256,11 +257,9 @@ export async function dockerStart(
256
257
 
257
258
  try {
258
259
  await waitUntilPortOpen(port);
259
- } catch (err: any) {
260
- error(
261
- "Failed to start function with error: " +
262
- (err.message ? err.message : err.toString()),
263
- );
260
+ } catch (err: unknown) {
261
+ const message = err instanceof Error ? err.message : String(err);
262
+ error(`Failed to start function with error: ${message}`);
264
263
  return;
265
264
  }
266
265
 
@@ -142,14 +142,14 @@ export const JwtManager = {
142
142
  await usersClient.get({
143
143
  userId,
144
144
  });
145
- const userResponse: any = await usersClient.createJWT({
145
+ const userResponse = await usersClient.createJWT({
146
146
  userId,
147
147
  duration: 60 * 60,
148
148
  });
149
149
  this.userJwt = userResponse.jwt;
150
150
  }
151
151
 
152
- const functionResponse: any = await projectsClient.createJWT({
152
+ const functionResponse = await projectsClient.createJWT({
153
153
  projectId: localConfig.getProject().projectId!,
154
154
  scopes: projectScopes,
155
155
  duration: 60 * 60,
package/lib/json.ts CHANGED
@@ -8,18 +8,25 @@ const MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);
8
8
  const MAX_INT64 = BigInt("9223372036854775807");
9
9
  const MIN_INT64 = BigInt("-9223372036854775808");
10
10
 
11
- function isBigNumber(value: any): boolean {
11
+ interface BigNumberLike {
12
+ _isBigNumber: boolean;
13
+ isInteger: () => boolean;
14
+ toFixed: () => string;
15
+ toNumber: () => number;
16
+ }
17
+
18
+ function isBigNumber(value: unknown): value is BigNumberLike {
12
19
  return (
13
20
  value !== null &&
14
21
  typeof value === "object" &&
15
- value._isBigNumber === true &&
16
- typeof value.isInteger === "function" &&
17
- typeof value.toFixed === "function" &&
18
- typeof value.toNumber === "function"
22
+ (value as BigNumberLike)._isBigNumber === true &&
23
+ typeof (value as BigNumberLike).isInteger === "function" &&
24
+ typeof (value as BigNumberLike).toFixed === "function" &&
25
+ typeof (value as BigNumberLike).toNumber === "function"
19
26
  );
20
27
  }
21
28
 
22
- function reviver(_key: string, value: any): any {
29
+ function reviver(_key: string, value: unknown): unknown {
23
30
  if (isBigNumber(value)) {
24
31
  if (value.isInteger()) {
25
32
  const str = value.toFixed();
@@ -38,6 +45,7 @@ function reviver(_key: string, value: any): any {
38
45
  }
39
46
 
40
47
  export const JSONBig = {
41
- parse: (text: string) => JSONbigParser.parse(text, reviver),
48
+ parse: <T = unknown>(text: string): T =>
49
+ JSONbigParser.parse(text, reviver) as T,
42
50
  stringify: JSONbigSerializer.stringify,
43
51
  };
package/lib/paginate.ts CHANGED
@@ -1,10 +1,12 @@
1
- interface PaginateArgs {
2
- [key: string]: any;
3
- }
1
+ type PaginateArgs = Record<string, unknown>;
2
+
3
+ type WrappedPaginateResponse<T, K extends string = string> = Record<K, T[]> & {
4
+ total: number;
5
+ };
4
6
 
5
7
  // Overload for when wrapper is empty string - returns array
6
- export function paginate<T = any>(
7
- action: (args: PaginateArgs) => Promise<any>,
8
+ export function paginate<T = unknown>(
9
+ action: (args: PaginateArgs) => Promise<T[]>,
8
10
  args: PaginateArgs,
9
11
  limit: number,
10
12
  wrapper: "",
@@ -12,22 +14,24 @@ export function paginate<T = any>(
12
14
  ): Promise<T[]>;
13
15
 
14
16
  // Overload for when wrapper is specified - returns object with that key
15
- export function paginate<T = any, K extends string = string>(
16
- action: (args: PaginateArgs) => Promise<any>,
17
+ export function paginate<T = unknown, K extends string = string>(
18
+ action: (args: PaginateArgs) => Promise<WrappedPaginateResponse<T, K>>,
17
19
  args: PaginateArgs,
18
20
  limit: number,
19
21
  wrapper: K,
20
22
  queries?: string[],
21
- ): Promise<Record<K, T[]> & { total: number }>;
23
+ ): Promise<WrappedPaginateResponse<T, K>>;
22
24
 
23
25
  // Implementation
24
- export async function paginate<T = any>(
25
- action: (args: PaginateArgs) => Promise<any>,
26
+ export async function paginate<T = unknown>(
27
+ action: (
28
+ args: PaginateArgs,
29
+ ) => Promise<T[] | WrappedPaginateResponse<T, string>>,
26
30
  args: PaginateArgs = {},
27
31
  limit: number = 100,
28
32
  wrapper: string = "",
29
33
  queries: string[] = [],
30
- ): Promise<T[] | (Record<string, T[]> & { total: number })> {
34
+ ): Promise<T[] | WrappedPaginateResponse<T, string>> {
31
35
  let pageNumber = 0;
32
36
  let results: T[] = [];
33
37
  let total = 0;
@@ -46,21 +50,27 @@ export async function paginate<T = any>(
46
50
  });
47
51
 
48
52
  if (wrapper === "") {
49
- if (response.length === 0) {
53
+ const listResponse = response as T[];
54
+
55
+ if (listResponse.length === 0) {
50
56
  break;
51
57
  }
52
- results = results.concat(response);
58
+
59
+ results = results.concat(listResponse);
53
60
  } else {
54
- if (response[wrapper].length === 0) {
61
+ const wrappedResponse = response as WrappedPaginateResponse<T, string>;
62
+ const wrappedResults = wrappedResponse[wrapper] ?? [];
63
+
64
+ if (wrappedResults.length === 0) {
55
65
  break;
56
66
  }
57
- results = results.concat(response[wrapper]);
58
- }
59
67
 
60
- total = response.total;
68
+ results = results.concat(wrappedResults);
69
+ total = wrappedResponse.total;
61
70
 
62
- if (results.length >= total) {
63
- break;
71
+ if (results.length >= total) {
72
+ break;
73
+ }
64
74
  }
65
75
 
66
76
  pageNumber++;
@@ -73,5 +83,5 @@ export async function paginate<T = any>(
73
83
  return {
74
84
  [wrapper]: results,
75
85
  total,
76
- } as Record<string, T[]> & { total: number };
86
+ } as WrappedPaginateResponse<T, string>;
77
87
  }
package/lib/parser.ts CHANGED
@@ -25,7 +25,36 @@ const cliConfig: CliConfig = {
25
25
  reportData: {},
26
26
  };
27
27
 
28
- export const parse = (data: Record<string, any>): void => {
28
+ type JsonObject = Record<string, unknown>;
29
+
30
+ interface ReportDataPayload {
31
+ data?: {
32
+ args?: string[];
33
+ };
34
+ }
35
+
36
+ const toJsonObject = (value: unknown): JsonObject | null => {
37
+ if (value && typeof value === "object" && !Array.isArray(value)) {
38
+ return value as JsonObject;
39
+ }
40
+
41
+ return null;
42
+ };
43
+
44
+ const extractReportCommandArgs = (value: unknown): string[] => {
45
+ if (!value || typeof value !== "object") {
46
+ return [];
47
+ }
48
+
49
+ const reportData = value as ReportDataPayload;
50
+ if (!Array.isArray(reportData.data?.args)) {
51
+ return [];
52
+ }
53
+
54
+ return reportData.data.args;
55
+ };
56
+
57
+ export const parse = (data: JsonObject): void => {
29
58
  if (cliConfig.json) {
30
59
  drawJSON(data);
31
60
  return;
@@ -46,7 +75,8 @@ export const parse = (data: Record<string, any>): void => {
46
75
  console.log(`${chalk.yellow.bold(key)} : ${data[key]}`);
47
76
  } else {
48
77
  console.log(`${chalk.yellow.bold.underline(key)}`);
49
- drawTable([data[key]]);
78
+ const tableRow = toJsonObject(data[key]) ?? {};
79
+ drawTable([tableRow]);
50
80
  }
51
81
  } else {
52
82
  console.log(`${chalk.yellow.bold(key)} : ${data[key]}`);
@@ -54,17 +84,13 @@ export const parse = (data: Record<string, any>): void => {
54
84
  }
55
85
  };
56
86
 
57
- export const drawTable = (
58
- data: Array<Record<string, any> | null | undefined>,
59
- ): void => {
87
+ export const drawTable = (data: Array<JsonObject | null | undefined>): void => {
60
88
  if (data.length == 0) {
61
89
  console.log("[]");
62
90
  return;
63
91
  }
64
92
 
65
- const rows = data.map((item) =>
66
- item && typeof item === "object" && !Array.isArray(item) ? item : {},
67
- );
93
+ const rows = data.map((item): JsonObject => toJsonObject(item) ?? {});
68
94
 
69
95
  // Create an object with all the keys in it
70
96
  const obj = rows.reduce((res, item) => ({ ...res, ...item }), {});
@@ -106,7 +132,7 @@ export const drawTable = (
106
132
  });
107
133
 
108
134
  normalizedData.forEach((row) => {
109
- const rowValues: any[] = [];
135
+ const rowValues: string[] = [];
110
136
  for (const key of columns) {
111
137
  if (row[key] == null) {
112
138
  rowValues.push("-");
@@ -115,7 +141,7 @@ export const drawTable = (
115
141
  } else if (typeof row[key] === "object") {
116
142
  rowValues.push(JSON.stringify(row[key]));
117
143
  } else {
118
- rowValues.push(row[key]);
144
+ rowValues.push(String(row[key]));
119
145
  }
120
146
  }
121
147
  table.push(rowValues);
@@ -123,13 +149,13 @@ export const drawTable = (
123
149
  console.log(table.toString());
124
150
  };
125
151
 
126
- export const drawJSON = (data: any): void => {
152
+ export const drawJSON = (data: unknown): void => {
127
153
  console.log(JSON.stringify(data, null, 2));
128
154
  };
129
155
 
130
156
  export const parseError = (err: Error): void => {
131
157
  if (cliConfig.report) {
132
- (async () => {
158
+ void (async () => {
133
159
  let appwriteVersion = "unknown";
134
160
  const endpoint = globalConfig.getEndpoint();
135
161
 
@@ -145,7 +171,8 @@ export const parseError = (err: Error): void => {
145
171
  }
146
172
 
147
173
  const version = SDK_VERSION;
148
- const stepsToReproduce = `Running \`${EXECUTABLE_NAME} ${(cliConfig.reportData as any).data.args.join(" ")}\``;
174
+ const commandArgs = extractReportCommandArgs(cliConfig.reportData);
175
+ const stepsToReproduce = `Running \`${EXECUTABLE_NAME} ${commandArgs.join(" ")}\``;
149
176
  const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud()}`;
150
177
 
151
178
  const stack = "```\n" + (err.stack || err.message) + "\n```";
@@ -188,7 +215,9 @@ export const parseError = (err: Error): void => {
188
215
  }
189
216
  };
190
217
 
191
- export const actionRunner = <T extends (...args: any[]) => Promise<any>>(
218
+ export const actionRunner = <
219
+ T extends (...args: unknown[]) => Promise<unknown>,
220
+ >(
192
221
  fn: T,
193
222
  ): ((...args: Parameters<T>) => Promise<void>) => {
194
223
  return (...args: Parameters<T>) => {
@@ -200,7 +229,9 @@ export const actionRunner = <T extends (...args: any[]) => Promise<any>>(
200
229
  error(`The '--all' and '--id' flags cannot be used together.`);
201
230
  process.exit(1);
202
231
  }
203
- return fn(...args).catch(parseError);
232
+ return fn(...args)
233
+ .then(() => undefined)
234
+ .catch(parseError);
204
235
  };
205
236
  };
206
237