appwrite-cli 13.5.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.
- package/CHANGELOG.md +14 -0
- package/README.md +2 -2
- package/cli.ts +7 -5
- package/dist/bundle-win-arm64.mjs +988 -258
- package/dist/cli.cjs +988 -258
- package/dist/index.cjs +183 -112
- package/dist/index.js +183 -112
- package/dist/lib/commands/config-validations.d.ts +1 -1
- package/dist/lib/commands/config-validations.d.ts.map +1 -1
- package/dist/lib/commands/errors.d.ts +4 -4
- package/dist/lib/commands/errors.d.ts.map +1 -1
- package/dist/lib/commands/generate.d.ts.map +1 -1
- package/dist/lib/commands/generators/base.d.ts +5 -0
- package/dist/lib/commands/generators/base.d.ts.map +1 -1
- package/dist/lib/commands/generic.d.ts.map +1 -1
- package/dist/lib/commands/init.d.ts.map +1 -1
- package/dist/lib/commands/run.d.ts.map +1 -1
- package/dist/lib/commands/schema.d.ts.map +1 -1
- package/dist/lib/commands/services/activities.d.ts +3 -0
- package/dist/lib/commands/services/activities.d.ts.map +1 -0
- package/dist/lib/commands/services/backups.d.ts +3 -0
- package/dist/lib/commands/services/backups.d.ts.map +1 -0
- package/dist/lib/commands/types.d.ts.map +1 -1
- package/dist/lib/commands/update.d.ts.map +1 -1
- package/dist/lib/commands/utils/change-approval.d.ts +3 -3
- package/dist/lib/commands/utils/change-approval.d.ts.map +1 -1
- package/dist/lib/commands/utils/database-sync.d.ts.map +1 -1
- package/dist/lib/commands/utils/deployment.d.ts +16 -4
- package/dist/lib/commands/utils/deployment.d.ts.map +1 -1
- package/dist/lib/commands/utils/pools.d.ts.map +1 -1
- package/dist/lib/constants.d.ts +1 -1
- package/dist/lib/emulation/docker.d.ts.map +1 -1
- package/dist/lib/json.d.ts +1 -1
- package/dist/lib/json.d.ts.map +1 -1
- package/dist/lib/paginate.d.ts +5 -6
- package/dist/lib/paginate.d.ts.map +1 -1
- package/dist/lib/parser.d.ts +5 -4
- package/dist/lib/parser.d.ts.map +1 -1
- package/dist/lib/spinner.d.ts +1 -1
- package/dist/lib/spinner.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +6 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/validations.d.ts +1 -1
- package/dist/lib/validations.d.ts.map +1 -1
- package/docs/examples/account/create-key.md +5 -0
- package/docs/examples/account/delete-key.md +4 -0
- package/docs/examples/account/get-key.md +4 -0
- package/docs/examples/account/list-keys.md +3 -0
- package/docs/examples/account/update-key.md +6 -0
- package/docs/examples/activities/get-event.md +4 -0
- package/docs/examples/activities/list-events.md +3 -0
- package/docs/examples/backups/create-archive.md +4 -0
- package/docs/examples/backups/create-policy.md +7 -0
- package/docs/examples/backups/create-restoration.md +5 -0
- package/docs/examples/backups/delete-archive.md +4 -0
- package/docs/examples/backups/delete-policy.md +4 -0
- package/docs/examples/backups/get-archive.md +4 -0
- package/docs/examples/backups/get-policy.md +4 -0
- package/docs/examples/backups/get-restoration.md +4 -0
- package/docs/examples/backups/list-archives.md +3 -0
- package/docs/examples/backups/list-policies.md +3 -0
- package/docs/examples/backups/list-restorations.md +3 -0
- package/docs/examples/backups/update-policy.md +4 -0
- package/eslint.config.js +45 -0
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.ts +3 -3
- package/lib/commands/config-validations.ts +1 -1
- package/lib/commands/config.ts +2 -2
- package/lib/commands/errors.ts +2 -2
- package/lib/commands/generate.ts +8 -6
- package/lib/commands/generators/base.ts +6 -0
- package/lib/commands/generators/typescript/databases.ts +9 -9
- package/lib/commands/generators/typescript/templates/databases.ts.hbs +16 -16
- package/lib/commands/generic.ts +21 -16
- package/lib/commands/init.ts +147 -61
- package/lib/commands/pull.ts +1 -1
- package/lib/commands/push.ts +19 -19
- package/lib/commands/run.ts +15 -9
- package/lib/commands/schema.ts +1 -3
- package/lib/commands/services/account.ts +234 -0
- package/lib/commands/services/activities.ts +51 -0
- package/lib/commands/services/backups.ts +184 -0
- package/lib/commands/services/health.ts +55 -0
- package/lib/commands/services/projects.ts +1 -1
- package/lib/commands/services/storage.ts +2 -2
- package/lib/commands/types.ts +18 -8
- package/lib/commands/update.ts +24 -16
- package/lib/commands/utils/attributes.ts +6 -6
- package/lib/commands/utils/change-approval.ts +26 -19
- package/lib/commands/utils/database-sync.ts +58 -18
- package/lib/commands/utils/deployment.ts +22 -5
- package/lib/commands/utils/pools.ts +11 -5
- package/lib/config.ts +1 -1
- package/lib/constants.ts +1 -1
- package/lib/emulation/docker.ts +5 -6
- package/lib/emulation/utils.ts +2 -2
- package/lib/json.ts +21 -8
- package/lib/paginate.ts +30 -20
- package/lib/parser.ts +46 -15
- package/lib/questions.ts +38 -38
- package/lib/spinner.ts +5 -1
- package/lib/utils.ts +15 -3
- package/lib/validations.ts +1 -1
- package/package.json +8 -2
- package/scoop/appwrite.config.json +3 -3
- package/dist/lib/commands/services/console.d.ts +0 -3
- package/dist/lib/commands/services/console.d.ts.map +0 -1
- package/docs/examples/console/get-resource.md +0 -5
- package/docs/examples/console/variables.md +0 -3
- package/lib/commands/services/console.ts +0 -49
package/lib/commands/update.ts
CHANGED
|
@@ -3,7 +3,11 @@ import { Command } from "commander";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import inquirer from "inquirer";
|
|
5
5
|
import { success, log, warn, error, hint, actionRunner } from "../parser.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getLatestVersion,
|
|
8
|
+
compareVersions,
|
|
9
|
+
getErrorMessage,
|
|
10
|
+
} from "../utils.js";
|
|
7
11
|
import {
|
|
8
12
|
GITHUB_RELEASES_URL,
|
|
9
13
|
NPM_PACKAGE_NAME,
|
|
@@ -12,6 +16,8 @@ import {
|
|
|
12
16
|
import packageJson from "../../package.json" with { type: "json" };
|
|
13
17
|
const { version } = packageJson;
|
|
14
18
|
|
|
19
|
+
type ExecCommandOptions = Exclude<Parameters<typeof spawn>[2], undefined>;
|
|
20
|
+
|
|
15
21
|
/**
|
|
16
22
|
* Check if the CLI was installed via npm
|
|
17
23
|
*/
|
|
@@ -36,7 +42,7 @@ const isInstalledViaNpm = (): boolean => {
|
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
return false;
|
|
39
|
-
} catch (
|
|
45
|
+
} catch (_e) {
|
|
40
46
|
return false;
|
|
41
47
|
}
|
|
42
48
|
};
|
|
@@ -51,7 +57,7 @@ const isInstalledViaHomebrew = (): boolean => {
|
|
|
51
57
|
scriptPath.includes("/opt/homebrew/") ||
|
|
52
58
|
scriptPath.includes("/usr/local/Cellar/")
|
|
53
59
|
);
|
|
54
|
-
} catch (
|
|
60
|
+
} catch (_e) {
|
|
55
61
|
return false;
|
|
56
62
|
}
|
|
57
63
|
};
|
|
@@ -62,7 +68,7 @@ const isInstalledViaHomebrew = (): boolean => {
|
|
|
62
68
|
const execCommand = (
|
|
63
69
|
command: string,
|
|
64
70
|
args: string[] = [],
|
|
65
|
-
options:
|
|
71
|
+
options: ExecCommandOptions = {},
|
|
66
72
|
): Promise<void> => {
|
|
67
73
|
return new Promise((resolve, reject) => {
|
|
68
74
|
const child = spawn(command, args, {
|
|
@@ -94,17 +100,16 @@ const updateViaNpm = async (): Promise<void> => {
|
|
|
94
100
|
console.log("");
|
|
95
101
|
success("Updated to latest version via npm!");
|
|
96
102
|
hint("Run 'appwrite --version' to verify the new version.");
|
|
97
|
-
} catch (e:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
) {
|
|
103
|
+
} catch (e: unknown) {
|
|
104
|
+
const message = getErrorMessage(e);
|
|
105
|
+
|
|
106
|
+
if (message.includes("EEXIST") || message.includes("file already exists")) {
|
|
102
107
|
console.log("");
|
|
103
108
|
success("Latest version is already installed via npm!");
|
|
104
109
|
hint("The CLI is up to date. Run 'appwrite --version' to verify.");
|
|
105
110
|
} else {
|
|
106
111
|
console.log("");
|
|
107
|
-
error(`Failed to update via npm: ${
|
|
112
|
+
error(`Failed to update via npm: ${message}`);
|
|
108
113
|
hint(`Try running: npm install -g ${NPM_PACKAGE_NAME}@latest --force`);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
@@ -119,17 +124,19 @@ const updateViaHomebrew = async (): Promise<void> => {
|
|
|
119
124
|
console.log("");
|
|
120
125
|
success("Updated to latest version via Homebrew!");
|
|
121
126
|
hint("Run 'appwrite --version' to verify the new version.");
|
|
122
|
-
} catch (e:
|
|
127
|
+
} catch (e: unknown) {
|
|
128
|
+
const message = getErrorMessage(e);
|
|
129
|
+
|
|
123
130
|
if (
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
message.includes("already installed") ||
|
|
132
|
+
message.includes("up-to-date")
|
|
126
133
|
) {
|
|
127
134
|
console.log("");
|
|
128
135
|
success("Latest version is already installed via Homebrew!");
|
|
129
136
|
hint("The CLI is up to date. Run 'appwrite --version' to verify.");
|
|
130
137
|
} else {
|
|
131
138
|
console.log("");
|
|
132
|
-
error(`Failed to update via Homebrew: ${
|
|
139
|
+
error(`Failed to update via Homebrew: ${message}`);
|
|
133
140
|
hint("Try running: brew upgrade appwrite");
|
|
134
141
|
}
|
|
135
142
|
}
|
|
@@ -230,9 +237,10 @@ const updateCli = async ({ manual }: UpdateOptions = {}): Promise<void> => {
|
|
|
230
237
|
} else {
|
|
231
238
|
await chooseUpdateMethod(latestVersion);
|
|
232
239
|
}
|
|
233
|
-
} catch (e:
|
|
240
|
+
} catch (e: unknown) {
|
|
241
|
+
const message = getErrorMessage(e);
|
|
234
242
|
console.log("");
|
|
235
|
-
error(`Failed to check for updates: ${
|
|
243
|
+
error(`Failed to check for updates: ${message}`);
|
|
236
244
|
hint(`You can manually check for updates at: ${GITHUB_RELEASES_URL}`);
|
|
237
245
|
}
|
|
238
246
|
};
|
|
@@ -76,7 +76,7 @@ export class Attributes {
|
|
|
76
76
|
return answers.changes;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
const answers = await inquirer.prompt(questionPushChanges);
|
|
80
80
|
|
|
81
81
|
if (answers.changes !== "YES" && answers.changes !== "NO") {
|
|
82
82
|
answers.changes = await fixConfirmation();
|
|
@@ -148,9 +148,9 @@ export class Attributes {
|
|
|
148
148
|
const keyName = `${chalk.yellow(local.key)} in ${collection.name} (${collection["$id"]})`;
|
|
149
149
|
const action = chalk.cyan(recreating ? "recreating" : "changing");
|
|
150
150
|
let reason = "";
|
|
151
|
-
|
|
151
|
+
const attribute = recreating ? remote : local;
|
|
152
152
|
|
|
153
|
-
for (
|
|
153
|
+
for (const key of Object.keys(remote)) {
|
|
154
154
|
if (!KeysAttributes.has(key)) {
|
|
155
155
|
continue;
|
|
156
156
|
}
|
|
@@ -737,7 +737,7 @@ export class Attributes {
|
|
|
737
737
|
log(`Creating indexes ...`);
|
|
738
738
|
|
|
739
739
|
const databasesService = await getDatabasesService(this.client);
|
|
740
|
-
for (
|
|
740
|
+
for (const index of indexes) {
|
|
741
741
|
await databasesService.createIndex({
|
|
742
742
|
databaseId: collection["databaseId"],
|
|
743
743
|
collectionId: collection["$id"],
|
|
@@ -769,7 +769,7 @@ export class Attributes {
|
|
|
769
769
|
): Promise<void> => {
|
|
770
770
|
log(`Creating attributes ...`);
|
|
771
771
|
|
|
772
|
-
for (
|
|
772
|
+
for (const attribute of attributes) {
|
|
773
773
|
if (attribute.side !== "child") {
|
|
774
774
|
await this.createAttribute(
|
|
775
775
|
collection["databaseId"],
|
|
@@ -803,7 +803,7 @@ export class Attributes {
|
|
|
803
803
|
): Promise<void> => {
|
|
804
804
|
log(`Creating columns ...`);
|
|
805
805
|
|
|
806
|
-
for (
|
|
806
|
+
for (const column of columns) {
|
|
807
807
|
if (column.side !== "child") {
|
|
808
808
|
await this.createAttribute(table["databaseId"], table["$id"], column);
|
|
809
809
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import inquirer from "inquirer";
|
|
3
|
+
import { AppwriteException } from "@appwrite.io/console";
|
|
3
4
|
import { cliConfig, success, warn, log, drawTable } from "../../parser.js";
|
|
4
5
|
import { whitelistKeys } from "../../config.js";
|
|
5
6
|
import {
|
|
@@ -10,7 +11,7 @@ import {
|
|
|
10
11
|
/**
|
|
11
12
|
* Check if a value is considered empty
|
|
12
13
|
*/
|
|
13
|
-
export const isEmpty = (value:
|
|
14
|
+
export const isEmpty = (value: unknown): boolean =>
|
|
14
15
|
value === null ||
|
|
15
16
|
value === undefined ||
|
|
16
17
|
(typeof value === "string" && value.trim().length === 0) ||
|
|
@@ -33,7 +34,7 @@ export const getConfirmation = async (): Promise<boolean> => {
|
|
|
33
34
|
return answers.changes;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
const answers = await inquirer.prompt(questionPushChanges);
|
|
37
38
|
|
|
38
39
|
if (answers.changes !== "YES" && answers.changes !== "NO") {
|
|
39
40
|
answers.changes = await fixConfirmation();
|
|
@@ -57,9 +58,9 @@ interface ObjectChange {
|
|
|
57
58
|
local: string;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
type ComparableValue = boolean | number | string |
|
|
61
|
+
type ComparableValue = boolean | number | string | unknown[] | undefined;
|
|
61
62
|
|
|
62
|
-
export const getObjectChanges = <T extends Record<string,
|
|
63
|
+
export const getObjectChanges = <T extends Record<string, unknown>>(
|
|
63
64
|
remote: T,
|
|
64
65
|
local: T,
|
|
65
66
|
index: keyof T,
|
|
@@ -110,8 +111,10 @@ export const getObjectChanges = <T extends Record<string, any>>(
|
|
|
110
111
|
* Compares local resources with remote resources and prompts user for confirmation
|
|
111
112
|
*/
|
|
112
113
|
export const approveChanges = async (
|
|
113
|
-
resource:
|
|
114
|
-
resourceGetFunction:
|
|
114
|
+
resource: Array<Record<string, unknown>>,
|
|
115
|
+
resourceGetFunction: (
|
|
116
|
+
options: Record<string, unknown>,
|
|
117
|
+
) => Promise<Record<string, unknown>>,
|
|
115
118
|
keys: Set<string>,
|
|
116
119
|
resourceName: string,
|
|
117
120
|
resourcePlural: string,
|
|
@@ -120,12 +123,12 @@ export const approveChanges = async (
|
|
|
120
123
|
secondResourceName: string = "",
|
|
121
124
|
): Promise<boolean> => {
|
|
122
125
|
log("Checking for changes ...");
|
|
123
|
-
const changes:
|
|
126
|
+
const changes: Array<Record<string, unknown>> = [];
|
|
124
127
|
|
|
125
128
|
await Promise.all(
|
|
126
129
|
resource.map(async (localResource) => {
|
|
127
130
|
try {
|
|
128
|
-
const options: Record<string,
|
|
131
|
+
const options: Record<string, unknown> = {
|
|
129
132
|
[resourceName]: localResource["$id"],
|
|
130
133
|
};
|
|
131
134
|
|
|
@@ -135,7 +138,7 @@ export const approveChanges = async (
|
|
|
135
138
|
|
|
136
139
|
const remoteResource = await resourceGetFunction(options);
|
|
137
140
|
|
|
138
|
-
for (
|
|
141
|
+
for (const [key, value] of Object.entries(
|
|
139
142
|
whitelistKeys(remoteResource, keys),
|
|
140
143
|
)) {
|
|
141
144
|
if (skipKeys.includes(key)) {
|
|
@@ -146,28 +149,32 @@ export const approveChanges = async (
|
|
|
146
149
|
continue;
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
const localValue = localResource[key];
|
|
153
|
+
|
|
154
|
+
if (Array.isArray(value) && Array.isArray(localValue)) {
|
|
155
|
+
if (JSON.stringify(value) !== JSON.stringify(localValue)) {
|
|
151
156
|
changes.push({
|
|
152
157
|
id: localResource["$id"],
|
|
153
158
|
key,
|
|
154
159
|
remote: chalk.red((value as string[]).join("\n")),
|
|
155
|
-
local: chalk.green(
|
|
160
|
+
local: chalk.green(
|
|
161
|
+
localValue.map((entry) => String(entry)).join("\n"),
|
|
162
|
+
),
|
|
156
163
|
});
|
|
157
164
|
}
|
|
158
|
-
} else if (value !==
|
|
165
|
+
} else if (value !== localValue) {
|
|
159
166
|
changes.push({
|
|
160
167
|
id: localResource["$id"],
|
|
161
168
|
key,
|
|
162
|
-
remote: chalk.red(value),
|
|
163
|
-
local: chalk.green(
|
|
169
|
+
remote: chalk.red(String(value ?? "")),
|
|
170
|
+
local: chalk.green(String(localValue ?? "")),
|
|
164
171
|
});
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
|
-
} catch (e:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
} catch (e: unknown) {
|
|
175
|
+
const isNotFound =
|
|
176
|
+
e instanceof AppwriteException && Number(e.code) === 404;
|
|
177
|
+
if (!isNotFound) throw e;
|
|
171
178
|
}
|
|
172
179
|
}),
|
|
173
180
|
);
|
|
@@ -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
|
|
23
|
-
async (args
|
|
55
|
+
const localTablesDBs: TablesDBResource[] = localConfig.getTablesDBs();
|
|
56
|
+
const paginatedResult = await paginate(
|
|
57
|
+
async (args) => {
|
|
24
58
|
const tablesDBService = await getTablesDBService();
|
|
25
|
-
|
|
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:
|
|
37
|
-
const toCreate:
|
|
38
|
-
const toUpdate:
|
|
39
|
-
const toDelete:
|
|
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
|
|
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:
|
|
175
|
+
} catch (e: unknown) {
|
|
136
176
|
error(
|
|
137
|
-
`Failed to delete database ${db.name} ( ${db.$id} ): ${e
|
|
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:
|
|
192
|
+
} catch (e: unknown) {
|
|
153
193
|
error(
|
|
154
|
-
`Failed to create database ${db.name} ( ${db.$id} ): ${e
|
|
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:
|
|
209
|
+
} catch (e: unknown) {
|
|
170
210
|
error(
|
|
171
|
-
`Failed to update database ${db.name} ( ${db.$id} ): ${e
|
|
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<
|
|
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
|
|
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<
|
|
122
|
-
getDeployment?: (deploymentId: string) => Promise<
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
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.
|
|
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';
|
package/lib/emulation/docker.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ignoreModule from "ignore";
|
|
2
2
|
const ignore: typeof ignoreModule =
|
|
3
|
-
(ignoreModule as
|
|
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:
|
|
260
|
-
|
|
261
|
-
|
|
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
|
|
package/lib/emulation/utils.ts
CHANGED
|
@@ -142,14 +142,14 @@ export const JwtManager = {
|
|
|
142
142
|
await usersClient.get({
|
|
143
143
|
userId,
|
|
144
144
|
});
|
|
145
|
-
const userResponse
|
|
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
|
|
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
|
@@ -5,19 +5,28 @@ const JSONbigSerializer = JSONbigModule({ useNativeBigInt: true });
|
|
|
5
5
|
|
|
6
6
|
const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);
|
|
7
7
|
const MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);
|
|
8
|
+
const MAX_INT64 = BigInt("9223372036854775807");
|
|
9
|
+
const MIN_INT64 = BigInt("-9223372036854775808");
|
|
8
10
|
|
|
9
|
-
|
|
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 {
|
|
10
19
|
return (
|
|
11
20
|
value !== null &&
|
|
12
21
|
typeof value === "object" &&
|
|
13
|
-
value._isBigNumber === true &&
|
|
14
|
-
typeof value.isInteger === "function" &&
|
|
15
|
-
typeof value.toFixed === "function" &&
|
|
16
|
-
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"
|
|
17
26
|
);
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
function reviver(_key: string, value:
|
|
29
|
+
function reviver(_key: string, value: unknown): unknown {
|
|
21
30
|
if (isBigNumber(value)) {
|
|
22
31
|
if (value.isInteger()) {
|
|
23
32
|
const str = value.toFixed();
|
|
@@ -25,7 +34,10 @@ function reviver(_key: string, value: any): any {
|
|
|
25
34
|
if (bi >= MIN_SAFE && bi <= MAX_SAFE) {
|
|
26
35
|
return Number(str);
|
|
27
36
|
}
|
|
28
|
-
|
|
37
|
+
if (bi >= MIN_INT64 && bi <= MAX_INT64) {
|
|
38
|
+
return bi;
|
|
39
|
+
}
|
|
40
|
+
return value.toNumber();
|
|
29
41
|
}
|
|
30
42
|
return value.toNumber();
|
|
31
43
|
}
|
|
@@ -33,6 +45,7 @@ function reviver(_key: string, value: any): any {
|
|
|
33
45
|
}
|
|
34
46
|
|
|
35
47
|
export const JSONBig = {
|
|
36
|
-
parse: (text: string) =>
|
|
48
|
+
parse: <T = unknown>(text: string): T =>
|
|
49
|
+
JSONbigParser.parse(text, reviver) as T,
|
|
37
50
|
stringify: JSONbigSerializer.stringify,
|
|
38
51
|
};
|