@lon-ask/dockit 0.1.1 → 0.1.2
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/README.md +482 -337
- package/SKILL.md +94 -103
- package/apps/client/index.html +12 -0
- package/apps/client/package.json +26 -0
- package/apps/client/src/App.tsx +18 -0
- package/apps/client/src/api/client.ts +54 -0
- package/apps/client/src/components/BuildPanel.tsx +77 -0
- package/apps/client/src/components/DocViewer.tsx +76 -0
- package/apps/client/src/components/EntryDetail.tsx +322 -0
- package/apps/client/src/components/EntryForm.tsx +117 -0
- package/apps/client/src/components/EntryList.tsx +165 -0
- package/apps/client/src/components/GlobalSearchBar.tsx +166 -0
- package/apps/client/src/components/Layout.tsx +57 -0
- package/apps/client/src/components/SearchBar.tsx +103 -0
- package/apps/client/src/components/SourceForm.tsx +497 -0
- package/apps/client/src/hooks/useTheme.ts +19 -0
- package/apps/client/src/index.css +77 -0
- package/apps/client/src/main.tsx +13 -0
- package/apps/client/src/types.ts +105 -0
- package/apps/client/vite.config.ts +13 -0
- package/apps/server/dist/core/domain/entry.js +20 -0
- package/apps/server/dist/core/domain/entry.js.map +1 -0
- package/apps/server/dist/core/domain/errors.js +33 -0
- package/apps/server/dist/core/domain/errors.js.map +1 -0
- package/apps/server/dist/core/domain/knowledge-graph.js +2 -0
- package/apps/server/dist/core/domain/knowledge-graph.js.map +1 -0
- package/apps/server/dist/core/domain/types.js +2 -0
- package/apps/server/dist/core/domain/types.js.map +1 -0
- package/apps/server/dist/core/ports/IBuildRepository.js +2 -0
- package/apps/server/dist/core/ports/IBuildRepository.js.map +1 -0
- package/apps/server/dist/core/ports/IDocumentNormalizer.js +2 -0
- package/apps/server/dist/core/ports/IDocumentNormalizer.js.map +1 -0
- package/apps/server/dist/core/ports/IDocumentStore.js +2 -0
- package/apps/server/dist/core/ports/IDocumentStore.js.map +1 -0
- package/apps/server/dist/core/ports/IEntryReadModel.js +2 -0
- package/apps/server/dist/core/ports/IEntryReadModel.js.map +1 -0
- package/apps/server/dist/core/ports/IEntryRepository.js +2 -0
- package/apps/server/dist/core/ports/IEntryRepository.js.map +1 -0
- package/apps/server/dist/core/ports/IKnowledgeGraph.js +2 -0
- package/apps/server/dist/core/ports/IKnowledgeGraph.js.map +1 -0
- package/apps/server/dist/core/ports/IPathResolver.js +2 -0
- package/apps/server/dist/core/ports/IPathResolver.js.map +1 -0
- package/apps/server/dist/core/ports/ISearchEngine.js +2 -0
- package/apps/server/dist/core/ports/ISearchEngine.js.map +1 -0
- package/apps/server/dist/core/ports/ISourceProcessor.js +2 -0
- package/apps/server/dist/core/ports/ISourceProcessor.js.map +1 -0
- package/apps/server/dist/core/ports/ISourceRepository.js +2 -0
- package/apps/server/dist/core/ports/ISourceRepository.js.map +1 -0
- package/apps/server/dist/core/usecases/BuildUseCase.js +76 -0
- package/apps/server/dist/core/usecases/BuildUseCase.js.map +1 -0
- package/apps/server/dist/core/usecases/ConfigUseCase.js +62 -0
- package/apps/server/dist/core/usecases/ConfigUseCase.js.map +1 -0
- package/apps/server/dist/core/usecases/SearchUseCase.js +17 -0
- package/apps/server/dist/core/usecases/SearchUseCase.js.map +1 -0
- package/apps/server/dist/index.js +86 -0
- package/apps/server/dist/index.js.map +1 -0
- package/apps/server/dist/infrastructure/filesystem/FileSystemDocumentStore.js +25 -0
- package/apps/server/dist/infrastructure/filesystem/FileSystemDocumentStore.js.map +1 -0
- package/apps/server/dist/infrastructure/graph/GraphSearchDecorator.js +42 -0
- package/apps/server/dist/infrastructure/graph/GraphSearchDecorator.js.map +1 -0
- package/apps/server/dist/infrastructure/graph/GraphifyKnowledgeGraph.js +145 -0
- package/apps/server/dist/infrastructure/graph/GraphifyKnowledgeGraph.js.map +1 -0
- package/apps/server/dist/infrastructure/graph/index.js +3 -0
- package/apps/server/dist/infrastructure/graph/index.js.map +1 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteBuildRepository.js +21 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteBuildRepository.js.map +1 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryReadModel.js +11 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryReadModel.js.map +1 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryRepository.js +59 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryRepository.js.map +1 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteSourceRepository.js +47 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/SqliteSourceRepository.js.map +1 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/connection.js +50 -0
- package/apps/server/dist/infrastructure/persistence/sqlite/connection.js.map +1 -0
- package/apps/server/dist/infrastructure/search/SearchEngineFactory.js +32 -0
- package/apps/server/dist/infrastructure/search/SearchEngineFactory.js.map +1 -0
- package/apps/server/dist/infrastructure/search/json/JsonSearchEngine.js +147 -0
- package/apps/server/dist/infrastructure/search/json/JsonSearchEngine.js.map +1 -0
- package/apps/server/dist/infrastructure/search/vector/EmbeddingService.js +23 -0
- package/apps/server/dist/infrastructure/search/vector/EmbeddingService.js.map +1 -0
- package/apps/server/dist/infrastructure/search/vector/VectorSearchEngine.js +378 -0
- package/apps/server/dist/infrastructure/search/vector/VectorSearchEngine.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/AntoraSourceProcessor.js +11 -0
- package/apps/server/dist/infrastructure/source-processors/AntoraSourceProcessor.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/AsciidocSourceProcessor.js +9 -0
- package/apps/server/dist/infrastructure/source-processors/AsciidocSourceProcessor.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/DocumentNormalizer.js +11 -0
- package/apps/server/dist/infrastructure/source-processors/DocumentNormalizer.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/GithubMarkdownSourceProcessor.js +9 -0
- package/apps/server/dist/infrastructure/source-processors/GithubMarkdownSourceProcessor.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/MavenSourceProcessor.js +9 -0
- package/apps/server/dist/infrastructure/source-processors/MavenSourceProcessor.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/PathResolver.js +5 -0
- package/apps/server/dist/infrastructure/source-processors/PathResolver.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/SourceCodeSourceProcessor.js +261 -0
- package/apps/server/dist/infrastructure/source-processors/SourceCodeSourceProcessor.js.map +1 -0
- package/apps/server/dist/infrastructure/source-processors/ZipSourceProcessor.js +9 -0
- package/apps/server/dist/infrastructure/source-processors/ZipSourceProcessor.js.map +1 -0
- package/apps/server/dist/mcp-http.js +93 -0
- package/apps/server/dist/mcp-http.js.map +1 -0
- package/apps/server/dist/mcp.js +339 -0
- package/apps/server/dist/mcp.js.map +1 -0
- package/apps/server/dist/routes/build.js +89 -0
- package/apps/server/dist/routes/build.js.map +1 -0
- package/apps/server/dist/routes/entries.js +52 -0
- package/apps/server/dist/routes/entries.js.map +1 -0
- package/apps/server/dist/routes/graph.js +58 -0
- package/apps/server/dist/routes/graph.js.map +1 -0
- package/apps/server/dist/routes/search.js +24 -0
- package/apps/server/dist/routes/search.js.map +1 -0
- package/apps/server/dist/routes/sources.js +100 -0
- package/apps/server/dist/routes/sources.js.map +1 -0
- package/apps/server/dist/routes/viewer.js +22 -0
- package/apps/server/dist/routes/viewer.js.map +1 -0
- package/apps/server/dist/services/antora.js +222 -0
- package/apps/server/dist/services/antora.js.map +1 -0
- package/apps/server/dist/services/asciidoc.js +206 -0
- package/apps/server/dist/services/asciidoc.js.map +1 -0
- package/apps/server/dist/services/configLoader.js +150 -0
- package/apps/server/dist/services/configLoader.js.map +1 -0
- package/apps/server/dist/services/githubMarkdown.js +221 -0
- package/apps/server/dist/services/githubMarkdown.js.map +1 -0
- package/apps/server/dist/services/maven.js +148 -0
- package/apps/server/dist/services/maven.js.map +1 -0
- package/apps/server/dist/services/normalizer.js +42 -0
- package/apps/server/dist/services/normalizer.js.map +1 -0
- package/apps/server/dist/services/paths.js +5 -0
- package/apps/server/dist/services/paths.js.map +1 -0
- package/apps/server/dist/services/textExtractor.js +46 -0
- package/apps/server/dist/services/textExtractor.js.map +1 -0
- package/apps/server/dist/services/zip.js +63 -0
- package/apps/server/dist/services/zip.js.map +1 -0
- package/apps/server/package.json +38 -0
- package/bin/commands/dev.ts +2 -2
- package/bin/commands/serve.ts +2 -2
- package/package.json +17 -3
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type EntryStatus = 'pending' | 'building' | 'ready' | 'error';
|
|
2
|
+
export type SourceType = 'zip' | 'antora' | 'maven' | 'asciidoc' | 'github-markdown' | 'source-code';
|
|
3
|
+
export type SourceStatus = 'pending' | 'building' | 'ready' | 'error';
|
|
4
|
+
export type BuildStatus = 'pending' | 'building' | 'ready' | 'error';
|
|
5
|
+
|
|
6
|
+
export interface Entry {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
version: string;
|
|
10
|
+
description: string;
|
|
11
|
+
status: EntryStatus;
|
|
12
|
+
source_count?: number;
|
|
13
|
+
created_at: string;
|
|
14
|
+
updated_at: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface Source {
|
|
18
|
+
id: string;
|
|
19
|
+
entry_id: string;
|
|
20
|
+
type: SourceType;
|
|
21
|
+
label: string;
|
|
22
|
+
config: SourceConfig;
|
|
23
|
+
status: SourceStatus;
|
|
24
|
+
created_at: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ZipSourceConfig {
|
|
28
|
+
url?: string;
|
|
29
|
+
localPath?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface AntoraSourceConfig {
|
|
33
|
+
repoUrl?: string;
|
|
34
|
+
zipPath?: string;
|
|
35
|
+
localPath?: string;
|
|
36
|
+
playbookOverrides?: Record<string, unknown>;
|
|
37
|
+
graphifyEnabled?: boolean;
|
|
38
|
+
graphifySourcePath?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface MavenSourceConfig {
|
|
42
|
+
groupId: string;
|
|
43
|
+
artifactId: string;
|
|
44
|
+
version: string;
|
|
45
|
+
classifier?: string;
|
|
46
|
+
useMavenCommand?: boolean;
|
|
47
|
+
localJar?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface AsciidocSourceConfig {
|
|
51
|
+
repoUrl?: string;
|
|
52
|
+
zipPath?: string;
|
|
53
|
+
localPath?: string;
|
|
54
|
+
sourcePath?: string;
|
|
55
|
+
graphifyEnabled?: boolean;
|
|
56
|
+
graphifySourcePath?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface GithubMarkdownSourceConfig {
|
|
60
|
+
repoUrl?: string;
|
|
61
|
+
localPath?: string;
|
|
62
|
+
sourcePath?: string;
|
|
63
|
+
branch?: string;
|
|
64
|
+
graphifyEnabled?: boolean;
|
|
65
|
+
graphifySourcePath?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface SourceCodeSourceConfig {
|
|
69
|
+
repoUrl?: string;
|
|
70
|
+
localPath?: string;
|
|
71
|
+
zipPath?: string;
|
|
72
|
+
sourcePath?: string;
|
|
73
|
+
branch?: string;
|
|
74
|
+
graphifySourcePath?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type SourceConfig = ZipSourceConfig | AntoraSourceConfig | MavenSourceConfig | AsciidocSourceConfig | GithubMarkdownSourceConfig | SourceCodeSourceConfig;
|
|
78
|
+
|
|
79
|
+
export interface Build {
|
|
80
|
+
id: string;
|
|
81
|
+
entry_id: string;
|
|
82
|
+
status: BuildStatus;
|
|
83
|
+
log: string;
|
|
84
|
+
started_at: string;
|
|
85
|
+
finished_at: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface EntryDetail extends Entry {
|
|
89
|
+
sources: Source[];
|
|
90
|
+
latestBuild: Build | null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface SearchResult {
|
|
94
|
+
path: string;
|
|
95
|
+
title: string;
|
|
96
|
+
headings: string[];
|
|
97
|
+
snippet: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface BuildStatusResponse {
|
|
101
|
+
status: 'none' | BuildStatus;
|
|
102
|
+
log: string;
|
|
103
|
+
startedAt: string;
|
|
104
|
+
finishedAt: string;
|
|
105
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import react from '@vitejs/plugin-react';
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [tailwindcss(), react()],
|
|
7
|
+
server: {
|
|
8
|
+
port: 5173,
|
|
9
|
+
proxy: {
|
|
10
|
+
'/api': 'http://localhost:3001',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function canTransitionTo(current, next) {
|
|
2
|
+
const transitions = {
|
|
3
|
+
pending: ['building'],
|
|
4
|
+
building: ['ready', 'error'],
|
|
5
|
+
ready: ['building'],
|
|
6
|
+
error: ['building'],
|
|
7
|
+
};
|
|
8
|
+
return transitions[current]?.includes(next) ?? false;
|
|
9
|
+
}
|
|
10
|
+
export function generateEntryId(name, version) {
|
|
11
|
+
const namePart = name
|
|
12
|
+
.toLowerCase()
|
|
13
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
14
|
+
.replace(/^-+|-+$/g, '');
|
|
15
|
+
const versionPart = version
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[^a-z0-9x]+/g, '');
|
|
18
|
+
return `${namePart}-${versionPart}`;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/core/domain/entry.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,OAAoB,EAAE,IAAiB;IACrE,MAAM,WAAW,GAAuC;QACtD,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAC5B,KAAK,EAAE,CAAC,UAAU,CAAC;QACnB,KAAK,EAAE,CAAC,UAAU,CAAC;KACpB,CAAC;IACF,OAAO,WAAW,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAe;IAC3D,MAAM,QAAQ,GAAG,IAAI;SAClB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,MAAM,WAAW,GAAG,OAAO;SACxB,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC/B,OAAO,GAAG,QAAQ,IAAI,WAAW,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class DomainError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(message, code) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.name = 'DomainError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class NotFoundError extends DomainError {
|
|
10
|
+
constructor(resource, id) {
|
|
11
|
+
super(`${resource} not found: ${id}`, 'NOT_FOUND');
|
|
12
|
+
this.name = 'NotFoundError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class ValidationError extends DomainError {
|
|
16
|
+
field;
|
|
17
|
+
value;
|
|
18
|
+
constructor(message, field, value) {
|
|
19
|
+
super(message, 'VALIDATION_ERROR');
|
|
20
|
+
this.field = field;
|
|
21
|
+
this.value = value;
|
|
22
|
+
this.name = 'ValidationError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class BuildError extends DomainError {
|
|
26
|
+
entryId;
|
|
27
|
+
constructor(message, entryId) {
|
|
28
|
+
super(`Build failed for entry ${entryId}: ${message}`, 'BUILD_ERROR');
|
|
29
|
+
this.entryId = entryId;
|
|
30
|
+
this.name = 'BuildError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/domain/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAY,SAAQ,KAAK;IACS;IAA7C,YAAY,OAAe,EAAkB,IAAY;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,SAAI,GAAJ,IAAI,CAAQ;QAEvD,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,WAAW;IAC5C,YAAY,QAAgB,EAAE,EAAU;QACtC,KAAK,CAAC,GAAG,QAAQ,eAAe,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,WAAW;IACD;IAAgC;IAA7E,YAAY,OAAe,EAAkB,KAAc,EAAkB,KAAe;QAC1F,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QADQ,UAAK,GAAL,KAAK,CAAS;QAAkB,UAAK,GAAL,KAAK,CAAU;QAE1F,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,WAAW;IACI;IAA7C,YAAY,OAAe,EAAkB,OAAe;QAC1D,KAAK,CAAC,0BAA0B,OAAO,KAAK,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;QAD3B,YAAO,GAAP,OAAO,CAAQ;QAE1D,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-graph.js","sourceRoot":"","sources":["../../../src/core/domain/knowledge-graph.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/domain/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IBuildRepository.js","sourceRoot":"","sources":["../../../src/core/ports/IBuildRepository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IDocumentNormalizer.js","sourceRoot":"","sources":["../../../src/core/ports/IDocumentNormalizer.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IDocumentStore.js","sourceRoot":"","sources":["../../../src/core/ports/IDocumentStore.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IEntryReadModel.js","sourceRoot":"","sources":["../../../src/core/ports/IEntryReadModel.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IEntryRepository.js","sourceRoot":"","sources":["../../../src/core/ports/IEntryRepository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IKnowledgeGraph.js","sourceRoot":"","sources":["../../../src/core/ports/IKnowledgeGraph.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IPathResolver.js","sourceRoot":"","sources":["../../../src/core/ports/IPathResolver.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISearchEngine.js","sourceRoot":"","sources":["../../../src/core/ports/ISearchEngine.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISourceProcessor.js","sourceRoot":"","sources":["../../../src/core/ports/ISourceProcessor.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISourceRepository.js","sourceRoot":"","sources":["../../../src/core/ports/ISourceRepository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { BuildError } from '../../core/domain/errors.js';
|
|
3
|
+
export class BuildUseCase {
|
|
4
|
+
buildRepo;
|
|
5
|
+
sourceRepo;
|
|
6
|
+
entryRepo;
|
|
7
|
+
searchEngine;
|
|
8
|
+
processors;
|
|
9
|
+
documentNormalizer;
|
|
10
|
+
pathResolver;
|
|
11
|
+
constructor(buildRepo, sourceRepo, entryRepo, searchEngine, processors, documentNormalizer, pathResolver) {
|
|
12
|
+
this.buildRepo = buildRepo;
|
|
13
|
+
this.sourceRepo = sourceRepo;
|
|
14
|
+
this.entryRepo = entryRepo;
|
|
15
|
+
this.searchEngine = searchEngine;
|
|
16
|
+
this.processors = processors;
|
|
17
|
+
this.documentNormalizer = documentNormalizer;
|
|
18
|
+
this.pathResolver = pathResolver;
|
|
19
|
+
}
|
|
20
|
+
async build(entryId) {
|
|
21
|
+
const sources = await this.sourceRepo.findByEntryId(entryId);
|
|
22
|
+
if (sources.length === 0)
|
|
23
|
+
throw new BuildError('Entry has no sources', entryId);
|
|
24
|
+
await this.entryRepo.updateStatus(entryId, 'building');
|
|
25
|
+
const build = await this.buildRepo.create(entryId);
|
|
26
|
+
const logLines = [];
|
|
27
|
+
const log = (msg) => logLines.push(`[${new Date().toISOString()}] ${msg}`);
|
|
28
|
+
log('Build started');
|
|
29
|
+
const entryDir = path.join(this.pathResolver.dataRoot, entryId);
|
|
30
|
+
const bundleDir = path.join(entryDir, 'bundle');
|
|
31
|
+
try {
|
|
32
|
+
const normalizedSources = [];
|
|
33
|
+
const scProcessor = this.processors.find((p) => p.sourceType === 'source-code');
|
|
34
|
+
for (const source of sources) {
|
|
35
|
+
const sourceDir = path.join(entryDir, 'sources', source.id);
|
|
36
|
+
log(`Processing source [${source.type}]: ${source.label}`);
|
|
37
|
+
await this.sourceRepo.updateStatus(source.id, 'building');
|
|
38
|
+
try {
|
|
39
|
+
const processor = this.processors.find((p) => p.sourceType === source.type);
|
|
40
|
+
if (!processor)
|
|
41
|
+
throw new BuildError(`No processor for source type: ${source.type}`, entryId);
|
|
42
|
+
const outputDir = await processor.process(source, sourceDir, entryDir, entryId, log);
|
|
43
|
+
normalizedSources.push({ label: source.label, dir: outputDir });
|
|
44
|
+
const sourceConfig = source.config;
|
|
45
|
+
if (sourceConfig.graphifyEnabled && scProcessor?.runGraphify) {
|
|
46
|
+
log(` Graphify enabled — generating knowledge graph...`);
|
|
47
|
+
await scProcessor.runGraphify(sourceConfig, entryDir, log);
|
|
48
|
+
}
|
|
49
|
+
await this.sourceRepo.updateStatus(source.id, 'ready');
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
await this.sourceRepo.updateStatus(source.id, 'error');
|
|
53
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
54
|
+
log(` ERROR processing source ${source.label}: ${message}`);
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
log('Normalizing documentation bundle');
|
|
59
|
+
const htmlSources = this.documentNormalizer.filterSources(normalizedSources, sources);
|
|
60
|
+
const htmlFiles = this.documentNormalizer.normalize(htmlSources, bundleDir, log);
|
|
61
|
+
log('Building search index');
|
|
62
|
+
await this.searchEngine.buildIndex(entryId, htmlFiles.map((f) => ({ relativePath: f, fullPath: path.join(bundleDir, f) })), log);
|
|
63
|
+
const fullLog = logLines.join('\n');
|
|
64
|
+
await this.buildRepo.update(build.id, 'ready', fullLog);
|
|
65
|
+
await this.entryRepo.updateStatus(entryId, 'ready');
|
|
66
|
+
return { buildId: build.id, entryId, status: 'ready', log: fullLog };
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const fullLog = logLines.join('\n');
|
|
70
|
+
await this.buildRepo.update(build.id, 'error', fullLog);
|
|
71
|
+
await this.entryRepo.updateStatus(entryId, 'error');
|
|
72
|
+
return { buildId: build.id, entryId, status: 'error', log: fullLog };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=BuildUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildUseCase.js","sourceRoot":"","sources":["../../../src/core/usecases/BuildUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { NotFoundError, ValidationError } from '../domain/errors.js';
|
|
2
|
+
import { generateEntryId } from '../domain/entry.js';
|
|
3
|
+
export class ConfigUseCase {
|
|
4
|
+
entryRepo;
|
|
5
|
+
sourceRepo;
|
|
6
|
+
constructor(entryRepo, sourceRepo) {
|
|
7
|
+
this.entryRepo = entryRepo;
|
|
8
|
+
this.sourceRepo = sourceRepo;
|
|
9
|
+
}
|
|
10
|
+
async listEntries() {
|
|
11
|
+
return this.entryRepo.findAll();
|
|
12
|
+
}
|
|
13
|
+
async getEntry(id) {
|
|
14
|
+
return this.entryRepo.findById(id);
|
|
15
|
+
}
|
|
16
|
+
async getEntryWithSources(id) {
|
|
17
|
+
const entry = await this.entryRepo.findById(id);
|
|
18
|
+
if (!entry)
|
|
19
|
+
return undefined;
|
|
20
|
+
const sources = await this.sourceRepo.findByEntryId(id);
|
|
21
|
+
return { ...entry, sources };
|
|
22
|
+
}
|
|
23
|
+
async createEntry(input) {
|
|
24
|
+
if (!input.name?.trim())
|
|
25
|
+
throw new ValidationError('Entry name is required', 'name', input.name);
|
|
26
|
+
if (!input.version?.trim())
|
|
27
|
+
throw new ValidationError('Entry version is required', 'version', input.version);
|
|
28
|
+
const id = input.id ?? generateEntryId(input.name, input.version);
|
|
29
|
+
return this.entryRepo.create({ ...input, id });
|
|
30
|
+
}
|
|
31
|
+
async updateEntry(id, input) {
|
|
32
|
+
const existing = await this.entryRepo.findById(id);
|
|
33
|
+
if (!existing)
|
|
34
|
+
throw new NotFoundError('Entry', id);
|
|
35
|
+
await this.entryRepo.update(id, input);
|
|
36
|
+
}
|
|
37
|
+
async deleteEntry(id) {
|
|
38
|
+
const existing = await this.entryRepo.findById(id);
|
|
39
|
+
if (!existing)
|
|
40
|
+
throw new NotFoundError('Entry', id);
|
|
41
|
+
await this.entryRepo.delete(id);
|
|
42
|
+
}
|
|
43
|
+
async createSource(entryId, input) {
|
|
44
|
+
const entry = await this.entryRepo.findById(entryId);
|
|
45
|
+
if (!entry)
|
|
46
|
+
throw new NotFoundError('Entry', entryId);
|
|
47
|
+
return this.sourceRepo.create(entryId, input);
|
|
48
|
+
}
|
|
49
|
+
async updateSource(id, input) {
|
|
50
|
+
const existing = await this.sourceRepo.findById(id);
|
|
51
|
+
if (!existing)
|
|
52
|
+
throw new NotFoundError('Source', id);
|
|
53
|
+
await this.sourceRepo.update(id, input);
|
|
54
|
+
}
|
|
55
|
+
async deleteSource(id) {
|
|
56
|
+
const existing = await this.sourceRepo.findById(id);
|
|
57
|
+
if (!existing)
|
|
58
|
+
throw new NotFoundError('Source', id);
|
|
59
|
+
await this.sourceRepo.delete(id);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=ConfigUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigUseCase.js","sourceRoot":"","sources":["../../../src/core/usecases/ConfigUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class SearchUseCase {
|
|
2
|
+
searchEngine;
|
|
3
|
+
constructor(searchEngine) {
|
|
4
|
+
this.searchEngine = searchEngine;
|
|
5
|
+
}
|
|
6
|
+
async searchEntry(entryId, query, limit = 20) {
|
|
7
|
+
if (!query.trim())
|
|
8
|
+
return [];
|
|
9
|
+
return this.searchEngine.search(entryId, query, limit);
|
|
10
|
+
}
|
|
11
|
+
async globalSearch(query, limit = 30) {
|
|
12
|
+
if (!query.trim())
|
|
13
|
+
return [];
|
|
14
|
+
return this.searchEngine.globalSearch(query, limit);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=SearchUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchUseCase.js","sourceRoot":"","sources":["../../../src/core/usecases/SearchUseCase.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,YAA2B;QAA3B,iBAAY,GAAZ,YAAY,CAAe;IAAG,CAAC;IAE5D,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,KAAa,EAAE,KAAK,GAAG,EAAE;QAC1D,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE;QAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;CACF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { getDb } from './infrastructure/persistence/sqlite/connection.js';
|
|
6
|
+
import { SqliteEntryRepository } from './infrastructure/persistence/sqlite/SqliteEntryRepository.js';
|
|
7
|
+
import { SqliteSourceRepository } from './infrastructure/persistence/sqlite/SqliteSourceRepository.js';
|
|
8
|
+
import { SqliteBuildRepository } from './infrastructure/persistence/sqlite/SqliteBuildRepository.js';
|
|
9
|
+
import { createSearchEngine } from './infrastructure/search/SearchEngineFactory.js';
|
|
10
|
+
import { SearchUseCase } from './core/usecases/SearchUseCase.js';
|
|
11
|
+
import { BuildUseCase } from './core/usecases/BuildUseCase.js';
|
|
12
|
+
import { ConfigUseCase } from './core/usecases/ConfigUseCase.js';
|
|
13
|
+
import { NotFoundError, ValidationError } from './core/domain/errors.js';
|
|
14
|
+
import { ZipSourceProcessor } from './infrastructure/source-processors/ZipSourceProcessor.js';
|
|
15
|
+
import { AntoraSourceProcessor } from './infrastructure/source-processors/AntoraSourceProcessor.js';
|
|
16
|
+
import { AsciidocSourceProcessor } from './infrastructure/source-processors/AsciidocSourceProcessor.js';
|
|
17
|
+
import { MavenSourceProcessor } from './infrastructure/source-processors/MavenSourceProcessor.js';
|
|
18
|
+
import { GithubMarkdownSourceProcessor } from './infrastructure/source-processors/GithubMarkdownSourceProcessor.js';
|
|
19
|
+
import { SourceCodeSourceProcessor } from './infrastructure/source-processors/SourceCodeSourceProcessor.js';
|
|
20
|
+
import { DocumentNormalizer } from './infrastructure/source-processors/DocumentNormalizer.js';
|
|
21
|
+
import { PathResolver } from './infrastructure/source-processors/PathResolver.js';
|
|
22
|
+
import { SqliteEntryReadModel } from './infrastructure/persistence/sqlite/SqliteEntryReadModel.js';
|
|
23
|
+
import { createEntryRoutes } from './routes/entries.js';
|
|
24
|
+
import { createSearchRoutes } from './routes/search.js';
|
|
25
|
+
import { createBuildRoutes } from './routes/build.js';
|
|
26
|
+
import { createSourceRoutes, createSourceFlatRoutes } from './routes/sources.js';
|
|
27
|
+
import viewerRoutes from './routes/viewer.js';
|
|
28
|
+
import { createGraphRoutes } from './routes/graph.js';
|
|
29
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
const PORT = process.env.PORT || 3001;
|
|
31
|
+
async function main() {
|
|
32
|
+
const app = express();
|
|
33
|
+
app.use(cors());
|
|
34
|
+
app.use(express.json());
|
|
35
|
+
const db = getDb();
|
|
36
|
+
const entryRepo = new SqliteEntryRepository(db);
|
|
37
|
+
const sourceRepo = new SqliteSourceRepository(db);
|
|
38
|
+
const buildRepo = new SqliteBuildRepository(db);
|
|
39
|
+
const entryReadModel = new SqliteEntryReadModel(db);
|
|
40
|
+
const searchEngine = await createSearchEngine(entryReadModel);
|
|
41
|
+
const configUseCase = new ConfigUseCase(entryRepo, sourceRepo);
|
|
42
|
+
const searchUseCase = new SearchUseCase(searchEngine);
|
|
43
|
+
const processors = [
|
|
44
|
+
new ZipSourceProcessor(),
|
|
45
|
+
new AntoraSourceProcessor(),
|
|
46
|
+
new AsciidocSourceProcessor(),
|
|
47
|
+
new MavenSourceProcessor(),
|
|
48
|
+
new GithubMarkdownSourceProcessor(),
|
|
49
|
+
new SourceCodeSourceProcessor(),
|
|
50
|
+
];
|
|
51
|
+
const documentNormalizer = new DocumentNormalizer();
|
|
52
|
+
const pathResolver = new PathResolver();
|
|
53
|
+
const buildUseCase = new BuildUseCase(buildRepo, sourceRepo, entryRepo, searchEngine, processors, documentNormalizer, pathResolver);
|
|
54
|
+
app.use('/api/entries', createEntryRoutes(configUseCase));
|
|
55
|
+
app.use('/api/entries/:entryId/sources', createSourceRoutes(configUseCase));
|
|
56
|
+
app.use('/api/sources', createSourceFlatRoutes(configUseCase));
|
|
57
|
+
app.use('/api', createBuildRoutes(buildUseCase, configUseCase, buildRepo));
|
|
58
|
+
app.use('/api', createSearchRoutes(searchUseCase));
|
|
59
|
+
app.use('/api', createGraphRoutes(buildRepo, configUseCase));
|
|
60
|
+
app.use('/api', viewerRoutes);
|
|
61
|
+
// Global error handler — catches domain errors thrown by use cases
|
|
62
|
+
app.use((err, _req, res, _next) => {
|
|
63
|
+
if (err instanceof NotFoundError) {
|
|
64
|
+
res.status(404).json({ error: err.message, code: err.code });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (err instanceof ValidationError) {
|
|
68
|
+
const body = { error: err.message, code: err.code };
|
|
69
|
+
if (err.field)
|
|
70
|
+
body.field = err.field;
|
|
71
|
+
res.status(400).json(body);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
console.error('Unhandled error:', err);
|
|
75
|
+
const message = err instanceof Error ? err.message : 'Internal server error';
|
|
76
|
+
res.status(500).json({ error: message });
|
|
77
|
+
});
|
|
78
|
+
app.listen(PORT, () => {
|
|
79
|
+
console.log(`Dockit server running on http://localhost:${PORT}`);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
main().catch((err) => {
|
|
83
|
+
console.error('Failed to start server:', err);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { DATA_ROOT } from '../../services/paths.js';
|
|
4
|
+
export class FileSystemDocumentStore {
|
|
5
|
+
async getDocument(entryId, docPath) {
|
|
6
|
+
const resolved = path.resolve(DATA_ROOT, entryId, 'bundle', docPath);
|
|
7
|
+
const dataRoot = path.resolve(DATA_ROOT);
|
|
8
|
+
if (!resolved.startsWith(dataRoot)) {
|
|
9
|
+
throw new Error('Invalid document path');
|
|
10
|
+
}
|
|
11
|
+
if (!fs.existsSync(resolved)) {
|
|
12
|
+
throw new Error(`Document not found: ${docPath} for entry ${entryId}`);
|
|
13
|
+
}
|
|
14
|
+
return fs.readFileSync(resolved, 'utf-8');
|
|
15
|
+
}
|
|
16
|
+
async documentExists(entryId, docPath) {
|
|
17
|
+
const resolved = path.resolve(DATA_ROOT, entryId, 'bundle', docPath);
|
|
18
|
+
const dataRoot = path.resolve(DATA_ROOT);
|
|
19
|
+
if (!resolved.startsWith(dataRoot)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return fs.existsSync(resolved);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=FileSystemDocumentStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSystemDocumentStore.js","sourceRoot":"","sources":["../../../src/infrastructure/filesystem/FileSystemDocumentStore.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,MAAM,OAAO,uBAAuB;IAClC,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,OAAe;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,cAAc,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe,EAAE,OAAe;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export class GraphSearchDecorator {
|
|
2
|
+
engine;
|
|
3
|
+
knowledgeGraph;
|
|
4
|
+
capability;
|
|
5
|
+
constructor(engine, knowledgeGraph) {
|
|
6
|
+
this.engine = engine;
|
|
7
|
+
this.knowledgeGraph = knowledgeGraph;
|
|
8
|
+
this.capability = engine.capability;
|
|
9
|
+
}
|
|
10
|
+
async buildIndex(entryId, htmlFiles, log) {
|
|
11
|
+
return this.engine.buildIndex(entryId, htmlFiles, log);
|
|
12
|
+
}
|
|
13
|
+
async search(entryId, query, limit = 10) {
|
|
14
|
+
const results = await this.engine.search(entryId, query, limit);
|
|
15
|
+
if (!this.knowledgeGraph.exists() || results.length === 0)
|
|
16
|
+
return results;
|
|
17
|
+
const graphResult = this.knowledgeGraph.query(query);
|
|
18
|
+
if (graphResult.totalNodes === 0)
|
|
19
|
+
return results;
|
|
20
|
+
const graphNames = new Set(graphResult.nodes.map((n) => n.name.toLowerCase()));
|
|
21
|
+
const scored = results.map((r) => {
|
|
22
|
+
let boost = 0;
|
|
23
|
+
const titleWords = r.title.toLowerCase().split(/\s+/);
|
|
24
|
+
const snippetWords = r.snippet.toLowerCase().split(/\s+/);
|
|
25
|
+
for (const word of titleWords) {
|
|
26
|
+
if (graphNames.has(word))
|
|
27
|
+
boost += 0.3;
|
|
28
|
+
}
|
|
29
|
+
for (const word of snippetWords) {
|
|
30
|
+
if (graphNames.has(word))
|
|
31
|
+
boost += 0.1;
|
|
32
|
+
}
|
|
33
|
+
return { ...r, _score: boost };
|
|
34
|
+
});
|
|
35
|
+
scored.sort((a, b) => (b._score || 0) - (a._score || 0));
|
|
36
|
+
return scored.slice(0, limit);
|
|
37
|
+
}
|
|
38
|
+
async globalSearch(query, limit = 20) {
|
|
39
|
+
return this.engine.globalSearch(query, limit);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=GraphSearchDecorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphSearchDecorator.js","sourceRoot":"","sources":["../../../src/infrastructure/graph/GraphSearchDecorator.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,oBAAoB;IAIZ;IACA;IAJV,UAAU,CAAmB;IAEtC,YACmB,MAAqB,EACrB,cAA+B;QAD/B,WAAM,GAAN,MAAM,CAAe;QACrB,mBAAc,GAAd,cAAc,CAAiB;QAEhD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,SAAqB,EAAE,GAA0B;QACjF,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,KAAa,EAAE,KAAK,GAAG,EAAE;QACrD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAChE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAE1E,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,WAAW,CAAC,UAAU,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAEjD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,KAAK,IAAI,GAAG,CAAC;YACzC,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;gBAChC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,KAAK,IAAI,GAAG,CAAC;YACzC,CAAC;YACD,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;CACF"}
|