sonamu 0.7.53 → 0.8.0
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/api/config.d.ts +9 -1
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +1 -1
- package/dist/api/sonamu.d.ts +21 -1
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +159 -65
- package/dist/auth/plugins/entity-definitions/anonymous.d.ts +10 -0
- package/dist/auth/plugins/entity-definitions/anonymous.d.ts.map +1 -0
- package/dist/auth/plugins/entity-definitions/anonymous.js +23 -0
- package/dist/auth/plugins/entity-definitions/api-key.d.ts +9 -0
- package/dist/auth/plugins/entity-definitions/api-key.d.ts.map +1 -0
- package/dist/auth/plugins/entity-definitions/api-key.js +199 -0
- package/dist/auth/plugins/entity-definitions/index.d.ts +6 -0
- package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/index.js +20 -2
- package/dist/auth/plugins/entity-definitions/jwt.d.ts +9 -0
- package/dist/auth/plugins/entity-definitions/jwt.d.ts.map +1 -0
- package/dist/auth/plugins/entity-definitions/jwt.js +67 -0
- package/dist/auth/plugins/entity-definitions/organization.d.ts +9 -0
- package/dist/auth/plugins/entity-definitions/organization.d.ts.map +1 -0
- package/dist/auth/plugins/entity-definitions/organization.js +424 -0
- package/dist/auth/plugins/entity-definitions/passkey.d.ts +10 -0
- package/dist/auth/plugins/entity-definitions/passkey.d.ts.map +1 -0
- package/dist/auth/plugins/entity-definitions/passkey.js +129 -0
- package/dist/auth/plugins/entity-definitions/sso.d.ts +10 -0
- package/dist/auth/plugins/entity-definitions/sso.d.ts.map +1 -0
- package/dist/auth/plugins/entity-definitions/sso.js +110 -0
- package/dist/auth/plugins/entity-definitions/types.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/types.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/types.js +1 -1
- package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/admin.js +2 -4
- package/dist/auth/plugins/wrappers/anonymous.d.ts +18 -0
- package/dist/auth/plugins/wrappers/anonymous.d.ts.map +1 -0
- package/dist/auth/plugins/wrappers/anonymous.js +26 -0
- package/dist/auth/plugins/wrappers/api-key.d.ts +18 -0
- package/dist/auth/plugins/wrappers/api-key.d.ts.map +1 -0
- package/dist/auth/plugins/wrappers/api-key.js +38 -0
- package/dist/auth/plugins/wrappers/index.d.ts +6 -0
- package/dist/auth/plugins/wrappers/index.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/index.js +7 -1
- package/dist/auth/plugins/wrappers/jwt.d.ts +18 -0
- package/dist/auth/plugins/wrappers/jwt.d.ts.map +1 -0
- package/dist/auth/plugins/wrappers/jwt.js +30 -0
- package/dist/auth/plugins/wrappers/organization.d.ts +18 -0
- package/dist/auth/plugins/wrappers/organization.d.ts.map +1 -0
- package/dist/auth/plugins/wrappers/organization.js +67 -0
- package/dist/auth/plugins/wrappers/passkey.d.ts +18 -0
- package/dist/auth/plugins/wrappers/passkey.d.ts.map +1 -0
- package/dist/auth/plugins/wrappers/passkey.js +32 -0
- package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/phone-number.js +2 -4
- package/dist/auth/plugins/wrappers/sso.d.ts +853 -0
- package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -0
- package/dist/auth/plugins/wrappers/sso.js +36 -0
- package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/two-factor.js +2 -4
- package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/username.js +2 -4
- package/dist/bin/build-config.d.ts +2 -2
- package/dist/bin/build-config.js +6 -7
- package/dist/bin/cli.js +417 -32
- package/dist/bin/fixture.d.ts +27 -0
- package/dist/bin/fixture.d.ts.map +1 -0
- package/dist/bin/fixture.js +245 -0
- package/dist/cache/decorator.d.ts +4 -3
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/decorator.js +5 -4
- package/dist/cone/cone-generator.d.ts +33 -0
- package/dist/cone/cone-generator.d.ts.map +1 -0
- package/dist/cone/cone-generator.js +286 -0
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +16 -2
- package/dist/database/puri-subset.test-d.js +1 -1
- package/dist/database/puri-subset.types.d.ts +1 -1
- package/dist/database/puri-subset.types.d.ts.map +1 -1
- package/dist/database/puri-subset.types.js +1 -1
- package/dist/database/puri.d.ts +4 -0
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +20 -2
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +19 -3
- package/dist/dict/en.d.ts +15 -0
- package/dist/dict/en.d.ts.map +1 -1
- package/dist/dict/en.js +2 -1
- package/dist/dict/ko.d.ts +15 -0
- package/dist/dict/ko.d.ts.map +1 -1
- package/dist/dict/ko.js +2 -1
- package/dist/dict/rc-keys.d.ts +28 -0
- package/dist/dict/rc-keys.d.ts.map +1 -1
- package/dist/dict/rc-keys.js +31 -1
- package/dist/dict/sd.d.ts.map +1 -1
- package/dist/dict/sd.js +20 -4
- package/dist/entity/entity-manager.d.ts +298 -2
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +4 -1
- package/dist/entity/entity-template-cone.d.ts +14 -0
- package/dist/entity/entity-template-cone.d.ts.map +1 -0
- package/dist/entity/entity-template-cone.js +222 -0
- package/dist/entity/entity.d.ts +47 -2
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +161 -14
- package/dist/ssr/renderer.js +3 -3
- package/dist/syncer/api-parser.js +12 -1
- package/dist/syncer/checksum.d.ts +0 -14
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +1 -23
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +8 -2
- package/dist/syncer/syncer.d.ts +1 -1
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +17 -10
- package/dist/tasks/workflow-manager.d.ts +13 -1
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +18 -1
- package/dist/template/entity-converter.js +4 -4
- package/dist/template/helpers.d.ts +10 -0
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +48 -1
- package/dist/template/implementations/entry-server.template.d.ts +1 -1
- package/dist/template/implementations/entry-server.template.js +7 -2
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +5 -1
- package/dist/template/implementations/generated_http.template.d.ts +1 -0
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +6 -2
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +29 -8
- package/dist/template/implementations/queries.template.d.ts.map +1 -1
- package/dist/template/implementations/queries.template.js +9 -1
- package/dist/template/implementations/sd.template.d.ts +1 -1
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +28 -4
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +12 -12
- package/dist/template/implementations/view_form.template.d.ts +11 -7
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +97 -87
- package/dist/template/implementations/view_list.template.d.ts +3 -3
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +115 -109
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +18 -14
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +95 -7
- package/dist/testing/_relation-graph.js +1 -1
- package/dist/testing/data-explorer.d.ts +61 -0
- package/dist/testing/data-explorer.d.ts.map +1 -0
- package/dist/testing/data-explorer.js +274 -0
- package/dist/testing/faker-mappings.d.ts +20 -0
- package/dist/testing/faker-mappings.d.ts.map +1 -0
- package/dist/testing/faker-mappings.js +421 -0
- package/dist/testing/fixture-generator.d.ts +161 -0
- package/dist/testing/fixture-generator.d.ts.map +1 -0
- package/dist/testing/fixture-generator.js +954 -0
- package/dist/testing/fixture-manager.d.ts +6 -1
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +72 -4
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4 -1
- package/dist/types/types.d.ts +1520 -26
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +136 -22
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +9 -4
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +303 -24
- package/dist/ui-web/assets/index-CsUr-_pV.js +254 -0
- package/dist/ui-web/assets/index-T42zzs1K.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/dist/utils/fs-utils.d.ts +2 -1
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +14 -3
- package/package.json +19 -11
- package/src/api/config.ts +12 -1
- package/src/api/sonamu.ts +179 -65
- package/src/auth/plugins/entity-definitions/anonymous.ts +17 -0
- package/src/auth/plugins/entity-definitions/api-key.ts +93 -0
- package/src/auth/plugins/entity-definitions/index.ts +18 -0
- package/src/auth/plugins/entity-definitions/jwt.ts +35 -0
- package/src/auth/plugins/entity-definitions/organization.ts +215 -0
- package/src/auth/plugins/entity-definitions/passkey.ts +64 -0
- package/src/auth/plugins/entity-definitions/sso.ts +62 -0
- package/src/auth/plugins/entity-definitions/types.ts +11 -1
- package/src/auth/plugins/wrappers/admin.ts +1 -3
- package/src/auth/plugins/wrappers/anonymous.ts +30 -0
- package/src/auth/plugins/wrappers/api-key.ts +42 -0
- package/src/auth/plugins/wrappers/index.ts +6 -0
- package/src/auth/plugins/wrappers/jwt.ts +34 -0
- package/src/auth/plugins/wrappers/organization.ts +73 -0
- package/src/auth/plugins/wrappers/passkey.ts +36 -0
- package/src/auth/plugins/wrappers/phone-number.ts +1 -3
- package/src/auth/plugins/wrappers/sso.ts +40 -0
- package/src/auth/plugins/wrappers/two-factor.ts +1 -3
- package/src/auth/plugins/wrappers/username.ts +1 -3
- package/src/bin/build-config.ts +6 -6
- package/src/bin/cli.ts +452 -31
- package/src/bin/fixture.ts +302 -0
- package/src/cache/decorator.ts +4 -3
- package/src/cone/cone-generator.ts +363 -0
- package/src/database/_batch_update.ts +11 -0
- package/src/database/puri-subset.test-d.ts +13 -13
- package/src/database/puri-subset.types.ts +1 -1
- package/src/database/puri.ts +43 -1
- package/src/database/upsert-builder.ts +16 -2
- package/src/dict/en.ts +1 -0
- package/src/dict/ko.ts +1 -0
- package/src/dict/rc-keys.ts +32 -0
- package/src/dict/sd.ts +23 -3
- package/src/entity/entity-manager.ts +4 -0
- package/src/entity/entity-template-cone.ts +298 -0
- package/src/entity/entity.ts +189 -13
- package/src/shared/app.shared.ts.txt +5 -0
- package/src/shared/web.shared.ts.txt +9 -5
- package/src/skills/project/README.md +21 -0
- package/src/skills/project/architecture.md +373 -0
- package/src/skills/project/business-logic.md +270 -0
- package/src/skills/project/requirements.md +160 -0
- package/src/skills/sonamu/SKILL.md +168 -3
- package/src/skills/sonamu/api.md +102 -0
- package/src/skills/sonamu/database.md +220 -1
- package/src/skills/sonamu/entity-relations.md +89 -1
- package/src/skills/sonamu/fixture-cli.md +501 -0
- package/src/skills/sonamu/frontend.md +214 -0
- package/src/skills/sonamu/i18n.md +95 -0
- package/src/skills/sonamu/model.md +153 -0
- package/src/skills/sonamu/project-init.md +178 -8
- package/src/skills/sonamu/scaffolding.md +112 -0
- package/src/skills/sonamu/subset.md +9 -3
- package/src/skills/sonamu/testing.md +287 -2
- package/src/skills/sonamu/workflow.md +70 -5
- package/src/ssr/renderer.ts +2 -2
- package/src/syncer/api-parser.ts +12 -0
- package/src/syncer/checksum.ts +0 -38
- package/src/syncer/syncer-actions.ts +7 -1
- package/src/syncer/syncer.ts +16 -5
- package/src/tasks/workflow-manager.ts +29 -8
- package/src/template/entity-converter.ts +3 -3
- package/src/template/helpers.ts +49 -0
- package/src/template/implementations/entry-server.template.ts +1 -1
- package/src/template/implementations/generated.template.ts +4 -0
- package/src/template/implementations/generated_http.template.ts +1 -0
- package/src/template/implementations/generated_sso.template.ts +40 -11
- package/src/template/implementations/queries.template.ts +8 -0
- package/src/template/implementations/sd.template.ts +22 -3
- package/src/template/implementations/services.template.ts +11 -10
- package/src/template/implementations/view_form.template.ts +111 -101
- package/src/template/implementations/view_list.template.ts +120 -119
- package/src/template/implementations/view_search_input.template.ts +17 -13
- package/src/template/zod-converter.ts +103 -6
- package/src/testing/_relation-graph.ts +1 -1
- package/src/testing/data-explorer.ts +427 -0
- package/src/testing/faker-mappings.ts +434 -0
- package/src/testing/fixture-generator.ts +1166 -0
- package/src/testing/fixture-manager.ts +91 -6
- package/src/testing/index.ts +3 -0
- package/src/types/types.ts +222 -26
- package/src/ui/ai-client.ts +9 -1
- package/src/ui/api.ts +429 -23
- package/src/utils/fs-utils.ts +14 -1
- package/dist/template/implementations/view_enums_select.template.d.ts +0 -17
- package/dist/template/implementations/view_enums_select.template.d.ts.map +0 -1
- package/dist/template/implementations/view_enums_select.template.js +0 -62
- package/dist/template/implementations/view_id_async_select.template.d.ts +0 -17
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +0 -1
- package/dist/template/implementations/view_id_async_select.template.js +0 -125
- package/dist/ui-web/assets/index-Bd_2AkLb.css +0 -1
- package/dist/ui-web/assets/index-BpSbhQWo.js +0 -225
- package/src/template/implementations/view_enums_select.template.ts +0 -65
- package/src/template/implementations/view_id_async_select.template.ts +0 -139
package/src/entity/entity.ts
CHANGED
|
@@ -6,11 +6,14 @@ import { group, unique } from "radashi";
|
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { Sonamu } from "../api/sonamu";
|
|
8
8
|
import {
|
|
9
|
+
type Cone,
|
|
9
10
|
type EntityIndex,
|
|
10
11
|
type EntityJson,
|
|
11
12
|
type EntityProp,
|
|
12
13
|
type EntityPropNode,
|
|
13
14
|
type EntitySubsetRow,
|
|
15
|
+
getEnumDefValues,
|
|
16
|
+
getSubsetFields,
|
|
14
17
|
isBelongsToOneRelationProp,
|
|
15
18
|
isEnumProp,
|
|
16
19
|
isHasManyRelationProp,
|
|
@@ -37,6 +40,7 @@ export class Entity {
|
|
|
37
40
|
parentId?: string;
|
|
38
41
|
table: string;
|
|
39
42
|
title: string;
|
|
43
|
+
cone?: Cone;
|
|
40
44
|
names: {
|
|
41
45
|
parentFs: string;
|
|
42
46
|
fs: string;
|
|
@@ -67,13 +71,20 @@ export class Entity {
|
|
|
67
71
|
[key: string]: string;
|
|
68
72
|
};
|
|
69
73
|
} = {};
|
|
74
|
+
enumCones: {
|
|
75
|
+
[enumId: string]: Cone;
|
|
76
|
+
} = {};
|
|
77
|
+
subsetCones: {
|
|
78
|
+
[subsetKey: string]: Cone;
|
|
79
|
+
} = {};
|
|
70
80
|
|
|
71
|
-
constructor({ id, parentId, table, title, props, indexes, subsets, enums }: EntityJson) {
|
|
81
|
+
constructor({ id, parentId, table, title, cone, props, indexes, subsets, enums }: EntityJson) {
|
|
72
82
|
// id
|
|
73
83
|
this.id = id;
|
|
74
84
|
this.parentId = parentId;
|
|
75
85
|
this.title = title ?? this.id;
|
|
76
86
|
this.table = table ?? inflection.underscore(inflection.pluralize(id));
|
|
87
|
+
this.cone = cone;
|
|
77
88
|
|
|
78
89
|
// props
|
|
79
90
|
if (props) {
|
|
@@ -104,16 +115,30 @@ export class Entity {
|
|
|
104
115
|
// indexes
|
|
105
116
|
this.indexes = indexes ?? [];
|
|
106
117
|
|
|
107
|
-
// subsets: SubsetField[]를
|
|
118
|
+
// subsets: SubsetDef에서 SubsetField[]를 추출하여 subsets(일반)와 subsetsInternal(internal)로 분리
|
|
108
119
|
this.subsets = {};
|
|
109
120
|
this.subsetsInternal = {};
|
|
110
|
-
for (const [key,
|
|
121
|
+
for (const [key, subsetDef] of Object.entries(subsets ?? {})) {
|
|
122
|
+
const fields = getSubsetFields(subsetDef);
|
|
111
123
|
this.subsets[key] = fields.filter((f) => !isInternalSubsetField(f)).map(normalizeSubsetField);
|
|
112
124
|
this.subsetsInternal[key] = fields.filter(isInternalSubsetField).map(normalizeSubsetField);
|
|
125
|
+
|
|
126
|
+
// cone 추출
|
|
127
|
+
if (!Array.isArray(subsetDef) && "cone" in subsetDef && subsetDef.cone) {
|
|
128
|
+
this.subsetCones[key] = subsetDef.cone;
|
|
129
|
+
}
|
|
113
130
|
}
|
|
114
131
|
|
|
115
|
-
// enums
|
|
116
|
-
this.enumLabels =
|
|
132
|
+
// enums: EnumDef에서 values와 cone를 추출하여 처리
|
|
133
|
+
this.enumLabels = Object.fromEntries(
|
|
134
|
+
Object.entries(enums ?? {}).map(([key, enumDef]) => {
|
|
135
|
+
// cone 추출
|
|
136
|
+
if ("values" in enumDef && "cone" in enumDef && enumDef.cone) {
|
|
137
|
+
this.enumCones[key] = enumDef.cone as Cone;
|
|
138
|
+
}
|
|
139
|
+
return [key, getEnumDefValues(enumDef)];
|
|
140
|
+
}),
|
|
141
|
+
);
|
|
117
142
|
this.enums = Object.fromEntries(
|
|
118
143
|
Object.entries(this.enumLabels).map(([key, enumLabel]) => {
|
|
119
144
|
return [key, z.enum(Object.keys(enumLabel) as unknown as readonly [string, ...string[]])];
|
|
@@ -290,12 +315,17 @@ export class Entity {
|
|
|
290
315
|
const loaderLines: string[] = [];
|
|
291
316
|
|
|
292
317
|
for (const loader of loaders) {
|
|
293
|
-
const { toTable, toCol, through } = loader.manyJoin;
|
|
318
|
+
const { toTable, toCol, through, fromTable } = loader.manyJoin;
|
|
319
|
+
|
|
320
|
+
// fromTable의 Entity를 가져와서 PK 타입 확인
|
|
321
|
+
const fromEntity = EntityManager.getByTable(fromTable);
|
|
322
|
+
const fromIdsType = fromEntity.getPkArrayType();
|
|
323
|
+
|
|
294
324
|
loaderLines.push(
|
|
295
325
|
"{",
|
|
296
326
|
`as: "${loader.as}",`,
|
|
297
327
|
`refId: "${loader.manyJoin.idField}",`,
|
|
298
|
-
`qb: (qbWrapper: PuriWrapper<DatabaseSchemaExtend>, fromIds: number[]) => {`,
|
|
328
|
+
`qb: (qbWrapper: PuriWrapper<DatabaseSchemaExtend>, fromIds: number[] | string[]) => {`,
|
|
299
329
|
);
|
|
300
330
|
|
|
301
331
|
if (through === undefined) {
|
|
@@ -327,7 +357,7 @@ export class Entity {
|
|
|
327
357
|
const selectObj = this.buildNestedSelectObject(loader.select);
|
|
328
358
|
selectObj.refId = `"${toTable}.${toCol}"`;
|
|
329
359
|
loaderLines.push(
|
|
330
|
-
`.whereIn("${toTable}.${toCol}", fromIds)`,
|
|
360
|
+
`.whereIn("${toTable}.${toCol}", fromIds as ${fromIdsType})`,
|
|
331
361
|
`.select(${this.stringifyNestedSelectObject(selectObj)});`,
|
|
332
362
|
);
|
|
333
363
|
} else {
|
|
@@ -359,7 +389,7 @@ export class Entity {
|
|
|
359
389
|
const selectObj = this.buildNestedSelectObject(loader.select);
|
|
360
390
|
selectObj.refId = `"${through.table}.${through.fromCol}"`;
|
|
361
391
|
loaderLines.push(
|
|
362
|
-
`.whereIn("${through.table}.${through.fromCol}", fromIds)`,
|
|
392
|
+
`.whereIn("${through.table}.${through.fromCol}", fromIds as ${fromIdsType})`,
|
|
363
393
|
`.select(${this.stringifyNestedSelectObject(selectObj)});`,
|
|
364
394
|
);
|
|
365
395
|
}
|
|
@@ -841,15 +871,39 @@ export class Entity {
|
|
|
841
871
|
}
|
|
842
872
|
|
|
843
873
|
toJson(): EntityJson {
|
|
844
|
-
// subsets와 subsetsInternal을
|
|
845
|
-
const subsets: { [key: string]:
|
|
874
|
+
// subsets와 subsetsInternal을 SubsetDef 형태로 복원 (cone 포함)
|
|
875
|
+
const subsets: { [key: string]: import("../types/types").SubsetDef } = {};
|
|
846
876
|
for (const key of Object.keys(this.subsets)) {
|
|
847
877
|
const normalFields: SubsetField[] = this.subsets[key];
|
|
848
878
|
const internalFields: SubsetField[] = (this.subsetsInternal[key] ?? []).map((field) => ({
|
|
849
879
|
field,
|
|
850
880
|
internal: true,
|
|
851
881
|
}));
|
|
852
|
-
|
|
882
|
+
const fields = [...normalFields, ...internalFields];
|
|
883
|
+
|
|
884
|
+
// cone이 있으면 새로운 객체 형태로, 없으면 배열 형태로
|
|
885
|
+
if (this.subsetCones[key]) {
|
|
886
|
+
subsets[key] = {
|
|
887
|
+
fields,
|
|
888
|
+
cone: this.subsetCones[key],
|
|
889
|
+
};
|
|
890
|
+
} else {
|
|
891
|
+
subsets[key] = fields;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// enums를 EnumDef 형태로 복원 (cone 포함)
|
|
896
|
+
const enums: { [key: string]: import("../types/types").EnumDef } = {};
|
|
897
|
+
for (const [key, values] of Object.entries(this.enumLabels)) {
|
|
898
|
+
// cone이 있으면 새로운 객체 형태로, 없으면 Record 형태로
|
|
899
|
+
if (this.enumCones[key]) {
|
|
900
|
+
enums[key] = {
|
|
901
|
+
values,
|
|
902
|
+
cone: this.enumCones[key],
|
|
903
|
+
};
|
|
904
|
+
} else {
|
|
905
|
+
enums[key] = values;
|
|
906
|
+
}
|
|
853
907
|
}
|
|
854
908
|
|
|
855
909
|
return {
|
|
@@ -857,10 +911,11 @@ export class Entity {
|
|
|
857
911
|
parentId: this.parentId,
|
|
858
912
|
table: this.table,
|
|
859
913
|
title: this.title,
|
|
914
|
+
cone: this.cone,
|
|
860
915
|
props: this.props,
|
|
861
916
|
indexes: this.indexes,
|
|
862
917
|
subsets,
|
|
863
|
-
enums
|
|
918
|
+
enums,
|
|
864
919
|
};
|
|
865
920
|
}
|
|
866
921
|
|
|
@@ -890,6 +945,118 @@ export class Entity {
|
|
|
890
945
|
await EntityManager.register(json);
|
|
891
946
|
}
|
|
892
947
|
|
|
948
|
+
/**
|
|
949
|
+
* 템플릿 cone 메타데이터를 생성합니다.
|
|
950
|
+
*
|
|
951
|
+
* LLM을 사용하지 않고 faker-mappings.ts를 활용하여 기본 cone을 생성합니다.
|
|
952
|
+
* stub entity 생성 시 자동으로 호출되어 최소한의 cone 메타데이터를 제공합니다.
|
|
953
|
+
*
|
|
954
|
+
* @param locale - 생성 시 사용할 locale (기본값: Sonamu.config.i18n.defaultLocale 또는 "ko")
|
|
955
|
+
*/
|
|
956
|
+
async generateTemplateCones(locale?: "ko" | "en" | "ja"): Promise<void> {
|
|
957
|
+
const { generateTemplateCones } = await import("./entity-template-cone");
|
|
958
|
+
const configLocale = Sonamu.config.i18n?.defaultLocale;
|
|
959
|
+
const effectiveLocale =
|
|
960
|
+
locale ||
|
|
961
|
+
(configLocale === "ko" || configLocale === "en" || configLocale === "ja"
|
|
962
|
+
? configLocale
|
|
963
|
+
: "ko");
|
|
964
|
+
const result = generateTemplateCones(this.toJson(), effectiveLocale);
|
|
965
|
+
|
|
966
|
+
// 결과를 Entity에 적용 (applyCones와 동일한 방식)
|
|
967
|
+
if (result.entityCone) {
|
|
968
|
+
this.cone = result.entityCone;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
for (const [propName, cone] of Object.entries(result.propCones)) {
|
|
972
|
+
const prop = this.props.find((p) => p.name === propName);
|
|
973
|
+
if (prop) {
|
|
974
|
+
(prop as { cone?: Cone }).cone = cone;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
this.enumCones = { ...this.enumCones, ...result.enumCones };
|
|
979
|
+
this.subsetCones = { ...this.subsetCones, ...result.subsetCones };
|
|
980
|
+
|
|
981
|
+
await this.save();
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* LLM을 사용하여 cone 메타데이터를 생성합니다.
|
|
986
|
+
*
|
|
987
|
+
* @param options.preserveExisting - 기존 cone 보존 여부 (기본값: true)
|
|
988
|
+
* @param options.onlyEmpty - fixtureHint가 없는 cone만 생성 (기본값: false)
|
|
989
|
+
* @param options.locale - 생성 시 사용할 locale (기본값: "ko")
|
|
990
|
+
*/
|
|
991
|
+
async generateCones(options?: {
|
|
992
|
+
preserveExisting?: boolean;
|
|
993
|
+
onlyEmpty?: boolean;
|
|
994
|
+
locale?: "ko" | "en" | "ja";
|
|
995
|
+
}): Promise<import("../cone/cone-generator").ConeGenerationResult> {
|
|
996
|
+
const { generateCones } = await import("../cone/cone-generator");
|
|
997
|
+
const context: import("../cone/cone-generator").ConeGenerationContext = {
|
|
998
|
+
entity: this.toJson(),
|
|
999
|
+
locale: options?.locale || "ko",
|
|
1000
|
+
existingCones: options?.preserveExisting !== false ? this.collectExistingCones() : undefined,
|
|
1001
|
+
onlyEmpty: options?.onlyEmpty ?? false,
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
const result = await generateCones(context);
|
|
1005
|
+
this.applyCones(result);
|
|
1006
|
+
await this.save();
|
|
1007
|
+
return result;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* 기존 cone들을 수집합니다 (entity, props, enums, subsets).
|
|
1012
|
+
*
|
|
1013
|
+
* @returns 키가 "entity:id", "prop:name", "enum:enumId", "subset:key" 형식인 cone 맵
|
|
1014
|
+
*/
|
|
1015
|
+
private collectExistingCones(): Record<string, Cone> {
|
|
1016
|
+
const cones: Record<string, Cone> = {};
|
|
1017
|
+
|
|
1018
|
+
if (this.cone) {
|
|
1019
|
+
cones[`entity:${this.id}`] = this.cone;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
for (const prop of this.props) {
|
|
1023
|
+
if (prop.cone) {
|
|
1024
|
+
cones[`prop:${prop.name}`] = prop.cone;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
for (const [enumId, cone] of Object.entries(this.enumCones)) {
|
|
1029
|
+
cones[`enum:${enumId}`] = cone;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
for (const [subsetKey, cone] of Object.entries(this.subsetCones)) {
|
|
1033
|
+
cones[`subset:${subsetKey}`] = cone;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
return cones;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* 생성된 cone들을 Entity에 적용합니다.
|
|
1041
|
+
*
|
|
1042
|
+
* @param result - LLM으로 생성된 cone 결과
|
|
1043
|
+
*/
|
|
1044
|
+
private applyCones(result: import("../cone/cone-generator").ConeGenerationResult): void {
|
|
1045
|
+
if (result.entityCone) {
|
|
1046
|
+
this.cone = result.entityCone;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
for (const [propName, cone] of Object.entries(result.propCones)) {
|
|
1050
|
+
const prop = this.props.find((p) => p.name === propName);
|
|
1051
|
+
if (prop) {
|
|
1052
|
+
(prop as { cone?: Cone }).cone = cone;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
this.enumCones = { ...this.enumCones, ...result.enumCones };
|
|
1057
|
+
this.subsetCones = { ...this.subsetCones, ...result.subsetCones };
|
|
1058
|
+
}
|
|
1059
|
+
|
|
893
1060
|
getSubsetRows(
|
|
894
1061
|
_subsets?: { [key: string]: string[] },
|
|
895
1062
|
_subsetsInternal?: { [key: string]: string[] },
|
|
@@ -1179,4 +1346,13 @@ export class Entity {
|
|
|
1179
1346
|
}
|
|
1180
1347
|
return idProp;
|
|
1181
1348
|
}
|
|
1349
|
+
|
|
1350
|
+
/**
|
|
1351
|
+
* 엔티티의 PK 배열 타입을 반환합니다.
|
|
1352
|
+
* LoaderQuery의 fromIds 타입으로 사용됩니다.
|
|
1353
|
+
*/
|
|
1354
|
+
getPkArrayType(): string {
|
|
1355
|
+
const pkType = this.getPkType();
|
|
1356
|
+
return pkType === "integer" ? "number[]" : "string[]";
|
|
1357
|
+
}
|
|
1182
1358
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @generated
|
|
3
|
+
* 최초 1회 생성되며, 이후에는 덮어쓰지 않습니다.
|
|
4
|
+
* 필요시 직접 수정할 수 있습니다.
|
|
5
|
+
*/
|
|
1
6
|
/** biome-ignore-all lint/correctness/useExhaustiveDependencies: shared */
|
|
2
7
|
/** biome-ignore-all lint/suspicious/noExplicitAny: shared */
|
|
3
8
|
|
|
@@ -368,12 +373,11 @@ export function useSSEStream<T extends Record<string, any>>(
|
|
|
368
373
|
const fullUrl = queryString ? `${url}?${queryString}` : url;
|
|
369
374
|
|
|
370
375
|
const eventSource = new EventSource(fullUrl, {
|
|
371
|
-
fetch: (url,
|
|
372
|
-
fetch({
|
|
373
|
-
|
|
374
|
-
...options,
|
|
376
|
+
fetch: (url, init) =>
|
|
377
|
+
globalThis.fetch(url, {
|
|
378
|
+
...init,
|
|
375
379
|
headers: {
|
|
376
|
-
...
|
|
380
|
+
...init?.headers,
|
|
377
381
|
"Accept-Language": getCurrentLocale(),
|
|
378
382
|
},
|
|
379
383
|
}),
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Project Skills
|
|
2
|
+
|
|
3
|
+
이 디렉토리는 프로젝트 고유의 문서를 저장하는 공간입니다.
|
|
4
|
+
|
|
5
|
+
## 용도
|
|
6
|
+
|
|
7
|
+
- **requirements.md**: 프로젝트 요구사항 명세
|
|
8
|
+
- **business-logic.md**: 비즈니스 로직 상세 (선택)
|
|
9
|
+
- **architecture.md**: 아키텍처 설계 문서 (선택)
|
|
10
|
+
|
|
11
|
+
## 사용 방법
|
|
12
|
+
|
|
13
|
+
1. 프로젝트 생성 시 AI가 요구사항을 받으면 `requirements.md`에 자동으로 저장됩니다.
|
|
14
|
+
2. 이후 대화에서 AI는 이 문서들을 지속적으로 참고합니다.
|
|
15
|
+
3. 사용자가 직접 추가하고 싶은 내용이 있으면 이 디렉토리에 새로운 .md 파일을 추가하거나 기존 파일을 수정하세요.
|
|
16
|
+
|
|
17
|
+
## 주의사항
|
|
18
|
+
|
|
19
|
+
- 이 디렉토리의 파일들은 프로젝트별로 관리됩니다.
|
|
20
|
+
- Sonamu skills sync 시에도 덮어쓰지 않고 유지됩니다.
|
|
21
|
+
- 민감한 정보(비밀번호, API 키 등)는 절대 포함하지 마세요.
|