sonamu 0.2.46 → 0.2.48
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/bin/cli.js +48 -48
- package/dist/bin/cli.js.map +1 -1
- package/dist/{chunk-77XBF27L.js → chunk-76VBQWGE.js} +500 -186
- package/dist/chunk-76VBQWGE.js.map +1 -0
- package/dist/index.d.ts +67 -2
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/sonamu.ts +17 -0
- package/src/bin/cli.ts +1 -1
- package/src/entity/entity.ts +5 -0
- package/src/exceptions/so-exceptions.ts +27 -9
- package/src/index.ts +1 -0
- package/src/syncer/syncer.ts +32 -45
- package/src/templates/entity.template.ts +27 -25
- package/src/testing/fixture-manager.ts +431 -0
- package/src/types/types.ts +34 -0
- package/dist/chunk-77XBF27L.js.map +0 -1
|
@@ -156,7 +156,11 @@ var TemplateOptions = _zod.z.object({
|
|
|
156
156
|
entityId: _zod.z.string(),
|
|
157
157
|
parentId: _zod.z.string().optional(),
|
|
158
158
|
title: _zod.z.string(),
|
|
159
|
-
table: _zod.z.string().optional()
|
|
159
|
+
table: _zod.z.string().optional(),
|
|
160
|
+
props: _zod.z.array(_zod.z.object({})).optional(),
|
|
161
|
+
indexes: _zod.z.array(_zod.z.object({})).optional(),
|
|
162
|
+
subsets: _zod.z.object({}).optional(),
|
|
163
|
+
enums: _zod.z.object({}).optional()
|
|
160
164
|
}),
|
|
161
165
|
init_types: _zod.z.object({
|
|
162
166
|
entityId: _zod.z.string()
|
|
@@ -802,21 +806,21 @@ var InternalServerErrorException = class extends SoException {
|
|
|
802
806
|
};
|
|
803
807
|
var AlreadyProcessedException = class extends SoException {
|
|
804
808
|
constructor(message = "Already Processed", payload) {
|
|
805
|
-
super(
|
|
809
|
+
super(541, message, payload);
|
|
806
810
|
this.message = message;
|
|
807
811
|
this.payload = payload;
|
|
808
812
|
}
|
|
809
813
|
};
|
|
810
814
|
var DuplicateRowException = class extends SoException {
|
|
811
815
|
constructor(message = "Duplicate Row", payload) {
|
|
812
|
-
super(
|
|
816
|
+
super(542, message, payload);
|
|
813
817
|
this.message = message;
|
|
814
818
|
this.payload = payload;
|
|
815
819
|
}
|
|
816
820
|
};
|
|
817
821
|
var TargetNotFoundException = class extends SoException {
|
|
818
822
|
constructor(message = "Target Not Found", payload) {
|
|
819
|
-
super(
|
|
823
|
+
super(520, message, payload);
|
|
820
824
|
this.message = message;
|
|
821
825
|
this.payload = payload;
|
|
822
826
|
}
|
|
@@ -874,15 +878,11 @@ function nonNullable(value) {
|
|
|
874
878
|
return value !== null && value !== void 0;
|
|
875
879
|
}
|
|
876
880
|
|
|
877
|
-
// src/entity/entity-manager.ts
|
|
878
|
-
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
881
|
// src/entity/entity.ts
|
|
884
882
|
var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash);
|
|
885
883
|
|
|
884
|
+
// src/entity/entity-manager.ts
|
|
885
|
+
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
886
886
|
|
|
887
887
|
|
|
888
888
|
|
|
@@ -1251,7 +1251,7 @@ var Template__entity = class extends Template {
|
|
|
1251
1251
|
title: _nullishCoalesce(title, () => ( entityId)),
|
|
1252
1252
|
parentId,
|
|
1253
1253
|
table: _nullishCoalesce(table, () => ( names.fsPlural.replace(/\-/g, "_"))),
|
|
1254
|
-
props: [
|
|
1254
|
+
props: _optionalChain([options, 'access', _61 => _61.props, 'optionalAccess', _62 => _62.length]) ? options.props : [
|
|
1255
1255
|
{ name: "id", type: "integer", unsigned: true, desc: "ID" },
|
|
1256
1256
|
...parent ? [
|
|
1257
1257
|
{
|
|
@@ -1271,20 +1271,20 @@ var Template__entity = class extends Template {
|
|
|
1271
1271
|
dbDefault: "CURRENT_TIMESTAMP"
|
|
1272
1272
|
}
|
|
1273
1273
|
],
|
|
1274
|
-
indexes: [],
|
|
1275
|
-
subsets: {
|
|
1274
|
+
indexes: [..._nullishCoalesce(options.indexes, () => ( []))],
|
|
1275
|
+
subsets: _nullishCoalesce(options.subsets, () => ( {
|
|
1276
1276
|
...parentId ? {} : {
|
|
1277
1277
|
A: ["id", "created_at"]
|
|
1278
1278
|
}
|
|
1279
|
-
},
|
|
1280
|
-
enums: {
|
|
1279
|
+
})),
|
|
1280
|
+
enums: _nullishCoalesce(options.enums, () => ( {
|
|
1281
1281
|
...parentId ? {} : {
|
|
1282
1282
|
[`${names.capital}OrderBy`]: {
|
|
1283
1283
|
"id-desc": "ID\uCD5C\uC2E0\uC21C"
|
|
1284
1284
|
},
|
|
1285
1285
|
[`${names.capital}SearchField`]: { id: "ID" }
|
|
1286
1286
|
}
|
|
1287
|
-
}
|
|
1287
|
+
}))
|
|
1288
1288
|
}).trim(),
|
|
1289
1289
|
importKeys: []
|
|
1290
1290
|
};
|
|
@@ -1342,7 +1342,7 @@ var Template__view_list = class extends Template {
|
|
|
1342
1342
|
return `<>{/* object ${colName} */}</>`;
|
|
1343
1343
|
case "object-pick":
|
|
1344
1344
|
const pickedChild = col.children.find(
|
|
1345
|
-
(child) => child.name === _optionalChain([col, 'access',
|
|
1345
|
+
(child) => child.name === _optionalChain([col, 'access', _63 => _63.config, 'optionalAccess', _64 => _64.picked])
|
|
1346
1346
|
);
|
|
1347
1347
|
if (!pickedChild) {
|
|
1348
1348
|
throw new Error(`object-pick \uC120\uD0DD \uC2E4\uD328 (\uC624\uBE0C\uC81D\uD2B8: ${col.name})`);
|
|
@@ -1456,13 +1456,13 @@ var Template__view_list = class extends Template {
|
|
|
1456
1456
|
orderBy: "id-desc",
|
|
1457
1457
|
search: "title"
|
|
1458
1458
|
};
|
|
1459
|
-
const orderByZodType = _optionalChain([columns, 'access',
|
|
1459
|
+
const orderByZodType = _optionalChain([columns, 'access', _65 => _65.find, 'call', _66 => _66(
|
|
1460
1460
|
(col) => col.name === "orderBy"
|
|
1461
|
-
), 'optionalAccess',
|
|
1461
|
+
), 'optionalAccess', _67 => _67.zodType]);
|
|
1462
1462
|
if (orderByZodType && orderByZodType instanceof _zod.z.ZodEnum) {
|
|
1463
1463
|
def.orderBy = Object.keys(orderByZodType.Enum)[0];
|
|
1464
1464
|
}
|
|
1465
|
-
const searchZodType = _optionalChain([columns, 'access',
|
|
1465
|
+
const searchZodType = _optionalChain([columns, 'access', _68 => _68.find, 'call', _69 => _69((col) => col.name === "search"), 'optionalAccess', _70 => _70.zodType]);
|
|
1466
1466
|
if (searchZodType && searchZodType instanceof _zod.z.ZodEnum) {
|
|
1467
1467
|
def.search = Object.keys(searchZodType.Enum)[0];
|
|
1468
1468
|
}
|
|
@@ -1475,7 +1475,7 @@ var Template__view_list = class extends Template {
|
|
|
1475
1475
|
const propCandidate = entity.props.find((p) => p.name === col.name);
|
|
1476
1476
|
return {
|
|
1477
1477
|
name: col.name,
|
|
1478
|
-
label: _nullishCoalesce(_optionalChain([propCandidate, 'optionalAccess',
|
|
1478
|
+
label: _nullishCoalesce(_optionalChain([propCandidate, 'optionalAccess', _71 => _71.desc]), () => ( col.label)),
|
|
1479
1479
|
tc: `(row) => ${this.renderColumn(entityId, col, names)}`
|
|
1480
1480
|
};
|
|
1481
1481
|
});
|
|
@@ -1814,7 +1814,7 @@ var Template__model = class extends Template {
|
|
|
1814
1814
|
const names = EntityManager.getNamesFromId(entityId);
|
|
1815
1815
|
const entity = EntityManager.get(entityId);
|
|
1816
1816
|
const vlTpl = new Template__view_list();
|
|
1817
|
-
if (_optionalChain([listParamsNode, 'optionalAccess',
|
|
1817
|
+
if (_optionalChain([listParamsNode, 'optionalAccess', _72 => _72.children]) === void 0) {
|
|
1818
1818
|
throw new Error(`listParamsNode\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. ${entityId}`);
|
|
1819
1819
|
}
|
|
1820
1820
|
const def = vlTpl.getDefault(listParamsNode.children);
|
|
@@ -2328,7 +2328,7 @@ var Template__view_form = class extends Template {
|
|
|
2328
2328
|
const propCandidate = entity.props.find(
|
|
2329
2329
|
(prop) => prop.name === col.name
|
|
2330
2330
|
);
|
|
2331
|
-
col.label = _nullishCoalesce(_optionalChain([propCandidate, 'optionalAccess',
|
|
2331
|
+
col.label = _nullishCoalesce(_optionalChain([propCandidate, 'optionalAccess', _73 => _73.desc]), () => ( col.label));
|
|
2332
2332
|
return col;
|
|
2333
2333
|
});
|
|
2334
2334
|
const defaultValue = this.resolveDefaultValue(columns);
|
|
@@ -3123,7 +3123,7 @@ var Syncer = class {
|
|
|
3123
3123
|
name: name.escapedText ? name.escapedText.toString() : `nonameAt${index}`,
|
|
3124
3124
|
type,
|
|
3125
3125
|
optional: paramDec.optional === true,
|
|
3126
|
-
defaultDef: _optionalChain([paramDec, 'optionalAccess',
|
|
3126
|
+
defaultDef: _optionalChain([paramDec, 'optionalAccess', _74 => _74.defaultDef])
|
|
3127
3127
|
};
|
|
3128
3128
|
};
|
|
3129
3129
|
}
|
|
@@ -3431,7 +3431,7 @@ var Syncer = class {
|
|
|
3431
3431
|
return extendedApis;
|
|
3432
3432
|
}
|
|
3433
3433
|
resolveTypeNode(typeNode) {
|
|
3434
|
-
switch (_optionalChain([typeNode, 'optionalAccess',
|
|
3434
|
+
switch (_optionalChain([typeNode, 'optionalAccess', _75 => _75.kind])) {
|
|
3435
3435
|
case _typescript2.default.SyntaxKind.AnyKeyword:
|
|
3436
3436
|
return "any";
|
|
3437
3437
|
case _typescript2.default.SyntaxKind.UnknownKeyword:
|
|
@@ -3507,7 +3507,7 @@ var Syncer = class {
|
|
|
3507
3507
|
return {
|
|
3508
3508
|
t: "ref",
|
|
3509
3509
|
id: typeNode.typeName.escapedText.toString(),
|
|
3510
|
-
args: _optionalChain([typeNode, 'access',
|
|
3510
|
+
args: _optionalChain([typeNode, 'access', _76 => _76.typeArguments, 'optionalAccess', _77 => _77.map, 'call', _78 => _78(
|
|
3511
3511
|
(typeArg) => this.resolveTypeNode(typeArg)
|
|
3512
3512
|
)])
|
|
3513
3513
|
};
|
|
@@ -3812,36 +3812,30 @@ var Syncer = class {
|
|
|
3812
3812
|
const enumsKeys = Object.keys(enums).filter(
|
|
3813
3813
|
(name) => name !== names.constant
|
|
3814
3814
|
);
|
|
3815
|
-
return keys.reduce(
|
|
3816
|
-
(
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
result[`${key}__${componentId}`] = _fsextra2.default.existsSync(
|
|
3825
|
-
_path2.default.join(Sonamu.appRootPath, target2, p2)
|
|
3826
|
-
);
|
|
3827
|
-
});
|
|
3828
|
-
return result;
|
|
3829
|
-
}
|
|
3830
|
-
const { target, path: p } = tpl.getTargetAndPath(names);
|
|
3831
|
-
const { targets } = Sonamu.config.sync;
|
|
3832
|
-
if (target.includes(":target")) {
|
|
3833
|
-
targets.map((t) => {
|
|
3834
|
-
result[`${key}__${t}`] = _fsextra2.default.existsSync(
|
|
3835
|
-
_path2.default.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
3836
|
-
);
|
|
3837
|
-
});
|
|
3838
|
-
} else {
|
|
3839
|
-
result[key] = _fsextra2.default.existsSync(_path2.default.join(Sonamu.appRootPath, target, p));
|
|
3840
|
-
}
|
|
3815
|
+
return keys.reduce((result, key) => {
|
|
3816
|
+
const tpl = this.getTemplate(key);
|
|
3817
|
+
if (key.startsWith("view_enums")) {
|
|
3818
|
+
enumsKeys.map((componentId) => {
|
|
3819
|
+
const { target: target2, path: p2 } = tpl.getTargetAndPath(names, componentId);
|
|
3820
|
+
result[`${key}__${componentId}`] = _fsextra2.default.existsSync(
|
|
3821
|
+
_path2.default.join(Sonamu.appRootPath, target2, p2)
|
|
3822
|
+
);
|
|
3823
|
+
});
|
|
3841
3824
|
return result;
|
|
3842
|
-
}
|
|
3843
|
-
{}
|
|
3844
|
-
|
|
3825
|
+
}
|
|
3826
|
+
const { target, path: p } = tpl.getTargetAndPath(names);
|
|
3827
|
+
const { targets } = Sonamu.config.sync;
|
|
3828
|
+
if (target.includes(":target")) {
|
|
3829
|
+
targets.map((t) => {
|
|
3830
|
+
result[`${key}__${t}`] = _fsextra2.default.existsSync(
|
|
3831
|
+
_path2.default.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
3832
|
+
);
|
|
3833
|
+
});
|
|
3834
|
+
} else {
|
|
3835
|
+
result[key] = _fsextra2.default.existsSync(_path2.default.join(Sonamu.appRootPath, target, p));
|
|
3836
|
+
}
|
|
3837
|
+
return result;
|
|
3838
|
+
}, {});
|
|
3845
3839
|
}
|
|
3846
3840
|
async getZodTypeById(zodTypeId) {
|
|
3847
3841
|
const modulePath = EntityManager.getModulePath(zodTypeId);
|
|
@@ -3881,12 +3875,14 @@ var Syncer = class {
|
|
|
3881
3875
|
const obj = await propNode.children.reduce(
|
|
3882
3876
|
async (promise, childPropNode) => {
|
|
3883
3877
|
const result = await promise;
|
|
3884
|
-
result[childPropNode.prop.name] = await this.propNodeToZodType(
|
|
3878
|
+
result[childPropNode.prop.name] = await this.propNodeToZodType(
|
|
3879
|
+
childPropNode
|
|
3880
|
+
);
|
|
3885
3881
|
return result;
|
|
3886
3882
|
},
|
|
3887
3883
|
{}
|
|
3888
3884
|
);
|
|
3889
|
-
if (_optionalChain([propNode, 'access',
|
|
3885
|
+
if (_optionalChain([propNode, 'access', _79 => _79.prop, 'optionalAccess', _80 => _80.nullable]) === true) {
|
|
3890
3886
|
return _zod.z.object(obj).nullable();
|
|
3891
3887
|
} else {
|
|
3892
3888
|
return _zod.z.object(obj);
|
|
@@ -4083,21 +4079,16 @@ var Syncer = class {
|
|
|
4083
4079
|
});
|
|
4084
4080
|
return columnsNode;
|
|
4085
4081
|
}
|
|
4086
|
-
async createEntity(
|
|
4087
|
-
if (!/^[A-Z][a-zA-Z0-9]*$/.test(entityId)) {
|
|
4082
|
+
async createEntity(form) {
|
|
4083
|
+
if (!/^[A-Z][a-zA-Z0-9]*$/.test(form.entityId)) {
|
|
4088
4084
|
throw new BadRequestException("entityId\uB294 CamelCase \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.");
|
|
4089
4085
|
}
|
|
4090
|
-
await this.generateTemplate("entity",
|
|
4091
|
-
entityId,
|
|
4092
|
-
parentId,
|
|
4093
|
-
table,
|
|
4094
|
-
title
|
|
4095
|
-
});
|
|
4086
|
+
await this.generateTemplate("entity", form);
|
|
4096
4087
|
await EntityManager.reload();
|
|
4097
4088
|
await this.actionGenerateSchemas();
|
|
4098
|
-
if (parentId === void 0) {
|
|
4089
|
+
if (form.parentId === void 0) {
|
|
4099
4090
|
await this.generateTemplate("init_types", {
|
|
4100
|
-
entityId
|
|
4091
|
+
entityId: form.entityId
|
|
4101
4092
|
});
|
|
4102
4093
|
}
|
|
4103
4094
|
}
|
|
@@ -4302,7 +4293,7 @@ var UpsertBuilder = class {
|
|
|
4302
4293
|
this.tables.set(tableName, {
|
|
4303
4294
|
references: /* @__PURE__ */ new Set(),
|
|
4304
4295
|
rows: [],
|
|
4305
|
-
uniqueIndexes: _nullishCoalesce(_optionalChain([tableSpec, 'optionalAccess',
|
|
4296
|
+
uniqueIndexes: _nullishCoalesce(_optionalChain([tableSpec, 'optionalAccess', _81 => _81.uniqueIndexes]), () => ( [])),
|
|
4306
4297
|
uniquesMap: /* @__PURE__ */ new Map()
|
|
4307
4298
|
});
|
|
4308
4299
|
}
|
|
@@ -4716,7 +4707,7 @@ var BaseModelClass = class {
|
|
|
4716
4707
|
_chalk2.default.blue(countQuery.toQuery().toString())
|
|
4717
4708
|
);
|
|
4718
4709
|
}
|
|
4719
|
-
return _nullishCoalesce(_optionalChain([countRow, 'optionalAccess',
|
|
4710
|
+
return _nullishCoalesce(_optionalChain([countRow, 'optionalAccess', _82 => _82.total]), () => ( 0));
|
|
4720
4711
|
})();
|
|
4721
4712
|
const rows = await (async () => {
|
|
4722
4713
|
if (queryMode === "count") {
|
|
@@ -4805,6 +4796,7 @@ var SonamuClass = class {
|
|
|
4805
4796
|
this._dbConfig = null;
|
|
4806
4797
|
this._syncer = null;
|
|
4807
4798
|
this._config = null;
|
|
4799
|
+
this._secrets = null;
|
|
4808
4800
|
}
|
|
4809
4801
|
set apiRootPath(apiRootPath) {
|
|
4810
4802
|
this._apiRootPath = apiRootPath;
|
|
@@ -4845,6 +4837,12 @@ var SonamuClass = class {
|
|
|
4845
4837
|
}
|
|
4846
4838
|
return this._config;
|
|
4847
4839
|
}
|
|
4840
|
+
set secrets(secrets) {
|
|
4841
|
+
this._secrets = secrets;
|
|
4842
|
+
}
|
|
4843
|
+
get secrets() {
|
|
4844
|
+
return this._secrets;
|
|
4845
|
+
}
|
|
4848
4846
|
async init(doSilent = false, enableSync = true, apiRootPath) {
|
|
4849
4847
|
if (this.isInitialized) {
|
|
4850
4848
|
return;
|
|
@@ -4852,12 +4850,18 @@ var SonamuClass = class {
|
|
|
4852
4850
|
!doSilent && console.time(_chalk2.default.cyan("Sonamu.init"));
|
|
4853
4851
|
this.apiRootPath = await _asyncNullishCoalesce(apiRootPath, async () => ( await findApiRootPath()));
|
|
4854
4852
|
const configPath = _path2.default.join(this.apiRootPath, "sonamu.config.json");
|
|
4853
|
+
const secretsPath = _path2.default.join(this.apiRootPath, "sonamu.secrets.json");
|
|
4855
4854
|
if (_fsextra2.default.existsSync(configPath) === false) {
|
|
4856
4855
|
throw new Error(`Cannot find sonamu.config.json in ${configPath}`);
|
|
4857
4856
|
}
|
|
4858
4857
|
this.config = JSON.parse(
|
|
4859
4858
|
_fsextra2.default.readFileSync(configPath).toString()
|
|
4860
4859
|
);
|
|
4860
|
+
if (_fsextra2.default.existsSync(secretsPath)) {
|
|
4861
|
+
this.secrets = JSON.parse(
|
|
4862
|
+
_fsextra2.default.readFileSync(secretsPath).toString()
|
|
4863
|
+
);
|
|
4864
|
+
}
|
|
4861
4865
|
this.dbConfig = await DB.readKnexfile();
|
|
4862
4866
|
!doSilent && console.log(_chalk2.default.green("DB Config Loaded!"));
|
|
4863
4867
|
attachOnDuplicateUpdate();
|
|
@@ -4969,8 +4973,125 @@ var SonamuClass = class {
|
|
|
4969
4973
|
};
|
|
4970
4974
|
var Sonamu = new SonamuClass();
|
|
4971
4975
|
|
|
4976
|
+
// src/entity/entity-manager.ts
|
|
4977
|
+
|
|
4978
|
+
var EntityManagerClass = class {
|
|
4979
|
+
constructor() {
|
|
4980
|
+
this.entities = /* @__PURE__ */ new Map();
|
|
4981
|
+
this.modulePaths = /* @__PURE__ */ new Map();
|
|
4982
|
+
this.tableSpecs = /* @__PURE__ */ new Map();
|
|
4983
|
+
this.isAutoloaded = false;
|
|
4984
|
+
}
|
|
4985
|
+
// 경로 전달받아 모든 entity.json 파일 로드
|
|
4986
|
+
async autoload(doSilent = false) {
|
|
4987
|
+
if (this.isAutoloaded) {
|
|
4988
|
+
return;
|
|
4989
|
+
}
|
|
4990
|
+
const pathPattern = _path2.default.join(
|
|
4991
|
+
Sonamu.apiRootPath,
|
|
4992
|
+
"/src/application/**/*.entity.json"
|
|
4993
|
+
);
|
|
4994
|
+
!doSilent && console.log(_chalk2.default.yellow(`autoload ${pathPattern}`));
|
|
4995
|
+
return new Promise((resolve) => {
|
|
4996
|
+
_glob2.default.glob(_path2.default.resolve(pathPattern), (_err, files) => {
|
|
4997
|
+
Promise.all(
|
|
4998
|
+
files.map(async (file) => {
|
|
4999
|
+
this.register(JSON.parse(_fsextra2.default.readFileSync(file).toString()));
|
|
5000
|
+
})
|
|
5001
|
+
).then(() => {
|
|
5002
|
+
resolve("ok");
|
|
5003
|
+
this.isAutoloaded = true;
|
|
5004
|
+
});
|
|
5005
|
+
});
|
|
5006
|
+
});
|
|
5007
|
+
}
|
|
5008
|
+
async reload(doSilent = false) {
|
|
5009
|
+
console.log("reload");
|
|
5010
|
+
this.entities.clear();
|
|
5011
|
+
this.modulePaths.clear();
|
|
5012
|
+
this.tableSpecs.clear();
|
|
5013
|
+
this.isAutoloaded = false;
|
|
5014
|
+
const sonamuPath = _path2.default.join(
|
|
5015
|
+
Sonamu.apiRootPath,
|
|
5016
|
+
"dist/application/sonamu.generated.js"
|
|
5017
|
+
);
|
|
5018
|
+
if (__require.cache[sonamuPath]) {
|
|
5019
|
+
delete __require.cache[sonamuPath];
|
|
5020
|
+
}
|
|
5021
|
+
return this.autoload(doSilent);
|
|
5022
|
+
}
|
|
5023
|
+
register(json) {
|
|
5024
|
+
const entity = new Entity(json);
|
|
5025
|
+
this.entities.set(json.id, entity);
|
|
5026
|
+
}
|
|
5027
|
+
get(entityId) {
|
|
5028
|
+
const entity = this.entities.get(entityId);
|
|
5029
|
+
if (entity === void 0) {
|
|
5030
|
+
throw new Error(`\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 Entity \uC694\uCCAD ${entityId}`);
|
|
5031
|
+
}
|
|
5032
|
+
return entity;
|
|
5033
|
+
}
|
|
5034
|
+
exists(entityId) {
|
|
5035
|
+
const entity = this.entities.get(entityId);
|
|
5036
|
+
return entity !== void 0;
|
|
5037
|
+
}
|
|
5038
|
+
getAllIds() {
|
|
5039
|
+
return Array.from(EntityManager.entities.keys());
|
|
5040
|
+
}
|
|
5041
|
+
getAllParentIds() {
|
|
5042
|
+
return this.getAllIds().filter((entityId) => {
|
|
5043
|
+
const entity = this.get(entityId);
|
|
5044
|
+
return entity.parentId === void 0;
|
|
5045
|
+
});
|
|
5046
|
+
}
|
|
5047
|
+
getChildrenIds(parentId) {
|
|
5048
|
+
return this.getAllIds().filter((entityId) => {
|
|
5049
|
+
const entity = this.get(entityId);
|
|
5050
|
+
return entity.parentId === parentId;
|
|
5051
|
+
});
|
|
5052
|
+
}
|
|
5053
|
+
setModulePath(key, modulePath) {
|
|
5054
|
+
this.modulePaths.set(key, modulePath);
|
|
5055
|
+
}
|
|
5056
|
+
getModulePath(key) {
|
|
5057
|
+
const modulePath = this.modulePaths.get(key);
|
|
5058
|
+
if (modulePath === void 0) {
|
|
5059
|
+
throw new Error(`\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uBAA8\uB4C8 \uD328\uC2A4 \uC694\uCCAD ${key}`);
|
|
5060
|
+
}
|
|
5061
|
+
return modulePath;
|
|
5062
|
+
}
|
|
5063
|
+
setTableSpec(tableSpec) {
|
|
5064
|
+
this.tableSpecs.set(tableSpec.name, tableSpec);
|
|
5065
|
+
}
|
|
5066
|
+
getTableSpec(key) {
|
|
5067
|
+
const tableSpec = this.tableSpecs.get(key);
|
|
5068
|
+
if (tableSpec === void 0) {
|
|
5069
|
+
throw new Error(`\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uD14C\uC774\uBE14 \uC2A4\uD399 \uC694\uCCAD ${key}`);
|
|
5070
|
+
}
|
|
5071
|
+
return tableSpec;
|
|
5072
|
+
}
|
|
5073
|
+
getNamesFromId(entityId) {
|
|
5074
|
+
const pluralized = _inflection2.default.pluralize(entityId) === entityId ? `${entityId}List` : _inflection2.default.pluralize(entityId);
|
|
5075
|
+
return {
|
|
5076
|
+
fs: _inflection2.default.dasherize(_inflection2.default.underscore(entityId)).toLowerCase(),
|
|
5077
|
+
fsPlural: _inflection2.default.dasherize(_inflection2.default.underscore(pluralized)).toLowerCase(),
|
|
5078
|
+
camel: _inflection2.default.camelize(entityId, true),
|
|
5079
|
+
camelPlural: _inflection2.default.camelize(pluralized, true),
|
|
5080
|
+
capital: entityId,
|
|
5081
|
+
capitalPlural: pluralized,
|
|
5082
|
+
upper: entityId.toUpperCase(),
|
|
5083
|
+
constant: _inflection2.default.underscore(entityId).toUpperCase()
|
|
5084
|
+
};
|
|
5085
|
+
}
|
|
5086
|
+
};
|
|
5087
|
+
var EntityManager = new EntityManagerClass();
|
|
5088
|
+
|
|
4972
5089
|
// src/entity/entity.ts
|
|
4973
5090
|
|
|
5091
|
+
|
|
5092
|
+
|
|
5093
|
+
|
|
5094
|
+
|
|
4974
5095
|
var Entity = class {
|
|
4975
5096
|
constructor({
|
|
4976
5097
|
id,
|
|
@@ -5180,7 +5301,7 @@ var Entity = class {
|
|
|
5180
5301
|
const relSubsetQuery = relEntity.resolveSubsetQuery("", relFields);
|
|
5181
5302
|
let manyJoin;
|
|
5182
5303
|
if (isHasManyRelationProp(relation)) {
|
|
5183
|
-
const fromCol = _nullishCoalesce(_optionalChain([relation, 'optionalAccess',
|
|
5304
|
+
const fromCol = _nullishCoalesce(_optionalChain([relation, 'optionalAccess', _83 => _83.fromColumn]), () => ( "id"));
|
|
5184
5305
|
manyJoin = {
|
|
5185
5306
|
fromTable: this.table,
|
|
5186
5307
|
fromCol,
|
|
@@ -5577,6 +5698,9 @@ var Entity = class {
|
|
|
5577
5698
|
}
|
|
5578
5699
|
}
|
|
5579
5700
|
}
|
|
5701
|
+
EntityManager.get(this.id).indexes.map((index) => {
|
|
5702
|
+
index.columns = index.columns.filter((col) => col !== oldName);
|
|
5703
|
+
});
|
|
5580
5704
|
this.props.splice(at, 1);
|
|
5581
5705
|
await Promise.all(entities.map(async (entity) => entity.save()));
|
|
5582
5706
|
}
|
|
@@ -5607,119 +5731,6 @@ var Entity = class {
|
|
|
5607
5731
|
}
|
|
5608
5732
|
};
|
|
5609
5733
|
|
|
5610
|
-
// src/entity/entity-manager.ts
|
|
5611
|
-
|
|
5612
|
-
var EntityManagerClass = class {
|
|
5613
|
-
constructor() {
|
|
5614
|
-
this.entities = /* @__PURE__ */ new Map();
|
|
5615
|
-
this.modulePaths = /* @__PURE__ */ new Map();
|
|
5616
|
-
this.tableSpecs = /* @__PURE__ */ new Map();
|
|
5617
|
-
this.isAutoloaded = false;
|
|
5618
|
-
}
|
|
5619
|
-
// 경로 전달받아 모든 entity.json 파일 로드
|
|
5620
|
-
async autoload(doSilent = false) {
|
|
5621
|
-
if (this.isAutoloaded) {
|
|
5622
|
-
return;
|
|
5623
|
-
}
|
|
5624
|
-
const pathPattern = _path2.default.join(
|
|
5625
|
-
Sonamu.apiRootPath,
|
|
5626
|
-
"/src/application/**/*.entity.json"
|
|
5627
|
-
);
|
|
5628
|
-
!doSilent && console.log(_chalk2.default.yellow(`autoload ${pathPattern}`));
|
|
5629
|
-
return new Promise((resolve) => {
|
|
5630
|
-
_glob2.default.glob(_path2.default.resolve(pathPattern), (_err, files) => {
|
|
5631
|
-
Promise.all(
|
|
5632
|
-
files.map(async (file) => {
|
|
5633
|
-
this.register(JSON.parse(_fsextra2.default.readFileSync(file).toString()));
|
|
5634
|
-
})
|
|
5635
|
-
).then(() => {
|
|
5636
|
-
resolve("ok");
|
|
5637
|
-
this.isAutoloaded = true;
|
|
5638
|
-
});
|
|
5639
|
-
});
|
|
5640
|
-
});
|
|
5641
|
-
}
|
|
5642
|
-
async reload(doSilent = false) {
|
|
5643
|
-
console.log("reload");
|
|
5644
|
-
this.entities.clear();
|
|
5645
|
-
this.modulePaths.clear();
|
|
5646
|
-
this.tableSpecs.clear();
|
|
5647
|
-
this.isAutoloaded = false;
|
|
5648
|
-
const sonamuPath = _path2.default.join(
|
|
5649
|
-
Sonamu.apiRootPath,
|
|
5650
|
-
"dist/application/sonamu.generated.js"
|
|
5651
|
-
);
|
|
5652
|
-
if (__require.cache[sonamuPath]) {
|
|
5653
|
-
delete __require.cache[sonamuPath];
|
|
5654
|
-
}
|
|
5655
|
-
return this.autoload(doSilent);
|
|
5656
|
-
}
|
|
5657
|
-
register(json) {
|
|
5658
|
-
const entity = new Entity(json);
|
|
5659
|
-
this.entities.set(json.id, entity);
|
|
5660
|
-
}
|
|
5661
|
-
get(entityId) {
|
|
5662
|
-
const entity = this.entities.get(entityId);
|
|
5663
|
-
if (entity === void 0) {
|
|
5664
|
-
throw new Error(`\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 Entity \uC694\uCCAD ${entityId}`);
|
|
5665
|
-
}
|
|
5666
|
-
return entity;
|
|
5667
|
-
}
|
|
5668
|
-
exists(entityId) {
|
|
5669
|
-
const entity = this.entities.get(entityId);
|
|
5670
|
-
return entity !== void 0;
|
|
5671
|
-
}
|
|
5672
|
-
getAllIds() {
|
|
5673
|
-
return Array.from(EntityManager.entities.keys());
|
|
5674
|
-
}
|
|
5675
|
-
getAllParentIds() {
|
|
5676
|
-
return this.getAllIds().filter((entityId) => {
|
|
5677
|
-
const entity = this.get(entityId);
|
|
5678
|
-
return entity.parentId === void 0;
|
|
5679
|
-
});
|
|
5680
|
-
}
|
|
5681
|
-
getChildrenIds(parentId) {
|
|
5682
|
-
return this.getAllIds().filter((entityId) => {
|
|
5683
|
-
const entity = this.get(entityId);
|
|
5684
|
-
return entity.parentId === parentId;
|
|
5685
|
-
});
|
|
5686
|
-
}
|
|
5687
|
-
setModulePath(key, modulePath) {
|
|
5688
|
-
this.modulePaths.set(key, modulePath);
|
|
5689
|
-
}
|
|
5690
|
-
getModulePath(key) {
|
|
5691
|
-
const modulePath = this.modulePaths.get(key);
|
|
5692
|
-
if (modulePath === void 0) {
|
|
5693
|
-
throw new Error(`\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uBAA8\uB4C8 \uD328\uC2A4 \uC694\uCCAD ${key}`);
|
|
5694
|
-
}
|
|
5695
|
-
return modulePath;
|
|
5696
|
-
}
|
|
5697
|
-
setTableSpec(tableSpec) {
|
|
5698
|
-
this.tableSpecs.set(tableSpec.name, tableSpec);
|
|
5699
|
-
}
|
|
5700
|
-
getTableSpec(key) {
|
|
5701
|
-
const tableSpec = this.tableSpecs.get(key);
|
|
5702
|
-
if (tableSpec === void 0) {
|
|
5703
|
-
throw new Error(`\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uD14C\uC774\uBE14 \uC2A4\uD399 \uC694\uCCAD ${key}`);
|
|
5704
|
-
}
|
|
5705
|
-
return tableSpec;
|
|
5706
|
-
}
|
|
5707
|
-
getNamesFromId(entityId) {
|
|
5708
|
-
const pluralized = _inflection2.default.pluralize(entityId) === entityId ? `${entityId}List` : _inflection2.default.pluralize(entityId);
|
|
5709
|
-
return {
|
|
5710
|
-
fs: _inflection2.default.dasherize(_inflection2.default.underscore(entityId)).toLowerCase(),
|
|
5711
|
-
fsPlural: _inflection2.default.dasherize(_inflection2.default.underscore(pluralized)).toLowerCase(),
|
|
5712
|
-
camel: _inflection2.default.camelize(entityId, true),
|
|
5713
|
-
camelPlural: _inflection2.default.camelize(pluralized, true),
|
|
5714
|
-
capital: entityId,
|
|
5715
|
-
capitalPlural: pluralized,
|
|
5716
|
-
upper: entityId.toUpperCase(),
|
|
5717
|
-
constant: _inflection2.default.underscore(entityId).toUpperCase()
|
|
5718
|
-
};
|
|
5719
|
-
}
|
|
5720
|
-
};
|
|
5721
|
-
var EntityManager = new EntityManagerClass();
|
|
5722
|
-
|
|
5723
5734
|
// src/entity/migrator.ts
|
|
5724
5735
|
|
|
5725
5736
|
|
|
@@ -6495,7 +6506,7 @@ ${onlyTs.map((f) => f.name).join("\n")}`
|
|
|
6495
6506
|
const [, keyName, from, referencesTable, referencesField, onClause] = matched2;
|
|
6496
6507
|
const [onUpdateFull, _onUpdate] = _nullishCoalesce((_nullishCoalesce(onClause, () => ( ""))).match(/ON UPDATE ([A-Z ]+)$/), () => ( []));
|
|
6497
6508
|
const onUpdate = _nullishCoalesce(_onUpdate, () => ( "NO ACTION"));
|
|
6498
|
-
const onDelete = _nullishCoalesce(_optionalChain([(_nullishCoalesce(onClause, () => ( ""))), 'access',
|
|
6509
|
+
const onDelete = _nullishCoalesce(_optionalChain([(_nullishCoalesce(onClause, () => ( ""))), 'access', _84 => _84.replace, 'call', _85 => _85(_nullishCoalesce(onUpdateFull, () => ( "")), ""), 'access', _86 => _86.match, 'call', _87 => _87(/ON DELETE ([A-Z ]+) /), 'optionalAccess', _88 => _88[1]]), () => ( "NO ACTION"));
|
|
6499
6510
|
return {
|
|
6500
6511
|
keyName,
|
|
6501
6512
|
from,
|
|
@@ -7179,10 +7190,13 @@ ${onlyTs.map((f) => f.name).join("\n")}`
|
|
|
7179
7190
|
|
|
7180
7191
|
|
|
7181
7192
|
|
|
7193
|
+
|
|
7194
|
+
var _fs = require('fs');
|
|
7182
7195
|
var FixtureManagerClass = class {
|
|
7183
7196
|
constructor() {
|
|
7184
7197
|
this._tdb = null;
|
|
7185
7198
|
this._fdb = null;
|
|
7199
|
+
this.dependencyGraph = /* @__PURE__ */ new Map();
|
|
7186
7200
|
}
|
|
7187
7201
|
set tdb(tdb) {
|
|
7188
7202
|
this._tdb = tdb;
|
|
@@ -7359,6 +7373,305 @@ var FixtureManagerClass = class {
|
|
|
7359
7373
|
}
|
|
7360
7374
|
await BaseModel.destroy();
|
|
7361
7375
|
}
|
|
7376
|
+
async getFixtures(sourceDBName, targetDBName, searchOptions) {
|
|
7377
|
+
const sourceDB = _knex2.default.call(void 0, Sonamu.dbConfig[sourceDBName]);
|
|
7378
|
+
const targetDB = _knex2.default.call(void 0, Sonamu.dbConfig[targetDBName]);
|
|
7379
|
+
const { entityId, field, value, searchType } = searchOptions;
|
|
7380
|
+
const entity = EntityManager.get(entityId);
|
|
7381
|
+
const column = _optionalChain([entity, 'access', _89 => _89.props, 'access', _90 => _90.find, 'call', _91 => _91((prop) => prop.name === field), 'optionalAccess', _92 => _92.type]) === "relation" ? `${field}_id` : field;
|
|
7382
|
+
let query = sourceDB(entity.table);
|
|
7383
|
+
if (searchType === "equals") {
|
|
7384
|
+
query = query.where(column, value);
|
|
7385
|
+
} else if (searchType === "like") {
|
|
7386
|
+
query = query.where(column, "like", `%${value}%`);
|
|
7387
|
+
}
|
|
7388
|
+
const rows = await query;
|
|
7389
|
+
if (rows.length === 0) {
|
|
7390
|
+
throw new Error("No records found");
|
|
7391
|
+
}
|
|
7392
|
+
const visitedEntities = /* @__PURE__ */ new Set();
|
|
7393
|
+
const records = [];
|
|
7394
|
+
for (const row of rows) {
|
|
7395
|
+
const initialRecordsLength = records.length;
|
|
7396
|
+
await this.createFixtureRecord(entity, row, visitedEntities, records);
|
|
7397
|
+
const currentFixtureRecord = records.find(
|
|
7398
|
+
(r) => r.fixtureId === `${entityId}#${row.id}`
|
|
7399
|
+
);
|
|
7400
|
+
if (currentFixtureRecord) {
|
|
7401
|
+
currentFixtureRecord.fetchedRecords = records.filter((r) => r.fixtureId !== currentFixtureRecord.fixtureId).slice(initialRecordsLength).map((r) => r.fixtureId);
|
|
7402
|
+
}
|
|
7403
|
+
}
|
|
7404
|
+
for await (const record of records) {
|
|
7405
|
+
const entity2 = EntityManager.get(record.entityId);
|
|
7406
|
+
const rows2 = [];
|
|
7407
|
+
const row = await targetDB(entity2.table).where("id", record.id).first();
|
|
7408
|
+
if (row) {
|
|
7409
|
+
await this.createFixtureRecord(
|
|
7410
|
+
entity2,
|
|
7411
|
+
row,
|
|
7412
|
+
/* @__PURE__ */ new Set(),
|
|
7413
|
+
rows2,
|
|
7414
|
+
true,
|
|
7415
|
+
targetDB
|
|
7416
|
+
);
|
|
7417
|
+
record.target = rows2[0];
|
|
7418
|
+
}
|
|
7419
|
+
}
|
|
7420
|
+
return records;
|
|
7421
|
+
}
|
|
7422
|
+
async createFixtureRecord(entity, row, visitedEntities, records, singleRecord = false, _db) {
|
|
7423
|
+
const fixtureId = `${entity.id}#${row.id}`;
|
|
7424
|
+
if (visitedEntities.has(fixtureId)) {
|
|
7425
|
+
return;
|
|
7426
|
+
}
|
|
7427
|
+
visitedEntities.add(fixtureId);
|
|
7428
|
+
const record = {
|
|
7429
|
+
fixtureId,
|
|
7430
|
+
entityId: entity.id,
|
|
7431
|
+
id: row.id,
|
|
7432
|
+
columns: {},
|
|
7433
|
+
fetchedRecords: [],
|
|
7434
|
+
belongsRecords: []
|
|
7435
|
+
};
|
|
7436
|
+
for (const prop of entity.props) {
|
|
7437
|
+
if (isVirtualProp(prop)) {
|
|
7438
|
+
continue;
|
|
7439
|
+
}
|
|
7440
|
+
record.columns[prop.name] = {
|
|
7441
|
+
prop,
|
|
7442
|
+
value: row[prop.name]
|
|
7443
|
+
};
|
|
7444
|
+
const db = _nullishCoalesce(_db, () => ( BaseModel.getDB("w")));
|
|
7445
|
+
if (isManyToManyRelationProp(prop)) {
|
|
7446
|
+
const relatedEntity = EntityManager.get(prop.with);
|
|
7447
|
+
const throughTable = prop.joinTable;
|
|
7448
|
+
const fromColumn = `${_inflection2.default.singularize(entity.table)}_id`;
|
|
7449
|
+
const toColumn = `${_inflection2.default.singularize(relatedEntity.table)}_id`;
|
|
7450
|
+
const relatedIds = await db(throughTable).where(fromColumn, row.id).pluck(toColumn);
|
|
7451
|
+
record.columns[prop.name].value = relatedIds;
|
|
7452
|
+
} else if (isHasManyRelationProp(prop)) {
|
|
7453
|
+
const relatedEntity = EntityManager.get(prop.with);
|
|
7454
|
+
const relatedIds = await db(relatedEntity.table).where(prop.joinColumn, row.id).pluck("id");
|
|
7455
|
+
record.columns[prop.name].value = relatedIds;
|
|
7456
|
+
} else if (isOneToOneRelationProp(prop) && !prop.hasJoinColumn) {
|
|
7457
|
+
const relatedEntity = EntityManager.get(prop.with);
|
|
7458
|
+
const relatedProp = relatedEntity.props.find(
|
|
7459
|
+
(p) => p.type === "relation" && p.with === entity.id
|
|
7460
|
+
);
|
|
7461
|
+
if (relatedProp) {
|
|
7462
|
+
const relatedRow = await db(relatedEntity.table).where("id", row.id).first();
|
|
7463
|
+
record.columns[prop.name].value = _optionalChain([relatedRow, 'optionalAccess', _93 => _93.id]);
|
|
7464
|
+
}
|
|
7465
|
+
} else if (isRelationProp(prop)) {
|
|
7466
|
+
const relatedId = row[`${prop.name}_id`];
|
|
7467
|
+
record.columns[prop.name].value = relatedId;
|
|
7468
|
+
if (relatedId) {
|
|
7469
|
+
record.belongsRecords.push(`${prop.with}#${relatedId}`);
|
|
7470
|
+
}
|
|
7471
|
+
if (!singleRecord && relatedId) {
|
|
7472
|
+
const relatedEntity = EntityManager.get(prop.with);
|
|
7473
|
+
const relatedRow = await db(relatedEntity.table).where("id", relatedId).first();
|
|
7474
|
+
if (relatedRow) {
|
|
7475
|
+
await this.createFixtureRecord(
|
|
7476
|
+
relatedEntity,
|
|
7477
|
+
relatedRow,
|
|
7478
|
+
visitedEntities,
|
|
7479
|
+
records,
|
|
7480
|
+
singleRecord,
|
|
7481
|
+
_db
|
|
7482
|
+
);
|
|
7483
|
+
}
|
|
7484
|
+
}
|
|
7485
|
+
}
|
|
7486
|
+
}
|
|
7487
|
+
records.push(record);
|
|
7488
|
+
}
|
|
7489
|
+
async insertFixtures(dbName, fixtures) {
|
|
7490
|
+
this.buildDependencyGraph(fixtures);
|
|
7491
|
+
const insertionOrder = this.getInsertionOrder();
|
|
7492
|
+
const db = _knex2.default.call(void 0, Sonamu.dbConfig[dbName]);
|
|
7493
|
+
await db.transaction(async (trx) => {
|
|
7494
|
+
await trx.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
7495
|
+
for (const fixtureId of insertionOrder) {
|
|
7496
|
+
const fixture = fixtures.find((f) => f.fixtureId === fixtureId);
|
|
7497
|
+
await this.insertFixture(trx, fixture);
|
|
7498
|
+
}
|
|
7499
|
+
for (const fixtureId of insertionOrder) {
|
|
7500
|
+
const fixture = fixtures.find((f) => f.fixtureId === fixtureId);
|
|
7501
|
+
await this.handleManyToManyRelations(trx, fixture, fixtures);
|
|
7502
|
+
}
|
|
7503
|
+
await trx.raw(`SET FOREIGN_KEY_CHECKS = 1`);
|
|
7504
|
+
});
|
|
7505
|
+
const records = [];
|
|
7506
|
+
for await (const r of fixtures) {
|
|
7507
|
+
const entity = EntityManager.get(r.entityId);
|
|
7508
|
+
const record = await db(entity.table).where("id", r.id).first();
|
|
7509
|
+
records.push({
|
|
7510
|
+
entityId: r.entityId,
|
|
7511
|
+
data: record
|
|
7512
|
+
});
|
|
7513
|
+
}
|
|
7514
|
+
return records;
|
|
7515
|
+
}
|
|
7516
|
+
getInsertionOrder() {
|
|
7517
|
+
const visited = /* @__PURE__ */ new Set();
|
|
7518
|
+
const order = [];
|
|
7519
|
+
const tempVisited = /* @__PURE__ */ new Set();
|
|
7520
|
+
const visit = (fixtureId) => {
|
|
7521
|
+
if (visited.has(fixtureId)) return;
|
|
7522
|
+
if (tempVisited.has(fixtureId)) {
|
|
7523
|
+
console.warn(`Circular dependency detected involving: ${fixtureId}`);
|
|
7524
|
+
return;
|
|
7525
|
+
}
|
|
7526
|
+
tempVisited.add(fixtureId);
|
|
7527
|
+
const node = this.dependencyGraph.get(fixtureId);
|
|
7528
|
+
const entity = EntityManager.get(node.entityId);
|
|
7529
|
+
for (const depId of node.dependencies) {
|
|
7530
|
+
const depNode = this.dependencyGraph.get(depId);
|
|
7531
|
+
const relationProp = entity.props.find(
|
|
7532
|
+
(prop) => isRelationProp(prop) && (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn) && prop.with === depNode.entityId
|
|
7533
|
+
);
|
|
7534
|
+
if (relationProp && !relationProp.nullable) {
|
|
7535
|
+
visit(depId);
|
|
7536
|
+
}
|
|
7537
|
+
}
|
|
7538
|
+
tempVisited.delete(fixtureId);
|
|
7539
|
+
visited.add(fixtureId);
|
|
7540
|
+
order.push(fixtureId);
|
|
7541
|
+
};
|
|
7542
|
+
for (const fixtureId of this.dependencyGraph.keys()) {
|
|
7543
|
+
visit(fixtureId);
|
|
7544
|
+
}
|
|
7545
|
+
for (const fixtureId of this.dependencyGraph.keys()) {
|
|
7546
|
+
if (!visited.has(fixtureId)) {
|
|
7547
|
+
order.push(fixtureId);
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
return order;
|
|
7551
|
+
}
|
|
7552
|
+
prepareInsertData(fixture) {
|
|
7553
|
+
const insertData = {};
|
|
7554
|
+
for (const [propName, column] of Object.entries(fixture.columns)) {
|
|
7555
|
+
if (isVirtualProp(column.prop)) {
|
|
7556
|
+
continue;
|
|
7557
|
+
}
|
|
7558
|
+
const prop = column.prop;
|
|
7559
|
+
if (!isRelationProp(prop)) {
|
|
7560
|
+
if (prop.type === "json") {
|
|
7561
|
+
insertData[propName] = JSON.stringify(column.value);
|
|
7562
|
+
} else {
|
|
7563
|
+
insertData[propName] = column.value;
|
|
7564
|
+
}
|
|
7565
|
+
} else if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn) {
|
|
7566
|
+
insertData[`${propName}_id`] = column.value;
|
|
7567
|
+
}
|
|
7568
|
+
}
|
|
7569
|
+
return insertData;
|
|
7570
|
+
}
|
|
7571
|
+
buildDependencyGraph(fixtures) {
|
|
7572
|
+
this.dependencyGraph.clear();
|
|
7573
|
+
for (const fixture of fixtures) {
|
|
7574
|
+
this.dependencyGraph.set(fixture.fixtureId, {
|
|
7575
|
+
fixtureId: fixture.fixtureId,
|
|
7576
|
+
entityId: fixture.entityId,
|
|
7577
|
+
dependencies: /* @__PURE__ */ new Set()
|
|
7578
|
+
});
|
|
7579
|
+
}
|
|
7580
|
+
for (const fixture of fixtures) {
|
|
7581
|
+
const node = this.dependencyGraph.get(fixture.fixtureId);
|
|
7582
|
+
for (const [, column] of Object.entries(fixture.columns)) {
|
|
7583
|
+
const prop = column.prop;
|
|
7584
|
+
if (isRelationProp(prop)) {
|
|
7585
|
+
if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn) {
|
|
7586
|
+
const relatedFixtureId = `${prop.with}#${column.value}`;
|
|
7587
|
+
if (this.dependencyGraph.has(relatedFixtureId)) {
|
|
7588
|
+
node.dependencies.add(relatedFixtureId);
|
|
7589
|
+
}
|
|
7590
|
+
} else if (isManyToManyRelationProp(prop)) {
|
|
7591
|
+
const relatedIds = column.value;
|
|
7592
|
+
for (const relatedId of relatedIds) {
|
|
7593
|
+
const relatedFixtureId = `${prop.with}#${relatedId}`;
|
|
7594
|
+
if (this.dependencyGraph.has(relatedFixtureId)) {
|
|
7595
|
+
node.dependencies.add(relatedFixtureId);
|
|
7596
|
+
this.dependencyGraph.get(relatedFixtureId).dependencies.add(fixture.fixtureId);
|
|
7597
|
+
}
|
|
7598
|
+
}
|
|
7599
|
+
}
|
|
7600
|
+
}
|
|
7601
|
+
}
|
|
7602
|
+
}
|
|
7603
|
+
}
|
|
7604
|
+
async insertFixture(db, fixture) {
|
|
7605
|
+
const insertData = this.prepareInsertData(fixture);
|
|
7606
|
+
const entity = EntityManager.get(fixture.entityId);
|
|
7607
|
+
try {
|
|
7608
|
+
const found = await db(entity.table).where("id", fixture.id).first();
|
|
7609
|
+
if (found && !fixture.override) {
|
|
7610
|
+
return {
|
|
7611
|
+
entityId: fixture.entityId,
|
|
7612
|
+
id: found.id
|
|
7613
|
+
};
|
|
7614
|
+
}
|
|
7615
|
+
const q = db.insert(insertData).into(entity.table);
|
|
7616
|
+
await q.onDuplicateUpdate.apply(q, Object.keys(insertData));
|
|
7617
|
+
return {
|
|
7618
|
+
entityId: fixture.entityId,
|
|
7619
|
+
id: fixture.id
|
|
7620
|
+
};
|
|
7621
|
+
} catch (err) {
|
|
7622
|
+
console.log(err);
|
|
7623
|
+
throw err;
|
|
7624
|
+
}
|
|
7625
|
+
}
|
|
7626
|
+
async handleManyToManyRelations(db, fixture, fixtures) {
|
|
7627
|
+
for (const [, column] of Object.entries(fixture.columns)) {
|
|
7628
|
+
const prop = column.prop;
|
|
7629
|
+
if (isManyToManyRelationProp(prop)) {
|
|
7630
|
+
const joinTable = prop.joinTable;
|
|
7631
|
+
const relatedIds = column.value;
|
|
7632
|
+
for (const relatedId of relatedIds) {
|
|
7633
|
+
if (!fixtures.find((f) => f.fixtureId === `${prop.with}#${relatedId}`)) {
|
|
7634
|
+
continue;
|
|
7635
|
+
}
|
|
7636
|
+
const entity = EntityManager.get(fixture.entityId);
|
|
7637
|
+
const relatedEntity = EntityManager.get(prop.with);
|
|
7638
|
+
if (!entity || !relatedEntity) {
|
|
7639
|
+
throw new Error(
|
|
7640
|
+
`Entity not found: ${fixture.entityId}, ${prop.with}`
|
|
7641
|
+
);
|
|
7642
|
+
}
|
|
7643
|
+
const [found] = await db(joinTable).where({
|
|
7644
|
+
[`${_inflection2.default.singularize(entity.table)}_id`]: fixture.id,
|
|
7645
|
+
[`${_inflection2.default.singularize(relatedEntity.table)}_id`]: relatedId
|
|
7646
|
+
}).limit(1);
|
|
7647
|
+
if (found) {
|
|
7648
|
+
continue;
|
|
7649
|
+
}
|
|
7650
|
+
const newIds = await db(joinTable).insert({
|
|
7651
|
+
[`${_inflection2.default.singularize(entity.table)}_id`]: fixture.id,
|
|
7652
|
+
[`${_inflection2.default.singularize(relatedEntity.table)}_id`]: relatedId
|
|
7653
|
+
});
|
|
7654
|
+
console.log(
|
|
7655
|
+
_chalk2.default.green(
|
|
7656
|
+
`Inserted into ${joinTable}: ${entity.table}(${fixture.id}) - ${relatedEntity.table}(${relatedId}) ID: ${newIds}`
|
|
7657
|
+
)
|
|
7658
|
+
);
|
|
7659
|
+
}
|
|
7660
|
+
}
|
|
7661
|
+
}
|
|
7662
|
+
}
|
|
7663
|
+
async addFixtureLoader(code) {
|
|
7664
|
+
const path8 = Sonamu.apiRootPath + "/src/testing/fixture.ts";
|
|
7665
|
+
let content = _fs.readFileSync.call(void 0, path8).toString();
|
|
7666
|
+
const fixtureLoaderStart = content.indexOf("const fixtureLoader = {");
|
|
7667
|
+
const fixtureLoaderEnd = content.indexOf("};", fixtureLoaderStart);
|
|
7668
|
+
if (fixtureLoaderStart !== -1 && fixtureLoaderEnd !== -1) {
|
|
7669
|
+
const newContent = content.slice(0, fixtureLoaderEnd) + " " + code + "\n" + content.slice(fixtureLoaderEnd);
|
|
7670
|
+
_fs.writeFileSync.call(void 0, path8, newContent);
|
|
7671
|
+
} else {
|
|
7672
|
+
throw new Error("Failed to find fixtureLoader in fixture.ts");
|
|
7673
|
+
}
|
|
7674
|
+
}
|
|
7362
7675
|
};
|
|
7363
7676
|
var FixtureManager = new FixtureManagerClass();
|
|
7364
7677
|
|
|
@@ -7443,5 +7756,6 @@ var FixtureManager = new FixtureManagerClass();
|
|
|
7443
7756
|
|
|
7444
7757
|
|
|
7445
7758
|
|
|
7446
|
-
|
|
7447
|
-
|
|
7759
|
+
|
|
7760
|
+
exports.SQLDateTimeString = SQLDateTimeString; exports.zArrayable = zArrayable; exports.isIntegerProp = isIntegerProp; exports.isBigIntegerProp = isBigIntegerProp; exports.isTextProp = isTextProp; exports.isStringProp = isStringProp; exports.isEnumProp = isEnumProp; exports.isFloatProp = isFloatProp; exports.isDoubleProp = isDoubleProp; exports.isDecimalProp = isDecimalProp; exports.isBooleanProp = isBooleanProp; exports.isDateProp = isDateProp; exports.isDateTimeProp = isDateTimeProp; exports.isTimeProp = isTimeProp; exports.isTimestampProp = isTimestampProp; exports.isJsonProp = isJsonProp; exports.isUuidProp = isUuidProp; exports.isVirtualProp = isVirtualProp; exports.isRelationProp = isRelationProp; exports.isOneToOneRelationProp = isOneToOneRelationProp; exports.isBelongsToOneRelationProp = isBelongsToOneRelationProp; exports.isHasManyRelationProp = isHasManyRelationProp; exports.isManyToManyRelationProp = isManyToManyRelationProp; exports.isCustomJoinClause = isCustomJoinClause; exports.SonamuQueryMode = SonamuQueryMode; exports.isKnexError = isKnexError; exports.ApiParamType = ApiParamType; exports.RenderingNode = RenderingNode; exports.TemplateOptions = TemplateOptions; exports.TemplateKey = TemplateKey; exports.GenerateOptions = GenerateOptions; exports.PathAndCode = PathAndCode; exports.getZodObjectFromApi = getZodObjectFromApi; exports.getZodObjectFromApiParams = getZodObjectFromApiParams; exports.getZodTypeFromApiParamType = getZodTypeFromApiParamType; exports.propNodeToZodTypeDef = propNodeToZodTypeDef; exports.getTextTypeLength = getTextTypeLength; exports.propToZodTypeDef = propToZodTypeDef; exports.zodTypeToZodCode = zodTypeToZodCode; exports.apiParamToTsCode = apiParamToTsCode; exports.apiParamTypeToTsType = apiParamTypeToTsType; exports.unwrapPromiseOnce = unwrapPromiseOnce; exports.serializeZodType = serializeZodType; exports.zodTypeToTsTypeDef = zodTypeToTsTypeDef; exports.registeredApis = registeredApis; exports.api = api; exports.SoException = SoException; exports.isSoException = isSoException; exports.BadRequestException = BadRequestException; exports.UnauthorizedException = UnauthorizedException; exports.NotFoundException = NotFoundException; exports.ServiceUnavailableException = ServiceUnavailableException; exports.InternalServerErrorException = InternalServerErrorException; exports.AlreadyProcessedException = AlreadyProcessedException; exports.DuplicateRowException = DuplicateRowException; exports.TargetNotFoundException = TargetNotFoundException; exports.globAsync = globAsync; exports.importMultiple = importMultiple; exports.findAppRootPath = findAppRootPath; exports.findApiRootPath = findApiRootPath; exports.nonNullable = nonNullable; exports.Entity = Entity; exports.EntityManager = EntityManager; exports.Syncer = Syncer; exports.isLocal = isLocal; exports.isRemote = isRemote; exports.isInDocker = isInDocker; exports.isDaemonServer = isDaemonServer; exports.isDevelopment = isDevelopment; exports.isStaging = isStaging; exports.isProduction = isProduction; exports.isTest = isTest; exports.DB = DB; exports.isRefField = isRefField; exports.UpsertBuilder = UpsertBuilder; exports.BaseModelClass = BaseModelClass; exports.BaseModel = BaseModel; exports.Sonamu = Sonamu; exports.Migrator = Migrator; exports.FixtureManagerClass = FixtureManagerClass; exports.FixtureManager = FixtureManager;
|
|
7761
|
+
//# sourceMappingURL=chunk-76VBQWGE.js.map
|