appwrite-utils-cli 1.6.7 → 1.6.9
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/collections/attributes.js +7 -0
- package/dist/migrations/services/ValidationService.js +2 -2
- package/dist/migrations/yaml/YamlImportIntegration.js +1 -1
- package/dist/migrations/yaml/generateImportSchemas.js +8 -0
- package/dist/utils/configDiscovery.js +9 -3
- package/dist/utils/setupFiles.js +16 -0
- package/package.json +1 -1
- package/src/collections/attributes.ts +11 -0
- package/src/migrations/services/ValidationService.ts +17 -17
- package/src/migrations/yaml/YamlImportIntegration.ts +10 -10
- package/src/migrations/yaml/generateImportSchemas.ts +8 -0
- package/src/utils/configDiscovery.ts +9 -3
- package/src/utils/setupFiles.ts +16 -0
@@ -607,6 +607,13 @@ const attributesSame = (databaseAttribute, configAttribute) => {
|
|
607
607
|
operation: 'attributesSame'
|
608
608
|
});
|
609
609
|
}
|
610
|
+
// Log differences if comparison failed (for debugging)
|
611
|
+
if (!result && differences.length > 0) {
|
612
|
+
MessageFormatter.debug(`Attribute '${configAttribute.key}' differences detected:`, { prefix: "Attributes" });
|
613
|
+
differences.forEach(diff => {
|
614
|
+
MessageFormatter.debug(` ${diff}`, { prefix: "Attributes" });
|
615
|
+
});
|
616
|
+
}
|
610
617
|
return result;
|
611
618
|
};
|
612
619
|
/**
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import { logger } from "../../shared/logging.js";
|
2
|
+
import fs from "fs";
|
3
|
+
import path from "path";
|
2
4
|
/**
|
3
5
|
* Service responsible for validation during import operations.
|
4
6
|
* Provides centralized validation logic extracted from ImportDataActions and DataLoader.
|
@@ -203,8 +205,6 @@ export class ValidationService {
|
|
203
205
|
errors.push(...importDefErrors.map(err => `${collection.name}.importDefs[${i}]: ${err}`));
|
204
206
|
// Check if import file exists
|
205
207
|
try {
|
206
|
-
const fs = require("fs");
|
207
|
-
const path = require("path");
|
208
208
|
const filePath = path.resolve(appwriteFolderPath, importDef.filePath);
|
209
209
|
if (!fs.existsSync(filePath)) {
|
210
210
|
errors.push(`${collection.name}.importDefs[${i}]: Import file not found: ${filePath}`);
|
@@ -4,6 +4,7 @@ import { logger } from "../../shared/logging.js";
|
|
4
4
|
import { normalizeYamlData, usesTableTerminology, convertTerminology } from "../../utils/yamlConverter.js";
|
5
5
|
import path from "path";
|
6
6
|
import fs from "fs";
|
7
|
+
import yaml from "js-yaml";
|
7
8
|
/**
|
8
9
|
* Integration service that bridges YAML import configurations with the existing import system.
|
9
10
|
* Provides seamless integration between new YAML configs and legacy TypeScript collection definitions.
|
@@ -225,7 +226,6 @@ export class YamlImportIntegration {
|
|
225
226
|
updateMapping: importDef.updateMapping,
|
226
227
|
},
|
227
228
|
};
|
228
|
-
const yaml = require("js-yaml");
|
229
229
|
const yamlContent = yaml.dump(yamlConfig, {
|
230
230
|
indent: 2,
|
231
231
|
lineWidth: 120,
|
@@ -462,6 +462,14 @@ export function generateCollectionSchema() {
|
|
462
462
|
"side": {
|
463
463
|
"type": "string",
|
464
464
|
"enum": ["parent", "child"]
|
465
|
+
},
|
466
|
+
"encrypt": {
|
467
|
+
"type": "boolean",
|
468
|
+
"description": "Whether the attribute should be encrypted"
|
469
|
+
},
|
470
|
+
"format": {
|
471
|
+
"type": "string",
|
472
|
+
"description": "Format for string attributes (e.g., email, url, ip)"
|
465
473
|
}
|
466
474
|
},
|
467
475
|
"required": ["key", "type"],
|
@@ -123,7 +123,9 @@ const YamlCollectionSchema = z.object({
|
|
123
123
|
twoWay: z.boolean().optional(),
|
124
124
|
twoWayKey: z.string().optional(),
|
125
125
|
onDelete: z.string().optional(),
|
126
|
-
side: z.string().optional()
|
126
|
+
side: z.string().optional(),
|
127
|
+
encrypt: z.boolean().optional(),
|
128
|
+
format: z.string().optional()
|
127
129
|
})).optional().default([]),
|
128
130
|
indexes: z.array(z.object({
|
129
131
|
key: z.string(),
|
@@ -168,7 +170,9 @@ export const loadYamlCollection = (filePath) => {
|
|
168
170
|
twoWay: attr.twoWay,
|
169
171
|
twoWayKey: attr.twoWayKey,
|
170
172
|
onDelete: attr.onDelete,
|
171
|
-
side: attr.side
|
173
|
+
side: attr.side,
|
174
|
+
encrypted: attr.encrypt,
|
175
|
+
format: attr.format
|
172
176
|
})),
|
173
177
|
indexes: parsedCollection.indexes.map(idx => ({
|
174
178
|
key: idx.key,
|
@@ -221,7 +225,9 @@ export const loadYamlTable = (filePath) => {
|
|
221
225
|
twoWay: attr.twoWay,
|
222
226
|
twoWayKey: attr.twoWayKey,
|
223
227
|
onDelete: attr.onDelete,
|
224
|
-
side: attr.side
|
228
|
+
side: attr.side,
|
229
|
+
encrypted: attr.encrypt,
|
230
|
+
format: attr.format
|
225
231
|
})),
|
226
232
|
indexes: parsedTable.indexes.map(idx => ({
|
227
233
|
key: idx.key,
|
package/dist/utils/setupFiles.js
CHANGED
@@ -479,6 +479,14 @@ importDefs: []
|
|
479
479
|
"type": "string",
|
480
480
|
"description": "Column description"
|
481
481
|
},
|
482
|
+
"encrypt": {
|
483
|
+
"type": "boolean",
|
484
|
+
"description": "Whether the column should be encrypted"
|
485
|
+
},
|
486
|
+
"format": {
|
487
|
+
"type": "string",
|
488
|
+
"description": "Format for string columns"
|
489
|
+
},
|
482
490
|
"min": {
|
483
491
|
"type": "number",
|
484
492
|
"description": "Minimum value for numeric columns"
|
@@ -673,6 +681,14 @@ importDefs: []
|
|
673
681
|
"type": "string",
|
674
682
|
"description": "Attribute description"
|
675
683
|
},
|
684
|
+
"encrypt": {
|
685
|
+
"type": "boolean",
|
686
|
+
"description": "Whether the attribute should be encrypted"
|
687
|
+
},
|
688
|
+
"format": {
|
689
|
+
"type": "string",
|
690
|
+
"description": "Format for string attributes"
|
691
|
+
},
|
676
692
|
"min": {
|
677
693
|
"type": "number",
|
678
694
|
"description": "Minimum value for numeric attributes"
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "appwrite-utils-cli",
|
3
3
|
"description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
|
4
|
-
"version": "1.6.
|
4
|
+
"version": "1.6.9",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -935,6 +935,17 @@ const attributesSame = (
|
|
935
935
|
});
|
936
936
|
}
|
937
937
|
|
938
|
+
// Log differences if comparison failed (for debugging)
|
939
|
+
if (!result && differences.length > 0) {
|
940
|
+
MessageFormatter.debug(
|
941
|
+
`Attribute '${configAttribute.key}' differences detected:`,
|
942
|
+
{ prefix: "Attributes" }
|
943
|
+
);
|
944
|
+
differences.forEach(diff => {
|
945
|
+
MessageFormatter.debug(` ${diff}`, { prefix: "Attributes" });
|
946
|
+
});
|
947
|
+
}
|
948
|
+
|
938
949
|
return result;
|
939
950
|
};
|
940
951
|
|
@@ -1,10 +1,12 @@
|
|
1
|
-
import type {
|
2
|
-
AttributeMappings,
|
3
|
-
ImportDef,
|
4
|
-
CollectionCreate,
|
5
|
-
} from "appwrite-utils";
|
6
|
-
import type { ImportDataActions } from "../importDataActions.js";
|
7
|
-
import { logger } from "../../shared/logging.js";
|
1
|
+
import type {
|
2
|
+
AttributeMappings,
|
3
|
+
ImportDef,
|
4
|
+
CollectionCreate,
|
5
|
+
} from "appwrite-utils";
|
6
|
+
import type { ImportDataActions } from "../importDataActions.js";
|
7
|
+
import { logger } from "../../shared/logging.js";
|
8
|
+
import fs from "fs";
|
9
|
+
import path from "path";
|
8
10
|
|
9
11
|
/**
|
10
12
|
* Service responsible for validation during import operations.
|
@@ -274,15 +276,13 @@ export class ValidationService {
|
|
274
276
|
);
|
275
277
|
|
276
278
|
// Check if import file exists
|
277
|
-
try {
|
278
|
-
const
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
);
|
285
|
-
}
|
279
|
+
try {
|
280
|
+
const filePath = path.resolve(appwriteFolderPath, importDef.filePath);
|
281
|
+
if (!fs.existsSync(filePath)) {
|
282
|
+
errors.push(
|
283
|
+
`${collection.name}.importDefs[${i}]: Import file not found: ${filePath}`
|
284
|
+
);
|
285
|
+
}
|
286
286
|
} catch (error) {
|
287
287
|
warnings.push(
|
288
288
|
`${collection.name}.importDefs[${i}]: Could not validate file existence: ${error}`
|
@@ -346,4 +346,4 @@ export class ValidationService {
|
|
346
346
|
shouldContinue: true,
|
347
347
|
};
|
348
348
|
}
|
349
|
-
}
|
349
|
+
}
|
@@ -1,10 +1,11 @@
|
|
1
|
-
import type { CollectionCreate, ImportDef } from "appwrite-utils";
|
2
|
-
import { YamlImportConfigLoader, type YamlImportConfig } from "./YamlImportConfigLoader.js";
|
3
|
-
import { createImportSchemas, createImportExamples } from "./generateImportSchemas.js";
|
4
|
-
import { logger } from "../../shared/logging.js";
|
5
|
-
import { normalizeYamlData, usesTableTerminology, convertTerminology, type YamlCollectionData } from "../../utils/yamlConverter.js";
|
6
|
-
import path from "path";
|
7
|
-
import fs from "fs";
|
1
|
+
import type { CollectionCreate, ImportDef } from "appwrite-utils";
|
2
|
+
import { YamlImportConfigLoader, type YamlImportConfig } from "./YamlImportConfigLoader.js";
|
3
|
+
import { createImportSchemas, createImportExamples } from "./generateImportSchemas.js";
|
4
|
+
import { logger } from "../../shared/logging.js";
|
5
|
+
import { normalizeYamlData, usesTableTerminology, convertTerminology, type YamlCollectionData } from "../../utils/yamlConverter.js";
|
6
|
+
import path from "path";
|
7
|
+
import fs from "fs";
|
8
|
+
import yaml from "js-yaml";
|
8
9
|
|
9
10
|
/**
|
10
11
|
* Integration service that bridges YAML import configurations with the existing import system.
|
@@ -284,8 +285,7 @@ export class YamlImportIntegration {
|
|
284
285
|
},
|
285
286
|
};
|
286
287
|
|
287
|
-
const
|
288
|
-
const yamlContent = yaml.dump(yamlConfig, {
|
288
|
+
const yamlContent = yaml.dump(yamlConfig, {
|
289
289
|
indent: 2,
|
290
290
|
lineWidth: 120,
|
291
291
|
sortKeys: false,
|
@@ -443,4 +443,4 @@ export class YamlImportIntegration {
|
|
443
443
|
missingComponents,
|
444
444
|
};
|
445
445
|
}
|
446
|
-
}
|
446
|
+
}
|
@@ -464,6 +464,14 @@ export function generateCollectionSchema(): any {
|
|
464
464
|
"side": {
|
465
465
|
"type": "string",
|
466
466
|
"enum": ["parent", "child"]
|
467
|
+
},
|
468
|
+
"encrypt": {
|
469
|
+
"type": "boolean",
|
470
|
+
"description": "Whether the attribute should be encrypted"
|
471
|
+
},
|
472
|
+
"format": {
|
473
|
+
"type": "string",
|
474
|
+
"description": "Format for string attributes (e.g., email, url, ip)"
|
467
475
|
}
|
468
476
|
},
|
469
477
|
"required": ["key", "type"],
|
@@ -139,7 +139,9 @@ const YamlCollectionSchema = z.object({
|
|
139
139
|
twoWay: z.boolean().optional(),
|
140
140
|
twoWayKey: z.string().optional(),
|
141
141
|
onDelete: z.string().optional(),
|
142
|
-
side: z.string().optional()
|
142
|
+
side: z.string().optional(),
|
143
|
+
encrypt: z.boolean().optional(),
|
144
|
+
format: z.string().optional()
|
143
145
|
})
|
144
146
|
).optional().default([]),
|
145
147
|
indexes: z.array(
|
@@ -191,7 +193,9 @@ export const loadYamlCollection = (filePath: string): CollectionCreate | null =>
|
|
191
193
|
twoWay: attr.twoWay,
|
192
194
|
twoWayKey: attr.twoWayKey,
|
193
195
|
onDelete: attr.onDelete as any,
|
194
|
-
side: attr.side as any
|
196
|
+
side: attr.side as any,
|
197
|
+
encrypted: (attr as any).encrypt,
|
198
|
+
format: (attr as any).format
|
195
199
|
})),
|
196
200
|
indexes: parsedCollection.indexes.map(idx => ({
|
197
201
|
key: idx.key,
|
@@ -247,7 +251,9 @@ export const loadYamlTable = (filePath: string): any | null => {
|
|
247
251
|
twoWay: attr.twoWay,
|
248
252
|
twoWayKey: attr.twoWayKey,
|
249
253
|
onDelete: attr.onDelete as any,
|
250
|
-
side: attr.side as any
|
254
|
+
side: attr.side as any,
|
255
|
+
encrypted: (attr as any).encrypt,
|
256
|
+
format: (attr as any).format
|
251
257
|
})),
|
252
258
|
indexes: parsedTable.indexes.map(idx => ({
|
253
259
|
key: idx.key,
|
package/src/utils/setupFiles.ts
CHANGED
@@ -516,6 +516,14 @@ importDefs: []
|
|
516
516
|
"type": "string",
|
517
517
|
"description": "Column description"
|
518
518
|
},
|
519
|
+
"encrypt": {
|
520
|
+
"type": "boolean",
|
521
|
+
"description": "Whether the column should be encrypted"
|
522
|
+
},
|
523
|
+
"format": {
|
524
|
+
"type": "string",
|
525
|
+
"description": "Format for string columns"
|
526
|
+
},
|
519
527
|
"min": {
|
520
528
|
"type": "number",
|
521
529
|
"description": "Minimum value for numeric columns"
|
@@ -710,6 +718,14 @@ importDefs: []
|
|
710
718
|
"type": "string",
|
711
719
|
"description": "Attribute description"
|
712
720
|
},
|
721
|
+
"encrypt": {
|
722
|
+
"type": "boolean",
|
723
|
+
"description": "Whether the attribute should be encrypted"
|
724
|
+
},
|
725
|
+
"format": {
|
726
|
+
"type": "string",
|
727
|
+
"description": "Format for string attributes"
|
728
|
+
},
|
713
729
|
"min": {
|
714
730
|
"type": "number",
|
715
731
|
"description": "Minimum value for numeric attributes"
|