appwrite-utils-cli 1.7.8 ā 1.8.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 +14 -199
- package/README.md +87 -30
- package/dist/adapters/AdapterFactory.js +5 -25
- package/dist/adapters/DatabaseAdapter.d.ts +17 -2
- package/dist/adapters/LegacyAdapter.d.ts +2 -1
- package/dist/adapters/LegacyAdapter.js +212 -16
- package/dist/adapters/TablesDBAdapter.d.ts +2 -12
- package/dist/adapters/TablesDBAdapter.js +261 -57
- package/dist/cli/commands/databaseCommands.js +10 -10
- package/dist/cli/commands/functionCommands.js +17 -8
- package/dist/collections/attributes.js +447 -125
- package/dist/collections/methods.js +197 -186
- package/dist/collections/tableOperations.d.ts +86 -0
- package/dist/collections/tableOperations.js +434 -0
- package/dist/collections/transferOperations.d.ts +3 -2
- package/dist/collections/transferOperations.js +93 -12
- package/dist/config/services/ConfigLoaderService.d.ts +7 -0
- package/dist/config/services/ConfigLoaderService.js +47 -1
- package/dist/config/yamlConfig.d.ts +221 -88
- package/dist/examples/yamlTerminologyExample.d.ts +1 -1
- package/dist/examples/yamlTerminologyExample.js +6 -3
- package/dist/functions/deployments.js +5 -23
- package/dist/functions/fnConfigDiscovery.d.ts +3 -0
- package/dist/functions/fnConfigDiscovery.js +108 -0
- package/dist/functions/methods.js +4 -2
- package/dist/functions/pathResolution.d.ts +37 -0
- package/dist/functions/pathResolution.js +185 -0
- package/dist/functions/templates/count-docs-in-collection/README.md +54 -0
- package/dist/functions/templates/count-docs-in-collection/package.json +25 -0
- package/dist/functions/templates/count-docs-in-collection/src/main.ts +159 -0
- package/dist/functions/templates/count-docs-in-collection/src/request.ts +9 -0
- package/dist/functions/templates/count-docs-in-collection/tsconfig.json +28 -0
- package/dist/functions/templates/hono-typescript/README.md +286 -0
- package/dist/functions/templates/hono-typescript/package.json +26 -0
- package/dist/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
- package/dist/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
- package/dist/functions/templates/hono-typescript/src/app.ts +180 -0
- package/dist/functions/templates/hono-typescript/src/context.ts +103 -0
- package/dist/functions/templates/hono-typescript/src/index.ts +54 -0
- package/dist/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
- package/dist/functions/templates/hono-typescript/tsconfig.json +20 -0
- package/dist/functions/templates/typescript-node/README.md +32 -0
- package/dist/functions/templates/typescript-node/package.json +25 -0
- package/dist/functions/templates/typescript-node/src/context.ts +103 -0
- package/dist/functions/templates/typescript-node/src/index.ts +29 -0
- package/dist/functions/templates/typescript-node/tsconfig.json +28 -0
- package/dist/functions/templates/uv/README.md +31 -0
- package/dist/functions/templates/uv/pyproject.toml +30 -0
- package/dist/functions/templates/uv/src/__init__.py +0 -0
- package/dist/functions/templates/uv/src/context.py +125 -0
- package/dist/functions/templates/uv/src/index.py +46 -0
- package/dist/interactiveCLI.js +18 -15
- package/dist/main.js +219 -81
- package/dist/migrations/appwriteToX.d.ts +88 -23
- package/dist/migrations/comprehensiveTransfer.d.ts +2 -0
- package/dist/migrations/comprehensiveTransfer.js +83 -6
- package/dist/migrations/dataLoader.d.ts +227 -69
- package/dist/migrations/dataLoader.js +3 -3
- package/dist/migrations/importController.js +3 -3
- package/dist/migrations/relationships.d.ts +8 -2
- package/dist/migrations/services/ImportOrchestrator.js +3 -3
- package/dist/migrations/transfer.js +159 -37
- package/dist/shared/attributeMapper.d.ts +20 -0
- package/dist/shared/attributeMapper.js +203 -0
- package/dist/shared/selectionDialogs.d.ts +1 -1
- package/dist/shared/selectionDialogs.js +39 -11
- package/dist/storage/schemas.d.ts +354 -92
- package/dist/utils/configDiscovery.js +4 -3
- package/dist/utils/versionDetection.d.ts +0 -4
- package/dist/utils/versionDetection.js +41 -173
- package/dist/utils/yamlConverter.js +89 -16
- package/dist/utils/yamlLoader.d.ts +1 -1
- package/dist/utils/yamlLoader.js +6 -2
- package/dist/utilsController.d.ts +2 -1
- package/dist/utilsController.js +151 -22
- package/package.json +7 -5
- package/scripts/copy-templates.ts +23 -0
- package/src/adapters/AdapterFactory.ts +119 -143
- package/src/adapters/DatabaseAdapter.ts +18 -3
- package/src/adapters/LegacyAdapter.ts +236 -105
- package/src/adapters/TablesDBAdapter.ts +773 -643
- package/src/cli/commands/databaseCommands.ts +19 -19
- package/src/cli/commands/functionCommands.ts +23 -14
- package/src/collections/attributes.ts +2054 -1611
- package/src/collections/methods.ts +208 -293
- package/src/collections/tableOperations.ts +506 -0
- package/src/collections/transferOperations.ts +218 -144
- package/src/config/services/ConfigLoaderService.ts +62 -1
- package/src/examples/yamlTerminologyExample.ts +10 -5
- package/src/functions/deployments.ts +10 -35
- package/src/functions/fnConfigDiscovery.ts +103 -0
- package/src/functions/methods.ts +4 -2
- package/src/functions/pathResolution.ts +227 -0
- package/src/interactiveCLI.ts +25 -20
- package/src/main.ts +557 -202
- package/src/migrations/comprehensiveTransfer.ts +126 -50
- package/src/migrations/dataLoader.ts +3 -3
- package/src/migrations/importController.ts +3 -3
- package/src/migrations/services/ImportOrchestrator.ts +3 -3
- package/src/migrations/transfer.ts +148 -131
- package/src/shared/attributeMapper.ts +229 -0
- package/src/shared/selectionDialogs.ts +65 -32
- package/src/utils/configDiscovery.ts +9 -3
- package/src/utils/versionDetection.ts +74 -228
- package/src/utils/yamlConverter.ts +94 -17
- package/src/utils/yamlLoader.ts +11 -4
- package/src/utilsController.ts +202 -36
- package/dist/utils/schemaStrings.d.ts +0 -14
- package/dist/utils/schemaStrings.js +0 -428
- package/dist/utils/sessionPreservationExample.d.ts +0 -1666
- package/dist/utils/sessionPreservationExample.js +0 -101
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import type { CreateAttributeParams, UpdateAttributeParams } from "../adapters/DatabaseAdapter.js";
|
|
2
|
+
import type { Attribute } from "appwrite-utils";
|
|
3
|
+
|
|
4
|
+
function ensureNumber(n: any): number | undefined {
|
|
5
|
+
if (n === null || n === undefined) return undefined;
|
|
6
|
+
const num = Number(n);
|
|
7
|
+
return Number.isFinite(num) ? num : undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Map a schema Attribute into DatabaseAdapter CreateAttributeParams
|
|
12
|
+
* Only includes fields valid for the specific type to satisfy TS unions.
|
|
13
|
+
* Also normalizes min/max ordering for numeric types to avoid server errors.
|
|
14
|
+
*/
|
|
15
|
+
export function mapToCreateAttributeParams(
|
|
16
|
+
attr: Attribute,
|
|
17
|
+
base: { databaseId: string; tableId: string }
|
|
18
|
+
): CreateAttributeParams {
|
|
19
|
+
const type = String((attr as any).type || "").toLowerCase();
|
|
20
|
+
const required = !!(attr as any).required;
|
|
21
|
+
const array = !!(attr as any).array;
|
|
22
|
+
const xdefault = (attr as any).xdefault;
|
|
23
|
+
const encrypt = (attr as any).encrypted ?? (attr as any).encrypt;
|
|
24
|
+
|
|
25
|
+
// Numeric helpers
|
|
26
|
+
const rawMin = ensureNumber((attr as any).min);
|
|
27
|
+
const rawMax = ensureNumber((attr as any).max);
|
|
28
|
+
let min = rawMin;
|
|
29
|
+
let max = rawMax;
|
|
30
|
+
if (min !== undefined && max !== undefined && min >= max) {
|
|
31
|
+
// Swap to satisfy server-side validation
|
|
32
|
+
const tmp = min;
|
|
33
|
+
min = Math.min(min, max);
|
|
34
|
+
max = Math.max(tmp, max);
|
|
35
|
+
if (min === max) {
|
|
36
|
+
// If still equal, unset max to avoid error
|
|
37
|
+
max = undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
switch (type) {
|
|
42
|
+
case "string":
|
|
43
|
+
return {
|
|
44
|
+
databaseId: base.databaseId,
|
|
45
|
+
tableId: base.tableId,
|
|
46
|
+
key: attr.key,
|
|
47
|
+
type,
|
|
48
|
+
size: (attr as any).size ?? 255,
|
|
49
|
+
required,
|
|
50
|
+
default: xdefault,
|
|
51
|
+
array,
|
|
52
|
+
encrypt: !!encrypt,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
case "integer":
|
|
56
|
+
return {
|
|
57
|
+
databaseId: base.databaseId,
|
|
58
|
+
tableId: base.tableId,
|
|
59
|
+
key: attr.key,
|
|
60
|
+
type,
|
|
61
|
+
required,
|
|
62
|
+
default: xdefault,
|
|
63
|
+
array,
|
|
64
|
+
min,
|
|
65
|
+
max,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
case "double":
|
|
69
|
+
case "float":
|
|
70
|
+
return {
|
|
71
|
+
databaseId: base.databaseId,
|
|
72
|
+
tableId: base.tableId,
|
|
73
|
+
key: attr.key,
|
|
74
|
+
type,
|
|
75
|
+
required,
|
|
76
|
+
default: xdefault,
|
|
77
|
+
array,
|
|
78
|
+
min,
|
|
79
|
+
max,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
case "boolean":
|
|
83
|
+
return {
|
|
84
|
+
databaseId: base.databaseId,
|
|
85
|
+
tableId: base.tableId,
|
|
86
|
+
key: attr.key,
|
|
87
|
+
type,
|
|
88
|
+
required,
|
|
89
|
+
default: xdefault,
|
|
90
|
+
array,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
case "datetime":
|
|
94
|
+
case "email":
|
|
95
|
+
case "ip":
|
|
96
|
+
case "url":
|
|
97
|
+
return {
|
|
98
|
+
databaseId: base.databaseId,
|
|
99
|
+
tableId: base.tableId,
|
|
100
|
+
key: attr.key,
|
|
101
|
+
type,
|
|
102
|
+
required,
|
|
103
|
+
default: xdefault,
|
|
104
|
+
array,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
case "enum":
|
|
108
|
+
{
|
|
109
|
+
const elements = (attr as any).elements;
|
|
110
|
+
if (!Array.isArray(elements) || elements.length === 0) {
|
|
111
|
+
// Creating an enum without elements is invalid ā fail fast with clear messaging
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Enum attribute '${(attr as any).key}' requires a non-empty 'elements' array for creation`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
databaseId: base.databaseId,
|
|
119
|
+
tableId: base.tableId,
|
|
120
|
+
key: attr.key,
|
|
121
|
+
type,
|
|
122
|
+
required,
|
|
123
|
+
default: xdefault,
|
|
124
|
+
array,
|
|
125
|
+
elements: (attr as any).elements,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
case "relationship": {
|
|
129
|
+
// Relationship attributes require related collection and metadata
|
|
130
|
+
return {
|
|
131
|
+
databaseId: base.databaseId,
|
|
132
|
+
tableId: base.tableId,
|
|
133
|
+
key: attr.key,
|
|
134
|
+
type,
|
|
135
|
+
relatedCollection: (attr as any).relatedCollection,
|
|
136
|
+
relationType: (attr as any).relationType,
|
|
137
|
+
twoWay: (attr as any).twoWay,
|
|
138
|
+
twoWayKey: (attr as any).twoWayKey,
|
|
139
|
+
onDelete: (attr as any).onDelete,
|
|
140
|
+
side: (attr as any).side,
|
|
141
|
+
} as unknown as CreateAttributeParams;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
default:
|
|
145
|
+
return {
|
|
146
|
+
databaseId: base.databaseId,
|
|
147
|
+
tableId: base.tableId,
|
|
148
|
+
key: attr.key,
|
|
149
|
+
type,
|
|
150
|
+
required,
|
|
151
|
+
} as CreateAttributeParams;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Map a schema Attribute into DatabaseAdapter UpdateAttributeParams
|
|
157
|
+
* Omits fields that are not explicitly provided, and guards enum updates
|
|
158
|
+
* so we never send an empty elements array (preserve existing on server).
|
|
159
|
+
*/
|
|
160
|
+
export function mapToUpdateAttributeParams(
|
|
161
|
+
attr: Attribute,
|
|
162
|
+
base: { databaseId: string; tableId: string }
|
|
163
|
+
): UpdateAttributeParams {
|
|
164
|
+
const type = String((attr as any).type || "").toLowerCase();
|
|
165
|
+
const params: UpdateAttributeParams = {
|
|
166
|
+
databaseId: base.databaseId,
|
|
167
|
+
tableId: base.tableId,
|
|
168
|
+
key: (attr as any).key,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const setIfDefined = <K extends keyof UpdateAttributeParams>(
|
|
172
|
+
key: K,
|
|
173
|
+
value: UpdateAttributeParams[K]
|
|
174
|
+
) => {
|
|
175
|
+
if (value !== undefined) (params as any)[key] = value;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// Common fields
|
|
179
|
+
setIfDefined("type", type);
|
|
180
|
+
setIfDefined("required", (attr as any).required);
|
|
181
|
+
// Only send default if explicitly provided and not on required
|
|
182
|
+
if (!(attr as any).required && (attr as any).xdefault !== undefined) {
|
|
183
|
+
setIfDefined("default", (attr as any).xdefault as any);
|
|
184
|
+
}
|
|
185
|
+
setIfDefined("array", (attr as any).array);
|
|
186
|
+
// encrypt only applies to string types
|
|
187
|
+
if (type === "string") setIfDefined("encrypt", (attr as any).encrypted ?? (attr as any).encrypt);
|
|
188
|
+
|
|
189
|
+
// Numeric normalization
|
|
190
|
+
const toNum = (n: any) => (n === null || n === undefined ? undefined : (Number(n)));
|
|
191
|
+
let min = toNum((attr as any).min);
|
|
192
|
+
let max = toNum((attr as any).max);
|
|
193
|
+
if (min !== undefined && max !== undefined && min >= max) {
|
|
194
|
+
const tmp = min;
|
|
195
|
+
min = Math.min(min, max);
|
|
196
|
+
max = Math.max(tmp, max);
|
|
197
|
+
if (min === max) max = undefined;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
switch (type) {
|
|
201
|
+
case "string":
|
|
202
|
+
setIfDefined("size", (attr as any).size);
|
|
203
|
+
break;
|
|
204
|
+
case "integer":
|
|
205
|
+
case "float":
|
|
206
|
+
case "double":
|
|
207
|
+
setIfDefined("min", min);
|
|
208
|
+
setIfDefined("max", max);
|
|
209
|
+
break;
|
|
210
|
+
case "enum": {
|
|
211
|
+
const elements = (attr as any).elements;
|
|
212
|
+
if (Array.isArray(elements) && elements.length > 0) {
|
|
213
|
+
// Only include when non-empty; otherwise preserve existing on server
|
|
214
|
+
setIfDefined("elements", elements as string[]);
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case "relationship": {
|
|
219
|
+
setIfDefined("relatedCollection", (attr as any).relatedCollection);
|
|
220
|
+
setIfDefined("relationType", (attr as any).relationType);
|
|
221
|
+
setIfDefined("twoWay", (attr as any).twoWay);
|
|
222
|
+
setIfDefined("twoWayKey", (attr as any).twoWayKey);
|
|
223
|
+
setIfDefined("onDelete", (attr as any).onDelete);
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return params;
|
|
229
|
+
}
|
|
@@ -244,12 +244,13 @@ export class SelectionDialogs {
|
|
|
244
244
|
return; // Skip configured databases if only allowing new ones
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
choices.push({
|
|
248
|
-
name,
|
|
249
|
-
value: database.$id,
|
|
250
|
-
short: database.name,
|
|
251
|
-
|
|
252
|
-
|
|
247
|
+
choices.push({
|
|
248
|
+
name,
|
|
249
|
+
value: database.$id,
|
|
250
|
+
short: database.name,
|
|
251
|
+
// Do not preselect anything unless explicitly provided
|
|
252
|
+
checked: defaultSelected.includes(database.$id)
|
|
253
|
+
});
|
|
253
254
|
});
|
|
254
255
|
|
|
255
256
|
if (choices.length === 0) {
|
|
@@ -327,12 +328,13 @@ export class SelectionDialogs {
|
|
|
327
328
|
return; // Skip configured tables if only allowing new ones
|
|
328
329
|
}
|
|
329
330
|
|
|
330
|
-
choices.push({
|
|
331
|
-
name,
|
|
332
|
-
value: table.$id,
|
|
333
|
-
short: table.name,
|
|
334
|
-
|
|
335
|
-
|
|
331
|
+
choices.push({
|
|
332
|
+
name,
|
|
333
|
+
value: table.$id,
|
|
334
|
+
short: table.name,
|
|
335
|
+
// Do not preselect anything unless explicitly provided
|
|
336
|
+
checked: defaultSelected.includes(table.$id)
|
|
337
|
+
});
|
|
336
338
|
});
|
|
337
339
|
|
|
338
340
|
if (choices.length === 0) {
|
|
@@ -436,12 +438,13 @@ export class SelectionDialogs {
|
|
|
436
438
|
return; // Skip configured buckets if only allowing new ones
|
|
437
439
|
}
|
|
438
440
|
|
|
439
|
-
choices.push({
|
|
440
|
-
name: ` ${name}`,
|
|
441
|
-
value: bucket.$id,
|
|
442
|
-
short: bucket.name,
|
|
443
|
-
|
|
444
|
-
|
|
441
|
+
choices.push({
|
|
442
|
+
name: ` ${name}`,
|
|
443
|
+
value: bucket.$id,
|
|
444
|
+
short: bucket.name,
|
|
445
|
+
// Do not preselect anything unless explicitly provided
|
|
446
|
+
checked: defaultSelected.includes(bucket.$id)
|
|
447
|
+
});
|
|
445
448
|
});
|
|
446
449
|
}
|
|
447
450
|
});
|
|
@@ -480,12 +483,13 @@ export class SelectionDialogs {
|
|
|
480
483
|
return; // Skip configured buckets if only allowing new ones
|
|
481
484
|
}
|
|
482
485
|
|
|
483
|
-
choices.push({
|
|
484
|
-
name,
|
|
485
|
-
value: bucket.$id,
|
|
486
|
-
short: bucket.name,
|
|
487
|
-
|
|
488
|
-
|
|
486
|
+
choices.push({
|
|
487
|
+
name,
|
|
488
|
+
value: bucket.$id,
|
|
489
|
+
short: bucket.name,
|
|
490
|
+
// Do not preselect anything unless explicitly provided
|
|
491
|
+
checked: defaultSelected.includes(bucket.$id)
|
|
492
|
+
});
|
|
489
493
|
});
|
|
490
494
|
}
|
|
491
495
|
|
|
@@ -520,8 +524,37 @@ export class SelectionDialogs {
|
|
|
520
524
|
/**
|
|
521
525
|
* Shows final confirmation dialog with sync selection summary
|
|
522
526
|
*/
|
|
523
|
-
static async confirmSyncSelection(
|
|
524
|
-
|
|
527
|
+
static async confirmSyncSelection(
|
|
528
|
+
selectionSummary: SyncSelectionSummary,
|
|
529
|
+
operationType: 'push' | 'pull' | 'sync' = 'sync'
|
|
530
|
+
): Promise<boolean> {
|
|
531
|
+
const labels = {
|
|
532
|
+
push: {
|
|
533
|
+
banner: "Push Selection Summary",
|
|
534
|
+
subtitle: "Review selections before pushing to Appwrite",
|
|
535
|
+
confirm: "Proceed with push operation?",
|
|
536
|
+
success: "Push operation confirmed.",
|
|
537
|
+
cancel: "Push operation cancelled."
|
|
538
|
+
},
|
|
539
|
+
pull: {
|
|
540
|
+
banner: "Pull Selection Summary",
|
|
541
|
+
subtitle: "Review selections before pulling from Appwrite",
|
|
542
|
+
confirm: "Proceed with pull operation?",
|
|
543
|
+
success: "Pull operation confirmed.",
|
|
544
|
+
cancel: "Pull operation cancelled."
|
|
545
|
+
},
|
|
546
|
+
sync: {
|
|
547
|
+
banner: "Sync Selection Summary",
|
|
548
|
+
subtitle: "Review your selections before proceeding",
|
|
549
|
+
confirm: "Proceed with sync operation?",
|
|
550
|
+
success: "Sync operation confirmed.",
|
|
551
|
+
cancel: "Sync operation cancelled."
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
const label = labels[operationType];
|
|
556
|
+
|
|
557
|
+
MessageFormatter.banner(label.banner, label.subtitle);
|
|
525
558
|
|
|
526
559
|
// Database summary
|
|
527
560
|
console.log(chalk.bold.cyan("\nš Databases:"));
|
|
@@ -563,20 +596,20 @@ export class SelectionDialogs {
|
|
|
563
596
|
const { confirmed } = await inquirer.prompt([{
|
|
564
597
|
type: 'confirm',
|
|
565
598
|
name: 'confirmed',
|
|
566
|
-
message: chalk.green.bold(
|
|
599
|
+
message: chalk.green.bold(label.confirm),
|
|
567
600
|
default: true
|
|
568
601
|
}]);
|
|
569
602
|
|
|
570
603
|
if (confirmed) {
|
|
571
|
-
MessageFormatter.success(
|
|
572
|
-
logger.info(
|
|
604
|
+
MessageFormatter.success(label.success, { skipLogging: true });
|
|
605
|
+
logger.info(`${operationType} selection confirmed`, {
|
|
573
606
|
databases: selectionSummary.totalDatabases,
|
|
574
607
|
tables: selectionSummary.totalTables,
|
|
575
608
|
buckets: selectionSummary.totalBuckets
|
|
576
609
|
});
|
|
577
610
|
} else {
|
|
578
|
-
MessageFormatter.warning(
|
|
579
|
-
logger.info(
|
|
611
|
+
MessageFormatter.warning(label.cancel, { skipLogging: true });
|
|
612
|
+
logger.info(`${operationType} selection cancelled by user`);
|
|
580
613
|
}
|
|
581
614
|
|
|
582
615
|
return confirmed;
|
|
@@ -713,4 +746,4 @@ export class SelectionDialogs {
|
|
|
713
746
|
MessageFormatter.success(message, { skipLogging: true });
|
|
714
747
|
logger.info(`Selection dialog success: ${message}`);
|
|
715
748
|
}
|
|
716
|
-
}
|
|
749
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import fs from "fs";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
CollectionCreateSchema,
|
|
5
|
+
type CollectionCreate,
|
|
6
|
+
type Collection
|
|
7
|
+
} from "appwrite-utils";
|
|
4
8
|
import { register } from "tsx/esm/api";
|
|
5
9
|
import { pathToFileURL } from "node:url";
|
|
6
10
|
import yaml from "js-yaml";
|
|
@@ -216,7 +220,7 @@ export const loadYamlCollection = (filePath: string): CollectionCreate | null =>
|
|
|
216
220
|
const parsedCollection = YamlCollectionSchema.parse(yamlData);
|
|
217
221
|
|
|
218
222
|
// Convert YAML collection to CollectionCreate format
|
|
219
|
-
const
|
|
223
|
+
const collectionInput: CollectionCreate = {
|
|
220
224
|
name: parsedCollection.name,
|
|
221
225
|
$id: parsedCollection.id || parsedCollection.name.toLowerCase().replace(/\s+/g, '_'),
|
|
222
226
|
documentSecurity: parsedCollection.documentSecurity,
|
|
@@ -241,7 +245,7 @@ export const loadYamlCollection = (filePath: string): CollectionCreate | null =>
|
|
|
241
245
|
twoWayKey: attr.twoWayKey,
|
|
242
246
|
onDelete: attr.onDelete as any,
|
|
243
247
|
side: attr.side as any,
|
|
244
|
-
|
|
248
|
+
encrypt: (attr as any).encrypt,
|
|
245
249
|
format: (attr as any).format
|
|
246
250
|
})),
|
|
247
251
|
indexes: parsedCollection.indexes.map(idx => ({
|
|
@@ -253,6 +257,8 @@ export const loadYamlCollection = (filePath: string): CollectionCreate | null =>
|
|
|
253
257
|
importDefs: parsedCollection.importDefs && Array.isArray(parsedCollection.importDefs) && parsedCollection.importDefs.length > 0 ? parsedCollection.importDefs : []
|
|
254
258
|
};
|
|
255
259
|
|
|
260
|
+
const collection = CollectionCreateSchema.parse(collectionInput);
|
|
261
|
+
|
|
256
262
|
return collection;
|
|
257
263
|
} catch (error) {
|
|
258
264
|
MessageFormatter.error(`Error loading YAML collection from ${filePath}`, error as Error, { prefix: "Config" });
|