appwrite-utils-cli 1.3.4 → 1.4.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.
- package/dist/adapters/AdapterFactory.d.ts +87 -0
- package/dist/adapters/AdapterFactory.js +217 -0
- package/dist/adapters/DatabaseAdapter.d.ts +217 -0
- package/dist/adapters/DatabaseAdapter.js +50 -0
- package/dist/adapters/LegacyAdapter.d.ts +49 -0
- package/dist/adapters/LegacyAdapter.js +382 -0
- package/dist/adapters/TablesDBAdapter.d.ts +55 -0
- package/dist/adapters/TablesDBAdapter.js +302 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.js +12 -0
- package/dist/collections/attributes.js +43 -24
- package/dist/collections/methods.d.ts +4 -3
- package/dist/collections/methods.js +34 -14
- package/dist/config/yamlConfig.d.ts +40 -437
- package/dist/config/yamlConfig.js +8 -2
- package/dist/databases/setup.js +2 -2
- package/dist/main.js +0 -0
- package/dist/migrations/appwriteToX.d.ts +26 -37
- package/dist/migrations/comprehensiveTransfer.js +4 -4
- package/dist/migrations/dataLoader.d.ts +124 -1484
- package/dist/migrations/dataLoader.js +2 -1
- package/dist/migrations/relationships.d.ts +2 -3
- package/dist/migrations/relationships.js +1 -1
- package/dist/migrations/services/UserMappingService.js +1 -1
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +24 -279
- package/dist/migrations/yaml/YamlImportConfigLoader.js +7 -2
- package/dist/schemas/authUser.d.ts +7 -47
- package/dist/schemas/authUser.js +1 -1
- package/dist/shared/jsonSchemaGenerator.d.ts +0 -2
- package/dist/shared/jsonSchemaGenerator.js +4 -17
- package/dist/shared/migrationHelpers.d.ts +17 -119
- package/dist/shared/operationQueue.js +16 -7
- package/dist/shared/schemaGenerator.js +2 -17
- package/dist/storage/schemas.d.ts +149 -296
- package/dist/users/methods.d.ts +2 -2
- package/dist/utils/configMigration.js +0 -1
- package/dist/utils/getClientFromConfig.d.ts +26 -0
- package/dist/utils/getClientFromConfig.js +37 -0
- package/dist/utils/loadConfigs.js +0 -2
- package/dist/utils/schemaStrings.js +2 -17
- package/dist/utils/setupFiles.js +2 -0
- package/dist/utils/versionDetection.d.ts +56 -0
- package/dist/utils/versionDetection.js +217 -0
- package/dist/utils/yamlConverter.d.ts +0 -1
- package/dist/utils/yamlConverter.js +0 -2
- package/dist/utilsController.js +2 -0
- package/package.json +3 -2
- package/src/adapters/AdapterFactory.ts +296 -0
- package/src/adapters/DatabaseAdapter.ts +290 -0
- package/src/adapters/LegacyAdapter.ts +667 -0
- package/src/adapters/TablesDBAdapter.ts +429 -0
- package/src/adapters/index.ts +37 -0
- package/src/collections/attributes.ts +351 -157
- package/src/collections/methods.ts +43 -28
- package/src/config/yamlConfig.ts +8 -2
- package/src/databases/setup.ts +2 -2
- package/src/migrations/afterImportActions.ts +2 -2
- package/src/migrations/comprehensiveTransfer.ts +4 -0
- package/src/migrations/dataLoader.ts +2 -1
- package/src/migrations/relationships.ts +1 -1
- package/src/migrations/services/UserMappingService.ts +1 -1
- package/src/migrations/yaml/YamlImportConfigLoader.ts +7 -2
- package/src/schemas/authUser.ts +1 -1
- package/src/shared/jsonSchemaGenerator.ts +4 -19
- package/src/shared/operationQueue.ts +20 -13
- package/src/shared/schemaGenerator.ts +2 -16
- package/src/types/node-appwrite-tablesdb.d.ts +44 -0
- package/src/users/methods.ts +2 -2
- package/src/utils/configMigration.ts +0 -1
- package/src/utils/getClientFromConfig.ts +56 -0
- package/src/utils/loadConfigs.ts +0 -2
- package/src/utils/schemaStrings.ts +2 -16
- package/src/utils/setupFiles.ts +2 -0
- package/src/utils/versionDetection.ts +265 -0
- package/src/utils/yamlConverter.ts +0 -2
- package/src/utilsController.ts +2 -0
- package/dist/functions/openapi.d.ts +0 -4
- package/dist/functions/openapi.js +0 -60
- package/dist/migrations/attributes.d.ts +0 -4
- package/dist/migrations/attributes.js +0 -301
- package/dist/migrations/backup.d.ts +0 -687
- package/dist/migrations/backup.js +0 -175
- package/dist/migrations/collections.d.ts +0 -22
- package/dist/migrations/collections.js +0 -347
- package/dist/migrations/converters.d.ts +0 -46
- package/dist/migrations/converters.js +0 -139
- package/dist/migrations/databases.d.ts +0 -2
- package/dist/migrations/databases.js +0 -28
- package/dist/migrations/dbHelpers.d.ts +0 -5
- package/dist/migrations/dbHelpers.js +0 -57
- package/dist/migrations/helper.d.ts +0 -3
- package/dist/migrations/helper.js +0 -21
- package/dist/migrations/indexes.d.ts +0 -4
- package/dist/migrations/indexes.js +0 -19
- package/dist/migrations/logging.d.ts +0 -10
- package/dist/migrations/logging.js +0 -46
- package/dist/migrations/migrationHelper.d.ts +0 -173
- package/dist/migrations/migrationHelper.js +0 -130
- package/dist/migrations/openapi.d.ts +0 -4
- package/dist/migrations/openapi.js +0 -60
- package/dist/migrations/queue.d.ts +0 -13
- package/dist/migrations/queue.js +0 -79
- package/dist/migrations/schemaStrings.d.ts +0 -14
- package/dist/migrations/schemaStrings.js +0 -478
- package/dist/migrations/setupDatabase.d.ts +0 -6
- package/dist/migrations/setupDatabase.js +0 -115
- package/dist/migrations/storage.d.ts +0 -10
- package/dist/migrations/storage.js +0 -340
- package/dist/migrations/users.d.ts +0 -16
- package/dist/migrations/users.js +0 -276
- package/dist/migrations/validationRules.d.ts +0 -43
- package/dist/migrations/validationRules.js +0 -42
- package/dist/shared/attributeManager.d.ts +0 -17
- package/dist/shared/attributeManager.js +0 -272
- package/src/functions/openapi.ts +0 -83
- package/src/shared/attributeManager.ts +0 -428
@@ -1,175 +0,0 @@
|
|
1
|
-
import { z } from "zod";
|
2
|
-
import { attributeSchema, parseAttribute, CollectionCreateSchema, } from "appwrite-utils";
|
3
|
-
export const BackupSchema = z.object({
|
4
|
-
$id: z.string(),
|
5
|
-
$createdAt: z.string(),
|
6
|
-
$updatedAt: z.string(),
|
7
|
-
database: z.string(),
|
8
|
-
collections: z.array(z.string()),
|
9
|
-
documents: z
|
10
|
-
.array(z.object({
|
11
|
-
collectionId: z.string(),
|
12
|
-
data: z.string(),
|
13
|
-
}))
|
14
|
-
.default([]),
|
15
|
-
});
|
16
|
-
export const BackupCreateSchema = BackupSchema.omit({
|
17
|
-
$id: true,
|
18
|
-
$createdAt: true,
|
19
|
-
$updatedAt: true,
|
20
|
-
});
|
21
|
-
export const BatchSchema = z.object({
|
22
|
-
$id: z.string(),
|
23
|
-
$createdAt: z.string(),
|
24
|
-
$updatedAt: z.string(),
|
25
|
-
data: z.string().describe("The serialized data for this batch"),
|
26
|
-
processed: z
|
27
|
-
.boolean()
|
28
|
-
.default(false)
|
29
|
-
.describe("Whether the batch has been processed"),
|
30
|
-
});
|
31
|
-
export const BatchCreateSchema = BatchSchema.omit({
|
32
|
-
$id: true,
|
33
|
-
$createdAt: true,
|
34
|
-
$updatedAt: true,
|
35
|
-
});
|
36
|
-
export const OperationSchema = z.object({
|
37
|
-
$id: z.string(),
|
38
|
-
$createdAt: z.string(),
|
39
|
-
$updatedAt: z.string(),
|
40
|
-
operationType: z.string(),
|
41
|
-
collectionId: z.string(),
|
42
|
-
data: z.any(),
|
43
|
-
batches: z.array(z.string()).default([]).optional(),
|
44
|
-
progress: z.number(),
|
45
|
-
total: z.number(),
|
46
|
-
error: z.string(),
|
47
|
-
status: z
|
48
|
-
.enum([
|
49
|
-
"pending",
|
50
|
-
"ready",
|
51
|
-
"in_progress",
|
52
|
-
"completed",
|
53
|
-
"error",
|
54
|
-
"cancelled",
|
55
|
-
])
|
56
|
-
.default("pending"),
|
57
|
-
});
|
58
|
-
export const OperationCreateSchema = OperationSchema.omit({
|
59
|
-
$id: true,
|
60
|
-
$createdAt: true,
|
61
|
-
$updatedAt: true,
|
62
|
-
});
|
63
|
-
export const getMigrationCollectionSchemas = () => {
|
64
|
-
const currentOperationsAttributes = [
|
65
|
-
parseAttribute({
|
66
|
-
key: "operationType",
|
67
|
-
type: "string",
|
68
|
-
error: "Invalid Operation Type",
|
69
|
-
size: 50,
|
70
|
-
required: true,
|
71
|
-
array: false,
|
72
|
-
xdefault: null,
|
73
|
-
}),
|
74
|
-
attributeSchema.parse({
|
75
|
-
key: "collectionId",
|
76
|
-
type: "string",
|
77
|
-
error: "Invalid Collection Id",
|
78
|
-
size: 50,
|
79
|
-
array: false,
|
80
|
-
xdefault: null,
|
81
|
-
}),
|
82
|
-
attributeSchema.parse({
|
83
|
-
key: "batches",
|
84
|
-
type: "string",
|
85
|
-
error: "Invalid Batches",
|
86
|
-
size: 1073741824,
|
87
|
-
array: true,
|
88
|
-
}),
|
89
|
-
attributeSchema.parse({
|
90
|
-
key: "data",
|
91
|
-
type: "string",
|
92
|
-
error: "Invalid Data",
|
93
|
-
size: 1073741824,
|
94
|
-
}),
|
95
|
-
attributeSchema.parse({
|
96
|
-
key: "progress",
|
97
|
-
type: "integer",
|
98
|
-
error: "Invalid Progress",
|
99
|
-
required: true,
|
100
|
-
array: false,
|
101
|
-
}),
|
102
|
-
attributeSchema.parse({
|
103
|
-
key: "total",
|
104
|
-
type: "integer",
|
105
|
-
error: "Invalid Total",
|
106
|
-
required: true,
|
107
|
-
array: false,
|
108
|
-
}),
|
109
|
-
attributeSchema.parse({
|
110
|
-
key: "error",
|
111
|
-
type: "string",
|
112
|
-
error: "Operation Error",
|
113
|
-
required: false,
|
114
|
-
array: false,
|
115
|
-
}),
|
116
|
-
attributeSchema.parse({
|
117
|
-
key: "status",
|
118
|
-
type: "enum",
|
119
|
-
elements: [
|
120
|
-
"pending",
|
121
|
-
"ready",
|
122
|
-
"in_progress",
|
123
|
-
"completed",
|
124
|
-
"error",
|
125
|
-
"cancelled",
|
126
|
-
],
|
127
|
-
error: "Invalid Status",
|
128
|
-
array: false,
|
129
|
-
xdefault: "pending",
|
130
|
-
}),
|
131
|
-
];
|
132
|
-
const currentOperationsConfig = CollectionCreateSchema.parse({
|
133
|
-
name: "CurrentOperations",
|
134
|
-
enabled: true,
|
135
|
-
documentSecurity: false,
|
136
|
-
attributes: [],
|
137
|
-
indexes: [],
|
138
|
-
});
|
139
|
-
const batchesAttributes = [
|
140
|
-
attributeSchema.parse({
|
141
|
-
key: "data",
|
142
|
-
type: "string",
|
143
|
-
size: 1073741824,
|
144
|
-
error: "Invalid Data",
|
145
|
-
required: true,
|
146
|
-
array: false,
|
147
|
-
}),
|
148
|
-
attributeSchema.parse({
|
149
|
-
key: "processed",
|
150
|
-
type: "boolean",
|
151
|
-
error: "Invalid Processed",
|
152
|
-
required: true,
|
153
|
-
array: false,
|
154
|
-
xdefault: false,
|
155
|
-
}),
|
156
|
-
];
|
157
|
-
const batchesConfig = CollectionCreateSchema.parse({
|
158
|
-
name: "Batches",
|
159
|
-
enabled: true,
|
160
|
-
documentSecurity: false,
|
161
|
-
attributes: [],
|
162
|
-
indexes: [],
|
163
|
-
});
|
164
|
-
const toReturn = {
|
165
|
-
CurrentOperations: {
|
166
|
-
collection: currentOperationsConfig,
|
167
|
-
attributes: currentOperationsAttributes,
|
168
|
-
},
|
169
|
-
Batches: {
|
170
|
-
collection: batchesConfig,
|
171
|
-
attributes: batchesAttributes,
|
172
|
-
},
|
173
|
-
};
|
174
|
-
return toReturn;
|
175
|
-
};
|
@@ -1,22 +0,0 @@
|
|
1
|
-
import { Databases, type Models } from "node-appwrite";
|
2
|
-
import type { AppwriteConfig, CollectionCreate } from "appwrite-utils";
|
3
|
-
export declare const documentExists: (db: Databases, dbId: string, targetCollectionId: string, toCreateObject: any) => Promise<Models.Document | null>;
|
4
|
-
export declare const checkForCollection: (db: Databases, dbId: string, collection: Partial<CollectionCreate>) => Promise<Models.Collection | null>;
|
5
|
-
export declare const fetchAndCacheCollectionByName: (db: Databases, dbId: string, collectionName: string) => Promise<Models.Collection | undefined>;
|
6
|
-
export declare const wipeDatabase: (database: Databases, databaseId: string) => Promise<{
|
7
|
-
collectionId: string;
|
8
|
-
collectionName: string;
|
9
|
-
}[]>;
|
10
|
-
export declare const generateSchemas: (config: AppwriteConfig, appwriteFolderPath: string) => Promise<void>;
|
11
|
-
export declare const createOrUpdateCollections: (database: Databases, databaseId: string, config: AppwriteConfig, deletedCollections?: {
|
12
|
-
collectionId: string;
|
13
|
-
collectionName: string;
|
14
|
-
}[]) => Promise<void>;
|
15
|
-
export declare const generateMockData: (database: Databases, databaseId: string, configCollections: any[]) => Promise<void>;
|
16
|
-
export declare const fetchAllCollections: (dbId: string, database: Databases) => Promise<Models.Collection[]>;
|
17
|
-
/**
|
18
|
-
* Transfers all documents from one collection to another in a different database
|
19
|
-
* within the same Appwrite Project
|
20
|
-
*/
|
21
|
-
export declare const transferDocumentsBetweenDbsLocalToLocal: (db: Databases, fromDbId: string, toDbId: string, fromCollId: string, toCollId: string) => Promise<void>;
|
22
|
-
export declare const transferDocumentsBetweenDbsLocalToRemote: (localDb: Databases, endpoint: string, projectId: string, apiKey: string, fromDbId: string, toDbId: string, fromCollId: string, toCollId: string) => Promise<void>;
|
@@ -1,347 +0,0 @@
|
|
1
|
-
import { Client, Databases, ID, Permission, Query, } from "node-appwrite";
|
2
|
-
import { nameToIdMapping, processQueue } from "./queue.js";
|
3
|
-
import { createUpdateCollectionAttributes } from "./attributes.js";
|
4
|
-
import { createOrUpdateIndexes } from "./indexes.js";
|
5
|
-
import _ from "lodash";
|
6
|
-
import { SchemaGenerator } from "./schemaStrings.js";
|
7
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
8
|
-
export const documentExists = async (db, dbId, targetCollectionId, toCreateObject) => {
|
9
|
-
// Had to do this because kept running into issues with type checking arrays so, sorry 40ms
|
10
|
-
const collection = await db.getCollection(dbId, targetCollectionId);
|
11
|
-
const attributes = collection.attributes;
|
12
|
-
let arrayTypeAttributes = attributes
|
13
|
-
.filter((attribute) => attribute.array === true)
|
14
|
-
.map((attribute) => attribute.key);
|
15
|
-
// Function to check if a string is JSON
|
16
|
-
const isJsonString = (str) => {
|
17
|
-
try {
|
18
|
-
const json = JSON.parse(str);
|
19
|
-
return typeof json === "object" && json !== null; // Check if parsed JSON is an object or array
|
20
|
-
}
|
21
|
-
catch (e) {
|
22
|
-
return false;
|
23
|
-
}
|
24
|
-
};
|
25
|
-
// Validate and prepare query parameters
|
26
|
-
const validQueryParams = _.chain(toCreateObject)
|
27
|
-
.pickBy((value, key) => !arrayTypeAttributes.includes(key) &&
|
28
|
-
!key.startsWith("$") &&
|
29
|
-
!_.isNull(value) &&
|
30
|
-
!_.isUndefined(value) &&
|
31
|
-
!_.isEmpty(value) &&
|
32
|
-
!_.isObject(value) && // Keeps excluding objects
|
33
|
-
!_.isArray(value) && // Explicitly exclude arrays
|
34
|
-
!(_.isString(value) && isJsonString(value)) && // Exclude JSON strings
|
35
|
-
(_.isString(value) ? value.length < 4096 && value.length > 0 : true) // String length check
|
36
|
-
)
|
37
|
-
.mapValues((value, key) => _.isString(value) || _.isNumber(value) || _.isBoolean(value)
|
38
|
-
? value
|
39
|
-
: null)
|
40
|
-
.omitBy(_.isNull) // Remove any null values that might have been added in mapValues
|
41
|
-
.toPairs()
|
42
|
-
.slice(0, 25) // Limit to 25 to adhere to query limit
|
43
|
-
.map(([key, value]) => Query.equal(key, value))
|
44
|
-
.value();
|
45
|
-
// Execute the query with the validated and prepared parameters
|
46
|
-
const result = await db.listDocuments(dbId, targetCollectionId, validQueryParams);
|
47
|
-
return result.documents[0] || null;
|
48
|
-
};
|
49
|
-
export const checkForCollection = async (db, dbId, collection) => {
|
50
|
-
try {
|
51
|
-
console.log(`Checking for collection with name: ${collection.name}`);
|
52
|
-
const response = await tryAwaitWithRetry(async () => await db.listCollections(dbId, [Query.equal("name", collection.name)]));
|
53
|
-
if (response.collections.length > 0) {
|
54
|
-
console.log(`Collection found: ${response.collections[0].$id}`);
|
55
|
-
return { ...collection, ...response.collections[0] };
|
56
|
-
}
|
57
|
-
else {
|
58
|
-
console.log(`No collection found with name: ${collection.name}`);
|
59
|
-
return null;
|
60
|
-
}
|
61
|
-
}
|
62
|
-
catch (error) {
|
63
|
-
console.error(`Error checking for collection: ${error}`);
|
64
|
-
return null;
|
65
|
-
}
|
66
|
-
};
|
67
|
-
// Helper function to fetch and cache collection by name
|
68
|
-
export const fetchAndCacheCollectionByName = async (db, dbId, collectionName) => {
|
69
|
-
if (nameToIdMapping.has(collectionName)) {
|
70
|
-
const collectionId = nameToIdMapping.get(collectionName);
|
71
|
-
console.log(`\tCollection found in cache: ${collectionId}`);
|
72
|
-
return await tryAwaitWithRetry(async () => await db.getCollection(dbId, collectionId));
|
73
|
-
}
|
74
|
-
else {
|
75
|
-
console.log(`\tFetching collection by name: ${collectionName}`);
|
76
|
-
const collectionsPulled = await tryAwaitWithRetry(async () => await db.listCollections(dbId, [Query.equal("name", collectionName)]));
|
77
|
-
if (collectionsPulled.total > 0) {
|
78
|
-
const collection = collectionsPulled.collections[0];
|
79
|
-
console.log(`\tCollection found: ${collection.$id}`);
|
80
|
-
nameToIdMapping.set(collectionName, collection.$id);
|
81
|
-
return collection;
|
82
|
-
}
|
83
|
-
else {
|
84
|
-
console.log(`\tCollection not found by name: ${collectionName}`);
|
85
|
-
return undefined;
|
86
|
-
}
|
87
|
-
}
|
88
|
-
};
|
89
|
-
export const wipeDatabase = async (database, databaseId) => {
|
90
|
-
console.log(`Wiping database: ${databaseId}`);
|
91
|
-
const existingCollections = await fetchAllCollections(databaseId, database);
|
92
|
-
let collectionsDeleted = [];
|
93
|
-
for (const { $id: collectionId, name: name } of existingCollections) {
|
94
|
-
console.log(`Deleting collection: ${collectionId}`);
|
95
|
-
collectionsDeleted.push({
|
96
|
-
collectionId: collectionId,
|
97
|
-
collectionName: name,
|
98
|
-
});
|
99
|
-
tryAwaitWithRetry(async () => await database.deleteCollection(databaseId, collectionId)); // Try to delete the collection and ignore errors if it doesn't exist or if it's already being deleted
|
100
|
-
}
|
101
|
-
return collectionsDeleted;
|
102
|
-
};
|
103
|
-
export const generateSchemas = async (config, appwriteFolderPath) => {
|
104
|
-
const schemaGenerator = new SchemaGenerator(config, appwriteFolderPath);
|
105
|
-
schemaGenerator.generateSchemas();
|
106
|
-
};
|
107
|
-
export const createOrUpdateCollections = async (database, databaseId, config, deletedCollections) => {
|
108
|
-
const configCollections = config.collections;
|
109
|
-
if (!configCollections) {
|
110
|
-
return;
|
111
|
-
}
|
112
|
-
const usedIds = new Set(); // To track IDs used in this operation
|
113
|
-
for (const { attributes, indexes, ...collection } of configCollections) {
|
114
|
-
// Prepare permissions for the collection
|
115
|
-
const permissions = [];
|
116
|
-
if (collection.$permissions && collection.$permissions.length > 0) {
|
117
|
-
for (const permission of collection.$permissions) {
|
118
|
-
switch (permission.permission) {
|
119
|
-
case "read":
|
120
|
-
permissions.push(Permission.read(permission.target));
|
121
|
-
break;
|
122
|
-
case "create":
|
123
|
-
permissions.push(Permission.create(permission.target));
|
124
|
-
break;
|
125
|
-
case "update":
|
126
|
-
permissions.push(Permission.update(permission.target));
|
127
|
-
break;
|
128
|
-
case "delete":
|
129
|
-
permissions.push(Permission.delete(permission.target));
|
130
|
-
break;
|
131
|
-
case "write":
|
132
|
-
permissions.push(Permission.write(permission.target));
|
133
|
-
break;
|
134
|
-
default:
|
135
|
-
console.log(`Unknown permission: ${permission.permission}`);
|
136
|
-
break;
|
137
|
-
}
|
138
|
-
}
|
139
|
-
}
|
140
|
-
// Check if the collection already exists by name
|
141
|
-
let collectionsFound = await tryAwaitWithRetry(async () => await database.listCollections(databaseId, [
|
142
|
-
Query.equal("name", collection.name),
|
143
|
-
]));
|
144
|
-
let collectionToUse = collectionsFound.total > 0 ? collectionsFound.collections[0] : null;
|
145
|
-
// Determine the correct ID for the collection
|
146
|
-
let collectionId;
|
147
|
-
if (!collectionToUse) {
|
148
|
-
console.log(`Creating collection: ${collection.name}`);
|
149
|
-
let foundColl = deletedCollections?.find((coll) => coll.collectionName.toLowerCase().trim().replace(" ", "") ===
|
150
|
-
collection.name.toLowerCase().trim().replace(" ", ""));
|
151
|
-
if (collection.$id) {
|
152
|
-
collectionId = collection.$id; // Always use the provided $id if present
|
153
|
-
}
|
154
|
-
else if (foundColl && !usedIds.has(foundColl.collectionId)) {
|
155
|
-
collectionId = foundColl.collectionId; // Use ID from deleted collection if not already used
|
156
|
-
}
|
157
|
-
else {
|
158
|
-
collectionId = ID.unique(); // Generate a new unique ID
|
159
|
-
}
|
160
|
-
usedIds.add(collectionId); // Mark this ID as used
|
161
|
-
// Create the collection with the determined ID
|
162
|
-
try {
|
163
|
-
collectionToUse = await tryAwaitWithRetry(async () => await database.createCollection(databaseId, collectionId, collection.name, permissions, collection.documentSecurity ?? false, collection.enabled ?? true));
|
164
|
-
collection.$id = collectionToUse.$id;
|
165
|
-
nameToIdMapping.set(collection.name, collectionToUse.$id);
|
166
|
-
}
|
167
|
-
catch (error) {
|
168
|
-
console.error(`Failed to create collection ${collection.name} with ID ${collectionId}: ${error}`);
|
169
|
-
continue; // Skip to the next collection on failure
|
170
|
-
}
|
171
|
-
}
|
172
|
-
else {
|
173
|
-
console.log(`Collection ${collection.name} exists, updating it`);
|
174
|
-
await tryAwaitWithRetry(async () => await database.updateCollection(databaseId, collectionToUse.$id, collection.name, permissions, collection.documentSecurity ?? false, collection.enabled ?? true));
|
175
|
-
}
|
176
|
-
// Update attributes and indexes for the collection
|
177
|
-
console.log("Creating Attributes");
|
178
|
-
await createUpdateCollectionAttributes(database, databaseId, collectionToUse, attributes);
|
179
|
-
console.log("Creating Indexes");
|
180
|
-
await createOrUpdateIndexes(databaseId, database, collectionToUse.$id, indexes ?? []);
|
181
|
-
}
|
182
|
-
// Process any remaining tasks in the queue
|
183
|
-
await processQueue(database, databaseId);
|
184
|
-
};
|
185
|
-
export const generateMockData = async (database, databaseId, configCollections) => {
|
186
|
-
for (const { collection, mockFunction } of configCollections) {
|
187
|
-
if (mockFunction) {
|
188
|
-
console.log(`Generating mock data for collection: ${collection.name}`);
|
189
|
-
const mockData = mockFunction();
|
190
|
-
for (const data of mockData) {
|
191
|
-
await database.createDocument(databaseId, collection.$id, ID.unique(), data);
|
192
|
-
}
|
193
|
-
}
|
194
|
-
}
|
195
|
-
};
|
196
|
-
export const fetchAllCollections = async (dbId, database) => {
|
197
|
-
console.log(`Fetching all collections for database ID: ${dbId}`);
|
198
|
-
let collections = [];
|
199
|
-
let moreCollections = true;
|
200
|
-
let lastCollectionId;
|
201
|
-
while (moreCollections) {
|
202
|
-
const queries = [Query.limit(500)];
|
203
|
-
if (lastCollectionId) {
|
204
|
-
queries.push(Query.cursorAfter(lastCollectionId));
|
205
|
-
}
|
206
|
-
const response = await tryAwaitWithRetry(async () => await database.listCollections(dbId, queries));
|
207
|
-
collections = collections.concat(response.collections);
|
208
|
-
moreCollections = response.collections.length === 500;
|
209
|
-
if (moreCollections) {
|
210
|
-
lastCollectionId =
|
211
|
-
response.collections[response.collections.length - 1].$id;
|
212
|
-
}
|
213
|
-
}
|
214
|
-
console.log(`Fetched a total of ${collections.length} collections.`);
|
215
|
-
return collections;
|
216
|
-
};
|
217
|
-
/**
|
218
|
-
* Transfers all documents from one collection to another in a different database
|
219
|
-
* within the same Appwrite Project
|
220
|
-
*/
|
221
|
-
export const transferDocumentsBetweenDbsLocalToLocal = async (db, fromDbId, toDbId, fromCollId, toCollId) => {
|
222
|
-
let fromCollDocs = await tryAwaitWithRetry(async () => db.listDocuments(fromDbId, fromCollId, [Query.limit(50)]));
|
223
|
-
let totalDocumentsTransferred = 0;
|
224
|
-
if (fromCollDocs.documents.length === 0) {
|
225
|
-
console.log(`No documents found in collection ${fromCollId}`);
|
226
|
-
return;
|
227
|
-
}
|
228
|
-
else if (fromCollDocs.documents.length < 50) {
|
229
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
230
|
-
const toCreateObject = {
|
231
|
-
...doc,
|
232
|
-
};
|
233
|
-
delete toCreateObject.$databaseId;
|
234
|
-
delete toCreateObject.$collectionId;
|
235
|
-
delete toCreateObject.$createdAt;
|
236
|
-
delete toCreateObject.$updatedAt;
|
237
|
-
delete toCreateObject.$id;
|
238
|
-
delete toCreateObject.$permissions;
|
239
|
-
return tryAwaitWithRetry(async () => await db.createDocument(toDbId, toCollId, doc.$id, toCreateObject, doc.$permissions));
|
240
|
-
});
|
241
|
-
await Promise.all(batchedPromises);
|
242
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
243
|
-
}
|
244
|
-
else {
|
245
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
246
|
-
const toCreateObject = {
|
247
|
-
...doc,
|
248
|
-
};
|
249
|
-
delete toCreateObject.$databaseId;
|
250
|
-
delete toCreateObject.$collectionId;
|
251
|
-
delete toCreateObject.$createdAt;
|
252
|
-
delete toCreateObject.$updatedAt;
|
253
|
-
delete toCreateObject.$id;
|
254
|
-
delete toCreateObject.$permissions;
|
255
|
-
return tryAwaitWithRetry(async () => db.createDocument(toDbId, toCollId, doc.$id, toCreateObject, doc.$permissions));
|
256
|
-
});
|
257
|
-
await Promise.all(batchedPromises);
|
258
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
259
|
-
while (fromCollDocs.documents.length === 50) {
|
260
|
-
fromCollDocs = await tryAwaitWithRetry(async () => await db.listDocuments(fromDbId, fromCollId, [
|
261
|
-
Query.limit(50),
|
262
|
-
Query.cursorAfter(fromCollDocs.documents[fromCollDocs.documents.length - 1].$id),
|
263
|
-
]));
|
264
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
265
|
-
const toCreateObject = {
|
266
|
-
...doc,
|
267
|
-
};
|
268
|
-
delete toCreateObject.$databaseId;
|
269
|
-
delete toCreateObject.$collectionId;
|
270
|
-
delete toCreateObject.$createdAt;
|
271
|
-
delete toCreateObject.$updatedAt;
|
272
|
-
delete toCreateObject.$id;
|
273
|
-
delete toCreateObject.$permissions;
|
274
|
-
return tryAwaitWithRetry(async () => await db.createDocument(toDbId, toCollId, doc.$id, toCreateObject, doc.$permissions));
|
275
|
-
});
|
276
|
-
await Promise.all(batchedPromises);
|
277
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
278
|
-
}
|
279
|
-
}
|
280
|
-
console.log(`Transferred ${totalDocumentsTransferred} documents from database ${fromDbId} to database ${toDbId} -- collection ${fromCollId} to collection ${toCollId}`);
|
281
|
-
};
|
282
|
-
export const transferDocumentsBetweenDbsLocalToRemote = async (localDb, endpoint, projectId, apiKey, fromDbId, toDbId, fromCollId, toCollId) => {
|
283
|
-
const client = new Client()
|
284
|
-
.setEndpoint(endpoint)
|
285
|
-
.setProject(projectId)
|
286
|
-
.setKey(apiKey);
|
287
|
-
let totalDocumentsTransferred = 0;
|
288
|
-
const remoteDb = new Databases(client);
|
289
|
-
let fromCollDocs = await tryAwaitWithRetry(async () => localDb.listDocuments(fromDbId, fromCollId, [Query.limit(50)]));
|
290
|
-
if (fromCollDocs.documents.length === 0) {
|
291
|
-
console.log(`No documents found in collection ${fromCollId}`);
|
292
|
-
return;
|
293
|
-
}
|
294
|
-
else if (fromCollDocs.documents.length < 50) {
|
295
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
296
|
-
const toCreateObject = {
|
297
|
-
...doc,
|
298
|
-
};
|
299
|
-
delete toCreateObject.$databaseId;
|
300
|
-
delete toCreateObject.$collectionId;
|
301
|
-
delete toCreateObject.$createdAt;
|
302
|
-
delete toCreateObject.$updatedAt;
|
303
|
-
delete toCreateObject.$id;
|
304
|
-
delete toCreateObject.$permissions;
|
305
|
-
return tryAwaitWithRetry(async () => remoteDb.createDocument(toDbId, toCollId, doc.$id, toCreateObject, doc.$permissions));
|
306
|
-
});
|
307
|
-
await Promise.all(batchedPromises);
|
308
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
309
|
-
}
|
310
|
-
else {
|
311
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
312
|
-
const toCreateObject = {
|
313
|
-
...doc,
|
314
|
-
};
|
315
|
-
delete toCreateObject.$databaseId;
|
316
|
-
delete toCreateObject.$collectionId;
|
317
|
-
delete toCreateObject.$createdAt;
|
318
|
-
delete toCreateObject.$updatedAt;
|
319
|
-
delete toCreateObject.$id;
|
320
|
-
delete toCreateObject.$permissions;
|
321
|
-
return tryAwaitWithRetry(async () => remoteDb.createDocument(toDbId, toCollId, doc.$id, toCreateObject, doc.$permissions));
|
322
|
-
});
|
323
|
-
await Promise.all(batchedPromises);
|
324
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
325
|
-
while (fromCollDocs.documents.length === 50) {
|
326
|
-
fromCollDocs = await tryAwaitWithRetry(async () => localDb.listDocuments(fromDbId, fromCollId, [
|
327
|
-
Query.limit(50),
|
328
|
-
Query.cursorAfter(fromCollDocs.documents[fromCollDocs.documents.length - 1].$id),
|
329
|
-
]));
|
330
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
331
|
-
const toCreateObject = {
|
332
|
-
...doc,
|
333
|
-
};
|
334
|
-
delete toCreateObject.$databaseId;
|
335
|
-
delete toCreateObject.$collectionId;
|
336
|
-
delete toCreateObject.$createdAt;
|
337
|
-
delete toCreateObject.$updatedAt;
|
338
|
-
delete toCreateObject.$id;
|
339
|
-
delete toCreateObject.$permissions;
|
340
|
-
return tryAwaitWithRetry(async () => remoteDb.createDocument(toDbId, toCollId, doc.$id, toCreateObject, doc.$permissions));
|
341
|
-
});
|
342
|
-
await Promise.all(batchedPromises);
|
343
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
344
|
-
}
|
345
|
-
}
|
346
|
-
console.log(`Total documents transferred from database ${fromDbId} to database ${toDbId} -- collection ${fromCollId} to collection ${toCollId}: ${totalDocumentsTransferred}`);
|
347
|
-
};
|
@@ -1,46 +0,0 @@
|
|
1
|
-
import { type AttributeMappings } from "appwrite-utils";
|
2
|
-
/**
|
3
|
-
* Deeply converts all properties of an object (or array) to strings.
|
4
|
-
* @param data The input data to convert.
|
5
|
-
* @returns The data with all its properties converted to strings.
|
6
|
-
*/
|
7
|
-
export declare const deepAnyToString: (data: any) => any;
|
8
|
-
/**
|
9
|
-
* Performs a deep conversion of all values in a nested structure to the specified type.
|
10
|
-
* Uses a conversion function like anyToString, anyToNumber, etc.
|
11
|
-
* @param data The data to convert.
|
12
|
-
* @param convertFn The conversion function to apply.
|
13
|
-
* @returns The converted data.
|
14
|
-
*/
|
15
|
-
export declare const deepConvert: <T>(data: any, convertFn: (value: any) => T) => any;
|
16
|
-
/**
|
17
|
-
* Converts an entire object's properties to different types based on a provided schema.
|
18
|
-
* @param obj The object to convert.
|
19
|
-
* @param schema A mapping of object keys to conversion functions.
|
20
|
-
* @returns The converted object.
|
21
|
-
*/
|
22
|
-
export declare const convertObjectBySchema: (obj: Record<string, any>, schema: Record<string, (value: any) => any>) => Record<string, any>;
|
23
|
-
/**
|
24
|
-
* Converts the keys of an object based on a provided attributeMappings.
|
25
|
-
* Each key in the object is checked against attributeMappings; if a matching entry is found,
|
26
|
-
* the key is renamed to the targetKey specified in attributeMappings.
|
27
|
-
*
|
28
|
-
* @param obj The object to convert.
|
29
|
-
* @param attributeMappings The attributeMappings defining how keys in the object should be converted.
|
30
|
-
* @returns The converted object with keys renamed according to attributeMappings.
|
31
|
-
*/
|
32
|
-
export declare const convertObjectByAttributeMappings: (obj: Record<string, any>, attributeMappings: AttributeMappings) => Record<string, any>;
|
33
|
-
/**
|
34
|
-
* Ensures data conversion without mutating the original input.
|
35
|
-
* @param data The data to convert.
|
36
|
-
* @param convertFn The conversion function to apply.
|
37
|
-
* @returns The converted data.
|
38
|
-
*/
|
39
|
-
export declare const immutableConvert: <T>(data: any, convertFn: (value: any) => T) => T;
|
40
|
-
/**
|
41
|
-
* Validates a string against a regular expression and returns the string if valid, or null.
|
42
|
-
* @param value The string to validate.
|
43
|
-
* @param pattern The regex pattern to validate against.
|
44
|
-
* @returns The original string if valid, otherwise null.
|
45
|
-
*/
|
46
|
-
export declare const validateString: (value: string, pattern: RegExp) => string | null;
|