@akis05/akis 0.1.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.
@@ -0,0 +1,439 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.init = init;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const readline = __importStar(require("readline"));
40
+ async function prompt(question, defaultValue) {
41
+ const rl = readline.createInterface({
42
+ input: process.stdin,
43
+ output: process.stdout,
44
+ });
45
+ const defaultText = defaultValue ? ` (${defaultValue})` : "";
46
+ return new Promise((resolve) => {
47
+ rl.question(`${question}${defaultText}: `, (answer) => {
48
+ rl.close();
49
+ resolve(answer.trim() || defaultValue || "");
50
+ });
51
+ });
52
+ }
53
+ const TYPES_TEMPLATE = `/* ═════════════════════════════════════════════════════════════════════════════
54
+ AKIS — TypeScript Types pour Appwrite
55
+ ═════════════════════════════════════════════════════════════════════════════ */
56
+
57
+ /* ─────────────────────────────────────────────────────────────────────────────
58
+ Exemple de collection
59
+ ───────────────────────────────────────────────────────────────────────────── */
60
+
61
+ export type Client = {
62
+ _id: string;
63
+ _creationTime: number;
64
+ nom: string;
65
+ email?: string;
66
+ telephone?: string;
67
+ adresse?: string;
68
+ note?: string;
69
+ storeId: string;
70
+ createdAt: number;
71
+ deletedAt?: number;
72
+ };
73
+
74
+ /* ─────────────────────────────────────────────────────────────────────────────
75
+ Utilitaires génériques
76
+ ───────────────────────────────────────────────────────────────────────────── */
77
+
78
+ export type NewDoc<T> = Omit<T, "_id" | "_creationTime">;
79
+ export type UpdateDoc<T> = Partial<Omit<T, "_id" | "_creationTime">>;
80
+ `;
81
+ const SETUP_COLLECTIONS_TEMPLATE = `import { Databases, ID, DatabasesIndexType, Query } from "node-appwrite";
82
+ import { collections, AttributeDefinition, CollectionSchema } from "./schema";
83
+
84
+ function delay(ms: number) {
85
+ return new Promise((resolve) => setTimeout(resolve, ms));
86
+ }
87
+
88
+ async function createAttribute(
89
+ databases: Databases,
90
+ databaseId: string,
91
+ collectionId: string,
92
+ attr: AttributeDefinition
93
+ ): Promise<void> {
94
+ const baseParams = {
95
+ databaseId,
96
+ collectionId,
97
+ key: attr.key,
98
+ required: attr.required,
99
+ };
100
+
101
+ switch (attr.type) {
102
+ case "string":
103
+ await databases.createStringAttribute({
104
+ ...baseParams,
105
+ size: attr.size || 255,
106
+ });
107
+ break;
108
+ case "integer":
109
+ await databases.createIntegerAttribute(baseParams);
110
+ break;
111
+ case "float":
112
+ await databases.createFloatAttribute(baseParams);
113
+ break;
114
+ case "boolean":
115
+ await databases.createBooleanAttribute(baseParams);
116
+ break;
117
+ case "datetime":
118
+ await databases.createDatetimeAttribute(baseParams);
119
+ break;
120
+ case "enum":
121
+ await databases.createEnumAttribute({
122
+ ...baseParams,
123
+ elements: attr.enumValues || [],
124
+ });
125
+ break;
126
+ case "string[]":
127
+ await databases.createStringAttribute({
128
+ ...baseParams,
129
+ size: attr.size || 255,
130
+ array: true,
131
+ });
132
+ break;
133
+ case "integer[]":
134
+ await databases.createIntegerAttribute({
135
+ ...baseParams,
136
+ array: true,
137
+ });
138
+ break;
139
+ }
140
+ }
141
+
142
+ export async function setupCollection(
143
+ databases: Databases,
144
+ databaseId: string,
145
+ schema: CollectionSchema
146
+ ): Promise<{ success: boolean; collectionId: string; error?: string }> {
147
+ try {
148
+ const collectionId = ID.unique();
149
+
150
+ await databases.createCollection({
151
+ databaseId,
152
+ collectionId,
153
+ name: schema.name,
154
+ permissions: [],
155
+ documentSecurity: false,
156
+ });
157
+
158
+ for (const attr of schema.attributes) {
159
+ try {
160
+ await createAttribute(databases, databaseId, collectionId, attr);
161
+ await delay(300);
162
+ } catch (error) {
163
+ console.error(\`Error creating attribute \${attr.key}:\`, error);
164
+ }
165
+ }
166
+
167
+ await delay(2000);
168
+
169
+ if (schema.indexes && schema.indexes.length > 0) {
170
+ for (const index of schema.indexes) {
171
+ const indexType = index.type === "key"
172
+ ? DatabasesIndexType.Key
173
+ : index.type === "unique"
174
+ ? DatabasesIndexType.Unique
175
+ : DatabasesIndexType.Fulltext;
176
+
177
+ let retries = 5;
178
+ while (retries > 0) {
179
+ try {
180
+ await databases.createIndex({
181
+ databaseId,
182
+ collectionId,
183
+ key: index.key,
184
+ type: indexType,
185
+ attributes: index.attributes,
186
+ });
187
+ await delay(500);
188
+ break;
189
+ } catch (indexError: unknown) {
190
+ const appwriteError = indexError as { type?: string };
191
+ if (appwriteError.type === "attribute_not_available" && retries > 1) {
192
+ retries--;
193
+ await delay(3000);
194
+ } else {
195
+ console.error(\`Error creating index \${index.key}:\`, indexError);
196
+ break;
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+ return { success: true, collectionId };
204
+ } catch (error) {
205
+ const errorMessage = error instanceof Error ? error.message : String(error);
206
+ return { success: false, collectionId: "", error: errorMessage };
207
+ }
208
+ }
209
+
210
+ export async function setupAllCollections(
211
+ databases: Databases,
212
+ databaseId: string
213
+ ): Promise<{ name: string; success: boolean; collectionId: string; error?: string }[]> {
214
+ const results: { name: string; success: boolean; collectionId: string; error?: string }[] = [];
215
+
216
+ for (const schema of collections) {
217
+ const result = await setupCollection(databases, databaseId, schema);
218
+ results.push({ name: schema.name, ...result });
219
+ await delay(500);
220
+ }
221
+
222
+ return results;
223
+ }
224
+
225
+ export async function deleteAllCollections(
226
+ databases: Databases,
227
+ databaseId: string
228
+ ): Promise<{ deleted: number; errors: string[] }> {
229
+ const errors: string[] = [];
230
+ let deleted = 0;
231
+
232
+ try {
233
+ const response = await databases.listCollections({
234
+ databaseId,
235
+ queries: [Query.limit(100)],
236
+ });
237
+
238
+ for (const collection of response.collections) {
239
+ try {
240
+ await databases.deleteCollection({
241
+ databaseId,
242
+ collectionId: collection.$id,
243
+ });
244
+ deleted++;
245
+ await delay(200);
246
+ } catch (err) {
247
+ const errorMessage = err instanceof Error ? err.message : String(err);
248
+ errors.push(\`\${collection.name}: \${errorMessage}\`);
249
+ }
250
+ }
251
+ } catch (err) {
252
+ const errorMessage = err instanceof Error ? err.message : String(err);
253
+ errors.push(\`Failed to list collections: \${errorMessage}\`);
254
+ }
255
+
256
+ return { deleted, errors };
257
+ }
258
+
259
+ export { collections };
260
+ `;
261
+ const SCHEMA_TEMPLATE = `export type AttributeType =
262
+ | "string"
263
+ | "integer"
264
+ | "float"
265
+ | "boolean"
266
+ | "datetime"
267
+ | "enum"
268
+ | "string[]"
269
+ | "integer[]";
270
+
271
+ export interface AttributeDefinition {
272
+ key: string;
273
+ type: AttributeType;
274
+ required: boolean;
275
+ size?: number;
276
+ enumValues?: string[];
277
+ default?: string | number | boolean | null;
278
+ }
279
+
280
+ export type IndexType = "key" | "unique" | "fulltext";
281
+
282
+ export interface IndexDefinition {
283
+ key: string;
284
+ type: IndexType;
285
+ attributes: string[];
286
+ orders?: ("ASC" | "DESC")[];
287
+ }
288
+
289
+ export interface CollectionSchema {
290
+ name: string;
291
+ attributes: AttributeDefinition[];
292
+ indexes?: IndexDefinition[];
293
+ }
294
+
295
+ // Définissez vos collections ici
296
+ export const collections: CollectionSchema[] = [
297
+ {
298
+ name: "clients",
299
+ attributes: [
300
+ { key: "nom", type: "string", required: true, size: 255 },
301
+ { key: "email", type: "string", required: false, size: 255 },
302
+ { key: "telephone", type: "string", required: false, size: 50 },
303
+ { key: "adresse", type: "string", required: false, size: 500 },
304
+ { key: "note", type: "string", required: false, size: 2000 },
305
+ { key: "storeId", type: "string", required: true, size: 36 },
306
+ { key: "createdAt", type: "integer", required: true },
307
+ { key: "deletedAt", type: "integer", required: false },
308
+ ],
309
+ indexes: [
310
+ { key: "idx_storeId", type: "key", attributes: ["storeId"] },
311
+ ],
312
+ },
313
+ ];
314
+ `;
315
+ const CLIENT_TEMPLATE = `import { Client, Databases } from "node-appwrite";
316
+
317
+ const APPWRITE_ENDPOINT = process.env.APPWRITE_ENDPOINT || "https://cloud.appwrite.io/v1";
318
+ const APPWRITE_PROJECT_ID = process.env.APPWRITE_PROJECT_ID || "";
319
+ const APPWRITE_API_KEY = process.env.APPWRITE_API_KEY || "";
320
+ const APPWRITE_DATABASE_ID = process.env.APPWRITE_DATABASE_ID || "";
321
+
322
+ export function createAdminClient() {
323
+ const client = new Client()
324
+ .setEndpoint(APPWRITE_ENDPOINT)
325
+ .setProject(APPWRITE_PROJECT_ID)
326
+ .setKey(APPWRITE_API_KEY);
327
+
328
+ return {
329
+ client,
330
+ databases: new Databases(client),
331
+ };
332
+ }
333
+
334
+ export const config = {
335
+ endpoint: APPWRITE_ENDPOINT,
336
+ projectId: APPWRITE_PROJECT_ID,
337
+ databaseId: APPWRITE_DATABASE_ID,
338
+ };
339
+ `;
340
+ const ENV_TEMPLATE = `# Appwrite Configuration
341
+ APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
342
+ APPWRITE_PROJECT_ID=
343
+ APPWRITE_DATABASE_ID=
344
+ APPWRITE_API_KEY=
345
+ `;
346
+ async function init(options) {
347
+ console.log("\n🚀 AKIS Init - Initialisation du projet\n");
348
+ const cwd = process.cwd();
349
+ const libPath = path.join(cwd, "core", "appwrite-model");
350
+ const typesPath = path.join(libPath, "types.ts");
351
+ const clientPath = path.join(libPath, "client.ts");
352
+ const schemaPath = path.join(libPath, "schema.ts");
353
+ const setupPath = path.join(libPath, "setup-collections.ts");
354
+ // Check if files already exist
355
+ const existingFiles = [];
356
+ if (fs.existsSync(typesPath))
357
+ existingFiles.push("core/appwrite-model/types.ts");
358
+ if (fs.existsSync(clientPath))
359
+ existingFiles.push("core/appwrite-model/client.ts");
360
+ if (fs.existsSync(schemaPath))
361
+ existingFiles.push("core/appwrite-model/schema.ts");
362
+ if (fs.existsSync(setupPath))
363
+ existingFiles.push("core/appwrite-model/setup-collections.ts");
364
+ if (existingFiles.length > 0 && !options.force) {
365
+ console.log("⚠️ Les fichiers suivants existent déjà:");
366
+ for (const file of existingFiles) {
367
+ console.log(` - ${file}`);
368
+ }
369
+ console.log("\n Utilisez --force pour les écraser\n");
370
+ return;
371
+ }
372
+ // Create directories
373
+ console.log("📁 Création des dossiers...");
374
+ if (!fs.existsSync(libPath)) {
375
+ fs.mkdirSync(libPath, { recursive: true });
376
+ console.log(" ✓ core/appwrite-model/");
377
+ }
378
+ else {
379
+ console.log(" ⏭️ core/appwrite-model/ (existe déjà)");
380
+ }
381
+ // Create types.ts
382
+ if (!fs.existsSync(typesPath) || options.force) {
383
+ fs.writeFileSync(typesPath, TYPES_TEMPLATE);
384
+ console.log(" ✓ core/appwrite-model/types.ts");
385
+ }
386
+ else {
387
+ console.log(" ⏭️ core/appwrite-model/types.ts (existe déjà)");
388
+ }
389
+ // Create client.ts
390
+ if (!fs.existsSync(clientPath) || options.force) {
391
+ fs.writeFileSync(clientPath, CLIENT_TEMPLATE);
392
+ console.log(" ✓ core/appwrite-model/client.ts");
393
+ }
394
+ else {
395
+ console.log(" ⏭️ core/appwrite-model/client.ts (existe déjà)");
396
+ }
397
+ // Create schema.ts
398
+ if (!fs.existsSync(schemaPath) || options.force) {
399
+ fs.writeFileSync(schemaPath, SCHEMA_TEMPLATE);
400
+ console.log(" ✓ core/appwrite-model/schema.ts");
401
+ }
402
+ else {
403
+ console.log(" ⏭️ core/appwrite-model/schema.ts (existe déjà)");
404
+ }
405
+ // Create setup-collections.ts
406
+ if (!fs.existsSync(setupPath) || options.force) {
407
+ fs.writeFileSync(setupPath, SETUP_COLLECTIONS_TEMPLATE);
408
+ console.log(" ✓ core/appwrite-model/setup-collections.ts");
409
+ }
410
+ else {
411
+ console.log(" ⏭️ core/appwrite-model/setup-collections.ts (existe déjà)");
412
+ }
413
+ console.log(`
414
+ ✨ Initialisation terminée!
415
+
416
+ 📁 Structure créée:
417
+ core/
418
+ └── appwrite-model/
419
+ ├── types.ts # Définitions TypeScript
420
+ ├── schema.ts # Schéma des collections Appwrite
421
+ ├── client.ts # Client Appwrite
422
+ └── setup-collections.ts # Fonctions de setup
423
+
424
+ 📖 Prochaines étapes:
425
+ 1. Configurez vos variables d'environnement (.env)
426
+ 2. Définissez vos types dans core/appwrite-model/types.ts
427
+ 3. Définissez vos collections dans core/appwrite-model/schema.ts
428
+ 4. Exécutez: pnpm akis migrate
429
+ 5. Vérifiez avec: pnpm akis status
430
+
431
+ 📚 Commandes disponibles:
432
+ pnpm akis status # Voir l'état des collections
433
+ pnpm akis migrate # Créer les collections manquantes
434
+ pnpm akis migrate --name X # Créer une collection spécifique
435
+ pnpm akis update # Mettre à jour les collections
436
+ pnpm akis delete # Supprimer les collections
437
+ `);
438
+ }
439
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface MigrateOptions {
2
+ dryRun?: boolean;
3
+ name?: string;
4
+ }
5
+ export declare function migrate(options: MigrateOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/migrate.ts"],"names":[],"mappings":"AAcA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA4DD,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBAyJpD"}
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.migrate = migrate;
37
+ const node_appwrite_1 = require("node-appwrite");
38
+ const path = __importStar(require("path"));
39
+ const dotenv = __importStar(require("dotenv"));
40
+ const parser_1 = require("../parser");
41
+ // Load env
42
+ dotenv.config({ path: path.resolve(process.cwd(), ".env") });
43
+ dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });
44
+ const APPWRITE_ENDPOINT = process.env.APPWRITE_ENDPOINT || "https://cloud.appwrite.io/v1";
45
+ const APPWRITE_PROJECT_ID = process.env.APPWRITE_PROJECT_ID || "";
46
+ const APPWRITE_API_KEY = process.env.APPWRITE_API_KEY || "";
47
+ const APPWRITE_DATABASE_ID = process.env.APPWRITE_DATABASE_ID || "";
48
+ async function delay(ms) {
49
+ return new Promise((resolve) => setTimeout(resolve, ms));
50
+ }
51
+ async function createAttribute(databases, databaseId, collectionId, field) {
52
+ const baseParams = {
53
+ databaseId,
54
+ collectionId,
55
+ key: field.key,
56
+ required: field.required,
57
+ };
58
+ switch (field.type) {
59
+ case "string":
60
+ await databases.createStringAttribute({
61
+ ...baseParams,
62
+ size: field.size || 255,
63
+ });
64
+ break;
65
+ case "integer":
66
+ await databases.createIntegerAttribute(baseParams);
67
+ break;
68
+ case "float":
69
+ await databases.createFloatAttribute(baseParams);
70
+ break;
71
+ case "boolean":
72
+ await databases.createBooleanAttribute(baseParams);
73
+ break;
74
+ case "enum":
75
+ await databases.createEnumAttribute({
76
+ ...baseParams,
77
+ elements: field.enumValues || [],
78
+ });
79
+ break;
80
+ case "string[]":
81
+ await databases.createStringAttribute({
82
+ ...baseParams,
83
+ size: field.size || 255,
84
+ array: true,
85
+ });
86
+ break;
87
+ case "integer[]":
88
+ await databases.createIntegerAttribute({
89
+ ...baseParams,
90
+ array: true,
91
+ });
92
+ break;
93
+ case "datetime":
94
+ await databases.createDatetimeAttribute(baseParams);
95
+ break;
96
+ }
97
+ }
98
+ async function migrate(options) {
99
+ const targetName = options.name;
100
+ console.log(`\n🚀 AKIS Migrate - ${targetName ? `Création de "${targetName}"` : "Création des collections manquantes"}\n`);
101
+ if (!APPWRITE_API_KEY) {
102
+ console.error("❌ APPWRITE_API_KEY non configurée dans .env");
103
+ process.exit(1);
104
+ }
105
+ if (!APPWRITE_DATABASE_ID) {
106
+ console.error("❌ APPWRITE_DATABASE_ID non configurée dans .env");
107
+ process.exit(1);
108
+ }
109
+ // Parse types.ts
110
+ const typesPath = path.resolve(process.cwd(), "core/appwrite-model/types.ts");
111
+ console.log(`📖 Lecture de ${typesPath}...`);
112
+ let collections;
113
+ try {
114
+ const allCollections = (0, parser_1.parseTypesFile)(typesPath);
115
+ if (targetName) {
116
+ collections = allCollections.filter((c) => c.name === targetName);
117
+ if (collections.length === 0) {
118
+ console.error(`❌ Collection "${targetName}" non trouvée dans types.ts`);
119
+ console.log(` Collections disponibles: ${allCollections.map((c) => c.name).join(", ")}`);
120
+ process.exit(1);
121
+ }
122
+ }
123
+ else {
124
+ collections = allCollections;
125
+ }
126
+ console.log(` ${collections.length} collection(s) à traiter\n`);
127
+ }
128
+ catch (error) {
129
+ console.error("❌ Erreur lors de la lecture de types.ts:", error);
130
+ process.exit(1);
131
+ }
132
+ if (options.dryRun) {
133
+ console.log("🔍 Mode dry-run - Aucune modification ne sera effectuée\n");
134
+ for (const col of collections) {
135
+ console.log(` 📦 ${col.name} (${col.fields.length} champs)`);
136
+ for (const field of col.fields) {
137
+ const req = field.required ? "required" : "optional";
138
+ const extra = field.enumValues ? ` [${field.enumValues.join(", ")}]` : field.size ? ` (${field.size})` : "";
139
+ console.log(` - ${field.key}: ${field.type} ${req}${extra}`);
140
+ }
141
+ }
142
+ return;
143
+ }
144
+ // Connect to Appwrite
145
+ const client = new node_appwrite_1.Client()
146
+ .setEndpoint(APPWRITE_ENDPOINT)
147
+ .setProject(APPWRITE_PROJECT_ID)
148
+ .setKey(APPWRITE_API_KEY);
149
+ const databases = new node_appwrite_1.Databases(client);
150
+ // Get existing collections
151
+ console.log("📡 Connexion à Appwrite...");
152
+ let existingCollections = [];
153
+ try {
154
+ const response = await databases.listCollections({
155
+ databaseId: APPWRITE_DATABASE_ID,
156
+ queries: [node_appwrite_1.Query.limit(100)],
157
+ });
158
+ existingCollections = response.collections.map((c) => c.name);
159
+ console.log(` ${existingCollections.length} collections existantes\n`);
160
+ }
161
+ catch (error) {
162
+ console.error("❌ Erreur lors de la connexion:", error);
163
+ process.exit(1);
164
+ }
165
+ // Create missing collections
166
+ let created = 0;
167
+ let skipped = 0;
168
+ for (const col of collections) {
169
+ if (existingCollections.includes(col.name)) {
170
+ console.log(`⏭️ ${col.name} - existe déjà`);
171
+ skipped++;
172
+ continue;
173
+ }
174
+ console.log(`\n📦 Création de ${col.name}...`);
175
+ try {
176
+ const collectionId = node_appwrite_1.ID.unique();
177
+ await databases.createCollection({
178
+ databaseId: APPWRITE_DATABASE_ID,
179
+ collectionId,
180
+ name: col.name,
181
+ permissions: [],
182
+ documentSecurity: false,
183
+ });
184
+ // Create attributes
185
+ for (const field of col.fields) {
186
+ try {
187
+ await createAttribute(databases, APPWRITE_DATABASE_ID, collectionId, field);
188
+ console.log(` ✓ ${field.key}`);
189
+ await delay(300);
190
+ }
191
+ catch (error) {
192
+ const err = error;
193
+ console.log(` ✗ ${field.key}: ${err.message || error}`);
194
+ }
195
+ }
196
+ // Wait for attributes to be available
197
+ await delay(2000);
198
+ // Create indexes
199
+ const indexes = (0, parser_1.generateIndexes)(col);
200
+ for (const index of indexes) {
201
+ let retries = 3;
202
+ while (retries > 0) {
203
+ try {
204
+ await databases.createIndex({
205
+ databaseId: APPWRITE_DATABASE_ID,
206
+ collectionId,
207
+ key: index.key,
208
+ type: node_appwrite_1.DatabasesIndexType.Key,
209
+ attributes: index.attributes,
210
+ });
211
+ console.log(` 🔑 ${index.key}`);
212
+ await delay(300);
213
+ break;
214
+ }
215
+ catch (error) {
216
+ const err = error;
217
+ if (err.type === "attribute_not_available" && retries > 1) {
218
+ retries--;
219
+ await delay(2000);
220
+ }
221
+ else {
222
+ console.log(` ⚠️ Index ${index.key} ignoré`);
223
+ break;
224
+ }
225
+ }
226
+ }
227
+ }
228
+ created++;
229
+ console.log(` ✅ ${col.name} créée`);
230
+ }
231
+ catch (error) {
232
+ const err = error;
233
+ console.error(` ❌ Erreur: ${err.message || error}`);
234
+ }
235
+ await delay(500);
236
+ }
237
+ console.log(`\n✨ Migration terminée: ${created} créées, ${skipped} ignorées\n`);
238
+ }
239
+ //# sourceMappingURL=migrate.js.map