appwrite-cli 13.6.0 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +66 -0
- package/CHANGELOG.md +14 -0
- package/README.md +2 -2
- package/cli.ts +3 -3
- package/dist/bundle-win-arm64.mjs +608 -310
- package/dist/cli.cjs +608 -310
- package/dist/index.cjs +354 -183
- package/dist/index.js +354 -183
- 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 +2 -0
- package/dist/lib/commands/generate.d.ts.map +1 -1
- package/dist/lib/commands/generators/base.d.ts +25 -2
- package/dist/lib/commands/generators/base.d.ts.map +1 -1
- package/dist/lib/commands/generators/index.d.ts +1 -1
- package/dist/lib/commands/generators/index.d.ts.map +1 -1
- package/dist/lib/commands/generators/typescript/databases.d.ts +2 -2
- package/dist/lib/commands/generators/typescript/databases.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/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/projects/update-status.md +5 -0
- package/docs/examples/sites/create-deployment.md +1 -2
- 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 +23 -8
- package/lib/commands/generators/base.ts +33 -2
- package/lib/commands/generators/index.ts +1 -0
- package/lib/commands/generators/typescript/databases.ts +31 -21
- 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/services/account.ts +1 -1
- package/lib/commands/services/databases.ts +20 -19
- package/lib/commands/services/health.ts +13 -0
- package/lib/commands/services/messaging.ts +1 -1
- package/lib/commands/services/projects.ts +25 -0
- package/lib/commands/services/sites.ts +8 -3
- package/lib/commands/services/tables-db.ts +3 -2
- package/lib/commands/services/teams.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 +15 -7
- 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/lib/commands/generate.ts
CHANGED
|
@@ -25,6 +25,8 @@ export interface GenerateCommandOptions {
|
|
|
25
25
|
output: string;
|
|
26
26
|
language?: string;
|
|
27
27
|
server?: ServerSideOverride;
|
|
28
|
+
appwriteImportSource?: string;
|
|
29
|
+
importExtension?: string;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
const generateAction = async (
|
|
@@ -77,17 +79,18 @@ const generateAction = async (
|
|
|
77
79
|
} else {
|
|
78
80
|
log(`Detected language: ${detectedLanguage} (${detection.reason})`);
|
|
79
81
|
}
|
|
80
|
-
} catch (err
|
|
82
|
+
} catch (err) {
|
|
81
83
|
const supported = getSupportedLanguages().join(", ");
|
|
84
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
82
85
|
error(
|
|
83
|
-
`${
|
|
86
|
+
`${message}\nUse --language to specify the target language. Supported: ${supported}`,
|
|
84
87
|
);
|
|
85
88
|
process.exit(1);
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
if (typeof
|
|
90
|
-
|
|
92
|
+
if (typeof generator.setServerSideOverride === "function") {
|
|
93
|
+
generator.setServerSideOverride(serverSideOverride);
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
const config: ConfigType = {
|
|
@@ -113,7 +116,10 @@ const generateAction = async (
|
|
|
113
116
|
);
|
|
114
117
|
|
|
115
118
|
try {
|
|
116
|
-
const result = await generator.generate(config
|
|
119
|
+
const result = await generator.generate(config, {
|
|
120
|
+
appwriteImportSource: options.appwriteImportSource,
|
|
121
|
+
importExtension: options.importExtension,
|
|
122
|
+
});
|
|
117
123
|
await generator.writeFiles(absoluteOutputDir, result);
|
|
118
124
|
|
|
119
125
|
const generatedFiles = generator.getGeneratedFilePaths(result);
|
|
@@ -130,7 +136,7 @@ const generateAction = async (
|
|
|
130
136
|
const firstEntity = entities?.[0];
|
|
131
137
|
const dbId = firstEntity?.databaseId ?? "databaseId";
|
|
132
138
|
const tableName = firstEntity?.name ?? "tableName";
|
|
133
|
-
const importExt = detectImportExtension();
|
|
139
|
+
const importExt = options.importExtension ?? detectImportExtension();
|
|
134
140
|
|
|
135
141
|
console.log("");
|
|
136
142
|
log(`Import the generated SDK in your project:`);
|
|
@@ -149,8 +155,9 @@ const generateAction = async (
|
|
|
149
155
|
` await mydb.use(${JSON.stringify(tableName)}).create({ ... });`,
|
|
150
156
|
);
|
|
151
157
|
}
|
|
152
|
-
} catch (err
|
|
153
|
-
|
|
158
|
+
} catch (err) {
|
|
159
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
160
|
+
error(`Failed to generate SDK: ${message}`);
|
|
154
161
|
process.exit(1);
|
|
155
162
|
}
|
|
156
163
|
};
|
|
@@ -173,6 +180,14 @@ export const generate = new Command("generate")
|
|
|
173
180
|
"Override server-side generation (auto|true|false)",
|
|
174
181
|
"auto",
|
|
175
182
|
)
|
|
183
|
+
.option(
|
|
184
|
+
"--appwrite-import-source <source>",
|
|
185
|
+
"Override Appwrite import source in generated files (e.g. node-appwrite, appwrite, @appwrite.io/console). Auto-detected from package.json/deno.json if not provided.",
|
|
186
|
+
)
|
|
187
|
+
.option(
|
|
188
|
+
"--import-extension <ext>",
|
|
189
|
+
'Override import file extension in generated files (.js for ESM, empty string for CJS). Auto-detected from package.json "type" field if not provided.',
|
|
190
|
+
)
|
|
176
191
|
.addHelpText(
|
|
177
192
|
"after",
|
|
178
193
|
`
|
|
@@ -26,6 +26,24 @@ export interface GenerateResult {
|
|
|
26
26
|
constantsContent: string;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Options for overriding auto-detected generation settings.
|
|
31
|
+
*/
|
|
32
|
+
export interface GenerateOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Override the Appwrite import source used in generated files.
|
|
35
|
+
* Auto-detected from package.json/deno.json if not provided.
|
|
36
|
+
* Examples: "node-appwrite", "appwrite", "@appwrite.io/console"
|
|
37
|
+
*/
|
|
38
|
+
appwriteImportSource?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Override the import file extension used in generated files.
|
|
41
|
+
* Auto-detected from package.json "type" field / deno.json if not provided.
|
|
42
|
+
* Use ".js" for ESM projects or "" for CJS/unknown projects.
|
|
43
|
+
*/
|
|
44
|
+
importExtension?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
29
47
|
/**
|
|
30
48
|
* Base interface for all language-specific database generators.
|
|
31
49
|
* Implement this interface to add support for new languages.
|
|
@@ -44,12 +62,16 @@ export interface IDatabasesGenerator {
|
|
|
44
62
|
/**
|
|
45
63
|
* Generate the SDK files from the configuration.
|
|
46
64
|
* @param config - The project configuration containing tables/collections
|
|
65
|
+
* @param options - Optional overrides for auto-detected settings (e.g. import source, extension)
|
|
47
66
|
* @returns Promise resolving to named file contents:
|
|
48
67
|
* `dbContent` (`databases.ts`), `typesContent` (`types.ts`),
|
|
49
68
|
* `indexContent` (`index.ts`), and `constantsContent` (`constants.ts`).
|
|
50
69
|
* Import your generated SDK from `index.ts` (or `index.js` after transpilation).
|
|
51
70
|
*/
|
|
52
|
-
generate(
|
|
71
|
+
generate(
|
|
72
|
+
config: ConfigType,
|
|
73
|
+
options?: GenerateOptions,
|
|
74
|
+
): Promise<GenerateResult>;
|
|
53
75
|
|
|
54
76
|
/**
|
|
55
77
|
* Write the generated files to disk.
|
|
@@ -64,6 +86,12 @@ export interface IDatabasesGenerator {
|
|
|
64
86
|
* @param result - The generation result
|
|
65
87
|
*/
|
|
66
88
|
getGeneratedFilePaths(result: GenerateResult): string[];
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Optional method to override server-side generation behavior.
|
|
92
|
+
* @param override - The override value
|
|
93
|
+
*/
|
|
94
|
+
setServerSideOverride?(override: "auto" | "true" | "false"): void;
|
|
67
95
|
}
|
|
68
96
|
|
|
69
97
|
/**
|
|
@@ -74,7 +102,10 @@ export abstract class BaseDatabasesGenerator implements IDatabasesGenerator {
|
|
|
74
102
|
abstract readonly language: SupportedLanguage;
|
|
75
103
|
abstract readonly fileExtension: string;
|
|
76
104
|
|
|
77
|
-
abstract generate(
|
|
105
|
+
abstract generate(
|
|
106
|
+
config: ConfigType,
|
|
107
|
+
options?: GenerateOptions,
|
|
108
|
+
): Promise<GenerateResult>;
|
|
78
109
|
|
|
79
110
|
async writeFiles(outputDir: string, result: GenerateResult): Promise<void> {
|
|
80
111
|
const sdkDir = path.join(outputDir, SDK_TITLE_LOWER);
|
|
@@ -6,6 +6,7 @@ import { TypeScript } from "../../../type-generation/languages/typescript.js";
|
|
|
6
6
|
import { SDK_TITLE, EXECUTABLE_NAME } from "../../../constants.js";
|
|
7
7
|
import {
|
|
8
8
|
BaseDatabasesGenerator,
|
|
9
|
+
GenerateOptions,
|
|
9
10
|
GenerateResult,
|
|
10
11
|
SupportedLanguage,
|
|
11
12
|
} from "../base.js";
|
|
@@ -240,7 +241,7 @@ export type DatabaseHandle<D extends DatabaseId> = {
|
|
|
240
241
|
use: <T extends keyof DatabaseTableMap[D] & string>(tableId: T) => DatabaseTableMap[D][T];
|
|
241
242
|
${
|
|
242
243
|
supportsServerSide
|
|
243
|
-
? ` create: (tableId: string, name: string, options?: { permissions?: ${PERMISSION_CALLBACK_INLINE}; rowSecurity?: boolean; enabled?: boolean; columns?:
|
|
244
|
+
? ` create: (tableId: string, name: string, options?: { permissions?: ${PERMISSION_CALLBACK_INLINE}; rowSecurity?: boolean; enabled?: boolean; columns?: object[]; indexes?: object[] }) => Promise<Models.Table>;
|
|
244
245
|
update: <T extends keyof DatabaseTableMap[D] & string>(tableId: T, options?: { name?: string; permissions?: ${PERMISSION_CALLBACK_INLINE}; rowSecurity?: boolean; enabled?: boolean }) => Promise<Models.Table>;
|
|
245
246
|
delete: <T extends keyof DatabaseTableMap[D] & string>(tableId: T) => Promise<void>;`
|
|
246
247
|
: ""
|
|
@@ -259,14 +260,13 @@ ${
|
|
|
259
260
|
};`;
|
|
260
261
|
}
|
|
261
262
|
|
|
262
|
-
private generateTypesFile(config: ConfigType): string {
|
|
263
|
+
private generateTypesFile(config: ConfigType, appwriteDep: string): string {
|
|
263
264
|
const entities = config.tables?.length ? config.tables : config.collections;
|
|
264
265
|
|
|
265
266
|
if (!entities || entities.length === 0) {
|
|
266
267
|
return "// No tables or collections found in configuration\n";
|
|
267
268
|
}
|
|
268
269
|
|
|
269
|
-
const appwriteDep = getAppwriteDependency();
|
|
270
270
|
const enums = this.generateEnums(entities);
|
|
271
271
|
const types = entities
|
|
272
272
|
.map((entity: Entity) => this.generateTableType(entity, entities))
|
|
@@ -330,26 +330,26 @@ ${
|
|
|
330
330
|
if (!supportsBulk) return "";
|
|
331
331
|
|
|
332
332
|
return `
|
|
333
|
-
createMany: (rows:
|
|
333
|
+
createMany: (rows: object[], options?: { transactionId?: string }) =>
|
|
334
334
|
tablesDB.createRows({
|
|
335
335
|
databaseId,
|
|
336
336
|
tableId,
|
|
337
337
|
rows,
|
|
338
338
|
transactionId: options?.transactionId,
|
|
339
339
|
}),
|
|
340
|
-
updateMany: (data:
|
|
340
|
+
updateMany: (data: object, options?: { queries?: (q: QueryBuilder<T>) => string[]; transactionId?: string }) =>
|
|
341
341
|
tablesDB.updateRows({
|
|
342
342
|
databaseId,
|
|
343
343
|
tableId,
|
|
344
344
|
data,
|
|
345
|
-
queries: options?.queries?.(createQueryBuilder()),
|
|
345
|
+
queries: options?.queries?.(createQueryBuilder<T>()),
|
|
346
346
|
transactionId: options?.transactionId,
|
|
347
347
|
}),
|
|
348
|
-
deleteMany: (options?: { queries?: (q:
|
|
348
|
+
deleteMany: (options?: { queries?: (q: QueryBuilder<T>) => string[]; transactionId?: string }) =>
|
|
349
349
|
tablesDB.deleteRows({
|
|
350
350
|
databaseId,
|
|
351
351
|
tableId,
|
|
352
|
-
queries: options?.queries?.(createQueryBuilder()),
|
|
352
|
+
queries: options?.queries?.(createQueryBuilder<T>()),
|
|
353
353
|
transactionId: options?.transactionId,
|
|
354
354
|
}),`;
|
|
355
355
|
}
|
|
@@ -364,13 +364,17 @@ ${
|
|
|
364
364
|
return `
|
|
365
365
|
// Remove bulk methods for tables with relationships
|
|
366
366
|
if (!hasBulkMethods(databaseId, tableId)) {
|
|
367
|
-
delete (api as
|
|
368
|
-
delete (api as
|
|
369
|
-
delete (api as
|
|
367
|
+
delete (api as Record<string, unknown>).createMany;
|
|
368
|
+
delete (api as Record<string, unknown>).updateMany;
|
|
369
|
+
delete (api as Record<string, unknown>).deleteMany;
|
|
370
370
|
}`;
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
private generateDatabasesFile(
|
|
373
|
+
private generateDatabasesFile(
|
|
374
|
+
config: ConfigType,
|
|
375
|
+
importExt: string,
|
|
376
|
+
appwriteDep: string,
|
|
377
|
+
): string {
|
|
374
378
|
const entities = config.tables?.length ? config.tables : config.collections;
|
|
375
379
|
|
|
376
380
|
if (!entities || entities.length === 0) {
|
|
@@ -378,7 +382,6 @@ ${
|
|
|
378
382
|
}
|
|
379
383
|
|
|
380
384
|
const entitiesByDb = this.groupEntitiesByDb(entities);
|
|
381
|
-
const appwriteDep = getAppwriteDependency();
|
|
382
385
|
const supportsServerSide = supportsServerSideMethods(
|
|
383
386
|
appwriteDep,
|
|
384
387
|
this.serverSideOverride,
|
|
@@ -405,8 +408,10 @@ ${
|
|
|
405
408
|
});
|
|
406
409
|
}
|
|
407
410
|
|
|
408
|
-
private generateConstantsFile(
|
|
409
|
-
|
|
411
|
+
private generateConstantsFile(
|
|
412
|
+
config: ConfigType,
|
|
413
|
+
appwriteDep: string,
|
|
414
|
+
): string {
|
|
410
415
|
const supportsServerSide = supportsServerSideMethods(
|
|
411
416
|
appwriteDep,
|
|
412
417
|
this.serverSideOverride,
|
|
@@ -420,12 +425,17 @@ ${
|
|
|
420
425
|
});
|
|
421
426
|
}
|
|
422
427
|
|
|
423
|
-
async generate(
|
|
428
|
+
async generate(
|
|
429
|
+
config: ConfigType,
|
|
430
|
+
options?: GenerateOptions,
|
|
431
|
+
): Promise<GenerateResult> {
|
|
424
432
|
if (!config.projectId) {
|
|
425
433
|
throw new Error("Project ID is required in configuration");
|
|
426
434
|
}
|
|
427
435
|
|
|
428
|
-
const
|
|
436
|
+
const appwriteDep =
|
|
437
|
+
options?.appwriteImportSource ?? getAppwriteDependency();
|
|
438
|
+
const importExt = options?.importExtension ?? detectImportExtension();
|
|
429
439
|
|
|
430
440
|
const hasEntities =
|
|
431
441
|
(config.tables && config.tables.length > 0) ||
|
|
@@ -439,15 +449,15 @@ ${
|
|
|
439
449
|
dbContent: "// No tables or collections found in configuration\n",
|
|
440
450
|
typesContent: "// No tables or collections found in configuration\n",
|
|
441
451
|
indexContent: this.generateIndexFile(importExt),
|
|
442
|
-
constantsContent: this.generateConstantsFile(config),
|
|
452
|
+
constantsContent: this.generateConstantsFile(config, appwriteDep),
|
|
443
453
|
};
|
|
444
454
|
}
|
|
445
455
|
|
|
446
456
|
return {
|
|
447
|
-
dbContent: this.generateDatabasesFile(config, importExt),
|
|
448
|
-
typesContent: this.generateTypesFile(config),
|
|
457
|
+
dbContent: this.generateDatabasesFile(config, importExt, appwriteDep),
|
|
458
|
+
typesContent: this.generateTypesFile(config, appwriteDep),
|
|
449
459
|
indexContent: this.generateIndexFile(importExt),
|
|
450
|
-
constantsContent: this.generateConstantsFile(config),
|
|
460
|
+
constantsContent: this.generateConstantsFile(config, appwriteDep),
|
|
451
461
|
};
|
|
452
462
|
}
|
|
453
463
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Client, TablesDB, ID, Query, type Models, Permission, Role } from '{{appwriteDep}}';
|
|
2
|
-
import type { DatabaseHandle, DatabaseId, DatabaseTableMap, DatabaseTables, QueryBuilder, PermissionBuilder, RoleBuilder, RoleString } from './types{{importExt}}';
|
|
2
|
+
import type { DatabaseHandle, DatabaseId, DatabaseTableMap, DatabaseTables, QueryBuilder, QueryValue, PermissionBuilder, RoleBuilder, RoleString } from './types{{importExt}}';
|
|
3
3
|
{{#if supportsServerSide}}
|
|
4
4
|
import { PROJECT_ID, ENDPOINT, API_KEY } from './constants{{importExt}}';
|
|
5
5
|
{{else}}
|
|
@@ -7,19 +7,19 @@ import { PROJECT_ID, ENDPOINT } from './constants{{importExt}}';
|
|
|
7
7
|
{{/if}}
|
|
8
8
|
|
|
9
9
|
const createQueryBuilder = <T>(): QueryBuilder<T> => ({
|
|
10
|
-
equal: (field, value) => Query.equal(String(field), value as
|
|
11
|
-
notEqual: (field, value) => Query.notEqual(String(field), value as
|
|
12
|
-
lessThan: (field, value) => Query.lessThan(String(field), value as
|
|
13
|
-
lessThanEqual: (field, value) => Query.lessThanEqual(String(field), value as
|
|
14
|
-
greaterThan: (field, value) => Query.greaterThan(String(field), value as
|
|
15
|
-
greaterThanEqual: (field, value) => Query.greaterThanEqual(String(field), value as
|
|
16
|
-
contains: (field, value) => Query.contains(String(field), value as
|
|
10
|
+
equal: (field, value) => Query.equal(String(field), value as QueryValue),
|
|
11
|
+
notEqual: (field, value) => Query.notEqual(String(field), value as QueryValue),
|
|
12
|
+
lessThan: (field, value) => Query.lessThan(String(field), value as QueryValue),
|
|
13
|
+
lessThanEqual: (field, value) => Query.lessThanEqual(String(field), value as QueryValue),
|
|
14
|
+
greaterThan: (field, value) => Query.greaterThan(String(field), value as QueryValue),
|
|
15
|
+
greaterThanEqual: (field, value) => Query.greaterThanEqual(String(field), value as QueryValue),
|
|
16
|
+
contains: (field, value) => Query.contains(String(field), value as string | QueryValue[]),
|
|
17
17
|
search: (field, value) => Query.search(String(field), value),
|
|
18
18
|
isNull: (field) => Query.isNull(String(field)),
|
|
19
19
|
isNotNull: (field) => Query.isNotNull(String(field)),
|
|
20
20
|
startsWith: (field, value) => Query.startsWith(String(field), value),
|
|
21
21
|
endsWith: (field, value) => Query.endsWith(String(field), value),
|
|
22
|
-
between: (field, start, end) => Query.between(String(field), start as
|
|
22
|
+
between: (field, start, end) => Query.between(String(field), start as string | number, end as string | number),
|
|
23
23
|
select: (fields) => Query.select(fields.map(String)),
|
|
24
24
|
orderAsc: (field) => Query.orderAsc(String(field)),
|
|
25
25
|
orderDesc: (field) => Query.orderDesc(String(field)),
|
|
@@ -62,12 +62,12 @@ function createTableApi<T extends Models.Row>(
|
|
|
62
62
|
tableId: string,
|
|
63
63
|
) {
|
|
64
64
|
return {
|
|
65
|
-
create: (data:
|
|
65
|
+
create: (data: Omit<T, keyof Models.Row>, options?: { rowId?: string; permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; transactionId?: string }) =>
|
|
66
66
|
tablesDB.createRow<T>({
|
|
67
67
|
databaseId,
|
|
68
68
|
tableId,
|
|
69
69
|
rowId: options?.rowId ?? ID.unique(),
|
|
70
|
-
data,
|
|
70
|
+
data: data as T extends Models.DefaultRow ? Partial<Models.Row> & Record<string, unknown> : Partial<Models.Row> & Omit<T, keyof Models.Row>,
|
|
71
71
|
permissions: resolvePermissions(options?.permissions),
|
|
72
72
|
transactionId: options?.transactionId,
|
|
73
73
|
}),
|
|
@@ -77,12 +77,12 @@ function createTableApi<T extends Models.Row>(
|
|
|
77
77
|
tableId,
|
|
78
78
|
rowId: id,
|
|
79
79
|
}),
|
|
80
|
-
update: (id: string, data:
|
|
80
|
+
update: (id: string, data: Partial<Omit<T, keyof Models.Row>>, options?: { permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; transactionId?: string }) =>
|
|
81
81
|
tablesDB.updateRow<T>({
|
|
82
82
|
databaseId,
|
|
83
83
|
tableId,
|
|
84
84
|
rowId: id,
|
|
85
|
-
data,
|
|
85
|
+
data: data as T extends Models.DefaultRow ? Partial<Models.Row> & Record<string, unknown> : Partial<Models.Row> & Partial<Omit<T, keyof Models.Row>>,
|
|
86
86
|
...(options?.permissions ? { permissions: resolvePermissions(options.permissions) } : {}),
|
|
87
87
|
transactionId: options?.transactionId,
|
|
88
88
|
}),
|
|
@@ -94,7 +94,7 @@ function createTableApi<T extends Models.Row>(
|
|
|
94
94
|
transactionId: options?.transactionId,
|
|
95
95
|
});
|
|
96
96
|
},
|
|
97
|
-
list: (options?: { queries?: (q:
|
|
97
|
+
list: (options?: { queries?: (q: QueryBuilder<T>) => string[] }) =>
|
|
98
98
|
tablesDB.listRows<T>({
|
|
99
99
|
databaseId,
|
|
100
100
|
tableId,
|
|
@@ -129,7 +129,7 @@ function createDatabaseHandle<D extends DatabaseId>(
|
|
|
129
129
|
return tableApiCache.get(tableId) as DatabaseTableMap[D][T];
|
|
130
130
|
},
|
|
131
131
|
{{#if supportsServerSide}}
|
|
132
|
-
create: (tableId: string, name: string, options?: { permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; rowSecurity?: boolean; enabled?: boolean; columns?:
|
|
132
|
+
create: (tableId: string, name: string, options?: { permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; rowSecurity?: boolean; enabled?: boolean; columns?: object[]; indexes?: object[] }) =>
|
|
133
133
|
tablesDB.createTable({
|
|
134
134
|
databaseId,
|
|
135
135
|
tableId,
|
|
@@ -148,7 +148,7 @@ function createDatabaseHandle<D extends DatabaseId>(
|
|
|
148
148
|
return tablesDB.updateTable({
|
|
149
149
|
databaseId,
|
|
150
150
|
tableId: resolvedTableId,
|
|
151
|
-
name: options?.name
|
|
151
|
+
name: options?.name,
|
|
152
152
|
permissions: resolvePermissions(options?.permissions),
|
|
153
153
|
rowSecurity: options?.rowSecurity,
|
|
154
154
|
enabled: options?.enabled,
|
package/lib/commands/generic.ts
CHANGED
|
@@ -28,9 +28,14 @@ import ClientLegacy from "../client.js";
|
|
|
28
28
|
|
|
29
29
|
const DEFAULT_ENDPOINT = "https://cloud.appwrite.io/v1";
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
interface AppwriteError {
|
|
32
|
+
type?: string;
|
|
33
|
+
response?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const isMfaRequiredError = (err: unknown): err is AppwriteError =>
|
|
37
|
+
(err as AppwriteError)?.type === "user_more_factors_required" ||
|
|
38
|
+
(err as AppwriteError)?.response === "user_more_factors_required";
|
|
34
39
|
|
|
35
40
|
const createLegacyConsoleClient = (endpoint: string): ClientLegacy => {
|
|
36
41
|
const legacyClient = new ClientLegacy();
|
|
@@ -52,7 +57,7 @@ const completeMfaLogin = async ({
|
|
|
52
57
|
legacyClient: ClientLegacy;
|
|
53
58
|
mfa?: string;
|
|
54
59
|
code?: string;
|
|
55
|
-
}): Promise<
|
|
60
|
+
}): Promise<unknown> => {
|
|
56
61
|
let accountClient = new Account(client);
|
|
57
62
|
|
|
58
63
|
const savedCookie = globalConfig.getCookie();
|
|
@@ -92,11 +97,11 @@ const completeMfaLogin = async ({
|
|
|
92
97
|
|
|
93
98
|
const deleteServerSession = async (sessionId: string): Promise<boolean> => {
|
|
94
99
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
const client = await sdkForConsole();
|
|
101
|
+
const accountClient = new Account(client);
|
|
97
102
|
await accountClient.deleteSession(sessionId);
|
|
98
103
|
return true;
|
|
99
|
-
} catch (
|
|
104
|
+
} catch (_e) {
|
|
100
105
|
return false;
|
|
101
106
|
}
|
|
102
107
|
};
|
|
@@ -206,7 +211,7 @@ export const loginCommand = async ({
|
|
|
206
211
|
|
|
207
212
|
try {
|
|
208
213
|
await accountClient.get();
|
|
209
|
-
} catch (err
|
|
214
|
+
} catch (err) {
|
|
210
215
|
if (!isMfaRequiredError(err)) {
|
|
211
216
|
throw err;
|
|
212
217
|
}
|
|
@@ -234,7 +239,7 @@ export const loginCommand = async ({
|
|
|
234
239
|
// Use legacy client for login to extract cookies from response
|
|
235
240
|
const legacyClient = createLegacyConsoleClient(configEndpoint);
|
|
236
241
|
|
|
237
|
-
|
|
242
|
+
const client = await sdkForConsole(false);
|
|
238
243
|
let accountClient = new Account(client);
|
|
239
244
|
|
|
240
245
|
let account;
|
|
@@ -261,7 +266,7 @@ export const loginCommand = async ({
|
|
|
261
266
|
|
|
262
267
|
accountClient = new Account(client);
|
|
263
268
|
account = await accountClient.get();
|
|
264
|
-
} catch (err
|
|
269
|
+
} catch (err) {
|
|
265
270
|
if (isMfaRequiredError(err)) {
|
|
266
271
|
account = await completeMfaLogin({
|
|
267
272
|
client,
|
|
@@ -301,8 +306,8 @@ export const whoami = new Command("whoami")
|
|
|
301
306
|
return;
|
|
302
307
|
}
|
|
303
308
|
|
|
304
|
-
|
|
305
|
-
|
|
309
|
+
const client = await sdkForConsole(false);
|
|
310
|
+
const accountClient = new Account(client);
|
|
306
311
|
|
|
307
312
|
let account;
|
|
308
313
|
|
|
@@ -501,7 +506,7 @@ export const client = new Command("client")
|
|
|
501
506
|
: cookieValue || "********";
|
|
502
507
|
maskedCookie = `${cookieName}=...${tail}`;
|
|
503
508
|
}
|
|
504
|
-
|
|
509
|
+
const config = {
|
|
505
510
|
endpoint: globalConfig.getEndpoint(),
|
|
506
511
|
key: maskedKey,
|
|
507
512
|
cookie: maskedCookie,
|
|
@@ -515,17 +520,17 @@ export const client = new Command("client")
|
|
|
515
520
|
if (endpoint !== undefined) {
|
|
516
521
|
try {
|
|
517
522
|
const id = ID.unique();
|
|
518
|
-
|
|
523
|
+
const url = new URL(endpoint);
|
|
519
524
|
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
520
525
|
throw new Error();
|
|
521
526
|
}
|
|
522
527
|
|
|
523
|
-
|
|
528
|
+
const clientInstance = new Client().setEndpoint(endpoint);
|
|
524
529
|
clientInstance.setProject("console");
|
|
525
530
|
if (selfSigned || globalConfig.getSelfSigned()) {
|
|
526
531
|
clientInstance.setSelfSigned(true);
|
|
527
532
|
}
|
|
528
|
-
|
|
533
|
+
const response = (await clientInstance.call(
|
|
529
534
|
"GET",
|
|
530
535
|
new URL(endpoint + "/health/version"),
|
|
531
536
|
)) as { version?: string };
|