appwrite-utils-cli 1.8.6 → 1.8.7

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.
@@ -182,11 +182,34 @@ export const createOrUpdateCollectionsViaAdapter = async (adapter, databaseId, c
182
182
  }
183
183
  }
184
184
  }
185
- // Find existing table by name
186
- const list = await adapter.listTables({ databaseId, queries: [Query.equal('name', collectionData.name)] });
187
- const items = list.tables || [];
188
- let table = items[0];
185
+ // Find existing table — prefer lookup by ID (if provided), then by name
186
+ let table;
189
187
  let tableId;
188
+ // 1) Try by explicit $id first (handles rename scenarios)
189
+ if (collectionData.$id) {
190
+ try {
191
+ const byId = await adapter.getTable({ databaseId, tableId: collectionData.$id });
192
+ table = byId.data || byId.tables?.[0];
193
+ if (table?.$id) {
194
+ MessageFormatter.info(`Found existing table by ID: ${table.$id}`, { prefix: 'Tables' });
195
+ }
196
+ }
197
+ catch {
198
+ // Not found by ID; fall back to name lookup
199
+ }
200
+ }
201
+ // 2) If not found by ID, try by name
202
+ if (!table) {
203
+ const list = await adapter.listTables({ databaseId, queries: [Query.equal('name', collectionData.name)] });
204
+ const items = list.tables || [];
205
+ table = items[0];
206
+ if (table?.$id) {
207
+ // If local has $id that differs from remote, prefer remote (IDs are immutable)
208
+ if (collectionData.$id && collectionData.$id !== table.$id) {
209
+ MessageFormatter.warning(`Config $id '${collectionData.$id}' differs from existing table ID '${table.$id}'. Using existing table.`, { prefix: 'Tables' });
210
+ }
211
+ }
212
+ }
190
213
  if (!table) {
191
214
  // Determine ID (prefer provided $id or re-use deleted one)
192
215
  let foundColl = deletedCollections?.find((coll) => coll.collectionName.toLowerCase().trim().replace(" ", "") === collectionData.name.toLowerCase().trim().replace(" ", ""));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "appwrite-utils-cli",
3
3
  "description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
4
- "version": "1.8.6",
4
+ "version": "1.8.7",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -262,45 +262,69 @@ export const createOrUpdateCollectionsViaAdapter = async (
262
262
  }
263
263
  }
264
264
 
265
- // Find existing table by name
266
- const list = await adapter.listTables({ databaseId, queries: [Query.equal('name', collectionData.name)] });
267
- const items: any[] = (list as any).tables || [];
268
- let table = items[0];
269
- let tableId: string;
270
-
271
- if (!table) {
272
- // Determine ID (prefer provided $id or re-use deleted one)
273
- let foundColl = deletedCollections?.find(
274
- (coll) => coll.collectionName.toLowerCase().trim().replace(" ", "") === collectionData.name.toLowerCase().trim().replace(" ", "")
275
- );
276
- if (collectionData.$id) tableId = collectionData.$id;
277
- else if (foundColl && !usedIds.has(foundColl.collectionId)) tableId = foundColl.collectionId;
278
- else tableId = ID.unique();
279
- usedIds.add(tableId);
280
-
281
- const res = await adapter.createTable({
282
- databaseId,
283
- id: tableId,
284
- name: collectionData.name,
285
- permissions,
286
- documentSecurity: !!collectionData.documentSecurity,
287
- enabled: collectionData.enabled !== false
288
- });
289
- table = (res as any).data || res;
290
- nameToIdMapping.set(collectionData.name, tableId);
291
- } else {
292
- tableId = table.$id;
293
- await adapter.updateTable({
294
- databaseId,
295
- id: tableId,
296
- name: collectionData.name,
297
- permissions,
298
- documentSecurity: !!collectionData.documentSecurity,
299
- enabled: collectionData.enabled !== false
300
- });
301
- // Cache the existing table ID
302
- nameToIdMapping.set(collectionData.name, tableId);
303
- }
265
+ // Find existing table — prefer lookup by ID (if provided), then by name
266
+ let table: any | undefined;
267
+ let tableId: string;
268
+
269
+ // 1) Try by explicit $id first (handles rename scenarios)
270
+ if (collectionData.$id) {
271
+ try {
272
+ const byId = await adapter.getTable({ databaseId, tableId: collectionData.$id });
273
+ table = (byId as any).data || (byId as any).tables?.[0];
274
+ if (table?.$id) {
275
+ MessageFormatter.info(`Found existing table by ID: ${table.$id}`, { prefix: 'Tables' });
276
+ }
277
+ } catch {
278
+ // Not found by ID; fall back to name lookup
279
+ }
280
+ }
281
+
282
+ // 2) If not found by ID, try by name
283
+ if (!table) {
284
+ const list = await adapter.listTables({ databaseId, queries: [Query.equal('name', collectionData.name)] });
285
+ const items: any[] = (list as any).tables || [];
286
+ table = items[0];
287
+ if (table?.$id) {
288
+ // If local has $id that differs from remote, prefer remote (IDs are immutable)
289
+ if (collectionData.$id && collectionData.$id !== table.$id) {
290
+ MessageFormatter.warning(`Config $id '${collectionData.$id}' differs from existing table ID '${table.$id}'. Using existing table.`, { prefix: 'Tables' });
291
+ }
292
+ }
293
+ }
294
+
295
+ if (!table) {
296
+ // Determine ID (prefer provided $id or re-use deleted one)
297
+ let foundColl = deletedCollections?.find(
298
+ (coll) => coll.collectionName.toLowerCase().trim().replace(" ", "") === collectionData.name.toLowerCase().trim().replace(" ", "")
299
+ );
300
+ if (collectionData.$id) tableId = collectionData.$id;
301
+ else if (foundColl && !usedIds.has(foundColl.collectionId)) tableId = foundColl.collectionId;
302
+ else tableId = ID.unique();
303
+ usedIds.add(tableId);
304
+
305
+ const res = await adapter.createTable({
306
+ databaseId,
307
+ id: tableId,
308
+ name: collectionData.name,
309
+ permissions,
310
+ documentSecurity: !!collectionData.documentSecurity,
311
+ enabled: collectionData.enabled !== false
312
+ });
313
+ table = (res as any).data || res;
314
+ nameToIdMapping.set(collectionData.name, tableId);
315
+ } else {
316
+ tableId = table.$id;
317
+ await adapter.updateTable({
318
+ databaseId,
319
+ id: tableId,
320
+ name: collectionData.name,
321
+ permissions,
322
+ documentSecurity: !!collectionData.documentSecurity,
323
+ enabled: collectionData.enabled !== false
324
+ });
325
+ // Cache the existing table ID
326
+ nameToIdMapping.set(collectionData.name, tableId);
327
+ }
304
328
 
305
329
  // Add small delay after table create/update
306
330
  await delay(250);