sonamu 0.7.12 → 0.7.13
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 +0 -3
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +1 -1
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +14 -4
- package/dist/bin/cli.js +2 -58
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +3 -2
- package/dist/syncer/syncer.d.ts +2 -1
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +17 -18
- package/dist/types/types.d.ts +1 -1
- package/dist/ui/ai-api.d.ts +1 -0
- package/dist/ui/ai-api.d.ts.map +1 -0
- package/dist/ui/ai-api.js +50 -0
- package/dist/ui/ai-client.d.ts +1 -0
- package/dist/ui/ai-client.d.ts.map +1 -0
- package/dist/ui/ai-client.js +438 -0
- package/dist/ui/api.d.ts +3 -0
- package/dist/ui/api.d.ts.map +1 -0
- package/dist/ui/api.js +680 -0
- package/dist/ui-web/assets/brand-icons-Cu_C0hZ4.svg +1008 -0
- package/dist/ui-web/assets/brand-icons-F3SPCeH1.woff +0 -0
- package/dist/ui-web/assets/brand-icons-XL9sxUpA.woff2 +0 -0
- package/dist/ui-web/assets/brand-icons-sqJ2Pg7a.eot +0 -0
- package/dist/ui-web/assets/brand-icons-ubhWoxly.ttf +0 -0
- package/dist/ui-web/assets/flags-DOLqOU7Y.png +0 -0
- package/dist/ui-web/assets/icons-BOCtAERH.woff +0 -0
- package/dist/ui-web/assets/icons-CHzK1VD9.eot +0 -0
- package/dist/ui-web/assets/icons-D29ZQHHw.ttf +0 -0
- package/dist/ui-web/assets/icons-Du6TOHnR.woff2 +0 -0
- package/dist/ui-web/assets/icons-RwhydX30.svg +1518 -0
- package/dist/ui-web/assets/index-CpaB9P6g.css +1 -0
- package/dist/ui-web/assets/index-J9MCfjCd.js +95 -0
- package/dist/ui-web/assets/outline-icons-BfdLr8tr.svg +366 -0
- package/dist/ui-web/assets/outline-icons-DD8jm0uy.ttf +0 -0
- package/dist/ui-web/assets/outline-icons-DInHoiqI.woff2 +0 -0
- package/dist/ui-web/assets/outline-icons-LX8adJ4n.eot +0 -0
- package/dist/ui-web/assets/outline-icons-aQ88nltS.woff +0 -0
- package/dist/ui-web/assets/provider-utils_false-BKJD46kk.js +1 -0
- package/dist/ui-web/assets/provider-utils_false-Bu5lmX18.js +1 -0
- package/dist/ui-web/index.html +13 -0
- package/dist/ui-web/vite.svg +1 -0
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +7 -7
- package/package.json +7 -5
- package/src/api/config.ts +0 -3
- package/src/api/sonamu.ts +17 -4
- package/src/bin/cli.ts +1 -67
- package/src/syncer/api-parser.ts +2 -1
- package/src/syncer/syncer.ts +20 -21
- package/src/ui/ai-api.ts +60 -0
- package/src/ui/ai-client.ts +499 -0
- package/src/ui/api.ts +786 -0
- package/src/vector/embedding.ts +8 -6
package/dist/vector/embedding.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
2
1
|
import { embedMany } from "ai";
|
|
3
|
-
import { VoyageAIClient } from "voyageai";
|
|
4
2
|
import { Sonamu } from "../api/sonamu.js";
|
|
5
3
|
import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
6
4
|
/**
|
|
@@ -34,7 +32,8 @@ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
|
34
32
|
}
|
|
35
33
|
/**
|
|
36
34
|
* Voyage AI 클라이언트 초기화
|
|
37
|
-
*/ getVoyageClient() {
|
|
35
|
+
*/ async getVoyageClient() {
|
|
36
|
+
const { VoyageAIClient } = await import("voyageai");
|
|
38
37
|
const apiKey = Sonamu.secrets?.voyage_api_key ?? process.env.VOYAGE_API_KEY;
|
|
39
38
|
if (!apiKey) {
|
|
40
39
|
throw new Error("VOYAGE_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
|
|
@@ -45,7 +44,8 @@ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
|
45
44
|
}
|
|
46
45
|
/**
|
|
47
46
|
* OpenAI provider 생성
|
|
48
|
-
*/ getOpenAIProvider() {
|
|
47
|
+
*/ async getOpenAIProvider() {
|
|
48
|
+
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
49
49
|
const apiKey = Sonamu.secrets?.openai_api_key ?? process.env.OPENAI_API_KEY;
|
|
50
50
|
if (!apiKey) {
|
|
51
51
|
throw new Error("OPENAI_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
|
|
@@ -85,7 +85,7 @@ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
|
85
85
|
/**
|
|
86
86
|
* Voyage AI 임베딩
|
|
87
87
|
*/ async embedVoyage(texts, inputType) {
|
|
88
|
-
const client = this.getVoyageClient();
|
|
88
|
+
const client = await this.getVoyageClient();
|
|
89
89
|
const voyageConfig = this.config.voyage;
|
|
90
90
|
const response = await client.embed({
|
|
91
91
|
input: texts,
|
|
@@ -104,7 +104,7 @@ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
|
104
104
|
/**
|
|
105
105
|
* OpenAI 임베딩
|
|
106
106
|
*/ async embedOpenAI(texts) {
|
|
107
|
-
const openai = this.getOpenAIProvider();
|
|
107
|
+
const openai = await this.getOpenAIProvider();
|
|
108
108
|
const openaiConfig = this.config.openai;
|
|
109
109
|
const model = openai.embeddingModel(openaiConfig.model);
|
|
110
110
|
const { embeddings, usage } = await embedMany({
|
|
@@ -125,4 +125,4 @@ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
|
125
125
|
}
|
|
126
126
|
export const Embedding = new EmbeddingClass();
|
|
127
127
|
|
|
128
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvZW1iZWRkaW5nLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyZWF0ZU9wZW5BSSwgdHlwZSBPcGVuQUlQcm92aWRlciB9IGZyb20gXCJAYWktc2RrL29wZW5haVwiO1xuaW1wb3J0IHsgdHlwZSBFbWJlZGRpbmdNb2RlbCwgZW1iZWRNYW55IH0gZnJvbSBcImFpXCI7XG5pbXBvcnQgeyBWb3lhZ2VBSUNsaWVudCB9IGZyb20gXCJ2b3lhZ2VhaVwiO1xuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IERFRkFVTFRfVkVDVE9SX0NPTkZJRyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0IHR5cGUge1xuICBFbWJlZGRpbmdQcm92aWRlcixcbiAgRW1iZWRkaW5nUmVzdWx0LFxuICBQcm9ncmVzc0NhbGxiYWNrLFxuICBWZWN0b3JDb25maWcsXG4gIFZlY3RvcklucHV0VHlwZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiDsnoTrsqDrlKkg7YG065287J207Ja47Yq4XG4gKiBWb3lhZ2UgQUnsmYAgT3BlbkFJIOyehOuyoOuUqeydhCBTREsg67Cp7Iud7Jy866GcIO2Gte2VqSDsp4Dsm5BcbiAqL1xuZXhwb3J0IGNsYXNzIEVtYmVkZGluZ0NsYXNzIHtcbiAgcHJpdmF0ZSBjb25maWc6IFZlY3RvckNvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8VmVjdG9yQ29uZmlnPiA9IHt9KSB7XG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICB2b3lhZ2U6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnZveWFnZSwgLi4uY29uZmlnLnZveWFnZSB9LFxuICAgICAgb3BlbmFpOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5vcGVuYWksIC4uLmNvbmZpZy5vcGVuYWkgfSxcbiAgICAgIGNodW5raW5nOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5jaHVua2luZywgLi4uY29uZmlnLmNodW5raW5nIH0sXG4gICAgICBzZWFyY2g6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnNlYXJjaCwgLi4uY29uZmlnLnNlYXJjaCB9LFxuICAgICAgcGd2ZWN0b3I6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnBndmVjdG9yLCAuLi5jb25maWcucGd2ZWN0b3IgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZveWFnZSBBSSDtgbTrnbzsnbTslrjtirgg7LSI6riw7ZmUXG4gICAqL1xuICBwcml2YXRlIGdldFZveWFnZUNsaWVudCgpOiBWb3lhZ2VBSUNsaWVudCB7XG4gICAgY29uc3QgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/LnZveWFnZV9hcGlfa2V5ID8/IHByb2Nlc3MuZW52LlZPWUFHRV9BUElfS0VZO1xuICAgIGlmICghYXBpS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJWT1lBR0VfQVBJX0tFWeqwgCDshKTsoJXrkJjsp4Ag7JWK7JWY7Iq164uI64ukLiDtmZjqsr3rs4DsiJjrpbwg7ZmV7J247ZWY7IS47JqULlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBWb3lhZ2VBSUNsaWVudCh7IGFwaUtleSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuQUkgcHJvdmlkZXIg7IOd7ISxXG4gICAqL1xuICBwcml2YXRlIGdldE9wZW5BSVByb3ZpZGVyKCk6IE9wZW5BSVByb3ZpZGVyIHtcbiAgICBjb25zdCBhcGlLZXkgPSBTb25hbXUuc2VjcmV0cz8ub3BlbmFpX2FwaV9rZXkgPz8gcHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVk7XG4gICAgaWYgKCFhcGlLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk9QRU5BSV9BUElfS0VZ6rCAIOyEpOygleuQmOyngCDslYrslZjsirXri4jri6QuIO2ZmOqyveuzgOyImOulvCDtmZXsnbjtlZjshLjsmpQuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlT3BlbkFJKHsgYXBpS2V5IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIO2FjeyKpO2KuCDsnoTrsqDrlKkg7IOd7ISxXG4gICAqIEBwYXJhbSB0ZXh0cyAtIOyehOuyoOuUqe2VoCDthY3siqTtirgg67Cw7Je0IChiYXRjaFNpemXsnbTsg4Eg7IucIOyekOuPmSDrtoTtlaApXG4gICAqIEBwYXJhbSBwcm92aWRlciAtICd2b3lhZ2UnIHwgJ29wZW5haSdcbiAgICogQHBhcmFtIGlucHV0VHlwZSAtICdkb2N1bWVudCcgfCAncXVlcnknIChWb3lhZ2UgQUnrp4wg7ZW064u5KVxuICAgKiBAcGFyYW0gb25Qcm9ncmVzcyAtIOynhO2WieuloCDsvZzrsLFcbiAgICovXG4gIGFzeW5jIGVtYmVkKFxuICAgIHRleHRzOiBzdHJpbmdbXSxcbiAgICBwcm92aWRlcjogRW1iZWRkaW5nUHJvdmlkZXIsXG4gICAgaW5wdXRUeXBlOiBWZWN0b3JJbnB1dFR5cGUgPSBcImRvY3VtZW50XCIsXG4gICAgb25Qcm9ncmVzcz86IFByb2dyZXNzQ2FsbGJhY2ssXG4gICk6IFByb21pc2U8RW1iZWRkaW5nUmVzdWx0W10+IHtcbiAgICBjb25zdCBtYXhCYXRjaFNpemUgPVxuICAgICAgcHJvdmlkZXIgPT09IFwidm95YWdlXCIgPyB0aGlzLmNvbmZpZy52b3lhZ2UuYmF0Y2hTaXplIDogdGhpcy5jb25maWcub3BlbmFpLmJhdGNoU2l6ZTtcblxuICAgIC8vIGJhdGNoU2l6ZeydtO2VmOuptCDrsJTroZwg7Zi47LacXG4gICAgaWYgKHRleHRzLmxlbmd0aCA8PSBtYXhCYXRjaFNpemUpIHtcbiAgICAgIHJldHVybiBwcm92aWRlciA9PT0gXCJ2b3lhZ2VcIlxuICAgICAgICA/IGF3YWl0IHRoaXMuZW1iZWRWb3lhZ2UodGV4dHMsIGlucHV0VHlwZSlcbiAgICAgICAgOiBhd2FpdCB0aGlzLmVtYmVkT3BlbkFJKHRleHRzKTtcbiAgICB9XG5cbiAgICAvLyBiYXRjaFNpemXsnbTsg4HsnbTrqbQg7J6Q64+Z7Jy866GcIOuCmOuIoOyEnCDsspjrpqxcbiAgICBjb25zdCBiYXRjaGVzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogTWF0aC5jZWlsKHRleHRzLmxlbmd0aCAvIG1heEJhdGNoU2l6ZSkgfSwgKF8sIGkpID0+XG4gICAgICB0ZXh0cy5zbGljZShpICogbWF4QmF0Y2hTaXplLCAoaSArIDEpICogbWF4QmF0Y2hTaXplKSxcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYmF0Y2hlcy5tYXAoKGJhdGNoKSA9PlxuICAgICAgICBwcm92aWRlciA9PT0gXCJ2b3lhZ2VcIiA/IHRoaXMuZW1iZWRWb3lhZ2UoYmF0Y2gsIGlucHV0VHlwZSkgOiB0aGlzLmVtYmVkT3BlbkFJKGJhdGNoKSxcbiAgICAgICksXG4gICAgKTtcblxuICAgIG9uUHJvZ3Jlc3M/Lih0ZXh0cy5sZW5ndGgsIHRleHRzLmxlbmd0aCk7XG4gICAgcmV0dXJuIHJlc3VsdHMuZmxhdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIOuLqOydvCDthY3siqTtirgg7J6E67Kg65SpICjtjrjsnZgg66mU7ISc65OcKVxuICAgKi9cbiAgYXN5bmMgZW1iZWRPbmUoXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIHByb3ZpZGVyOiBFbWJlZGRpbmdQcm92aWRlcixcbiAgICBpbnB1dFR5cGU6IFZlY3RvcklucHV0VHlwZSA9IFwiZG9jdW1lbnRcIixcbiAgKTogUHJvbWlzZTxFbWJlZGRpbmdSZXN1bHQ+IHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5lbWJlZChbdGV4dF0sIHByb3ZpZGVyLCBpbnB1dFR5cGUpO1xuICAgIHJldHVybiByZXN1bHRzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFZveWFnZSBBSSDsnoTrsqDrlKlcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW1iZWRWb3lhZ2UoXG4gICAgdGV4dHM6IHN0cmluZ1tdLFxuICAgIGlucHV0VHlwZTogVmVjdG9ySW5wdXRUeXBlLFxuICApOiBQcm9taXNlPEVtYmVkZGluZ1Jlc3VsdFtdPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXRWb3lhZ2VDbGllbnQoKTtcbiAgICBjb25zdCB2b3lhZ2VDb25maWcgPSB0aGlzLmNvbmZpZy52b3lhZ2U7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5lbWJlZCh7XG4gICAgICBpbnB1dDogdGV4dHMsXG4gICAgICBtb2RlbDogdm95YWdlQ29uZmlnLm1vZGVsLFxuICAgICAgaW5wdXRUeXBlOiBpbnB1dFR5cGUsXG4gICAgfSk7XG4gICAgaWYgKCFyZXNwb25zZS5kYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJWb3lhZ2UgQVBJOiDsnZHri7Ug642w7J207YSw6rCAIOyXhuyKteuLiOuLpC5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEubWFwKChpdGVtKSA9PiAoe1xuICAgICAgZW1iZWRkaW5nOiBpdGVtLmVtYmVkZGluZyA/PyBbXSxcbiAgICAgIG1vZGVsOiB2b3lhZ2VDb25maWcubW9kZWwsXG4gICAgICB0b2tlbkNvdW50OiByZXNwb25zZS51c2FnZT8udG90YWxUb2tlbnMgPz8gMCxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbkFJIOyehOuyoOuUqVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbWJlZE9wZW5BSSh0ZXh0czogc3RyaW5nW10pOiBQcm9taXNlPEVtYmVkZGluZ1Jlc3VsdFtdPiB7XG4gICAgY29uc3Qgb3BlbmFpID0gdGhpcy5nZXRPcGVuQUlQcm92aWRlcigpO1xuICAgIGNvbnN0IG9wZW5haUNvbmZpZyA9IHRoaXMuY29uZmlnLm9wZW5haTtcbiAgICBjb25zdCBtb2RlbCA9IG9wZW5haS5lbWJlZGRpbmdNb2RlbChvcGVuYWlDb25maWcubW9kZWwpO1xuXG4gICAgY29uc3QgeyBlbWJlZGRpbmdzLCB1c2FnZSB9ID0gYXdhaXQgZW1iZWRNYW55KHtcbiAgICAgIG1vZGVsOiBtb2RlbCBhcyBFbWJlZGRpbmdNb2RlbCxcbiAgICAgIHZhbHVlczogdGV4dHMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZW1iZWRkaW5ncy5tYXAoKGVtYmVkZGluZykgPT4gKHtcbiAgICAgIGVtYmVkZGluZyxcbiAgICAgIG1vZGVsOiBvcGVuYWlDb25maWcubW9kZWwsXG4gICAgICB0b2tlbkNvdW50OiB1c2FnZT8udG9rZW5zID8/IDAsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOyehOuyoOuUqSBwcm92aWRlcuydmCDssKjsm5Ag7IiYIOuwmO2ZmFxuICAgKi9cbiAgZ2V0RGltZW5zaW9ucyhwcm92aWRlcjogRW1iZWRkaW5nUHJvdmlkZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBwcm92aWRlciA9PT0gXCJ2b3lhZ2VcIiA/IHRoaXMuY29uZmlnLnZveWFnZS5kaW1lbnNpb25zIDogdGhpcy5jb25maWcub3BlbmFpLmRpbWVuc2lvbnM7XG4gIH1cbn1cbmV4cG9ydCBjb25zdCBFbWJlZGRpbmcgPSBuZXcgRW1iZWRkaW5nQ2xhc3MoKTtcbiJdLCJuYW1lcyI6WyJjcmVhdGVPcGVuQUkiLCJlbWJlZE1hbnkiLCJWb3lhZ2VBSUNsaWVudCIsIlNvbmFtdSIsIkRFRkFVTFRfVkVDVE9SX0NPTkZJRyIsIkVtYmVkZGluZ0NsYXNzIiwiY29uZmlnIiwidm95YWdlIiwib3BlbmFpIiwiY2h1bmtpbmciLCJzZWFyY2giLCJwZ3ZlY3RvciIsImdldFZveWFnZUNsaWVudCIsImFwaUtleSIsInNlY3JldHMiLCJ2b3lhZ2VfYXBpX2tleSIsInByb2Nlc3MiLCJlbnYiLCJWT1lBR0VfQVBJX0tFWSIsIkVycm9yIiwiZ2V0T3BlbkFJUHJvdmlkZXIiLCJvcGVuYWlfYXBpX2tleSIsIk9QRU5BSV9BUElfS0VZIiwiZW1iZWQiLCJ0ZXh0cyIsInByb3ZpZGVyIiwiaW5wdXRUeXBlIiwib25Qcm9ncmVzcyIsIm1heEJhdGNoU2l6ZSIsImJhdGNoU2l6ZSIsImxlbmd0aCIsImVtYmVkVm95YWdlIiwiZW1iZWRPcGVuQUkiLCJiYXRjaGVzIiwiQXJyYXkiLCJmcm9tIiwiTWF0aCIsImNlaWwiLCJfIiwiaSIsInNsaWNlIiwicmVzdWx0cyIsIlByb21pc2UiLCJhbGwiLCJtYXAiLCJiYXRjaCIsImZsYXQiLCJlbWJlZE9uZSIsInRleHQiLCJjbGllbnQiLCJ2b3lhZ2VDb25maWciLCJyZXNwb25zZSIsImlucHV0IiwibW9kZWwiLCJkYXRhIiwiaXRlbSIsImVtYmVkZGluZyIsInRva2VuQ291bnQiLCJ1c2FnZSIsInRvdGFsVG9rZW5zIiwib3BlbmFpQ29uZmlnIiwiZW1iZWRkaW5nTW9kZWwiLCJlbWJlZGRpbmdzIiwidmFsdWVzIiwidG9rZW5zIiwiZ2V0RGltZW5zaW9ucyIsImRpbWVuc2lvbnMiLCJFbWJlZGRpbmciXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFlBQVksUUFBNkIsaUJBQWlCO0FBQ25FLFNBQThCQyxTQUFTLFFBQVEsS0FBSztBQUNwRCxTQUFTQyxjQUFjLFFBQVEsV0FBVztBQUMxQyxTQUFTQyxNQUFNLFFBQVEsbUJBQWdCO0FBQ3ZDLFNBQVNDLHFCQUFxQixRQUFRLGNBQVc7QUFTakQ7OztDQUdDLEdBQ0QsT0FBTyxNQUFNQztJQUNIQyxPQUFxQjtJQUU3QixZQUFZQSxTQUFnQyxDQUFDLENBQUMsQ0FBRTtRQUM5QyxJQUFJLENBQUNBLE1BQU0sR0FBRztZQUNaQyxRQUFRO2dCQUFFLEdBQUdILHNCQUFzQkcsTUFBTTtnQkFBRSxHQUFHRCxPQUFPQyxNQUFNO1lBQUM7WUFDNURDLFFBQVE7Z0JBQUUsR0FBR0osc0JBQXNCSSxNQUFNO2dCQUFFLEdBQUdGLE9BQU9FLE1BQU07WUFBQztZQUM1REMsVUFBVTtnQkFBRSxHQUFHTCxzQkFBc0JLLFFBQVE7Z0JBQUUsR0FBR0gsT0FBT0csUUFBUTtZQUFDO1lBQ2xFQyxRQUFRO2dCQUFFLEdBQUdOLHNCQUFzQk0sTUFBTTtnQkFBRSxHQUFHSixPQUFPSSxNQUFNO1lBQUM7WUFDNURDLFVBQVU7Z0JBQUUsR0FBR1Asc0JBQXNCTyxRQUFRO2dC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
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvZW1iZWRkaW5nLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgT3BlbkFJUHJvdmlkZXIgfSBmcm9tIFwiQGFpLXNkay9vcGVuYWlcIjtcbmltcG9ydCB7IHR5cGUgRW1iZWRkaW5nTW9kZWwsIGVtYmVkTWFueSB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHR5cGUgeyBWb3lhZ2VBSUNsaWVudCB9IGZyb20gXCJ2b3lhZ2VhaVwiO1xuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IERFRkFVTFRfVkVDVE9SX0NPTkZJRyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0IHR5cGUge1xuICBFbWJlZGRpbmdQcm92aWRlcixcbiAgRW1iZWRkaW5nUmVzdWx0LFxuICBQcm9ncmVzc0NhbGxiYWNrLFxuICBWZWN0b3JDb25maWcsXG4gIFZlY3RvcklucHV0VHlwZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiDsnoTrsqDrlKkg7YG065287J207Ja47Yq4XG4gKiBWb3lhZ2UgQUnsmYAgT3BlbkFJIOyehOuyoOuUqeydhCBTREsg67Cp7Iud7Jy866GcIO2Gte2VqSDsp4Dsm5BcbiAqL1xuZXhwb3J0IGNsYXNzIEVtYmVkZGluZ0NsYXNzIHtcbiAgcHJpdmF0ZSBjb25maWc6IFZlY3RvckNvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8VmVjdG9yQ29uZmlnPiA9IHt9KSB7XG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICB2b3lhZ2U6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnZveWFnZSwgLi4uY29uZmlnLnZveWFnZSB9LFxuICAgICAgb3BlbmFpOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5vcGVuYWksIC4uLmNvbmZpZy5vcGVuYWkgfSxcbiAgICAgIGNodW5raW5nOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5jaHVua2luZywgLi4uY29uZmlnLmNodW5raW5nIH0sXG4gICAgICBzZWFyY2g6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnNlYXJjaCwgLi4uY29uZmlnLnNlYXJjaCB9LFxuICAgICAgcGd2ZWN0b3I6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnBndmVjdG9yLCAuLi5jb25maWcucGd2ZWN0b3IgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZveWFnZSBBSSDtgbTrnbzsnbTslrjtirgg7LSI6riw7ZmUXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldFZveWFnZUNsaWVudCgpOiBQcm9taXNlPFZveWFnZUFJQ2xpZW50PiB7XG4gICAgY29uc3QgeyBWb3lhZ2VBSUNsaWVudCB9ID0gYXdhaXQgaW1wb3J0KFwidm95YWdlYWlcIik7XG4gICAgY29uc3QgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/LnZveWFnZV9hcGlfa2V5ID8/IHByb2Nlc3MuZW52LlZPWUFHRV9BUElfS0VZO1xuICAgIGlmICghYXBpS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJWT1lBR0VfQVBJX0tFWeqwgCDshKTsoJXrkJjsp4Ag7JWK7JWY7Iq164uI64ukLiDtmZjqsr3rs4DsiJjrpbwg7ZmV7J247ZWY7IS47JqULlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBWb3lhZ2VBSUNsaWVudCh7IGFwaUtleSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuQUkgcHJvdmlkZXIg7IOd7ISxXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldE9wZW5BSVByb3ZpZGVyKCk6IFByb21pc2U8T3BlbkFJUHJvdmlkZXI+IHtcbiAgICBjb25zdCB7IGNyZWF0ZU9wZW5BSSB9ID0gYXdhaXQgaW1wb3J0KFwiQGFpLXNkay9vcGVuYWlcIik7XG4gICAgY29uc3QgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/Lm9wZW5haV9hcGlfa2V5ID8/IHByb2Nlc3MuZW52Lk9QRU5BSV9BUElfS0VZO1xuICAgIGlmICghYXBpS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPUEVOQUlfQVBJX0tFWeqwgCDshKTsoJXrkJjsp4Ag7JWK7JWY7Iq164uI64ukLiDtmZjqsr3rs4DsiJjrpbwg7ZmV7J247ZWY7IS47JqULlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZU9wZW5BSSh7IGFwaUtleSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthY3siqTtirgg7J6E67Kg65SpIOyDneyEsVxuICAgKiBAcGFyYW0gdGV4dHMgLSDsnoTrsqDrlKntlaAg7YWN7Iqk7Yq4IOuwsOyXtCAoYmF0Y2hTaXpl7J207IOBIOyLnCDsnpDrj5kg67aE7ZWgKVxuICAgKiBAcGFyYW0gcHJvdmlkZXIgLSAndm95YWdlJyB8ICdvcGVuYWknXG4gICAqIEBwYXJhbSBpbnB1dFR5cGUgLSAnZG9jdW1lbnQnIHwgJ3F1ZXJ5JyAoVm95YWdlIEFJ66eMIO2VtOuLuSlcbiAgICogQHBhcmFtIG9uUHJvZ3Jlc3MgLSDsp4TtlonrpaAg7L2c67CxXG4gICAqL1xuICBhc3luYyBlbWJlZChcbiAgICB0ZXh0czogc3RyaW5nW10sXG4gICAgcHJvdmlkZXI6IEVtYmVkZGluZ1Byb3ZpZGVyLFxuICAgIGlucHV0VHlwZTogVmVjdG9ySW5wdXRUeXBlID0gXCJkb2N1bWVudFwiLFxuICAgIG9uUHJvZ3Jlc3M/OiBQcm9ncmVzc0NhbGxiYWNrLFxuICApOiBQcm9taXNlPEVtYmVkZGluZ1Jlc3VsdFtdPiB7XG4gICAgY29uc3QgbWF4QmF0Y2hTaXplID1cbiAgICAgIHByb3ZpZGVyID09PSBcInZveWFnZVwiID8gdGhpcy5jb25maWcudm95YWdlLmJhdGNoU2l6ZSA6IHRoaXMuY29uZmlnLm9wZW5haS5iYXRjaFNpemU7XG5cbiAgICAvLyBiYXRjaFNpemXsnbTtlZjrqbQg67CU66GcIO2YuOy2nFxuICAgIGlmICh0ZXh0cy5sZW5ndGggPD0gbWF4QmF0Y2hTaXplKSB7XG4gICAgICByZXR1cm4gcHJvdmlkZXIgPT09IFwidm95YWdlXCJcbiAgICAgICAgPyBhd2FpdCB0aGlzLmVtYmVkVm95YWdlKHRleHRzLCBpbnB1dFR5cGUpXG4gICAgICAgIDogYXdhaXQgdGhpcy5lbWJlZE9wZW5BSSh0ZXh0cyk7XG4gICAgfVxuXG4gICAgLy8gYmF0Y2hTaXpl7J207IOB7J2066m0IOyekOuPmeycvOuhnCDrgpjriKDshJwg7LKY66asXG4gICAgY29uc3QgYmF0Y2hlcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IE1hdGguY2VpbCh0ZXh0cy5sZW5ndGggLyBtYXhCYXRjaFNpemUpIH0sIChfLCBpKSA9PlxuICAgICAgdGV4dHMuc2xpY2UoaSAqIG1heEJhdGNoU2l6ZSwgKGkgKyAxKSAqIG1heEJhdGNoU2l6ZSksXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGJhdGNoZXMubWFwKChiYXRjaCkgPT5cbiAgICAgICAgcHJvdmlkZXIgPT09IFwidm95YWdlXCIgPyB0aGlzLmVtYmVkVm95YWdlKGJhdGNoLCBpbnB1dFR5cGUpIDogdGhpcy5lbWJlZE9wZW5BSShiYXRjaCksXG4gICAgICApLFxuICAgICk7XG5cbiAgICBvblByb2dyZXNzPy4odGV4dHMubGVuZ3RoLCB0ZXh0cy5sZW5ndGgpO1xuICAgIHJldHVybiByZXN1bHRzLmZsYXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDri6jsnbwg7YWN7Iqk7Yq4IOyehOuyoOuUqSAo7Y647J2YIOuplOyEnOuTnClcbiAgICovXG4gIGFzeW5jIGVtYmVkT25lKFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICBwcm92aWRlcjogRW1iZWRkaW5nUHJvdmlkZXIsXG4gICAgaW5wdXRUeXBlOiBWZWN0b3JJbnB1dFR5cGUgPSBcImRvY3VtZW50XCIsXG4gICk6IFByb21pc2U8RW1iZWRkaW5nUmVzdWx0PiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuZW1iZWQoW3RleHRdLCBwcm92aWRlciwgaW5wdXRUeXBlKTtcbiAgICByZXR1cm4gcmVzdWx0c1swXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWb3lhZ2UgQUkg7J6E67Kg65SpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVtYmVkVm95YWdlKFxuICAgIHRleHRzOiBzdHJpbmdbXSxcbiAgICBpbnB1dFR5cGU6IFZlY3RvcklucHV0VHlwZSxcbiAgKTogUHJvbWlzZTxFbWJlZGRpbmdSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Vm95YWdlQ2xpZW50KCk7XG4gICAgY29uc3Qgdm95YWdlQ29uZmlnID0gdGhpcy5jb25maWcudm95YWdlO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZW1iZWQoe1xuICAgICAgaW5wdXQ6IHRleHRzLFxuICAgICAgbW9kZWw6IHZveWFnZUNvbmZpZy5tb2RlbCxcbiAgICAgIGlucHV0VHlwZTogaW5wdXRUeXBlLFxuICAgIH0pO1xuICAgIGlmICghcmVzcG9uc2UuZGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVm95YWdlIEFQSTog7J2R64u1IOuNsOydtO2EsOqwgCDsl4bsirXri4jri6QuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5kYXRhLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgIGVtYmVkZGluZzogaXRlbS5lbWJlZGRpbmcgPz8gW10sXG4gICAgICBtb2RlbDogdm95YWdlQ29uZmlnLm1vZGVsLFxuICAgICAgdG9rZW5Db3VudDogcmVzcG9uc2UudXNhZ2U/LnRvdGFsVG9rZW5zID8/IDAsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5BSSDsnoTrsqDrlKlcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW1iZWRPcGVuQUkodGV4dHM6IHN0cmluZ1tdKTogUHJvbWlzZTxFbWJlZGRpbmdSZXN1bHRbXT4ge1xuICAgIGNvbnN0IG9wZW5haSA9IGF3YWl0IHRoaXMuZ2V0T3BlbkFJUHJvdmlkZXIoKTtcbiAgICBjb25zdCBvcGVuYWlDb25maWcgPSB0aGlzLmNvbmZpZy5vcGVuYWk7XG4gICAgY29uc3QgbW9kZWwgPSBvcGVuYWkuZW1iZWRkaW5nTW9kZWwob3BlbmFpQ29uZmlnLm1vZGVsKTtcblxuICAgIGNvbnN0IHsgZW1iZWRkaW5ncywgdXNhZ2UgfSA9IGF3YWl0IGVtYmVkTWFueSh7XG4gICAgICBtb2RlbDogbW9kZWwgYXMgRW1iZWRkaW5nTW9kZWwsXG4gICAgICB2YWx1ZXM6IHRleHRzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVtYmVkZGluZ3MubWFwKChlbWJlZGRpbmcpID0+ICh7XG4gICAgICBlbWJlZGRpbmcsXG4gICAgICBtb2RlbDogb3BlbmFpQ29uZmlnLm1vZGVsLFxuICAgICAgdG9rZW5Db3VudDogdXNhZ2U/LnRva2VucyA/PyAwLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsnoTrsqDrlKkgcHJvdmlkZXLsnZgg7LCo7JuQIOyImCDrsJjtmZhcbiAgICovXG4gIGdldERpbWVuc2lvbnMocHJvdmlkZXI6IEVtYmVkZGluZ1Byb3ZpZGVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcHJvdmlkZXIgPT09IFwidm95YWdlXCIgPyB0aGlzLmNvbmZpZy52b3lhZ2UuZGltZW5zaW9ucyA6IHRoaXMuY29uZmlnLm9wZW5haS5kaW1lbnNpb25zO1xuICB9XG59XG5leHBvcnQgY29uc3QgRW1iZWRkaW5nID0gbmV3IEVtYmVkZGluZ0NsYXNzKCk7XG4iXSwibmFtZXMiOlsiZW1iZWRNYW55IiwiU29uYW11IiwiREVGQVVMVF9WRUNUT1JfQ09ORklHIiwiRW1iZWRkaW5nQ2xhc3MiLCJjb25maWciLCJ2b3lhZ2UiLCJvcGVuYWkiLCJjaHVua2luZyIsInNlYXJjaCIsInBndmVjdG9yIiwiZ2V0Vm95YWdlQ2xpZW50IiwiVm95YWdlQUlDbGllbnQiLCJhcGlLZXkiLCJzZWNyZXRzIiwidm95YWdlX2FwaV9rZXkiLCJwcm9jZXNzIiwiZW52IiwiVk9ZQUdFX0FQSV9LRVkiLCJFcnJvciIsImdldE9wZW5BSVByb3ZpZGVyIiwiY3JlYXRlT3BlbkFJIiwib3BlbmFpX2FwaV9rZXkiLCJPUEVOQUlfQVBJX0tFWSIsImVtYmVkIiwidGV4dHMiLCJwcm92aWRlciIsImlucHV0VHlwZSIsIm9uUHJvZ3Jlc3MiLCJtYXhCYXRjaFNpemUiLCJiYXRjaFNpemUiLCJsZW5ndGgiLCJlbWJlZFZveWFnZSIsImVtYmVkT3BlbkFJIiwiYmF0Y2hlcyIsIkFycmF5IiwiZnJvbSIsIk1hdGgiLCJjZWlsIiwiXyIsImkiLCJzbGljZSIsInJlc3VsdHMiLCJQcm9taXNlIiwiYWxsIiwibWFwIiwiYmF0Y2giLCJmbGF0IiwiZW1iZWRPbmUiLCJ0ZXh0IiwiY2xpZW50Iiwidm95YWdlQ29uZmlnIiwicmVzcG9uc2UiLCJpbnB1dCIsIm1vZGVsIiwiZGF0YSIsIml0ZW0iLCJlbWJlZGRpbmciLCJ0b2tlbkNvdW50IiwidXNhZ2UiLCJ0b3RhbFRva2VucyIsIm9wZW5haUNvbmZpZyIsImVtYmVkZGluZ01vZGVsIiwiZW1iZWRkaW5ncyIsInZhbHVlcyIsInRva2VucyIsImdldERpbWVuc2lvbnMiLCJkaW1lbnNpb25zIiwiRW1iZWRkaW5nIl0sIm1hcHBpbmdzIjoiQUFDQSxTQUE4QkEsU0FBUyxRQUFRLEtBQUs7QUFFcEQsU0FBU0MsTUFBTSxRQUFRLG1CQUFnQjtBQUN2QyxTQUFTQyxxQkFBcUIsUUFBUSxjQUFXO0FBU2pEOzs7Q0FHQyxHQUNELE9BQU8sTUFBTUM7SUFDSEMsT0FBcUI7SUFFN0IsWUFBWUEsU0FBZ0MsQ0FBQyxDQUFDLENBQUU7UUFDOUMsSUFBSSxDQUFDQSxNQUFNLEdBQUc7WUFDWkMsUUFBUTtnQkFBRSxHQUFHSCxzQkFBc0JHLE1BQU07Z0JBQUUsR0FBR0QsT0FBT0MsTUFBTTtZQUFDO1lBQzVEQyxRQUFRO2dCQUFFLEdBQUdKLHNCQUFzQkksTUFBTTtnQkFBRSxHQUFHRixPQUFPRSxNQUFNO1lBQUM7WUFDNURDLFVBQVU7Z0JBQUUsR0FBR0wsc0JBQXNCSyxRQUFRO2dCQUFFLEdBQUdILE9BQU9HLFFBQVE7WUFBQztZQUNs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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonamu",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.13",
|
|
4
4
|
"description": "Sonamu — TypeScript Fullstack API Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"knex": "^3.1.0",
|
|
69
69
|
"mime-types": "^3.0.1",
|
|
70
70
|
"minimatch": "^10.0.3",
|
|
71
|
+
"node-cron": "^4.2.1",
|
|
71
72
|
"node-sql-parser": "^5.2.0",
|
|
72
73
|
"pg": "^8.16.3",
|
|
73
74
|
"prompts": "^2.4.2",
|
|
@@ -76,10 +77,9 @@
|
|
|
76
77
|
"tsicli": "^1.0.5",
|
|
77
78
|
"vitest": "^4.0.10",
|
|
78
79
|
"zod": "^4.1.12",
|
|
79
|
-
"node-cron": "^4.2.1",
|
|
80
80
|
"@sonamu-kit/hmr-hook": "^0.4.1",
|
|
81
|
-
"@sonamu-kit/ts-loader": "^2.1.3",
|
|
82
81
|
"@sonamu-kit/tasks": "^0.0.1",
|
|
82
|
+
"@sonamu-kit/ts-loader": "^2.1.3",
|
|
83
83
|
"@sonamu-kit/hmr-runner": "^0.1.1"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"ai": "6.0.0-beta.138",
|
|
105
105
|
"fastify": "^4.23.2",
|
|
106
106
|
"knex": "^3.1.0",
|
|
107
|
-
"typescript": "^5.9.3",
|
|
108
107
|
"pgvector": "^0.2.1",
|
|
108
|
+
"typescript": "^5.9.3",
|
|
109
109
|
"voyageai": "^0.0.8"
|
|
110
110
|
},
|
|
111
111
|
"peerDependenciesMeta": {
|
|
@@ -130,7 +130,9 @@
|
|
|
130
130
|
},
|
|
131
131
|
"scripts": {
|
|
132
132
|
"dev": "nodemon exec",
|
|
133
|
-
"build": "
|
|
133
|
+
"build": "run-s 'build:sonamu' 'build:ui-web'",
|
|
134
|
+
"build:sonamu": "rm -rf dist && swc src -d dist --strip-leading-paths && tsc --emitDeclarationOnly",
|
|
135
|
+
"build:ui-web": "cd ui-web && pnpm install && pnpm build",
|
|
134
136
|
"test:type": "vitest --typecheck test-d.ts"
|
|
135
137
|
}
|
|
136
138
|
}
|
package/src/api/config.ts
CHANGED
package/src/api/sonamu.ts
CHANGED
|
@@ -231,8 +231,6 @@ class SonamuClass {
|
|
|
231
231
|
await this.syncer.sync();
|
|
232
232
|
|
|
233
233
|
await this.startWatcher();
|
|
234
|
-
|
|
235
|
-
this.syncer.syncUI();
|
|
236
234
|
}
|
|
237
235
|
|
|
238
236
|
this.isInitialized = true;
|
|
@@ -346,10 +344,19 @@ class SonamuClass {
|
|
|
346
344
|
},
|
|
347
345
|
);
|
|
348
346
|
|
|
347
|
+
// Sonamu UI API
|
|
348
|
+
const { sonamuUIApiPlugin } = await import("../ui/api");
|
|
349
|
+
server.register(sonamuUIApiPlugin);
|
|
350
|
+
|
|
349
351
|
// API 라우팅 (로컬HMR 상태와 구분)
|
|
350
352
|
const { isLocal } = await import("../utils/controller");
|
|
351
353
|
if (isLocal()) {
|
|
352
354
|
server.all("*", async (request, reply) => {
|
|
355
|
+
// Sonamu UI
|
|
356
|
+
if (request.url.startsWith("/sonamu-ui")) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
353
360
|
const found = this.syncer.apis.find(
|
|
354
361
|
(api) =>
|
|
355
362
|
this.config.api.route.prefix + api.path === request.url.split("?")[0] &&
|
|
@@ -358,8 +365,14 @@ class SonamuClass {
|
|
|
358
365
|
if (found) {
|
|
359
366
|
return this.getApiHandler(found, config)(request, reply);
|
|
360
367
|
}
|
|
361
|
-
|
|
362
|
-
|
|
368
|
+
|
|
369
|
+
if (request.url.startsWith("/api/")) {
|
|
370
|
+
const { NotFoundException } = await import("../exceptions/so-exceptions");
|
|
371
|
+
throw new NotFoundException(`존재하지 않는 API 접근입니다. ${request.url}`);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// 일반 파일 접근시 별도의 에러 출력하지 않음
|
|
375
|
+
return;
|
|
363
376
|
});
|
|
364
377
|
} else {
|
|
365
378
|
for (const api of this.syncer.apis) {
|
package/src/bin/cli.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { BUILD_DIR, SWC_BUILD_COMMAND, TSC_TYPE_CHECK_COMMAND } from "./build-co
|
|
|
22
22
|
let migrator: Migrator;
|
|
23
23
|
|
|
24
24
|
async function bootstrap() {
|
|
25
|
-
const notToInit = ["dev", "build", "start"
|
|
25
|
+
const notToInit = ["dev", "build", "start"].includes(process.argv[2] ?? "");
|
|
26
26
|
if (!notToInit) {
|
|
27
27
|
await Sonamu.init(false, false);
|
|
28
28
|
}
|
|
@@ -58,7 +58,6 @@ async function bootstrap() {
|
|
|
58
58
|
["scaffold", "model_test", "#entityId"],
|
|
59
59
|
["scaffold", "view_list", "#entityId"],
|
|
60
60
|
["scaffold", "view_form", "#entityId"],
|
|
61
|
-
["ui"],
|
|
62
61
|
["sync"],
|
|
63
62
|
["dev"],
|
|
64
63
|
["build"],
|
|
@@ -74,7 +73,6 @@ async function bootstrap() {
|
|
|
74
73
|
stub_entity,
|
|
75
74
|
scaffold_model,
|
|
76
75
|
scaffold_model_test,
|
|
77
|
-
ui,
|
|
78
76
|
// scaffold_view_list,
|
|
79
77
|
// scaffold_view_form,
|
|
80
78
|
sync,
|
|
@@ -452,67 +450,3 @@ async function scaffold_model_test(entityId: string) {
|
|
|
452
450
|
entityId,
|
|
453
451
|
});
|
|
454
452
|
}
|
|
455
|
-
|
|
456
|
-
async function ui() {
|
|
457
|
-
try {
|
|
458
|
-
const apiRootPath = findApiRootPath();
|
|
459
|
-
|
|
460
|
-
// 사용자 프로젝트의 패키지들 중에서 @sonamu-kit/ui를 찾습니다.
|
|
461
|
-
// 이를 위해서 createRequire를 사용하여 프로젝트 경로 기준으로 resolve합니다.
|
|
462
|
-
const projectRequire = createRequire(path.join(apiRootPath, "package.json"));
|
|
463
|
-
const uiPackagePath = projectRequire.resolve("@sonamu-kit/ui"); // 없으면 여기서 터져요(MODULE_NOT_FOUND)
|
|
464
|
-
const uiNodePath = path.join(path.dirname(uiPackagePath), "run-ui.js");
|
|
465
|
-
|
|
466
|
-
if (!(await exists(uiNodePath))) {
|
|
467
|
-
console.log(
|
|
468
|
-
chalk.red(`UI runner script not found at ${uiNodePath}. Please rebuild @sonamu-kit/ui.`),
|
|
469
|
-
);
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// UI를 별도 프로세스로 실행 (hmr-hook 활성화)
|
|
474
|
-
const uiProcess = spawn(
|
|
475
|
-
process.execPath,
|
|
476
|
-
[
|
|
477
|
-
"--import",
|
|
478
|
-
"sonamu/ts-loader-register",
|
|
479
|
-
"--import",
|
|
480
|
-
"sonamu/hmr-hook-register",
|
|
481
|
-
"--enable-source-maps",
|
|
482
|
-
"--no-warnings",
|
|
483
|
-
uiNodePath,
|
|
484
|
-
],
|
|
485
|
-
{
|
|
486
|
-
stdio: "inherit",
|
|
487
|
-
env: {
|
|
488
|
-
...process.env,
|
|
489
|
-
HOT: "yes",
|
|
490
|
-
API_ROOT_PATH: apiRootPath, // UI는 얘만 알면 돼요! 나머지는 얘가 떠서 알아서 할 것임 ㅎ
|
|
491
|
-
},
|
|
492
|
-
},
|
|
493
|
-
);
|
|
494
|
-
|
|
495
|
-
// 종료 처리
|
|
496
|
-
const cleanup = () => {
|
|
497
|
-
console.log(chalk.yellow("\n\n👋 Shutting down UI server..."));
|
|
498
|
-
uiProcess.kill("SIGTERM");
|
|
499
|
-
process.exit(0);
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
process.on("SIGINT", cleanup);
|
|
503
|
-
process.on("SIGTERM", cleanup);
|
|
504
|
-
|
|
505
|
-
uiProcess.on("exit", (code) => {
|
|
506
|
-
if (code !== 0) {
|
|
507
|
-
console.error(chalk.red(`❌ UI server exited with code ${code}`));
|
|
508
|
-
process.exit(code || 1);
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
} catch (e: unknown) {
|
|
512
|
-
if (e instanceof Error && e.message.includes("isn't declared")) {
|
|
513
|
-
console.log(`You need to install ${chalk.blue(`@sonamu-kit/ui`)} first.`);
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
|
-
throw e;
|
|
517
|
-
}
|
|
518
|
-
}
|
package/src/syncer/api-parser.ts
CHANGED
|
@@ -98,7 +98,8 @@ export async function readApisFromFile(filePath: AbsolutePath): Promise<Extended
|
|
|
98
98
|
// const p = path.join(tmpdir(), "sonamu-syncer-error.json");
|
|
99
99
|
// writeFileSync(p, JSON.stringify(registeredApis, null, 2));
|
|
100
100
|
// execSync(`open ${p}`);
|
|
101
|
-
throw new Error(`현재 파일에 사전 등록된 API가 없습니다. ${filePath}`);
|
|
101
|
+
// throw new Error(`현재 파일에 사전 등록된 API가 없습니다. ${filePath}`);
|
|
102
|
+
return [];
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
// 등록된 API에 현재 메소드 타입 정보 확장
|
package/src/syncer/syncer.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hot } from "@sonamu-kit/hmr-hook";
|
|
2
2
|
import assert from "assert";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { EventEmitter } from "events";
|
|
4
5
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
5
6
|
import inflection from "inflection";
|
|
6
7
|
import { minimatch } from "minimatch";
|
|
@@ -45,6 +46,7 @@ export class Syncer {
|
|
|
45
46
|
models: LoadedModels = {};
|
|
46
47
|
workflows: Map<string, WorkflowMetadata[]> = new Map();
|
|
47
48
|
isSyncing: boolean = false;
|
|
49
|
+
eventEmitter: EventEmitter = new EventEmitter();
|
|
48
50
|
|
|
49
51
|
/**
|
|
50
52
|
* 체크섬이 변경된 부분에 대해 싱크를 진행합니다.
|
|
@@ -100,17 +102,24 @@ export class Syncer {
|
|
|
100
102
|
console.log(chalk.bold(`🔄 Invalidated:`));
|
|
101
103
|
|
|
102
104
|
for (const invalidatedPath of invalidatedPaths) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
try {
|
|
106
|
+
// 만약 model.ts 파일이 변경(invalidate)되었다? 그러면 registeredApis 중에서 이 모델에 해당하는 api들은 지워줘요.
|
|
107
|
+
// registeredApis는 통으로 다 날려버릴 수 없습니다. registeredApis에 올라오는 친구들은 초기 로드시 또는 HMR시에만 등록되기 때문입니다.
|
|
108
|
+
// 따라서 model.ts 파일의 변경으로 다음번 새로운 eval이 예상되는 이 시점에서만, 이 모델에서 나온 registeredApis들을 지워줄 수 있습니다.
|
|
109
|
+
const removedApis = this.removeInvalidatedRegisteredApis(invalidatedPath);
|
|
110
|
+
if (removedApis.length > 0) {
|
|
111
|
+
console.log(
|
|
112
|
+
chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`),
|
|
113
|
+
chalk.gray(`(with ${removedApis.length} APIs)`),
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
console.log(chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`));
|
|
117
|
+
}
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error(e);
|
|
120
|
+
console.error(
|
|
121
|
+
chalk.red(`Failed to remove invalidated registered APIs for ${invalidatedPath}`),
|
|
111
122
|
);
|
|
112
|
-
} else {
|
|
113
|
-
console.log(chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`));
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
125
|
}
|
|
@@ -132,7 +141,7 @@ export class Syncer {
|
|
|
132
141
|
await this.autoloadApis();
|
|
133
142
|
await this.autoloadWorkflows();
|
|
134
143
|
|
|
135
|
-
this.
|
|
144
|
+
this.eventEmitter.emit("onHMRCompleted");
|
|
136
145
|
}
|
|
137
146
|
|
|
138
147
|
removeInvalidatedRegisteredApis(
|
|
@@ -551,16 +560,6 @@ export class Syncer {
|
|
|
551
560
|
);
|
|
552
561
|
}
|
|
553
562
|
|
|
554
|
-
syncUI() {
|
|
555
|
-
const uiPort = Sonamu.config.ui?.port ?? 57000;
|
|
556
|
-
|
|
557
|
-
if (!isTest()) {
|
|
558
|
-
fetch(`http://127.0.0.1:${uiPort}/api/reload`, {
|
|
559
|
-
method: "GET",
|
|
560
|
-
}).catch((e) => console.log(chalk.dim(`Failed to reload Sonamu UI: ${e.message}`)));
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
|
|
564
563
|
/**
|
|
565
564
|
* 하위호환용 프록시 메소드입니다.
|
|
566
565
|
*/
|
package/src/ui/ai-api.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// import { convertToModelMessages, type UIMessage } from "ai";
|
|
2
|
+
// import type { FastifyInstance } from "fastify";
|
|
3
|
+
// import { BadRequestException, type FixtureRecord } from "sonamu";
|
|
4
|
+
// import { aiClient } from "./ai-client";
|
|
5
|
+
|
|
6
|
+
// export async function setAiApi(server: FastifyInstance) {
|
|
7
|
+
// await aiClient.init();
|
|
8
|
+
|
|
9
|
+
// server.post("/api/ai/fixture/chat", async (request, reply) => {
|
|
10
|
+
// const { messages, fixtureRecords } = request.body as {
|
|
11
|
+
// messages: UIMessage[];
|
|
12
|
+
// fixtureRecords?: FixtureRecord[];
|
|
13
|
+
// };
|
|
14
|
+
|
|
15
|
+
// if (!fixtureRecords || fixtureRecords.length === 0) {
|
|
16
|
+
// throw new BadRequestException("픽스쳐 레코드가 없습니다. 픽스쳐 조회 후 시도하세요.");
|
|
17
|
+
// }
|
|
18
|
+
|
|
19
|
+
// const result = aiClient.handleFixture(convertToModelMessages(messages), fixtureRecords);
|
|
20
|
+
// const response = result.toUIMessageStreamResponse();
|
|
21
|
+
|
|
22
|
+
// reply.raw.writeHead(response.status, Object.fromEntries(response.headers.entries()));
|
|
23
|
+
|
|
24
|
+
// if (response.body) {
|
|
25
|
+
// const reader = response.body.getReader();
|
|
26
|
+
// while (true) {
|
|
27
|
+
// const { done, value } = await reader.read();
|
|
28
|
+
// if (done) break;
|
|
29
|
+
// reply.raw.write(value);
|
|
30
|
+
// }
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
// reply.raw.end();
|
|
34
|
+
// return reply;
|
|
35
|
+
// });
|
|
36
|
+
|
|
37
|
+
// // Entity/Enum 생성용 AI Chat Stream
|
|
38
|
+
// server.post("/api/ai/entity/chat", async (request, reply) => {
|
|
39
|
+
// const { messages } = request.body as {
|
|
40
|
+
// messages: UIMessage[];
|
|
41
|
+
// };
|
|
42
|
+
|
|
43
|
+
// const result = aiClient.handleEntity(convertToModelMessages(messages));
|
|
44
|
+
// const response = result.toUIMessageStreamResponse();
|
|
45
|
+
|
|
46
|
+
// reply.raw.writeHead(response.status, Object.fromEntries(response.headers.entries()));
|
|
47
|
+
|
|
48
|
+
// if (response.body) {
|
|
49
|
+
// const reader = response.body.getReader();
|
|
50
|
+
// while (true) {
|
|
51
|
+
// const { done, value } = await reader.read();
|
|
52
|
+
// if (done) break;
|
|
53
|
+
// reply.raw.write(value);
|
|
54
|
+
// }
|
|
55
|
+
// }
|
|
56
|
+
|
|
57
|
+
// reply.raw.end();
|
|
58
|
+
// return reply;
|
|
59
|
+
// });
|
|
60
|
+
// }
|