appwrite-utils-cli 0.0.32 → 0.0.33
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/README.md +98 -97
- package/dist/migrations/backup.d.ts +2 -0
- package/dist/migrations/dataLoader.d.ts +22 -4
- package/dist/migrations/dataLoader.js +73 -102
- package/dist/migrations/schemaStrings.js +38 -38
- package/dist/migrations/users.js +3 -0
- package/package.json +54 -54
- package/src/main.ts +83 -83
- package/src/migrations/dataLoader.ts +97 -144
- package/src/migrations/openapi.ts +83 -83
- package/src/migrations/schemaStrings.ts +473 -473
- package/src/migrations/users.ts +3 -0
- package/src/utilsController.ts +194 -194
|
@@ -234,6 +234,10 @@ export class DataLoader {
|
|
|
234
234
|
// Determine if this is the users collection
|
|
235
235
|
let isUsersCollection = this.getCollectionKey(this.config.usersCollectionName) ===
|
|
236
236
|
this.getCollectionKey(collection.name);
|
|
237
|
+
const collectionDefs = collection.importDefs;
|
|
238
|
+
if (!collectionDefs || !collectionDefs.length) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
237
241
|
// Process create and update definitions for the collection
|
|
238
242
|
const createDefs = collection.importDefs.filter((def) => def.type === "create" || !def.type);
|
|
239
243
|
const updateDefs = collection.importDefs.filter((def) => def.type === "update");
|
|
@@ -258,8 +262,8 @@ export class DataLoader {
|
|
|
258
262
|
}
|
|
259
263
|
}
|
|
260
264
|
console.log("Running update references");
|
|
261
|
-
|
|
262
|
-
|
|
265
|
+
this.dealWithMergedUsers();
|
|
266
|
+
this.updateOldReferencesForNew();
|
|
263
267
|
console.log("Done running update references");
|
|
264
268
|
}
|
|
265
269
|
// for (const collection of this.config.collections) {
|
|
@@ -272,7 +276,7 @@ export class DataLoader {
|
|
|
272
276
|
this.writeMapsToJsonFile();
|
|
273
277
|
}
|
|
274
278
|
}
|
|
275
|
-
|
|
279
|
+
dealWithMergedUsers() {
|
|
276
280
|
const usersCollectionKey = this.getCollectionKey(this.config.usersCollectionName);
|
|
277
281
|
const usersCollectionPrimaryKeyFields = new Set();
|
|
278
282
|
if (!this.config.collections) {
|
|
@@ -281,7 +285,11 @@ export class DataLoader {
|
|
|
281
285
|
// Collect primary key fields from the users collection definitions
|
|
282
286
|
this.config.collections.forEach((collection) => {
|
|
283
287
|
if (this.getCollectionKey(collection.name) === usersCollectionKey) {
|
|
284
|
-
collection.importDefs
|
|
288
|
+
const collectionImportDefs = collection.importDefs;
|
|
289
|
+
if (!collectionImportDefs || !collectionImportDefs.length) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
collectionImportDefs.forEach((importDef) => {
|
|
285
293
|
if (importDef.primaryKeyField) {
|
|
286
294
|
usersCollectionPrimaryKeyFields.add(importDef.primaryKeyField);
|
|
287
295
|
}
|
|
@@ -293,19 +301,23 @@ export class DataLoader {
|
|
|
293
301
|
const collectionData = this.importMap.get(this.getCollectionKey(collection.name));
|
|
294
302
|
if (!collectionData || !collectionData.data)
|
|
295
303
|
return;
|
|
296
|
-
collection.importDefs
|
|
304
|
+
const collectionImportDefs = collection.importDefs;
|
|
305
|
+
if (!collectionImportDefs || !collectionImportDefs.length) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
collectionImportDefs.forEach((importDef) => {
|
|
297
309
|
importDef.idMappings?.forEach((idMapping) => {
|
|
298
310
|
if (this.getCollectionKey(idMapping.targetCollection) ===
|
|
299
311
|
usersCollectionKey) {
|
|
300
|
-
|
|
312
|
+
const targetFieldKey = idMapping.targetFieldToMatch || idMapping.targetField;
|
|
313
|
+
if (usersCollectionPrimaryKeyFields.has(targetFieldKey)) {
|
|
301
314
|
// Process each item in the collection
|
|
302
315
|
collectionData.data.forEach((item) => {
|
|
303
316
|
const oldId = item.context[idMapping.sourceField];
|
|
304
317
|
const newId = this.mergedUserMap.get(oldId);
|
|
305
318
|
if (newId) {
|
|
306
319
|
// Update context to use new user ID
|
|
307
|
-
item.context[idMapping.fieldToSet ||
|
|
308
|
-
newId;
|
|
320
|
+
item.context[idMapping.fieldToSet || targetFieldKey] = newId;
|
|
309
321
|
}
|
|
310
322
|
});
|
|
311
323
|
}
|
|
@@ -333,123 +345,82 @@ export class DataLoader {
|
|
|
333
345
|
for (const idMapping of importDef.idMappings) {
|
|
334
346
|
const targetCollectionKey = this.getCollectionKey(idMapping.targetCollection);
|
|
335
347
|
const fieldToSetKey = idMapping.fieldToSet || idMapping.sourceField;
|
|
348
|
+
const targetFieldKey = idMapping.targetFieldToMatch || idMapping.targetField;
|
|
336
349
|
const valueToMatch = collectionData.data[i].context[idMapping.sourceField];
|
|
350
|
+
// Skip if value to match is missing or empty
|
|
337
351
|
if (!valueToMatch || _.isEmpty(valueToMatch))
|
|
338
352
|
continue;
|
|
353
|
+
const isFieldToSetArray = collectionConfig.attributes.find((attribute) => attribute.key === fieldToSetKey)?.array;
|
|
339
354
|
const targetCollectionData = this.importMap.get(targetCollectionKey);
|
|
340
355
|
if (!targetCollectionData || !targetCollectionData.data)
|
|
341
356
|
continue;
|
|
342
|
-
|
|
343
|
-
|
|
357
|
+
// Find matching data in the target collection
|
|
358
|
+
const foundData = targetCollectionData.data.filter(({ context }) => {
|
|
359
|
+
const targetValue = context[targetFieldKey];
|
|
344
360
|
const isMatch = `${targetValue}` === `${valueToMatch}`;
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
|
|
361
|
+
// Ensure the targetValue is defined and not null
|
|
362
|
+
return (isMatch &&
|
|
363
|
+
targetValue !== undefined &&
|
|
364
|
+
targetValue !== null);
|
|
348
365
|
});
|
|
366
|
+
// Log and skip if no matching data found
|
|
349
367
|
if (!foundData.length) {
|
|
350
|
-
console.log(`No data found for collection: ${targetCollectionKey}
|
|
368
|
+
console.log(`No data found for collection ${collectionConfig.name}:\nTarget collection: ${targetCollectionKey}\nValue to match: ${valueToMatch}\nField to set: ${fieldToSetKey}\nTarget field to match: ${targetFieldKey}\nTarget field value: ${idMapping.targetField}`);
|
|
351
369
|
logger.error(`No data found for collection: ${targetCollectionKey} with value: ${valueToMatch} for field: ${fieldToSetKey} -- idMapping: ${JSON.stringify(idMapping, null, 2)}`);
|
|
352
370
|
continue;
|
|
353
371
|
}
|
|
354
372
|
needsUpdate = true;
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
373
|
+
const getCurrentDataFiltered = (currentData) => {
|
|
374
|
+
if (Array.isArray(currentData.finalData[fieldToSetKey])) {
|
|
375
|
+
return currentData.finalData[fieldToSetKey].filter((data) => `${data}` !== `${valueToMatch}`);
|
|
376
|
+
}
|
|
377
|
+
return currentData.finalData[fieldToSetKey];
|
|
378
|
+
};
|
|
379
|
+
// Get the current data to be updated
|
|
380
|
+
const currentDataFiltered = getCurrentDataFiltered(collectionData.data[i]);
|
|
381
|
+
// Extract the new data to set
|
|
382
|
+
const newData = foundData.map((data) => data.context[idMapping.targetField]);
|
|
383
|
+
// Handle cases where current data is an array
|
|
384
|
+
if (isFieldToSetArray) {
|
|
385
|
+
if (!currentDataFiltered) {
|
|
386
|
+
// Set new data if current data is undefined
|
|
387
|
+
collectionData.data[i].finalData[fieldToSetKey] =
|
|
388
|
+
Array.isArray(newData) ? newData : [newData];
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
// Merge arrays if new data is non-empty array and filter for uniqueness
|
|
392
|
+
collectionData.data[i].finalData[fieldToSetKey] = [
|
|
393
|
+
...new Set([...currentDataFiltered, ...newData].filter((value) => `${value}` !== `${valueToMatch}`)),
|
|
394
|
+
];
|
|
395
|
+
}
|
|
359
396
|
}
|
|
360
397
|
else {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
if (needsUpdate) {
|
|
370
|
-
this.importMap.set(collectionKey, collectionData);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
async updateReferencesInRelatedCollections() {
|
|
375
|
-
if (!this.config.collections) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
// Iterate over each collection configuration
|
|
379
|
-
for (const collectionConfig of this.config.collections) {
|
|
380
|
-
const collectionKey = this.getCollectionKey(collectionConfig.name);
|
|
381
|
-
const collectionData = this.importMap.get(collectionKey);
|
|
382
|
-
if (!collectionData || !collectionData.data)
|
|
383
|
-
continue;
|
|
384
|
-
console.log(`Updating references for collection: ${collectionConfig.name}`);
|
|
385
|
-
// Iterate over each data item in the current collection
|
|
386
|
-
for (const item of collectionData.data) {
|
|
387
|
-
let needsUpdate = false;
|
|
388
|
-
// Check if the current collection has import definitions with idMappings
|
|
389
|
-
if (collectionConfig.importDefs) {
|
|
390
|
-
for (const importDef of collectionConfig.importDefs) {
|
|
391
|
-
if (importDef.idMappings) {
|
|
392
|
-
// Iterate over each idMapping defined for the current import definition
|
|
393
|
-
for (const idMapping of importDef.idMappings) {
|
|
394
|
-
const oldIds = Array.isArray(item.context[idMapping.sourceField])
|
|
395
|
-
? item.context[idMapping.sourceField]
|
|
396
|
-
: [item.context[idMapping.sourceField]];
|
|
397
|
-
const resolvedNewIds = [];
|
|
398
|
-
oldIds.forEach((oldId) => {
|
|
399
|
-
// Attempt to find a new ID for the old ID
|
|
400
|
-
let newIdForOldId = this.findNewIdForOldId(oldId, idMapping, importDef);
|
|
401
|
-
if (newIdForOldId &&
|
|
402
|
-
!resolvedNewIds.includes(newIdForOldId)) {
|
|
403
|
-
resolvedNewIds.push(newIdForOldId);
|
|
398
|
+
if (!currentDataFiltered) {
|
|
399
|
+
// Set new data if current data is undefined
|
|
400
|
+
collectionData.data[i].finalData[fieldToSetKey] =
|
|
401
|
+
Array.isArray(newData) ? newData : [newData];
|
|
404
402
|
}
|
|
405
|
-
else {
|
|
406
|
-
|
|
403
|
+
else if (Array.isArray(newData) && newData.length > 0) {
|
|
404
|
+
// Convert current data to array and merge if new data is non-empty array, then filter for uniqueness
|
|
405
|
+
collectionData.data[i].finalData[fieldToSetKey] = [
|
|
406
|
+
...new Set([currentDataFiltered, ...newData].filter((value) => `${value}` !== `${valueToMatch}`)),
|
|
407
|
+
];
|
|
408
|
+
}
|
|
409
|
+
else if (!Array.isArray(newData) && newData !== undefined) {
|
|
410
|
+
// Simply update the field if new data is not an array and defined
|
|
411
|
+
collectionData.data[i].finalData[fieldToSetKey] = newData;
|
|
407
412
|
}
|
|
408
|
-
});
|
|
409
|
-
if (resolvedNewIds.length) {
|
|
410
|
-
const targetField = idMapping.fieldToSet || idMapping.targetField;
|
|
411
|
-
const isArray = collectionConfig.attributes.some((attribute) => attribute.key === targetField && attribute.array);
|
|
412
|
-
// Set the target field based on whether it's an array or single value
|
|
413
|
-
item.finalData[targetField] = isArray
|
|
414
|
-
? resolvedNewIds
|
|
415
|
-
: resolvedNewIds[0];
|
|
416
|
-
needsUpdate = true;
|
|
417
413
|
}
|
|
418
414
|
}
|
|
419
415
|
}
|
|
420
416
|
}
|
|
421
417
|
}
|
|
422
|
-
// Update the importMap if changes were made to the item
|
|
423
|
-
if (needsUpdate) {
|
|
424
|
-
this.importMap.set(collectionKey, collectionData);
|
|
425
|
-
logger.info(`Updated item: ${JSON.stringify(item.finalData, undefined, 2)}`);
|
|
426
|
-
}
|
|
427
418
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
// First, check if this ID mapping is related to the users collection.
|
|
432
|
-
const targetCollectionKey = this.getCollectionKey(idMapping.targetCollection);
|
|
433
|
-
const isUsersCollection = targetCollectionKey ===
|
|
434
|
-
this.getCollectionKey(this.config.usersCollectionName);
|
|
435
|
-
// If handling users, check the mergedUserMap for any existing new ID.
|
|
436
|
-
if (isUsersCollection) {
|
|
437
|
-
for (const [newUserId, oldIds] of this.mergedUserMap.entries()) {
|
|
438
|
-
if (oldIds.includes(oldId)) {
|
|
439
|
-
return newUserId;
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
// If not a user or no merged ID found, check the regular ID mapping from old to new.
|
|
444
|
-
const targetCollectionData = this.importMap.get(targetCollectionKey);
|
|
445
|
-
if (targetCollectionData) {
|
|
446
|
-
const foundEntry = targetCollectionData.data.find((entry) => entry.context[importDef.primaryKeyField] === oldId);
|
|
447
|
-
if (foundEntry) {
|
|
448
|
-
return foundEntry.context.docId; // Assuming `docId` stores the new ID after import
|
|
419
|
+
// Update the import map if any changes were made
|
|
420
|
+
if (needsUpdate) {
|
|
421
|
+
this.importMap.set(collectionKey, collectionData);
|
|
449
422
|
}
|
|
450
423
|
}
|
|
451
|
-
logger.error(`No corresponding new ID found for ${oldId} in ${targetCollectionKey}`);
|
|
452
|
-
return null; // Return null if no new ID is found
|
|
453
424
|
}
|
|
454
425
|
writeMapsToJsonFile() {
|
|
455
426
|
const outputDir = path.resolve(process.cwd());
|
|
@@ -601,12 +572,12 @@ export class DataLoader {
|
|
|
601
572
|
if (!existingId) {
|
|
602
573
|
// No existing user ID, generate a new unique ID
|
|
603
574
|
existingId = this.getTrueUniqueId(this.getCollectionKey("users"));
|
|
604
|
-
transformedItem.
|
|
575
|
+
transformedItem.docId = existingId; // Assign the new ID to the transformed data's docId field
|
|
605
576
|
}
|
|
606
577
|
// Create a context object for the item, including the new ID
|
|
607
578
|
let context = this.createContext(db, collection, item, existingId);
|
|
608
579
|
// Merge the transformed data into the context
|
|
609
|
-
context = { ...context, ...transformedItem };
|
|
580
|
+
context = { ...context, ...transformedItem, ...userData.finalData };
|
|
610
581
|
// If a primary key field is defined, handle the ID mapping and check for duplicates
|
|
611
582
|
if (importDef.primaryKeyField) {
|
|
612
583
|
const oldId = item[importDef.primaryKeyField];
|
|
@@ -17,25 +17,25 @@ export class SchemaGenerator {
|
|
|
17
17
|
const collections = this.config.collections;
|
|
18
18
|
delete this.config.collections;
|
|
19
19
|
const configPath = path.join(this.appwriteFolderPath, "appwriteConfig.ts");
|
|
20
|
-
const configContent = `import { type AppwriteConfig } from "appwrite-utils";
|
|
21
|
-
|
|
22
|
-
const appwriteConfig: AppwriteConfig = {
|
|
23
|
-
appwriteEndpoint: "${this.config.appwriteEndpoint}",
|
|
24
|
-
appwriteProject: "${this.config.appwriteProject}",
|
|
25
|
-
appwriteKey: "${this.config.appwriteKey}",
|
|
26
|
-
enableDevDatabase: ${this.config.enableDevDatabase},
|
|
27
|
-
enableBackups: ${this.config.enableBackups},
|
|
28
|
-
backupInterval: ${this.config.backupInterval},
|
|
29
|
-
backupRetention: ${this.config.backupRetention},
|
|
30
|
-
enableBackupCleanup: ${this.config.enableBackupCleanup},
|
|
31
|
-
enableMockData: ${this.config.enableMockData},
|
|
32
|
-
enableWipeOtherDatabases: ${this.config.enableWipeOtherDatabases},
|
|
33
|
-
documentBucketId: "${this.config.documentBucketId}",
|
|
34
|
-
usersCollectionName: "${this.config.usersCollectionName}",
|
|
35
|
-
databases: ${JSON.stringify(this.config.databases)}
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export default appwriteConfig;
|
|
20
|
+
const configContent = `import { type AppwriteConfig } from "appwrite-utils";
|
|
21
|
+
|
|
22
|
+
const appwriteConfig: AppwriteConfig = {
|
|
23
|
+
appwriteEndpoint: "${this.config.appwriteEndpoint}",
|
|
24
|
+
appwriteProject: "${this.config.appwriteProject}",
|
|
25
|
+
appwriteKey: "${this.config.appwriteKey}",
|
|
26
|
+
enableDevDatabase: ${this.config.enableDevDatabase},
|
|
27
|
+
enableBackups: ${this.config.enableBackups},
|
|
28
|
+
backupInterval: ${this.config.backupInterval},
|
|
29
|
+
backupRetention: ${this.config.backupRetention},
|
|
30
|
+
enableBackupCleanup: ${this.config.enableBackupCleanup},
|
|
31
|
+
enableMockData: ${this.config.enableMockData},
|
|
32
|
+
enableWipeOtherDatabases: ${this.config.enableWipeOtherDatabases},
|
|
33
|
+
documentBucketId: "${this.config.documentBucketId}",
|
|
34
|
+
usersCollectionName: "${this.config.usersCollectionName}",
|
|
35
|
+
databases: ${JSON.stringify(this.config.databases)}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default appwriteConfig;
|
|
39
39
|
`;
|
|
40
40
|
fs.writeFileSync(configPath, configContent, { encoding: "utf-8" });
|
|
41
41
|
const collectionsFolderPath = path.join(this.appwriteFolderPath, "collections");
|
|
@@ -45,19 +45,19 @@ export class SchemaGenerator {
|
|
|
45
45
|
collections?.forEach((collection) => {
|
|
46
46
|
const { databaseId, ...collectionWithoutDbId } = collection; // Destructure to exclude databaseId
|
|
47
47
|
const collectionFilePath = path.join(collectionsFolderPath, `${collection.name}.ts`);
|
|
48
|
-
const collectionContent = `import { type CollectionCreate } from "appwrite-utils";
|
|
49
|
-
|
|
50
|
-
const ${collection.name}Config: Partial<CollectionCreate> = {
|
|
51
|
-
name: "${collection.name}",
|
|
52
|
-
$id: "${collection.$id}",
|
|
53
|
-
enabled: ${collection.enabled},
|
|
54
|
-
documentSecurity: ${collection.documentSecurity},
|
|
55
|
-
$permissions: [
|
|
48
|
+
const collectionContent = `import { type CollectionCreate } from "appwrite-utils";
|
|
49
|
+
|
|
50
|
+
const ${collection.name}Config: Partial<CollectionCreate> = {
|
|
51
|
+
name: "${collection.name}",
|
|
52
|
+
$id: "${collection.$id}",
|
|
53
|
+
enabled: ${collection.enabled},
|
|
54
|
+
documentSecurity: ${collection.documentSecurity},
|
|
55
|
+
$permissions: [
|
|
56
56
|
${collection.$permissions
|
|
57
57
|
.map((permission) => `{ permission: "${permission.permission}", target: "${permission.target}" }`)
|
|
58
|
-
.join(",\n ")}
|
|
59
|
-
],
|
|
60
|
-
attributes: [
|
|
58
|
+
.join(",\n ")}
|
|
59
|
+
],
|
|
60
|
+
attributes: [
|
|
61
61
|
${collection.attributes
|
|
62
62
|
.map((attr) => {
|
|
63
63
|
return `{ ${Object.entries(attr)
|
|
@@ -85,9 +85,9 @@ export class SchemaGenerator {
|
|
|
85
85
|
})
|
|
86
86
|
.join(", ")} }`;
|
|
87
87
|
})
|
|
88
|
-
.join(",\n ")}
|
|
89
|
-
],
|
|
90
|
-
indexes: [
|
|
88
|
+
.join(",\n ")}
|
|
89
|
+
],
|
|
90
|
+
indexes: [
|
|
91
91
|
${(collection.indexes?.map((index) => {
|
|
92
92
|
// Map each attribute to ensure it is properly quoted
|
|
93
93
|
const formattedAttributes = index.attributes.map((attr) => `"${attr}"`).join(", ") ?? "";
|
|
@@ -95,11 +95,11 @@ export class SchemaGenerator {
|
|
|
95
95
|
?.filter((order) => order !== null)
|
|
96
96
|
.map((order) => `"${order}"`)
|
|
97
97
|
.join(", ") ?? ""}] }`;
|
|
98
|
-
}) ?? []).join(",\n ")}
|
|
99
|
-
]
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export default ${collection.name}Config;
|
|
98
|
+
}) ?? []).join(",\n ")}
|
|
99
|
+
]
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export default ${collection.name}Config;
|
|
103
103
|
`;
|
|
104
104
|
fs.writeFileSync(collectionFilePath, collectionContent, {
|
|
105
105
|
encoding: "utf-8",
|
package/dist/migrations/users.js
CHANGED
|
@@ -69,6 +69,9 @@ export class UsersController {
|
|
|
69
69
|
async getAllUsers() {
|
|
70
70
|
const allUsers = [];
|
|
71
71
|
const users = await this.users.list([Query.limit(200)]);
|
|
72
|
+
if (users.users.length === 0) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
72
75
|
if (users.users.length === 200) {
|
|
73
76
|
let lastDocumentId = users.users[users.users.length - 1].$id;
|
|
74
77
|
allUsers.push(...users.users);
|
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "appwrite-utils-cli",
|
|
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": "0.0.
|
|
5
|
-
"main": "src/main.ts",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "https://github.com/zachhandley/AppwriteUtils"
|
|
10
|
-
},
|
|
11
|
-
"author": "Zach Handley <zach@blackleafdigital.com> (https://zachhandley.com)",
|
|
12
|
-
"keywords": [
|
|
13
|
-
"appwrite",
|
|
14
|
-
"cli",
|
|
15
|
-
"utils",
|
|
16
|
-
"migrations",
|
|
17
|
-
"data",
|
|
18
|
-
"database",
|
|
19
|
-
"import",
|
|
20
|
-
"migration",
|
|
21
|
-
"utility"
|
|
22
|
-
],
|
|
23
|
-
"bin": {
|
|
24
|
-
"appwrite-init": "./dist/init.js",
|
|
25
|
-
"appwrite-migrate": "./dist/main.js"
|
|
26
|
-
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "bun run tsc",
|
|
29
|
-
"init": "tsx --no-cache src/init.ts",
|
|
30
|
-
"migrate": "tsx --no-cache src/main.ts",
|
|
31
|
-
"deploy": "bun run build && npm publish --access public",
|
|
32
|
-
"postinstall": "echo 'This package is intended for CLI use only and should not be added as a dependency in other projects.'"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"@types/inquirer": "^9.0.7",
|
|
36
|
-
"appwrite-utils": "^0.2.
|
|
37
|
-
"commander": "^12.0.0",
|
|
38
|
-
"inquirer": "^9.2.20",
|
|
39
|
-
"js-yaml": "^4.1.0",
|
|
40
|
-
"lodash": "^4.17.21",
|
|
41
|
-
"luxon": "^3.4.4",
|
|
42
|
-
"nanostores": "^0.10.3",
|
|
43
|
-
"node-appwrite": "^12.0.1",
|
|
44
|
-
"tsx": "^4.9.3",
|
|
45
|
-
"winston": "^3.13.0",
|
|
46
|
-
"zod": "^3.22.4"
|
|
47
|
-
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@types/js-yaml": "^4.0.9",
|
|
50
|
-
"@types/lodash": "^4.17.0",
|
|
51
|
-
"@types/luxon": "^3.4.2",
|
|
52
|
-
"typescript": "^5.0.0"
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "appwrite-utils-cli",
|
|
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": "0.0.33",
|
|
5
|
+
"main": "src/main.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/zachhandley/AppwriteUtils"
|
|
10
|
+
},
|
|
11
|
+
"author": "Zach Handley <zach@blackleafdigital.com> (https://zachhandley.com)",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"appwrite",
|
|
14
|
+
"cli",
|
|
15
|
+
"utils",
|
|
16
|
+
"migrations",
|
|
17
|
+
"data",
|
|
18
|
+
"database",
|
|
19
|
+
"import",
|
|
20
|
+
"migration",
|
|
21
|
+
"utility"
|
|
22
|
+
],
|
|
23
|
+
"bin": {
|
|
24
|
+
"appwrite-init": "./dist/init.js",
|
|
25
|
+
"appwrite-migrate": "node --max-old-space-size=16384 ./dist/main.js"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "bun run tsc",
|
|
29
|
+
"init": "tsx --no-cache src/init.ts",
|
|
30
|
+
"migrate": "tsx --no-cache src/main.ts",
|
|
31
|
+
"deploy": "bun run build && npm publish --access public",
|
|
32
|
+
"postinstall": "echo 'This package is intended for CLI use only and should not be added as a dependency in other projects.'"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@types/inquirer": "^9.0.7",
|
|
36
|
+
"appwrite-utils": "^0.2.5",
|
|
37
|
+
"commander": "^12.0.0",
|
|
38
|
+
"inquirer": "^9.2.20",
|
|
39
|
+
"js-yaml": "^4.1.0",
|
|
40
|
+
"lodash": "^4.17.21",
|
|
41
|
+
"luxon": "^3.4.4",
|
|
42
|
+
"nanostores": "^0.10.3",
|
|
43
|
+
"node-appwrite": "^12.0.1",
|
|
44
|
+
"tsx": "^4.9.3",
|
|
45
|
+
"winston": "^3.13.0",
|
|
46
|
+
"zod": "^3.22.4"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/js-yaml": "^4.0.9",
|
|
50
|
+
"@types/lodash": "^4.17.0",
|
|
51
|
+
"@types/luxon": "^3.4.2",
|
|
52
|
+
"typescript": "^5.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|