sonamu 0.9.19 → 0.10.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/_virtual/_rolldown/runtime.js +36 -0
- package/dist/ai/agents/agent.js +5 -7
- package/dist/ai/agents/index.js +1 -2
- package/dist/ai/agents/types.js +1 -1
- package/dist/ai/index.js +1 -2
- package/dist/ai/providers/rtzr/api.js +2 -3
- package/dist/ai/providers/rtzr/error.js +14 -29
- package/dist/ai/providers/rtzr/index.js +1 -2
- package/dist/ai/providers/rtzr/model.js +13 -20
- package/dist/ai/providers/rtzr/options.js +2 -3
- package/dist/ai/providers/rtzr/provider.js +2 -3
- package/dist/ai/providers/rtzr/utils.js +12 -21
- package/dist/api/base-frame.js +4 -4
- package/dist/api/caster.js +21 -38
- package/dist/api/code-converters.js +41 -98
- package/dist/api/config.d.ts +1 -10
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +9 -8
- package/dist/api/context.js +2 -3
- package/dist/api/decorators.js +80 -116
- package/dist/api/index.js +2 -3
- package/dist/api/secret.js +6 -10
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +200 -387
- package/dist/api/validator.js +5 -8
- package/dist/api/websocket-helpers.js +21 -32
- package/dist/auth/audit-log/builders.js +2 -3
- package/dist/auth/audit-log/events.js +2 -2
- package/dist/auth/audit-log/plugin.js +30 -61
- package/dist/auth/audit-log-ingestor.js +19 -41
- package/dist/auth/auth-generator.js +16 -41
- package/dist/auth/better-auth-entities.js +3 -4
- package/dist/auth/index.js +2 -3
- package/dist/auth/knex-adapter.js +18 -45
- package/dist/auth/plugins/entity-definitions/admin.js +2 -2
- package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
- package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
- package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
- package/dist/auth/plugins/entity-definitions/index.js +2 -3
- package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
- package/dist/auth/plugins/entity-definitions/organization.js +2 -2
- package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
- package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
- package/dist/auth/plugins/entity-definitions/sso.js +2 -2
- package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
- package/dist/auth/plugins/entity-definitions/types.js +1 -1
- package/dist/auth/plugins/entity-definitions/username.js +2 -2
- package/dist/auth/plugins/index.js +1 -2
- package/dist/auth/plugins/wrappers/admin.js +2 -3
- package/dist/auth/plugins/wrappers/anonymous.js +2 -3
- package/dist/auth/plugins/wrappers/api-key.js +2 -3
- package/dist/auth/plugins/wrappers/index.js +1 -2
- package/dist/auth/plugins/wrappers/jwt.js +2 -3
- package/dist/auth/plugins/wrappers/organization.js +2 -3
- package/dist/auth/plugins/wrappers/passkey.js +2 -3
- package/dist/auth/plugins/wrappers/phone-number.js +2 -3
- package/dist/auth/plugins/wrappers/sso.js +2 -3
- package/dist/auth/plugins/wrappers/two-factor.js +2 -3
- package/dist/auth/plugins/wrappers/username.js +2 -3
- package/dist/bin/build-config.js +2 -2
- package/dist/bin/cli.js +151 -258
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +55 -97
- package/dist/bin/hmr-hook-register.js +3 -3
- package/dist/bin/migrate-targets.d.ts +3 -0
- package/dist/bin/migrate-targets.d.ts.map +1 -0
- package/dist/bin/migrate-targets.js +11 -0
- package/dist/bin/test-command.js +25 -55
- package/dist/bin/ts-loader-register.js +5 -6
- package/dist/bin/ts-loader-registration.js +6 -13
- package/dist/cache/cache-manager.js +3 -4
- package/dist/cache/decorator.js +11 -21
- package/dist/cache/drivers.js +2 -3
- package/dist/cache/index.js +2 -3
- package/dist/cache/types.js +1 -1
- package/dist/cache-control/cache-control.js +21 -34
- package/dist/cache-control/types.js +1 -1
- package/dist/compress/compress.js +10 -10
- package/dist/compress/index.js +1 -2
- package/dist/compress/types.js +1 -1
- package/dist/cone/cone-generator.js +25 -63
- package/dist/database/_batch_update.js +26 -46
- package/dist/database/base-model.js +44 -97
- package/dist/database/base-model.types.js +1 -1
- package/dist/database/db.d.ts +8 -14
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +127 -72
- package/dist/database/knex.js +5 -8
- package/dist/database/puri-subset.types.js +1 -1
- package/dist/database/puri-wrapper.js +11 -15
- package/dist/database/puri.js +117 -234
- package/dist/database/puri.types.js +3 -4
- package/dist/database/transaction-context.js +4 -5
- package/dist/database/upsert-builder.js +109 -176
- package/dist/dict/en.d.ts +1 -0
- package/dist/dict/en.d.ts.map +1 -1
- package/dist/dict/en.js +4 -4
- package/dist/dict/index.js +2 -3
- package/dist/dict/ko.d.ts +1 -0
- package/dist/dict/ko.d.ts.map +1 -1
- package/dist/dict/ko.js +4 -4
- package/dist/dict/rc-keys.js +3 -4
- package/dist/dict/sd.js +8 -19
- package/dist/dict/sonamu-dictionary.js +141 -284
- package/dist/dict/types.js +1 -1
- package/dist/dict/utils.js +4 -5
- package/dist/entity/entity-manager.d.ts +2 -2
- package/dist/entity/entity-manager.js +34 -82
- package/dist/entity/entity-template-cone.js +33 -66
- package/dist/entity/entity.js +156 -310
- package/dist/env.d.ts +14 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +75 -0
- package/dist/exceptions/error-handler.js +2 -3
- package/dist/exceptions/so-exceptions.js +7 -5
- package/dist/filter/index.js +1 -2
- package/dist/filter/types.js +3 -4
- package/dist/filter/utils.js +21 -54
- package/dist/index.js +8 -7
- package/dist/logger/category.js +6 -12
- package/dist/logger/configure.js +23 -34
- package/dist/migration/code-generation.js +146 -314
- package/dist/migration/index-where-predicate.js +52 -144
- package/dist/migration/migration-set.js +19 -33
- package/dist/migration/migrator.d.ts +2 -0
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +69 -53
- package/dist/migration/postgresql-schema-reader.js +126 -225
- package/dist/migration/slack-confirm.d.ts +1 -0
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +28 -38
- package/dist/migration/types.js +1 -1
- package/dist/naite/messaging-types.js +1 -1
- package/dist/naite/naite-reporter.js +15 -32
- package/dist/naite/naite.js +43 -76
- package/dist/ssr/index.js +6 -9
- package/dist/ssr/registry.js +10 -18
- package/dist/ssr/renderer.js +10 -21
- package/dist/ssr/types.js +1 -1
- package/dist/storage/base-file.js +5 -10
- package/dist/storage/buffered-file.js +3 -4
- package/dist/storage/drivers.js +2 -3
- package/dist/storage/index.js +2 -3
- package/dist/storage/s3-driver.js +5 -9
- package/dist/storage/storage-manager.js +5 -5
- package/dist/storage/types.js +1 -1
- package/dist/storage/uploaded-file.js +4 -6
- package/dist/stream/index.js +1 -2
- package/dist/stream/sse.js +8 -13
- package/dist/stream/ws-audience-resolver.js +5 -5
- package/dist/stream/ws-audience.js +3 -4
- package/dist/stream/ws-cluster-bus.js +3 -4
- package/dist/stream/ws-core.js +1 -1
- package/dist/stream/ws-delivery.js +11 -25
- package/dist/stream/ws-local-connection-store.js +9 -18
- package/dist/stream/ws-presence-store.js +43 -97
- package/dist/stream/ws-registry.js +17 -22
- package/dist/stream/ws-telemetry-memory.js +38 -45
- package/dist/stream/ws-telemetry-trace.js +4 -6
- package/dist/stream/ws-telemetry.js +82 -135
- package/dist/stream/ws.js +47 -91
- package/dist/syncer/api-parser.js +81 -147
- package/dist/syncer/checksum.js +9 -20
- package/dist/syncer/code-generator.js +29 -47
- package/dist/syncer/entity-operations.js +17 -27
- package/dist/syncer/event-batcher.js +8 -15
- package/dist/syncer/file-patterns.js +3 -4
- package/dist/syncer/file-tracking.js +6 -10
- package/dist/syncer/index.js +1 -2
- package/dist/syncer/module-loader.js +10 -26
- package/dist/syncer/syncer-actions.js +19 -37
- package/dist/syncer/syncer.js +46 -98
- package/dist/syncer/watcher.js +12 -26
- package/dist/tasks/decorator.js +7 -11
- package/dist/tasks/step-wrapper.js +7 -8
- package/dist/tasks/workflow-manager.js +18 -25
- package/dist/template/entity-converter.js +40 -64
- package/dist/template/helpers.js +32 -63
- package/dist/template/implementations/entity.template.js +7 -11
- package/dist/template/implementations/entry-server.template.js +2 -3
- package/dist/template/implementations/generated.template.js +25 -51
- package/dist/template/implementations/generated_http.template.js +31 -58
- package/dist/template/implementations/generated_sso.template.js +45 -85
- package/dist/template/implementations/init_types.template.js +4 -7
- package/dist/template/implementations/model.template.js +5 -10
- package/dist/template/implementations/model_test.template.js +2 -3
- package/dist/template/implementations/queries.template.js +4 -7
- package/dist/template/implementations/sd.template.js +17 -35
- package/dist/template/implementations/services.template.js +18 -30
- package/dist/template/implementations/view_form.template.js +72 -125
- package/dist/template/implementations/view_id_all_select.template.js +2 -3
- package/dist/template/implementations/view_list.template.js +86 -143
- package/dist/template/implementations/view_search_input.template.js +2 -3
- package/dist/template/index.js +5 -8
- package/dist/template/template-manager.js +13 -26
- package/dist/template/template-types.js +2 -3
- package/dist/template/template.js +7 -11
- package/dist/template/zod-converter.js +173 -348
- package/dist/testing/_relation-graph.js +18 -37
- package/dist/testing/bootstrap.js +5 -8
- package/dist/testing/data-explorer.js +34 -78
- package/dist/testing/dev-test-routes.js +54 -60
- package/dist/testing/dev-vitest-manager.js +33 -84
- package/dist/testing/faker-mappings.js +3 -4
- package/dist/testing/fixture-generator.d.ts +2 -1
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +159 -321
- package/dist/testing/fixture-loader.js +2 -2
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +124 -227
- package/dist/testing/global-setup.d.ts.map +1 -1
- package/dist/testing/global-setup.js +29 -17
- package/dist/testing/index.js +1 -2
- package/dist/testing/naite-vitest-reporter.js +2 -3
- package/dist/testing/parallel-db-manager.js +5 -3
- package/dist/testing/vitest-helpers.d.ts.map +1 -1
- package/dist/testing/vitest-helpers.js +15 -12
- package/dist/types/types.d.ts +14 -14
- package/dist/types/types.js +27 -50
- package/dist/ui/ai-api.js +6 -11
- package/dist/ui/ai-client.js +86 -134
- package/dist/ui/api.js +99 -195
- package/dist/ui/cdd-service.js +78 -130
- package/dist/ui/cdd-types.js +1 -1
- package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
- package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/dist/utils/async-utils.js +13 -25
- package/dist/utils/class-name.js +3 -4
- package/dist/utils/console-util.js +11 -26
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +14 -12
- package/dist/utils/esm-utils.js +5 -8
- package/dist/utils/formatter.js +10 -22
- package/dist/utils/fs-utils.js +14 -25
- package/dist/utils/lodash-able.js +3 -4
- package/dist/utils/model.js +7 -14
- package/dist/utils/object-utils.js +41 -73
- package/dist/utils/path-utils.js +5 -9
- package/dist/utils/process-utils.js +4 -7
- package/dist/utils/sql-parser.js +6 -13
- package/dist/utils/type-utils.js +16 -26
- package/dist/utils/utils.js +18 -40
- package/dist/utils/zod-error.js +9 -16
- package/dist/vector/chunking.js +24 -37
- package/dist/vector/config.js +2 -2
- package/dist/vector/embedding.js +8 -19
- package/dist/vector/index.js +1 -2
- package/dist/vector/types.js +1 -1
- package/package.json +7 -7
- package/src/__tests__/env.test.ts +127 -0
- package/src/api/__tests__/config.test.ts +10 -1
- package/src/api/config.ts +4 -12
- package/src/api/sonamu.ts +14 -4
- package/src/bin/__tests__/migrate-targets.test.ts +28 -0
- package/src/bin/__tests__/test-command.test.ts +82 -1
- package/src/bin/cli.ts +9 -18
- package/src/bin/fixture.ts +5 -4
- package/src/bin/migrate-targets.ts +7 -0
- package/src/bin/test-command.ts +2 -2
- package/src/database/__tests__/db.test.ts +175 -0
- package/src/database/db.ts +193 -71
- package/src/dict/en.ts +2 -0
- package/src/dict/ko.ts +2 -0
- package/src/env.ts +123 -0
- package/src/migration/__tests__/migrator.test.ts +149 -0
- package/src/migration/migrator.ts +74 -17
- package/src/migration/slack-confirm.ts +21 -0
- package/src/skills/sonamu/database.md +1 -1
- package/src/skills/sonamu/entity-basic.md +31 -0
- package/src/skills/sonamu/puri.md +22 -0
- package/src/skills/sonamu/testing-devrunner.md +1 -1
- package/src/skills/sonamu/upsert.md +53 -6
- package/src/stream/ws-telemetry-memory.ts +2 -2
- package/src/testing/fixture-generator.ts +2 -1
- package/src/testing/fixture-manager.ts +3 -4
- package/src/testing/global-setup.ts +42 -18
- package/src/testing/vitest-helpers.ts +14 -0
- package/src/utils/controller.ts +14 -7
- package/tsdown.api.config.ts +6 -0
- package/dist/_virtual/rolldown_runtime.js +0 -39
- package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
package/dist/vector/embedding.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
2
2
|
import { DEFAULT_VECTOR_CONFIG } from "./config.js";
|
|
3
3
|
import { embedMany } from "ai";
|
|
4
|
-
|
|
5
4
|
//#region src/vector/embedding.ts
|
|
6
5
|
init_sonamu();
|
|
7
6
|
/**
|
|
@@ -40,9 +39,7 @@ var EmbeddingClass = class {
|
|
|
40
39
|
async getVoyageClient() {
|
|
41
40
|
const { VoyageAIClient } = await import("voyageai");
|
|
42
41
|
const apiKey = Sonamu.secrets?.voyage_api_key ?? process.env.VOYAGE_API_KEY;
|
|
43
|
-
if (!apiKey)
|
|
44
|
-
throw new Error("VOYAGE_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
|
|
45
|
-
}
|
|
42
|
+
if (!apiKey) throw new Error("VOYAGE_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
|
|
46
43
|
return new VoyageAIClient({ apiKey });
|
|
47
44
|
}
|
|
48
45
|
/**
|
|
@@ -51,9 +48,7 @@ var EmbeddingClass = class {
|
|
|
51
48
|
async getOpenAIProvider() {
|
|
52
49
|
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
53
50
|
const apiKey = Sonamu.secrets?.openai_api_key ?? process.env.OPENAI_API_KEY;
|
|
54
|
-
if (!apiKey)
|
|
55
|
-
throw new Error("OPENAI_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
|
|
56
|
-
}
|
|
51
|
+
if (!apiKey) throw new Error("OPENAI_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
|
|
57
52
|
return createOpenAI({ apiKey });
|
|
58
53
|
}
|
|
59
54
|
/**
|
|
@@ -65,9 +60,7 @@ var EmbeddingClass = class {
|
|
|
65
60
|
*/
|
|
66
61
|
async embed(texts, provider, inputType = "document", onProgress) {
|
|
67
62
|
const maxBatchSize = provider === "voyage" ? this.config.voyage.batchSize : this.config.openai.batchSize;
|
|
68
|
-
if (texts.length <= maxBatchSize)
|
|
69
|
-
return provider === "voyage" ? await this.embedVoyage(texts, inputType) : await this.embedOpenAI(texts);
|
|
70
|
-
}
|
|
63
|
+
if (texts.length <= maxBatchSize) return provider === "voyage" ? await this.embedVoyage(texts, inputType) : await this.embedOpenAI(texts);
|
|
71
64
|
const batches = Array.from({ length: Math.ceil(texts.length / maxBatchSize) }, (_, i) => texts.slice(i * maxBatchSize, (i + 1) * maxBatchSize));
|
|
72
65
|
const results = await Promise.all(batches.map((batch) => provider === "voyage" ? this.embedVoyage(batch, inputType) : this.embedOpenAI(batch)));
|
|
73
66
|
onProgress?.(texts.length, texts.length);
|
|
@@ -77,8 +70,7 @@ var EmbeddingClass = class {
|
|
|
77
70
|
* 단일 텍스트 임베딩 (편의 메서드)
|
|
78
71
|
*/
|
|
79
72
|
async embedOne(text, provider, inputType = "document") {
|
|
80
|
-
|
|
81
|
-
return results[0];
|
|
73
|
+
return (await this.embed([text], provider, inputType))[0];
|
|
82
74
|
}
|
|
83
75
|
/**
|
|
84
76
|
* Voyage AI 임베딩
|
|
@@ -91,9 +83,7 @@ var EmbeddingClass = class {
|
|
|
91
83
|
model: voyageConfig.model,
|
|
92
84
|
inputType
|
|
93
85
|
});
|
|
94
|
-
if (!response.data)
|
|
95
|
-
throw new Error("Voyage API: 응답 데이터가 없습니다.");
|
|
96
|
-
}
|
|
86
|
+
if (!response.data) throw new Error("Voyage API: 응답 데이터가 없습니다.");
|
|
97
87
|
return response.data.map((item) => ({
|
|
98
88
|
embedding: item.embedding ?? [],
|
|
99
89
|
model: voyageConfig.model,
|
|
@@ -106,9 +96,8 @@ var EmbeddingClass = class {
|
|
|
106
96
|
async embedOpenAI(texts) {
|
|
107
97
|
const openai = await this.getOpenAIProvider();
|
|
108
98
|
const openaiConfig = this.config.openai;
|
|
109
|
-
const model = openai.embeddingModel(openaiConfig.model);
|
|
110
99
|
const { embeddings, usage } = await embedMany({
|
|
111
|
-
model,
|
|
100
|
+
model: openai.embeddingModel(openaiConfig.model),
|
|
112
101
|
values: texts
|
|
113
102
|
});
|
|
114
103
|
return embeddings.map((embedding) => ({
|
|
@@ -125,7 +114,7 @@ var EmbeddingClass = class {
|
|
|
125
114
|
}
|
|
126
115
|
};
|
|
127
116
|
const Embedding = new EmbeddingClass();
|
|
128
|
-
|
|
129
117
|
//#endregion
|
|
130
118
|
export { Embedding };
|
|
131
|
-
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1iZWRkaW5nLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvZW1iZWRkaW5nLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHR5cGUgT3BlbkFJUHJvdmlkZXIgfSBmcm9tIFwiQGFpLXNkay9vcGVuYWlcIjtcbmltcG9ydCB7IGVtYmVkTWFueSB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHsgdHlwZSBFbWJlZGRpbmdNb2RlbCB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHsgdHlwZSBWb3lhZ2VBSUNsaWVudCB9IGZyb20gXCJ2b3lhZ2VhaVwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgREVGQVVMVF9WRUNUT1JfQ09ORklHIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQge1xuICB0eXBlIEVtYmVkZGluZ1Byb3ZpZGVyLFxuICB0eXBlIEVtYmVkZGluZ1Jlc3VsdCxcbiAgdHlwZSBQcm9ncmVzc0NhbGxiYWNrLFxuICB0eXBlIFZlY3RvckNvbmZpZyxcbiAgdHlwZSBWZWN0b3JJbnB1dFR5cGUsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICog7J6E67Kg65SpIO2BtOudvOydtOyWuO2KuFxuICogVm95YWdlIEFJ7JmAIE9wZW5BSSDsnoTrsqDrlKnsnYQgU0RLIOuwqeyLneycvOuhnCDthrXtlakg7KeA7JuQXG4gKi9cbmNsYXNzIEVtYmVkZGluZ0NsYXNzIHtcbiAgcHJpdmF0ZSBjb25maWc6IFZlY3RvckNvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8VmVjdG9yQ29uZmlnPiA9IHt9KSB7XG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICB2b3lhZ2U6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnZveWFnZSwgLi4uY29uZmlnLnZveWFnZSB9LFxuICAgICAgb3BlbmFpOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5vcGVuYWksIC4uLmNvbmZpZy5vcGVuYWkgfSxcbiAgICAgIGNodW5raW5nOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5jaHVua2luZywgLi4uY29uZmlnLmNodW5raW5nIH0sXG4gICAgICBzZWFyY2g6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnNlYXJjaCwgLi4uY29uZmlnLnNlYXJjaCB9LFxuICAgICAgcGd2ZWN0b3I6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnBndmVjdG9yLCAuLi5jb25maWcucGd2ZWN0b3IgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZveWFnZSBBSSDtgbTrnbzsnbTslrjtirgg7LSI6riw7ZmUXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldFZveWFnZUNsaWVudCgpOiBQcm9taXNlPFZveWFnZUFJQ2xpZW50PiB7XG4gICAgY29uc3QgeyBWb3lhZ2VBSUNsaWVudCB9ID0gYXdhaXQgaW1wb3J0KFwidm95YWdlYWlcIik7XG4gICAgY29uc3QgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/LnZveWFnZV9hcGlfa2V5ID8/IHByb2Nlc3MuZW52LlZPWUFHRV9BUElfS0VZO1xuICAgIGlmICghYXBpS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJWT1lBR0VfQVBJX0tFWeqwgCDshKTsoJXrkJjsp4Ag7JWK7JWY7Iq164uI64ukLiDtmZjqsr3rs4DsiJjrpbwg7ZmV7J247ZWY7IS47JqULlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBWb3lhZ2VBSUNsaWVudCh7IGFwaUtleSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuQUkgcHJvdmlkZXIg7IOd7ISxXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldE9wZW5BSVByb3ZpZGVyKCk6IFByb21pc2U8T3BlbkFJUHJvdmlkZXI+IHtcbiAgICBjb25zdCB7IGNyZWF0ZU9wZW5BSSB9ID0gYXdhaXQgaW1wb3J0KFwiQGFpLXNkay9vcGVuYWlcIik7XG4gICAgY29uc3QgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/Lm9wZW5haV9hcGlfa2V5ID8/IHByb2Nlc3MuZW52Lk9QRU5BSV9BUElfS0VZO1xuICAgIGlmICghYXBpS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPUEVOQUlfQVBJX0tFWeqwgCDshKTsoJXrkJjsp4Ag7JWK7JWY7Iq164uI64ukLiDtmZjqsr3rs4DsiJjrpbwg7ZmV7J247ZWY7IS47JqULlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZU9wZW5BSSh7IGFwaUtleSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthY3siqTtirgg7J6E67Kg65SpIOyDneyEsVxuICAgKiBAcGFyYW0gdGV4dHMgLSDsnoTrsqDrlKntlaAg7YWN7Iqk7Yq4IOuwsOyXtCAoYmF0Y2hTaXpl7J207IOBIOyLnCDsnpDrj5kg67aE7ZWgKVxuICAgKiBAcGFyYW0gcHJvdmlkZXIgLSAndm95YWdlJyB8ICdvcGVuYWknXG4gICAqIEBwYXJhbSBpbnB1dFR5cGUgLSAnZG9jdW1lbnQnIHwgJ3F1ZXJ5JyAoVm95YWdlIEFJ66eMIO2VtOuLuSlcbiAgICogQHBhcmFtIG9uUHJvZ3Jlc3MgLSDsp4TtlonrpaAg7L2c67CxXG4gICAqL1xuICBhc3luYyBlbWJlZChcbiAgICB0ZXh0czogc3RyaW5nW10sXG4gICAgcHJvdmlkZXI6IEVtYmVkZGluZ1Byb3ZpZGVyLFxuICAgIGlucHV0VHlwZTogVmVjdG9ySW5wdXRUeXBlID0gXCJkb2N1bWVudFwiLFxuICAgIG9uUHJvZ3Jlc3M/OiBQcm9ncmVzc0NhbGxiYWNrLFxuICApOiBQcm9taXNlPEVtYmVkZGluZ1Jlc3VsdFtdPiB7XG4gICAgY29uc3QgbWF4QmF0Y2hTaXplID1cbiAgICAgIHByb3ZpZGVyID09PSBcInZveWFnZVwiID8gdGhpcy5jb25maWcudm95YWdlLmJhdGNoU2l6ZSA6IHRoaXMuY29uZmlnLm9wZW5haS5iYXRjaFNpemU7XG5cbiAgICAvLyBiYXRjaFNpemXsnbTtlZjrqbQg67CU66GcIO2YuOy2nFxuICAgIGlmICh0ZXh0cy5sZW5ndGggPD0gbWF4QmF0Y2hTaXplKSB7XG4gICAgICByZXR1cm4gcHJvdmlkZXIgPT09IFwidm95YWdlXCJcbiAgICAgICAgPyBhd2FpdCB0aGlzLmVtYmVkVm95YWdlKHRleHRzLCBpbnB1dFR5cGUpXG4gICAgICAgIDogYXdhaXQgdGhpcy5lbWJlZE9wZW5BSSh0ZXh0cyk7XG4gICAgfVxuXG4gICAgLy8gYmF0Y2hTaXpl7J207IOB7J2066m0IOyekOuPmeycvOuhnCDrgpjriKDshJwg7LKY66asXG4gICAgY29uc3QgYmF0Y2hlcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IE1hdGguY2VpbCh0ZXh0cy5sZW5ndGggLyBtYXhCYXRjaFNpemUpIH0sIChfLCBpKSA9PlxuICAgICAgdGV4dHMuc2xpY2UoaSAqIG1heEJhdGNoU2l6ZSwgKGkgKyAxKSAqIG1heEJhdGNoU2l6ZSksXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGJhdGNoZXMubWFwKChiYXRjaCkgPT5cbiAgICAgICAgcHJvdmlkZXIgPT09IFwidm95YWdlXCIgPyB0aGlzLmVtYmVkVm95YWdlKGJhdGNoLCBpbnB1dFR5cGUpIDogdGhpcy5lbWJlZE9wZW5BSShiYXRjaCksXG4gICAgICApLFxuICAgICk7XG5cbiAgICBvblByb2dyZXNzPy4odGV4dHMubGVuZ3RoLCB0ZXh0cy5sZW5ndGgpO1xuICAgIHJldHVybiByZXN1bHRzLmZsYXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDri6jsnbwg7YWN7Iqk7Yq4IOyehOuyoOuUqSAo7Y647J2YIOuplOyEnOuTnClcbiAgICovXG4gIGFzeW5jIGVtYmVkT25lKFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICBwcm92aWRlcjogRW1iZWRkaW5nUHJvdmlkZXIsXG4gICAgaW5wdXRUeXBlOiBWZWN0b3JJbnB1dFR5cGUgPSBcImRvY3VtZW50XCIsXG4gICk6IFByb21pc2U8RW1iZWRkaW5nUmVzdWx0PiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuZW1iZWQoW3RleHRdLCBwcm92aWRlciwgaW5wdXRUeXBlKTtcbiAgICByZXR1cm4gcmVzdWx0c1swXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWb3lhZ2UgQUkg7J6E67Kg65SpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVtYmVkVm95YWdlKFxuICAgIHRleHRzOiBzdHJpbmdbXSxcbiAgICBpbnB1dFR5cGU6IFZlY3RvcklucHV0VHlwZSxcbiAgKTogUHJvbWlzZTxFbWJlZGRpbmdSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Vm95YWdlQ2xpZW50KCk7XG4gICAgY29uc3Qgdm95YWdlQ29uZmlnID0gdGhpcy5jb25maWcudm95YWdlO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZW1iZWQoe1xuICAgICAgaW5wdXQ6IHRleHRzLFxuICAgICAgbW9kZWw6IHZveWFnZUNvbmZpZy5tb2RlbCxcbiAgICAgIGlucHV0VHlwZTogaW5wdXRUeXBlLFxuICAgIH0pO1xuICAgIGlmICghcmVzcG9uc2UuZGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVm95YWdlIEFQSTog7J2R64u1IOuNsOydtO2EsOqwgCDsl4bsirXri4jri6QuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5kYXRhLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgIGVtYmVkZGluZzogaXRlbS5lbWJlZGRpbmcgPz8gW10sXG4gICAgICBtb2RlbDogdm95YWdlQ29uZmlnLm1vZGVsLFxuICAgICAgdG9rZW5Db3VudDogcmVzcG9uc2UudXNhZ2U/LnRvdGFsVG9rZW5zID8/IDAsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5BSSDsnoTrsqDrlKlcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW1iZWRPcGVuQUkodGV4dHM6IHN0cmluZ1tdKTogUHJvbWlzZTxFbWJlZGRpbmdSZXN1bHRbXT4ge1xuICAgIGNvbnN0IG9wZW5haSA9IGF3YWl0IHRoaXMuZ2V0T3BlbkFJUHJvdmlkZXIoKTtcbiAgICBjb25zdCBvcGVuYWlDb25maWcgPSB0aGlzLmNvbmZpZy5vcGVuYWk7XG4gICAgY29uc3QgbW9kZWwgPSBvcGVuYWkuZW1iZWRkaW5nTW9kZWwob3BlbmFpQ29uZmlnLm1vZGVsKTtcblxuICAgIGNvbnN0IHsgZW1iZWRkaW5ncywgdXNhZ2UgfSA9IGF3YWl0IGVtYmVkTWFueSh7XG4gICAgICBtb2RlbDogbW9kZWwgYXMgRW1iZWRkaW5nTW9kZWwsXG4gICAgICB2YWx1ZXM6IHRleHRzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVtYmVkZGluZ3MubWFwKChlbWJlZGRpbmcpID0+ICh7XG4gICAgICBlbWJlZGRpbmcsXG4gICAgICBtb2RlbDogb3BlbmFpQ29uZmlnLm1vZGVsLFxuICAgICAgdG9rZW5Db3VudDogdXNhZ2U/LnRva2VucyA/PyAwLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsnoTrsqDrlKkgcHJvdmlkZXLsnZgg7LCo7JuQIOyImCDrsJjtmZhcbiAgICovXG4gIGdldERpbWVuc2lvbnMocHJvdmlkZXI6IEVtYmVkZGluZ1Byb3ZpZGVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcHJvdmlkZXIgPT09IFwidm95YWdlXCIgPyB0aGlzLmNvbmZpZy52b3lhZ2UuZGltZW5zaW9ucyA6IHRoaXMuY29uZmlnLm9wZW5haS5kaW1lbnNpb25zO1xuICB9XG59XG5leHBvcnQgY29uc3QgRW1iZWRkaW5nID0gbmV3IEVtYmVkZGluZ0NsYXNzKCk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7WUFLc0M7Ozs7O0FBY3RDLElBQU0saUJBQU4sTUFBcUI7Q0FDbkI7Q0FFQSxZQUFZLFNBQWdDLENBQUMsR0FBRztFQUM5QyxLQUFLLFNBQVM7R0FDWixRQUFRO0lBQUUsR0FBRyxzQkFBc0I7SUFBUSxHQUFHLE9BQU87R0FBTztHQUM1RCxRQUFRO0lBQUUsR0FBRyxzQkFBc0I7SUFBUSxHQUFHLE9BQU87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
|
package/dist/vector/index.js
CHANGED
|
@@ -2,5 +2,4 @@ import { DEFAULT_VECTOR_CONFIG, createVectorConfig } from "./config.js";
|
|
|
2
2
|
import { Chunking } from "./chunking.js";
|
|
3
3
|
import { Embedding } from "./embedding.js";
|
|
4
4
|
import "./types.js";
|
|
5
|
-
|
|
6
|
-
export { Chunking, DEFAULT_VECTOR_CONFIG, Embedding, createVectorConfig };
|
|
5
|
+
export { Chunking, DEFAULT_VECTOR_CONFIG, Embedding, createVectorConfig };
|
package/dist/vector/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonamu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Sonamu — TypeScript Fullstack API Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -120,18 +120,18 @@
|
|
|
120
120
|
"minimatch": "^10.0.3",
|
|
121
121
|
"node-cron": "^4.2.1",
|
|
122
122
|
"node-sql-parser": "^5.2.0",
|
|
123
|
-
"oxfmt": "^0.
|
|
124
|
-
"oxlint": "^1.
|
|
123
|
+
"oxfmt": "^0.55.0",
|
|
124
|
+
"oxlint": "^1.70.0",
|
|
125
125
|
"pg": "^8.16.3",
|
|
126
126
|
"prompts": "^2.4.2",
|
|
127
127
|
"qs": "^6.14.1",
|
|
128
128
|
"radashi": "^12.2.0",
|
|
129
129
|
"tsicli": "^1.0.5",
|
|
130
|
-
"vite": "8.0.
|
|
131
|
-
"vitest": "^4.1.
|
|
130
|
+
"vite": "8.0.16",
|
|
131
|
+
"vitest": "^4.1.9",
|
|
132
132
|
"@sonamu-kit/hmr-runner": "^0.2.0",
|
|
133
|
+
"@sonamu-kit/tasks": "^0.3.1",
|
|
133
134
|
"@sonamu-kit/ts-loader": "^2.2.0",
|
|
134
|
-
"@sonamu-kit/tasks": "^0.3.0",
|
|
135
135
|
"@sonamu-kit/hmr-hook": "^0.5.1"
|
|
136
136
|
},
|
|
137
137
|
"devDependencies": {
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"@types/prompts": "^2.0.14",
|
|
144
144
|
"@types/qs": "^6.14.0",
|
|
145
145
|
"nodemon": "^3.1.10",
|
|
146
|
-
"tsdown": "^0.
|
|
146
|
+
"tsdown": "^0.22.3",
|
|
147
147
|
"typescript": "^6.0.3"
|
|
148
148
|
},
|
|
149
149
|
"peerDependencies": {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
6
|
+
|
|
7
|
+
import { readAllEnvironmentSnapshots, readEnvironmentSnapshot } from "../env";
|
|
8
|
+
|
|
9
|
+
describe("readAllEnvironmentSnapshots", () => {
|
|
10
|
+
const tempRoots: string[] = [];
|
|
11
|
+
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
await Promise.all(
|
|
14
|
+
tempRoots.splice(0).map((rootPath) => rm(rootPath, { recursive: true, force: true })),
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("does not reuse the current environment dotenv values as other environments' base values", async () => {
|
|
19
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
20
|
+
tempRoots.push(rootPath);
|
|
21
|
+
|
|
22
|
+
await mkdir(rootPath, { recursive: true });
|
|
23
|
+
await writeFile(path.join(rootPath, ".env"), "SONAMU_DB_USER=base_user\n");
|
|
24
|
+
await writeFile(
|
|
25
|
+
path.join(rootPath, ".env.development"),
|
|
26
|
+
"SONAMU_DB_HOST=development.example.com\nSONAMU_DB_PASSWORD=development_password\n",
|
|
27
|
+
);
|
|
28
|
+
await writeFile(path.join(rootPath, ".env.staging"), "SONAMU_DB_HOST=staging.example.com\n");
|
|
29
|
+
|
|
30
|
+
const snapshots = readAllEnvironmentSnapshots(rootPath, {
|
|
31
|
+
NODE_ENV: "development",
|
|
32
|
+
SONAMU_DB_PASSWORD: "shell_password",
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(snapshots.development.SONAMU_DB_HOST).toBe("development.example.com");
|
|
36
|
+
expect(snapshots.development.SONAMU_DB_PASSWORD).toBe("shell_password");
|
|
37
|
+
expect(snapshots.staging.SONAMU_DB_HOST).toBe("staging.example.com");
|
|
38
|
+
expect(snapshots.staging.SONAMU_DB_PASSWORD).toBe("shell_password");
|
|
39
|
+
expect(snapshots.staging.SONAMU_DB_USER).toBe("base_user");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("throws when both common and environment dotenv files are missing", async () => {
|
|
43
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
44
|
+
tempRoots.push(rootPath);
|
|
45
|
+
|
|
46
|
+
await writeFile(path.join(rootPath, ".env.local"), "SONAMU_DB_HOST=local.example.com\n");
|
|
47
|
+
|
|
48
|
+
expect(() => readAllEnvironmentSnapshots(rootPath)).toThrow(
|
|
49
|
+
/Missing Sonamu dotenv file.*\.env.*\.env\.test/,
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("allows environment snapshots when only the common dotenv file exists", async () => {
|
|
54
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
55
|
+
tempRoots.push(rootPath);
|
|
56
|
+
|
|
57
|
+
await writeFile(path.join(rootPath, ".env"), "SONAMU_DB_HOST=common.example.com\n");
|
|
58
|
+
|
|
59
|
+
const snapshots = readAllEnvironmentSnapshots(rootPath);
|
|
60
|
+
|
|
61
|
+
expect(snapshots.development.SONAMU_DB_HOST).toBe("common.example.com");
|
|
62
|
+
expect(snapshots.production.SONAMU_DB_HOST).toBe("common.example.com");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("allows an environment snapshot when only the environment dotenv file exists", async () => {
|
|
66
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
67
|
+
tempRoots.push(rootPath);
|
|
68
|
+
|
|
69
|
+
await writeFile(path.join(rootPath, ".env.development"), "SONAMU_DB_HOST=dev.example.com\n");
|
|
70
|
+
|
|
71
|
+
const snapshot = readEnvironmentSnapshot(rootPath, "development");
|
|
72
|
+
|
|
73
|
+
expect(snapshot.SONAMU_DB_HOST).toBe("dev.example.com");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("keeps exported environment variables over dotenv file values", async () => {
|
|
77
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
78
|
+
tempRoots.push(rootPath);
|
|
79
|
+
|
|
80
|
+
await writeFile(
|
|
81
|
+
path.join(rootPath, ".env.development"),
|
|
82
|
+
"SONAMU_DB_HOST=file-host\nSONAMU_DB_PASSWORD=file-password\n",
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const snapshot = readEnvironmentSnapshot(rootPath, "development", {
|
|
86
|
+
SONAMU_DB_HOST: "runtime-host",
|
|
87
|
+
SONAMU_DB_PASSWORD: "runtime-password",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
expect(snapshot.SONAMU_DB_HOST).toBe("runtime-host");
|
|
91
|
+
expect(snapshot.SONAMU_DB_PASSWORD).toBe("runtime-password");
|
|
92
|
+
expect(snapshot.NODE_ENV).toBe("development");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("lets environment dotenv values override common dotenv values", async () => {
|
|
96
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
97
|
+
tempRoots.push(rootPath);
|
|
98
|
+
|
|
99
|
+
await writeFile(path.join(rootPath, ".env"), "SONAMU_DB_HOST=common.example.com\n");
|
|
100
|
+
await writeFile(path.join(rootPath, ".env.production"), "SONAMU_DB_HOST=prod.example.com\n");
|
|
101
|
+
|
|
102
|
+
const snapshot = readEnvironmentSnapshot(rootPath, "production");
|
|
103
|
+
|
|
104
|
+
expect(snapshot.SONAMU_DB_HOST).toBe("prod.example.com");
|
|
105
|
+
expect(snapshot.NODE_ENV).toBe("production");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("does not let preloaded common dotenv values override environment dotenv values", async () => {
|
|
109
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-env-test-"));
|
|
110
|
+
tempRoots.push(rootPath);
|
|
111
|
+
|
|
112
|
+
await writeFile(
|
|
113
|
+
path.join(rootPath, ".env"),
|
|
114
|
+
"SONAMU_DB_HOST=common.example.com\nSONAMU_DB_USER=common_user\n",
|
|
115
|
+
);
|
|
116
|
+
await writeFile(path.join(rootPath, ".env.production"), "SONAMU_DB_HOST=prod.example.com\n");
|
|
117
|
+
|
|
118
|
+
const snapshot = readEnvironmentSnapshot(rootPath, "production", {
|
|
119
|
+
SONAMU_DB_HOST: "common.example.com",
|
|
120
|
+
SONAMU_DB_USER: "shell_user",
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(snapshot.SONAMU_DB_HOST).toBe("prod.example.com");
|
|
124
|
+
expect(snapshot.SONAMU_DB_USER).toBe("shell_user");
|
|
125
|
+
expect(snapshot.NODE_ENV).toBe("production");
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -21,7 +21,9 @@ function resetRegisterState() {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async function createTempRoot(): Promise<string> {
|
|
24
|
-
|
|
24
|
+
const rootPath = await mkdtemp(path.join(os.tmpdir(), "sonamu-config-test-"));
|
|
25
|
+
await writeFile(path.join(rootPath, ".env"), "SONAMU_DB_HOST=localhost\n");
|
|
26
|
+
return rootPath;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
async function writeSourceFixture(rootPath: string): Promise<void> {
|
|
@@ -136,6 +138,7 @@ describe("loadConfig", () => {
|
|
|
136
138
|
const tempRoots: string[] = [];
|
|
137
139
|
const originalHot = process.env.HOT;
|
|
138
140
|
const originalVitest = process.env.VITEST;
|
|
141
|
+
const originalNodeEnv = process.env.NODE_ENV;
|
|
139
142
|
|
|
140
143
|
beforeEach(() => {
|
|
141
144
|
vi.resetModules();
|
|
@@ -162,6 +165,12 @@ describe("loadConfig", () => {
|
|
|
162
165
|
process.env.VITEST = originalVitest;
|
|
163
166
|
}
|
|
164
167
|
|
|
168
|
+
if (originalNodeEnv === undefined) {
|
|
169
|
+
delete process.env.NODE_ENV;
|
|
170
|
+
} else {
|
|
171
|
+
process.env.NODE_ENV = originalNodeEnv;
|
|
172
|
+
}
|
|
173
|
+
|
|
165
174
|
await Promise.all(
|
|
166
175
|
tempRoots.splice(0).map((rootPath) => rm(rootPath, { recursive: true, force: true })),
|
|
167
176
|
);
|
package/src/api/config.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { type Knex } from "knex";
|
|
|
17
17
|
|
|
18
18
|
import { type CacheConfig } from "../cache/types";
|
|
19
19
|
import { type SonamuDBConfig } from "../database/db";
|
|
20
|
+
import { applyCurrentSnapshotToProcessEnv } from "../env";
|
|
20
21
|
import { type SonamuLoggingOptions } from "../logger/configure";
|
|
21
22
|
import { type StorageConfig } from "../storage/types";
|
|
22
23
|
import { type WebSocketRuntimeOptions } from "../stream/ws";
|
|
@@ -94,19 +95,8 @@ export type SonamuConfig<TSinkId extends string = string, TFilterId extends stri
|
|
|
94
95
|
database: {
|
|
95
96
|
// 데이터베이스(pg는 pg 모듈, pgnative는 pg-native 모듈의 설치가 필요합니다.)
|
|
96
97
|
database?: "pg" | "pgnative";
|
|
97
|
-
// 기본 데이터베이스 이름
|
|
98
|
-
name: string;
|
|
99
98
|
// 모든 환경에 적용될 기본 Knex 옵션
|
|
100
|
-
defaultOptions
|
|
101
|
-
// 환경별 설정
|
|
102
|
-
environments?: {
|
|
103
|
-
development?: DatabaseConfig;
|
|
104
|
-
development_slave?: DatabaseConfig;
|
|
105
|
-
production?: DatabaseConfig;
|
|
106
|
-
production_slave?: DatabaseConfig;
|
|
107
|
-
fixture?: DatabaseConfig;
|
|
108
|
-
test?: DatabaseConfig;
|
|
109
|
-
};
|
|
99
|
+
defaultOptions?: DatabaseConfig;
|
|
110
100
|
};
|
|
111
101
|
|
|
112
102
|
logging?: false | SonamuLoggingOptions<TSinkId, TFilterId>;
|
|
@@ -319,6 +309,8 @@ export function defineConfig(config: Executable<SonamuConfig>): Promise<SonamuCo
|
|
|
319
309
|
* @returns
|
|
320
310
|
*/
|
|
321
311
|
export async function loadConfig(rootPath: string): Promise<SonamuConfig> {
|
|
312
|
+
applyCurrentSnapshotToProcessEnv(rootPath);
|
|
313
|
+
|
|
322
314
|
const shouldLoadSourceConfig = process.env.HOT === "yes" || process.env.VITEST === "true";
|
|
323
315
|
const configPath = shouldLoadSourceConfig
|
|
324
316
|
? `${rootPath}/src/sonamu.config.ts`
|
package/src/api/sonamu.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { DB } from "../database/db";
|
|
|
24
24
|
import { type SonamuDBConfig } from "../database/db";
|
|
25
25
|
import { SD, setSDConfig } from "../dict/sd";
|
|
26
26
|
import { type LocalizedString } from "../dict/types";
|
|
27
|
+
import { getSonamuEnvironment, readAllEnvironmentSnapshots } from "../env";
|
|
27
28
|
import { NotFoundException } from "../exceptions/so-exceptions";
|
|
28
29
|
import { BufferedFile } from "../storage/buffered-file";
|
|
29
30
|
import { type StorageManager } from "../storage/storage-manager";
|
|
@@ -231,6 +232,7 @@ class SonamuClass {
|
|
|
231
232
|
// API 루트 패스
|
|
232
233
|
const { findApiRootPath } = await import("../utils/utils");
|
|
233
234
|
this.apiRootPath = apiRootPath ?? findApiRootPath();
|
|
235
|
+
const baseEnvBeforeConfigLoad = { ...process.env };
|
|
234
236
|
|
|
235
237
|
// 설정을 로딩하는 것부터 시작
|
|
236
238
|
const configStart = performance.now();
|
|
@@ -240,6 +242,7 @@ class SonamuClass {
|
|
|
240
242
|
setSDConfig(this.config.i18n);
|
|
241
243
|
// sonamu.config.ts 기본값 설정
|
|
242
244
|
this.config.database.database = this.config.database.database ?? "pg";
|
|
245
|
+
this.config.database.defaultOptions = this.config.database.defaultOptions ?? {};
|
|
243
246
|
this.config.database.defaultOptions.client = this.config.database.database ?? "pg";
|
|
244
247
|
|
|
245
248
|
// 로깅 설정
|
|
@@ -252,7 +255,15 @@ class SonamuClass {
|
|
|
252
255
|
|
|
253
256
|
// DB 로드
|
|
254
257
|
const { DB } = await import("../database/db");
|
|
255
|
-
|
|
258
|
+
const { isLocal: isLocalEnvironment } = await import("../utils/controller");
|
|
259
|
+
const environmentSnapshots = isLocalEnvironment()
|
|
260
|
+
? readAllEnvironmentSnapshots(this.apiRootPath, baseEnvBeforeConfigLoad)
|
|
261
|
+
: undefined;
|
|
262
|
+
this.dbConfig = DB.generateDBConfig(
|
|
263
|
+
this.config.database,
|
|
264
|
+
this.config.projectName,
|
|
265
|
+
environmentSnapshots,
|
|
266
|
+
);
|
|
256
267
|
DB.setConfig(this.dbConfig);
|
|
257
268
|
|
|
258
269
|
// Entity 로드
|
|
@@ -1825,8 +1836,7 @@ class SonamuClass {
|
|
|
1825
1836
|
|
|
1826
1837
|
private async printStartupSummary() {
|
|
1827
1838
|
const chalk = (await import("chalk")).default;
|
|
1828
|
-
const
|
|
1829
|
-
const activePreset = env === "production" ? "production_master" : "development_master";
|
|
1839
|
+
const activePreset = getSonamuEnvironment();
|
|
1830
1840
|
|
|
1831
1841
|
const dim = (msg: string) => console.log(chalk.dim(`✓ ${msg}`));
|
|
1832
1842
|
const green = (msg: string) => console.log(chalk.green(`✓ ${msg}`));
|
|
@@ -1843,7 +1853,7 @@ class SonamuClass {
|
|
|
1843
1853
|
| { host?: string; port?: number; database?: string }
|
|
1844
1854
|
| undefined;
|
|
1845
1855
|
const host = conn?.host ?? "localhost";
|
|
1846
|
-
const addr = `@ ${host}:${conn?.port ?? 5432}/${conn?.database ??
|
|
1856
|
+
const addr = `@ ${host}:${conn?.port ?? 5432}/${conn?.database ?? "(unknown)"}`;
|
|
1847
1857
|
const padded = name.padEnd(maxLen);
|
|
1848
1858
|
const remoteTag = isLocal() && !isLocalHost(host) ? chalk.yellow(` \u26a0 remote`) : "";
|
|
1849
1859
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { getMigrateRunTargets } from "../migrate-targets";
|
|
4
|
+
|
|
5
|
+
describe("getMigrateRunTargets", () => {
|
|
6
|
+
const originalEnv = { ...process.env };
|
|
7
|
+
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
for (const key of Object.keys(process.env)) {
|
|
10
|
+
if (!(key in originalEnv)) {
|
|
11
|
+
delete process.env[key];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
Object.assign(process.env, originalEnv);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("includes fixture when running migrations in the test environment", () => {
|
|
18
|
+
process.env.NODE_ENV = "test";
|
|
19
|
+
|
|
20
|
+
expect(getMigrateRunTargets()).toEqual(["test", "fixture"]);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("uses only the current environment outside test", () => {
|
|
24
|
+
process.env.NODE_ENV = "staging";
|
|
25
|
+
|
|
26
|
+
expect(getMigrateRunTargets()).toEqual(["staging"]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
const originalArgv = process.argv;
|
|
4
|
+
const originalNodeEnv = process.env.NODE_ENV;
|
|
5
|
+
const originalVitest = process.env.VITEST;
|
|
6
|
+
const originalFetch = globalThis.fetch;
|
|
2
7
|
|
|
3
8
|
// process.argv 파싱 로직을 검증하는 유닛 테스트
|
|
4
9
|
// test-command.ts의 파싱 로직을 동일하게 구현하여 독립 검증
|
|
@@ -83,3 +88,79 @@ describe("test-command argument parsing", () => {
|
|
|
83
88
|
expect(showTraces).toBe(true);
|
|
84
89
|
});
|
|
85
90
|
});
|
|
91
|
+
|
|
92
|
+
describe("test-command dev server endpoint resolution", () => {
|
|
93
|
+
beforeEach(() => {
|
|
94
|
+
vi.resetModules();
|
|
95
|
+
vi.restoreAllMocks();
|
|
96
|
+
process.argv = [process.execPath, "sonamu", "test", "--status"];
|
|
97
|
+
process.env.NODE_ENV = "development";
|
|
98
|
+
delete process.env.VITEST;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
afterEach(() => {
|
|
102
|
+
vi.resetModules();
|
|
103
|
+
vi.restoreAllMocks();
|
|
104
|
+
process.argv = originalArgv;
|
|
105
|
+
globalThis.fetch = originalFetch;
|
|
106
|
+
|
|
107
|
+
if (originalNodeEnv === undefined) {
|
|
108
|
+
delete process.env.NODE_ENV;
|
|
109
|
+
} else {
|
|
110
|
+
process.env.NODE_ENV = originalNodeEnv;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (originalVitest === undefined) {
|
|
114
|
+
delete process.env.VITEST;
|
|
115
|
+
} else {
|
|
116
|
+
process.env.VITEST = originalVitest;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("status 명령은 NODE_ENV=test로 바꾸지 않고 dev server 설정의 endpoint를 호출한다", async () => {
|
|
121
|
+
const loadConfig = vi.fn(async () => {
|
|
122
|
+
expect(process.env.NODE_ENV).toBe("development");
|
|
123
|
+
expect(process.env.VITEST).toBe("true");
|
|
124
|
+
return {
|
|
125
|
+
server: {
|
|
126
|
+
listen: {
|
|
127
|
+
host: "127.0.0.1",
|
|
128
|
+
port: 4401,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
test: {
|
|
132
|
+
devRunner: {
|
|
133
|
+
enabled: true,
|
|
134
|
+
routePrefix: "/__dev_test__",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
const fetch = vi.fn(async () => {
|
|
140
|
+
return new Response(
|
|
141
|
+
JSON.stringify({
|
|
142
|
+
ready: true,
|
|
143
|
+
running: false,
|
|
144
|
+
lastRunAt: null,
|
|
145
|
+
sseAvailable: true,
|
|
146
|
+
}),
|
|
147
|
+
{
|
|
148
|
+
status: 200,
|
|
149
|
+
headers: { "Content-Type": "application/json" },
|
|
150
|
+
},
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
vi.doMock("../../api/config", () => ({ loadConfig }));
|
|
155
|
+
vi.doMock("../../utils/utils", () => ({ findApiRootPath: () => "/tmp/api" }));
|
|
156
|
+
vi.spyOn(console, "log").mockImplementation(() => {});
|
|
157
|
+
globalThis.fetch = fetch as typeof globalThis.fetch;
|
|
158
|
+
|
|
159
|
+
const { testCommand } = await import("../test-command");
|
|
160
|
+
await testCommand();
|
|
161
|
+
|
|
162
|
+
expect(loadConfig).toHaveBeenCalledWith("/tmp/api");
|
|
163
|
+
expect(fetch).toHaveBeenCalledWith("http://127.0.0.1:4401/__dev_test__/status");
|
|
164
|
+
expect(process.env.NODE_ENV).toBe("development");
|
|
165
|
+
});
|
|
166
|
+
});
|
package/src/bin/cli.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import dotenv from "dotenv";
|
|
3
|
-
|
|
4
|
-
dotenv.config();
|
|
5
|
-
|
|
6
1
|
import assert from "assert";
|
|
7
2
|
import { execSync, spawn } from "child_process";
|
|
8
3
|
import { cp, mkdir, readdir, readFile, rm, symlink, writeFile } from "fs/promises";
|
|
@@ -11,6 +6,7 @@ import os from "os";
|
|
|
11
6
|
import path from "path";
|
|
12
7
|
import process from "process";
|
|
13
8
|
|
|
9
|
+
import chalk from "chalk";
|
|
14
10
|
import knex from "knex";
|
|
15
11
|
import { type Knex } from "knex";
|
|
16
12
|
import { tsicli } from "tsicli";
|
|
@@ -21,6 +17,7 @@ import { isValidPluginId, SUPPORTED_PLUGIN_IDS } from "../auth/plugins/entity-de
|
|
|
21
17
|
import { type BetterAuthPluginId } from "../auth/plugins/entity-definitions";
|
|
22
18
|
import { type SonamuDBConfig } from "../database/db";
|
|
23
19
|
import { EntityManager } from "../entity/entity-manager";
|
|
20
|
+
import { getSonamuEnvironment } from "../env";
|
|
24
21
|
import { Migrator } from "../migration/migrator";
|
|
25
22
|
import { FixtureManager } from "../testing/fixture-manager";
|
|
26
23
|
import {
|
|
@@ -36,6 +33,7 @@ import { findApiRootPath, findAppRootPath } from "../utils/utils";
|
|
|
36
33
|
import { API_ARTIFACTS, WEB_ARTIFACTS } from "./build-config";
|
|
37
34
|
import { type BuildArtifact } from "./build-config";
|
|
38
35
|
import { fixtureExploreCommand, fixtureFetchCommand, fixtureGenCommand } from "./fixture";
|
|
36
|
+
import { getMigrateRunTargets } from "./migrate-targets";
|
|
39
37
|
import { testCommand } from "./test-command";
|
|
40
38
|
|
|
41
39
|
let migrator: Migrator;
|
|
@@ -144,8 +142,9 @@ async function bootstrap() {
|
|
|
144
142
|
name: "#targets",
|
|
145
143
|
message: "Please input #targets",
|
|
146
144
|
choices: [
|
|
147
|
-
{ title: "Development", value: "
|
|
148
|
-
{ title: "
|
|
145
|
+
{ title: "Development", value: "development" },
|
|
146
|
+
{ title: "Staging", value: "staging" },
|
|
147
|
+
{ title: "Production", value: "production" },
|
|
149
148
|
{ title: "Fixture", value: "fixture" },
|
|
150
149
|
{ title: "Test", value: "test" },
|
|
151
150
|
],
|
|
@@ -284,7 +283,7 @@ function spawnApiDevServer(options?: { extraEnv?: Record<string, string> }) {
|
|
|
284
283
|
stdio: "inherit",
|
|
285
284
|
env: {
|
|
286
285
|
...process.env,
|
|
287
|
-
NODE_ENV: "development",
|
|
286
|
+
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
288
287
|
HOT: "yes", // 얘가 있어야 HMR이 활성화됩니다.
|
|
289
288
|
API_ROOT_PATH: apiRoot, // 이 경로가 hmr-hook의 루트 디렉토리가 됩니다.
|
|
290
289
|
...options?.extraEnv,
|
|
@@ -553,15 +552,7 @@ async function migrate_apply(targets: (keyof SonamuDBConfig)[]) {
|
|
|
553
552
|
|
|
554
553
|
async function migrate_run() {
|
|
555
554
|
await setupMigrator();
|
|
556
|
-
|
|
557
|
-
const targets = Object.keys(Sonamu.dbConfig).filter((target) => {
|
|
558
|
-
const targetConfig = Sonamu.dbConfig[target as keyof SonamuDBConfig];
|
|
559
|
-
const host = (targetConfig?.connection as { host?: string })?.host ?? "localhost";
|
|
560
|
-
return localHosts.includes(host.toLowerCase());
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
// 로컬 데이터베이스에 대해서만 전체 마이그레이션에서 동작
|
|
564
|
-
await migrator.runAction("apply", targets as (keyof SonamuDBConfig)[]);
|
|
555
|
+
await migrator.runAction("apply", getMigrateRunTargets());
|
|
565
556
|
}
|
|
566
557
|
|
|
567
558
|
async function migrate_generate() {
|
|
@@ -598,7 +589,7 @@ async function migrate_status() {
|
|
|
598
589
|
}
|
|
599
590
|
|
|
600
591
|
async function fixture_init() {
|
|
601
|
-
const srcConfig = Sonamu.dbConfig
|
|
592
|
+
const srcConfig = Sonamu.dbConfig[getSonamuEnvironment()];
|
|
602
593
|
const targets = [
|
|
603
594
|
{
|
|
604
595
|
label: "(REMOTE) Fixture DB",
|
package/src/bin/fixture.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { Sonamu } from "../api/sonamu";
|
|
|
5
5
|
import { DB } from "../database/db";
|
|
6
6
|
import { createKnexInstance } from "../database/knex";
|
|
7
7
|
import { EntityManager } from "../entity/entity-manager";
|
|
8
|
+
import { getSonamuEnvironment } from "../env";
|
|
8
9
|
import { DataExplorer } from "../testing/data-explorer";
|
|
9
10
|
import { type DataExplorerStrategy } from "../testing/data-explorer";
|
|
10
11
|
import { FixtureGenerator } from "../testing/fixture-generator";
|
|
@@ -129,12 +130,12 @@ export async function fixtureGenCommand(options: FixtureCommandOptions) {
|
|
|
129
130
|
const enableLLMCache = !options["no-cache"];
|
|
130
131
|
const DEFAULT_PASSWORD = "Test1234!";
|
|
131
132
|
|
|
132
|
-
// 로그인 가능 경로에서는 sourceDb로
|
|
133
|
+
// 로그인 가능 경로에서는 현재 환경의 읽기 DB를 sourceDb로 사용
|
|
133
134
|
const sourceDb = DB.getDB("r");
|
|
134
135
|
const generator = new FixtureGenerator(
|
|
135
136
|
sourceDb,
|
|
136
137
|
sourceDb,
|
|
137
|
-
|
|
138
|
+
getSonamuEnvironment(),
|
|
138
139
|
EntityManager,
|
|
139
140
|
{ useLLM, enableLLMCache },
|
|
140
141
|
);
|
|
@@ -395,8 +396,8 @@ export async function fixtureFetchCommand(options: FixtureCommandOptions) {
|
|
|
395
396
|
const strategy: DataExplorerStrategy = options.strategy ?? "recent";
|
|
396
397
|
const limit = options.limit ? Number.parseInt(options.limit, 10) : 10;
|
|
397
398
|
|
|
398
|
-
// fixture fetch:
|
|
399
|
-
const sourceDb = DB.getDB("r");
|
|
399
|
+
// fixture fetch: 현재 환경 데이터를 fixture DB로 import합니다
|
|
400
|
+
const sourceDb = DB.getDB("r");
|
|
400
401
|
const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
|
|
401
402
|
const generator = new FixtureGenerator(sourceDb, fixtureDb, "fixture", EntityManager);
|
|
402
403
|
|