@dyrected/cli 0.0.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.
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > @dyrected/cli@0.0.1 build /Users/busola/Work/dyrected/packages/cli
4
+ > tsc && chmod +x dist/index.js
5
+
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @dyrected/cli
2
+
3
+ This is the cli package/app for the Dyrected ecosystem.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import prettier from 'prettier';
4
+ import chalk from 'chalk';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ const program = new Command();
8
+ program
9
+ .name('dyrected')
10
+ .description('Dyrected CMS CLI tool')
11
+ .version('0.0.1');
12
+ program
13
+ .command('generate:types')
14
+ .description('Generate TypeScript interfaces from your Dyrected schema')
15
+ .option('-u, --url <url>', 'Base URL of your Dyrected API', 'http://localhost:3000')
16
+ .option('-o, --output <path>', 'Output file path', './dyrected-types.ts')
17
+ .action(async (options) => {
18
+ try {
19
+ console.log(chalk.blue(`Fetching schemas from ${options.url}/api/schemas...`));
20
+ const response = await fetch(`${options.url}/api/schemas`);
21
+ if (!response.ok) {
22
+ throw new Error(`Failed to fetch schemas: ${response.statusText}`);
23
+ }
24
+ const schema = await response.json();
25
+ const code = generateTypes(schema);
26
+ const formattedCode = await prettier.format(code, { parser: 'typescript' });
27
+ await fs.outputFile(path.resolve(process.cwd(), options.output), formattedCode);
28
+ console.log(chalk.green(`\nSuccess! Types generated at ${options.output}`));
29
+ }
30
+ catch (error) {
31
+ console.error(chalk.red(`\nError: ${error.message}`));
32
+ process.exit(1);
33
+ }
34
+ });
35
+ function generateTypes(schema) {
36
+ let code = `/**
37
+ * This file was automatically generated by Dyrected CLI.
38
+ * DO NOT MODIFY IT BY HAND.
39
+ */
40
+
41
+ export interface Media {
42
+ id: string;
43
+ filename: string;
44
+ filesize: number;
45
+ mimeType: string;
46
+ url: string;
47
+ width?: number;
48
+ height?: number;
49
+ createdAt: string;
50
+ updatedAt: string;
51
+ }
52
+ \n`;
53
+ // Collections
54
+ for (const col of schema.collections) {
55
+ const interfaceName = toPascalCase(col.slug);
56
+ code += `export interface ${interfaceName} {\n`;
57
+ code += ` id: string;\n`;
58
+ for (const field of col.fields) {
59
+ code += ` ${field.name}${field.required ? '' : '?'}: ${mapFieldType(field)};\n`;
60
+ }
61
+ code += ` createdAt: string;\n`;
62
+ code += ` updatedAt: string;\n`;
63
+ code += `}\n\n`;
64
+ }
65
+ // Globals
66
+ for (const glb of schema.globals) {
67
+ const interfaceName = `${toPascalCase(glb.slug)}Global`;
68
+ code += `export interface ${interfaceName} {\n`;
69
+ for (const field of glb.fields) {
70
+ code += ` ${field.name}${field.required ? '' : '?'}: ${mapFieldType(field)};\n`;
71
+ }
72
+ code += `}\n\n`;
73
+ }
74
+ // Registry
75
+ code += `export interface DyrectedSchema {\n`;
76
+ code += ` collections: {\n`;
77
+ for (const col of schema.collections) {
78
+ code += ` ${col.slug}: ${toPascalCase(col.slug)};\n`;
79
+ }
80
+ code += ` };\n`;
81
+ code += ` globals: {\n`;
82
+ for (const glb of schema.globals) {
83
+ code += ` ${glb.slug}: ${toPascalCase(glb.slug)}Global;\n`;
84
+ }
85
+ code += ` };\n`;
86
+ code += `}\n`;
87
+ return code;
88
+ }
89
+ function mapFieldType(field) {
90
+ switch (field.type) {
91
+ case 'text':
92
+ case 'textarea':
93
+ case 'richText':
94
+ case 'date':
95
+ case 'email':
96
+ case 'url':
97
+ return 'string';
98
+ case 'number':
99
+ return 'number';
100
+ case 'boolean':
101
+ return 'boolean';
102
+ case 'select':
103
+ return field.options ? field.options.map((o) => `'${typeof o === 'string' ? o : o.value}'`).join(' | ') : 'string';
104
+ case 'relationship':
105
+ return field.collection === 'media' ? 'Media | string' : `${toPascalCase(field.collection)} | string`;
106
+ case 'array':
107
+ return 'any[]'; // Deep nesting handled later
108
+ case 'object':
109
+ return 'any';
110
+ default:
111
+ return 'any';
112
+ }
113
+ }
114
+ function toPascalCase(str) {
115
+ return str.replace(/(^\w|-\w)/g, (m) => m.replace(/-/, '').toUpperCase());
116
+ }
117
+ program.parse();
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@dyrected/cli",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "bin": {
6
+ "dyrected": "./dist/index.js"
7
+ },
8
+ "dependencies": {
9
+ "chalk": "^5.3.0",
10
+ "commander": "^12.1.0",
11
+ "fs-extra": "^11.2.0",
12
+ "prettier": "^3.2.5"
13
+ },
14
+ "devDependencies": {
15
+ "@types/fs-extra": "^11.0.4",
16
+ "@types/node": "^20.12.12",
17
+ "typescript": "^5.4.5"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc && chmod +x dist/index.js",
21
+ "dev": "tsc --watch"
22
+ }
23
+ }
package/src/index.ts ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import prettier from 'prettier';
4
+ import chalk from 'chalk';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+
8
+ const program = new Command();
9
+
10
+ program
11
+ .name('dyrected')
12
+ .description('Dyrected CMS CLI tool')
13
+ .version('0.0.1');
14
+
15
+ program
16
+ .command('generate:types')
17
+ .description('Generate TypeScript interfaces from your Dyrected schema')
18
+ .option('-u, --url <url>', 'Base URL of your Dyrected API', 'http://localhost:3000')
19
+ .option('-o, --output <path>', 'Output file path', './dyrected-types.ts')
20
+ .action(async (options) => {
21
+ try {
22
+ console.log(chalk.blue(`Fetching schemas from ${options.url}/api/schemas...`));
23
+
24
+ const response = await fetch(`${options.url}/api/schemas`);
25
+ if (!response.ok) {
26
+ throw new Error(`Failed to fetch schemas: ${response.statusText}`);
27
+ }
28
+
29
+ const schema = await response.json();
30
+ const code = generateTypes(schema);
31
+
32
+ const formattedCode = await prettier.format(code, { parser: 'typescript' });
33
+
34
+ await fs.outputFile(path.resolve(process.cwd(), options.output), formattedCode);
35
+
36
+ console.log(chalk.green(`\nSuccess! Types generated at ${options.output}`));
37
+ } catch (error: any) {
38
+ console.error(chalk.red(`\nError: ${error.message}`));
39
+ process.exit(1);
40
+ }
41
+ });
42
+
43
+ function generateTypes(schema: any) {
44
+ let code = `/**
45
+ * This file was automatically generated by Dyrected CLI.
46
+ * DO NOT MODIFY IT BY HAND.
47
+ */
48
+
49
+ export interface Media {
50
+ id: string;
51
+ filename: string;
52
+ filesize: number;
53
+ mimeType: string;
54
+ url: string;
55
+ width?: number;
56
+ height?: number;
57
+ createdAt: string;
58
+ updatedAt: string;
59
+ }
60
+ \n`;
61
+
62
+ // Collections
63
+ for (const col of schema.collections) {
64
+ const interfaceName = toPascalCase(col.slug);
65
+ code += `export interface ${interfaceName} {\n`;
66
+ code += ` id: string;\n`;
67
+
68
+ for (const field of col.fields) {
69
+ code += ` ${field.name}${field.required ? '' : '?'}: ${mapFieldType(field)};\n`;
70
+ }
71
+
72
+ code += ` createdAt: string;\n`;
73
+ code += ` updatedAt: string;\n`;
74
+ code += `}\n\n`;
75
+ }
76
+
77
+ // Globals
78
+ for (const glb of schema.globals) {
79
+ const interfaceName = `${toPascalCase(glb.slug)}Global`;
80
+ code += `export interface ${interfaceName} {\n`;
81
+
82
+ for (const field of glb.fields) {
83
+ code += ` ${field.name}${field.required ? '' : '?'}: ${mapFieldType(field)};\n`;
84
+ }
85
+
86
+ code += `}\n\n`;
87
+ }
88
+
89
+ // Registry
90
+ code += `export interface DyrectedSchema {\n`;
91
+ code += ` collections: {\n`;
92
+ for (const col of schema.collections) {
93
+ code += ` ${col.slug}: ${toPascalCase(col.slug)};\n`;
94
+ }
95
+ code += ` };\n`;
96
+ code += ` globals: {\n`;
97
+ for (const glb of schema.globals) {
98
+ code += ` ${glb.slug}: ${toPascalCase(glb.slug)}Global;\n`;
99
+ }
100
+ code += ` };\n`;
101
+ code += `}\n`;
102
+
103
+ return code;
104
+ }
105
+
106
+ function mapFieldType(field: any): string {
107
+ switch (field.type) {
108
+ case 'text':
109
+ case 'textarea':
110
+ case 'richText':
111
+ case 'date':
112
+ case 'email':
113
+ case 'url':
114
+ return 'string';
115
+ case 'number':
116
+ return 'number';
117
+ case 'boolean':
118
+ return 'boolean';
119
+ case 'select':
120
+ return field.options ? field.options.map((o: any) => `'${typeof o === 'string' ? o : o.value}'`).join(' | ') : 'string';
121
+ case 'relationship':
122
+ return field.collection === 'media' ? 'Media | string' : `${toPascalCase(field.collection)} | string`;
123
+ case 'array':
124
+ return 'any[]'; // Deep nesting handled later
125
+ case 'object':
126
+ return 'any';
127
+ default:
128
+ return 'any';
129
+ }
130
+ }
131
+
132
+ function toPascalCase(str: string) {
133
+ return str.replace(/(^\w|-\w)/g, (m) => m.replace(/-/, '').toUpperCase());
134
+ }
135
+
136
+ program.parse();
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "module": "NodeNext",
7
+ "moduleResolution": "NodeNext"
8
+ },
9
+ "include": ["src/**/*"],
10
+ "exclude": ["node_modules", "dist"]
11
+ }