sonamu 0.7.1 → 0.7.3

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.
Files changed (81) hide show
  1. package/dist/ai/agents/types.d.ts +4 -3
  2. package/dist/ai/agents/types.d.ts.map +1 -1
  3. package/dist/ai/agents/types.js +1 -1
  4. package/dist/api/code-converters.js +2 -2
  5. package/dist/api/config.d.ts +4 -2
  6. package/dist/api/config.d.ts.map +1 -1
  7. package/dist/api/config.js +6 -3
  8. package/dist/api/decorators.d.ts.map +1 -1
  9. package/dist/api/decorators.js +3 -2
  10. package/dist/api/sonamu.d.ts.map +1 -1
  11. package/dist/api/sonamu.js +3 -4
  12. package/dist/bin/cli.js +13 -29
  13. package/dist/bin/{hot-hook-register.d.ts → hmr-hook-register.d.ts} +3 -3
  14. package/dist/bin/hmr-hook-register.d.ts.map +1 -0
  15. package/dist/bin/{hot-hook-register.js → hmr-hook-register.js} +5 -5
  16. package/dist/bin/ts-loader-register.d.ts +2 -0
  17. package/dist/bin/ts-loader-register.d.ts.map +1 -0
  18. package/dist/bin/ts-loader-register.js +34 -0
  19. package/dist/database/base-model.d.ts +2 -34
  20. package/dist/database/base-model.d.ts.map +1 -1
  21. package/dist/database/base-model.js +3 -170
  22. package/dist/database/base-model.types.d.ts +1 -0
  23. package/dist/database/base-model.types.d.ts.map +1 -1
  24. package/dist/database/base-model.types.js +2 -2
  25. package/dist/database/puri-wrapper.js +7 -3
  26. package/dist/database/upsert-builder.d.ts +7 -3
  27. package/dist/database/upsert-builder.d.ts.map +1 -1
  28. package/dist/database/upsert-builder.js +63 -25
  29. package/dist/entity/entity-manager.d.ts +1 -1
  30. package/dist/entity/entity.js +3 -3
  31. package/dist/migration/code-generation.d.ts.map +1 -1
  32. package/dist/migration/code-generation.js +8 -7
  33. package/dist/migration/migration-set.d.ts.map +1 -1
  34. package/dist/migration/migration-set.js +2 -25
  35. package/dist/migration/migrator.js +2 -2
  36. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  37. package/dist/migration/postgresql-schema-reader.js +2 -1
  38. package/dist/syncer/file-patterns.js +2 -2
  39. package/dist/syncer/syncer.js +3 -3
  40. package/dist/template/implementations/service.template.d.ts.map +1 -1
  41. package/dist/template/implementations/service.template.js +3 -2
  42. package/dist/template/zod-converter.js +4 -2
  43. package/dist/types/types.d.ts +6 -5
  44. package/dist/types/types.d.ts.map +1 -1
  45. package/dist/types/types.js +2 -2
  46. package/dist/utils/model.d.ts +9 -2
  47. package/dist/utils/model.d.ts.map +1 -1
  48. package/dist/utils/model.js +1 -1
  49. package/dist/utils/path-utils.d.ts +1 -1
  50. package/dist/utils/path-utils.d.ts.map +1 -1
  51. package/dist/utils/path-utils.js +1 -1
  52. package/package.json +12 -12
  53. package/src/ai/agents/types.ts +6 -3
  54. package/src/api/code-converters.ts +2 -2
  55. package/src/api/config.ts +17 -6
  56. package/src/api/decorators.ts +2 -1
  57. package/src/api/sonamu.ts +2 -5
  58. package/src/bin/cli.ts +13 -30
  59. package/src/bin/{hot-hook-register.ts → hmr-hook-register.ts} +4 -4
  60. package/src/bin/{loader-register.ts → ts-loader-register.ts} +2 -2
  61. package/src/database/base-model.ts +5 -236
  62. package/src/database/base-model.types.ts +2 -0
  63. package/src/database/puri-wrapper.ts +2 -2
  64. package/src/database/upsert-builder.ts +88 -29
  65. package/src/entity/entity.ts +2 -2
  66. package/src/migration/code-generation.ts +8 -6
  67. package/src/migration/migration-set.ts +0 -20
  68. package/src/migration/migrator.ts +1 -1
  69. package/src/migration/postgresql-schema-reader.ts +1 -0
  70. package/src/shared/web.shared.ts.txt +6 -4
  71. package/src/syncer/file-patterns.ts +1 -1
  72. package/src/syncer/syncer.ts +2 -2
  73. package/src/template/implementations/service.template.ts +2 -1
  74. package/src/template/zod-converter.ts +3 -1
  75. package/src/types/types.ts +3 -2
  76. package/src/utils/model.ts +10 -4
  77. package/src/utils/path-utils.ts +5 -2
  78. package/dist/bin/hot-hook-register.d.ts.map +0 -1
  79. package/dist/bin/loader-register.d.ts +0 -2
  80. package/dist/bin/loader-register.d.ts.map +0 -1
  81. package/dist/bin/loader-register.js +0 -34
