@an5/orm 1.0.0 → 1.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.
- package/dist/an5Orm.js +2 -2
- package/dist/cleanup.js +3 -3
- package/dist/cli.js +64 -0
- package/dist/generator/src/code-generator.d.ts +13 -0
- package/dist/generator/src/code-generator.js +225 -0
- package/dist/generator/src/dotnet-generator.d.ts +11 -0
- package/dist/generator/src/dotnet-generator.js +546 -0
- package/dist/generator/src/index.d.ts +1 -0
- package/dist/generator/src/index.js +85 -0
- package/dist/generator/src/metadata-generator.d.ts +8 -0
- package/dist/generator/src/metadata-generator.js +72 -0
- package/dist/generator/src/parser.d.ts +11 -0
- package/dist/generator/src/parser.js +206 -0
- package/dist/generator/src/python-generator.d.ts +9 -0
- package/dist/generator/src/python-generator.js +85 -0
- package/dist/generator/src/types.d.ts +27 -0
- package/dist/generator/src/types.js +2 -0
- package/dist/migrate.js +3 -3
- package/dist/pull.js +3 -3
- package/dist/push.js +3 -3
- package/generator/src/index.ts +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MetadataGenerator = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
class MetadataGenerator {
|
|
9
|
+
constructor(outputPath) {
|
|
10
|
+
this.outputPath = outputPath;
|
|
11
|
+
}
|
|
12
|
+
generate(models) {
|
|
13
|
+
let metaContent = '// This file is auto-generated. Do not edit directly.\n\n';
|
|
14
|
+
metaContent += 'export const modelToTable: Record<string, string> = {\n';
|
|
15
|
+
for (const model of models) {
|
|
16
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
17
|
+
const fullTableName = `[${model.schemaName}].[${model.tableName}]`;
|
|
18
|
+
for (const prop of props) {
|
|
19
|
+
metaContent += ` ${prop}: "${fullTableName}",\n`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
metaContent += '};\n\n';
|
|
23
|
+
metaContent += 'export const modelFields: Record<string, Record<string, { ts: string; sql: string }>> = {\n';
|
|
24
|
+
for (const model of models) {
|
|
25
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
26
|
+
const fieldsStr = `{ ${model.fields.map(f => `${f.name}: { ts: "${f.type}${f.isOptional ? '?' : ''}", sql: "${f.sqlType}" }`).join(', ')} }`;
|
|
27
|
+
for (const prop of props) {
|
|
28
|
+
metaContent += ` ${prop}: ${fieldsStr},\n`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
metaContent += '};\n\n';
|
|
32
|
+
metaContent += 'export interface RelationDef {\n modelName: string;\n relationType: "many" | "one";\n foreignKey: string;\n localKey: string;\n}\n\n';
|
|
33
|
+
metaContent += 'export const relationMap: Record<string, Record<string, RelationDef>> = {\n';
|
|
34
|
+
for (const model of models) {
|
|
35
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
36
|
+
let relationsContent = ` {\n`;
|
|
37
|
+
for (const rel of model.relations) {
|
|
38
|
+
relationsContent += ` ${rel.name}: { modelName: "${this.toCamelCase(rel.type)}", relationType: "${rel.isArray ? 'many' : 'one'}", foreignKey: "${rel.foreignKey || 'id'}", localKey: "${rel.localKey || 'id'}" },\n`;
|
|
39
|
+
}
|
|
40
|
+
relationsContent += ` }`;
|
|
41
|
+
for (const prop of props) {
|
|
42
|
+
metaContent += ` ${prop}: ${relationsContent},\n`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
metaContent += '};\n';
|
|
46
|
+
fs_1.default.writeFileSync(this.outputPath, metaContent);
|
|
47
|
+
}
|
|
48
|
+
getAllPropertyVariations(modelName) {
|
|
49
|
+
const variations = new Set();
|
|
50
|
+
// 1. Standard camelCase (e.g. User -> user, McpServer -> mcpServer)
|
|
51
|
+
variations.add(this.toCamelCase(modelName));
|
|
52
|
+
// 2. Handle known acronyms at start (e.g. LLMProvider -> lLMProvider)
|
|
53
|
+
// This is already handled by toCamelCase if it only lowercases the first letter.
|
|
54
|
+
// But we might want 'llmProvider' as well.
|
|
55
|
+
const acronyms = ['LLM', 'AI', 'MCP', 'IT', 'QC', 'HR', 'MR', 'WH', 'SSIS', 'API', 'URL', 'ID', 'JSON'];
|
|
56
|
+
for (const acronym of acronyms) {
|
|
57
|
+
if (modelName.startsWith(acronym)) {
|
|
58
|
+
// e.g. LLMProvider -> llmProvider
|
|
59
|
+
variations.add(acronym.toLowerCase() + modelName.slice(acronym.length));
|
|
60
|
+
// e.g. LLMProvider -> lLMProvider (Prisma style)
|
|
61
|
+
variations.add(acronym[0].toLowerCase() + acronym.slice(1) + modelName.slice(acronym.length));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return Array.from(variations);
|
|
65
|
+
}
|
|
66
|
+
toCamelCase(str) {
|
|
67
|
+
if (!str)
|
|
68
|
+
return '';
|
|
69
|
+
return str[0].toLowerCase() + str.slice(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.MetadataGenerator = MetadataGenerator;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Model } from './types';
|
|
2
|
+
export declare function sqlTypeToTs(sqlType: string): string;
|
|
3
|
+
export declare class SchemaParser {
|
|
4
|
+
private schemaDir;
|
|
5
|
+
private schemaText;
|
|
6
|
+
constructor(schemaDir: string);
|
|
7
|
+
parse(): Promise<Model[]>;
|
|
8
|
+
private loadSchema;
|
|
9
|
+
private parseModelLine;
|
|
10
|
+
private postProcessRelations;
|
|
11
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SchemaParser = void 0;
|
|
7
|
+
exports.sqlTypeToTs = sqlTypeToTs;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
// SQL Server type → TypeScript type mapping
|
|
11
|
+
const AN5_TO_TS = {
|
|
12
|
+
// String types
|
|
13
|
+
'NVARCHAR': 'string',
|
|
14
|
+
'VARCHAR': 'string',
|
|
15
|
+
'CHAR': 'string',
|
|
16
|
+
'NCHAR': 'string',
|
|
17
|
+
'TEXT': 'string',
|
|
18
|
+
'NTEXT': 'string',
|
|
19
|
+
'XML': 'string',
|
|
20
|
+
// Numeric types
|
|
21
|
+
'INT': 'number',
|
|
22
|
+
'SMALLINT': 'number',
|
|
23
|
+
'TINYINT': 'number',
|
|
24
|
+
'BIGINT': 'number | bigint',
|
|
25
|
+
'FLOAT': 'number',
|
|
26
|
+
'REAL': 'number',
|
|
27
|
+
'DECIMAL': 'number',
|
|
28
|
+
'NUMERIC': 'number',
|
|
29
|
+
'MONEY': 'number',
|
|
30
|
+
'SMALLMONEY': 'number',
|
|
31
|
+
// Boolean
|
|
32
|
+
'BIT': 'boolean',
|
|
33
|
+
// Date types
|
|
34
|
+
'DATETIME': 'Date',
|
|
35
|
+
'DATETIME2': 'Date',
|
|
36
|
+
'SMALLDATETIME': 'Date',
|
|
37
|
+
'DATE': 'Date',
|
|
38
|
+
'TIME': 'Date',
|
|
39
|
+
'DATETIMEOFFSET': 'Date',
|
|
40
|
+
// Binary types
|
|
41
|
+
'VARBINARY': 'Buffer',
|
|
42
|
+
'BINARY': 'Buffer',
|
|
43
|
+
'IMAGE': 'Buffer',
|
|
44
|
+
// Other
|
|
45
|
+
'UNIQUEIDENTIFIER': 'string',
|
|
46
|
+
'SQL_VARIANT': 'any',
|
|
47
|
+
'ROWVERSION': 'Buffer',
|
|
48
|
+
'HIERARCHYID': 'string',
|
|
49
|
+
'GEOGRAPHY': 'string',
|
|
50
|
+
'GEOMETRY': 'string',
|
|
51
|
+
'VECTOR': 'number[] | string',
|
|
52
|
+
};
|
|
53
|
+
// Parse base type from "NVARCHAR(255)" → "NVARCHAR"
|
|
54
|
+
function parseSqlType(raw) {
|
|
55
|
+
const match = raw.match(/^(\w+)(?:\((.+)\))?$/);
|
|
56
|
+
if (!match)
|
|
57
|
+
return { base: raw, params: '' };
|
|
58
|
+
return { base: match[1].toUpperCase(), params: match[2] || '' };
|
|
59
|
+
}
|
|
60
|
+
// Map SQL Server type to TypeScript type
|
|
61
|
+
function sqlTypeToTs(sqlType) {
|
|
62
|
+
const { base } = parseSqlType(sqlType);
|
|
63
|
+
return AN5_TO_TS[base] || 'any';
|
|
64
|
+
}
|
|
65
|
+
class SchemaParser {
|
|
66
|
+
constructor(schemaDir) {
|
|
67
|
+
this.schemaDir = schemaDir;
|
|
68
|
+
this.schemaText = '';
|
|
69
|
+
}
|
|
70
|
+
async parse() {
|
|
71
|
+
this.loadSchema();
|
|
72
|
+
const lines = this.schemaText.split('\n');
|
|
73
|
+
const models = [];
|
|
74
|
+
let currentModel = null;
|
|
75
|
+
for (let line of lines) {
|
|
76
|
+
line = line.trim();
|
|
77
|
+
if (!line || line.startsWith('//'))
|
|
78
|
+
continue;
|
|
79
|
+
const modelHeaderMatch = line.match(/^model\s+(\w+)\s*\{/);
|
|
80
|
+
if (modelHeaderMatch) {
|
|
81
|
+
const modelName = modelHeaderMatch[1];
|
|
82
|
+
currentModel = {
|
|
83
|
+
name: modelName,
|
|
84
|
+
tableName: modelName.toLowerCase() + 's',
|
|
85
|
+
schemaName: 'dbo',
|
|
86
|
+
fields: [],
|
|
87
|
+
relations: []
|
|
88
|
+
};
|
|
89
|
+
models.push(currentModel);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (line === '}') {
|
|
93
|
+
currentModel = null;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (currentModel) {
|
|
97
|
+
this.parseModelLine(line, currentModel);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
this.postProcessRelations(models);
|
|
101
|
+
return models;
|
|
102
|
+
}
|
|
103
|
+
loadSchema() {
|
|
104
|
+
if (fs_1.default.existsSync(this.schemaDir)) {
|
|
105
|
+
const files = fs_1.default.readdirSync(this.schemaDir).filter(f => f.endsWith('.an5'));
|
|
106
|
+
for (const file of files) {
|
|
107
|
+
this.schemaText += fs_1.default.readFileSync(path_1.default.join(this.schemaDir, file), 'utf8') + '\n';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
throw new Error(`No schema directory found at ${this.schemaDir}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
parseModelLine(line, model) {
|
|
115
|
+
if (line.startsWith('@@map')) {
|
|
116
|
+
const mapMatch = line.match(/@@map\("(.+)"\)/);
|
|
117
|
+
if (mapMatch)
|
|
118
|
+
model.tableName = mapMatch[1];
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (line.startsWith('@@schema')) {
|
|
122
|
+
const schemaMatch = line.match(/@@schema\("(.+)"\)/);
|
|
123
|
+
if (schemaMatch)
|
|
124
|
+
model.schemaName = schemaMatch[1];
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (line.startsWith('@@unique')) {
|
|
128
|
+
const uniqueMatch = line.match(/@@unique\(\[([\w,\s]+)\]\)/);
|
|
129
|
+
if (uniqueMatch) {
|
|
130
|
+
const fields = uniqueMatch[1].split(',').map(f => f.trim());
|
|
131
|
+
model.compoundUniques = model.compoundUniques || [];
|
|
132
|
+
model.compoundUniques.push(fields);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (line.startsWith('@@description')) {
|
|
137
|
+
const descMatch = line.match(/@@description\("(.+)"\)/);
|
|
138
|
+
if (descMatch)
|
|
139
|
+
model.description = descMatch[1];
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (line.startsWith('@@'))
|
|
143
|
+
return;
|
|
144
|
+
const parts = line.split(/\s+/);
|
|
145
|
+
const fieldName = parts[0];
|
|
146
|
+
let fieldType = parts[1];
|
|
147
|
+
if (!fieldName || !fieldType)
|
|
148
|
+
return;
|
|
149
|
+
const isArray = fieldType.endsWith('[]');
|
|
150
|
+
const isOptional = fieldType.endsWith('?');
|
|
151
|
+
const cleanType = fieldType.replace('[]', '').replace('?', '');
|
|
152
|
+
// Parse SQL Server type (e.g., "NVARCHAR(255)" → base="NVARCHAR")
|
|
153
|
+
const { base: sqlBase } = parseSqlType(cleanType);
|
|
154
|
+
let tsType = 'any';
|
|
155
|
+
let isRelation = false;
|
|
156
|
+
// Check if it's a known SQL Server type
|
|
157
|
+
if (AN5_TO_TS[sqlBase]) {
|
|
158
|
+
tsType = sqlTypeToTs(cleanType);
|
|
159
|
+
}
|
|
160
|
+
else if (cleanType[0] === cleanType[0].toUpperCase() && !cleanType.includes('(')) {
|
|
161
|
+
// Uppercase without parens = likely a relation to another model
|
|
162
|
+
tsType = cleanType;
|
|
163
|
+
isRelation = true;
|
|
164
|
+
}
|
|
165
|
+
if (isRelation) {
|
|
166
|
+
let foreignKey = '', localKey = '', relationName = '';
|
|
167
|
+
const nameMatch = line.match(/@relation\("(\w+)"/);
|
|
168
|
+
if (nameMatch)
|
|
169
|
+
relationName = nameMatch[1];
|
|
170
|
+
const relationMatch = line.match(/@relation\((?:.*fields:\s*\[(\w+)\],)?\s*(?:.*references:\s*\[(\w+)\],?)?.*\)/);
|
|
171
|
+
if (relationMatch) {
|
|
172
|
+
foreignKey = relationMatch[1] || '';
|
|
173
|
+
localKey = relationMatch[2] || '';
|
|
174
|
+
}
|
|
175
|
+
model.relations.push({ name: fieldName, type: tsType, isArray, isOptional, foreignKey, localKey, relationName });
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const hasDefault = line.includes('@default') || line.includes('@updatedAt') || line.includes('@id');
|
|
179
|
+
const isId = line.includes('@id');
|
|
180
|
+
let description;
|
|
181
|
+
const descMatch = line.match(/@description\("(.+)"\)/);
|
|
182
|
+
if (descMatch)
|
|
183
|
+
description = descMatch[1];
|
|
184
|
+
model.fields.push({ name: fieldName, type: tsType, sqlType: cleanType, isOptional, hasDefault, isId, description });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
postProcessRelations(models) {
|
|
188
|
+
for (const model of models) {
|
|
189
|
+
for (const rel of model.relations) {
|
|
190
|
+
if (!rel.foreignKey || !rel.localKey) {
|
|
191
|
+
const targetModel = models.find(m => m.name === rel.type);
|
|
192
|
+
if (targetModel) {
|
|
193
|
+
let opposite = rel.relationName ?
|
|
194
|
+
targetModel.relations.find(r => r.type === model.name && r.relationName === rel.relationName && r.foreignKey && r.localKey) :
|
|
195
|
+
targetModel.relations.find(r => r.type === model.name && r.foreignKey && r.localKey);
|
|
196
|
+
if (opposite) {
|
|
197
|
+
rel.foreignKey = opposite.foreignKey;
|
|
198
|
+
rel.localKey = opposite.localKey;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.SchemaParser = SchemaParser;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PythonGenerator = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
class PythonGenerator {
|
|
9
|
+
constructor(outputPath) {
|
|
10
|
+
this.outputPath = outputPath;
|
|
11
|
+
}
|
|
12
|
+
generate(models) {
|
|
13
|
+
let pyContent = '# This file is auto-generated. Do not edit directly.\n\n';
|
|
14
|
+
// 1. MODEL_TO_TABLE
|
|
15
|
+
pyContent += 'MODEL_TO_TABLE = {\n';
|
|
16
|
+
for (const model of models) {
|
|
17
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
18
|
+
const fullTableName = `[${model.schemaName}].[${model.tableName}]`;
|
|
19
|
+
for (const prop of props) {
|
|
20
|
+
pyContent += ` "${prop}": "${fullTableName}",\n`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
pyContent += '}\n\n';
|
|
24
|
+
// 2. MODEL_FIELDS
|
|
25
|
+
pyContent += 'MODEL_FIELDS = {\n';
|
|
26
|
+
for (const model of models) {
|
|
27
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
28
|
+
const fieldsStr = `{ ${model.fields.map(f => `"${f.name}": "${f.type}${f.isOptional ? '?' : ''}"`).join(', ')} }`;
|
|
29
|
+
for (const prop of props) {
|
|
30
|
+
pyContent += ` "${prop}": ${fieldsStr},\n`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
pyContent += '}\n\n';
|
|
34
|
+
// 3. RELATION_MAP
|
|
35
|
+
pyContent += 'RELATION_MAP = {\n';
|
|
36
|
+
for (const model of models) {
|
|
37
|
+
const props = this.getAllPropertyVariations(model.name);
|
|
38
|
+
let relationsContent = `{\n`;
|
|
39
|
+
for (const rel of model.relations) {
|
|
40
|
+
relationsContent += ` "${rel.name}": {\n`;
|
|
41
|
+
relationsContent += ` "modelName": "${this.toCamelCase(rel.type)}",\n`;
|
|
42
|
+
relationsContent += ` "relationType": "${rel.isArray ? 'many' : 'one'}",\n`;
|
|
43
|
+
relationsContent += ` "foreignKey": "${rel.foreignKey || 'id'}",\n`;
|
|
44
|
+
relationsContent += ` "localKey": "${rel.localKey || 'id'}"\n`;
|
|
45
|
+
relationsContent += ` },\n`;
|
|
46
|
+
}
|
|
47
|
+
relationsContent += ` }`;
|
|
48
|
+
for (const prop of props) {
|
|
49
|
+
pyContent += ` "${prop}": ${relationsContent},\n`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
pyContent += '}\n';
|
|
53
|
+
fs_1.default.writeFileSync(this.outputPath, pyContent);
|
|
54
|
+
}
|
|
55
|
+
getAllPropertyVariations(modelName) {
|
|
56
|
+
const variations = new Set();
|
|
57
|
+
// 1. camelCase (User -> user, McpServer -> mcpServer)
|
|
58
|
+
variations.add(this.toCamelCase(modelName));
|
|
59
|
+
// 2. snake_case (User -> user, McpServer -> mcp_server)
|
|
60
|
+
variations.add(this.toSnakeCase(modelName));
|
|
61
|
+
const acronyms = ['LLM', 'AI', 'MCP', 'IT', 'QC', 'HR', 'MR', 'WH', 'SSIS', 'API', 'URL', 'ID', 'JSON'];
|
|
62
|
+
for (const acronym of acronyms) {
|
|
63
|
+
if (modelName.startsWith(acronym)) {
|
|
64
|
+
variations.add(acronym.toLowerCase() + modelName.slice(acronym.length));
|
|
65
|
+
variations.add(acronym[0].toLowerCase() + acronym.slice(1) + modelName.slice(acronym.length));
|
|
66
|
+
variations.add(this.toSnakeCase(acronym.toLowerCase() + modelName.slice(acronym.length)));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return Array.from(variations);
|
|
70
|
+
}
|
|
71
|
+
toCamelCase(str) {
|
|
72
|
+
if (!str)
|
|
73
|
+
return '';
|
|
74
|
+
return str[0].toLowerCase() + str.slice(1);
|
|
75
|
+
}
|
|
76
|
+
toSnakeCase(str) {
|
|
77
|
+
if (!str)
|
|
78
|
+
return '';
|
|
79
|
+
return str
|
|
80
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
|
81
|
+
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
|
|
82
|
+
.toLowerCase();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.PythonGenerator = PythonGenerator;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface Field {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
sqlType: string;
|
|
5
|
+
isOptional: boolean;
|
|
6
|
+
hasDefault: boolean;
|
|
7
|
+
isId: boolean;
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Relation {
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
isArray: boolean;
|
|
14
|
+
isOptional: boolean;
|
|
15
|
+
foreignKey: string;
|
|
16
|
+
localKey: string;
|
|
17
|
+
relationName: string;
|
|
18
|
+
}
|
|
19
|
+
export interface Model {
|
|
20
|
+
name: string;
|
|
21
|
+
tableName: string;
|
|
22
|
+
schemaName: string;
|
|
23
|
+
fields: Field[];
|
|
24
|
+
relations: Relation[];
|
|
25
|
+
compoundUniques?: string[][];
|
|
26
|
+
description?: string;
|
|
27
|
+
}
|
package/dist/migrate.js
CHANGED
|
@@ -15,8 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
require("dotenv/config");
|
|
16
16
|
const fs_1 = __importDefault(require("fs"));
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
|
-
const an5_adapters_1 = require("an5
|
|
19
|
-
const rootDir =
|
|
18
|
+
const an5_adapters_1 = require("@an5/adapters");
|
|
19
|
+
const rootDir = process.cwd();
|
|
20
20
|
let config = {};
|
|
21
21
|
try {
|
|
22
22
|
const configPath = path_1.default.join(rootDir, 'an5Orm.config.js');
|
|
@@ -295,4 +295,4 @@ main().catch((err) => {
|
|
|
295
295
|
console.error('❌ Migration failed:', err);
|
|
296
296
|
process.exit(1);
|
|
297
297
|
});
|
|
298
|
-
//# sourceMappingURL=migrate.js.map
|
|
298
|
+
//# sourceMappingURL=migrate.js.map
|
package/dist/pull.js
CHANGED
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
require("dotenv/config");
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const an5_adapters_1 = require("an5
|
|
10
|
-
const rootDir =
|
|
9
|
+
const an5_adapters_1 = require("@an5/adapters");
|
|
10
|
+
const rootDir = process.cwd();
|
|
11
11
|
let config = {};
|
|
12
12
|
try {
|
|
13
13
|
const configPath = path_1.default.join(rootDir, "an5Orm.config.js");
|
|
@@ -333,4 +333,4 @@ pull().catch((err) => {
|
|
|
333
333
|
console.error("❌ Pull failed:", err);
|
|
334
334
|
process.exit(1);
|
|
335
335
|
});
|
|
336
|
-
//# sourceMappingURL=pull.js.map
|
|
336
|
+
//# sourceMappingURL=pull.js.map
|
package/dist/push.js
CHANGED
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
require("dotenv/config");
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const an5_adapters_1 = require("an5
|
|
10
|
-
const rootDir =
|
|
9
|
+
const an5_adapters_1 = require("@an5/adapters");
|
|
10
|
+
const rootDir = process.cwd();
|
|
11
11
|
let config = {};
|
|
12
12
|
try {
|
|
13
13
|
const configPath = path_1.default.join(rootDir, "an5Orm.config.js");
|
|
@@ -255,4 +255,4 @@ push().catch((err) => {
|
|
|
255
255
|
console.error("❌ Push failed:", err);
|
|
256
256
|
process.exit(1);
|
|
257
257
|
});
|
|
258
|
-
//# sourceMappingURL=push.js.map
|
|
258
|
+
//# sourceMappingURL=push.js.map
|
package/generator/src/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@an5/orm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "The lightweight ORM for SQL Server with support for TypeScript, Python, and .NET (C#).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"an5": "./dist/cli.js",
|
|
10
|
+
"an5-orm": "./dist/cli.js"
|
|
11
|
+
},
|
|
8
12
|
"files": [
|
|
9
13
|
"dist/**/*.{js,d.ts}",
|
|
10
14
|
"generator/src/**/*.ts",
|