appwrite-utils-cli 0.0.273 → 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 +5 -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 +98 -70
  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 +5 -5
  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 -145
  56. package/src/migrations/backup.ts +1 -1
  57. package/src/migrations/collections.ts +6 -12
  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
@@ -0,0 +1,47 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import {} from "appwrite-utils";
4
+ import { register } from "tsx/esm/api"; // Import the register function
5
+ /**
6
+ * Recursively searches for a file named 'appwriteConfig.ts' starting from the given directory.
7
+ * @param dir The directory to start the search from.
8
+ * @returns The path to the file if found, or null if not found.
9
+ */
10
+ export const findAppwriteConfig = (dir) => {
11
+ const files = fs.readdirSync(dir, { withFileTypes: true });
12
+ for (const file of files) {
13
+ if (file.isDirectory()) {
14
+ const result = findAppwriteConfig(path.join(dir, file.name));
15
+ if (result)
16
+ return result;
17
+ }
18
+ else if (file.name === "appwriteConfig.ts") {
19
+ return path.join(dir, file.name);
20
+ }
21
+ }
22
+ return null;
23
+ };
24
+ /**
25
+ * Loads the Appwrite configuration and all collection configurations from a specified directory.
26
+ * @param configDir The directory containing the appwriteConfig.ts and collections folder.
27
+ * @returns The loaded Appwrite configuration including collections.
28
+ */
29
+ export const loadConfig = async (configDir) => {
30
+ const unregister = register(); // Register tsx enhancement
31
+ try {
32
+ const configPath = path.resolve(configDir, "appwriteConfig.ts");
33
+ const config = (await import(configPath)).default;
34
+ const collectionsDir = path.resolve(configDir, "collections");
35
+ const collectionFiles = fs.readdirSync(collectionsDir);
36
+ config.collections = [];
37
+ for (const file of collectionFiles) {
38
+ const filePath = path.resolve(collectionsDir, file);
39
+ const collectionModule = (await import(filePath)).default;
40
+ config.collections.push(collectionModule);
41
+ }
42
+ return config;
43
+ }
44
+ finally {
45
+ unregister(); // Unregister tsx when done
46
+ }
47
+ };
@@ -1,2 +1,3 @@
1
1
  export declare const customDefinitionsFile = "import type { ConverterFunctions, ValidationRules, AfterImportActions } from \"appwrite-utils\";\n\nexport const customConverterFunctions: ConverterFunctions = {\n // Add your custom converter functions here\n}\nexport const customValidationRules: ValidationRules = {\n // Add your custom validation rules here\n}\nexport const customAfterImportActions: AfterImportActions = {\n // Add your custom after import actions here\n}";
2
+ export declare const createEmptyCollection: (collectionName: string) => void;
2
3
  export declare const setupDirsFiles: (example?: boolean) => Promise<void>;