@@ -88,10 +88,6 @@ export function getMigrationSetFromEntity(entity: Entity): MigrationSetAndJoinTa
88
88
  r.joinTables.push({
89
89
  table: through.from.split(".")[0],
90
90
  indexes: [
91
- {
92
- type: "unique",
93
- columns: ["uuid"],
94
- },
95
91
  // 조인 테이블에 걸린 인덱스 찾아와서 연결
96
92
  ...entity.indexes
97
93
  .filter((index) => index.columns.find((col) => col.includes(`${prop.joinTable}.`)))
@@ -113,11 +109,6 @@ export function getMigrationSetFromEntity(entity: Entity): MigrationSetAndJoinTa
113
109
  nullable: false,
114
110
  } as MigrationColumn;
115
111
  }),
116
- {
117
- name: "uuid",
118
- nullable: true,
119
- type: "uuid",
120
- },
121
112
  ],
122
113
  foreigns: fields.map((field) => {
123
114
  // 현재 필드가 어떤 테이블에 속하는지 판단
@@ -175,17 +166,6 @@ export function getMigrationSetFromEntity(entity: Entity): MigrationSetAndJoinTa
175
166
  index.columns.find((col) => col.includes(".") === false),
176
167
  );
177
168
 
178
- // uuid
179
- migrationSet.columns = migrationSet.columns.concat({
180
- name: "uuid",
181
- nullable: true,
182
- type: "uuid",
183
- } as MigrationColumn);
184
- migrationSet.indexes = migrationSet.indexes.concat({
185
- type: "unique",
186
- columns: ["uuid"],
187
- } as MigrationIndex);
188
-
189
169
  return migrationSet;
190
170
  }
191
171
 
@@ -341,7 +341,7 @@ export class Migrator {
341
341
  ...tables[0],
342
342
  indexes: unique(
343
343
  tables.flatMap((t) => t.indexes),
344
- (index) => [index.type, ...index.columns.sort()].join("-"),
344
+ (index) => [index.type, ...index.columns].join("-"),
345
345
  ),
346
346
  };
347
347
  });
@@ -109,6 +109,7 @@ class PostgreSQLSchemaReaderClass {
109
109
 
110
110
  return {
111
111
  type,
112
+ name: indexName,
112
113
  columns: currentIndexes.map((idx) => idx.column_name),
113
114
  };
114
115
  });
