appwrite-utils-cli 0.0.274 → 0.0.275

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.
Files changed (77) hide show
  1. package/README.md +4 -39
  2. package/dist/init.d.ts +2 -0
  3. package/dist/init.js +57 -0
  4. package/dist/main.js +62 -100
  5. package/dist/migrations/afterImportActions.d.ts +1 -4
  6. package/dist/migrations/afterImportActions.js +1 -0
  7. package/dist/migrations/appwriteToX.d.ts +46 -46
  8. package/dist/migrations/appwriteToX.js +6 -2
  9. package/dist/migrations/attributes.d.ts +1 -1
  10. package/dist/migrations/attributes.js +97 -71
  11. package/dist/migrations/backup.d.ts +240 -240
  12. package/dist/migrations/backup.js +1 -1
  13. package/dist/migrations/collections.d.ts +1 -1
  14. package/dist/migrations/collections.js +4 -4
  15. package/dist/migrations/converters.d.ts +9 -127
  16. package/dist/migrations/converters.js +1 -504
  17. package/dist/migrations/dataLoader.d.ts +470 -453
  18. package/dist/migrations/dataLoader.js +19 -1
  19. package/dist/migrations/dbHelpers.d.ts +1 -1
  20. package/dist/migrations/dbHelpers.js +3 -0
  21. package/dist/migrations/importController.d.ts +1 -1
  22. package/dist/migrations/importController.js +4 -7
  23. package/dist/migrations/importDataActions.d.ts +4 -6
  24. package/dist/migrations/importDataActions.js +6 -4
  25. package/dist/migrations/indexes.d.ts +1 -1
  26. package/dist/migrations/indexes.js +1 -1
  27. package/dist/migrations/migrationHelper.d.ts +29 -29
  28. package/dist/migrations/migrationHelper.js +1 -1
  29. package/dist/migrations/openapi.d.ts +1 -1
  30. package/dist/migrations/openapi.js +4 -1
  31. package/dist/migrations/queue.d.ts +1 -1
  32. package/dist/migrations/relationships.d.ts +5 -5
  33. package/dist/migrations/relationships.js +3 -0
  34. package/dist/migrations/schemaStrings.d.ts +2 -2
  35. package/dist/migrations/schemaStrings.js +93 -8
  36. package/dist/migrations/setupDatabase.d.ts +1 -1
  37. package/dist/migrations/setupDatabase.js +1 -1
  38. package/dist/migrations/storage.d.ts +1 -1
  39. package/dist/migrations/users.d.ts +1 -1
  40. package/dist/schemas/authUser.d.ts +12 -10
  41. package/dist/types.d.ts +0 -5
  42. package/dist/types.js +0 -2
  43. package/dist/utils/helperFunctions.d.ts +2 -3
  44. package/dist/utils/loadConfigs.d.ts +13 -0
  45. package/dist/utils/loadConfigs.js +47 -0
  46. package/dist/utils/setupFiles.d.ts +1 -0
  47. package/dist/utils/setupFiles.js +98 -223
  48. package/dist/utilsController.d.ts +1 -3
  49. package/dist/utilsController.js +14 -18
  50. package/package.json +9 -2
  51. package/src/init.ts +64 -0
  52. package/src/main.ts +73 -98
  53. package/src/migrations/afterImportActions.ts +1 -5
  54. package/src/migrations/appwriteToX.ts +6 -2
  55. package/src/migrations/attributes.ts +198 -150
  56. package/src/migrations/backup.ts +1 -1
  57. package/src/migrations/collections.ts +5 -11
  58. package/src/migrations/converters.ts +1 -540
  59. package/src/migrations/dataLoader.ts +19 -2
  60. package/src/migrations/dbHelpers.ts +4 -1
  61. package/src/migrations/importController.ts +5 -15
  62. package/src/migrations/importDataActions.ts +10 -14
  63. package/src/migrations/indexes.ts +1 -1
  64. package/src/migrations/migrationHelper.ts +1 -1
  65. package/src/migrations/openapi.ts +4 -1
  66. package/src/migrations/queue.ts +1 -1
  67. package/src/migrations/relationships.ts +4 -1
  68. package/src/migrations/schemaStrings.ts +106 -9
  69. package/src/migrations/setupDatabase.ts +1 -1
  70. package/src/migrations/storage.ts +1 -1
  71. package/src/migrations/users.ts +1 -1
  72. package/src/types.ts +0 -5
  73. package/src/utils/helperFunctions.ts +2 -3
  74. package/src/utils/loadConfigs.ts +55 -0
  75. package/src/utils/setupFiles.ts +114 -225
  76. package/src/utilsController.ts +27 -35
  77. package/src/migrations/schema.ts +0 -748