@@ -1,222 +1,59 @@
1
1
  import { mkdirSync, writeFileSync, existsSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import configSchema from "./configSchema.json" assert { type: "json" };
4
+ import { findAppwriteConfig } from "./loadConfigs.js";
5
+ // Example base configuration using types from appwrite-utils
6
+ const baseConfig = {
7
+ appwriteEndpoint: "https://cloud.appwrite.io/v1",
8
+ appwriteProject: "YOUR_PROJECT_ID",
9
+ appwriteKey: "YOUR_API_KEY",
10
+ enableDevDatabase: true,
11
+ enableBackups: true,
12
+ backupInterval: 3600,
13
+ backupRetention: 30,
14
+ enableBackupCleanup: true,
15
+ enableMockData: false,
16
+ enableWipeOtherDatabases: true,
17
+ documentBucketId: "documents",
18
+ usersCollectionName: "Members",
19
+ databases: [
20
+ { $id: "main", name: "Main" },
21
+ { $id: "staging", name: "Staging" },
22
+ { $id: "dev", name: "Development" },
23
+ ],
24
+ };
25
+ const collectionsConfig = [
26
+ {
27
+ name: "ExampleCollection",
28
+ content: `import { CollectionCreate } from "appwrite-utils";
29
+
30
+ const ExampleCollection: Partial<CollectionCreate> = {
31
+ name: 'ExampleCollection',
32
+ $permissions: [
33
+ { permission: 'read', target: 'any' },
34
+ { permission: 'create', target: 'users' },
35
+ { permission: 'update', target: 'users' },
36
+ { permission: 'delete', target: 'users' }
37
+ ],
38
+ attributes: [
39
+ { key: 'alterEgoName', type: 'string', size: 255, required: false },
40
+ // Add more attributes here
41
+ ],
42
+ indexes: [
43
+ { key: 'alterEgoName_search', type: 'fulltext', attributes: ['alterEgoName'] }
44
+ ],
45
+ importDefs: [
46
+ // Define import definitions here
47
+ ]
48
+ };
49
+
50
+ export default ExampleCollection;`,
51
+ },
52
+ // Add more collections here
53
+ ];
4
54
  // Define our YAML files
5
55
  // Define our YAML files
6
- const configFileExample = `# yaml-language-server: $schema=./.appwrite/appwriteUtilsConfigSchema.json
7
- # Appwrite configuration settings
8
- appwriteEndpoint: 'https://cloud.appwrite.io/v1' # Your Appwrite endpoint. Default: 'https://cloud.appwrite.io/v1'
9
- appwriteProject: 'YOUR_PROJECT_ID' # Your Appwrite project ID
10
- appwriteKey: 'YOUR_API_KEY' # Your Appwrite API key (needs storage and databases at minimum)
11
- appwriteClient: null # Your Appwrite client -- don't worry about this
12
- enableDevDatabase: true # Enable development database alongside main
13
- enableBackups: true # Enable backups
14
- backupInterval: 3600 # Backup interval in seconds
15
- backupRetention: 30 # Backup retention in days
16
- enableBackupCleanup: true # Enable backup cleanup
17
- enableMockData: false # Enable mock data generation
18
- enableWipeOtherDatabases: true # Enable wiping other databases
19
- documentBucketId: 'documents' # Your Appwrite bucket ID for documents
20
- usersCollectionName: 'Members' # Your Appwrite collection for any extra info while importing members (if any)
21
- # This allows you to use any targetKey in the users field to create your user
22
- # these are: name, email, phone, labels, prefs, password, userId and (not yet added)
23
- # $createdAt, $updatedAt -- Add them to your attributeMappings (NOT attributes) to define them and set the
24
- # targetKey to the same as the Appwrite targetKey
25
- databases:
26
- - $id: 'main'
27
- name: 'Main'
28
- - $id: 'staging'
29
- name: 'Staging'
30
- - $id: 'dev'
31
- name: 'Development'
32
- collections:
33
- - name: 'Members'
34
- $permissions:
35
- - permission: read
36
- target: any
37
- - permission: create
38
- target: users
39
- - permission: update
40
- target: users
41
- - permission: delete
42
- target: users
43
- attributes:
44
- - key: 'idOrig'
45
- type: 'string'
46
- size: 255
47
- required: false
48
- - key: 'dogs'
49
- type: 'relationship'
50
- relatedCollection: 'Dogs'
51
- relationType: 'oneToMany'
52
- twoWay: true
53
- twoWayKey: 'owner'
54
- side: 'parent'
55
- onDelete: 'cascade'
56
- importMapping: { originalIdField: 'idOrig', targetField: 'ownerIdOrig' }
57
- - key: 'dogIds'
58
- type: 'string'
59
- size: 255
60
- array: true
61
- - key: 'profilePhoto'
62
- type: 'string'
63
- size: 255
64
- required: false
65
- - key: 'profilePhotoTest'
66
- type: 'string'
67
- size: 255
68
- required: false
69
- indexes:
70
- - key: 'idOrig_index'
71
- type: 'key'
72
- attributes: ['idOrig']
73
- importDefs:
74
- - filePath: 'importData/members.json'
75
- basePath: 'RECORDS'
76
- attributeMappings:
77
- - oldKey: 'id'
78
- targetKey: 'idOrig'
79
- converters: ['anyToString']
80
- postImportActions:
81
- - action: 'checkAndUpdateFieldInDocument'
82
- params:
83
- - "{dbId}"
84
- - "{collId}"
85
- - "{docId}"
86
- - "idOrig"
87
- - "{id}"
88
- - "{$id}"
89
- - oldKey: 'name'
90
- targetKey: 'name'
91
- - oldKey: 'email'
92
- targetKey: 'email'
93
- - oldKey: 'doesntMatter'
94
- targetKey: 'profilePhoto'
95
- fileData: { name: "profilePhoto_{id}", path: "importData/profilePhotos" }
96
- - oldKey: 'photoUrl'
97
- targetKey: 'profilePhotoTest'
98
- fileData: { name: "profilePhotoTest_{id}", path: "{photoUrl}" }
99
- - name: 'Dogs'
100
- $permissions:
101
- - permission: read
102
- target: any
103
- - permission: create
104
- target: users
105
- - permission: update
106
- target: users
107
- - permission: delete
108
- target: users
109
- attributes:
110
- - key: 'name'
111
- type: 'string'
112
- size: 255
113
- required: true
114
- - key: 'breed'
115
- type: 'string'
116
- size: 255
117
- required: false
118
- - key: 'age'
119
- type: 'integer'
120
- required: false
121
- min: 0
122
- max: 100
123
- - key: 'idOrig'
124
- type: 'string'
125
- size: 20
126
- required: false
127
- - key: 'ownerIdOrig'
128
- type: 'string'
129
- size: 255
130
- required: false
131
- - key: 'vetRecords'
132
- type: 'string'
133
- size: 255
134
- required: false
135
- - key: 'vetRecordIds'
136
- type: 'string'
137
- size: 255
138
- array: true
139
- required: false
140
- indexes:
141
- - key: 'ownerIdIndex'
142
- type: 'key'
143
- attributes: ['ownerIdOrig']
144
- importDefs:
145
- - filePath: 'importData/dogs.json'
146
- basePath: 'RECORDS'
147
- attributeMappings:
148
- - oldKey: 'id'
149
- targetKey: 'idOrig'
150
- - oldKey: 'name'
151
- targetKey: 'name'
152
- - oldKey: 'breed'
153
- targetKey: 'breed'
154
- - oldKey: 'age'
155
- targetKey: 'age'
156
- - oldKey: 'ownerId'
157
- targetKey: 'ownerIdOrig'
158
- - oldKey: 'vetRecords'
159
- targetKey: 'vetRecords'
160
- converters: ['stringifyObject']
161
- - oldKey: 'vetRecords.[any].id'
162
- targetKey: 'vetRecordIds'
163
- converters: ['anyToString']
164
- - filePath: 'importData/dogs.json'
165
- basePath: 'RECORDS'
166
- type: 'update'
167
- updateMapping: { originalIdField: 'id', targetField: 'idOrig' }
168
- attributeMappings:
169
- - oldKey: 'name'
170
- targetKey: 'name'
171
- - oldKey: 'breed'
172
- targetKey: 'breed'
173
- - oldKey: 'age'
174
- targetKey: 'age'`;
175
- const configFile = `# yaml-language-server: $schema=./.appwrite/appwriteUtilsConfigSchema.json
176
- # Basic Appwrite configuration settings
177
- appwriteEndpoint: 'https://cloud.appwrite.io/v1' # Your Appwrite endpoint
178
- appwriteProject: 'YOUR_PROJECT_ID' # Your Appwrite project ID
179
- appwriteKey: 'YOUR_API_KEY' # Your Appwrite API key (needs storage and databases at minimum)
180
- enableDevDatabase: true # Enable development database alongside main. Default: true
181
- enableBackups: true # Enable backups. Default: true
182
- backupInterval: 3600 # Backup interval in seconds. Default: 3600 - DOES NOTHING RIGHT NOW
183
- backupRetention: 30 # Backup retention in days. Default: 30 - DOES NOTHING RIGHT NOW
184
- enableBackupCleanup: true # Enable backup cleanup. Default: true - DOES NOTHING RIGHT NOW
185
- enableMockData: false # Enable mock data generation. Default: false - DOES NOTHING RIGHT NOW
186
- enableWipeOtherDatabases: true # Enable wiping other databases. Default: true
187
- documentBucketId: 'documents' # Your Appwrite bucket ID for documents. Default: 'documents'
188
- usersCollectionName: 'Members' # Your Appwrite collection for any extra info while importing members (if any). Default: 'Members'
189
- # Databases configuration
190
- # The first one is *always* Production
191
- # The second is *always* Staging
192
- # The third is *always* Development
193
- # They are found by name matching (without spaces and all lowercase), not $id
194
- # If no $id is included for anything defined, Appwrite will auto-generate one in its stead
195
- databases:
196
- - $id: 'main' # Database ID
197
- name: 'Main' # Database name
198
- - $id: 'staging'
199
- name: 'Staging'
200
- - $id: 'dev'
201
- name: 'Development'
202
-
203
- # Collections configuration
204
- collections:
205
- - name: 'ExampleCollection' # Collection name
206
- $permissions: # Permissions for the collection
207
- - permission: read # Permission type
208
- target: any # Permission target
209
- - permission: create
210
- target: users
211
- - permission: update
212
- target: users
213
- - permission: delete
214
- target: users
215
- attributes: # Attributes of the collection
216
- - key: 'exampleKey' # Attribute key
217
- type: 'string' # Attribute type
218
- size: 255 # Size of the attribute (for strings)
219
- required: true # Whether the attribute is required`;
56
+ const configFileExample = `d`;
220
57
  export const customDefinitionsFile = `import type { ConverterFunctions, ValidationRules, AfterImportActions } from "appwrite-utils";
221
58
 
222
59
  export const customConverterFunctions: ConverterFunctions = {
@@ -228,39 +65,77 @@ export const customValidationRules: ValidationRules = {
228
65
  export const customAfterImportActions: AfterImportActions = {
229
66
  // Add your custom after import actions here
230
67
  }`;
68
+ export const createEmptyCollection = (collectionName) => {
69
+ const emptyCollection = `import type { CollectionCreate } from "appwrite-utils";
70
+
71
+ const ${collectionName}: Partial<CollectionCreate> = {
72
+ name: '${collectionName}',
73
+ $permissions: [
74
+ { permission: 'read', target: 'any' },
75
+ { permission: 'create', target: 'users' },
76
+ { permission: 'update', target: 'users' },
77
+ { permission: 'delete', target: 'users' }
78
+ ],
79
+ attributes: [
80
+ // Add more attributes here
81
+ ],
82
+ indexes: [
83
+ // Add more indexes here
84
+ ],
85
+ };
86
+
87
+ export default ${collectionName};`;
88
+ const appwriteConfigPath = findAppwriteConfig(process.cwd());
89
+ if (!appwriteConfigPath) {
90
+ console.error("Failed to find appwriteConfig.ts");
91
+ return;
92
+ }
93
+ const collectionsFolder = path.join(path.dirname(appwriteConfigPath), "collections");
94
+ const collectionFilePath = path.join(collectionsFolder, `${collectionName}.ts`);
95
+ writeFileSync(collectionFilePath, emptyCollection);
96
+ };
231
97
  export const setupDirsFiles = async (example = false) => {
232
98
  const basePath = process.cwd();
233
- const srcPath = path.join(basePath, "src");
99
+ const srcPath = path.join(basePath);
234
100
  // Check if src directory exists in the current working directory
235
101
  if (!existsSync(srcPath)) {
236
102
  console.error("No 'src' directory found in the current working directory.");
237
103
  return;
238
104
  }
239
105
  const appwriteFolder = path.join(srcPath, "appwrite");
240
- const appwriteConfigFile = path.join(appwriteFolder, "appwriteConfig.yaml");
106
+ const appwriteConfigFile = path.join(appwriteFolder, "appwriteConfig.ts");
241
107
  const appwriteCustomDefsFile = path.join(appwriteFolder, "customDefinitions.ts");
242
108
  // const appwriteMigrationsFolder = path.join(appwriteFolder, "migrations");
243
109
  const appwriteSchemaFolder = path.join(appwriteFolder, "schemas");
244
110
  const appwriteDataFolder = path.join(appwriteFolder, "importData");
245
111
  const appwriteHiddenFolder = path.join(appwriteFolder, ".appwrite");
112
+ const collectionsFolder = path.join(appwriteFolder, "collections");
246
113
  // Directory creation and file writing logic remains the same
247
114
  if (!existsSync(appwriteFolder)) {
248
115
  mkdirSync(appwriteFolder, { recursive: true });
249
116
  }
117
+ if (!existsSync(collectionsFolder)) {
118
+ mkdirSync(collectionsFolder, { recursive: true });
119
+ }
250
120
  if (!existsSync(appwriteConfigFile)) {
251
121
  if (example) {
252
122
  writeFileSync(appwriteConfigFile, configFileExample);
253
123
  }
254
124
  else {
255
- writeFileSync(appwriteConfigFile, configFile);
125
+ const baseConfigContent = `import { AppwriteConfig } from "appwrite-utils";
126
+
127
+ const appwriteConfig: AppwriteConfig = ${JSON.stringify(baseConfig, null, 2)};
128
+
129
+ export default appwriteConfig;
130
+ `;
131
+ writeFileSync(appwriteConfigFile, baseConfigContent);
256
132
  }
257
133
  }
258
- // if (!existsSync(appwriteCustomDefsFile)) {
259
- // writeFileSync(appwriteCustomDefsFile, customDefinitionsFile);
260
- // }
261
- // if (!existsSync(appwriteMigrationsFolder)) {
262
- // mkdirSync(appwriteMigrationsFolder, { recursive: true });
263
- // }
134
+ // Create TypeScript files for each collection
135
+ collectionsConfig.forEach((collection) => {
136
+ const collectionFilePath = path.join(collectionsFolder, `${collection.name}.ts`);
137
+ writeFileSync(collectionFilePath, collection.content);
138
+ });
264
139
  if (!existsSync(appwriteSchemaFolder)) {
265
140
  mkdirSync(appwriteSchemaFolder, { recursive: true });
266
141
  }
@@ -1,6 +1,4 @@
1
- import { type ConverterFunctions } from "./migrations/converters.js";
2
- import { type AfterImportActions } from "./migrations/afterImportActions.js";
3
- import { type ValidationRules } from "./migrations/validationRules.js";
1
+ import { type AfterImportActions, type ConverterFunctions, type ValidationRules } from "appwrite-utils";
4
2
  export interface SetupOptions {
5
3
  sync: boolean;
6
4
  runProd: boolean;
@@ -1,26 +1,17 @@
1
1
  import { Client, Databases, Storage } from "node-appwrite";
2
2
  import { startSetup } from "./migrations/setupDatabase.js";
3
- import { AppwriteConfigSchema, } from "./migrations/schema.js";
4
3
  import path from "path";
5
4
  import fs from "fs";
6
5
  import { load } from "js-yaml";
7
6
  import { ImportDataActions } from "./migrations/importDataActions.js";
8
- import { converterFunctions, } from "./migrations/converters.js";
9
7
  import { readFileSync } from "./utils/helperFunctions.js";
10
- import { afterImportActions, } from "./migrations/afterImportActions.js";
11
- import { validationRules, } from "./migrations/validationRules.js";
8
+ import { afterImportActions } from "./migrations/afterImportActions.js";
9
+ import { converterFunctions, validationRules, AppwriteConfigSchema, } from "appwrite-utils";
12
10
  import { ImportController } from "./migrations/importController.js";
13
11
  import _ from "lodash";
14
12
  import { AppwriteToX } from "./migrations/appwriteToX.js";
15
- async function loadConfig(configPath) {
16
- if (!fs.existsSync(configPath)) {
17
- throw new Error(`Configuration file not found at ${configPath}`);
18
- }
19
- const configModule = await load(readFileSync(configPath), {
20
- json: true,
21
- });
22
- return AppwriteConfigSchema.parse(configModule);
23
- }
13
+ import { loadConfig as loadTsConfig } from "./utils/loadConfigs.js";
14
+ import { findAppwriteConfig } from "./utils/loadConfigs.js";
24
15
  export class UtilsController {
25
16
  appwriteFolderPath;
26
17
  appwriteConfigPath;
@@ -33,10 +24,12 @@ export class UtilsController {
33
24
  afterImportActionsDefinitions = afterImportActions;
34
25
  constructor() {
35
26
  const basePath = process.cwd(); // Gets the current working directory
36
- const appwriteFolderPath = path.join(basePath, "src", "appwrite");
37
- const appwriteConfigPath = path.join(appwriteFolderPath, "appwriteConfig.yaml");
38
- this.appwriteFolderPath = appwriteFolderPath;
39
- this.appwriteConfigPath = appwriteConfigPath;
27
+ const appwriteConfigFound = findAppwriteConfig(basePath);
28
+ if (!appwriteConfigFound) {
29
+ throw new Error("Failed to find appwriteConfig.ts");
30
+ }
31
+ this.appwriteConfigPath = appwriteConfigFound;
32
+ this.appwriteFolderPath = path.dirname(appwriteConfigFound);
40
33
  }
41
34
  // async loadCustomDefinitions(): Promise<void> {
42
35
  // try {
@@ -69,7 +62,10 @@ export class UtilsController {
69
62
  async init(setupOptions) {
70
63
  if (!this.config) {
71
64
  console.log("Initializing appwrite client & loading config...");
72
- this.config = await loadConfig(this.appwriteConfigPath);
65
+ this.config = await loadTsConfig(this.appwriteFolderPath);
66
+ if (!this.config) {
67
+ throw new Error("Failed to load config");
68
+ }
73
69
  this.appwriteServer = new Client();
74
70
  if (setupOptions.endpoint) {
75
71
  if (!setupOptions.project || !setupOptions.key) {
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": "0.0.273",
4
+ "version": "0.0.275",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -21,21 +21,28 @@
21
21
  "utility"
22
22
  ],
23
23
  "bin": {
24
- "appwrite-setup": "./dist/setup.js",
24
+ "appwrite-init": "./dist/init.js",
25
25
  "appwrite-migrate": "./dist/main.js"
26
26
  },
27
27
  "scripts": {
28
28
  "build": "bun run tsc",
29
+ "init": "tsx --no-cache src/init.ts",
30
+ "migrate": "tsx --no-cache src/main.ts",
29
31
  "deploy": "bun run build && npm publish --access public",
30
32
  "postinstall": "echo 'This package is intended for CLI use only and should not be added as a dependency in other projects.'"
31
33
  },
32
34
  "dependencies": {
33
35
  "@asteasolutions/zod-to-openapi": "^7.0.0",
36
+ "@types/inquirer": "^9.0.7",
37
+ "appwrite-utils": "workspace:*",
38
+ "commander": "^12.0.0",
39
+ "inquirer": "^9.2.20",
34
40
  "js-yaml": "^4.1.0",
35
41
  "lodash": "^4.17.21",
36
42
  "luxon": "^3.4.4",
37
43
  "nanostores": "^0.10.3",
38
44
  "node-appwrite": "^12.0.1",
45
+ "tsx": "^4.9.3",
39
46
  "winston": "^3.13.0",
40
47
  "zod": "^3.22.4"
41
48
  },
package/src/init.ts ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+ import inquirer from "inquirer";
3
+ import { createEmptyCollection, setupDirsFiles } from "./utils/setupFiles.js";
4
+
5
+ console.log("Welcome to Appwrite Utils CLI Tool by Zach Handley");
6
+ console.log(
7
+ "For more information, visit https://github.com/zachhandley/appwrite-utils"
8
+ );
9
+
10
+ async function main() {
11
+ const answers = await inquirer.prompt([
12
+ {
13
+ type: "list",
14
+ name: "action",
15
+ message: "What would you like to do?",
16
+ choices: [
17
+ "Create collection config file",
18
+ "Create function (not available)",
19
+ "Setup directories and files",
20
+ "Setup directories and files with example data",
21
+ "Exit",
22
+ ],
23
+ },
24
+ ]);
25
+
26
+ switch (answers.action) {
27
+ case "Create collection config file":
28
+ const { collectionName } = await inquirer.prompt([
29
+ {
30
+ type: "input",
31
+ name: "collectionName",
32
+ message: "Enter the name of the collection:",
33
+ validate: (input) =>
34
+ input.trim() !== "" || "Collection name cannot be empty.",
35
+ },
36
+ ]);
37
+ console.log(`Creating collection config file for '${collectionName}'...`);
38
+ createEmptyCollection(collectionName);
39
+ break;
40
+ case "Create function (not available)":
41
+ console.log("This feature is not available yet.");
42
+ break;
43
+ case "Setup directories and files":
44
+ console.log("Setting up directories and files...");
45
+ setupDirsFiles(false); // Assuming false means no example data
46
+ break;
47
+ case "Setup directories and files with example data":
48
+ console.log("Setting up directories and files with example data...");
49
+ setupDirsFiles(true); // Assuming false means no example data
50
+ break;
51
+ case "Exit":
52
+ console.log("Exiting...");
53
+ process.exit(0);
54
+ break;
55
+ default:
56
+ console.log("Invalid option, please try again.");
57
+ break;
58
+ }
59
+ }
60
+
61
+ main().catch((error) => {
62
+ console.error("An error occurred:", error);
63
+ process.exit(1);
64
+ });