@@ -86,10 +86,12 @@ export function defaultCatch(e: any) {
86
86
  /*
87
87
  Isomorphic Types
88
88
  */
89
- export type ListResult<T> = {
90
- rows: T[];
91
- total?: number;
92
- };
89
+ export type ListResult<LP extends { queryMode?: SonamuQueryMode }, T> = LP["queryMode"] extends "list"
90
+ ? { rows: T[] }
91
+ : LP["queryMode"] extends "count"
92
+ ? { total: number }
93
+ : { rows: T[]; total: number };
94
+
93
95
  export const SonamuQueryMode = z.enum(["both", "list", "count"]);
94
96
  export type SonamuQueryMode = z.infer<typeof SonamuQueryMode>;
95
97
 
@@ -30,7 +30,7 @@ export const checksumPatternGroup: GlobPattern<ApiRelativePath> = {
30
30
  model: "src/application/**/*.model.ts",
31
31
  frame: "src/application/**/*.frame.ts",
32
32
  functions: "src/application/**/*.functions.ts",
33
- config: "sonamu.config.ts",
33
+ config: "src/sonamu.config.ts",
34
34
  };
35
35
 
36
36
  /**
@@ -1,4 +1,4 @@
1
- import { hot } from "@sonamu-kit/hot-hook";
1
+ import { hot } from "@sonamu-kit/hmr-hook";
2
2
  import assert from "assert";
3
3
  import chalk from "chalk";
4
4
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -122,7 +122,7 @@ export class Syncer {
122
122
  }
123
123
 
124
124
  // 싱크 작업이 끝나면 모든 모듈을 로드합니다.
125
- // hot-hook에 의해 invalidate된 부분들이 아니라면 캐시 그대로 유지합니다.
125
+ // hmr-hook에 의해 invalidate된 부분들이 아니라면 캐시 그대로 유지합니다.
126
126
  await this.autoloadTypes();
127
127
  await this.autoloadModels();
128
128
  await this.autoloadApis();
@@ -85,11 +85,12 @@ export class Template__service extends Template {
85
85
  );
86
86
 
87
87
  // 파라미터 타입 정의
88
- const typeParamsDef = api.typeParameters
88
+ const typeParametersAsTsType = api.typeParameters
89
89
  .map((typeParam) => {
90
90
  return apiParamTypeToTsType(typeParam, importKeys);
91
91
  })
92
92
  .join(", ");
93
+ const typeParamsDef = typeParametersAsTsType ? `<${typeParametersAsTsType}>` : "";
93
94
  typeParamNames = typeParamNames.concat(
94
95
  api.typeParameters.map((typeParam) => typeParam.id),
95
96
  );
@@ -342,7 +342,7 @@ export function zodTypeToTsTypeDef(zt: z.ZodType): string {
342
342
  // ZodType - 재귀적으로 변환
343
343
  if (part && typeof part === "object" && (part as z.ZodType)._zod) {
344
344
  const innerType = zodTypeToTsTypeDef(part as z.ZodType);
345
- return `\${${innerType}}`;
345
+ return `$\{${innerType}}`;
346
346
  }
347
347
 
348
348
  // 폴백
@@ -571,6 +571,8 @@ function resolveRenderType(key: string, zodType: z.ZodTypeAny): RenderingNode["r
571
571
  return "string-plain";
572
572
  } else if (zodType instanceof z.ZodLiteral) {
573
573
  return "string-plain";
574
+ } else if (zodType instanceof z.ZodTemplateLiteral) {
575
+ return "string-plain";
574
576
  } else {
575
577
  throw new Error(`타입 파싱 불가 ${key} ${zodType.def.type}`);
576
578
  }
@@ -175,7 +175,7 @@ export type EntityProp =
175
175
  export type EntityIndex = {
176
176
  type: "index" | "unique" | "fulltext";
177
177
  columns: string[];
178
- name?: string;
178
+ name: string;
179
179
  parser?: "built-in" | "ngram";
180
180
  };
181
181
  export type EntityJson = {
@@ -451,6 +451,7 @@ export type MigrationColumn = {
451
451
  scale?: number;
452
452
  };
453
453
  export type MigrationIndex = {
454
+ name: string;
454
455
  columns: string[];
455
456
  type: "unique" | "index" | "fulltext";
456
457
  parser?: "built-in" | "ngram";
@@ -942,7 +943,7 @@ const EntityIndexSchema = z
942
943
  .object({
943
944
  type: z.enum(["index", "unique", "fulltext"]),
944
945
  columns: z.array(z.string()),
945
- name: z.string().optional(),
946
+ name: z.string().min(1).max(63),
946
947
  parser: z.enum(["built-in", "ngram"]).optional(),
947
948
  })
948
949
  .strict();
@@ -1,7 +1,13 @@
1
- export type ListResult<T> = {
2
- rows: T[];
3
- total?: number;
4
- };
1
+ import type { SonamuQueryMode } from "..";
2
+
3
+ export type ListResult<
4
+ LP extends { queryMode?: SonamuQueryMode },
5
+ T,
6
+ > = LP["queryMode"] extends "list"
7
+ ? { rows: T[] }
8
+ : LP["queryMode"] extends "count"
9
+ ? { total: number }
10
+ : { rows: T[]; total: number };
5
11
 
6
12
  export type ArrayOr<T> = T | T[];
7
13
 
@@ -10,7 +10,7 @@ import { isHotReloadServer, isTest } from "./controller.js";
10
10
  *
11
11
  * **기준점**: `Sonamu.apiRootPath` (일반적으로 프로젝트의 `/api` 디렉토리)
12
12
  */
13
- export type ApiRelativePath = `${"src" | "dist"}/${string}` | "sonamu.config.ts";
13
+ export type ApiRelativePath = `${"src" | "dist"}/${string}`;
14
14
 
15
15
  /**
16
16
  * 앱 루트 기준 상대 경로 (api/, web/ 등 타겟 디렉토리로 시작)
@@ -90,7 +90,10 @@ export type AbsolutePath = `/${string}`;
90
90
  * @param anyPath
91
91
  * @returns
92
92
  */
93
- export function runtimePath(anyPath: string, isDev: boolean = isHotReloadServer() || isTest()): string {
93
+ export function runtimePath(
94
+ anyPath: string,
95
+ isDev: boolean = isHotReloadServer() || isTest(),
96
+ ): string {
94
97
  if (isDev) {
95
98
  return anyPath.replace(/dist\//, "src/").replace(/\.js/, ".ts");
96
99
  } else {
@@ -1 +0,0 @@
1
- {"version":3,"file":"hot-hook-register.d.ts","sourceRoot":"","sources":["../../src/bin/hot-hook-register.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=loader-register.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loader-register.d.ts","sourceRoot":"","sources":["../../src/bin/loader-register.ts"],"names":[],"mappings":""}
@@ -1,34 +0,0 @@
1
- import { register } from "node:module";
2
- import * as path from "node:path";
3
- import { exists } from "../utils/fs-utils.js";
4
- import { findApiRootPath } from "../utils/utils.js";
5
- /**
6
- * @sonamu-kit/loader/loader를 등록하는 스크립트입니다.
7
- * 이 스크립트는 sonamu cli로 dev 실행할 때 --import로 실행됩니다.
8
- */ async function setupSwcConfig() {
9
- try {
10
- const apiRoot = findApiRootPath();
11
- // 프로젝트 루트에서 .swcrc 찾기
12
- const projectSwcrcPath = path.join(apiRoot, ".swcrc");
13
- if (await exists(projectSwcrcPath)) {
14
- // 사용자 프로젝트에 .swcrc가 있으면 우선으로 사용합니다.
15
- process.env.SWCRC_PATH = projectSwcrcPath;
16
- return;
17
- }
18
- // 아니라면 sonamu가 관리하는 .swcrc.project-default를 가져다 씁니다.
19
- const sonamuSwcrcPath = path.join(import.meta.dirname, "..", "..", ".swcrc.project-default");
20
- if (await exists(sonamuSwcrcPath)) {
21
- process.env.SWCRC_PATH = sonamuSwcrcPath;
22
- return;
23
- }
24
- } catch {
25
- // 환경 변수 설정 실패는 무시 (loader가 기본 설정 사용)
26
- }
27
- }
28
- // swc 설정 파일 경로를 환경 변수로 설정
29
- await setupSwcConfig();
30
- register("@sonamu-kit/loader/loader", {
31
- parentURL: import.meta.url
32
- });
33
-
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iaW4vbG9hZGVyLXJlZ2lzdGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJlZ2lzdGVyIH0gZnJvbSBcIm5vZGU6bW9kdWxlXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGV4aXN0cyB9IGZyb20gXCIuLi91dGlscy9mcy11dGlscy5qc1wiO1xuaW1wb3J0IHsgZmluZEFwaVJvb3RQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzLmpzXCI7XG5cbi8qKlxuICogQHNvbmFtdS1raXQvbG9hZGVyL2xvYWRlcuulvCDrk7HroZ3tlZjripQg7Iqk7YGs66a97Yq47J6F64uI64ukLlxuICog7J20IOyKpO2BrOumve2KuOuKlCBzb25hbXUgY2xp66GcIGRldiDsi6TtlontlaAg65WMIC0taW1wb3J066GcIOyLpO2WieuQqeuLiOuLpC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2V0dXBTd2NDb25maWcoKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgYXBpUm9vdCA9IGZpbmRBcGlSb290UGF0aCgpO1xuXG4gICAgLy8g7ZSE66Gc7KCd7Yq4IOujqO2KuOyXkOyEnCAuc3djcmMg7LC+6riwXG4gICAgY29uc3QgcHJvamVjdFN3Y3JjUGF0aCA9IHBhdGguam9pbihhcGlSb290LCBcIi5zd2NyY1wiKTtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKHByb2plY3RTd2NyY1BhdGgpKSB7XG4gICAgICAvLyDsgqzsmqnsnpAg7ZSE66Gc7KCd7Yq47JeQIC5zd2NyY+qwgCDsnojsnLzrqbQg7Jqw7ISg7Jy866GcIOyCrOyaqe2VqeuLiOuLpC5cbiAgICAgIHByb2Nlc3MuZW52LlNXQ1JDX1BBVEggPSBwcm9qZWN0U3djcmNQYXRoO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyVhOuLiOudvOuptCBzb25hbXXqsIAg6rSA66as7ZWY64qUIC5zd2NyYy5wcm9qZWN0LWRlZmF1bHTrpbwg6rCA7KC464ukIOyUgeuLiOuLpC5cbiAgICBjb25zdCBzb25hbXVTd2NyY1BhdGggPSBwYXRoLmpvaW4oaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwiLnN3Y3JjLnByb2plY3QtZGVmYXVsdFwiKTtcbiAgICBpZiAoYXdhaXQgZXhpc3RzKHNvbmFtdVN3Y3JjUGF0aCkpIHtcbiAgICAgIHByb2Nlc3MuZW52LlNXQ1JDX1BBVEggPSBzb25hbXVTd2NyY1BhdGg7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICAvLyDtmZjqsr0g67OA7IiYIOyEpOyglSDsi6TtjKjripQg66y07IucIChsb2FkZXLqsIAg6riw67O4IOyEpOyglSDsgqzsmqkpXG4gIH1cbn1cblxuLy8gc3djIOyEpOyglSDtjIzsnbwg6rK966Gc66W8IO2ZmOqyvSDrs4DsiJjroZwg7ISk7KCVXG5hd2FpdCBzZXR1cFN3Y0NvbmZpZygpO1xuXG5yZWdpc3RlcihcIkBzb25hbXUta2l0L2xvYWRlci9sb2FkZXJcIiwge1xuICBwYXJlbnRVUkw6IGltcG9ydC5tZXRhLnVybCxcbn0pO1xuIl0sIm5hbWVzIjpbInJlZ2lzdGVyIiwicGF0aCIsImV4aXN0cyIsImZpbmRBcGlSb290UGF0aCIsInNldHVwU3djQ29uZmlnIiwiYXBpUm9vdCIsInByb2plY3RTd2NyY1BhdGgiLCJqb2luIiwicHJvY2VzcyIsImVudiIsIlNXQ1JDX1BBVEgiLCJzb25hbXVTd2NyY1BhdGgiLCJkaXJuYW1lIiwicGFyZW50VVJMIiwidXJsIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxRQUFRLFFBQVEsY0FBYztBQUN2QyxZQUFZQyxVQUFVLFlBQVk7QUFDbEMsU0FBU0MsTUFBTSxRQUFRLHVCQUF1QjtBQUM5QyxTQUFTQyxlQUFlLFFBQVEsb0JBQW9CO0FBRXBEOzs7Q0FHQyxHQUNELGVBQWVDO0lBQ2IsSUFBSTtRQUNGLE1BQU1DLFVBQVVGO1FBRWhCLHNCQUFzQjtRQUN0QixNQUFNRyxtQkFBbUJMLEtBQUtNLElBQUksQ0FBQ0YsU0FBUztRQUM1QyxJQUFJLE1BQU1ILE9BQU9JLG1CQUFtQjtZQUNsQyxvQ0FBb0M7WUFDcENFLFFBQVFDLEdBQUcsQ0FBQ0MsVUFBVSxHQUFHSjtZQUN6QjtRQUNGO1FBRUEscURBQXFEO1FBQ3JELE1BQU1LLGtCQUFrQlYsS0FBS00sSUFBSSxDQUFDLFlBQVlLLE9BQU8sRUFBRSxNQUFNLE1BQU07UUFDbkUsSUFBSSxNQUFNVixPQUFPUyxrQkFBa0I7WUFDakNILFFBQVFDLEdBQUcsQ0FBQ0MsVUFBVSxHQUFHQztZQUN6QjtRQUNGO0lBQ0YsRUFBRSxPQUFNO0lBQ04scUNBQXFDO0lBQ3ZDO0FBQ0Y7QUFFQSwwQkFBMEI7QUFDMUIsTUFBTVA7QUFFTkosU0FBUyw2QkFBNkI7SUFDcENhLFdBQVcsWUFBWUMsR0FBRztBQUM1QiJ9