appwrite-utils-cli 1.8.2 → 1.8.5
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 +6 -1
- package/README.md +42 -13
- package/dist/adapters/TablesDBAdapter.js +1 -1
- package/dist/cli/commands/functionCommands.js +30 -3
- package/dist/cli/commands/schemaCommands.js +39 -4
- package/dist/cli/commands/storageCommands.d.ts +5 -0
- package/dist/cli/commands/storageCommands.js +143 -0
- package/dist/collections/attributes.js +7 -7
- package/dist/collections/methods.js +1 -1
- package/dist/collections/tableOperations.js +2 -2
- package/dist/interactiveCLI.d.ts +1 -0
- package/dist/interactiveCLI.js +30 -0
- package/dist/main.js +17 -0
- package/dist/migrations/appwriteToX.js +1 -1
- package/dist/migrations/yaml/generateImportSchemas.js +2 -2
- package/dist/setupCommands.js +6 -0
- package/dist/shared/attributeMapper.js +2 -2
- package/dist/shared/jsonSchemaGenerator.js +3 -1
- package/dist/shared/pydanticModelGenerator.d.ts +17 -0
- package/dist/shared/pydanticModelGenerator.js +615 -0
- package/dist/shared/schemaGenerator.d.ts +3 -2
- package/dist/shared/schemaGenerator.js +22 -9
- package/dist/storage/methods.js +50 -7
- package/dist/utils/configDiscovery.js +2 -3
- package/dist/utils/constantsGenerator.d.ts +20 -8
- package/dist/utils/constantsGenerator.js +37 -25
- package/dist/utils/projectConfig.js +1 -1
- package/dist/utils/yamlConverter.d.ts +2 -2
- package/dist/utils/yamlConverter.js +2 -2
- package/package.json +1 -1
- package/src/adapters/TablesDBAdapter.ts +1 -1
- package/src/cli/commands/functionCommands.ts +28 -3
- package/src/cli/commands/schemaCommands.ts +59 -22
- package/src/cli/commands/storageCommands.ts +152 -0
- package/src/collections/attributes.ts +7 -7
- package/src/collections/methods.ts +7 -7
- package/src/collections/tableOperations.ts +2 -2
- package/src/interactiveCLI.ts +42 -12
- package/src/main.ts +32 -9
- package/src/migrations/appwriteToX.ts +1 -1
- package/src/migrations/yaml/generateImportSchemas.ts +7 -7
- package/src/setupCommands.ts +6 -0
- package/src/shared/attributeMapper.ts +2 -2
- package/src/shared/jsonSchemaGenerator.ts +4 -2
- package/src/shared/pydanticModelGenerator.ts +618 -0
- package/src/shared/schemaGenerator.ts +38 -25
- package/src/storage/methods.ts +67 -23
- package/src/utils/configDiscovery.ts +40 -41
- package/src/utils/constantsGenerator.ts +43 -26
- package/src/utils/projectConfig.ts +11 -11
- package/src/utils/yamlConverter.ts +40 -40
|
@@ -345,28 +345,34 @@ export default appwriteConfig;
|
|
|
345
345
|
this.relationshipMap = extractTwoWayRelationships(this.config);
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
public generateSchemas(options: {
|
|
349
|
-
format?: "zod" | "json" | "both";
|
|
350
|
-
verbose?: boolean;
|
|
351
|
-
|
|
352
|
-
|
|
348
|
+
public async generateSchemas(options: {
|
|
349
|
+
format?: "zod" | "json" | "pydantic" | "both" | "all";
|
|
350
|
+
verbose?: boolean;
|
|
351
|
+
outputDir?: string;
|
|
352
|
+
} = {}): Promise<void> {
|
|
353
|
+
const { format = "both", verbose = false, outputDir } = options;
|
|
353
354
|
|
|
354
355
|
if (!this.config.collections) {
|
|
355
356
|
return;
|
|
356
357
|
}
|
|
357
358
|
|
|
358
359
|
// Create schemas directory using config setting
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
360
|
+
const configuredDir = outputDir || this.config.schemaConfig?.outputDirectory || "schemas";
|
|
361
|
+
let schemasPath: string;
|
|
362
|
+
if (path.isAbsolute(configuredDir)) {
|
|
363
|
+
schemasPath = configuredDir;
|
|
364
|
+
} else if (configuredDir === "schemas") {
|
|
365
|
+
schemasPath = resolveSchemaDir(this.appwriteFolderPath);
|
|
366
|
+
} else {
|
|
367
|
+
schemasPath = path.join(this.appwriteFolderPath, configuredDir);
|
|
368
|
+
}
|
|
363
369
|
if (!fs.existsSync(schemasPath)) {
|
|
364
370
|
fs.mkdirSync(schemasPath, { recursive: true });
|
|
365
371
|
}
|
|
366
372
|
|
|
367
|
-
// Generate Zod schemas (TypeScript)
|
|
368
|
-
if (format === "zod" || format === "both") {
|
|
369
|
-
this.config.collections.forEach((collection) => {
|
|
373
|
+
// Generate Zod schemas (TypeScript)
|
|
374
|
+
if (format === "zod" || format === "both" || format === "all") {
|
|
375
|
+
this.config.collections.forEach((collection) => {
|
|
370
376
|
const schemaString = this.createSchemaStringV4(
|
|
371
377
|
collection.name,
|
|
372
378
|
collection.attributes || []
|
|
@@ -381,19 +387,26 @@ export default appwriteConfig;
|
|
|
381
387
|
}
|
|
382
388
|
|
|
383
389
|
// Generate JSON schemas (all at once)
|
|
384
|
-
if (format === "json" || format === "both") {
|
|
385
|
-
const jsonSchemaGenerator = new JsonSchemaGenerator(this.config, this.appwriteFolderPath);
|
|
386
|
-
jsonSchemaGenerator.generateJsonSchemas({
|
|
387
|
-
outputFormat: format === "json" ? "json" : "both",
|
|
388
|
-
outputDirectory:
|
|
389
|
-
verbose: verbose
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
390
|
+
if (format === "json" || format === "both" || format === "all") {
|
|
391
|
+
const jsonSchemaGenerator = new JsonSchemaGenerator(this.config, this.appwriteFolderPath);
|
|
392
|
+
jsonSchemaGenerator.generateJsonSchemas({
|
|
393
|
+
outputFormat: format === "json" ? "json" : "both",
|
|
394
|
+
outputDirectory: configuredDir,
|
|
395
|
+
verbose: verbose
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Generate Python Pydantic models
|
|
400
|
+
if (format === "pydantic" || format === "all") {
|
|
401
|
+
const mod = await import("./pydanticModelGenerator.js");
|
|
402
|
+
const pgen = new mod.PydanticModelGenerator(this.config, this.appwriteFolderPath);
|
|
403
|
+
pgen.generatePydanticModels({ baseOutputDirectory: schemasPath, verbose });
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (verbose) {
|
|
407
|
+
MessageFormatter.success(`Schema generation completed (format: ${format})`, { prefix: "Schema" });
|
|
408
|
+
}
|
|
409
|
+
}
|
|
397
410
|
|
|
398
411
|
// Zod v4 recursive getter-based schemas
|
|
399
412
|
createSchemaStringV4 = (name: string, attributes: Attribute[]): string => {
|
package/src/storage/methods.ts
CHANGED
|
@@ -105,18 +105,65 @@ export const deleteFile = async (
|
|
|
105
105
|
return await storage.deleteFile(bucketId, fileId);
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
export const ensureDatabaseConfigBucketsExist = async (
|
|
109
|
-
storage: Storage,
|
|
110
|
-
config: AppwriteConfig,
|
|
111
|
-
databases: Models.Database[] = []
|
|
112
|
-
) => {
|
|
113
|
-
for (const db of databases) {
|
|
114
|
-
const database = config.databases?.find((d) => d.$id === db.$id);
|
|
115
|
-
if (database?.bucket) {
|
|
116
|
-
try {
|
|
117
|
-
await storage.getBucket(database.bucket.$id);
|
|
118
|
-
|
|
119
|
-
|
|
108
|
+
export const ensureDatabaseConfigBucketsExist = async (
|
|
109
|
+
storage: Storage,
|
|
110
|
+
config: AppwriteConfig,
|
|
111
|
+
databases: Models.Database[] = []
|
|
112
|
+
) => {
|
|
113
|
+
for (const db of databases) {
|
|
114
|
+
const database = config.databases?.find((d) => d.$id === db.$id);
|
|
115
|
+
if (database?.bucket) {
|
|
116
|
+
try {
|
|
117
|
+
const existing = await storage.getBucket(database.bucket.$id);
|
|
118
|
+
// Compare and update if needed
|
|
119
|
+
const desired = database.bucket;
|
|
120
|
+
// Build desired permissions via Permission helper
|
|
121
|
+
const permissions: string[] = [];
|
|
122
|
+
if (desired.permissions && desired.permissions.length > 0) {
|
|
123
|
+
for (const p of desired.permissions as any[]) {
|
|
124
|
+
switch (p.permission) {
|
|
125
|
+
case 'read': permissions.push(Permission.read(p.target)); break;
|
|
126
|
+
case 'create': permissions.push(Permission.create(p.target)); break;
|
|
127
|
+
case 'update': permissions.push(Permission.update(p.target)); break;
|
|
128
|
+
case 'delete': permissions.push(Permission.delete(p.target)); break;
|
|
129
|
+
case 'write': permissions.push(Permission.write(p.target)); break;
|
|
130
|
+
default: break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const diff = (
|
|
135
|
+
existing.name !== desired.name ||
|
|
136
|
+
JSON.stringify(existing.$permissions || []) !== JSON.stringify(permissions) ||
|
|
137
|
+
!!existing.fileSecurity !== !!desired.fileSecurity ||
|
|
138
|
+
!!existing.enabled !== !!desired.enabled ||
|
|
139
|
+
(existing.maximumFileSize ?? undefined) !== (desired.maximumFileSize ?? undefined) ||
|
|
140
|
+
JSON.stringify(existing.allowedFileExtensions || []) !== JSON.stringify(desired.allowedFileExtensions || []) ||
|
|
141
|
+
String(existing.compression || 'none') !== String(desired.compression || 'none') ||
|
|
142
|
+
!!existing.encryption !== !!desired.encryption ||
|
|
143
|
+
!!existing.antivirus !== !!desired.antivirus
|
|
144
|
+
);
|
|
145
|
+
if (diff) {
|
|
146
|
+
try {
|
|
147
|
+
await storage.updateBucket(
|
|
148
|
+
desired.$id,
|
|
149
|
+
desired.name,
|
|
150
|
+
permissions,
|
|
151
|
+
desired.fileSecurity,
|
|
152
|
+
desired.enabled,
|
|
153
|
+
desired.maximumFileSize,
|
|
154
|
+
desired.allowedFileExtensions,
|
|
155
|
+
desired.compression as Compression,
|
|
156
|
+
desired.encryption,
|
|
157
|
+
desired.antivirus
|
|
158
|
+
);
|
|
159
|
+
MessageFormatter.info(`Updated bucket ${desired.$id} to match config`, { prefix: 'Buckets' });
|
|
160
|
+
} catch (updateErr) {
|
|
161
|
+
MessageFormatter.warning(`Failed to update bucket ${desired.$id}: ${updateErr instanceof Error ? updateErr.message : String(updateErr)}`, { prefix: 'Buckets' });
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
MessageFormatter.debug(`Bucket ${desired.$id} up-to-date`, undefined, { prefix: 'Buckets' });
|
|
165
|
+
}
|
|
166
|
+
} catch (e) {
|
|
120
167
|
const permissions: string[] = [];
|
|
121
168
|
if (
|
|
122
169
|
database.bucket.permissions &&
|
|
@@ -158,17 +205,14 @@ export const ensureDatabaseConfigBucketsExist = async (
|
|
|
158
205
|
database.bucket.encryption,
|
|
159
206
|
database.bucket.antivirus
|
|
160
207
|
);
|
|
161
|
-
|
|
162
|
-
} catch (createError) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
208
|
+
MessageFormatter.success(`Bucket ${database.bucket.$id} created`, { prefix: 'Buckets' });
|
|
209
|
+
} catch (createError) {
|
|
210
|
+
MessageFormatter.error(`Failed to create bucket ${database.bucket.$id}`, createError instanceof Error ? createError : new Error(String(createError)), { prefix: 'Buckets' });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
172
216
|
|
|
173
217
|
export const wipeDocumentStorage = async (
|
|
174
218
|
storage: Storage,
|
|
@@ -173,28 +173,27 @@ const YamlTableSchema = z.object({
|
|
|
173
173
|
target: z.string()
|
|
174
174
|
})
|
|
175
175
|
).optional().default([]),
|
|
176
|
-
columns: z.array( // Tables use columns terminology
|
|
177
|
-
z.object({
|
|
178
|
-
key: z.string(),
|
|
179
|
-
type: z.string(),
|
|
180
|
-
size: z.number().optional(),
|
|
181
|
-
required: z.boolean().default(false),
|
|
182
|
-
array: z.boolean().optional(),
|
|
183
|
-
|
|
184
|
-
default: z.any().optional(),
|
|
185
|
-
min: z.number().optional(),
|
|
186
|
-
max: z.number().optional(),
|
|
187
|
-
elements: z.array(z.string()).optional(),
|
|
188
|
-
relatedTable: z.string().optional(), // Tables use relatedTable
|
|
189
|
-
relationType: z.string().optional(),
|
|
190
|
-
twoWay: z.boolean().optional(),
|
|
191
|
-
twoWayKey: z.string().optional(),
|
|
192
|
-
onDelete: z.string().optional(),
|
|
193
|
-
side: z.string().optional(),
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
).optional().default([]),
|
|
176
|
+
columns: z.array( // Tables use columns terminology
|
|
177
|
+
z.object({
|
|
178
|
+
key: z.string(),
|
|
179
|
+
type: z.string(),
|
|
180
|
+
size: z.number().optional(),
|
|
181
|
+
required: z.boolean().default(false),
|
|
182
|
+
array: z.boolean().optional(),
|
|
183
|
+
encrypt: z.boolean().optional(), // Tables support encrypt property
|
|
184
|
+
default: z.any().optional(),
|
|
185
|
+
min: z.number().optional(),
|
|
186
|
+
max: z.number().optional(),
|
|
187
|
+
elements: z.array(z.string()).optional(),
|
|
188
|
+
relatedTable: z.string().optional(), // Tables use relatedTable
|
|
189
|
+
relationType: z.string().optional(),
|
|
190
|
+
twoWay: z.boolean().optional(),
|
|
191
|
+
twoWayKey: z.string().optional(),
|
|
192
|
+
onDelete: z.string().optional(),
|
|
193
|
+
side: z.string().optional(),
|
|
194
|
+
format: z.string().optional()
|
|
195
|
+
})
|
|
196
|
+
).optional().default([]),
|
|
198
197
|
indexes: z.array(
|
|
199
198
|
z.object({
|
|
200
199
|
key: z.string(),
|
|
@@ -289,25 +288,25 @@ export const loadYamlTable = (filePath: string): CollectionCreate | null => {
|
|
|
289
288
|
permission: p.permission as any,
|
|
290
289
|
target: p.target
|
|
291
290
|
})),
|
|
292
|
-
attributes: parsedTable.columns.map(col => ({ // Convert columns to attributes
|
|
293
|
-
key: col.key,
|
|
294
|
-
type: col.type as any,
|
|
295
|
-
size: col.size,
|
|
296
|
-
required: col.required,
|
|
297
|
-
array: col.array,
|
|
298
|
-
xdefault: col.default,
|
|
299
|
-
min: col.min,
|
|
300
|
-
max: col.max,
|
|
301
|
-
elements: col.elements,
|
|
302
|
-
relatedCollection: col.relatedTable, // Convert relatedTable to relatedCollection
|
|
303
|
-
relationType: col.relationType as any,
|
|
304
|
-
twoWay: col.twoWay,
|
|
305
|
-
twoWayKey: col.twoWayKey,
|
|
306
|
-
onDelete: col.onDelete as any,
|
|
307
|
-
side: col.side as any,
|
|
308
|
-
|
|
309
|
-
format: col.format
|
|
310
|
-
})),
|
|
291
|
+
attributes: parsedTable.columns.map(col => ({ // Convert columns to attributes
|
|
292
|
+
key: col.key,
|
|
293
|
+
type: col.type as any,
|
|
294
|
+
size: col.size,
|
|
295
|
+
required: col.required,
|
|
296
|
+
array: col.array,
|
|
297
|
+
xdefault: col.default,
|
|
298
|
+
min: col.min,
|
|
299
|
+
max: col.max,
|
|
300
|
+
elements: col.elements,
|
|
301
|
+
relatedCollection: col.relatedTable, // Convert relatedTable to relatedCollection
|
|
302
|
+
relationType: col.relationType as any,
|
|
303
|
+
twoWay: col.twoWay,
|
|
304
|
+
twoWayKey: col.twoWayKey,
|
|
305
|
+
onDelete: col.onDelete as any,
|
|
306
|
+
side: col.side as any,
|
|
307
|
+
encrypt: col.encrypt,
|
|
308
|
+
format: col.format
|
|
309
|
+
})),
|
|
311
310
|
indexes: parsedTable.indexes.map(idx => ({
|
|
312
311
|
key: idx.key,
|
|
313
312
|
type: idx.type as any,
|
|
@@ -89,8 +89,8 @@ export class ConstantsGenerator {
|
|
|
89
89
|
return name.toLowerCase();
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
generateTypeScript(): string {
|
|
93
|
-
const { databases, collections, buckets, functions } = this.constants;
|
|
92
|
+
generateTypeScript(constantsOverride?: Constants): string {
|
|
93
|
+
const { databases, collections, buckets, functions } = constantsOverride || this.constants;
|
|
94
94
|
|
|
95
95
|
return `// Auto-generated Appwrite constants
|
|
96
96
|
// Generated on ${new Date().toISOString()}
|
|
@@ -125,8 +125,8 @@ export const ALL_FUNCTION_IDS = Object.values(FUNCTION_IDS);
|
|
|
125
125
|
`;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
generateJavaScript(): string {
|
|
129
|
-
const { databases, collections, buckets, functions } = this.constants;
|
|
128
|
+
generateJavaScript(constantsOverride?: Constants): string {
|
|
129
|
+
const { databases, collections, buckets, functions } = constantsOverride || this.constants;
|
|
130
130
|
|
|
131
131
|
return `// Auto-generated Appwrite constants
|
|
132
132
|
// Generated on ${new Date().toISOString()}
|
|
@@ -155,8 +155,8 @@ export const ALL_FUNCTION_IDS = Object.values(FUNCTION_IDS);
|
|
|
155
155
|
`;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
generatePython(): string {
|
|
159
|
-
const { databases, collections, buckets, functions } = this.constants;
|
|
158
|
+
generatePython(constantsOverride?: Constants): string {
|
|
159
|
+
const { databases, collections, buckets, functions } = constantsOverride || this.constants;
|
|
160
160
|
|
|
161
161
|
return `# Auto-generated Appwrite constants
|
|
162
162
|
# Generated on ${new Date().toISOString()}
|
|
@@ -196,8 +196,8 @@ ${Object.entries(functions).map(([key, value]) => ` "${this.toSnakeCase(key)}
|
|
|
196
196
|
`;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
generatePHP(): string {
|
|
200
|
-
const { databases, collections, buckets, functions } = this.constants;
|
|
199
|
+
generatePHP(constantsOverride?: Constants): string {
|
|
200
|
+
const { databases, collections, buckets, functions } = constantsOverride || this.constants;
|
|
201
201
|
|
|
202
202
|
return `<?php
|
|
203
203
|
// Auto-generated Appwrite constants
|
|
@@ -252,8 +252,8 @@ ${Object.entries(functions).map(([key, value]) => ` '${key}' => '${value}
|
|
|
252
252
|
`;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
generateDart(): string {
|
|
256
|
-
const { databases, collections, buckets, functions } = this.constants;
|
|
255
|
+
generateDart(constantsOverride?: Constants): string {
|
|
256
|
+
const { databases, collections, buckets, functions } = constantsOverride || this.constants;
|
|
257
257
|
|
|
258
258
|
return `// Auto-generated Appwrite constants
|
|
259
259
|
// Generated on ${new Date().toISOString()}
|
|
@@ -288,21 +288,22 @@ ${Object.entries(functions).map(([key, value]) => ` static String get ${this.to
|
|
|
288
288
|
`;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
generateJSON(): string {
|
|
291
|
+
generateJSON(constantsOverride?: Constants): string {
|
|
292
|
+
const c = constantsOverride || this.constants;
|
|
292
293
|
return JSON.stringify({
|
|
293
294
|
meta: {
|
|
294
295
|
generated: new Date().toISOString(),
|
|
295
296
|
generator: "appwrite-utils-cli"
|
|
296
297
|
},
|
|
297
|
-
databases:
|
|
298
|
-
collections:
|
|
299
|
-
buckets:
|
|
300
|
-
functions:
|
|
298
|
+
databases: c.databases,
|
|
299
|
+
collections: c.collections,
|
|
300
|
+
buckets: c.buckets,
|
|
301
|
+
functions: c.functions
|
|
301
302
|
}, null, 2);
|
|
302
303
|
}
|
|
303
304
|
|
|
304
|
-
generateEnv(): string {
|
|
305
|
-
const { databases, collections, buckets, functions } = this.constants;
|
|
305
|
+
generateEnv(constantsOverride?: Constants): string {
|
|
306
|
+
const { databases, collections, buckets, functions } = constantsOverride || this.constants;
|
|
306
307
|
|
|
307
308
|
const lines = [
|
|
308
309
|
"# Auto-generated Appwrite constants",
|
|
@@ -324,17 +325,33 @@ ${Object.entries(functions).map(([key, value]) => ` static String get ${this.to
|
|
|
324
325
|
return lines.join('\n');
|
|
325
326
|
}
|
|
326
327
|
|
|
327
|
-
async generateFiles(
|
|
328
|
+
async generateFiles(
|
|
329
|
+
languages: SupportedLanguage[],
|
|
330
|
+
outputDir: string,
|
|
331
|
+
include?: { databases?: boolean; collections?: boolean; buckets?: boolean; functions?: boolean }
|
|
332
|
+
): Promise<void> {
|
|
328
333
|
await fs.mkdir(outputDir, { recursive: true });
|
|
329
334
|
|
|
335
|
+
const filterConstants = (): Constants => {
|
|
336
|
+
if (!include) return this.constants;
|
|
337
|
+
return {
|
|
338
|
+
databases: include.databases === false ? {} : this.constants.databases,
|
|
339
|
+
collections: include.collections === false ? {} : this.constants.collections,
|
|
340
|
+
buckets: include.buckets === false ? {} : this.constants.buckets,
|
|
341
|
+
functions: include.functions === false ? {} : this.constants.functions,
|
|
342
|
+
};
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const subset = filterConstants();
|
|
346
|
+
|
|
330
347
|
const generators = {
|
|
331
|
-
typescript: () => ({ content: this.generateTypeScript(), filename: "appwrite-constants.ts" }),
|
|
332
|
-
javascript: () => ({ content: this.generateJavaScript(), filename: "appwrite-constants.js" }),
|
|
333
|
-
python: () => ({ content: this.generatePython(), filename: "appwrite_constants.py" }),
|
|
334
|
-
php: () => ({ content: this.generatePHP(), filename: "AppwriteConstants.php" }),
|
|
335
|
-
dart: () => ({ content: this.generateDart(), filename: "appwrite_constants.dart" }),
|
|
336
|
-
json: () => ({ content: this.generateJSON(), filename: "appwrite-constants.json" }),
|
|
337
|
-
env: () => ({ content: this.generateEnv(), filename: ".env.appwrite" })
|
|
348
|
+
typescript: () => ({ content: this.generateTypeScript(subset), filename: "appwrite-constants.ts" }),
|
|
349
|
+
javascript: () => ({ content: this.generateJavaScript(subset), filename: "appwrite-constants.js" }),
|
|
350
|
+
python: () => ({ content: this.generatePython(subset), filename: "appwrite_constants.py" }),
|
|
351
|
+
php: () => ({ content: this.generatePHP(subset), filename: "AppwriteConstants.php" }),
|
|
352
|
+
dart: () => ({ content: this.generateDart(subset), filename: "appwrite_constants.dart" }),
|
|
353
|
+
json: () => ({ content: this.generateJSON(subset), filename: "appwrite-constants.json" }),
|
|
354
|
+
env: () => ({ content: this.generateEnv(subset), filename: ".env.appwrite" })
|
|
338
355
|
};
|
|
339
356
|
|
|
340
357
|
for (const language of languages) {
|
|
@@ -349,4 +366,4 @@ ${Object.entries(functions).map(([key, value]) => ` static String get ${this.to
|
|
|
349
366
|
}
|
|
350
367
|
}
|
|
351
368
|
}
|
|
352
|
-
}
|
|
369
|
+
}
|
|
@@ -251,16 +251,16 @@ export function getCollectionsFromProject(projectConfig: AppwriteProjectConfig):
|
|
|
251
251
|
documentSecurity: table.rowSecurity || false,
|
|
252
252
|
enabled: table.enabled !== false,
|
|
253
253
|
// Convert columns to attributes for compatibility
|
|
254
|
-
attributes: table.columns.map(col => ({
|
|
255
|
-
key: col.key,
|
|
256
|
-
type: col.type,
|
|
257
|
-
required: col.required,
|
|
258
|
-
array: col.array,
|
|
259
|
-
size: col.size,
|
|
260
|
-
default: col.default,
|
|
261
|
-
|
|
262
|
-
unique: col.unique,
|
|
263
|
-
})),
|
|
254
|
+
attributes: table.columns.map(col => ({
|
|
255
|
+
key: col.key,
|
|
256
|
+
type: col.type,
|
|
257
|
+
required: col.required,
|
|
258
|
+
array: col.array,
|
|
259
|
+
size: col.size,
|
|
260
|
+
default: col.default,
|
|
261
|
+
encrypt: col.encrypt,
|
|
262
|
+
unique: col.unique,
|
|
263
|
+
})),
|
|
264
264
|
indexes: table.indexes || [],
|
|
265
265
|
// Mark as coming from TablesDB for processing
|
|
266
266
|
_isFromTablesDir: true,
|
|
@@ -296,4 +296,4 @@ export function isTablesDBProject(projectConfig: AppwriteProjectConfig): boolean
|
|
|
296
296
|
*/
|
|
297
297
|
export function getProjectDirectoryName(projectConfig: AppwriteProjectConfig): "tables" | "collections" {
|
|
298
298
|
return isTablesDBProject(projectConfig) ? "tables" : "collections";
|
|
299
|
-
}
|
|
299
|
+
}
|
|
@@ -101,43 +101,43 @@ export interface YamlCollectionData {
|
|
|
101
101
|
permission: string;
|
|
102
102
|
target: string;
|
|
103
103
|
}>;
|
|
104
|
-
attributes?: Array<{
|
|
105
|
-
key: string;
|
|
106
|
-
type: string;
|
|
107
|
-
size?: number;
|
|
108
|
-
required?: boolean;
|
|
109
|
-
array?: boolean;
|
|
110
|
-
|
|
111
|
-
default?: any;
|
|
112
|
-
min?: number;
|
|
113
|
-
max?: number;
|
|
114
|
-
elements?: string[];
|
|
115
|
-
relatedCollection?: string;
|
|
116
|
-
relationType?: string;
|
|
117
|
-
twoWay?: boolean;
|
|
118
|
-
twoWayKey?: string;
|
|
119
|
-
onDelete?: string;
|
|
120
|
-
side?: string;
|
|
121
|
-
}>;
|
|
104
|
+
attributes?: Array<{
|
|
105
|
+
key: string;
|
|
106
|
+
type: string;
|
|
107
|
+
size?: number;
|
|
108
|
+
required?: boolean;
|
|
109
|
+
array?: boolean;
|
|
110
|
+
encrypt?: boolean;
|
|
111
|
+
default?: any;
|
|
112
|
+
min?: number;
|
|
113
|
+
max?: number;
|
|
114
|
+
elements?: string[];
|
|
115
|
+
relatedCollection?: string;
|
|
116
|
+
relationType?: string;
|
|
117
|
+
twoWay?: boolean;
|
|
118
|
+
twoWayKey?: string;
|
|
119
|
+
onDelete?: string;
|
|
120
|
+
side?: string;
|
|
121
|
+
}>;
|
|
122
122
|
// Table terminology support (columns is an alias for attributes)
|
|
123
|
-
columns?: Array<{
|
|
124
|
-
key: string;
|
|
125
|
-
type: string;
|
|
126
|
-
size?: number;
|
|
127
|
-
required?: boolean;
|
|
128
|
-
array?: boolean;
|
|
129
|
-
|
|
130
|
-
default?: any;
|
|
131
|
-
min?: number;
|
|
132
|
-
max?: number;
|
|
133
|
-
elements?: string[];
|
|
134
|
-
relatedTable?: string;
|
|
135
|
-
relationType?: string;
|
|
136
|
-
twoWay?: boolean;
|
|
137
|
-
twoWayKey?: string;
|
|
138
|
-
onDelete?: string;
|
|
139
|
-
side?: string;
|
|
140
|
-
}>;
|
|
123
|
+
columns?: Array<{
|
|
124
|
+
key: string;
|
|
125
|
+
type: string;
|
|
126
|
+
size?: number;
|
|
127
|
+
required?: boolean;
|
|
128
|
+
array?: boolean;
|
|
129
|
+
encrypt?: boolean;
|
|
130
|
+
default?: any;
|
|
131
|
+
min?: number;
|
|
132
|
+
max?: number;
|
|
133
|
+
elements?: string[];
|
|
134
|
+
relatedTable?: string;
|
|
135
|
+
relationType?: string;
|
|
136
|
+
twoWay?: boolean;
|
|
137
|
+
twoWayKey?: string;
|
|
138
|
+
onDelete?: string;
|
|
139
|
+
side?: string;
|
|
140
|
+
}>;
|
|
141
141
|
indexes?: Array<{
|
|
142
142
|
key: string;
|
|
143
143
|
type: string;
|
|
@@ -205,10 +205,10 @@ export function collectionToYaml(
|
|
|
205
205
|
if (attr.required !== undefined) yamlAttr.required = attr.required;
|
|
206
206
|
if (attr.array !== undefined) yamlAttr.array = attr.array;
|
|
207
207
|
|
|
208
|
-
// Always include
|
|
209
|
-
if (attr.type === 'string') {
|
|
210
|
-
yamlAttr.
|
|
211
|
-
}
|
|
208
|
+
// Always include encrypt field for string attributes (default to false)
|
|
209
|
+
if (attr.type === 'string') {
|
|
210
|
+
yamlAttr.encrypt = ('encrypt' in attr && (attr as any).encrypt === true) ? true : false;
|
|
211
|
+
}
|
|
212
212
|
|
|
213
213
|
if ('xdefault' in attr && attr.xdefault !== undefined) yamlAttr.default = attr.xdefault;
|
|
214
214
|
|