sonamu 0.9.20 → 0.10.1
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 +210 -406
- package/dist/api/validator.js +5 -8
- package/dist/api/websocket-helpers.js +22 -33
- package/dist/auth/audit-log/builders.d.ts.map +1 -1
- package/dist/auth/audit-log/builders.js +4 -3
- package/dist/auth/audit-log/client-ip.d.ts +3 -0
- package/dist/auth/audit-log/client-ip.d.ts.map +1 -0
- package/dist/auth/audit-log/client-ip.js +27 -0
- package/dist/auth/audit-log/events.d.ts +1 -0
- package/dist/auth/audit-log/events.d.ts.map +1 -1
- package/dist/auth/audit-log/events.js +2 -2
- package/dist/auth/audit-log/plugin.js +30 -61
- package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
- package/dist/auth/audit-log-ingestor.js +26 -43
- package/dist/auth/auth-generator.js +16 -41
- package/dist/auth/better-auth-entities.js +3 -4
- package/dist/auth/better-auth-request.d.ts +3 -0
- package/dist/auth/better-auth-request.d.ts.map +1 -0
- package/dist/auth/better-auth-request.js +23 -0
- 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 +152 -259
- 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 +157 -311
- 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 +9 -8
- package/dist/logger/category.js +6 -12
- package/dist/logger/configure.js +23 -34
- package/dist/migration/code-generation.js +147 -315
- 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 +14 -32
- 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.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -4
- 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 +100 -196
- 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 +8 -8
- 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 +28 -33
- package/src/auth/audit-log/builders.ts +3 -0
- package/src/auth/audit-log/client-ip.ts +38 -0
- package/src/auth/audit-log/events.ts +1 -0
- package/src/auth/audit-log-ingestor.ts +22 -15
- package/src/auth/better-auth-request.ts +20 -0
- 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/puri.md +33 -0
- package/src/skills/sonamu/testing-devrunner.md +1 -1
- package/src/stream/ws-telemetry-memory.ts +2 -2
- package/src/syncer/checksum.ts +7 -12
- 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/index.ts +1 -0
- 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
|
@@ -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
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SonamuDBConfig } from "../database/db";
|
|
2
|
+
import { getSonamuEnvironment } from "../env";
|
|
3
|
+
|
|
4
|
+
export function getMigrateRunTargets(): (keyof SonamuDBConfig)[] {
|
|
5
|
+
const environment = getSonamuEnvironment();
|
|
6
|
+
return environment === "test" ? ["test", "fixture"] : [environment];
|
|
7
|
+
}
|
package/src/bin/test-command.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { loadConfig } from "../api/config";
|
|
|
7
7
|
import { type RunResult, type TestCaseResult } from "../testing";
|
|
8
8
|
import { findApiRootPath } from "../utils/utils";
|
|
9
9
|
|
|
10
|
-
async function
|
|
10
|
+
async function loadDevServerConfig(): Promise<SonamuConfig> {
|
|
11
11
|
const prevVitest = process.env.VITEST;
|
|
12
12
|
process.env.VITEST = "true";
|
|
13
13
|
try {
|
|
@@ -37,7 +37,7 @@ function resolveTestBaseUrl(config: SonamuConfig): {
|
|
|
37
37
|
export async function testCommand(): Promise<void> {
|
|
38
38
|
const args = process.argv.slice(3);
|
|
39
39
|
|
|
40
|
-
const config = await
|
|
40
|
+
const config = await loadDevServerConfig();
|
|
41
41
|
|
|
42
42
|
// process.argv 파싱: sonamu test [file...] --pattern "이름" --traces --status
|
|
43
43
|
const files: string[] = [];
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { type EnvironmentSnapshots } from "../../env";
|
|
4
|
+
import { DBClass } from "../db";
|
|
5
|
+
|
|
6
|
+
describe("DBClass.generateDBConfig", () => {
|
|
7
|
+
const originalEnv = { ...process.env };
|
|
8
|
+
const emptySnapshots: EnvironmentSnapshots = {
|
|
9
|
+
test: {},
|
|
10
|
+
development: {},
|
|
11
|
+
staging: {},
|
|
12
|
+
production: {},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
for (const key of Object.keys(process.env)) {
|
|
17
|
+
if (!(key in originalEnv)) {
|
|
18
|
+
delete process.env[key];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
Object.assign(process.env, originalEnv);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("keeps defaultOptions.connection values when matching SONAMU_DB env vars are absent", () => {
|
|
25
|
+
delete process.env.SONAMU_DB_HOST;
|
|
26
|
+
delete process.env.SONAMU_DB_PORT;
|
|
27
|
+
delete process.env.SONAMU_DB_USER;
|
|
28
|
+
delete process.env.SONAMU_DB_PASSWORD;
|
|
29
|
+
delete process.env.SONAMU_DB_NAME;
|
|
30
|
+
|
|
31
|
+
const dbConfig = new DBClass().generateDBConfig(
|
|
32
|
+
{
|
|
33
|
+
database: "pg",
|
|
34
|
+
defaultOptions: {
|
|
35
|
+
connection: {
|
|
36
|
+
host: "default-host",
|
|
37
|
+
port: 15432,
|
|
38
|
+
user: "default-user",
|
|
39
|
+
password: "default-password",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
"Miomock",
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
expect(dbConfig.development!.connection).toMatchObject({
|
|
47
|
+
host: "default-host",
|
|
48
|
+
port: 15432,
|
|
49
|
+
user: "default-user",
|
|
50
|
+
password: "default-password",
|
|
51
|
+
database: "miomock_development",
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("derives database names from projectName even when defaultOptions.connection.database is set", () => {
|
|
56
|
+
const dbConfig = new DBClass().generateDBConfig(
|
|
57
|
+
{
|
|
58
|
+
database: "pg",
|
|
59
|
+
defaultOptions: {
|
|
60
|
+
connection: {
|
|
61
|
+
database: "legacy_database",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
"Miomock",
|
|
66
|
+
emptySnapshots,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(dbConfig.development!.connection).toMatchObject({
|
|
70
|
+
database: "miomock_development",
|
|
71
|
+
});
|
|
72
|
+
expect(dbConfig.production!.connection).toMatchObject({
|
|
73
|
+
database: "miomock_production",
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("fails fast when legacy database.name or database.environments keys are present", () => {
|
|
78
|
+
const legacyConfig = {
|
|
79
|
+
database: "pg",
|
|
80
|
+
name: "miomock",
|
|
81
|
+
environments: {
|
|
82
|
+
production: {},
|
|
83
|
+
},
|
|
84
|
+
} as Parameters<DBClass["generateDBConfig"]>[0];
|
|
85
|
+
|
|
86
|
+
expect(() => new DBClass().generateDBConfig(legacyConfig, "Miomock")).toThrow(
|
|
87
|
+
/database\.name and database\.environments were removed/,
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("lets readonly env vars override only the readonly connection fields", () => {
|
|
92
|
+
process.env.SONAMU_DB_HOST = "writer-host";
|
|
93
|
+
process.env.SONAMU_DB_USER = "writer-user";
|
|
94
|
+
process.env.SONAMU_DB_PASSWORD = "writer-password";
|
|
95
|
+
process.env.SONAMU_DB_READONLY_HOST = "readonly-host";
|
|
96
|
+
|
|
97
|
+
const dbConfig = new DBClass().generateDBConfig(
|
|
98
|
+
{
|
|
99
|
+
database: "pg",
|
|
100
|
+
defaultOptions: {
|
|
101
|
+
connection: {
|
|
102
|
+
port: 15432,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
"Miomock",
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
expect(dbConfig.development_readonly!.connection).toMatchObject({
|
|
110
|
+
host: "readonly-host",
|
|
111
|
+
port: 15432,
|
|
112
|
+
user: "writer-user",
|
|
113
|
+
password: "writer-password",
|
|
114
|
+
database: "miomock_development",
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("does not let current process connection values leak into other environment snapshots", () => {
|
|
119
|
+
const dbConfig = new DBClass().generateDBConfig(
|
|
120
|
+
{
|
|
121
|
+
database: "pg",
|
|
122
|
+
defaultOptions: {
|
|
123
|
+
connection: {
|
|
124
|
+
host: "development-host",
|
|
125
|
+
port: 15432,
|
|
126
|
+
user: "development-user",
|
|
127
|
+
password: "development-password",
|
|
128
|
+
ssl: true,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
"Miomock",
|
|
133
|
+
{
|
|
134
|
+
...emptySnapshots,
|
|
135
|
+
staging: {
|
|
136
|
+
SONAMU_DB_HOST: "staging-host",
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
expect(dbConfig.staging!.connection).toMatchObject({
|
|
142
|
+
host: "staging-host",
|
|
143
|
+
port: 5432,
|
|
144
|
+
user: "postgres",
|
|
145
|
+
database: "miomock_staging",
|
|
146
|
+
ssl: true,
|
|
147
|
+
});
|
|
148
|
+
expect(dbConfig.staging!.connection).not.toMatchObject({
|
|
149
|
+
password: "development-password",
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("does not reuse SONAMU_DB_NAME as the fixture database name", () => {
|
|
154
|
+
const dbConfig = new DBClass().generateDBConfig(
|
|
155
|
+
{
|
|
156
|
+
database: "pg",
|
|
157
|
+
defaultOptions: {},
|
|
158
|
+
},
|
|
159
|
+
"Miomock",
|
|
160
|
+
{
|
|
161
|
+
...emptySnapshots,
|
|
162
|
+
test: {
|
|
163
|
+
SONAMU_DB_NAME: "miomock_test",
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
expect(dbConfig.test!.connection).toMatchObject({
|
|
169
|
+
database: "miomock_test",
|
|
170
|
+
});
|
|
171
|
+
expect(dbConfig.fixture!.connection).toMatchObject({
|
|
172
|
+
database: "miomock_fixture",
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
});
|