@an5/orm 1.0.3 → 1.0.5
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.
|
@@ -20,10 +20,18 @@ class MetadataGenerator {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
metaContent += '};\n\n';
|
|
23
|
-
metaContent += 'export const
|
|
23
|
+
metaContent += 'export const modelDescriptions: Record<string, string | undefined> = {\n';
|
|
24
24
|
for (const model of models) {
|
|
25
25
|
const props = this.getAllPropertyVariations(model.name);
|
|
26
|
-
|
|
26
|
+
for (const prop of props) {
|
|
27
|
+
metaContent += ` ${prop}: ${model.description ? JSON.stringify(model.description) : 'undefined'},\n`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
metaContent += '};\n\n';
|
|
31
|
+
metaContent += 'export const modelFields: Record<string, Record<string, { ts: string; sql: string; description?: string }>> = {\n';
|
|
32
|
+
for (const model of models) {
|
|
33
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
34
|
+
const fieldsStr = `{ ${model.fields.map(f => `${f.name}: ${this.formatFieldMetadata(f)}`).join(', ')} }`;
|
|
27
35
|
for (const prop of props) {
|
|
28
36
|
metaContent += ` ${prop}: ${fieldsStr},\n`;
|
|
29
37
|
}
|
|
@@ -63,6 +71,16 @@ class MetadataGenerator {
|
|
|
63
71
|
}
|
|
64
72
|
return Array.from(variations);
|
|
65
73
|
}
|
|
74
|
+
formatFieldMetadata(field) {
|
|
75
|
+
const entries = [
|
|
76
|
+
`ts: ${JSON.stringify(`${field.type}${field.isOptional ? '?' : ''}`)}`,
|
|
77
|
+
`sql: ${JSON.stringify(field.sqlType)}`,
|
|
78
|
+
];
|
|
79
|
+
if (field.description) {
|
|
80
|
+
entries.push(`description: ${JSON.stringify(field.description)}`);
|
|
81
|
+
}
|
|
82
|
+
return `{ ${entries.join(', ')} }`;
|
|
83
|
+
}
|
|
66
84
|
toCamelCase(str) {
|
|
67
85
|
if (!str)
|
|
68
86
|
return '';
|
|
@@ -21,17 +21,26 @@ class PythonGenerator {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
pyContent += '}\n\n';
|
|
24
|
-
// 2.
|
|
24
|
+
// 2. MODEL_DESCRIPTIONS
|
|
25
|
+
pyContent += 'MODEL_DESCRIPTIONS = {\n';
|
|
26
|
+
for (const model of models) {
|
|
27
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
28
|
+
for (const prop of props) {
|
|
29
|
+
pyContent += ` "${prop}": ${this.pyString(model.description)},\n`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
pyContent += '}\n\n';
|
|
33
|
+
// 3. MODEL_FIELDS
|
|
25
34
|
pyContent += 'MODEL_FIELDS = {\n';
|
|
26
35
|
for (const model of models) {
|
|
27
36
|
const props = this.getAllPropertyVariations(model.name);
|
|
28
|
-
const fieldsStr =
|
|
37
|
+
const fieldsStr = this.formatFields(model);
|
|
29
38
|
for (const prop of props) {
|
|
30
39
|
pyContent += ` "${prop}": ${fieldsStr},\n`;
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
pyContent += '}\n\n';
|
|
34
|
-
//
|
|
43
|
+
// 4. RELATION_MAP
|
|
35
44
|
pyContent += 'RELATION_MAP = {\n';
|
|
36
45
|
for (const model of models) {
|
|
37
46
|
const props = this.getAllPropertyVariations(model.name);
|
|
@@ -68,6 +77,17 @@ class PythonGenerator {
|
|
|
68
77
|
}
|
|
69
78
|
return Array.from(variations);
|
|
70
79
|
}
|
|
80
|
+
formatFields(model) {
|
|
81
|
+
if (model.fields.length === 0)
|
|
82
|
+
return '[]';
|
|
83
|
+
const fields = model.fields.map(f => {
|
|
84
|
+
return ` { "name": "${f.name}", "type": "${f.type}${f.isOptional ? '?' : ''}", "sql": "${f.sqlType}", "isOptional": ${f.isOptional ? 'True' : 'False'}, "hasDefault": ${f.hasDefault ? 'True' : 'False'}, "isId": ${f.isId ? 'True' : 'False'}, "description": ${this.pyString(f.description)} }`;
|
|
85
|
+
});
|
|
86
|
+
return `[\n${fields.join(',\n')}\n ]`;
|
|
87
|
+
}
|
|
88
|
+
pyString(value) {
|
|
89
|
+
return value ? JSON.stringify(value) : 'None';
|
|
90
|
+
}
|
|
71
91
|
toCamelCase(str) {
|
|
72
92
|
if (!str)
|
|
73
93
|
return '';
|
|
@@ -15,13 +15,22 @@ export class MetadataGenerator {
|
|
|
15
15
|
for (const prop of props) {
|
|
16
16
|
metaContent += ` ${prop}: "${fullTableName}",\n`;
|
|
17
17
|
}
|
|
18
|
-
}
|
|
19
|
-
metaContent += '};\n\n';
|
|
20
|
-
|
|
21
|
-
metaContent += 'export const
|
|
22
|
-
for (const model of models) {
|
|
23
|
-
const props = this.getAllPropertyVariations(model.name);
|
|
24
|
-
|
|
18
|
+
}
|
|
19
|
+
metaContent += '};\n\n';
|
|
20
|
+
|
|
21
|
+
metaContent += 'export const modelDescriptions: Record<string, string | undefined> = {\n';
|
|
22
|
+
for (const model of models) {
|
|
23
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
24
|
+
for (const prop of props) {
|
|
25
|
+
metaContent += ` ${prop}: ${model.description ? JSON.stringify(model.description) : 'undefined'},\n`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
metaContent += '};\n\n';
|
|
29
|
+
|
|
30
|
+
metaContent += 'export const modelFields: Record<string, Record<string, { ts: string; sql: string; description?: string }>> = {\n';
|
|
31
|
+
for (const model of models) {
|
|
32
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
33
|
+
const fieldsStr = `{ ${model.fields.map(f => `${f.name}: ${this.formatFieldMetadata(f)}`).join(', ')} }`;
|
|
25
34
|
for (const prop of props) {
|
|
26
35
|
metaContent += ` ${prop}: ${fieldsStr},\n`;
|
|
27
36
|
}
|
|
@@ -48,7 +57,7 @@ export class MetadataGenerator {
|
|
|
48
57
|
fs.writeFileSync(this.outputPath, metaContent);
|
|
49
58
|
}
|
|
50
59
|
|
|
51
|
-
private getAllPropertyVariations(modelName: string): string[] {
|
|
60
|
+
private getAllPropertyVariations(modelName: string): string[] {
|
|
52
61
|
const variations = new Set<string>();
|
|
53
62
|
|
|
54
63
|
// 1. Standard camelCase (e.g. User -> user, McpServer -> mcpServer)
|
|
@@ -68,11 +77,22 @@ export class MetadataGenerator {
|
|
|
68
77
|
variations.add(acronym[0].toLowerCase() + acronym.slice(1) + modelName.slice(acronym.length));
|
|
69
78
|
}
|
|
70
79
|
}
|
|
71
|
-
|
|
72
|
-
return Array.from(variations);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private
|
|
80
|
+
|
|
81
|
+
return Array.from(variations);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private formatFieldMetadata(field: Model['fields'][number]): string {
|
|
85
|
+
const entries = [
|
|
86
|
+
`ts: ${JSON.stringify(`${field.type}${field.isOptional ? '?' : ''}`)}`,
|
|
87
|
+
`sql: ${JSON.stringify(field.sqlType)}`,
|
|
88
|
+
];
|
|
89
|
+
if (field.description) {
|
|
90
|
+
entries.push(`description: ${JSON.stringify(field.description)}`);
|
|
91
|
+
}
|
|
92
|
+
return `{ ${entries.join(', ')} }`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private toCamelCase(str: string): string {
|
|
76
96
|
if (!str) return '';
|
|
77
97
|
return str[0].toLowerCase() + str.slice(1);
|
|
78
98
|
}
|
|
@@ -16,21 +16,31 @@ export class PythonGenerator {
|
|
|
16
16
|
for (const prop of props) {
|
|
17
17
|
pyContent += ` "${prop}": "${fullTableName}",\n`;
|
|
18
18
|
}
|
|
19
|
+
}
|
|
20
|
+
pyContent += '}\n\n';
|
|
21
|
+
|
|
22
|
+
// 2. MODEL_DESCRIPTIONS
|
|
23
|
+
pyContent += 'MODEL_DESCRIPTIONS = {\n';
|
|
24
|
+
for (const model of models) {
|
|
25
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
26
|
+
for (const prop of props) {
|
|
27
|
+
pyContent += ` "${prop}": ${this.pyString(model.description)},\n`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
pyContent += '}\n\n';
|
|
31
|
+
|
|
32
|
+
// 3. MODEL_FIELDS
|
|
33
|
+
pyContent += 'MODEL_FIELDS = {\n';
|
|
34
|
+
for (const model of models) {
|
|
35
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
36
|
+
const fieldsStr = this.formatFields(model);
|
|
37
|
+
for (const prop of props) {
|
|
38
|
+
pyContent += ` "${prop}": ${fieldsStr},\n`;
|
|
39
|
+
}
|
|
19
40
|
}
|
|
20
41
|
pyContent += '}\n\n';
|
|
21
42
|
|
|
22
|
-
//
|
|
23
|
-
pyContent += 'MODEL_FIELDS = {\n';
|
|
24
|
-
for (const model of models) {
|
|
25
|
-
const props = this.getAllPropertyVariations(model.name);
|
|
26
|
-
const fieldsStr = `{ ${model.fields.map(f => `"${f.name}": "${f.type}${f.isOptional ? '?' : ''}"`).join(', ')} }`;
|
|
27
|
-
for (const prop of props) {
|
|
28
|
-
pyContent += ` "${prop}": ${fieldsStr},\n`;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
pyContent += '}\n\n';
|
|
32
|
-
|
|
33
|
-
// 3. RELATION_MAP
|
|
43
|
+
// 4. RELATION_MAP
|
|
34
44
|
pyContent += 'RELATION_MAP = {\n';
|
|
35
45
|
for (const model of models) {
|
|
36
46
|
const props = this.getAllPropertyVariations(model.name);
|
|
@@ -54,7 +64,7 @@ export class PythonGenerator {
|
|
|
54
64
|
fs.writeFileSync(this.outputPath, pyContent);
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
private getAllPropertyVariations(modelName: string): string[] {
|
|
67
|
+
private getAllPropertyVariations(modelName: string): string[] {
|
|
58
68
|
const variations = new Set<string>();
|
|
59
69
|
|
|
60
70
|
// 1. camelCase (User -> user, McpServer -> mcpServer)
|
|
@@ -73,9 +83,23 @@ export class PythonGenerator {
|
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
return Array.from(variations);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private formatFields(model: Model): string {
|
|
89
|
+
if (model.fields.length === 0) return '[]';
|
|
90
|
+
|
|
91
|
+
const fields = model.fields.map(f => {
|
|
92
|
+
return ` { "name": "${f.name}", "type": "${f.type}${f.isOptional ? '?' : ''}", "sql": "${f.sqlType}", "isOptional": ${f.isOptional ? 'True' : 'False'}, "hasDefault": ${f.hasDefault ? 'True' : 'False'}, "isId": ${f.isId ? 'True' : 'False'}, "description": ${this.pyString(f.description)} }`;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return `[\n${fields.join(',\n')}\n ]`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private pyString(value?: string): string {
|
|
99
|
+
return value ? JSON.stringify(value) : 'None';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private toCamelCase(str: string): string {
|
|
79
103
|
if (!str) return '';
|
|
80
104
|
return str[0].toLowerCase() + str.slice(1);
|
|
81
105
|
}
|
package/package.json
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@an5/orm",
|
|
3
|
-
"version": "1.0.
|
|
2
|
+
"name": "@an5/orm",
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "The lightweight ORM for SQL Server with support for TypeScript, Python, and .NET (C#).",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"bin": {
|
|
9
|
-
"an5": "./dist/cli.js",
|
|
10
|
-
"an5-orm": "./dist/cli.js"
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
"dist/**/*.{js,d.ts}",
|
|
14
|
-
"generator/src/**/*.ts",
|
|
15
|
-
"README.md"
|
|
16
|
-
],
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"an5": "./dist/cli.js",
|
|
10
|
+
"an5-orm": "./dist/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/**/*.{js,d.ts}",
|
|
14
|
+
"generator/src/**/*.ts",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
19
|
"url": "https://github.com/an5ORM/an5Orm.git"
|
|
20
20
|
},
|
|
21
|
-
"scripts": {
|
|
22
|
-
"generate": "npx tsx generator/src/index.ts",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"generate": "npx tsx generator/src/index.ts",
|
|
23
23
|
"db:push": "npx tsx push.ts",
|
|
24
24
|
"db:pull": "npx tsx pull.ts",
|
|
25
25
|
"db:seed": "npx tsx seed.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"test:generator": "node test/generator.test.js"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@an5/adapters": "^0.
|
|
38
|
+
"@an5/adapters": "^0.2.0",
|
|
39
39
|
"bcryptjs": "^2.4.3",
|
|
40
40
|
"dotenv": "^16.4.5",
|
|
41
41
|
"mssql": "^12.5.5"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/bcryptjs": "^2.4.6",
|
|
45
45
|
"@types/mssql": "^9.1.8",
|
|
46
|
-
"@types/node": "^20.
|
|
46
|
+
"@types/node": "^20.19.43",
|
|
47
47
|
"tsx": "^4.7.1",
|
|
48
48
|
"typescript": "^6.0.3"
|
|
49
49
|
},
|