appwrite-utils-cli 1.5.2 → 1.6.1
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/CHANGELOG.md +199 -0
- package/README.md +251 -29
- package/dist/adapters/AdapterFactory.d.ts +10 -3
- package/dist/adapters/AdapterFactory.js +213 -17
- package/dist/adapters/TablesDBAdapter.js +60 -17
- package/dist/backups/operations/bucketBackup.d.ts +19 -0
- package/dist/backups/operations/bucketBackup.js +197 -0
- package/dist/backups/operations/collectionBackup.d.ts +30 -0
- package/dist/backups/operations/collectionBackup.js +201 -0
- package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
- package/dist/backups/operations/comprehensiveBackup.js +238 -0
- package/dist/backups/schemas/bucketManifest.d.ts +93 -0
- package/dist/backups/schemas/bucketManifest.js +33 -0
- package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
- package/dist/backups/schemas/comprehensiveManifest.js +32 -0
- package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
- package/dist/backups/tracking/centralizedTracking.js +274 -0
- package/dist/cli/commands/configCommands.d.ts +8 -0
- package/dist/cli/commands/configCommands.js +160 -0
- package/dist/cli/commands/databaseCommands.d.ts +13 -0
- package/dist/cli/commands/databaseCommands.js +479 -0
- package/dist/cli/commands/functionCommands.d.ts +7 -0
- package/dist/cli/commands/functionCommands.js +289 -0
- package/dist/cli/commands/schemaCommands.d.ts +7 -0
- package/dist/cli/commands/schemaCommands.js +134 -0
- package/dist/cli/commands/transferCommands.d.ts +5 -0
- package/dist/cli/commands/transferCommands.js +384 -0
- package/dist/collections/attributes.d.ts +5 -4
- package/dist/collections/attributes.js +539 -246
- package/dist/collections/indexes.js +39 -37
- package/dist/collections/methods.d.ts +2 -16
- package/dist/collections/methods.js +90 -538
- package/dist/collections/transferOperations.d.ts +7 -0
- package/dist/collections/transferOperations.js +331 -0
- package/dist/collections/wipeOperations.d.ts +16 -0
- package/dist/collections/wipeOperations.js +328 -0
- package/dist/config/configMigration.d.ts +87 -0
- package/dist/config/configMigration.js +390 -0
- package/dist/config/configValidation.d.ts +66 -0
- package/dist/config/configValidation.js +358 -0
- package/dist/config/yamlConfig.d.ts +455 -1
- package/dist/config/yamlConfig.js +145 -52
- package/dist/databases/methods.js +3 -2
- package/dist/databases/setup.d.ts +1 -2
- package/dist/databases/setup.js +9 -87
- package/dist/examples/yamlTerminologyExample.d.ts +42 -0
- package/dist/examples/yamlTerminologyExample.js +269 -0
- package/dist/functions/deployments.js +11 -10
- package/dist/functions/methods.d.ts +1 -1
- package/dist/functions/methods.js +5 -4
- package/dist/init.js +9 -9
- package/dist/interactiveCLI.d.ts +8 -17
- package/dist/interactiveCLI.js +209 -1172
- package/dist/main.js +364 -21
- package/dist/migrations/afterImportActions.js +22 -30
- package/dist/migrations/appwriteToX.js +71 -25
- package/dist/migrations/dataLoader.js +35 -26
- package/dist/migrations/importController.js +29 -30
- package/dist/migrations/relationships.js +13 -12
- package/dist/migrations/services/ImportOrchestrator.js +16 -19
- package/dist/migrations/transfer.js +46 -46
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +3 -1
- package/dist/migrations/yaml/YamlImportConfigLoader.js +6 -3
- package/dist/migrations/yaml/YamlImportIntegration.d.ts +9 -3
- package/dist/migrations/yaml/YamlImportIntegration.js +22 -11
- package/dist/migrations/yaml/generateImportSchemas.d.ts +14 -1
- package/dist/migrations/yaml/generateImportSchemas.js +736 -7
- package/dist/schemas/authUser.d.ts +1 -1
- package/dist/setupController.js +3 -2
- package/dist/shared/backupMetadataSchema.d.ts +94 -0
- package/dist/shared/backupMetadataSchema.js +38 -0
- package/dist/shared/backupTracking.d.ts +18 -0
- package/dist/shared/backupTracking.js +176 -0
- package/dist/shared/confirmationDialogs.js +15 -15
- package/dist/shared/errorUtils.d.ts +54 -0
- package/dist/shared/errorUtils.js +95 -0
- package/dist/shared/functionManager.js +20 -19
- package/dist/shared/indexManager.js +12 -11
- package/dist/shared/jsonSchemaGenerator.js +10 -26
- package/dist/shared/logging.d.ts +51 -0
- package/dist/shared/logging.js +70 -0
- package/dist/shared/messageFormatter.d.ts +2 -0
- package/dist/shared/messageFormatter.js +10 -0
- package/dist/shared/migrationHelpers.d.ts +6 -16
- package/dist/shared/migrationHelpers.js +24 -21
- package/dist/shared/operationLogger.d.ts +8 -1
- package/dist/shared/operationLogger.js +11 -24
- package/dist/shared/operationQueue.d.ts +28 -1
- package/dist/shared/operationQueue.js +268 -66
- package/dist/shared/operationsTable.d.ts +26 -0
- package/dist/shared/operationsTable.js +286 -0
- package/dist/shared/operationsTableSchema.d.ts +48 -0
- package/dist/shared/operationsTableSchema.js +35 -0
- package/dist/shared/relationshipExtractor.d.ts +56 -0
- package/dist/shared/relationshipExtractor.js +138 -0
- package/dist/shared/schemaGenerator.d.ts +19 -1
- package/dist/shared/schemaGenerator.js +56 -75
- package/dist/storage/backupCompression.d.ts +20 -0
- package/dist/storage/backupCompression.js +67 -0
- package/dist/storage/methods.d.ts +16 -2
- package/dist/storage/methods.js +98 -14
- package/dist/users/methods.js +9 -8
- package/dist/utils/configDiscovery.d.ts +78 -0
- package/dist/utils/configDiscovery.js +430 -0
- package/dist/utils/directoryUtils.d.ts +22 -0
- package/dist/utils/directoryUtils.js +59 -0
- package/dist/utils/getClientFromConfig.d.ts +17 -8
- package/dist/utils/getClientFromConfig.js +162 -17
- package/dist/utils/helperFunctions.d.ts +16 -2
- package/dist/utils/helperFunctions.js +19 -5
- package/dist/utils/loadConfigs.d.ts +34 -9
- package/dist/utils/loadConfigs.js +236 -316
- package/dist/utils/pathResolvers.d.ts +53 -0
- package/dist/utils/pathResolvers.js +72 -0
- package/dist/utils/projectConfig.d.ts +119 -0
- package/dist/utils/projectConfig.js +171 -0
- package/dist/utils/retryFailedPromises.js +4 -2
- package/dist/utils/sessionAuth.d.ts +48 -0
- package/dist/utils/sessionAuth.js +164 -0
- package/dist/utils/sessionPreservationExample.d.ts +1666 -0
- package/dist/utils/sessionPreservationExample.js +101 -0
- package/dist/utils/setupFiles.js +301 -41
- package/dist/utils/typeGuards.d.ts +35 -0
- package/dist/utils/typeGuards.js +57 -0
- package/dist/utils/versionDetection.js +145 -9
- package/dist/utils/yamlConverter.d.ts +53 -3
- package/dist/utils/yamlConverter.js +232 -13
- package/dist/utils/yamlLoader.d.ts +70 -0
- package/dist/utils/yamlLoader.js +263 -0
- package/dist/utilsController.d.ts +36 -3
- package/dist/utilsController.js +186 -56
- package/package.json +12 -2
- package/src/adapters/AdapterFactory.ts +263 -35
- package/src/adapters/TablesDBAdapter.ts +225 -36
- package/src/backups/operations/bucketBackup.ts +277 -0
- package/src/backups/operations/collectionBackup.ts +310 -0
- package/src/backups/operations/comprehensiveBackup.ts +342 -0
- package/src/backups/schemas/bucketManifest.ts +78 -0
- package/src/backups/schemas/comprehensiveManifest.ts +76 -0
- package/src/backups/tracking/centralizedTracking.ts +352 -0
- package/src/cli/commands/configCommands.ts +194 -0
- package/src/cli/commands/databaseCommands.ts +635 -0
- package/src/cli/commands/functionCommands.ts +379 -0
- package/src/cli/commands/schemaCommands.ts +163 -0
- package/src/cli/commands/transferCommands.ts +457 -0
- package/src/collections/attributes.ts +900 -621
- package/src/collections/attributes.ts.backup +1555 -0
- package/src/collections/indexes.ts +116 -114
- package/src/collections/methods.ts +295 -968
- package/src/collections/transferOperations.ts +516 -0
- package/src/collections/wipeOperations.ts +501 -0
- package/src/config/README.md +274 -0
- package/src/config/configMigration.ts +575 -0
- package/src/config/configValidation.ts +445 -0
- package/src/config/yamlConfig.ts +168 -55
- package/src/databases/methods.ts +3 -2
- package/src/databases/setup.ts +11 -138
- package/src/examples/yamlTerminologyExample.ts +341 -0
- package/src/functions/deployments.ts +14 -12
- package/src/functions/methods.ts +11 -11
- package/src/functions/templates/hono-typescript/README.md +286 -0
- package/src/functions/templates/hono-typescript/package.json +26 -0
- package/src/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
- package/src/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
- package/src/functions/templates/hono-typescript/src/app.ts +180 -0
- package/src/functions/templates/hono-typescript/src/context.ts +103 -0
- package/src/functions/templates/hono-typescript/src/index.ts +54 -0
- package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
- package/src/functions/templates/hono-typescript/tsconfig.json +20 -0
- package/src/functions/templates/typescript-node/package.json +2 -1
- package/src/functions/templates/typescript-node/src/context.ts +103 -0
- package/src/functions/templates/typescript-node/src/index.ts +18 -12
- package/src/functions/templates/uv/pyproject.toml +1 -0
- package/src/functions/templates/uv/src/context.py +125 -0
- package/src/functions/templates/uv/src/index.py +35 -5
- package/src/init.ts +9 -11
- package/src/interactiveCLI.ts +274 -1563
- package/src/main.ts +418 -24
- package/src/migrations/afterImportActions.ts +71 -44
- package/src/migrations/appwriteToX.ts +100 -34
- package/src/migrations/dataLoader.ts +48 -34
- package/src/migrations/importController.ts +44 -39
- package/src/migrations/relationships.ts +28 -18
- package/src/migrations/services/ImportOrchestrator.ts +24 -27
- package/src/migrations/transfer.ts +159 -121
- package/src/migrations/yaml/YamlImportConfigLoader.ts +11 -4
- package/src/migrations/yaml/YamlImportIntegration.ts +47 -20
- package/src/migrations/yaml/generateImportSchemas.ts +751 -12
- package/src/setupController.ts +3 -2
- package/src/shared/backupMetadataSchema.ts +93 -0
- package/src/shared/backupTracking.ts +211 -0
- package/src/shared/confirmationDialogs.ts +19 -19
- package/src/shared/errorUtils.ts +110 -0
- package/src/shared/functionManager.ts +21 -20
- package/src/shared/indexManager.ts +12 -11
- package/src/shared/jsonSchemaGenerator.ts +38 -52
- package/src/shared/logging.ts +75 -0
- package/src/shared/messageFormatter.ts +14 -1
- package/src/shared/migrationHelpers.ts +45 -38
- package/src/shared/operationLogger.ts +11 -36
- package/src/shared/operationQueue.ts +322 -93
- package/src/shared/operationsTable.ts +338 -0
- package/src/shared/operationsTableSchema.ts +60 -0
- package/src/shared/relationshipExtractor.ts +214 -0
- package/src/shared/schemaGenerator.ts +179 -219
- package/src/storage/backupCompression.ts +88 -0
- package/src/storage/methods.ts +131 -34
- package/src/users/methods.ts +11 -9
- package/src/utils/configDiscovery.ts +502 -0
- package/src/utils/directoryUtils.ts +61 -0
- package/src/utils/getClientFromConfig.ts +205 -22
- package/src/utils/helperFunctions.ts +23 -5
- package/src/utils/loadConfigs.ts +313 -345
- package/src/utils/pathResolvers.ts +81 -0
- package/src/utils/projectConfig.ts +299 -0
- package/src/utils/retryFailedPromises.ts +4 -2
- package/src/utils/sessionAuth.ts +230 -0
- package/src/utils/setupFiles.ts +322 -54
- package/src/utils/typeGuards.ts +65 -0
- package/src/utils/versionDetection.ts +218 -64
- package/src/utils/yamlConverter.ts +296 -13
- package/src/utils/yamlLoader.ts +364 -0
- package/src/utilsController.ts +314 -110
- package/tests/README.md +497 -0
- package/tests/adapters/AdapterFactory.test.ts +277 -0
- package/tests/integration/syncOperations.test.ts +463 -0
- package/tests/jest.config.js +25 -0
- package/tests/migration/configMigration.test.ts +546 -0
- package/tests/setup.ts +62 -0
- package/tests/testUtils.ts +340 -0
- package/tests/utils/loadConfigs.test.ts +350 -0
- package/tests/validation/configValidation.test.ts +412 -0
- package/src/utils/schemaStrings.ts +0 -517
@@ -5,6 +5,7 @@ import fs from "node:fs";
|
|
5
5
|
import chalk from "chalk";
|
6
6
|
import pLimit from "p-limit";
|
7
7
|
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
8
|
+
import { MessageFormatter } from "./messageFormatter.js";
|
8
9
|
/**
|
9
10
|
* Validates and filters events array for Appwrite functions
|
10
11
|
* - Filters out empty/invalid strings
|
@@ -34,7 +35,7 @@ export class FunctionManager {
|
|
34
35
|
async findFunctionDirectory(functionName, options = {}) {
|
35
36
|
const { searchPaths = [process.cwd()], caseSensitive = false, allowFuzzyMatch = true, verbose = false } = options;
|
36
37
|
if (verbose) {
|
37
|
-
|
38
|
+
MessageFormatter.info(`Searching for function: ${functionName}`, { prefix: "Functions" });
|
38
39
|
}
|
39
40
|
// Normalize function name for comparison
|
40
41
|
const normalizedName = caseSensitive ? functionName : functionName.toLowerCase();
|
@@ -44,7 +45,7 @@ export class FunctionManager {
|
|
44
45
|
for (const path of standardPaths) {
|
45
46
|
if (await this.isValidFunctionDirectory(path)) {
|
46
47
|
if (verbose) {
|
47
|
-
|
48
|
+
MessageFormatter.success(`Found function at standard location: ${path}`, { prefix: "Functions" });
|
48
49
|
}
|
49
50
|
return path;
|
50
51
|
}
|
@@ -55,14 +56,14 @@ export class FunctionManager {
|
|
55
56
|
const foundPath = await this.recursiveDirectorySearch(searchPath, nameVariations, { caseSensitive, verbose });
|
56
57
|
if (foundPath) {
|
57
58
|
if (verbose) {
|
58
|
-
|
59
|
+
MessageFormatter.success(`Found function via fuzzy search: ${foundPath}`, { prefix: "Functions" });
|
59
60
|
}
|
60
61
|
return foundPath;
|
61
62
|
}
|
62
63
|
}
|
63
64
|
}
|
64
65
|
if (verbose) {
|
65
|
-
|
66
|
+
MessageFormatter.warning(`Function directory not found: ${functionName}`, { prefix: "Functions" });
|
66
67
|
}
|
67
68
|
return null;
|
68
69
|
}
|
@@ -116,7 +117,7 @@ export class FunctionManager {
|
|
116
117
|
}
|
117
118
|
catch (error) {
|
118
119
|
if (verbose) {
|
119
|
-
|
120
|
+
MessageFormatter.debug(`Skipping inaccessible directory: ${searchPath}`, undefined, { prefix: "Functions" });
|
120
121
|
}
|
121
122
|
}
|
122
123
|
return null;
|
@@ -169,9 +170,9 @@ export class FunctionManager {
|
|
169
170
|
const { activate = true, entrypoint = functionConfig.entrypoint || "index.js", commands = functionConfig.commands || "npm install", ignored = ["node_modules", ".git", ".vscode", ".DS_Store", "__pycache__", ".venv"], verbose = false, forceRedeploy = false } = options;
|
170
171
|
return await functionLimit(async () => {
|
171
172
|
if (verbose) {
|
172
|
-
|
173
|
-
|
174
|
-
|
173
|
+
MessageFormatter.processing(`Deploying function: ${functionConfig.name}`, { prefix: "Functions" });
|
174
|
+
MessageFormatter.debug(`Path: ${functionPath}`, undefined, { prefix: "Functions" });
|
175
|
+
MessageFormatter.debug(`Entrypoint: ${entrypoint}`, undefined, { prefix: "Functions" });
|
175
176
|
}
|
176
177
|
// Validate function directory
|
177
178
|
if (!await this.isValidFunctionDirectory(functionPath)) {
|
@@ -185,7 +186,7 @@ export class FunctionManager {
|
|
185
186
|
}
|
186
187
|
catch (error) {
|
187
188
|
if (verbose) {
|
188
|
-
|
189
|
+
MessageFormatter.info(`Function ${functionConfig.$id} does not exist, creating...`, { prefix: "Functions" });
|
189
190
|
}
|
190
191
|
}
|
191
192
|
// Create function if it doesn't exist
|
@@ -202,7 +203,7 @@ export class FunctionManager {
|
|
202
203
|
// Deploy the function
|
203
204
|
const deployment = await this.createDeployment(functionConfig.$id, functionPath, { activate, entrypoint, commands, ignored, verbose });
|
204
205
|
if (verbose) {
|
205
|
-
|
206
|
+
MessageFormatter.success(`Function ${functionConfig.name} deployed successfully`, { prefix: "Functions" });
|
206
207
|
}
|
207
208
|
return deployment;
|
208
209
|
});
|
@@ -210,7 +211,7 @@ export class FunctionManager {
|
|
210
211
|
async createFunction(functionConfig, options = {}) {
|
211
212
|
const { verbose = false } = options;
|
212
213
|
if (verbose) {
|
213
|
-
|
214
|
+
MessageFormatter.processing(`Creating function: ${functionConfig.name}`, { prefix: "Functions" });
|
214
215
|
}
|
215
216
|
return await tryAwaitWithRetry(async () => {
|
216
217
|
return await this.functions.create(functionConfig.$id, functionConfig.name, functionConfig.runtime, functionConfig.execute || [], functionConfig.events || [], functionConfig.schedule || "", functionConfig.timeout || 15, functionConfig.enabled !== false, functionConfig.logging !== false, functionConfig.entrypoint, functionConfig.commands, functionConfig.scopes || [], functionConfig.installationId, functionConfig.providerRepositoryId, functionConfig.providerBranch, functionConfig.providerSilentMode, functionConfig.providerRootDirectory);
|
@@ -219,7 +220,7 @@ export class FunctionManager {
|
|
219
220
|
async updateFunction(functionConfig, options = {}) {
|
220
221
|
const { verbose = false } = options;
|
221
222
|
if (verbose) {
|
222
|
-
|
223
|
+
MessageFormatter.processing(`Updating function: ${functionConfig.name}`, { prefix: "Functions" });
|
223
224
|
}
|
224
225
|
return await tryAwaitWithRetry(async () => {
|
225
226
|
return await this.functions.update(functionConfig.$id, functionConfig.name, functionConfig.runtime, functionConfig.execute || [], functionConfig.events || [], functionConfig.schedule || "", functionConfig.timeout || 15, functionConfig.enabled !== false, functionConfig.logging !== false, functionConfig.entrypoint, functionConfig.commands, functionConfig.scopes || [], functionConfig.installationId, functionConfig.providerRepositoryId, functionConfig.providerBranch, functionConfig.providerSilentMode, functionConfig.providerRootDirectory, functionConfig.specification);
|
@@ -230,12 +231,12 @@ export class FunctionManager {
|
|
230
231
|
const { execSync } = await import("child_process");
|
231
232
|
const { platform } = await import("node:os");
|
232
233
|
if (verbose) {
|
233
|
-
|
234
|
+
MessageFormatter.processing("Executing pre-deploy commands...", { prefix: "Functions" });
|
234
235
|
}
|
235
236
|
const isWindows = platform() === "win32";
|
236
237
|
for (const command of commands) {
|
237
238
|
if (verbose) {
|
238
|
-
|
239
|
+
MessageFormatter.debug(`$ ${command}`, undefined, { prefix: "Functions" });
|
239
240
|
}
|
240
241
|
try {
|
241
242
|
execSync(command, {
|
@@ -246,12 +247,12 @@ export class FunctionManager {
|
|
246
247
|
});
|
247
248
|
}
|
248
249
|
catch (error) {
|
249
|
-
|
250
|
+
MessageFormatter.error(`Failed to execute command: ${command}`, error, { prefix: "Functions" });
|
250
251
|
throw error;
|
251
252
|
}
|
252
253
|
}
|
253
254
|
if (verbose) {
|
254
|
-
|
255
|
+
MessageFormatter.success("Pre-deploy commands completed", { prefix: "Functions" });
|
255
256
|
}
|
256
257
|
}
|
257
258
|
async createDeployment(functionId, codePath, options = {}) {
|
@@ -261,7 +262,7 @@ export class FunctionManager {
|
|
261
262
|
const tarPath = join(process.cwd(), `function-${functionId}-${Date.now()}.tar.gz`);
|
262
263
|
try {
|
263
264
|
if (verbose) {
|
264
|
-
|
265
|
+
MessageFormatter.processing("Creating deployment archive...", { prefix: "Functions" });
|
265
266
|
}
|
266
267
|
// Create tarball
|
267
268
|
await createTarball({
|
@@ -274,7 +275,7 @@ export class FunctionManager {
|
|
274
275
|
relativePath.includes(`/${pattern.toLowerCase()}`) ||
|
275
276
|
relativePath.includes(`\\${pattern.toLowerCase()}`));
|
276
277
|
if (shouldIgnore && verbose) {
|
277
|
-
|
278
|
+
MessageFormatter.debug(`Ignoring: ${path}`, undefined, { prefix: "Functions" });
|
278
279
|
}
|
279
280
|
return !shouldIgnore;
|
280
281
|
},
|
@@ -283,7 +284,7 @@ export class FunctionManager {
|
|
283
284
|
const fileBuffer = await fs.promises.readFile(tarPath);
|
284
285
|
const fileObject = InputFile.fromBuffer(new Uint8Array(fileBuffer), `function-${functionId}.tar.gz`);
|
285
286
|
if (verbose) {
|
286
|
-
|
287
|
+
MessageFormatter.processing("Uploading deployment...", { prefix: "Functions" });
|
287
288
|
}
|
288
289
|
const deployment = await tryAwaitWithRetry(async () => {
|
289
290
|
return await this.functions.createDeployment(functionId, fileObject, activate, entrypoint, commands);
|
@@ -3,6 +3,7 @@ import { Databases, IndexType, Query } from "node-appwrite";
|
|
3
3
|
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
4
4
|
import chalk from "chalk";
|
5
5
|
import pLimit from "p-limit";
|
6
|
+
import { MessageFormatter } from "./messageFormatter.js";
|
6
7
|
// Concurrency limits for different operations
|
7
8
|
const indexLimit = pLimit(3); // Low limit for index operations
|
8
9
|
const queryLimit = pLimit(25); // Higher limit for read operations
|
@@ -23,7 +24,7 @@ export const createOrUpdateIndex = async (dbId, db, collectionId, index, options
|
|
23
24
|
existingIndex = existingIndexes.indexes[0];
|
24
25
|
if (forceRecreate || !indexesSame(existingIndex, index)) {
|
25
26
|
if (verbose) {
|
26
|
-
|
27
|
+
MessageFormatter.warning(`Updating index ${index.key} in collection ${collectionId}`, { prefix: "Index Manager" });
|
27
28
|
}
|
28
29
|
// Delete existing index
|
29
30
|
await tryAwaitWithRetry(async () => {
|
@@ -34,7 +35,7 @@ export const createOrUpdateIndex = async (dbId, db, collectionId, index, options
|
|
34
35
|
}
|
35
36
|
else {
|
36
37
|
if (verbose) {
|
37
|
-
|
38
|
+
MessageFormatter.success(`Index ${index.key} is up to date`, { prefix: "Index Manager" });
|
38
39
|
}
|
39
40
|
return existingIndex;
|
40
41
|
}
|
@@ -42,7 +43,7 @@ export const createOrUpdateIndex = async (dbId, db, collectionId, index, options
|
|
42
43
|
else {
|
43
44
|
shouldCreate = true;
|
44
45
|
if (verbose) {
|
45
|
-
|
46
|
+
MessageFormatter.info(`Creating index ${index.key} in collection ${collectionId}`, { prefix: "Index Manager" });
|
46
47
|
}
|
47
48
|
}
|
48
49
|
if (shouldCreate) {
|
@@ -50,7 +51,7 @@ export const createOrUpdateIndex = async (dbId, db, collectionId, index, options
|
|
50
51
|
return await db.createIndex(dbId, collectionId, index.key, index.type, index.attributes, index.orders);
|
51
52
|
});
|
52
53
|
if (verbose) {
|
53
|
-
|
54
|
+
MessageFormatter.success(`Created index ${index.key}`, { prefix: "Index Manager" });
|
54
55
|
}
|
55
56
|
return newIndex;
|
56
57
|
}
|
@@ -63,7 +64,7 @@ export const createOrUpdateIndexes = async (dbId, db, collectionId, indexes, opt
|
|
63
64
|
return;
|
64
65
|
}
|
65
66
|
if (verbose) {
|
66
|
-
|
67
|
+
MessageFormatter.info(`Processing ${indexes.length} indexes for collection ${collectionId}`, { prefix: "Index Manager" });
|
67
68
|
}
|
68
69
|
// Process indexes sequentially to avoid conflicts
|
69
70
|
for (const index of indexes) {
|
@@ -73,12 +74,12 @@ export const createOrUpdateIndexes = async (dbId, db, collectionId, indexes, opt
|
|
73
74
|
await delay(250);
|
74
75
|
}
|
75
76
|
catch (error) {
|
76
|
-
|
77
|
+
MessageFormatter.error(`Failed to process index ${index.key}`, error, { prefix: "Index Manager" });
|
77
78
|
throw error;
|
78
79
|
}
|
79
80
|
}
|
80
81
|
if (verbose) {
|
81
|
-
|
82
|
+
MessageFormatter.success(`Completed processing indexes for collection ${collectionId}`, { prefix: "Index Manager" });
|
82
83
|
}
|
83
84
|
};
|
84
85
|
export const createUpdateCollectionIndexes = async (db, dbId, collection, collectionConfig, options = {}) => {
|
@@ -98,7 +99,7 @@ export const deleteObsoleteIndexes = async (db, dbId, collection, collectionConf
|
|
98
99
|
return;
|
99
100
|
}
|
100
101
|
if (verbose) {
|
101
|
-
|
102
|
+
MessageFormatter.warning(`Removing ${obsoleteIndexes.length} obsolete indexes from collection ${collection.name}`, { prefix: "Index Manager" });
|
102
103
|
}
|
103
104
|
// Process deletions with rate limiting
|
104
105
|
for (const index of obsoleteIndexes) {
|
@@ -108,7 +109,7 @@ export const deleteObsoleteIndexes = async (db, dbId, collection, collectionConf
|
|
108
109
|
});
|
109
110
|
});
|
110
111
|
if (verbose) {
|
111
|
-
|
112
|
+
MessageFormatter.info(`Deleted obsolete index ${index.key}`, { prefix: "Index Manager" });
|
112
113
|
}
|
113
114
|
await delay(250);
|
114
115
|
}
|
@@ -143,8 +144,8 @@ export const validateIndexConfiguration = (indexes, options = {}) => {
|
|
143
144
|
}
|
144
145
|
}
|
145
146
|
if (verbose && errors.length > 0) {
|
146
|
-
|
147
|
-
errors.forEach(error =>
|
147
|
+
MessageFormatter.error("Index validation errors", undefined, { prefix: "Index Manager" });
|
148
|
+
errors.forEach(error => MessageFormatter.error(` - ${error}`, undefined, { prefix: "Index Manager" }));
|
148
149
|
}
|
149
150
|
return { valid: errors.length === 0, errors };
|
150
151
|
};
|
@@ -2,6 +2,8 @@ import fs from "fs";
|
|
2
2
|
import path from "path";
|
3
3
|
import { toCamelCase, toPascalCase } from "../utils/index.js";
|
4
4
|
import chalk from "chalk";
|
5
|
+
import { extractSimpleRelationships, resolveCollectionName } from "./relationshipExtractor.js";
|
6
|
+
import { MessageFormatter } from "./messageFormatter.js";
|
5
7
|
export class JsonSchemaGenerator {
|
6
8
|
config;
|
7
9
|
appwriteFolderPath;
|
@@ -12,28 +14,10 @@ export class JsonSchemaGenerator {
|
|
12
14
|
this.extractRelationships();
|
13
15
|
}
|
14
16
|
resolveCollectionName = (idOrName) => {
|
15
|
-
|
16
|
-
return col?.name ?? idOrName;
|
17
|
+
return resolveCollectionName(this.config, idOrName);
|
17
18
|
};
|
18
19
|
extractRelationships() {
|
19
|
-
|
20
|
-
return;
|
21
|
-
this.config.collections.forEach((collection) => {
|
22
|
-
if (!collection.attributes)
|
23
|
-
return;
|
24
|
-
collection.attributes.forEach((attr) => {
|
25
|
-
if (attr.type === "relationship" && attr.relatedCollection) {
|
26
|
-
const relationships = this.relationshipMap.get(collection.name) || [];
|
27
|
-
relationships.push({
|
28
|
-
attributeKey: attr.key,
|
29
|
-
relatedCollection: this.resolveCollectionName(attr.relatedCollection),
|
30
|
-
relationType: attr.relationType,
|
31
|
-
isArray: attr.relationType === "oneToMany" || attr.relationType === "manyToMany"
|
32
|
-
});
|
33
|
-
this.relationshipMap.set(collection.name, relationships);
|
34
|
-
}
|
35
|
-
});
|
36
|
-
});
|
20
|
+
this.relationshipMap = extractSimpleRelationships(this.config);
|
37
21
|
}
|
38
22
|
attributeToJsonSchemaProperty(attribute) {
|
39
23
|
const property = {
|
@@ -188,7 +172,7 @@ export class JsonSchemaGenerator {
|
|
188
172
|
const { outputFormat = "both", outputDirectory = "schemas", verbose = false } = options;
|
189
173
|
if (!this.config.collections) {
|
190
174
|
if (verbose) {
|
191
|
-
|
175
|
+
MessageFormatter.warning("No collections found in config", { prefix: "Schema" });
|
192
176
|
}
|
193
177
|
return;
|
194
178
|
}
|
@@ -198,7 +182,7 @@ export class JsonSchemaGenerator {
|
|
198
182
|
fs.mkdirSync(jsonSchemasPath, { recursive: true });
|
199
183
|
}
|
200
184
|
if (verbose) {
|
201
|
-
|
185
|
+
MessageFormatter.processing(`Generating JSON schemas for ${this.config.collections.length} collections...`, { prefix: "Schema" });
|
202
186
|
}
|
203
187
|
this.config.collections.forEach((collection) => {
|
204
188
|
const schema = this.createJsonSchema(collection);
|
@@ -208,7 +192,7 @@ export class JsonSchemaGenerator {
|
|
208
192
|
const jsonPath = path.join(jsonSchemasPath, `${camelCaseName}.json`);
|
209
193
|
fs.writeFileSync(jsonPath, JSON.stringify(schema, null, 2), { encoding: "utf-8" });
|
210
194
|
if (verbose) {
|
211
|
-
|
195
|
+
MessageFormatter.success(`JSON schema written to ${jsonPath}`, { prefix: "Schema" });
|
212
196
|
}
|
213
197
|
}
|
214
198
|
// Generate TypeScript file
|
@@ -217,7 +201,7 @@ export class JsonSchemaGenerator {
|
|
217
201
|
const tsPath = path.join(jsonSchemasPath, `${camelCaseName}.schema.ts`);
|
218
202
|
fs.writeFileSync(tsPath, tsContent, { encoding: "utf-8" });
|
219
203
|
if (verbose) {
|
220
|
-
|
204
|
+
MessageFormatter.success(`TypeScript schema written to ${tsPath}`, { prefix: "Schema" });
|
221
205
|
}
|
222
206
|
}
|
223
207
|
});
|
@@ -226,7 +210,7 @@ export class JsonSchemaGenerator {
|
|
226
210
|
this.generateIndexFile(outputFormat, jsonSchemasPath, verbose);
|
227
211
|
}
|
228
212
|
if (verbose) {
|
229
|
-
|
213
|
+
MessageFormatter.success("JSON schema generation completed", { prefix: "Schema" });
|
230
214
|
}
|
231
215
|
}
|
232
216
|
generateTypeScriptSchema(schema, collectionName) {
|
@@ -274,7 +258,7 @@ export default jsonSchemas;
|
|
274
258
|
`;
|
275
259
|
fs.writeFileSync(indexPath, indexContent, { encoding: "utf-8" });
|
276
260
|
if (verbose) {
|
277
|
-
|
261
|
+
MessageFormatter.success(`Index file written to ${indexPath}`, { prefix: "Schema" });
|
278
262
|
}
|
279
263
|
}
|
280
264
|
validateSchema(schema) {
|
package/dist/shared/logging.d.ts
CHANGED
@@ -5,6 +5,57 @@ export interface LoggingConfig {
|
|
5
5
|
logDirectory?: string;
|
6
6
|
console: boolean;
|
7
7
|
}
|
8
|
+
/**
|
9
|
+
* Predefined logging configurations for common debugging scenarios
|
10
|
+
*/
|
11
|
+
export declare const LOGGING_PRESETS: {
|
12
|
+
/** Minimal logging - errors only to console */
|
13
|
+
readonly minimal: {
|
14
|
+
readonly enabled: false;
|
15
|
+
readonly level: "error";
|
16
|
+
readonly console: true;
|
17
|
+
};
|
18
|
+
/** Standard logging - info level to file and console */
|
19
|
+
readonly standard: {
|
20
|
+
readonly enabled: true;
|
21
|
+
readonly level: "info";
|
22
|
+
readonly console: true;
|
23
|
+
};
|
24
|
+
/** Debug logging - verbose debug output for troubleshooting */
|
25
|
+
readonly debug: {
|
26
|
+
readonly enabled: true;
|
27
|
+
readonly level: "debug";
|
28
|
+
readonly console: true;
|
29
|
+
};
|
30
|
+
/** Silent - no logging output */
|
31
|
+
readonly silent: {
|
32
|
+
readonly enabled: false;
|
33
|
+
readonly level: "error";
|
34
|
+
readonly console: false;
|
35
|
+
};
|
36
|
+
};
|
8
37
|
export declare const configureLogging: (config?: Partial<LoggingConfig>) => void;
|
38
|
+
/**
|
39
|
+
* Configure logging using a preset
|
40
|
+
*/
|
41
|
+
export declare const configureLoggingPreset: (preset: keyof typeof LOGGING_PRESETS, logDirectory?: string) => void;
|
9
42
|
export declare let logger: winston.Logger;
|
10
43
|
export declare const updateLogger: () => void;
|
44
|
+
/**
|
45
|
+
* Enable debug logging for troubleshooting push process issues
|
46
|
+
* This is a convenience function for quickly enabling comprehensive logging
|
47
|
+
*/
|
48
|
+
export declare const enableDebugLogging: (logDirectory?: string) => void;
|
49
|
+
/**
|
50
|
+
* Disable logging (reset to default)
|
51
|
+
*/
|
52
|
+
export declare const disableLogging: () => void;
|
53
|
+
/**
|
54
|
+
* Get current logging configuration
|
55
|
+
*/
|
56
|
+
export declare const getLoggingConfig: () => {
|
57
|
+
enabled: boolean;
|
58
|
+
level: string;
|
59
|
+
logDirectory?: string;
|
60
|
+
console: boolean;
|
61
|
+
};
|
package/dist/shared/logging.js
CHANGED
@@ -1,6 +1,35 @@
|
|
1
1
|
import winston from "winston";
|
2
2
|
import fs from "fs";
|
3
3
|
import path from "path";
|
4
|
+
/**
|
5
|
+
* Predefined logging configurations for common debugging scenarios
|
6
|
+
*/
|
7
|
+
export const LOGGING_PRESETS = {
|
8
|
+
/** Minimal logging - errors only to console */
|
9
|
+
minimal: {
|
10
|
+
enabled: false,
|
11
|
+
level: 'error',
|
12
|
+
console: true
|
13
|
+
},
|
14
|
+
/** Standard logging - info level to file and console */
|
15
|
+
standard: {
|
16
|
+
enabled: true,
|
17
|
+
level: 'info',
|
18
|
+
console: true
|
19
|
+
},
|
20
|
+
/** Debug logging - verbose debug output for troubleshooting */
|
21
|
+
debug: {
|
22
|
+
enabled: true,
|
23
|
+
level: 'debug',
|
24
|
+
console: true
|
25
|
+
},
|
26
|
+
/** Silent - no logging output */
|
27
|
+
silent: {
|
28
|
+
enabled: false,
|
29
|
+
level: 'error',
|
30
|
+
console: false
|
31
|
+
}
|
32
|
+
};
|
4
33
|
const DEFAULT_LOGGING_CONFIG = {
|
5
34
|
enabled: false,
|
6
35
|
level: "info",
|
@@ -10,6 +39,17 @@ let loggingConfig = DEFAULT_LOGGING_CONFIG;
|
|
10
39
|
export const configureLogging = (config = {}) => {
|
11
40
|
loggingConfig = { ...DEFAULT_LOGGING_CONFIG, ...config };
|
12
41
|
};
|
42
|
+
/**
|
43
|
+
* Configure logging using a preset
|
44
|
+
*/
|
45
|
+
export const configureLoggingPreset = (preset, logDirectory) => {
|
46
|
+
const presetConfig = LOGGING_PRESETS[preset];
|
47
|
+
configureLogging({
|
48
|
+
...presetConfig,
|
49
|
+
...(logDirectory && { logDirectory })
|
50
|
+
});
|
51
|
+
updateLogger();
|
52
|
+
};
|
13
53
|
const createLogger = () => {
|
14
54
|
const transports = [];
|
15
55
|
// Add console transport if enabled
|
@@ -44,3 +84,33 @@ export let logger = createLogger();
|
|
44
84
|
export const updateLogger = () => {
|
45
85
|
logger = createLogger();
|
46
86
|
};
|
87
|
+
/**
|
88
|
+
* Enable debug logging for troubleshooting push process issues
|
89
|
+
* This is a convenience function for quickly enabling comprehensive logging
|
90
|
+
*/
|
91
|
+
export const enableDebugLogging = (logDirectory) => {
|
92
|
+
configureLogging({
|
93
|
+
enabled: true,
|
94
|
+
level: 'debug',
|
95
|
+
console: true,
|
96
|
+
logDirectory
|
97
|
+
});
|
98
|
+
updateLogger();
|
99
|
+
logger.info('Debug logging enabled for push process troubleshooting', {
|
100
|
+
level: 'debug',
|
101
|
+
console: true,
|
102
|
+
logDirectory: logDirectory || 'zlogs',
|
103
|
+
operation: 'enableDebugLogging'
|
104
|
+
});
|
105
|
+
};
|
106
|
+
/**
|
107
|
+
* Disable logging (reset to default)
|
108
|
+
*/
|
109
|
+
export const disableLogging = () => {
|
110
|
+
configureLogging(DEFAULT_LOGGING_CONFIG);
|
111
|
+
updateLogger();
|
112
|
+
};
|
113
|
+
/**
|
114
|
+
* Get current logging configuration
|
115
|
+
*/
|
116
|
+
export const getLoggingConfig = () => ({ ...loggingConfig });
|
@@ -11,6 +11,8 @@ export declare class MessageFormatter {
|
|
11
11
|
static step(step: number, total: number, message: string, options?: MessageOptions): void;
|
12
12
|
static progress(message: string, options?: MessageOptions): void;
|
13
13
|
static debug(message: string, data?: any, options?: MessageOptions): void;
|
14
|
+
static processing(message: string, options?: MessageOptions): void;
|
15
|
+
static divider(): void;
|
14
16
|
static banner(title: string, subtitle?: string): void;
|
15
17
|
static section(title: string): void;
|
16
18
|
static list(items: string[], title?: string): void;
|
@@ -59,6 +59,16 @@ export class MessageFormatter {
|
|
59
59
|
logger.debug(`DEBUG: ${options.prefix ? `${options.prefix}: ` : ""}${message}`, data);
|
60
60
|
}
|
61
61
|
}
|
62
|
+
static processing(message, options = {}) {
|
63
|
+
const formatted = `${chalk.cyan("⚙️")} ${options.prefix ? `${options.prefix}: ` : ""}${message}`;
|
64
|
+
console.log(formatted);
|
65
|
+
if (!options.skipLogging) {
|
66
|
+
logger.info(`PROCESSING: ${options.prefix ? `${options.prefix}: ` : ""}${message}`);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
static divider() {
|
70
|
+
console.log(chalk.gray("─".repeat(60)));
|
71
|
+
}
|
62
72
|
static banner(title, subtitle) {
|
63
73
|
const divider = chalk.cyan("═".repeat(60));
|
64
74
|
console.log(`\n${divider}`);
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { type Databases } from "node-appwrite";
|
2
2
|
import { z } from "zod";
|
3
|
+
import type { DatabaseAdapter } from "../adapters/DatabaseAdapter.js";
|
3
4
|
/**
|
4
5
|
* Object that contains the context for an action that needs to be executed after import
|
5
6
|
* Used in the afterImportActionsDefinitions
|
@@ -37,9 +38,9 @@ export declare const ContextObject: z.ZodObject<{
|
|
37
38
|
context: z.ZodAny;
|
38
39
|
}, z.core.$strip>;
|
39
40
|
export type ContextObject = z.infer<typeof ContextObject>;
|
40
|
-
export declare const createOrFindAfterImportOperation: (database: Databases, collectionId: string, context: ContextObject
|
41
|
+
export declare const createOrFindAfterImportOperation: (database: Databases, collectionId: string, context: ContextObject) => Promise<void>;
|
41
42
|
export declare const addBatch: (database: Databases, data: string) => Promise<string>;
|
42
|
-
export declare const getAfterImportOperations: (database: Databases, collectionId: string
|
43
|
+
export declare const getAfterImportOperations: (database: Databases, collectionId: string) => Promise<{
|
43
44
|
$id: string;
|
44
45
|
$createdAt: string;
|
45
46
|
$updatedAt: string;
|
@@ -52,20 +53,9 @@ export declare const getAfterImportOperations: (database: Databases, collectionI
|
|
52
53
|
status: "error" | "pending" | "ready" | "in_progress" | "completed" | "cancelled";
|
53
54
|
batches?: string[] | undefined;
|
54
55
|
}[]>;
|
55
|
-
export declare const findOrCreateOperation: (
|
56
|
-
|
57
|
-
|
58
|
-
$updatedAt: string;
|
59
|
-
operationType: string;
|
60
|
-
collectionId: string;
|
61
|
-
data: any;
|
62
|
-
progress: number;
|
63
|
-
total: number;
|
64
|
-
error: string;
|
65
|
-
status: "error" | "pending" | "ready" | "in_progress" | "completed" | "cancelled";
|
66
|
-
batches?: string[] | undefined;
|
67
|
-
}>;
|
68
|
-
export declare const updateOperation: (database: Databases, operationId: string, updateFields: any, useMigrations?: boolean) => Promise<void>;
|
56
|
+
export declare const findOrCreateOperation: (db: DatabaseAdapter, databaseId: string, operationType: string, collectionId?: string, data?: any) => Promise<any>;
|
57
|
+
export declare const updateOperation: (db: DatabaseAdapter, databaseId: string, operationId: string, updates: any) => Promise<any>;
|
58
|
+
export declare const getOperation: (db: DatabaseAdapter, databaseId: string, operationId: string) => Promise<any>;
|
69
59
|
export declare const maxDataLength = 1073741820;
|
70
60
|
export declare const maxBatchItems = 25;
|
71
61
|
export declare const splitIntoBatches: (data: any[]) => any[][];
|
@@ -4,6 +4,8 @@ import { AttributeMappingsSchema } from "appwrite-utils";
|
|
4
4
|
import { z } from "zod";
|
5
5
|
import { logger } from "./logging.js";
|
6
6
|
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
7
|
+
import { findOrCreateOperation as findOrCreateOp, updateOperation as updateOp, getOperation as getOp } from "./operationsTable.js";
|
8
|
+
import { MessageFormatter } from "./messageFormatter.js";
|
7
9
|
/**
|
8
10
|
* Object that contains the context for an action that needs to be executed after import
|
9
11
|
* Used in the afterImportActionsDefinitions
|
@@ -22,12 +24,8 @@ export const ContextObject = z.object({
|
|
22
24
|
attributeMappings: AttributeMappingsSchema,
|
23
25
|
context: z.any(),
|
24
26
|
});
|
25
|
-
export const createOrFindAfterImportOperation = async (database, collectionId, context
|
26
|
-
|
27
|
-
logger.info("Migrations disabled, skipping after import operation tracking");
|
28
|
-
return;
|
29
|
-
}
|
30
|
-
let operation = await findOrCreateOperation(database, collectionId, "afterImportAction");
|
27
|
+
export const createOrFindAfterImportOperation = async (database, collectionId, context) => {
|
28
|
+
let operation = await findOrCreateOperationLegacy(database, collectionId, "afterImportAction");
|
31
29
|
if (!operation.batches) {
|
32
30
|
operation.batches = [];
|
33
31
|
}
|
@@ -46,11 +44,7 @@ export const addBatch = async (database, data) => {
|
|
46
44
|
});
|
47
45
|
return batch.$id;
|
48
46
|
};
|
49
|
-
export const getAfterImportOperations = async (database, collectionId
|
50
|
-
if (!useMigrations) {
|
51
|
-
logger.info("Migrations disabled, returning empty operations list");
|
52
|
-
return [];
|
53
|
-
}
|
47
|
+
export const getAfterImportOperations = async (database, collectionId) => {
|
54
48
|
let lastDocumentId;
|
55
49
|
const allOperations = [];
|
56
50
|
let total = 0;
|
@@ -74,7 +68,8 @@ export const getAfterImportOperations = async (database, collectionId, useMigrat
|
|
74
68
|
const allOps = allOperations.map((op) => OperationSchema.parse(op));
|
75
69
|
return allOps;
|
76
70
|
};
|
77
|
-
|
71
|
+
// Legacy function for backward compatibility with old migrations database
|
72
|
+
const findOrCreateOperationLegacy = async (database, collectionId, operationType, additionalQueries) => {
|
78
73
|
const operations = await tryAwaitWithRetry(async () => await database.listDocuments("migrations", "currentOperations", [
|
79
74
|
Query.equal("collectionId", collectionId),
|
80
75
|
Query.equal("operationType", operationType),
|
@@ -82,10 +77,9 @@ export const findOrCreateOperation = async (database, collectionId, operationTyp
|
|
82
77
|
...(additionalQueries || []),
|
83
78
|
]));
|
84
79
|
if (operations.documents.length > 0) {
|
85
|
-
return OperationSchema.parse(operations.documents[0]);
|
80
|
+
return OperationSchema.parse(operations.documents[0]);
|
86
81
|
}
|
87
82
|
else {
|
88
|
-
// Create a new operation document
|
89
83
|
const op = await tryAwaitWithRetry(async () => await database.createDocument("migrations", "currentOperations", ID.unique(), {
|
90
84
|
operationType,
|
91
85
|
collectionId,
|
@@ -98,12 +92,20 @@ export const findOrCreateOperation = async (database, collectionId, operationTyp
|
|
98
92
|
return OperationSchema.parse(op);
|
99
93
|
}
|
100
94
|
};
|
101
|
-
export const
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
95
|
+
export const findOrCreateOperation = async (db, databaseId, operationType, collectionId, data) => {
|
96
|
+
// Use new operations table system
|
97
|
+
return await findOrCreateOp(db, databaseId, operationType, {
|
98
|
+
targetCollection: collectionId,
|
99
|
+
data: data
|
100
|
+
});
|
101
|
+
};
|
102
|
+
export const updateOperation = async (db, databaseId, operationId, updates) => {
|
103
|
+
// Use new operations table system
|
104
|
+
return await updateOp(db, databaseId, operationId, updates);
|
105
|
+
};
|
106
|
+
export const getOperation = async (db, databaseId, operationId) => {
|
107
|
+
// Use new operations table system
|
108
|
+
return await getOp(db, databaseId, operationId);
|
107
109
|
};
|
108
110
|
// Actual max 1073741824
|
109
111
|
export const maxDataLength = 1073741820;
|
@@ -116,7 +118,8 @@ export const splitIntoBatches = (data) => {
|
|
116
118
|
data.forEach((item, index) => {
|
117
119
|
const itemLength = JSON.stringify(item).length;
|
118
120
|
if (itemLength > maxDataLength) {
|
119
|
-
|
121
|
+
MessageFormatter.warning(`Large item found at index ${index} with length ${itemLength}`, { prefix: "Batch Splitter" });
|
122
|
+
logger.debug("Large item data:", item);
|
120
123
|
}
|
121
124
|
// Check if adding the current item would exceed the max length or max items per batch
|
122
125
|
if (currentBatchLength + itemLength >= maxDataLength ||
|