@@ -5,22 +5,18 @@ import {
5
5
  type Databases,
6
6
  type Storage,
7
7
  } from "node-appwrite";
8
- import type { AppwriteConfig } from "./schema.js";
9
- import { validationRules, type ValidationRules } from "./validationRules.js";
8
+ import type { AppwriteConfig } from "appwrite-utils";
10
9
  import {
11
- converterFunctions,
12
- convertObjectBySchema,
13
- type ConverterFunctions,
14
- } from "./converters.js";
15
- import {
16
- afterImportActions,
17
- type AfterImportActions,
18
- } from "./afterImportActions.js";
10
+ validationRules,
11
+ type ValidationRules,
12
+ type AttributeMappings,
13
+ } from "appwrite-utils";
14
+ import { converterFunctions, type ConverterFunctions } from "appwrite-utils";
15
+ import { convertObjectBySchema } from "./converters.js";
16
+ import { type AfterImportActions } from "appwrite-utils";
17
+ import { afterImportActions } from "./afterImportActions.js";
19
18
  import { logger } from "./logging.js";
20
19
 
21
- type AttributeMappings =
22
- AppwriteConfig["collections"][number]["importDefs"][number]["attributeMappings"];
23
-
24
20
  export class ImportDataActions {
25
21
  private db: Databases;
26
22
  private storage: Storage;
@@ -48,7 +44,7 @@ export class ImportDataActions {
48
44
  runConverterFunctions(item: any, attributeMappings: AttributeMappings) {
49
45
  const conversionSchema = attributeMappings.reduce((schema, mapping) => {
50
46
  schema[mapping.targetKey] = (originalValue: any) => {
51
- return mapping.converters.reduce((value, converterName) => {
47
+ return mapping.converters?.reduce((value, converterName) => {
52
48
  let shouldProcessAsArray = false;
53
49
  if (
54
50
  (converterName.includes("[Arr]") ||
@@ -1,4 +1,4 @@
1
- import { indexSchema, type Index } from "./schema.js";
1
+ import { indexSchema, type Index } from "appwrite-utils";
2
2
  import { Databases, Query, type Models } from "node-appwrite";
3
3
  // import {}
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { ID, Query, type Databases } from "node-appwrite";
2
2
  import { BatchSchema, OperationSchema, type Operation } from "./backup.js";
3
- import { type AttributeMappings, AttributeMappingsSchema } from "./schema.js";
3
+ import { AttributeMappingsSchema } from "appwrite-utils";
4
4
  import { z } from "zod";
5
5
  import { logger } from "./logging.js";
6
6
 
@@ -10,13 +10,16 @@ import {
10
10
  type Attribute,
11
11
  type Collection,
12
12
  type CollectionCreate,
13
- } from "./schema.js";
13
+ } from "appwrite-utils";
14
14
  import { z } from "zod";
15
15
  import { writeFileSync } from "fs";
16
16
 
17
17
  const registry = new OpenAPIRegistry();
18
18
 
19
19
  export const generateOpenApi = async (config: AppwriteConfig) => {
20
+ if (!config.collections) {
21
+ return;
22
+ }
20
23
  for (const collection of config.collections) {
21
24
  // Transform and register each attribute schema
22
25
  const attributeSchemas = collection.attributes.map((attribute) => {
@@ -1,5 +1,5 @@
1
1
  import { Query, type Databases, type Models } from "node-appwrite";
2
- import type { Attribute } from "./schema.js";
2
+ import type { Attribute } from "appwrite-utils";
3
3
  import { createOrUpdateAttribute } from "./attributes.js";
4
4
  import _ from "lodash";
5
5
  import { fetchAndCacheCollectionByName } from "./collections.js";
@@ -4,7 +4,7 @@ import type {
4
4
  AppwriteConfig,
5
5
  Attribute,
6
6
  RelationshipAttribute,
7
- } from "./schema.js";
7
+ } from "appwrite-utils";
8
8
  import { logger } from "./logging.js";
9
9
 
10
10
  /**
@@ -12,6 +12,9 @@ import { logger } from "./logging.js";
12
12
  */
13
13
  export const findCollectionsWithRelationships = (config: AppwriteConfig) => {
14
14
  const toReturn = new Map<string, RelationshipAttribute[]>();
15
+ if (!config.collections) {
16
+ return toReturn;
17
+ }
15
18
  for (const collection of config.collections) {
16
19
  if (collection.attributes) {
17
20
  for (const attribute of collection.attributes) {
@@ -3,7 +3,7 @@ import type {
3
3
  AppwriteConfig,
4
4
  Attribute,
5
5
  RelationshipAttribute,
6
- } from "./schema.js";
6
+ } from "appwrite-utils";
7
7
  import { z } from "zod";
8
8
  import fs from "fs";
9
9
  import path from "path";
@@ -30,17 +30,111 @@ export class SchemaGenerator {
30
30
  this.extractRelationships();
31
31
  }
32
32
 
33
- public updateYamlSchemas(): void {
34
- // Output this.config to a YAML file at appwriteFolderPath/appwriteConfig.yaml
35
- let finalConfig = this.config;
36
- finalConfig.appwriteClient = null;
37
- const yamlConfig = finalConfig;
38
- const yamlPath = path.join(this.appwriteFolderPath, "appwriteConfig.yaml");
39
- fs.writeFileSync(yamlPath, dump(yamlConfig), { encoding: "utf-8" });
40
- console.log(`YAML written to ${yamlPath}`);
33
+ public updateTsSchemas(): void {
34
+ const collections = this.config.collections;
35
+ delete this.config.collections;
36
+
37
+ const configPath = path.join(this.appwriteFolderPath, "appwriteConfig.ts");
38
+ const configContent = `import { AppwriteConfig } from "appwrite-utils";
39
+
40
+ const appwriteConfig: AppwriteConfig = {
41
+ appwriteEndpoint: "${this.config.appwriteEndpoint}",
42
+ appwriteProject: "${this.config.appwriteProject}",
43
+ appwriteKey: "${this.config.appwriteKey}",
44
+ enableDevDatabase: ${this.config.enableDevDatabase},
45
+ enableBackups: ${this.config.enableBackups},
46
+ backupInterval: ${this.config.backupInterval},
47
+ backupRetention: ${this.config.backupRetention},
48
+ enableBackupCleanup: ${this.config.enableBackupCleanup},
49
+ enableMockData: ${this.config.enableMockData},
50
+ enableWipeOtherDatabases: ${this.config.enableWipeOtherDatabases},
51
+ documentBucketId: "${this.config.documentBucketId}",
52
+ usersCollectionName: "${this.config.usersCollectionName}",
53
+ databases: ${JSON.stringify(this.config.databases)}
54
+ };
55
+
56
+ export default appwriteConfig;
57
+ `;
58
+ fs.writeFileSync(configPath, configContent, { encoding: "utf-8" });
59
+
60
+ const collectionsFolderPath = path.join(
61
+ this.appwriteFolderPath,
62
+ "collections"
63
+ );
64
+ if (!fs.existsSync(collectionsFolderPath)) {
65
+ fs.mkdirSync(collectionsFolderPath, { recursive: true });
66
+ }
67
+
68
+ collections?.forEach((collection) => {
69
+ const { databaseId, ...collectionWithoutDbId } = collection; // Destructure to exclude databaseId
70
+ const collectionFilePath = path.join(
71
+ collectionsFolderPath,
72
+ `${collection.name}.ts`
73
+ );
74
+ const collectionContent = `import { CollectionCreate } from "appwrite-utils";
75
+
76
+ const ${collection.name}Config: Partial<CollectionCreate> = {
77
+ name: "${collection.name}",
78
+ $id: "${collection.$id}",
79
+ enabled: ${collection.enabled},
80
+ documentSecurity: ${collection.documentSecurity},
81
+ $permissions: [
82
+ ${collection.$permissions
83
+ .map(
84
+ (permission) =>
85
+ `{ permission: "${permission.permission}", target: "${permission.target}" }`
86
+ )
87
+ .join(",\n ")}
88
+ ],
89
+ attributes: [
90
+ ${collection.attributes
91
+ .map((attr) => {
92
+ return `{ ${Object.entries(attr)
93
+ .map(([key, value]) => {
94
+ // Check the type of the value and format it accordingly
95
+ if (typeof value === "string") {
96
+ // If the value is a string, wrap it in quotes
97
+ return `${key}: "${value.replace(/"/g, '\\"')}"`; // Escape existing quotes in the string
98
+ } else if (Array.isArray(value)) {
99
+ // If the value is an array, join it with commas
100
+ return `${key}: [${value
101
+ .map((item) => `"${item}"`)
102
+ .join(", ")}]`;
103
+ } else {
104
+ // If the value is not a string (e.g., boolean or number), output it directly
105
+ return `${key}: ${value}`;
106
+ }
107
+ })
108
+ .join(", ")} }`;
109
+ })
110
+ .join(",\n ")}
111
+ ],
112
+ indexes: [
113
+ ${(
114
+ collection.indexes?.map((index) => {
115
+ // Map each attribute to ensure it is properly quoted
116
+ const formattedAttributes = index.attributes
117
+ .map((attr) => `"${attr}"`)
118
+ .join(", ");
119
+ return `{ key: "${index.key}", type: "${index.type}", attributes: [${formattedAttributes}] }`;
120
+ }) ?? []
121
+ ).join(",\n ")}
122
+ ]
123
+ };
124
+
125
+ export default ${collection.name}Config;
126
+ `;
127
+ fs.writeFileSync(collectionFilePath, collectionContent, {
128
+ encoding: "utf-8",
129
+ });
130
+ console.log(`Collection schema written to ${collectionFilePath}`);
131
+ });
41
132
  }
42
133
 
43
134
  private extractRelationships(): void {
135
+ if (!this.config.collections) {
136
+ return;
137
+ }
44
138
  this.config.collections.forEach((collection) => {
45
139
  collection.attributes.forEach((attr) => {
46
140
  if (attr.type === "relationship" && attr.twoWay && attr.twoWayKey) {
@@ -115,6 +209,9 @@ export class SchemaGenerator {
115
209
  }
116
210
 
117
211
  public generateSchemas(): void {
212
+ if (!this.config.collections) {
213
+ return;
214
+ }
118
215
  this.config.collections.forEach((collection) => {
119
216
  const schemaString = this.createSchemaString(
120
217
  collection.name,
@@ -13,7 +13,7 @@ import {
13
13
  initOrGetDocumentStorage,
14
14
  wipeDocumentStorage,
15
15
  } from "./storage.js";
16
- import { type AppwriteConfig } from "./schema.js";
16
+ import { type AppwriteConfig } from "appwrite-utils";
17
17
  import type { SetupOptions } from "../utilsController.js";
18
18
  import { nameToIdMapping } from "./queue.js";
19
19
  import { UsersController } from "./users.js";
@@ -9,7 +9,7 @@ import {
9
9
  } from "node-appwrite";
10
10
  import { type OperationCreate, type BackupCreate } from "./backup.js";
11
11
  import { splitIntoBatches } from "./migrationHelper.js";
12
- import type { AppwriteConfig } from "./schema.js";
12
+ import type { AppwriteConfig } from "appwrite-utils";
13
13
 
14
14
  export const logOperation = async (
15
15
  db: Databases,
@@ -1,4 +1,4 @@
1
- import type { AppwriteConfig, ConfigCollection } from "./schema.js";
1
+ import type { AppwriteConfig, ConfigCollection } from "appwrite-utils";
2
2
  import { Databases, ID, Query, Users, type Models } from "node-appwrite";
3
3
  import {
4
4
  AuthUserSchema,
package/src/types.ts CHANGED
@@ -1,14 +1,9 @@
1
- export type { AppwriteConfig } from "./migrations/schema.js";
2
- export type { ConverterFunctions } from "./migrations/converters.js";
3
1
  export type { ValidationRules } from "./migrations/validationRules.js";
4
- export type { AfterImportActions } from "./migrations/afterImportActions.js";
5
2
  export {
6
3
  type AuthUserCreate,
7
4
  AuthUserCreateSchema,
8
5
  type AuthUser,
9
6
  AuthUserSchema,
10
7
  } from "./schemas/authUser.js";
11
- export { getFileViewUrl, getFileDownloadUrl } from "./utils/helperFunctions.js";
12
- export { converterFunctions } from "./migrations/converters.js";
13
8
  export { validationRules } from "./migrations/validationRules.js";
14
9
  export { afterImportActions } from "./migrations/afterImportActions.js";
@@ -1,9 +1,8 @@
1
- import type { AppwriteConfig } from "../types.js";
2
1
  import type { Models, Storage } from "node-appwrite";
3
2
  import fs from "node:fs";
4
3
  import path from "node:path";
5
- import type { CollectionImportData } from "src/migrations/dataLoader.js";
6
- import type { ConfigCollection } from "src/migrations/schema.js";
4
+ import type { CollectionImportData } from "../migrations/dataLoader.js";
5
+ import type { ConfigCollection } from "appwrite-utils";
7
6
 
8
7
  export const toPascalCase = (str: string): string => {
9
8
  return (
@@ -0,0 +1,55 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import { type AppwriteConfig, type Collection } from "appwrite-utils";
4
+ import { register } from "tsx/esm/api"; // Import the register function
5
+
6
+ /**
7
+ * Recursively searches for a file named 'appwriteConfig.ts' starting from the given directory.
8
+ * @param dir The directory to start the search from.
9
+ * @returns The path to the file if found, or null if not found.
10
+ */
11
+ export const findAppwriteConfig = (dir: string): string | null => {
12
+ const files = fs.readdirSync(dir, { withFileTypes: true });
13
+
14
+ for (const file of files) {
15
+ if (file.isDirectory()) {
16
+ const result = findAppwriteConfig(path.join(dir, file.name));
17
+ if (result) return result;
18
+ } else if (file.name === "appwriteConfig.ts") {
19
+ return path.join(dir, file.name);
20
+ }
21
+ }
22
+
23
+ return null;
24
+ };
25
+
26
+ /**
27
+ * Loads the Appwrite configuration and all collection configurations from a specified directory.
28
+ * @param configDir The directory containing the appwriteConfig.ts and collections folder.
29
+ * @returns The loaded Appwrite configuration including collections.
30
+ */
31
+ export const loadConfig = async (
32
+ configDir: string
33
+ ): Promise<AppwriteConfig> => {
34
+ const unregister = register(); // Register tsx enhancement
35
+
36
+ try {
37
+ const configPath = path.resolve(configDir, "appwriteConfig.ts");
38
+ const config = (await import(configPath)).default as AppwriteConfig;
39
+
40
+ const collectionsDir = path.resolve(configDir, "collections");
41
+ const collectionFiles = fs.readdirSync(collectionsDir);
42
+
43
+ config.collections = [];
44
+
45
+ for (const file of collectionFiles) {
46
+ const filePath = path.resolve(collectionsDir, file);
47
+ const collectionModule = (await import(filePath)).default as Collection;
48
+ config.collections.push(collectionModule);
49
+ }
50
+
51
+ return config;
52
+ } finally {
53
+ unregister(); // Unregister tsx when done
54
+ }
55
+ };