appwrite-utils-cli 0.0.2 → 0.0.4
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/dist/migrations/afterImportActions.js +3 -0
- package/dist/migrations/backup.d.ts +8 -8
- package/dist/migrations/backup.js +18 -2
- package/dist/migrations/importController.d.ts +2 -2
- package/dist/migrations/importController.js +78 -12
- package/dist/migrations/migrationHelper.d.ts +154 -2
- package/dist/migrations/migrationHelper.js +101 -7
- package/dist/migrations/relationships.d.ts +5 -72
- package/dist/migrations/relationships.js +88 -97
- package/dist/migrations/schema.d.ts +80 -10
- package/dist/migrations/schema.js +43 -42
- package/dist/migrations/schemaStrings.js +5 -2
- package/dist/schemas/authUser.d.ts +3 -3
- package/package.json +1 -1
- package/src/appwrite/.appwrite/appwriteUtilsConfigSchema.json +667 -0
- package/src/appwrite/customDefinitions.ts +11 -0
- package/src/appwrite/importData/dogs.json +76 -0
- package/src/appwrite/importData/members.json +16 -0
- package/src/appwrite/importData/profilePhotos/profilePhoto_123.jpg +0 -0
- package/src/appwrite/importData/profilePhotos/profilePhoto_456.png +0 -0
- package/src/appwrite/schemas/dogs.ts +27 -0
- package/src/appwrite/schemas/members.ts +24 -0
- package/src/migrations/afterImportActions.ts +3 -0
- package/src/migrations/backup.ts +18 -2
- package/src/migrations/importController.ts +119 -28
- package/src/migrations/migrationHelper.ts +168 -7
- package/src/migrations/relationships.ts +122 -137
- package/src/migrations/schema.ts +60 -58
- package/src/migrations/schemaStrings.ts +4 -2
|
@@ -1,42 +1,27 @@
|
|
|
1
1
|
import { Databases, Query } from "node-appwrite";
|
|
2
2
|
import { fetchAllCollections } from "./collections.js";
|
|
3
|
+
import { logger } from "./logging.js";
|
|
4
|
+
/**
|
|
5
|
+
* Finds collections that have defined relationship attributes.
|
|
6
|
+
*/
|
|
3
7
|
export const findCollectionsWithRelationships = (config) => {
|
|
4
8
|
const toReturn = new Map();
|
|
5
|
-
// Map of collection name to array of attributes so we can update the relationships
|
|
6
9
|
for (const collection of config.collections) {
|
|
7
10
|
if (collection.attributes) {
|
|
8
11
|
for (const attribute of collection.attributes) {
|
|
9
|
-
if (attribute.type === "relationship"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
toReturn
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
toReturn.get(attribute.relatedCollection)?.push(attribute);
|
|
12
|
+
if (attribute.type === "relationship" &&
|
|
13
|
+
attribute.twoWay &&
|
|
14
|
+
attribute.side === "parent") {
|
|
15
|
+
toReturn.set(collection.name, toReturn.get(collection.name) || []);
|
|
16
|
+
toReturn
|
|
17
|
+
.get(collection.name)
|
|
18
|
+
?.push(attribute);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
return toReturn;
|
|
23
24
|
};
|
|
24
|
-
async function fetchAllDocuments(dbId, database, collectionId) {
|
|
25
|
-
let allDocuments = [];
|
|
26
|
-
let after; // This will be used for pagination
|
|
27
|
-
while (true) {
|
|
28
|
-
const response = await database.listDocuments(dbId, collectionId, [
|
|
29
|
-
Query.limit(100), // Adjust based on the maximum limit your database allows
|
|
30
|
-
...(after ? [Query.cursorAfter(after)] : []),
|
|
31
|
-
]);
|
|
32
|
-
allDocuments = allDocuments.concat(response.documents);
|
|
33
|
-
if (response.documents.length === 0 || response.total === 0) {
|
|
34
|
-
break; // Exit the loop if there are no more documents to fetch
|
|
35
|
-
}
|
|
36
|
-
after = response.documents[response.documents.length - 1].$id; // Prepare for the next page
|
|
37
|
-
}
|
|
38
|
-
return allDocuments;
|
|
39
|
-
}
|
|
40
25
|
export async function resolveAndUpdateRelationships(dbId, database, config) {
|
|
41
26
|
const collections = await fetchAllCollections(dbId, database);
|
|
42
27
|
const collectionsWithRelationships = findCollectionsWithRelationships(config);
|
|
@@ -53,17 +38,30 @@ export async function resolveAndUpdateRelationships(dbId, database, config) {
|
|
|
53
38
|
console.log(`Completed relationship resolution and update for database ID: ${dbId}`);
|
|
54
39
|
}
|
|
55
40
|
async function processCollection(dbId, database, collection, relAttributeMap) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
41
|
+
let after; // For pagination
|
|
42
|
+
let hasMore = true;
|
|
43
|
+
while (hasMore) {
|
|
44
|
+
const response = await database.listDocuments(dbId, collection.$id, [
|
|
45
|
+
Query.limit(100), // Fetch documents in batches of 100
|
|
46
|
+
...(after ? [Query.cursorAfter(after)] : []),
|
|
47
|
+
]);
|
|
48
|
+
const documents = response.documents;
|
|
49
|
+
console.log(`Fetched ${documents.length} documents from collection: ${collection.name}`);
|
|
50
|
+
if (documents.length > 0) {
|
|
51
|
+
const updates = await prepareDocumentUpdates(database, dbId, collection.name, documents, relAttributeMap);
|
|
52
|
+
// Execute updates for the current batch
|
|
53
|
+
await executeUpdatesInBatches(dbId, database, updates);
|
|
54
|
+
}
|
|
55
|
+
if (documents.length === 100) {
|
|
56
|
+
after = documents[documents.length - 1].$id; // Prepare for the next page
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
hasMore = false; // No more documents to fetch
|
|
60
|
+
}
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
|
-
async function findDocumentsByOriginalId(database, dbId,
|
|
63
|
+
async function findDocumentsByOriginalId(database, dbId, targetCollection, targetKey, originalId) {
|
|
64
|
+
const relatedCollectionId = targetCollection.$id;
|
|
67
65
|
const collection = await database.listCollections(dbId, [
|
|
68
66
|
Query.equal("$id", relatedCollectionId),
|
|
69
67
|
]);
|
|
@@ -90,10 +88,10 @@ async function findDocumentsByOriginalId(database, dbId, relatedCollectionId, ta
|
|
|
90
88
|
...queries,
|
|
91
89
|
Query.limit(500), // Adjust the limit based on your needs or implement pagination
|
|
92
90
|
]);
|
|
93
|
-
if (response.
|
|
91
|
+
if (response.documents.length < 0) {
|
|
94
92
|
return undefined;
|
|
95
93
|
}
|
|
96
|
-
if (response.documents.length > 0) {
|
|
94
|
+
else if (response.documents.length > 0) {
|
|
97
95
|
return response.documents;
|
|
98
96
|
}
|
|
99
97
|
else {
|
|
@@ -109,68 +107,62 @@ async function prepareDocumentUpdates(database, dbId, collectionName, documents,
|
|
|
109
107
|
console.log(`No collection found with name: ${collectionName}`);
|
|
110
108
|
return [];
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
for (const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
110
|
+
for (const doc of documents) {
|
|
111
|
+
let updatePayload = {};
|
|
112
|
+
for (const rel of relationships) {
|
|
113
|
+
// Skip if not dealing with the parent side of a two-way relationship
|
|
114
|
+
if (rel.twoWay && rel.side !== "parent") {
|
|
115
|
+
console.log("Skipping non-parent side of two-way relationship...");
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const isSingleReference = rel.relationType === "oneToOne" || rel.relationType === "manyToOne";
|
|
119
|
+
const originalIdField = rel.importMapping?.originalIdField;
|
|
120
|
+
const targetField = rel.importMapping?.targetField || originalIdField; // Use originalIdField if targetField is not specified
|
|
121
|
+
if (!originalIdField) {
|
|
122
|
+
console.log("Missing originalIdField in importMapping, skipping...");
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const originalId = doc[originalIdField];
|
|
126
|
+
if (!originalId) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const relatedCollection = (await database.listCollections(dbId, [
|
|
130
|
+
Query.equal("name", rel.relatedCollection),
|
|
131
|
+
])).collections[0];
|
|
132
|
+
if (!relatedCollection) {
|
|
133
|
+
console.log(`Related collection ${rel.relatedCollection} not found, skipping...`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const foundDocuments = await findDocumentsByOriginalId(database, dbId, relatedCollection, targetField, originalId);
|
|
137
|
+
if (foundDocuments && foundDocuments.length > 0) {
|
|
138
|
+
const relationshipKey = rel.key;
|
|
139
|
+
const existingRefs = doc[relationshipKey] || [];
|
|
140
|
+
let existingRefIds = [];
|
|
141
|
+
if (Array.isArray(existingRefs)) {
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
existingRefIds = existingRefs.map((ref) => ref.$id);
|
|
139
144
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (foundDocuments && foundDocuments.length > 0) {
|
|
144
|
-
const relationshipKey = rel.key;
|
|
145
|
-
const existingRefs = doc[relationshipKey] || [];
|
|
146
|
-
let existingRefIds = [];
|
|
147
|
-
if (Array.isArray(existingRefs)) {
|
|
148
|
-
// @ts-ignore
|
|
149
|
-
existingRefIds = existingRefs.map((ref) => ref.$id);
|
|
150
|
-
}
|
|
151
|
-
else if (existingRefs) {
|
|
152
|
-
// @ts-ignore
|
|
153
|
-
existingRefIds = [existingRefs.$id];
|
|
154
|
-
}
|
|
155
|
-
const newRefs = foundDocuments.map((fd) => fd.$id);
|
|
156
|
-
const allRefs = [...new Set([...existingRefIds, ...newRefs])]; // Combine and remove duplicates
|
|
157
|
-
// Update logic based on the relationship cardinality
|
|
158
|
-
updatePayload[relationshipKey] = isSingleReference
|
|
159
|
-
? newRefs[0] || existingRefIds[0]
|
|
160
|
-
: allRefs;
|
|
145
|
+
else if (existingRefs) {
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
existingRefIds = [existingRefs.$id];
|
|
161
148
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
149
|
+
const newRefs = foundDocuments.map((fd) => fd.$id);
|
|
150
|
+
const allRefs = [...new Set([...existingRefIds, ...newRefs])]; // Combine and remove duplicates
|
|
151
|
+
// Update logic based on the relationship cardinality
|
|
152
|
+
updatePayload[relationshipKey] = isSingleReference
|
|
153
|
+
? newRefs[0] || existingRefIds[0]
|
|
154
|
+
: allRefs;
|
|
155
|
+
console.log(`Updating ${relationshipKey} with ${allRefs.length} refs`);
|
|
169
156
|
}
|
|
170
157
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
158
|
+
if (Object.keys(updatePayload).length > 0) {
|
|
159
|
+
updates.push({
|
|
160
|
+
collectionId: thisCollectionId,
|
|
161
|
+
documentId: doc.$id,
|
|
162
|
+
updatePayload: updatePayload,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
174
166
|
return updates;
|
|
175
167
|
}
|
|
176
168
|
async function processInBatches(items, batchSize, processFunction) {
|
|
@@ -202,8 +194,7 @@ async function executeUpdatesInBatches(dbId, database, updates) {
|
|
|
202
194
|
await Promise.all(batch.map((update) => database
|
|
203
195
|
.updateDocument(dbId, update.collectionId, update.documentId, update.updatePayload)
|
|
204
196
|
.catch((error) => {
|
|
205
|
-
|
|
206
|
-
console.error("Document ID: ", update.documentId, "Collection ID: ", update.collectionId, "Document update payload: ", JSON.stringify(update.updatePayload, undefined, 4));
|
|
197
|
+
logger.error(`Error updating doc ${update.documentId} in ${dbId}, update payload: ${JSON.stringify(update.updatePayload, undefined, 4)}, error: ${error}`);
|
|
207
198
|
})));
|
|
208
199
|
}
|
|
209
200
|
}
|
|
@@ -676,6 +676,76 @@ export declare const indexSchema: z.ZodObject<{
|
|
|
676
676
|
orders?: string[] | undefined;
|
|
677
677
|
}>;
|
|
678
678
|
export type Index = z.infer<typeof indexSchema>;
|
|
679
|
+
export declare const AttributeMappingsSchema: z.ZodArray<z.ZodObject<{
|
|
680
|
+
oldKey: z.ZodOptional<z.ZodString>;
|
|
681
|
+
oldKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
682
|
+
targetKey: z.ZodString;
|
|
683
|
+
fileData: z.ZodOptional<z.ZodObject<{
|
|
684
|
+
name: z.ZodString;
|
|
685
|
+
path: z.ZodString;
|
|
686
|
+
}, "strip", z.ZodTypeAny, {
|
|
687
|
+
path: string;
|
|
688
|
+
name: string;
|
|
689
|
+
}, {
|
|
690
|
+
path: string;
|
|
691
|
+
name: string;
|
|
692
|
+
}>>;
|
|
693
|
+
converters: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
694
|
+
validationActions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
695
|
+
action: z.ZodString;
|
|
696
|
+
params: z.ZodArray<z.ZodString, "many">;
|
|
697
|
+
}, "strip", z.ZodTypeAny, {
|
|
698
|
+
params: string[];
|
|
699
|
+
action: string;
|
|
700
|
+
}, {
|
|
701
|
+
params: string[];
|
|
702
|
+
action: string;
|
|
703
|
+
}>, "many">>;
|
|
704
|
+
postImportActions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
705
|
+
action: z.ZodString;
|
|
706
|
+
params: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodAny>]>, "many">;
|
|
707
|
+
}, "strip", z.ZodTypeAny, {
|
|
708
|
+
params: (string | Record<string, any>)[];
|
|
709
|
+
action: string;
|
|
710
|
+
}, {
|
|
711
|
+
params: (string | Record<string, any>)[];
|
|
712
|
+
action: string;
|
|
713
|
+
}>, "many">>;
|
|
714
|
+
}, "strip", z.ZodTypeAny, {
|
|
715
|
+
targetKey: string;
|
|
716
|
+
converters: string[];
|
|
717
|
+
validationActions: {
|
|
718
|
+
params: string[];
|
|
719
|
+
action: string;
|
|
720
|
+
}[];
|
|
721
|
+
postImportActions: {
|
|
722
|
+
params: (string | Record<string, any>)[];
|
|
723
|
+
action: string;
|
|
724
|
+
}[];
|
|
725
|
+
oldKey?: string | undefined;
|
|
726
|
+
oldKeys?: string[] | undefined;
|
|
727
|
+
fileData?: {
|
|
728
|
+
path: string;
|
|
729
|
+
name: string;
|
|
730
|
+
} | undefined;
|
|
731
|
+
}, {
|
|
732
|
+
targetKey: string;
|
|
733
|
+
oldKey?: string | undefined;
|
|
734
|
+
oldKeys?: string[] | undefined;
|
|
735
|
+
fileData?: {
|
|
736
|
+
path: string;
|
|
737
|
+
name: string;
|
|
738
|
+
} | undefined;
|
|
739
|
+
converters?: string[] | undefined;
|
|
740
|
+
validationActions?: {
|
|
741
|
+
params: string[];
|
|
742
|
+
action: string;
|
|
743
|
+
}[] | undefined;
|
|
744
|
+
postImportActions?: {
|
|
745
|
+
params: (string | Record<string, any>)[];
|
|
746
|
+
action: string;
|
|
747
|
+
}[] | undefined;
|
|
748
|
+
}>, "many">;
|
|
679
749
|
export declare const collectionSchema: z.ZodObject<{
|
|
680
750
|
$id: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
681
751
|
$createdAt: z.ZodString;
|
|
@@ -1206,6 +1276,7 @@ export declare const collectionSchema: z.ZodObject<{
|
|
|
1206
1276
|
targetField?: string | undefined;
|
|
1207
1277
|
} | undefined;
|
|
1208
1278
|
})[];
|
|
1279
|
+
name: string;
|
|
1209
1280
|
$id: string;
|
|
1210
1281
|
$createdAt: string;
|
|
1211
1282
|
$updatedAt: string;
|
|
@@ -1213,7 +1284,6 @@ export declare const collectionSchema: z.ZodObject<{
|
|
|
1213
1284
|
permission: string;
|
|
1214
1285
|
target: string;
|
|
1215
1286
|
}[];
|
|
1216
|
-
name: string;
|
|
1217
1287
|
enabled: boolean;
|
|
1218
1288
|
documentSecurity: boolean;
|
|
1219
1289
|
indexes: {
|
|
@@ -1253,9 +1323,9 @@ export declare const collectionSchema: z.ZodObject<{
|
|
|
1253
1323
|
}[];
|
|
1254
1324
|
databaseId?: string | undefined;
|
|
1255
1325
|
}, {
|
|
1326
|
+
name: string;
|
|
1256
1327
|
$createdAt: string;
|
|
1257
1328
|
$updatedAt: string;
|
|
1258
|
-
name: string;
|
|
1259
1329
|
$id?: string | undefined;
|
|
1260
1330
|
$permissions?: {
|
|
1261
1331
|
permission: string;
|
|
@@ -1917,12 +1987,12 @@ export declare const CollectionCreateSchema: z.ZodObject<Omit<{
|
|
|
1917
1987
|
targetField?: string | undefined;
|
|
1918
1988
|
} | undefined;
|
|
1919
1989
|
})[];
|
|
1990
|
+
name: string;
|
|
1920
1991
|
$id: string;
|
|
1921
1992
|
$permissions: {
|
|
1922
1993
|
permission: string;
|
|
1923
1994
|
target: string;
|
|
1924
1995
|
}[];
|
|
1925
|
-
name: string;
|
|
1926
1996
|
enabled: boolean;
|
|
1927
1997
|
documentSecurity: boolean;
|
|
1928
1998
|
indexes: {
|
|
@@ -2114,11 +2184,11 @@ export declare const AppwriteConfigSchema: z.ZodObject<{
|
|
|
2114
2184
|
$id: z.ZodString;
|
|
2115
2185
|
name: z.ZodString;
|
|
2116
2186
|
}, "strip", z.ZodTypeAny, {
|
|
2117
|
-
$id: string;
|
|
2118
2187
|
name: string;
|
|
2119
|
-
}, {
|
|
2120
2188
|
$id: string;
|
|
2189
|
+
}, {
|
|
2121
2190
|
name: string;
|
|
2191
|
+
$id: string;
|
|
2122
2192
|
}>, "many">>;
|
|
2123
2193
|
collections: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<Omit<{
|
|
2124
2194
|
$id: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -2650,12 +2720,12 @@ export declare const AppwriteConfigSchema: z.ZodObject<{
|
|
|
2650
2720
|
targetField?: string | undefined;
|
|
2651
2721
|
} | undefined;
|
|
2652
2722
|
})[];
|
|
2723
|
+
name: string;
|
|
2653
2724
|
$id: string;
|
|
2654
2725
|
$permissions: {
|
|
2655
2726
|
permission: string;
|
|
2656
2727
|
target: string;
|
|
2657
2728
|
}[];
|
|
2658
|
-
name: string;
|
|
2659
2729
|
enabled: boolean;
|
|
2660
2730
|
documentSecurity: boolean;
|
|
2661
2731
|
indexes: {
|
|
@@ -2841,8 +2911,8 @@ export declare const AppwriteConfigSchema: z.ZodObject<{
|
|
|
2841
2911
|
documentBucketId: string;
|
|
2842
2912
|
usersCollectionName: string;
|
|
2843
2913
|
databases: {
|
|
2844
|
-
$id: string;
|
|
2845
2914
|
name: string;
|
|
2915
|
+
$id: string;
|
|
2846
2916
|
}[];
|
|
2847
2917
|
collections: {
|
|
2848
2918
|
attributes: ({
|
|
@@ -2932,12 +3002,12 @@ export declare const AppwriteConfigSchema: z.ZodObject<{
|
|
|
2932
3002
|
targetField?: string | undefined;
|
|
2933
3003
|
} | undefined;
|
|
2934
3004
|
})[];
|
|
3005
|
+
name: string;
|
|
2935
3006
|
$id: string;
|
|
2936
3007
|
$permissions: {
|
|
2937
3008
|
permission: string;
|
|
2938
3009
|
target: string;
|
|
2939
3010
|
}[];
|
|
2940
|
-
name: string;
|
|
2941
3011
|
enabled: boolean;
|
|
2942
3012
|
documentSecurity: boolean;
|
|
2943
3013
|
indexes: {
|
|
@@ -2993,8 +3063,8 @@ export declare const AppwriteConfigSchema: z.ZodObject<{
|
|
|
2993
3063
|
documentBucketId?: string | undefined;
|
|
2994
3064
|
usersCollectionName?: string | undefined;
|
|
2995
3065
|
databases?: {
|
|
2996
|
-
$id: string;
|
|
2997
3066
|
name: string;
|
|
3067
|
+
$id: string;
|
|
2998
3068
|
}[] | undefined;
|
|
2999
3069
|
collections?: {
|
|
3000
3070
|
name: string;
|
|
@@ -3137,6 +3207,6 @@ export type ConfigDatabases = AppwriteConfig["databases"];
|
|
|
3137
3207
|
export type ConfigDatabase = ConfigDatabases[number];
|
|
3138
3208
|
export type ImportDefs = ConfigCollections[number]["importDefs"];
|
|
3139
3209
|
export type ImportDef = ImportDefs[number];
|
|
3140
|
-
export type AttributeMappings =
|
|
3210
|
+
export type AttributeMappings = z.infer<typeof AttributeMappingsSchema>;
|
|
3141
3211
|
export type AttributeMapping = AttributeMappings[number];
|
|
3142
3212
|
export {};
|
|
@@ -324,6 +324,48 @@ export const indexSchema = z.object({
|
|
|
324
324
|
attributes: z.array(z.string()),
|
|
325
325
|
orders: z.array(z.string()).optional(),
|
|
326
326
|
});
|
|
327
|
+
export const AttributeMappingsSchema = z.array(z.object({
|
|
328
|
+
oldKey: z
|
|
329
|
+
.string()
|
|
330
|
+
.optional()
|
|
331
|
+
.describe("The key of the attribute in the old document"),
|
|
332
|
+
oldKeys: z
|
|
333
|
+
.array(z.string())
|
|
334
|
+
.optional()
|
|
335
|
+
.describe("The keys of the attribute in the old document, if there are more than one"),
|
|
336
|
+
targetKey: z
|
|
337
|
+
.string()
|
|
338
|
+
.describe("The key of the attribute in the new document"),
|
|
339
|
+
fileData: z
|
|
340
|
+
.object({
|
|
341
|
+
name: z
|
|
342
|
+
.string()
|
|
343
|
+
.describe("The name of the file, can use template strings"),
|
|
344
|
+
path: z
|
|
345
|
+
.string()
|
|
346
|
+
.describe("The path of the file, relative to the appwrite folder"),
|
|
347
|
+
})
|
|
348
|
+
.optional()
|
|
349
|
+
.describe("The file data to use for the import, if defined it will upload and replace with ID"),
|
|
350
|
+
converters: z
|
|
351
|
+
.array(z.string())
|
|
352
|
+
.describe("The converters to use for the import")
|
|
353
|
+
.default([]),
|
|
354
|
+
validationActions: z
|
|
355
|
+
.array(z.object({
|
|
356
|
+
action: z.string(),
|
|
357
|
+
params: z.array(z.string().startsWith("{").endsWith("}")),
|
|
358
|
+
}))
|
|
359
|
+
.describe("The after import actions and parameter placeholders (they'll be replaced with the actual data) to use for the import")
|
|
360
|
+
.default([]),
|
|
361
|
+
postImportActions: z
|
|
362
|
+
.array(z.object({
|
|
363
|
+
action: z.string(),
|
|
364
|
+
params: z.array(z.string().or(z.record(z.string(), z.any()))),
|
|
365
|
+
}))
|
|
366
|
+
.describe("The after import actions and parameter placeholders (they'll be replaced with the actual data) to use for the import")
|
|
367
|
+
.default([]),
|
|
368
|
+
}));
|
|
327
369
|
export const collectionSchema = z.object({
|
|
328
370
|
$id: z
|
|
329
371
|
.string()
|
|
@@ -383,48 +425,7 @@ export const collectionSchema = z.object({
|
|
|
383
425
|
})
|
|
384
426
|
.optional()
|
|
385
427
|
.describe("Configuration for mapping and resolving the update during data import"),
|
|
386
|
-
attributeMappings:
|
|
387
|
-
oldKey: z
|
|
388
|
-
.string()
|
|
389
|
-
.optional()
|
|
390
|
-
.describe("The key of the attribute in the old document"),
|
|
391
|
-
oldKeys: z
|
|
392
|
-
.array(z.string())
|
|
393
|
-
.optional()
|
|
394
|
-
.describe("The keys of the attribute in the old document, if there are more than one"),
|
|
395
|
-
targetKey: z
|
|
396
|
-
.string()
|
|
397
|
-
.describe("The key of the attribute in the new document"),
|
|
398
|
-
fileData: z
|
|
399
|
-
.object({
|
|
400
|
-
name: z
|
|
401
|
-
.string()
|
|
402
|
-
.describe("The name of the file, can use template strings"),
|
|
403
|
-
path: z
|
|
404
|
-
.string()
|
|
405
|
-
.describe("The path of the file, relative to the appwrite folder"),
|
|
406
|
-
})
|
|
407
|
-
.optional()
|
|
408
|
-
.describe("The file data to use for the import, if defined it will upload and replace with ID"),
|
|
409
|
-
converters: z
|
|
410
|
-
.array(z.string())
|
|
411
|
-
.describe("The converters to use for the import")
|
|
412
|
-
.default([]),
|
|
413
|
-
validationActions: z
|
|
414
|
-
.array(z.object({
|
|
415
|
-
action: z.string(),
|
|
416
|
-
params: z.array(z.string().startsWith("{").endsWith("}")),
|
|
417
|
-
}))
|
|
418
|
-
.describe("The after import actions and parameter placeholders (they'll be replaced with the actual data) to use for the import")
|
|
419
|
-
.default([]),
|
|
420
|
-
postImportActions: z
|
|
421
|
-
.array(z.object({
|
|
422
|
-
action: z.string(),
|
|
423
|
-
params: z.array(z.string().or(z.record(z.string(), z.any()))),
|
|
424
|
-
}))
|
|
425
|
-
.describe("The after import actions and parameter placeholders (they'll be replaced with the actual data) to use for the import")
|
|
426
|
-
.default([]),
|
|
427
|
-
})),
|
|
428
|
+
attributeMappings: AttributeMappingsSchema.describe("The attribute mappings to use for the import"),
|
|
428
429
|
}))
|
|
429
430
|
.optional()
|
|
430
431
|
.default([])
|
|
@@ -99,9 +99,12 @@ export class SchemaGenerator {
|
|
|
99
99
|
let endNameLazy = `${relatedPascalName}Schema`;
|
|
100
100
|
if (relatedCollection[2] === "array") {
|
|
101
101
|
endNameTypes += "[]";
|
|
102
|
-
endNameLazy += ".array()";
|
|
102
|
+
endNameLazy += ".array().default([])";
|
|
103
|
+
}
|
|
104
|
+
else if (!(relatedCollection[2] === "array")) {
|
|
105
|
+
endNameTypes += " | null";
|
|
106
|
+
endNameLazy += ".nullish()";
|
|
103
107
|
}
|
|
104
|
-
endNameLazy += ".nullish()";
|
|
105
108
|
imports += `import { ${relatedPascalName}Schema, type ${relatedPascalName} } from "./${relatedCamelName}";\n`;
|
|
106
109
|
relatedTypes += `${relatedCollection[1]}?: ${endNameTypes};\n`;
|
|
107
110
|
if (relatedTypes.length > 0 && curNum !== maxNum) {
|
|
@@ -30,9 +30,9 @@ export declare const AuthUserSchema: z.ZodObject<{
|
|
|
30
30
|
export type AuthUser = z.infer<typeof AuthUserSchema>;
|
|
31
31
|
export declare const AuthUserCreateSchema: z.ZodObject<{
|
|
32
32
|
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
33
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
33
34
|
$createdAt: z.ZodOptional<z.ZodString>;
|
|
34
35
|
$updatedAt: z.ZodOptional<z.ZodString>;
|
|
35
|
-
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
36
36
|
phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
37
37
|
prefs: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
38
38
|
labels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
@@ -42,17 +42,17 @@ export declare const AuthUserCreateSchema: z.ZodObject<{
|
|
|
42
42
|
prefs: Record<string, string>;
|
|
43
43
|
labels: string[];
|
|
44
44
|
email?: string | null | undefined;
|
|
45
|
+
name?: string | null | undefined;
|
|
45
46
|
$createdAt?: string | undefined;
|
|
46
47
|
$updatedAt?: string | undefined;
|
|
47
|
-
name?: string | null | undefined;
|
|
48
48
|
phone?: string | null | undefined;
|
|
49
49
|
userId?: string | undefined;
|
|
50
50
|
password?: string | undefined;
|
|
51
51
|
}, {
|
|
52
52
|
email?: string | null | undefined;
|
|
53
|
+
name?: string | null | undefined;
|
|
53
54
|
$createdAt?: string | undefined;
|
|
54
55
|
$updatedAt?: string | undefined;
|
|
55
|
-
name?: string | null | undefined;
|
|
56
56
|
phone?: string | null | undefined;
|
|
57
57
|
prefs?: Record<string, string> | undefined;
|
|
58
58
|
labels?: string[] | undefined;
|
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": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"main": "src/main.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|