appwrite-cli 13.2.0 → 13.3.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.
- package/CHANGELOG.md +9 -0
- package/README.md +2 -2
- package/dist/bundle-win-arm64.mjs +285 -74
- package/dist/cli.cjs +285 -74
- package/dist/index.js +96 -13
- package/dist/lib/commands/config-validations.d.ts +1 -1
- package/dist/lib/commands/config.d.ts +24 -0
- package/dist/lib/commands/config.d.ts.map +1 -1
- package/dist/lib/commands/generic.d.ts +2 -4
- package/dist/lib/commands/generic.d.ts.map +1 -1
- package/dist/lib/commands/push.d.ts.map +1 -1
- package/dist/lib/commands/utils/attributes.d.ts.map +1 -1
- package/dist/lib/constants.d.ts +1 -1
- package/dist/lib/questions.d.ts +1 -0
- package/dist/lib/questions.d.ts.map +1 -1
- package/dist/lib/shared/typescript-type-utils.d.ts.map +1 -1
- package/dist/lib/type-generation/attribute.d.ts +4 -0
- package/dist/lib/type-generation/attribute.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/csharp.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/dart.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/java.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/javascript.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/kotlin.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/php.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/swift.d.ts.map +1 -1
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/commands/config-validations.ts +3 -3
- package/lib/commands/config.ts +10 -2
- package/lib/commands/generic.ts +211 -76
- package/lib/commands/push.ts +3 -2
- package/lib/commands/utils/attributes.ts +70 -0
- package/lib/config.ts +4 -4
- package/lib/constants.ts +1 -1
- package/lib/questions.ts +3 -1
- package/lib/shared/typescript-type-utils.ts +4 -0
- package/lib/type-generation/attribute.ts +4 -0
- package/lib/type-generation/languages/csharp.ts +6 -2
- package/lib/type-generation/languages/dart.ts +5 -1
- package/lib/type-generation/languages/java.ts +4 -0
- package/lib/type-generation/languages/javascript.ts +4 -0
- package/lib/type-generation/languages/kotlin.ts +4 -0
- package/lib/type-generation/languages/php.ts +4 -0
- package/lib/type-generation/languages/swift.ts +8 -4
- package/package.json +1 -1
- package/scoop/appwrite.config.json +3 -3
package/lib/commands/generic.ts
CHANGED
|
@@ -28,13 +28,131 @@ import ClientLegacy from "../client.js";
|
|
|
28
28
|
|
|
29
29
|
const DEFAULT_ENDPOINT = "https://cloud.appwrite.io/v1";
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
const isMfaRequiredError = (err: any): boolean =>
|
|
32
|
+
err?.type === "user_more_factors_required" ||
|
|
33
|
+
err?.response === "user_more_factors_required";
|
|
34
|
+
|
|
35
|
+
const createLegacyConsoleClient = (endpoint: string): ClientLegacy => {
|
|
36
|
+
const legacyClient = new ClientLegacy();
|
|
37
|
+
legacyClient.setEndpoint(endpoint);
|
|
38
|
+
legacyClient.setProject("console");
|
|
39
|
+
if (globalConfig.getSelfSigned()) {
|
|
40
|
+
legacyClient.setSelfSigned(true);
|
|
41
|
+
}
|
|
42
|
+
return legacyClient;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const completeMfaLogin = async ({
|
|
46
|
+
client,
|
|
47
|
+
legacyClient,
|
|
48
|
+
mfa,
|
|
49
|
+
code,
|
|
50
|
+
}: {
|
|
51
|
+
client: ConsoleClient;
|
|
52
|
+
legacyClient: ClientLegacy;
|
|
35
53
|
mfa?: string;
|
|
36
54
|
code?: string;
|
|
37
|
-
}
|
|
55
|
+
}): Promise<any> => {
|
|
56
|
+
let accountClient = new Account(client);
|
|
57
|
+
|
|
58
|
+
const savedCookie = globalConfig.getCookie();
|
|
59
|
+
if (savedCookie) {
|
|
60
|
+
legacyClient.setCookie(savedCookie);
|
|
61
|
+
client.setCookie(savedCookie);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { factor } = mfa
|
|
65
|
+
? { factor: mfa }
|
|
66
|
+
: await inquirer.prompt(questionsListFactors);
|
|
67
|
+
const challenge = await accountClient.createMfaChallenge(factor);
|
|
68
|
+
|
|
69
|
+
const { otp } = code
|
|
70
|
+
? { otp: code }
|
|
71
|
+
: await inquirer.prompt(questionsMFAChallenge);
|
|
72
|
+
await legacyClient.call(
|
|
73
|
+
"PUT",
|
|
74
|
+
"/account/mfa/challenges",
|
|
75
|
+
{
|
|
76
|
+
"content-type": "application/json",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
challengeId: challenge.$id,
|
|
80
|
+
otp,
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const updatedCookie = globalConfig.getCookie();
|
|
85
|
+
if (updatedCookie) {
|
|
86
|
+
client.setCookie(updatedCookie);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
accountClient = new Account(client);
|
|
90
|
+
return accountClient.get();
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const deleteServerSession = async (sessionId: string): Promise<boolean> => {
|
|
94
|
+
try {
|
|
95
|
+
let client = await sdkForConsole();
|
|
96
|
+
let accountClient = new Account(client);
|
|
97
|
+
await accountClient.deleteSession(sessionId);
|
|
98
|
+
return true;
|
|
99
|
+
} catch (e) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const deleteLocalSession = (accountId: string): void => {
|
|
105
|
+
globalConfig.removeSession(accountId);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const getSessionAccountKey = (sessionId: string): string | undefined => {
|
|
109
|
+
const session = globalConfig.get(sessionId) as
|
|
110
|
+
| { email?: string; endpoint?: string }
|
|
111
|
+
| undefined;
|
|
112
|
+
if (!session) return undefined;
|
|
113
|
+
return `${session.email ?? ""}|${session.endpoint ?? ""}`;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Given selected session IDs, determine which sessions should be logged out
|
|
118
|
+
* from the server (one per unique account) and which should be removed locally (all sessions for those accounts).
|
|
119
|
+
*
|
|
120
|
+
* @param selectedSessionIds Array of session IDs to process for logout.
|
|
121
|
+
* @returns Object containing `serverTargets` (sessions to logout from server)
|
|
122
|
+
* and `localTargets` (sessions to remove locally).
|
|
123
|
+
*/
|
|
124
|
+
const planSessionLogout = (
|
|
125
|
+
selectedSessionIds: string[],
|
|
126
|
+
): { serverTargets: string[]; localTargets: string[] } => {
|
|
127
|
+
// Map to group all session IDs by their unique account key (email+endpoint)
|
|
128
|
+
const sessionIdsByAccount = new Map<string, string[]>();
|
|
129
|
+
for (const sessionId of globalConfig.getSessionIds()) {
|
|
130
|
+
const key = getSessionAccountKey(sessionId);
|
|
131
|
+
if (!key) continue; // Skip sessions without proper account key
|
|
132
|
+
|
|
133
|
+
// For each account key, gather all associated session IDs
|
|
134
|
+
const ids = sessionIdsByAccount.get(key) ?? [];
|
|
135
|
+
ids.push(sessionId);
|
|
136
|
+
sessionIdsByAccount.set(key, ids);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Map to store one selected session ID per unique account for server logout
|
|
140
|
+
const selectedByAccount = new Map<string, string>();
|
|
141
|
+
for (const selectedSessionId of selectedSessionIds) {
|
|
142
|
+
const key = getSessionAccountKey(selectedSessionId);
|
|
143
|
+
if (!key || selectedByAccount.has(key)) continue; // Skip if key missing or already considered for this account
|
|
144
|
+
selectedByAccount.set(key, selectedSessionId);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Sessions to target for server logout: one per unique account
|
|
148
|
+
const serverTargets = Array.from(selectedByAccount.values());
|
|
149
|
+
// Sessions to remove locally: all sessions under selected accounts
|
|
150
|
+
const localTargets = Array.from(selectedByAccount.keys()).flatMap(
|
|
151
|
+
(accountKey) => sessionIdsByAccount.get(accountKey) ?? [],
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
return { serverTargets, localTargets };
|
|
155
|
+
};
|
|
38
156
|
|
|
39
157
|
export const loginCommand = async ({
|
|
40
158
|
email,
|
|
@@ -42,7 +160,13 @@ export const loginCommand = async ({
|
|
|
42
160
|
endpoint,
|
|
43
161
|
mfa,
|
|
44
162
|
code,
|
|
45
|
-
}:
|
|
163
|
+
}: {
|
|
164
|
+
email?: string;
|
|
165
|
+
password?: string;
|
|
166
|
+
endpoint?: string;
|
|
167
|
+
mfa?: string;
|
|
168
|
+
code?: string;
|
|
169
|
+
}): Promise<void> => {
|
|
46
170
|
const oldCurrent = globalConfig.getCurrentSession();
|
|
47
171
|
|
|
48
172
|
const configEndpoint =
|
|
@@ -73,7 +197,29 @@ export const loginCommand = async ({
|
|
|
73
197
|
}
|
|
74
198
|
|
|
75
199
|
globalConfig.setCurrentSession(accountId);
|
|
76
|
-
|
|
200
|
+
|
|
201
|
+
const client = await sdkForConsole(false);
|
|
202
|
+
const accountClient = new Account(client);
|
|
203
|
+
const legacyClient = createLegacyConsoleClient(
|
|
204
|
+
globalConfig.getEndpoint() || DEFAULT_ENDPOINT,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
await accountClient.get();
|
|
209
|
+
} catch (err: any) {
|
|
210
|
+
if (!isMfaRequiredError(err)) {
|
|
211
|
+
throw err;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
await completeMfaLogin({
|
|
215
|
+
client,
|
|
216
|
+
legacyClient,
|
|
217
|
+
mfa,
|
|
218
|
+
code,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
success(`Switched to ${globalConfig.getEmail()}`);
|
|
77
223
|
|
|
78
224
|
return;
|
|
79
225
|
}
|
|
@@ -86,12 +232,7 @@ export const loginCommand = async ({
|
|
|
86
232
|
globalConfig.setEmail(answers.email);
|
|
87
233
|
|
|
88
234
|
// Use legacy client for login to extract cookies from response
|
|
89
|
-
const legacyClient =
|
|
90
|
-
legacyClient.setEndpoint(configEndpoint);
|
|
91
|
-
legacyClient.setProject("console");
|
|
92
|
-
if (globalConfig.getSelfSigned()) {
|
|
93
|
-
legacyClient.setSelfSigned(true);
|
|
94
|
-
}
|
|
235
|
+
const legacyClient = createLegacyConsoleClient(configEndpoint);
|
|
95
236
|
|
|
96
237
|
let client = await sdkForConsole(false);
|
|
97
238
|
let accountClient = new Account(client);
|
|
@@ -121,37 +262,13 @@ export const loginCommand = async ({
|
|
|
121
262
|
accountClient = new Account(client);
|
|
122
263
|
account = await accountClient.get();
|
|
123
264
|
} catch (err: any) {
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const challenge = await accountClient.createMfaChallenge(factor);
|
|
132
|
-
|
|
133
|
-
const { otp } = code
|
|
134
|
-
? { otp: code }
|
|
135
|
-
: await inquirer.prompt(questionsMFAChallenge);
|
|
136
|
-
await legacyClient.call(
|
|
137
|
-
"PUT",
|
|
138
|
-
"/account/mfa/challenges",
|
|
139
|
-
{
|
|
140
|
-
"content-type": "application/json",
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
challengeId: challenge.$id,
|
|
144
|
-
otp: otp,
|
|
145
|
-
},
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
const savedCookie = globalConfig.getCookie();
|
|
149
|
-
if (savedCookie) {
|
|
150
|
-
client.setCookie(savedCookie);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
accountClient = new Account(client);
|
|
154
|
-
account = await accountClient.get();
|
|
265
|
+
if (isMfaRequiredError(err)) {
|
|
266
|
+
account = await completeMfaLogin({
|
|
267
|
+
client,
|
|
268
|
+
legacyClient,
|
|
269
|
+
mfa,
|
|
270
|
+
code,
|
|
271
|
+
});
|
|
155
272
|
} else {
|
|
156
273
|
globalConfig.removeSession(id);
|
|
157
274
|
globalConfig.setCurrentSession(oldCurrent);
|
|
@@ -241,19 +358,6 @@ export const login = new Command("login")
|
|
|
241
358
|
})
|
|
242
359
|
.action(actionRunner(loginCommand));
|
|
243
360
|
|
|
244
|
-
const deleteSession = async (accountId: string): Promise<void> => {
|
|
245
|
-
try {
|
|
246
|
-
let client = await sdkForConsole();
|
|
247
|
-
let accountClient = new Account(client);
|
|
248
|
-
|
|
249
|
-
await accountClient.deleteSession("current");
|
|
250
|
-
} catch (e) {
|
|
251
|
-
error("Unable to log out, removing locally saved session information");
|
|
252
|
-
} finally {
|
|
253
|
-
globalConfig.removeSession(accountId);
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
|
|
257
361
|
export const logout = new Command("logout")
|
|
258
362
|
.description(commandDescriptions["logout"])
|
|
259
363
|
.configureHelp({
|
|
@@ -263,44 +367,69 @@ export const logout = new Command("logout")
|
|
|
263
367
|
actionRunner(async () => {
|
|
264
368
|
const sessions = globalConfig.getSessions();
|
|
265
369
|
const current = globalConfig.getCurrentSession();
|
|
370
|
+
const originalCurrent = current;
|
|
266
371
|
|
|
267
372
|
if (current === "" || !sessions.length) {
|
|
268
373
|
log("No active sessions found.");
|
|
269
374
|
return;
|
|
270
375
|
}
|
|
271
376
|
if (sessions.length === 1) {
|
|
272
|
-
|
|
377
|
+
// Try to delete from server, then remove locally
|
|
378
|
+
const serverDeleted = await deleteServerSession(current);
|
|
379
|
+
// Remove all local sessions with the same email+endpoint
|
|
380
|
+
const allSessionIds = globalConfig.getSessionIds();
|
|
381
|
+
for (const sessId of allSessionIds) {
|
|
382
|
+
deleteLocalSession(sessId);
|
|
383
|
+
}
|
|
273
384
|
globalConfig.setCurrentSession("");
|
|
274
|
-
|
|
385
|
+
if (!serverDeleted) {
|
|
386
|
+
hint("Could not reach server, removed local session data");
|
|
387
|
+
}
|
|
388
|
+
success("Logged out successfully");
|
|
275
389
|
|
|
276
390
|
return;
|
|
277
391
|
}
|
|
278
392
|
|
|
279
393
|
const answers = await inquirer.prompt(questionsLogout);
|
|
280
394
|
|
|
281
|
-
if (answers.accounts) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
395
|
+
if (answers.accounts?.length) {
|
|
396
|
+
const { serverTargets, localTargets } = planSessionLogout(
|
|
397
|
+
answers.accounts as string[],
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
for (const sessionId of serverTargets) {
|
|
401
|
+
globalConfig.setCurrentSession(sessionId);
|
|
402
|
+
await deleteServerSession(sessionId);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
for (const sessionId of localTargets) {
|
|
406
|
+
deleteLocalSession(sessionId);
|
|
285
407
|
}
|
|
286
408
|
}
|
|
287
409
|
|
|
288
410
|
const remainingSessions = globalConfig.getSessions();
|
|
411
|
+
const hasCurrent = remainingSessions.some(
|
|
412
|
+
(session) => session.id === originalCurrent,
|
|
413
|
+
);
|
|
289
414
|
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
globalConfig.setCurrentSession(
|
|
297
|
-
|
|
298
|
-
success(
|
|
415
|
+
if (remainingSessions.length > 0 && hasCurrent) {
|
|
416
|
+
globalConfig.setCurrentSession(originalCurrent);
|
|
417
|
+
} else if (remainingSessions.length > 0) {
|
|
418
|
+
const nextSession =
|
|
419
|
+
remainingSessions.find((session) => session.email) ??
|
|
420
|
+
remainingSessions[0];
|
|
421
|
+
globalConfig.setCurrentSession(nextSession.id);
|
|
422
|
+
|
|
423
|
+
success(
|
|
424
|
+
nextSession.email
|
|
425
|
+
? `Switched to ${nextSession.email}`
|
|
426
|
+
: `Switched to session at ${nextSession.endpoint}`,
|
|
427
|
+
);
|
|
299
428
|
} else if (remainingSessions.length === 0) {
|
|
300
429
|
globalConfig.setCurrentSession("");
|
|
301
430
|
}
|
|
302
431
|
|
|
303
|
-
success("
|
|
432
|
+
success("Logged out successfully");
|
|
304
433
|
}),
|
|
305
434
|
);
|
|
306
435
|
|
|
@@ -438,10 +567,16 @@ export const client = new Command("client")
|
|
|
438
567
|
if (reset !== undefined) {
|
|
439
568
|
const sessions = globalConfig.getSessions();
|
|
440
569
|
|
|
441
|
-
for (
|
|
442
|
-
globalConfig.setCurrentSession(
|
|
443
|
-
await
|
|
570
|
+
for (const sessionId of sessions.map((session) => session.id)) {
|
|
571
|
+
globalConfig.setCurrentSession(sessionId);
|
|
572
|
+
await deleteServerSession(sessionId);
|
|
444
573
|
}
|
|
574
|
+
|
|
575
|
+
for (const sessionId of globalConfig.getSessionIds()) {
|
|
576
|
+
deleteLocalSession(sessionId);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
globalConfig.setCurrentSession("");
|
|
445
580
|
}
|
|
446
581
|
|
|
447
582
|
if (!debug) {
|
package/lib/commands/push.ts
CHANGED
|
@@ -1100,7 +1100,8 @@ export class Push {
|
|
|
1100
1100
|
this.consoleClient,
|
|
1101
1101
|
);
|
|
1102
1102
|
const variables = await consoleService.variables();
|
|
1103
|
-
|
|
1103
|
+
const domains = variables["_APP_DOMAIN_SITES"].split(",");
|
|
1104
|
+
domain = ID.unique() + "." + domains[0].trim();
|
|
1104
1105
|
} catch (err) {
|
|
1105
1106
|
this.error("Error fetching console variables.");
|
|
1106
1107
|
throw err;
|
|
@@ -2323,7 +2324,7 @@ const pushCollection = async (): Promise<void> => {
|
|
|
2323
2324
|
const { successfullyPushed, errors } = result;
|
|
2324
2325
|
|
|
2325
2326
|
if (successfullyPushed === 0) {
|
|
2326
|
-
|
|
2327
|
+
warn("No collections were pushed.");
|
|
2327
2328
|
} else {
|
|
2328
2329
|
success(`Successfully pushed ${successfullyPushed} collections.`);
|
|
2329
2330
|
}
|
|
@@ -250,6 +250,43 @@ export class Attributes {
|
|
|
250
250
|
encrypt: attribute.encrypt,
|
|
251
251
|
});
|
|
252
252
|
}
|
|
253
|
+
case "varchar":
|
|
254
|
+
return databasesService.createVarcharAttribute({
|
|
255
|
+
databaseId,
|
|
256
|
+
collectionId,
|
|
257
|
+
key: attribute.key,
|
|
258
|
+
size: attribute.size,
|
|
259
|
+
required: attribute.required,
|
|
260
|
+
xdefault: attribute.default,
|
|
261
|
+
array: attribute.array,
|
|
262
|
+
});
|
|
263
|
+
case "text":
|
|
264
|
+
return databasesService.createTextAttribute({
|
|
265
|
+
databaseId,
|
|
266
|
+
collectionId,
|
|
267
|
+
key: attribute.key,
|
|
268
|
+
required: attribute.required,
|
|
269
|
+
xdefault: attribute.default,
|
|
270
|
+
array: attribute.array,
|
|
271
|
+
});
|
|
272
|
+
case "mediumtext":
|
|
273
|
+
return databasesService.createMediumtextAttribute({
|
|
274
|
+
databaseId,
|
|
275
|
+
collectionId,
|
|
276
|
+
key: attribute.key,
|
|
277
|
+
required: attribute.required,
|
|
278
|
+
xdefault: attribute.default,
|
|
279
|
+
array: attribute.array,
|
|
280
|
+
});
|
|
281
|
+
case "longtext":
|
|
282
|
+
return databasesService.createLongtextAttribute({
|
|
283
|
+
databaseId,
|
|
284
|
+
collectionId,
|
|
285
|
+
key: attribute.key,
|
|
286
|
+
required: attribute.required,
|
|
287
|
+
xdefault: attribute.default,
|
|
288
|
+
array: attribute.array,
|
|
289
|
+
});
|
|
253
290
|
case "integer":
|
|
254
291
|
return databasesService.createIntegerAttribute({
|
|
255
292
|
databaseId,
|
|
@@ -382,6 +419,39 @@ export class Attributes {
|
|
|
382
419
|
xdefault: attribute.default,
|
|
383
420
|
});
|
|
384
421
|
}
|
|
422
|
+
case "varchar":
|
|
423
|
+
return databasesService.updateVarcharAttribute({
|
|
424
|
+
databaseId,
|
|
425
|
+
collectionId,
|
|
426
|
+
key: attribute.key,
|
|
427
|
+
required: attribute.required,
|
|
428
|
+
xdefault: attribute.default,
|
|
429
|
+
size: attribute.size,
|
|
430
|
+
});
|
|
431
|
+
case "text":
|
|
432
|
+
return databasesService.updateTextAttribute({
|
|
433
|
+
databaseId,
|
|
434
|
+
collectionId,
|
|
435
|
+
key: attribute.key,
|
|
436
|
+
required: attribute.required,
|
|
437
|
+
xdefault: attribute.default,
|
|
438
|
+
});
|
|
439
|
+
case "mediumtext":
|
|
440
|
+
return databasesService.updateMediumtextAttribute({
|
|
441
|
+
databaseId,
|
|
442
|
+
collectionId,
|
|
443
|
+
key: attribute.key,
|
|
444
|
+
required: attribute.required,
|
|
445
|
+
xdefault: attribute.default,
|
|
446
|
+
});
|
|
447
|
+
case "longtext":
|
|
448
|
+
return databasesService.updateLongtextAttribute({
|
|
449
|
+
databaseId,
|
|
450
|
+
collectionId,
|
|
451
|
+
key: attribute.key,
|
|
452
|
+
required: attribute.required,
|
|
453
|
+
xdefault: attribute.default,
|
|
454
|
+
});
|
|
385
455
|
case "integer":
|
|
386
456
|
return databasesService.updateIntegerAttribute({
|
|
387
457
|
databaseId,
|
package/lib/config.ts
CHANGED
|
@@ -749,15 +749,15 @@ class Global extends Config<GlobalConfigData> {
|
|
|
749
749
|
|
|
750
750
|
sessions.forEach((sessionId) => {
|
|
751
751
|
const sessionData = (this.data as any)[sessionId];
|
|
752
|
-
const email = sessionData[Global.PREFERENCE_EMAIL];
|
|
753
|
-
const endpoint = sessionData[Global.PREFERENCE_ENDPOINT];
|
|
752
|
+
const email = sessionData[Global.PREFERENCE_EMAIL] ?? "";
|
|
753
|
+
const endpoint = sessionData[Global.PREFERENCE_ENDPOINT] ?? "";
|
|
754
754
|
const key = `${email}|${endpoint}`;
|
|
755
755
|
|
|
756
756
|
if (sessionId === current || !sessionMap.has(key)) {
|
|
757
757
|
sessionMap.set(key, {
|
|
758
758
|
id: sessionId,
|
|
759
|
-
endpoint
|
|
760
|
-
email
|
|
759
|
+
endpoint,
|
|
760
|
+
email,
|
|
761
761
|
});
|
|
762
762
|
}
|
|
763
763
|
});
|
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.3.0';
|
|
5
5
|
export const SDK_NAME = 'Command Line';
|
|
6
6
|
export const SDK_PLATFORM = 'console';
|
|
7
7
|
export const SDK_LANGUAGE = 'cli';
|
package/lib/questions.ts
CHANGED
|
@@ -28,6 +28,7 @@ interface Choice {
|
|
|
28
28
|
value: any;
|
|
29
29
|
disabled?: boolean | string;
|
|
30
30
|
current?: boolean;
|
|
31
|
+
short?: string;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
interface Question {
|
|
@@ -752,7 +753,7 @@ export const questionsLogin: Question[] = [
|
|
|
752
753
|
when: (answers: Answers) => answers.method !== "select",
|
|
753
754
|
},
|
|
754
755
|
{
|
|
755
|
-
type: "
|
|
756
|
+
type: "list",
|
|
756
757
|
name: "accountId",
|
|
757
758
|
message: "Select an account to use",
|
|
758
759
|
choices() {
|
|
@@ -772,6 +773,7 @@ export const questionsLogin: Question[] = [
|
|
|
772
773
|
data.push({
|
|
773
774
|
current: current === session.id,
|
|
774
775
|
value: session.id,
|
|
776
|
+
short: `${session.email} (${session.endpoint})`,
|
|
775
777
|
name: `${session.email.padEnd(longestEmail)} ${current === session.id ? chalk.green.bold("current") : " ".repeat(6)} ${session.endpoint}`,
|
|
776
778
|
});
|
|
777
779
|
}
|
|
@@ -10,6 +10,10 @@ export class CSharp extends LanguageMeta {
|
|
|
10
10
|
let type = "";
|
|
11
11
|
switch (attribute.type) {
|
|
12
12
|
case AttributeType.STRING:
|
|
13
|
+
case AttributeType.TEXT:
|
|
14
|
+
case AttributeType.VARCHAR:
|
|
15
|
+
case AttributeType.MEDIUMTEXT:
|
|
16
|
+
case AttributeType.LONGTEXT:
|
|
13
17
|
case AttributeType.DATETIME:
|
|
14
18
|
type = "string";
|
|
15
19
|
if (attribute.format === AttributeType.ENUM) {
|
|
@@ -126,7 +130,7 @@ public class <%= toPascalCase(collection.name) %>
|
|
|
126
130
|
}
|
|
127
131
|
// ARRAY TYPES
|
|
128
132
|
} else if (attribute.array) {
|
|
129
|
-
if (
|
|
133
|
+
if (['string', 'text', 'varchar', 'mediumtext', 'longtext', 'datetime', 'email'].includes(attribute.type)) {
|
|
130
134
|
-%>((IEnumerable<object>)map["<%- attribute.key %>"]).Select(x => x?.ToString())<%- attribute.required ? '.Where(x => x != null)' : '' %>.ToList()!<%
|
|
131
135
|
} else if (attribute.type === 'integer') {
|
|
132
136
|
-%>((IEnumerable<object>)map["<%- attribute.key %>"]).Select(x => <%- !attribute.required ? 'x == null ? (long?)null : ' : '' %>Convert.ToInt64(x)).ToList()<%
|
|
@@ -142,7 +146,7 @@ public class <%= toPascalCase(collection.name) %>
|
|
|
142
146
|
-%><%- !attribute.required ? 'map["' + attribute.key + '"] == null ? null : ' : '' %>Convert.ToDouble(map["<%- attribute.key %>"])<%
|
|
143
147
|
} else if (attribute.type === 'boolean') {
|
|
144
148
|
-%>(<%- getType(attribute, collections, collection.name) %>)map["<%- attribute.key %>"]<%
|
|
145
|
-
} else if (
|
|
149
|
+
} else if (['string', 'text', 'varchar', 'mediumtext', 'longtext', 'datetime', 'email'].includes(attribute.type)) {
|
|
146
150
|
-%>map["<%- attribute.key %>"]<%- !attribute.required ? '?' : '' %>.ToString()<%- attribute.required ? '!' : ''%><%
|
|
147
151
|
} else {
|
|
148
152
|
-%>default<%
|
|
@@ -72,6 +72,10 @@ export class Dart extends LanguageMeta {
|
|
|
72
72
|
let type = "";
|
|
73
73
|
switch (attribute.type) {
|
|
74
74
|
case AttributeType.STRING:
|
|
75
|
+
case AttributeType.TEXT:
|
|
76
|
+
case AttributeType.VARCHAR:
|
|
77
|
+
case AttributeType.MEDIUMTEXT:
|
|
78
|
+
case AttributeType.LONGTEXT:
|
|
75
79
|
case AttributeType.DATETIME:
|
|
76
80
|
type = "String";
|
|
77
81
|
if (attribute.format === AttributeType.ENUM) {
|
|
@@ -193,7 +197,7 @@ class <%= toPascalCase(collection.name) %> {
|
|
|
193
197
|
factory <%= toPascalCase(collection.name) %>.fromMap(Map<String, dynamic> map) {
|
|
194
198
|
return <%= toPascalCase(collection.name) %>(<% if (__attrs.length > 0) { %>
|
|
195
199
|
<% for (const [index, attribute] of Object.entries(__attrs)) { -%>
|
|
196
|
-
<%= strict ? toCamelCase(attribute.key) : attribute.key %>: <% if (
|
|
200
|
+
<%= strict ? toCamelCase(attribute.key) : attribute.key %>: <% if (['${AttributeType.STRING}', '${AttributeType.TEXT}', '${AttributeType.VARCHAR}', '${AttributeType.MEDIUMTEXT}', '${AttributeType.LONGTEXT}', '${AttributeType.EMAIL}', '${AttributeType.DATETIME}'].includes(attribute.type)) { -%>
|
|
197
201
|
<% if (attribute.format === '${AttributeType.ENUM}') { -%>
|
|
198
202
|
<% if (attribute.array) { -%>
|
|
199
203
|
(map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(collection.name) %><%- toPascalCase(attribute.key) %>.values.firstWhere((element) => element.value == e)).toList()<% } else { -%>
|
|
@@ -10,6 +10,10 @@ export class Java extends LanguageMeta {
|
|
|
10
10
|
let type = "";
|
|
11
11
|
switch (attribute.type) {
|
|
12
12
|
case AttributeType.STRING:
|
|
13
|
+
case AttributeType.TEXT:
|
|
14
|
+
case AttributeType.VARCHAR:
|
|
15
|
+
case AttributeType.MEDIUMTEXT:
|
|
16
|
+
case AttributeType.LONGTEXT:
|
|
13
17
|
case AttributeType.DATETIME:
|
|
14
18
|
type = "String";
|
|
15
19
|
if (attribute.format === AttributeType.ENUM) {
|
|
@@ -8,6 +8,10 @@ export class JavaScript extends LanguageMeta {
|
|
|
8
8
|
let type = "";
|
|
9
9
|
switch (attribute.type) {
|
|
10
10
|
case AttributeType.STRING:
|
|
11
|
+
case AttributeType.TEXT:
|
|
12
|
+
case AttributeType.VARCHAR:
|
|
13
|
+
case AttributeType.MEDIUMTEXT:
|
|
14
|
+
case AttributeType.LONGTEXT:
|
|
11
15
|
case AttributeType.DATETIME:
|
|
12
16
|
type = "string";
|
|
13
17
|
if (attribute.format === AttributeType.ENUM) {
|
|
@@ -10,6 +10,10 @@ export class Kotlin extends LanguageMeta {
|
|
|
10
10
|
let type = "";
|
|
11
11
|
switch (attribute.type) {
|
|
12
12
|
case AttributeType.STRING:
|
|
13
|
+
case AttributeType.TEXT:
|
|
14
|
+
case AttributeType.VARCHAR:
|
|
15
|
+
case AttributeType.MEDIUMTEXT:
|
|
16
|
+
case AttributeType.LONGTEXT:
|
|
13
17
|
case AttributeType.DATETIME:
|
|
14
18
|
type = "String";
|
|
15
19
|
if (attribute.format === AttributeType.ENUM) {
|
|
@@ -13,6 +13,10 @@ export class PHP extends LanguageMeta {
|
|
|
13
13
|
let type = "";
|
|
14
14
|
switch (attribute.type) {
|
|
15
15
|
case AttributeType.STRING:
|
|
16
|
+
case AttributeType.TEXT:
|
|
17
|
+
case AttributeType.VARCHAR:
|
|
18
|
+
case AttributeType.MEDIUMTEXT:
|
|
19
|
+
case AttributeType.LONGTEXT:
|
|
16
20
|
case AttributeType.DATETIME:
|
|
17
21
|
type = "string";
|
|
18
22
|
if (attribute.format === AttributeType.ENUM) {
|