appwrite-utils-cli 1.0.5 → 1.0.7
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/README.md +96 -0
- package/dist/config/yamlConfig.js +0 -9
- package/dist/interactiveCLI.d.ts +1 -0
- package/dist/interactiveCLI.js +83 -17
- package/dist/main.js +43 -0
- package/dist/utils/constantsGenerator.d.ts +19 -0
- package/dist/utils/constantsGenerator.js +309 -0
- package/dist/utils/loadConfigs.js +5 -5
- package/package.json +1 -1
- package/src/config/yamlConfig.ts +0 -9
- package/src/interactiveCLI.ts +90 -17
- package/src/main.ts +53 -0
- package/src/utils/constantsGenerator.ts +352 -0
- package/src/utils/loadConfigs.ts +6 -5
package/README.md
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
### Development Tools
|
24
24
|
- **Database Migrations**: Full migration control with progress tracking and operation summaries
|
25
25
|
- **Schema Generation**: Generate TypeScript and JSON schemas from database configurations
|
26
|
+
- **Constants Generation**: Generate cross-language constants files (TypeScript, Python, PHP, Dart, JSON, Env) for database, collection, bucket, and function IDs
|
26
27
|
- **Data Transfer**: Transfer data between databases, collections, and instances with real-time progress
|
27
28
|
- **Configuration Sync**: Bidirectional synchronization between local YAML configs and Appwrite projects
|
28
29
|
- **Function Management**: Deploy and manage Appwrite Functions with specification updates
|
@@ -218,8 +219,53 @@ Available options:
|
|
218
219
|
- `--functionId`: Function ID to update
|
219
220
|
- `--specification`: New function specification (s-0.5vcpu-512mb to s-8vcpu-8gb)
|
220
221
|
|
222
|
+
### Constants Generation
|
223
|
+
- `--generateConstants` / `--constants`: Generate cross-language constants files with database, collection, bucket, and function IDs
|
224
|
+
- `--constantsLanguages`: Comma-separated list of languages for constants generation (default: typescript)
|
225
|
+
- Available languages: `typescript`, `javascript`, `python`, `php`, `dart`, `json`, `env`
|
226
|
+
- `--constantsOutput`: Output directory for generated constants files (default: config-folder/constants)
|
227
|
+
|
221
228
|
## Examples
|
222
229
|
|
230
|
+
### Generate Constants
|
231
|
+
|
232
|
+
Generate cross-language constants files for all your Appwrite resource IDs:
|
233
|
+
|
234
|
+
```bash
|
235
|
+
# Generate TypeScript constants (default)
|
236
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants
|
237
|
+
|
238
|
+
# Generate multiple language formats
|
239
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants --constantsLanguages="typescript,python,php,json"
|
240
|
+
|
241
|
+
# Generate all available formats
|
242
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants --constantsLanguages="typescript,javascript,python,php,dart,json,env"
|
243
|
+
|
244
|
+
# Generate with custom output directory
|
245
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants --constantsOutput="./my-constants"
|
246
|
+
```
|
247
|
+
|
248
|
+
This generates constants files in your configuration directory (e.g., `.appwrite/constants/`) containing:
|
249
|
+
- Database IDs
|
250
|
+
- Collection IDs
|
251
|
+
- Bucket IDs
|
252
|
+
- Function IDs
|
253
|
+
|
254
|
+
**Example TypeScript output:**
|
255
|
+
```typescript
|
256
|
+
export const DATABASE_IDS = {
|
257
|
+
MAIN_DATABASE: "main"
|
258
|
+
} as const;
|
259
|
+
|
260
|
+
export const COLLECTION_IDS = {
|
261
|
+
USERS: "01JYDBQTB5W8SCBAYB654CCADQ",
|
262
|
+
POSTS: "01JYDBQTB5W8SCBAYB654POSTS"
|
263
|
+
} as const;
|
264
|
+
|
265
|
+
// Type helpers and utility arrays included
|
266
|
+
export type DatabaseId = typeof DATABASE_IDS[keyof typeof DATABASE_IDS];
|
267
|
+
```
|
268
|
+
|
223
269
|
### Transfer Databases
|
224
270
|
|
225
271
|
Transfer databases within the same project or from a local to a remote project:
|
@@ -281,6 +327,56 @@ This updated CLI ensures that developers have robust tools at their fingertips t
|
|
281
327
|
|
282
328
|
## Changelog
|
283
329
|
|
330
|
+
### 1.0.7 - Forgot to remove debug logs
|
331
|
+
|
332
|
+
### 1.0.6 - Cross-Language Constants Generation
|
333
|
+
|
334
|
+
**🚀 Enhanced Developer Experience with Multi-Language Constants**
|
335
|
+
|
336
|
+
#### Constants Generation System
|
337
|
+
- **Cross-Language Support**: Generate constants in 7 languages for seamless multi-platform development
|
338
|
+
- **TypeScript**: Type-safe constants with `as const` and helper types
|
339
|
+
- **JavaScript**: ES6 modules with utility arrays
|
340
|
+
- **Python**: Class-based constants with snake_case dictionaries
|
341
|
+
- **PHP**: Static class methods and associative arrays
|
342
|
+
- **Dart**: Maps with individual getter methods (camelCase)
|
343
|
+
- **JSON**: Structured data with metadata for cross-platform integration
|
344
|
+
- **Environment Variables**: Prefixed environment variables for deployment
|
345
|
+
- **Smart Directory Structure**: Constants generated in `{config-folder}/constants/` by default
|
346
|
+
- **CLI Integration**: Both command-line and interactive mode support
|
347
|
+
- **Custom Output**: Support for custom output directories when needed
|
348
|
+
|
349
|
+
#### Resource ID Extraction
|
350
|
+
- **Database IDs**: Extract all configured database identifiers
|
351
|
+
- **Collection IDs**: Generate constants for all collection ULIDs/names
|
352
|
+
- **Bucket IDs**: Include storage bucket identifiers
|
353
|
+
- **Function IDs**: Support for Appwrite Function identifiers
|
354
|
+
- **Naming Conventions**: Language-appropriate naming (UPPER_CASE, camelCase, snake_case)
|
355
|
+
|
356
|
+
#### Developer Experience Improvements
|
357
|
+
- **Interactive Mode**: Checkbox selection for languages with smart defaults
|
358
|
+
- **CLI Commands**: Simple `--generateConstants` with language and output options
|
359
|
+
- **Type Safety**: Full TypeScript support with generated types and helpers
|
360
|
+
- **Cross-Platform Compatibility**: Enable seamless development across different tech stacks
|
361
|
+
|
362
|
+
#### Usage Examples
|
363
|
+
```bash
|
364
|
+
# Default TypeScript generation
|
365
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants
|
366
|
+
|
367
|
+
# Multi-language generation
|
368
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants --constantsLanguages="typescript,python,php,json"
|
369
|
+
|
370
|
+
# All formats with custom output
|
371
|
+
npx appwrite-utils-cli appwrite-migrate --generateConstants --constantsLanguages="typescript,javascript,python,php,dart,json,env" --constantsOutput="./constants"
|
372
|
+
```
|
373
|
+
|
374
|
+
**Migration Benefits**:
|
375
|
+
- Eliminates hardcoded resource IDs across codebases
|
376
|
+
- Enables type-safe resource access in TypeScript projects
|
377
|
+
- Supports multi-language development workflows
|
378
|
+
- Maintains constants alongside configuration for easy maintenance
|
379
|
+
|
284
380
|
### 1.0.1 - Function Templates & Attribute Type Improvements
|
285
381
|
|
286
382
|
**🚀 Enhanced Function Management & Type System Fixes**
|
@@ -243,17 +243,13 @@ export const findYamlConfig = (startDir) => {
|
|
243
243
|
path.join(startDir, "appwrite.yaml"),
|
244
244
|
path.join(startDir, "appwrite.yml"),
|
245
245
|
];
|
246
|
-
console.log(`DEBUG: Checking YAML paths in ${startDir}:`);
|
247
246
|
for (const configPath of possiblePaths) {
|
248
|
-
console.log(` - ${configPath}: ${fs.existsSync(configPath)}`);
|
249
247
|
if (fs.existsSync(configPath)) {
|
250
248
|
return configPath;
|
251
249
|
}
|
252
250
|
}
|
253
251
|
// Recursively search subdirectories for .appwrite folders
|
254
|
-
console.log(`DEBUG: Starting recursive search from ${startDir}`);
|
255
252
|
const yamlConfigInSubdirs = findYamlConfigRecursive(startDir);
|
256
|
-
console.log(`DEBUG: Recursive search result: ${yamlConfigInSubdirs}`);
|
257
253
|
if (yamlConfigInSubdirs) {
|
258
254
|
return yamlConfigInSubdirs;
|
259
255
|
}
|
@@ -316,23 +312,18 @@ const shouldIgnoreDirectory = (dirName) => {
|
|
316
312
|
const findYamlConfigRecursive = (dir, depth = 0) => {
|
317
313
|
// Limit search depth to prevent infinite recursion
|
318
314
|
if (depth > 5) {
|
319
|
-
console.log(`DEBUG: Stopping search at depth ${depth} in ${dir}`);
|
320
315
|
return null;
|
321
316
|
}
|
322
317
|
if (shouldIgnoreDirectory(path.basename(dir))) {
|
323
|
-
console.log(`DEBUG: Ignoring directory ${dir}`);
|
324
318
|
return null;
|
325
319
|
}
|
326
320
|
try {
|
327
321
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
328
|
-
console.log(`DEBUG: Searching directory ${dir} at depth ${depth}, found ${entries.length} entries`);
|
329
322
|
for (const entry of entries) {
|
330
323
|
if (entry.isDirectory() && !shouldIgnoreDirectory(entry.name)) {
|
331
324
|
const fullPath = path.join(dir, entry.name);
|
332
|
-
console.log(`DEBUG: Checking subdirectory: ${fullPath}`);
|
333
325
|
// Check if this is an .appwrite directory
|
334
326
|
if (entry.name === ".appwrite") {
|
335
|
-
console.log(`DEBUG: Found .appwrite directory at ${fullPath}`);
|
336
327
|
const configPaths = [
|
337
328
|
path.join(fullPath, "appwriteConfig.yaml"),
|
338
329
|
path.join(fullPath, "appwriteConfig.yml"),
|
package/dist/interactiveCLI.d.ts
CHANGED
package/dist/interactiveCLI.js
CHANGED
@@ -13,6 +13,7 @@ import { DateTime } from "luxon";
|
|
13
13
|
import { createFunctionTemplate, deleteFunction, downloadLatestFunctionDeployment, getFunction, listFunctions, listSpecifications, } from "./functions/methods.js";
|
14
14
|
import { deployLocalFunction } from "./functions/deployments.js";
|
15
15
|
import { join } from "node:path";
|
16
|
+
import path from "path";
|
16
17
|
import fs from "node:fs";
|
17
18
|
import { SchemaGenerator } from "./shared/schemaGenerator.js";
|
18
19
|
import { ConfirmationDialogs } from "./shared/confirmationDialogs.js";
|
@@ -23,23 +24,24 @@ import { findYamlConfig, addFunctionToYamlConfig } from "./config/yamlConfig.js"
|
|
23
24
|
var CHOICES;
|
24
25
|
(function (CHOICES) {
|
25
26
|
CHOICES["MIGRATE_CONFIG"] = "\uD83D\uDD04 Migrate TypeScript config to YAML (.appwrite structure)";
|
26
|
-
CHOICES["CREATE_COLLECTION_CONFIG"] = "Create collection config file";
|
27
|
-
CHOICES["CREATE_FUNCTION"] = "Create a new function, from scratch or using a template";
|
28
|
-
CHOICES["DEPLOY_FUNCTION"] = "Deploy function(s)";
|
29
|
-
CHOICES["DELETE_FUNCTION"] = "Delete function";
|
30
|
-
CHOICES["SETUP_DIRS_FILES"] = "Setup directories and files";
|
31
|
-
CHOICES["SETUP_DIRS_FILES_WITH_EXAMPLE_DATA"] = "Setup directories and files with example data";
|
32
|
-
CHOICES["SYNC_DB"] = "Push local config to Appwrite";
|
33
|
-
CHOICES["SYNCHRONIZE_CONFIGURATIONS"] = "Synchronize configurations - Pull from Appwrite and write to local config";
|
34
|
-
CHOICES["TRANSFER_DATA"] = "Transfer data";
|
35
|
-
CHOICES["BACKUP_DATABASE"] = "Backup database";
|
36
|
-
CHOICES["WIPE_DATABASE"] = "Wipe database";
|
37
|
-
CHOICES["WIPE_COLLECTIONS"] = "Wipe collections";
|
38
|
-
CHOICES["GENERATE_SCHEMAS"] = "Generate schemas";
|
39
|
-
CHOICES["
|
40
|
-
CHOICES["
|
41
|
-
CHOICES["
|
42
|
-
CHOICES["
|
27
|
+
CHOICES["CREATE_COLLECTION_CONFIG"] = "\uD83D\uDCC4 Create collection config file";
|
28
|
+
CHOICES["CREATE_FUNCTION"] = "\u26A1 Create a new function, from scratch or using a template";
|
29
|
+
CHOICES["DEPLOY_FUNCTION"] = "\uD83D\uDE80 Deploy function(s)";
|
30
|
+
CHOICES["DELETE_FUNCTION"] = "\uD83D\uDDD1\uFE0F Delete function";
|
31
|
+
CHOICES["SETUP_DIRS_FILES"] = "\uD83D\uDCC1 Setup directories and files";
|
32
|
+
CHOICES["SETUP_DIRS_FILES_WITH_EXAMPLE_DATA"] = "\uD83D\uDCC1\u2728 Setup directories and files with example data";
|
33
|
+
CHOICES["SYNC_DB"] = "\u2B06\uFE0F Push local config to Appwrite";
|
34
|
+
CHOICES["SYNCHRONIZE_CONFIGURATIONS"] = "\uD83D\uDD04 Synchronize configurations - Pull from Appwrite and write to local config";
|
35
|
+
CHOICES["TRANSFER_DATA"] = "\uD83D\uDCE6 Transfer data";
|
36
|
+
CHOICES["BACKUP_DATABASE"] = "\uD83D\uDCBE Backup database";
|
37
|
+
CHOICES["WIPE_DATABASE"] = "\uD83E\uDDF9 Wipe database";
|
38
|
+
CHOICES["WIPE_COLLECTIONS"] = "\uD83E\uDDF9 Wipe collections";
|
39
|
+
CHOICES["GENERATE_SCHEMAS"] = "\uD83C\uDFD7\uFE0F Generate schemas";
|
40
|
+
CHOICES["GENERATE_CONSTANTS"] = "\uD83D\uDCCB Generate cross-language constants (TypeScript, Python, PHP, Dart, etc.)";
|
41
|
+
CHOICES["IMPORT_DATA"] = "\uD83D\uDCE5 Import data";
|
42
|
+
CHOICES["RELOAD_CONFIG"] = "\uD83D\uDD04 Reload configuration files";
|
43
|
+
CHOICES["UPDATE_FUNCTION_SPEC"] = "\u2699\uFE0F Update function specifications";
|
44
|
+
CHOICES["EXIT"] = "\uD83D\uDC4B Exit";
|
43
45
|
})(CHOICES || (CHOICES = {}));
|
44
46
|
export class InteractiveCLI {
|
45
47
|
currentDir;
|
@@ -123,6 +125,10 @@ export class InteractiveCLI {
|
|
123
125
|
await this.initControllerIfNeeded();
|
124
126
|
await this.generateSchemas();
|
125
127
|
break;
|
128
|
+
case CHOICES.GENERATE_CONSTANTS:
|
129
|
+
await this.initControllerIfNeeded();
|
130
|
+
await this.generateConstants();
|
131
|
+
break;
|
126
132
|
case CHOICES.IMPORT_DATA:
|
127
133
|
await this.initControllerIfNeeded();
|
128
134
|
await this.importData();
|
@@ -1167,6 +1173,66 @@ export class InteractiveCLI {
|
|
1167
1173
|
schemaGenerator.generateSchemas({ format: schemaType, verbose: true });
|
1168
1174
|
MessageFormatter.success("Schema generation completed", { prefix: "Schemas" });
|
1169
1175
|
}
|
1176
|
+
async generateConstants() {
|
1177
|
+
console.log(chalk.yellow("Generating cross-language constants..."));
|
1178
|
+
if (!this.controller?.config) {
|
1179
|
+
MessageFormatter.error("No configuration found", undefined, { prefix: "Constants" });
|
1180
|
+
return;
|
1181
|
+
}
|
1182
|
+
// Prompt for languages
|
1183
|
+
const { languages } = await inquirer.prompt([
|
1184
|
+
{
|
1185
|
+
type: "checkbox",
|
1186
|
+
name: "languages",
|
1187
|
+
message: "Select languages for constants generation:",
|
1188
|
+
choices: [
|
1189
|
+
{ name: "TypeScript", value: "typescript", checked: true },
|
1190
|
+
{ name: "JavaScript", value: "javascript" },
|
1191
|
+
{ name: "Python", value: "python" },
|
1192
|
+
{ name: "PHP", value: "php" },
|
1193
|
+
{ name: "Dart", value: "dart" },
|
1194
|
+
{ name: "JSON", value: "json" },
|
1195
|
+
{ name: "Environment Variables", value: "env" },
|
1196
|
+
],
|
1197
|
+
validate: (input) => {
|
1198
|
+
if (input.length === 0) {
|
1199
|
+
return "Please select at least one language";
|
1200
|
+
}
|
1201
|
+
return true;
|
1202
|
+
},
|
1203
|
+
},
|
1204
|
+
]);
|
1205
|
+
// Determine default output directory based on config location
|
1206
|
+
const configPath = this.controller.getAppwriteFolderPath();
|
1207
|
+
const defaultOutputDir = configPath
|
1208
|
+
? path.join(configPath, "constants")
|
1209
|
+
: path.join(process.cwd(), "constants");
|
1210
|
+
// Prompt for output directory
|
1211
|
+
const { outputDir } = await inquirer.prompt([
|
1212
|
+
{
|
1213
|
+
type: "input",
|
1214
|
+
name: "outputDir",
|
1215
|
+
message: "Output directory for constants files:",
|
1216
|
+
default: defaultOutputDir,
|
1217
|
+
validate: (input) => {
|
1218
|
+
if (!input.trim()) {
|
1219
|
+
return "Output directory cannot be empty";
|
1220
|
+
}
|
1221
|
+
return true;
|
1222
|
+
},
|
1223
|
+
},
|
1224
|
+
]);
|
1225
|
+
try {
|
1226
|
+
const { ConstantsGenerator } = await import("./utils/constantsGenerator.js");
|
1227
|
+
const generator = new ConstantsGenerator(this.controller.config);
|
1228
|
+
MessageFormatter.info(`Generating constants for: ${languages.join(", ")}`, { prefix: "Constants" });
|
1229
|
+
await generator.generateFiles(languages, outputDir);
|
1230
|
+
MessageFormatter.success(`Constants generated in ${outputDir}`, { prefix: "Constants" });
|
1231
|
+
}
|
1232
|
+
catch (error) {
|
1233
|
+
MessageFormatter.error("Failed to generate constants", error instanceof Error ? error : new Error(String(error)), { prefix: "Constants" });
|
1234
|
+
}
|
1235
|
+
}
|
1170
1236
|
async importData() {
|
1171
1237
|
console.log(chalk.yellow("Importing data..."));
|
1172
1238
|
const { doBackup } = await inquirer.prompt([
|
package/dist/main.js
CHANGED
@@ -13,6 +13,7 @@ import chalk from "chalk";
|
|
13
13
|
import { listSpecifications } from "./functions/methods.js";
|
14
14
|
import { MessageFormatter } from "./shared/messageFormatter.js";
|
15
15
|
import { ConfirmationDialogs } from "./shared/confirmationDialogs.js";
|
16
|
+
import path from "path";
|
16
17
|
const argv = yargs(hideBin(process.argv))
|
17
18
|
.option("config", {
|
18
19
|
type: "string",
|
@@ -158,6 +159,21 @@ const argv = yargs(hideBin(process.argv))
|
|
158
159
|
alias: ["migrate"],
|
159
160
|
type: "boolean",
|
160
161
|
description: "Migrate appwriteConfig.ts to .appwrite structure with YAML configuration",
|
162
|
+
})
|
163
|
+
.option("generateConstants", {
|
164
|
+
alias: ["constants"],
|
165
|
+
type: "boolean",
|
166
|
+
description: "Generate cross-language constants file with database, collection, bucket, and function IDs",
|
167
|
+
})
|
168
|
+
.option("constantsLanguages", {
|
169
|
+
type: "string",
|
170
|
+
description: "Comma-separated list of languages for constants (typescript,javascript,python,php,dart,json,env)",
|
171
|
+
default: "typescript",
|
172
|
+
})
|
173
|
+
.option("constantsOutput", {
|
174
|
+
type: "string",
|
175
|
+
description: "Output directory for generated constants files (default: config-folder/constants)",
|
176
|
+
default: "auto",
|
161
177
|
})
|
162
178
|
.parse();
|
163
179
|
async function main() {
|
@@ -186,6 +202,33 @@ async function main() {
|
|
186
202
|
await migrateConfig(process.cwd());
|
187
203
|
return;
|
188
204
|
}
|
205
|
+
if (argv.generateConstants) {
|
206
|
+
const { ConstantsGenerator } = await import("./utils/constantsGenerator.js");
|
207
|
+
if (!controller.config) {
|
208
|
+
MessageFormatter.error("No Appwrite configuration found", undefined, { prefix: "Constants" });
|
209
|
+
return;
|
210
|
+
}
|
211
|
+
const languages = argv.constantsLanguages.split(",").map(l => l.trim());
|
212
|
+
// Determine output directory - use config folder/constants by default, or custom path if specified
|
213
|
+
let outputDir;
|
214
|
+
if (argv.constantsOutput === "auto") {
|
215
|
+
// Default case: use config directory + constants, fallback to current directory
|
216
|
+
const configPath = controller.getAppwriteFolderPath();
|
217
|
+
outputDir = configPath
|
218
|
+
? path.join(configPath, "constants")
|
219
|
+
: path.join(process.cwd(), "constants");
|
220
|
+
}
|
221
|
+
else {
|
222
|
+
// Custom output directory specified
|
223
|
+
outputDir = argv.constantsOutput;
|
224
|
+
}
|
225
|
+
MessageFormatter.info(`Generating constants for languages: ${languages.join(", ")}`, { prefix: "Constants" });
|
226
|
+
const generator = new ConstantsGenerator(controller.config);
|
227
|
+
await generator.generateFiles(languages, outputDir);
|
228
|
+
operationStats.generatedConstants = languages.length;
|
229
|
+
MessageFormatter.success(`Constants generated in ${outputDir}`, { prefix: "Constants" });
|
230
|
+
return;
|
231
|
+
}
|
189
232
|
if (!controller.config) {
|
190
233
|
MessageFormatter.error("No Appwrite connection found", undefined, { prefix: "CLI" });
|
191
234
|
return;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { type AppwriteConfig } from "appwrite-utils";
|
2
|
+
export type SupportedLanguage = "typescript" | "javascript" | "python" | "php" | "dart" | "json" | "env";
|
3
|
+
export declare class ConstantsGenerator {
|
4
|
+
private config;
|
5
|
+
private constants;
|
6
|
+
constructor(config: AppwriteConfig);
|
7
|
+
private extractConstants;
|
8
|
+
private toConstantName;
|
9
|
+
private toCamelCase;
|
10
|
+
private toSnakeCase;
|
11
|
+
generateTypeScript(): string;
|
12
|
+
generateJavaScript(): string;
|
13
|
+
generatePython(): string;
|
14
|
+
generatePHP(): string;
|
15
|
+
generateDart(): string;
|
16
|
+
generateJSON(): string;
|
17
|
+
generateEnv(): string;
|
18
|
+
generateFiles(languages: SupportedLanguage[], outputDir: string): Promise<void>;
|
19
|
+
}
|