@koalarx/nest 4.0.2 → 4.0.5
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/cli/commands/new/index.js +5 -1
- package/cli/constants/cli-project-checklist.js +8 -1
- package/cli/utils/install-workspace-config.js +79 -0
- package/cli/utils/patch-infra-module.js +68 -48
- package/koala-nest/.vscode/extensions.json +7 -0
- package/koala-nest/.vscode/launch.json +16 -0
- package/koala-nest/.vscode/settings.json +77 -0
- package/koala-nest/.vscode/tasks.json +37 -0
- package/koala-nest/src/infra/services/database.indicator.service.ts +21 -4
- package/package.json +1 -1
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
resolveProjectFeatures
|
|
27
27
|
} from "../../utils/install-module.js";
|
|
28
28
|
import { fixLintConfig } from "./fix-lint-config.js";
|
|
29
|
+
import { finalizeNewProjectSetup } from "../../utils/install-workspace-config.js";
|
|
29
30
|
async function promptAuthStrategies(template) {
|
|
30
31
|
const isCrud = template === Template.CRUD_SAMPLE;
|
|
31
32
|
return assertNotCancel(await p.multiselect({
|
|
@@ -180,6 +181,8 @@ export async function runNew(args = []) {
|
|
|
180
181
|
auth: authStrategies,
|
|
181
182
|
features
|
|
182
183
|
});
|
|
184
|
+
spinner.message("Configurando workspace (.vscode e .env)...");
|
|
185
|
+
finalizeNewProjectSetup(project.name, project.packageManager);
|
|
183
186
|
spinner.stop("Projeto criado com sucesso!");
|
|
184
187
|
const projectFeatures = resolveProjectFeatures(features, authStrategies);
|
|
185
188
|
const extrasSummary = [
|
|
@@ -196,7 +199,8 @@ export async function runNew(args = []) {
|
|
|
196
199
|
`${color.bold("Gerenciador:")} ${project.packageManager}`,
|
|
197
200
|
`${color.bold("Autenticação:")} ${formatAuthStrategies(authStrategies)}`,
|
|
198
201
|
`${color.bold("Extras:")} ${extrasSummary || color.dim("nenhum")}`,
|
|
199
|
-
`${color.dim("Depois:")} cd ${project.name} &&
|
|
202
|
+
`${color.dim("Depois:")} cd ${project.name} && ${project.packageManager} start`,
|
|
203
|
+
`${color.dim("Extras:")} kl-nest add <feature>`
|
|
200
204
|
].join(`
|
|
201
205
|
`), "Resumo");
|
|
202
206
|
}
|
|
@@ -5,6 +5,13 @@ import {
|
|
|
5
5
|
resolveNewProjectOptions
|
|
6
6
|
} from "./domain.js";
|
|
7
7
|
import { resolveProjectFeatures } from "../utils/install-module.js";
|
|
8
|
+
export const WORKSPACE_SETUP_PATHS = [
|
|
9
|
+
".vscode/launch.json",
|
|
10
|
+
".vscode/settings.json",
|
|
11
|
+
".vscode/tasks.json",
|
|
12
|
+
".vscode/extensions.json",
|
|
13
|
+
".env"
|
|
14
|
+
];
|
|
8
15
|
export const CORE_REQUIRED_PATHS = [
|
|
9
16
|
"src/core/env.ts",
|
|
10
17
|
"src/host/main.ts",
|
|
@@ -165,7 +172,7 @@ export function buildProjectExpectation(template, auth, features) {
|
|
|
165
172
|
};
|
|
166
173
|
}
|
|
167
174
|
export function requiredPathsForExpectation(expectation) {
|
|
168
|
-
const paths = [...CORE_REQUIRED_PATHS];
|
|
175
|
+
const paths = [...CORE_REQUIRED_PATHS, ...WORKSPACE_SETUP_PATHS];
|
|
169
176
|
if (expectation.template === Template.CRUD_SAMPLE) {
|
|
170
177
|
paths.push(...CRUD_TEMPLATE_REQUIRED_PATHS);
|
|
171
178
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { cpSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getSourceCodePath } from "./get-source-code-path.js";
|
|
4
|
+
import { resolveProjectPath } from "./resolve-project-path.js";
|
|
5
|
+
const PACKAGE_MANAGER_COMMAND = {
|
|
6
|
+
bun: "bun",
|
|
7
|
+
npm: "npm",
|
|
8
|
+
pnpm: "pnpm"
|
|
9
|
+
};
|
|
10
|
+
export function projectNameToSnakeCase(projectName) {
|
|
11
|
+
const baseName = path.isAbsolute(projectName) ? path.basename(projectName) : projectName;
|
|
12
|
+
return baseName.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").replace(/__+/g, "_").toLowerCase().replace(/^_+|_+$/g, "");
|
|
13
|
+
}
|
|
14
|
+
function patchDatabaseUrl(content, databaseName) {
|
|
15
|
+
if (!/^DATABASE_URL=/m.test(content)) {
|
|
16
|
+
return content;
|
|
17
|
+
}
|
|
18
|
+
return content.replace(/^(DATABASE_URL=.+\/)([^/\r\n]+)(\s*)$/m, `$1${databaseName}$3`);
|
|
19
|
+
}
|
|
20
|
+
function patchJsonFile(filePath, patch) {
|
|
21
|
+
const content = readFileSync(filePath, "utf8");
|
|
22
|
+
const json = JSON.parse(content);
|
|
23
|
+
patch(json);
|
|
24
|
+
writeFileSync(filePath, `${JSON.stringify(json, null, 2)}
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
function runScriptCommand(packageManager, script) {
|
|
28
|
+
return `${PACKAGE_MANAGER_COMMAND[packageManager]} run ${script}`;
|
|
29
|
+
}
|
|
30
|
+
export function installWorkspaceConfig(projectName, packageManager) {
|
|
31
|
+
const projectRoot = resolveProjectPath(projectName);
|
|
32
|
+
const sourceVscode = path.join(getSourceCodePath(), ".vscode");
|
|
33
|
+
const targetVscode = path.join(projectRoot, ".vscode");
|
|
34
|
+
cpSync(sourceVscode, targetVscode, { recursive: true });
|
|
35
|
+
const pmCommand = PACKAGE_MANAGER_COMMAND[packageManager];
|
|
36
|
+
patchJsonFile(path.join(targetVscode, "launch.json"), (launch) => {
|
|
37
|
+
const config = launch.configurations[0];
|
|
38
|
+
config.runtimeExecutable = pmCommand;
|
|
39
|
+
config.runtimeArgs = ["run", "start:debug"];
|
|
40
|
+
config.cwd = "${workspaceFolder}";
|
|
41
|
+
});
|
|
42
|
+
patchJsonFile(path.join(targetVscode, "tasks.json"), (tasks) => {
|
|
43
|
+
for (const task of tasks.tasks) {
|
|
44
|
+
if (task.command.includes("start:dev")) {
|
|
45
|
+
task.command = runScriptCommand(packageManager, "start:dev");
|
|
46
|
+
} else if (task.command.includes("test")) {
|
|
47
|
+
task.command = runScriptCommand(packageManager, "test");
|
|
48
|
+
} else if (task.command.includes("migration:run")) {
|
|
49
|
+
task.command = runScriptCommand(packageManager, "migration:run");
|
|
50
|
+
}
|
|
51
|
+
task.options = { cwd: "${workspaceFolder}" };
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
patchJsonFile(path.join(targetVscode, "settings.json"), (settings) => {
|
|
55
|
+
settings["npm.packageManager"] = packageManager;
|
|
56
|
+
});
|
|
57
|
+
const gitignoreSource = path.join(getSourceCodePath(), ".gitignore");
|
|
58
|
+
if (existsSync(gitignoreSource)) {
|
|
59
|
+
cpSync(gitignoreSource, path.join(projectRoot, ".gitignore"), {
|
|
60
|
+
force: true
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function createEnvFromExample(projectName) {
|
|
65
|
+
const projectRoot = resolveProjectPath(projectName);
|
|
66
|
+
const examplePath = path.join(projectRoot, ".env.example");
|
|
67
|
+
const envPath = path.join(projectRoot, ".env");
|
|
68
|
+
if (!existsSync(examplePath)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const databaseName = projectNameToSnakeCase(projectName);
|
|
72
|
+
const envContent = patchDatabaseUrl(readFileSync(examplePath, "utf8"), databaseName);
|
|
73
|
+
writeFileSync(examplePath, envContent);
|
|
74
|
+
writeFileSync(envPath, envContent);
|
|
75
|
+
}
|
|
76
|
+
export function finalizeNewProjectSetup(projectName, packageManager) {
|
|
77
|
+
installWorkspaceConfig(projectName, packageManager);
|
|
78
|
+
createEnvFromExample(projectName);
|
|
79
|
+
}
|
|
@@ -1,61 +1,81 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
let patched = content.replace("import { ILoggingService } from '@/domain/common/ilogging.service';", `import { ICacheService } from '@/domain/common/icache.service';
|
|
7
|
-
import { ILoggingService } from '@/domain/common/ilogging.service';
|
|
8
|
-
import { IRedLockService } from '@/domain/common/ired-lock.service';`).replace("import { LoggingService } from '@/infra/common/logging.service';", `import { CacheServiceProvider } from '@/infra/common/cache-service.provider';
|
|
9
|
-
import { LoggingService } from '@/infra/common/logging.service';
|
|
10
|
-
import { RedLockService } from '@/infra/common/red-lock.service';`).replace(` providers: [
|
|
11
|
-
{ provide: ILoggingService, useClass: LoggingService },`, ` providers: [
|
|
12
|
-
CacheServiceProvider,
|
|
13
|
-
{ provide: ICacheService, useExisting: CacheServiceProvider },
|
|
14
|
-
{ provide: ILoggingService, useClass: LoggingService },
|
|
15
|
-
{ provide: IRedLockService, useClass: RedLockService },`);
|
|
16
|
-
if (withAuth) {
|
|
17
|
-
return patched.replace(" exports: [RepositoryModule, ILoggingService, ILoggedUserInfoService],", ` exports: [
|
|
18
|
-
RepositoryModule,
|
|
19
|
-
ICacheService,
|
|
20
|
-
ILoggingService,
|
|
21
|
-
IRedLockService,
|
|
22
|
-
ILoggedUserInfoService,
|
|
23
|
-
],`);
|
|
24
|
-
}
|
|
25
|
-
return patched.replace(" exports: [RepositoryModule, ILoggingService],", ` exports: [
|
|
26
|
-
RepositoryModule,
|
|
27
|
-
ICacheService,
|
|
28
|
-
ILoggingService,
|
|
29
|
-
IRedLockService,
|
|
30
|
-
],`);
|
|
1
|
+
function hasCacheProviders(content) {
|
|
2
|
+
return content.includes("{ provide: ICacheService, useExisting: CacheServiceProvider }");
|
|
3
|
+
}
|
|
4
|
+
function hasAuthProviders(content) {
|
|
5
|
+
return content.includes("{ provide: ILoggedUserInfoService, useClass: LoggedUserInfoService }");
|
|
31
6
|
}
|
|
32
|
-
export
|
|
33
|
-
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
7
|
+
export function buildInfraModule({ cache, auth }) {
|
|
8
|
+
const importLines = [
|
|
9
|
+
...cache ? ["import { ICacheService } from '@/domain/common/icache.service';"] : [],
|
|
10
|
+
"import { ILoggingService } from '@/domain/common/ilogging.service';",
|
|
11
|
+
...auth ? [
|
|
12
|
+
"import { ILoggedUserInfoService } from '@/domain/services/ilogged-user-info.service';"
|
|
13
|
+
] : [],
|
|
14
|
+
...cache ? ["import { IRedLockService } from '@/domain/common/ired-lock.service';"] : [],
|
|
15
|
+
"import { Module } from '@nestjs/common';",
|
|
16
|
+
...cache ? [
|
|
17
|
+
"import { CacheServiceProvider } from '@/infra/common/cache-service.provider';"
|
|
18
|
+
] : [],
|
|
19
|
+
"import { LoggingService } from '@/infra/common/logging.service';",
|
|
20
|
+
...auth ? [
|
|
21
|
+
"import { LoggedUserInfoService } from '@/infra/services/logged-user-info.service';"
|
|
22
|
+
] : [],
|
|
23
|
+
...cache ? ["import { RedLockService } from '@/infra/common/red-lock.service';"] : [],
|
|
24
|
+
"import { RepositoryModule } from '@/infra/repositories/repository.module';"
|
|
25
|
+
];
|
|
26
|
+
const providerLines = [
|
|
27
|
+
...cache ? [
|
|
28
|
+
" CacheServiceProvider,",
|
|
29
|
+
" { provide: ICacheService, useExisting: CacheServiceProvider },"
|
|
30
|
+
] : [],
|
|
31
|
+
" { provide: ILoggingService, useClass: LoggingService },",
|
|
32
|
+
...cache ? [" { provide: IRedLockService, useClass: RedLockService },"] : [],
|
|
33
|
+
...auth ? [
|
|
34
|
+
" { provide: ILoggedUserInfoService, useClass: LoggedUserInfoService },"
|
|
35
|
+
] : []
|
|
36
|
+
];
|
|
37
|
+
const exportLines = [
|
|
38
|
+
" RepositoryModule,",
|
|
39
|
+
...cache ? [" ICacheService,"] : [],
|
|
40
|
+
" ILoggingService,",
|
|
41
|
+
...cache ? [" IRedLockService,"] : [],
|
|
42
|
+
...auth ? [" ILoggedUserInfoService,"] : []
|
|
43
|
+
];
|
|
44
|
+
return `${importLines.join(`
|
|
45
|
+
`)}
|
|
36
46
|
|
|
37
47
|
@Module({
|
|
38
48
|
imports: [RepositoryModule],
|
|
39
|
-
providers: [
|
|
40
|
-
|
|
49
|
+
providers: [
|
|
50
|
+
${providerLines.join(`
|
|
51
|
+
`)}
|
|
52
|
+
],
|
|
53
|
+
exports: [
|
|
54
|
+
${exportLines.join(`
|
|
55
|
+
`)}
|
|
56
|
+
],
|
|
41
57
|
})
|
|
42
58
|
export class InfraModule {}
|
|
43
59
|
`;
|
|
44
|
-
|
|
45
|
-
|
|
60
|
+
}
|
|
61
|
+
export function patchInfraModuleForCache(content) {
|
|
62
|
+
if (hasCacheProviders(content)) {
|
|
46
63
|
return content;
|
|
47
64
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
return buildInfraModule({
|
|
66
|
+
cache: true,
|
|
67
|
+
auth: hasAuthProviders(content) || content.includes("ILoggedUserInfoService")
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
export const SLIM_INFRA_MODULE = buildInfraModule({ cache: false, auth: false });
|
|
71
|
+
export function patchInfraModuleForAuth(content) {
|
|
72
|
+
if (hasAuthProviders(content)) {
|
|
73
|
+
return content;
|
|
57
74
|
}
|
|
58
|
-
return
|
|
75
|
+
return buildInfraModule({
|
|
76
|
+
cache: hasCacheProviders(content) || content.includes("ICacheService"),
|
|
77
|
+
auth: true
|
|
78
|
+
});
|
|
59
79
|
}
|
|
60
80
|
export function stripInfraModuleCache(_content) {
|
|
61
81
|
return SLIM_INFRA_MODULE;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"type": "node",
|
|
6
|
+
"request": "launch",
|
|
7
|
+
"name": "NestJS Debug",
|
|
8
|
+
"runtimeExecutable": "bun",
|
|
9
|
+
"runtimeArgs": ["run", "start:debug"],
|
|
10
|
+
"cwd": "${workspaceFolder}",
|
|
11
|
+
"autoAttachChildProcesses": true,
|
|
12
|
+
"restart": true,
|
|
13
|
+
"console": "integratedTerminal"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"material-icon-theme.activeIconPack": "nest",
|
|
3
|
+
"editor.fontFamily": "Fira Code",
|
|
4
|
+
"editor.fontSize": 15,
|
|
5
|
+
"editor.fontLigatures": true,
|
|
6
|
+
"workbench.startupEditor": "newUntitledFile",
|
|
7
|
+
"js/ts.suggest.autoImports": true,
|
|
8
|
+
"js/ts.updateImportsOnFileMove.enabled": "always",
|
|
9
|
+
"editor.rulers": [80, 120],
|
|
10
|
+
"extensions.ignoreRecommendations": true,
|
|
11
|
+
"files.associations": {
|
|
12
|
+
".env.*": "dotenv",
|
|
13
|
+
".prettierrc": "json"
|
|
14
|
+
},
|
|
15
|
+
"editor.parameterHints.enabled": false,
|
|
16
|
+
"editor.renderLineHighlight": "gutter",
|
|
17
|
+
"editor.lineHeight": 26,
|
|
18
|
+
"editor.suggestSelection": "first",
|
|
19
|
+
"explorer.confirmDelete": false,
|
|
20
|
+
"workbench.editor.labelFormat": "short",
|
|
21
|
+
"editor.acceptSuggestionOnCommitCharacter": false,
|
|
22
|
+
"explorer.compactFolders": false,
|
|
23
|
+
"git.enableSmartCommit": true,
|
|
24
|
+
"explorer.confirmDragAndDrop": false,
|
|
25
|
+
"terminal.integrated.fontSize": 14,
|
|
26
|
+
"breadcrumbs.enabled": true,
|
|
27
|
+
"editor.tabSize": 2,
|
|
28
|
+
"workbench.iconTheme": "material-icon-theme",
|
|
29
|
+
"material-icon-theme.languages.associations": {
|
|
30
|
+
"dotenv": "tune"
|
|
31
|
+
},
|
|
32
|
+
"material-icon-theme.files.associations": {
|
|
33
|
+
"*.e2e-spec.ts": "test-js",
|
|
34
|
+
"*.dto.ts": "diff",
|
|
35
|
+
"*.handler.ts": "esbuild",
|
|
36
|
+
"*.request.ts": "log",
|
|
37
|
+
"*.schema.ts": "scheme",
|
|
38
|
+
"*.response.ts": "conduct",
|
|
39
|
+
"*.validator.ts": "commitlint"
|
|
40
|
+
},
|
|
41
|
+
"material-icon-theme.folders.associations": {
|
|
42
|
+
"entities": "class",
|
|
43
|
+
"migrations": "tools",
|
|
44
|
+
"schemas": "class",
|
|
45
|
+
"domain": "class",
|
|
46
|
+
"infra": "app",
|
|
47
|
+
"dtos": "typescript",
|
|
48
|
+
"repositories": "mappings"
|
|
49
|
+
},
|
|
50
|
+
"[javascript]": {
|
|
51
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
52
|
+
"editor.formatOnSave": true,
|
|
53
|
+
"editor.codeActionsOnSave": {
|
|
54
|
+
"source.fixAll.eslint": "explicit"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"[typescript]": {
|
|
58
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
59
|
+
"editor.formatOnSave": true,
|
|
60
|
+
"editor.codeActionsOnSave": {
|
|
61
|
+
"source.fixAll.eslint": "explicit"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"prettier.documentSelectors": ["**/*.ts", "**/*.tsx", "**/*.js"],
|
|
65
|
+
"npm.scriptExplorerAction": "run",
|
|
66
|
+
"npm.packageManager": "bun",
|
|
67
|
+
"editor.wordWrap": "on",
|
|
68
|
+
"editor.wrappingIndent": "indent",
|
|
69
|
+
"eslint.workingDirectories": [{ "mode": "auto" }],
|
|
70
|
+
"eslint.validate": [
|
|
71
|
+
"javascript",
|
|
72
|
+
"javascriptreact",
|
|
73
|
+
"typescript",
|
|
74
|
+
"typescriptreact"
|
|
75
|
+
],
|
|
76
|
+
"files.eol": "\n"
|
|
77
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"tasks": [
|
|
4
|
+
{
|
|
5
|
+
"type": "shell",
|
|
6
|
+
"command": "bun run start:dev",
|
|
7
|
+
"options": {
|
|
8
|
+
"cwd": "${workspaceFolder}"
|
|
9
|
+
},
|
|
10
|
+
"group": {
|
|
11
|
+
"kind": "build",
|
|
12
|
+
"isDefault": true
|
|
13
|
+
},
|
|
14
|
+
"isBackground": true,
|
|
15
|
+
"problemMatcher": [],
|
|
16
|
+
"label": "Start API (dev)",
|
|
17
|
+
"detail": "nest start --watch"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "shell",
|
|
21
|
+
"command": "bun run test",
|
|
22
|
+
"options": {
|
|
23
|
+
"cwd": "${workspaceFolder}"
|
|
24
|
+
},
|
|
25
|
+
"group": "test",
|
|
26
|
+
"label": "Run tests"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "shell",
|
|
30
|
+
"command": "bun run migration:run",
|
|
31
|
+
"options": {
|
|
32
|
+
"cwd": "${workspaceFolder}"
|
|
33
|
+
},
|
|
34
|
+
"label": "Run migrations"
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
import { DATA_SOURCE_PROVIDER_TOKEN } from '@/infra/database/data-source-factory';
|
|
2
2
|
import { Inject, Injectable } from '@nestjs/common';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
HealthIndicatorResult,
|
|
5
|
+
HealthIndicatorService,
|
|
6
|
+
} from '@nestjs/terminus';
|
|
4
7
|
import { DataSource } from 'typeorm';
|
|
5
8
|
|
|
6
9
|
@Injectable()
|
|
7
10
|
export class DatabaseIndicator {
|
|
8
11
|
constructor(
|
|
9
|
-
private readonly
|
|
12
|
+
private readonly healthIndicatorService: HealthIndicatorService,
|
|
10
13
|
@Inject(DATA_SOURCE_PROVIDER_TOKEN)
|
|
11
14
|
private readonly dataSource: DataSource,
|
|
12
15
|
) {}
|
|
13
16
|
|
|
14
|
-
isHealthy() {
|
|
15
|
-
|
|
17
|
+
async isHealthy(): Promise<HealthIndicatorResult> {
|
|
18
|
+
const indicator = this.healthIndicatorService.check('db');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
if (!this.dataSource.isInitialized) {
|
|
22
|
+
return indicator.down({ message: 'DataSource not initialized' });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
await this.dataSource.query('SELECT 1');
|
|
26
|
+
|
|
27
|
+
return indicator.up();
|
|
28
|
+
} catch (error) {
|
|
29
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30
|
+
|
|
31
|
+
return indicator.down({ message });
|
|
32
|
+
}
|
|
16
33
|
}
|
|
17
34
|
}
|