@eventcatalog/core 3.35.1 → 3.36.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/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/chunk-D6IBLY3O.js +320 -0
- package/dist/{chunk-R4DR3YAH.js → chunk-H6TGUW5O.js} +1 -1
- package/dist/{chunk-VJ357XOI.js → chunk-IO4U4MPC.js} +1 -1
- package/dist/{chunk-JEQZWJWP.js → chunk-L723FWAT.js} +1 -1
- package/dist/{chunk-B7C4DHFE.js → chunk-R5ZDI2JO.js} +1 -1
- package/dist/{chunk-4SNN54V4.js → chunk-SEAN3UND.js} +1 -1
- package/dist/{chunk-3KXCGYET.js → chunk-ULZYHF3V.js} +5 -0
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/api/02-config.md +22 -0
- package/dist/docs/api/_category_.json +1 -1
- package/dist/docs/contributing/_category_.json +1 -1
- package/dist/docs/development/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/04-skills/_category_.json +1 -1
- package/dist/docs/development/authentication/providers/_category_.json +1 -1
- package/dist/docs/development/bring-your-own-documentation/custom-pages/_category_.json +1 -1
- package/dist/docs/development/customization/01-customize-landing-page.md +1 -1
- package/dist/docs/development/customization/03-search.md +79 -0
- package/dist/docs/development/customization/custom-components/_category_.json +1 -1
- package/dist/docs/development/customization/customize-sidebars/_category_.json +1 -1
- package/dist/docs/development/customization/customize-visualizer/_category_.json +1 -1
- package/dist/docs/development/design/_category_.json +1 -1
- package/dist/docs/development/guides/changelogs/_category_.json +1 -1
- package/dist/docs/development/guides/channels/_category_.json +1 -1
- package/dist/docs/development/guides/channels/ownership-and-components/_category_.json +1 -1
- package/dist/docs/development/guides/channels/versioning-and-lifecycle/_category_.json +1 -1
- package/dist/docs/development/guides/data/_category_.json +1 -1
- package/dist/docs/development/guides/data/ownership-and-components/_category_.json +1 -1
- package/dist/docs/development/guides/data-products/_category_.json +1 -1
- package/dist/docs/development/guides/domains/02-creating-domains/_category_.json +1 -1
- package/dist/docs/development/guides/domains/03-ownership-and-language/_category_.json +1 -1
- package/dist/docs/development/guides/domains/05-entities/_category_.json +1 -1
- package/dist/docs/development/guides/domains/_category_.json +1 -1
- package/dist/docs/development/guides/flows/_category_.json +1 -1
- package/dist/docs/development/guides/messages/_category_.json +1 -1
- package/dist/docs/development/guides/messages/commands/_category_.json +1 -1
- package/dist/docs/development/guides/messages/common/_category_.json +1 -1
- package/dist/docs/development/guides/messages/events/_category_.json +1 -1
- package/dist/docs/development/guides/messages/queries/_category_.json +1 -1
- package/dist/docs/development/guides/owners/_category_.json +1 -1
- package/dist/docs/development/guides/owners/teams/_category_.json +1 -1
- package/dist/docs/development/guides/owners/users/_category_.json +1 -1
- package/dist/docs/development/guides/schemas/_category_.json +1 -1
- package/dist/docs/development/guides/services/_category_.json +1 -1
- package/dist/docs/development/guides/services/adding-to-services/_category_.json +1 -1
- package/dist/docs/development/guides/services/ownership-and-components/_category_.json +1 -1
- package/dist/docs/development/guides/services/versioning-and-lifecycle/_category_.json +1 -1
- package/dist/docs/plugins/_category_.json +1 -1
- package/dist/docs/plugins/amazon-apigateway/_category_.json +1 -1
- package/dist/docs/plugins/asyncapi/_category_.json +1 -1
- package/dist/docs/plugins/aws-glue-registry/_category_.json +1 -1
- package/dist/docs/plugins/backstage/_category_.json +1 -1
- package/dist/docs/plugins/confluent-schema-registry/_category_.json +1 -1
- package/dist/docs/plugins/eventbridge/_category_.json +1 -1
- package/dist/docs/plugins/eventcatalog-federation/_category_.json +1 -1
- package/dist/docs/plugins/github/_category_.json +1 -1
- package/dist/docs/plugins/graphql/_category_.json +1 -1
- package/dist/docs/plugins/hookdeck/_category_.json +1 -1
- package/dist/docs/plugins/openapi/_category_.json +1 -1
- package/dist/eventcatalog.cjs +434 -35
- package/dist/eventcatalog.config.d.cts +13 -1
- package/dist/eventcatalog.config.d.ts +13 -1
- package/dist/eventcatalog.js +88 -11
- package/dist/features.cjs +6 -0
- package/dist/features.d.cts +2 -1
- package/dist/features.d.ts +2 -1
- package/dist/features.js +3 -1
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/search-indexer.cjs +356 -0
- package/dist/search-indexer.d.cts +30 -0
- package/dist/search-indexer.d.ts +30 -0
- package/dist/search-indexer.js +10 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/astro.config.mjs +28 -32
- package/eventcatalog/src/components/Search/SearchModal.tsx +248 -148
- package/eventcatalog/src/components/Search/search-utils.spec.ts +138 -1
- package/eventcatalog/src/components/Search/search-utils.ts +271 -0
- package/eventcatalog/src/env.d.ts +1 -0
- package/eventcatalog/src/layouts/BaseLayout.astro +4 -7
- package/eventcatalog/src/stores/theme-store.ts +9 -13
- package/package.json +3 -2
|
@@ -64,6 +64,7 @@ type IntegrationsConfig = {
|
|
|
64
64
|
/** Log all analytics events to the browser console */
|
|
65
65
|
debug?: boolean;
|
|
66
66
|
};
|
|
67
|
+
type CatalogTheme = 'default' | 'ocean' | 'sapphire' | 'sunset' | 'forest' | (string & {});
|
|
67
68
|
type ScalarConfiguration = any;
|
|
68
69
|
interface Config {
|
|
69
70
|
title: string;
|
|
@@ -82,14 +83,25 @@ interface Config {
|
|
|
82
83
|
* Theme for the catalog UI.
|
|
83
84
|
* - 'default': Default purple/slate theme
|
|
84
85
|
* - 'ocean': Deep blue/teal ocean-inspired theme
|
|
86
|
+
* - 'sapphire': Blue/violet theme
|
|
87
|
+
* - 'sunset': Orange/pink sunset-inspired theme
|
|
88
|
+
* - 'forest': Green forest-inspired theme
|
|
85
89
|
* @default 'default'
|
|
86
90
|
*/
|
|
87
|
-
theme?:
|
|
91
|
+
theme?: CatalogTheme;
|
|
88
92
|
auth?: AuthConfig;
|
|
89
93
|
rss?: {
|
|
90
94
|
enabled: boolean;
|
|
91
95
|
limit: number;
|
|
92
96
|
};
|
|
97
|
+
search?: {
|
|
98
|
+
/**
|
|
99
|
+
* - 'resource': Fast default search across catalog resources.
|
|
100
|
+
* - 'indexed': Opt-in full-content search index generated at build time.
|
|
101
|
+
* @default 'resource'
|
|
102
|
+
*/
|
|
103
|
+
type?: 'resource' | 'indexed';
|
|
104
|
+
};
|
|
93
105
|
llmsTxt?: {
|
|
94
106
|
enabled: boolean;
|
|
95
107
|
};
|
package/dist/eventcatalog.js
CHANGED
|
@@ -1,34 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runMigrations
|
|
3
|
+
} from "./chunk-XUAF2H54.js";
|
|
4
|
+
import "./chunk-CA4U2JP7.js";
|
|
1
5
|
import {
|
|
2
6
|
resolve_catalog_dependencies_default
|
|
3
7
|
} from "./chunk-WAJIJEI3.js";
|
|
8
|
+
import {
|
|
9
|
+
buildSearchIndex
|
|
10
|
+
} from "./chunk-D6IBLY3O.js";
|
|
4
11
|
import {
|
|
5
12
|
watch
|
|
6
13
|
} from "./chunk-K3ZVEX2Y.js";
|
|
7
14
|
import {
|
|
8
15
|
log_build_default
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-L723FWAT.js";
|
|
17
|
+
import "./chunk-IO4U4MPC.js";
|
|
11
18
|
import "./chunk-4UVFXLPI.js";
|
|
12
|
-
import {
|
|
13
|
-
runMigrations
|
|
14
|
-
} from "./chunk-XUAF2H54.js";
|
|
15
|
-
import "./chunk-CA4U2JP7.js";
|
|
16
19
|
import {
|
|
17
20
|
catalogToAstro
|
|
18
21
|
} from "./chunk-YDXB3BD2.js";
|
|
19
22
|
import "./chunk-55D645EH.js";
|
|
20
23
|
import {
|
|
24
|
+
getProjectOutDir,
|
|
25
|
+
isAuthEnabled,
|
|
26
|
+
isIndexedSearchEnabled,
|
|
21
27
|
isOutputServer
|
|
22
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-ULZYHF3V.js";
|
|
23
29
|
import {
|
|
24
30
|
generate
|
|
25
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-H6TGUW5O.js";
|
|
26
32
|
import {
|
|
27
33
|
logger
|
|
28
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-SEAN3UND.js";
|
|
29
35
|
import {
|
|
30
36
|
VERSION
|
|
31
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-R5ZDI2JO.js";
|
|
32
38
|
import {
|
|
33
39
|
getEventCatalogConfigFile,
|
|
34
40
|
verifyRequiredFieldsAreInCatalogConfigFile
|
|
@@ -678,6 +684,57 @@ var createAstroDevLineFilter = () => {
|
|
|
678
684
|
return shouldFilterAstroLine(line) || line.includes("[router]");
|
|
679
685
|
};
|
|
680
686
|
};
|
|
687
|
+
var buildDevSearchIndex = async ({ config }) => {
|
|
688
|
+
const result = await buildSearchIndex({
|
|
689
|
+
projectDir: dir,
|
|
690
|
+
outDir: path2.join(core, "public"),
|
|
691
|
+
searchOutputPath: path2.join(core, "public", "pagefind"),
|
|
692
|
+
config,
|
|
693
|
+
isServer: false
|
|
694
|
+
});
|
|
695
|
+
logger.info(`Indexed ${result.records} page(s) into ${path2.relative(core, result.outputPath)}`, "search");
|
|
696
|
+
};
|
|
697
|
+
var warnIfIndexedSearchUsesAuth = async () => {
|
|
698
|
+
if (!await isAuthEnabled()) {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
logger.info(
|
|
702
|
+
"Indexed search creates client-readable search files. Make sure your deployment protects /pagefind assets if your catalog is private.",
|
|
703
|
+
"search"
|
|
704
|
+
);
|
|
705
|
+
};
|
|
706
|
+
var createDevSearchIndexWatcher = ({ config }) => {
|
|
707
|
+
let timeout;
|
|
708
|
+
let isBuilding = false;
|
|
709
|
+
let queued = false;
|
|
710
|
+
const run = async () => {
|
|
711
|
+
if (isBuilding) {
|
|
712
|
+
queued = true;
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
isBuilding = true;
|
|
716
|
+
try {
|
|
717
|
+
await buildDevSearchIndex({ config });
|
|
718
|
+
} catch (err) {
|
|
719
|
+
logger.info(`Failed to rebuild indexed search: ${err.message}`, "search");
|
|
720
|
+
} finally {
|
|
721
|
+
isBuilding = false;
|
|
722
|
+
if (queued) {
|
|
723
|
+
queued = false;
|
|
724
|
+
run();
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
return (_err, events) => {
|
|
729
|
+
if (!events.some((event) => event.path.endsWith(".md") || event.path.endsWith(".mdx"))) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
if (timeout) {
|
|
733
|
+
clearTimeout(timeout);
|
|
734
|
+
}
|
|
735
|
+
timeout = setTimeout(run, 500);
|
|
736
|
+
};
|
|
737
|
+
};
|
|
681
738
|
var replaceAstroReadyVersionLine = (line) => {
|
|
682
739
|
const matches = line.match(/^(\s*)astro(\s+)v\S+(\s+ready.*)$/i);
|
|
683
740
|
if (!matches) {
|
|
@@ -823,6 +880,7 @@ program.command("dev").description("Run development server of EventCatalog").opt
|
|
|
823
880
|
await resolve_catalog_dependencies_default(dir, core);
|
|
824
881
|
await runMigrations(dir);
|
|
825
882
|
await catalogToAstro(dir, core);
|
|
883
|
+
const config = await getEventCatalogConfigFile(dir);
|
|
826
884
|
const canEmbedPages = await isFeatureEnabled(
|
|
827
885
|
"@eventcatalog/backstage-plugin-eventcatalog",
|
|
828
886
|
process.env.EVENTCATALOG_LICENSE_KEY_BACKSTAGE
|
|
@@ -842,10 +900,16 @@ program.command("dev").description("Run development server of EventCatalog").opt
|
|
|
842
900
|
logger.info(`Failed to build fields index: ${err.message}`, "fields");
|
|
843
901
|
}
|
|
844
902
|
}
|
|
903
|
+
const shouldBuildIndexedSearch = await isIndexedSearchEnabled();
|
|
904
|
+
if (shouldBuildIndexedSearch) {
|
|
905
|
+
await warnIfIndexedSearchUsesAuth();
|
|
906
|
+
logger.info("Building indexed search for local development...", "search");
|
|
907
|
+
await buildDevSearchIndex({ config });
|
|
908
|
+
}
|
|
845
909
|
checkForUpdate();
|
|
846
910
|
let watchUnsub;
|
|
847
911
|
try {
|
|
848
|
-
watchUnsub = await watch(dir, core);
|
|
912
|
+
watchUnsub = await watch(dir, core, shouldBuildIndexedSearch ? createDevSearchIndexWatcher({ config }) : void 0);
|
|
849
913
|
const args = command.args.join(" ").trim();
|
|
850
914
|
if (options.prewarm) {
|
|
851
915
|
const prewarmPort = await resolveDevPort({
|
|
@@ -929,6 +993,19 @@ program.command("build").description("Run build of EventCatalog").action(async (
|
|
|
929
993
|
},
|
|
930
994
|
shouldFilterLine: createAstroLineFilter()
|
|
931
995
|
});
|
|
996
|
+
if (await isIndexedSearchEnabled()) {
|
|
997
|
+
await warnIfIndexedSearchUsesAuth();
|
|
998
|
+
const config = await getEventCatalogConfigFile(dir);
|
|
999
|
+
const outDir = path2.resolve(dir, await getProjectOutDir());
|
|
1000
|
+
logger.info("Building indexed search...", "search");
|
|
1001
|
+
const result = await buildSearchIndex({
|
|
1002
|
+
projectDir: dir,
|
|
1003
|
+
outDir,
|
|
1004
|
+
config,
|
|
1005
|
+
isServer
|
|
1006
|
+
});
|
|
1007
|
+
logger.info(`Indexed ${result.records} page(s) into ${path2.relative(dir, result.outputPath)}`, "search");
|
|
1008
|
+
}
|
|
932
1009
|
});
|
|
933
1010
|
var previewCatalog = ({
|
|
934
1011
|
command,
|
package/dist/features.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var features_exports = {};
|
|
|
32
32
|
__export(features_exports, {
|
|
33
33
|
getProjectOutDir: () => getProjectOutDir,
|
|
34
34
|
isAuthEnabled: () => isAuthEnabled,
|
|
35
|
+
isIndexedSearchEnabled: () => isIndexedSearchEnabled,
|
|
35
36
|
isOutputServer: () => isOutputServer
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(features_exports);
|
|
@@ -86,6 +87,10 @@ var isOutputServer = async () => {
|
|
|
86
87
|
const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
|
|
87
88
|
return config?.output === "server";
|
|
88
89
|
};
|
|
90
|
+
var isIndexedSearchEnabled = async () => {
|
|
91
|
+
const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
|
|
92
|
+
return config?.search?.type === "indexed";
|
|
93
|
+
};
|
|
89
94
|
var isAuthEnabled = async () => {
|
|
90
95
|
const directory = process.env.PROJECT_DIR || process.cwd();
|
|
91
96
|
const hasAuthConfig = import_node_fs2.default.existsSync((0, import_node_path2.join)(directory, "eventcatalog.auth.js"));
|
|
@@ -95,5 +100,6 @@ var isAuthEnabled = async () => {
|
|
|
95
100
|
0 && (module.exports = {
|
|
96
101
|
getProjectOutDir,
|
|
97
102
|
isAuthEnabled,
|
|
103
|
+
isIndexedSearchEnabled,
|
|
98
104
|
isOutputServer
|
|
99
105
|
});
|
package/dist/features.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
declare const getProjectOutDir: () => Promise<any>;
|
|
2
2
|
declare const isOutputServer: () => Promise<boolean>;
|
|
3
|
+
declare const isIndexedSearchEnabled: () => Promise<boolean>;
|
|
3
4
|
declare const isAuthEnabled: () => Promise<boolean>;
|
|
4
5
|
|
|
5
|
-
export { getProjectOutDir, isAuthEnabled, isOutputServer };
|
|
6
|
+
export { getProjectOutDir, isAuthEnabled, isIndexedSearchEnabled, isOutputServer };
|
package/dist/features.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
declare const getProjectOutDir: () => Promise<any>;
|
|
2
2
|
declare const isOutputServer: () => Promise<boolean>;
|
|
3
|
+
declare const isIndexedSearchEnabled: () => Promise<boolean>;
|
|
3
4
|
declare const isAuthEnabled: () => Promise<boolean>;
|
|
4
5
|
|
|
5
|
-
export { getProjectOutDir, isAuthEnabled, isOutputServer };
|
|
6
|
+
export { getProjectOutDir, isAuthEnabled, isIndexedSearchEnabled, isOutputServer };
|
package/dist/features.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getProjectOutDir,
|
|
3
3
|
isAuthEnabled,
|
|
4
|
+
isIndexedSearchEnabled,
|
|
4
5
|
isOutputServer
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ULZYHF3V.js";
|
|
6
7
|
import "./chunk-5T63CXKU.js";
|
|
7
8
|
export {
|
|
8
9
|
getProjectOutDir,
|
|
9
10
|
isAuthEnabled,
|
|
11
|
+
isIndexedSearchEnabled,
|
|
10
12
|
isOutputServer
|
|
11
13
|
};
|
package/dist/generate.cjs
CHANGED
package/dist/generate.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generate
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-H6TGUW5O.js";
|
|
4
|
+
import "./chunk-SEAN3UND.js";
|
|
5
|
+
import "./chunk-R5ZDI2JO.js";
|
|
6
6
|
import "./chunk-5T63CXKU.js";
|
|
7
7
|
export {
|
|
8
8
|
generate
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/search-indexer.ts
|
|
31
|
+
var search_indexer_exports = {};
|
|
32
|
+
__export(search_indexer_exports, {
|
|
33
|
+
buildSearchIndex: () => buildSearchIndex,
|
|
34
|
+
collectSearchRecords: () => collectSearchRecords,
|
|
35
|
+
markdownToSearchText: () => markdownToSearchText
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(search_indexer_exports);
|
|
38
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
39
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
40
|
+
var import_glob = require("glob");
|
|
41
|
+
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
42
|
+
var RESOURCE_COLLECTIONS = {
|
|
43
|
+
channels: { docsPath: "channels", type: "Channel" },
|
|
44
|
+
commands: { docsPath: "commands", type: "Command" },
|
|
45
|
+
containers: { docsPath: "containers", type: "Container" },
|
|
46
|
+
"data-products": { docsPath: "data-products", type: "Data Product" },
|
|
47
|
+
domains: { docsPath: "domains", type: "Domain" },
|
|
48
|
+
entities: { docsPath: "entities", type: "Entity" },
|
|
49
|
+
events: { docsPath: "events", type: "Event" },
|
|
50
|
+
flows: { docsPath: "flows", type: "Flow" },
|
|
51
|
+
queries: { docsPath: "queries", type: "Query" },
|
|
52
|
+
services: { docsPath: "services", type: "Service" },
|
|
53
|
+
subdomains: { docsPath: "domains", type: "Domain" }
|
|
54
|
+
};
|
|
55
|
+
var IGNORED_GLOBS = [
|
|
56
|
+
"**/.git/**",
|
|
57
|
+
"**/.eventcatalog-core/**",
|
|
58
|
+
"**/dist/**",
|
|
59
|
+
"**/node_modules/**",
|
|
60
|
+
"**/public/**",
|
|
61
|
+
"**/snippets/**",
|
|
62
|
+
"**/chat-prompts/**"
|
|
63
|
+
];
|
|
64
|
+
var trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
|
|
65
|
+
var normalizePath = (value) => value.replace(/\\/g, "/");
|
|
66
|
+
var removeExtension = (value) => value.replace(/\.(md|mdx)$/i, "");
|
|
67
|
+
var stripNumericPrefix = (value) => value.replace(/^\d+(?:[-_.\s]+)?/, "") || value;
|
|
68
|
+
var normalizeUrlPath = (value) => {
|
|
69
|
+
const withoutIndex = value.replace(/\/index$/i, "");
|
|
70
|
+
return withoutIndex || "";
|
|
71
|
+
};
|
|
72
|
+
var buildUrl = (pathname, config) => {
|
|
73
|
+
const base = config.base ? `/${trimSlashes(config.base)}` : "";
|
|
74
|
+
const cleanPath = `/${trimSlashes(pathname)}`;
|
|
75
|
+
const url = `${base}${cleanPath}`.replace(/\/{2,}/g, "/");
|
|
76
|
+
if (config.trailingSlash === true && !url.endsWith("/")) {
|
|
77
|
+
return `${url}/`;
|
|
78
|
+
}
|
|
79
|
+
return url || "/";
|
|
80
|
+
};
|
|
81
|
+
var valueToSearchText = (value) => {
|
|
82
|
+
if (value === null || value === void 0) return "";
|
|
83
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
|
|
84
|
+
if (Array.isArray(value)) return value.map(valueToSearchText).filter(Boolean).join(" ");
|
|
85
|
+
if (typeof value === "object") return Object.values(value).map(valueToSearchText).filter(Boolean).join(" ");
|
|
86
|
+
return "";
|
|
87
|
+
};
|
|
88
|
+
var markdownToSearchText = (content) => {
|
|
89
|
+
return content.replace(/<!--[\s\S]*?-->/g, " ").replace(/^\s*import\s+.*$/gm, " ").replace(/^\s*export\s+.*$/gm, " ").replace(/```[\s\S]*?```/g, (match) => match.replace(/```[a-zA-Z0-9-]*\n?/g, " ").replace(/```/g, " ")).replace(/<([A-Z][A-Za-z0-9.]*)\b([^>]*)\/?>/g, (_match, _component, attributes) => {
|
|
90
|
+
const quotedValues = [...String(attributes).matchAll(/(?:title|label|description|alt|summary)=["'`]([^"'`]+)["'`]/g)];
|
|
91
|
+
return quotedValues.map((entry) => entry[1]).join(" ");
|
|
92
|
+
}).replace(/<\/?[A-Za-z][^>]*>/g, " ").replace(/\[\[([^|\]]+)\|([^\]]+)\]\]/g, "$2").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[`*_~>#|{}[\]():]/g, " ").replace(/\s+/g, " ").trim();
|
|
93
|
+
};
|
|
94
|
+
var inferDocIdFromFile = (relativePath, frontmatterId) => {
|
|
95
|
+
if (frontmatterId) return frontmatterId;
|
|
96
|
+
const fileName = import_node_path.default.posix.basename(removeExtension(relativePath));
|
|
97
|
+
if (fileName.toLowerCase() === "index") {
|
|
98
|
+
return import_node_path.default.posix.basename(import_node_path.default.posix.dirname(relativePath));
|
|
99
|
+
}
|
|
100
|
+
return stripNumericPrefix(fileName);
|
|
101
|
+
};
|
|
102
|
+
var findResourceSegment = (segments) => {
|
|
103
|
+
let match = null;
|
|
104
|
+
for (let index = 0; index < segments.length - 1; index++) {
|
|
105
|
+
const segment = segments[index];
|
|
106
|
+
if (RESOURCE_COLLECTIONS[segment] && segments[index + 1]) {
|
|
107
|
+
match = { index, segment };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return match;
|
|
111
|
+
};
|
|
112
|
+
var readResourceFrontmatter = async (projectDir, resourcePath) => {
|
|
113
|
+
const candidates = [import_node_path.default.join(projectDir, resourcePath, "index.mdx"), import_node_path.default.join(projectDir, resourcePath, "index.md")];
|
|
114
|
+
for (const candidate of candidates) {
|
|
115
|
+
try {
|
|
116
|
+
const file = await import_promises.default.readFile(candidate, "utf8");
|
|
117
|
+
return (0, import_gray_matter.default)(file).data;
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {};
|
|
122
|
+
};
|
|
123
|
+
var deriveRecordFromPath = async ({
|
|
124
|
+
projectDir,
|
|
125
|
+
relativePath,
|
|
126
|
+
data,
|
|
127
|
+
config
|
|
128
|
+
}) => {
|
|
129
|
+
const normalizedRelativePath = normalizePath(relativePath);
|
|
130
|
+
const segments = normalizedRelativePath.split("/").filter(Boolean);
|
|
131
|
+
const fileName = segments[segments.length - 1] || "";
|
|
132
|
+
const fileNameWithoutExtension = removeExtension(fileName);
|
|
133
|
+
if (data.hidden === true || data.draft) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
if (segments[0] === "docs") {
|
|
137
|
+
const customPath = normalizeUrlPath(removeExtension(segments.slice(1).join("/")));
|
|
138
|
+
const title = data.title || data.label || import_node_path.default.posix.basename(customPath) || "Custom docs";
|
|
139
|
+
return {
|
|
140
|
+
url: buildUrl(`/docs/custom/${customPath}`, config),
|
|
141
|
+
title,
|
|
142
|
+
summary: data.summary,
|
|
143
|
+
type: "Custom Doc",
|
|
144
|
+
collection: "custom-docs",
|
|
145
|
+
id: customPath
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if (segments[0] === "users" || segments[0] === "teams") {
|
|
149
|
+
const id = data.id || (fileNameWithoutExtension === "index" ? segments[1] : fileNameWithoutExtension);
|
|
150
|
+
const type = segments[0] === "users" ? "User" : "Team";
|
|
151
|
+
return {
|
|
152
|
+
url: buildUrl(`/docs/${segments[0]}/${id}`, config),
|
|
153
|
+
title: data.name || data.title || id,
|
|
154
|
+
summary: data.summary,
|
|
155
|
+
type,
|
|
156
|
+
collection: segments[0],
|
|
157
|
+
id
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const resourceMatch = findResourceSegment(segments);
|
|
161
|
+
if (!resourceMatch) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const resourceConfig = RESOURCE_COLLECTIONS[resourceMatch.segment];
|
|
165
|
+
const resourceFolderId = segments[resourceMatch.index + 1];
|
|
166
|
+
const resourcePathSegments = segments.slice(0, resourceMatch.index + 2);
|
|
167
|
+
const versionFromPath = segments[resourceMatch.index + 2] === "versioned" && segments[resourceMatch.index + 3] ? segments[resourceMatch.index + 3] : void 0;
|
|
168
|
+
if (versionFromPath) {
|
|
169
|
+
resourcePathSegments.push("versioned", versionFromPath);
|
|
170
|
+
}
|
|
171
|
+
const resourcePath = resourcePathSegments.join("/");
|
|
172
|
+
const resourceData = fileNameWithoutExtension === "index" ? data : await readResourceFrontmatter(projectDir, resourcePath);
|
|
173
|
+
const resourceId = resourceData.id || data.resourceId || resourceFolderId;
|
|
174
|
+
const resourceVersion = versionFromPath || resourceData.version || data.resourceVersion || data.version;
|
|
175
|
+
if (!resourceVersion) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
if (fileNameWithoutExtension === "index") {
|
|
179
|
+
return {
|
|
180
|
+
url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/${resourceVersion}`, config),
|
|
181
|
+
title: data.name || data.title || resourceId,
|
|
182
|
+
summary: data.summary,
|
|
183
|
+
type: resourceConfig.type,
|
|
184
|
+
collection: resourceConfig.docsPath,
|
|
185
|
+
id: resourceId,
|
|
186
|
+
version: resourceVersion
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (fileNameWithoutExtension === "ubiquitous-language") {
|
|
190
|
+
return {
|
|
191
|
+
url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/language`, config),
|
|
192
|
+
title: data.title || `${resourceData.name || resourceId} ubiquitous language`,
|
|
193
|
+
summary: data.summary,
|
|
194
|
+
type: "Language",
|
|
195
|
+
collection: "language",
|
|
196
|
+
id: resourceId,
|
|
197
|
+
version: resourceVersion
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (fileNameWithoutExtension === "changelog") {
|
|
201
|
+
return {
|
|
202
|
+
url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/${resourceVersion}/changelog`, config),
|
|
203
|
+
title: data.title || `${resourceData.name || resourceId} changelog`,
|
|
204
|
+
summary: data.summary,
|
|
205
|
+
type: "Changelog",
|
|
206
|
+
collection: "changelog",
|
|
207
|
+
id: resourceId,
|
|
208
|
+
version: resourceVersion
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const docsIndex = segments.indexOf("docs");
|
|
212
|
+
if (docsIndex > resourceMatch.index) {
|
|
213
|
+
const docType = data.type || segments[docsIndex + 1] || "pages";
|
|
214
|
+
const docId = inferDocIdFromFile(normalizedRelativePath, data.id);
|
|
215
|
+
const title = data.title || stripNumericPrefix(removeExtension(fileName));
|
|
216
|
+
return {
|
|
217
|
+
url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/${resourceVersion}/${docType}/${docId}`, config),
|
|
218
|
+
title,
|
|
219
|
+
summary: data.summary,
|
|
220
|
+
type: "Resource Doc",
|
|
221
|
+
collection: docType,
|
|
222
|
+
id: docId,
|
|
223
|
+
version: data.version || resourceVersion
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
if (segments[0] === "diagrams") {
|
|
227
|
+
const id = data.id || resourceFolderId;
|
|
228
|
+
const version = data.version || resourceVersion;
|
|
229
|
+
return {
|
|
230
|
+
url: buildUrl(`/diagrams/${id}/${version}`, config),
|
|
231
|
+
title: data.name || data.title || id,
|
|
232
|
+
summary: data.summary,
|
|
233
|
+
type: "Design",
|
|
234
|
+
collection: "diagrams",
|
|
235
|
+
id,
|
|
236
|
+
version
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
};
|
|
241
|
+
var collectSearchRecords = async ({
|
|
242
|
+
projectDir,
|
|
243
|
+
config
|
|
244
|
+
}) => {
|
|
245
|
+
const files = await (0, import_glob.glob)("**/*.{md,mdx}", {
|
|
246
|
+
cwd: projectDir,
|
|
247
|
+
absolute: true,
|
|
248
|
+
nodir: true,
|
|
249
|
+
ignore: IGNORED_GLOBS,
|
|
250
|
+
windowsPathsNoEscape: process.platform === "win32"
|
|
251
|
+
});
|
|
252
|
+
const records = await Promise.all(
|
|
253
|
+
files.map(async (file) => {
|
|
254
|
+
const raw = await import_promises.default.readFile(file, "utf8");
|
|
255
|
+
const parsed = (0, import_gray_matter.default)(raw);
|
|
256
|
+
const relativePath = normalizePath(import_node_path.default.relative(projectDir, file));
|
|
257
|
+
const baseRecord = await deriveRecordFromPath({
|
|
258
|
+
projectDir,
|
|
259
|
+
relativePath,
|
|
260
|
+
data: parsed.data,
|
|
261
|
+
config
|
|
262
|
+
});
|
|
263
|
+
if (!baseRecord) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
const frontmatterText = valueToSearchText({
|
|
267
|
+
id: baseRecord.id,
|
|
268
|
+
title: baseRecord.title,
|
|
269
|
+
summary: baseRecord.summary,
|
|
270
|
+
version: baseRecord.version,
|
|
271
|
+
owners: parsed.data.owners,
|
|
272
|
+
badges: parsed.data.badges
|
|
273
|
+
});
|
|
274
|
+
const content = [frontmatterText, markdownToSearchText(parsed.content)].filter(Boolean).join("\n\n");
|
|
275
|
+
if (!content.trim()) {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
...baseRecord,
|
|
280
|
+
content
|
|
281
|
+
};
|
|
282
|
+
})
|
|
283
|
+
);
|
|
284
|
+
const uniqueRecords = /* @__PURE__ */ new Map();
|
|
285
|
+
for (const record of records) {
|
|
286
|
+
if (!record) continue;
|
|
287
|
+
uniqueRecords.set(record.url, record);
|
|
288
|
+
}
|
|
289
|
+
return [...uniqueRecords.values()].sort((a, b) => a.url.localeCompare(b.url));
|
|
290
|
+
};
|
|
291
|
+
var getSearchOutputPath = ({
|
|
292
|
+
outDir,
|
|
293
|
+
isServer,
|
|
294
|
+
searchOutputPath
|
|
295
|
+
}) => {
|
|
296
|
+
if (searchOutputPath) {
|
|
297
|
+
return searchOutputPath;
|
|
298
|
+
}
|
|
299
|
+
return import_node_path.default.join(outDir, isServer ? "client" : "", "pagefind");
|
|
300
|
+
};
|
|
301
|
+
var buildSearchIndex = async ({ projectDir, outDir, config, isServer, searchOutputPath }) => {
|
|
302
|
+
const records = await collectSearchRecords({ projectDir, config });
|
|
303
|
+
if (records.length === 0) {
|
|
304
|
+
throw new Error("No searchable Markdown or MDX content was found.");
|
|
305
|
+
}
|
|
306
|
+
const pagefind = await import("pagefind");
|
|
307
|
+
const { index } = await pagefind.createIndex({
|
|
308
|
+
keepIndexUrl: false,
|
|
309
|
+
writePlayground: false
|
|
310
|
+
});
|
|
311
|
+
const errors = [];
|
|
312
|
+
for (const record of records) {
|
|
313
|
+
const result = await index.addCustomRecord({
|
|
314
|
+
url: record.url,
|
|
315
|
+
content: record.content,
|
|
316
|
+
language: "en",
|
|
317
|
+
meta: {
|
|
318
|
+
title: record.title,
|
|
319
|
+
summary: record.summary || "",
|
|
320
|
+
type: record.type,
|
|
321
|
+
collection: record.collection,
|
|
322
|
+
id: record.id || "",
|
|
323
|
+
version: record.version || ""
|
|
324
|
+
},
|
|
325
|
+
filters: {
|
|
326
|
+
type: [record.type],
|
|
327
|
+
collection: [record.collection]
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
if (result.errors?.length) {
|
|
331
|
+
errors.push(...result.errors.map((error) => `${record.url}: ${error.message || error}`));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const outputPath = getSearchOutputPath({ outDir, isServer, searchOutputPath });
|
|
335
|
+
await import_promises.default.rm(outputPath, { recursive: true, force: true });
|
|
336
|
+
const writeResult = await index.writeFiles({ outputPath });
|
|
337
|
+
if (writeResult.errors?.length) {
|
|
338
|
+
errors.push(...writeResult.errors.map((error) => error.message || String(error)));
|
|
339
|
+
}
|
|
340
|
+
await index.deleteIndex?.();
|
|
341
|
+
await pagefind.close?.();
|
|
342
|
+
if (errors.length > 0) {
|
|
343
|
+
throw new Error(`Failed to build indexed search:
|
|
344
|
+
${errors.join("\n")}`);
|
|
345
|
+
}
|
|
346
|
+
return {
|
|
347
|
+
records: records.length,
|
|
348
|
+
outputPath
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
352
|
+
0 && (module.exports = {
|
|
353
|
+
buildSearchIndex,
|
|
354
|
+
collectSearchRecords,
|
|
355
|
+
markdownToSearchText
|
|
356
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Config } from './eventcatalog.config.cjs';
|
|
2
|
+
|
|
3
|
+
type SearchRecord = {
|
|
4
|
+
url: string;
|
|
5
|
+
title: string;
|
|
6
|
+
content: string;
|
|
7
|
+
type: string;
|
|
8
|
+
collection: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
summary?: string;
|
|
12
|
+
};
|
|
13
|
+
type BuildSearchIndexOptions = {
|
|
14
|
+
projectDir: string;
|
|
15
|
+
outDir: string;
|
|
16
|
+
config: Config;
|
|
17
|
+
isServer: boolean;
|
|
18
|
+
searchOutputPath?: string;
|
|
19
|
+
};
|
|
20
|
+
declare const markdownToSearchText: (content: string) => string;
|
|
21
|
+
declare const collectSearchRecords: ({ projectDir, config, }: {
|
|
22
|
+
projectDir: string;
|
|
23
|
+
config: Config;
|
|
24
|
+
}) => Promise<SearchRecord[]>;
|
|
25
|
+
declare const buildSearchIndex: ({ projectDir, outDir, config, isServer, searchOutputPath }: BuildSearchIndexOptions) => Promise<{
|
|
26
|
+
records: number;
|
|
27
|
+
outputPath: string;
|
|
28
|
+
}>;
|
|
29
|
+
|
|
30
|
+
export { buildSearchIndex, collectSearchRecords, markdownToSearchText };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Config } from './eventcatalog.config.js';
|
|
2
|
+
|
|
3
|
+
type SearchRecord = {
|
|
4
|
+
url: string;
|
|
5
|
+
title: string;
|
|
6
|
+
content: string;
|
|
7
|
+
type: string;
|
|
8
|
+
collection: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
summary?: string;
|
|
12
|
+
};
|
|
13
|
+
type BuildSearchIndexOptions = {
|
|
14
|
+
projectDir: string;
|
|
15
|
+
outDir: string;
|
|
16
|
+
config: Config;
|
|
17
|
+
isServer: boolean;
|
|
18
|
+
searchOutputPath?: string;
|
|
19
|
+
};
|
|
20
|
+
declare const markdownToSearchText: (content: string) => string;
|
|
21
|
+
declare const collectSearchRecords: ({ projectDir, config, }: {
|
|
22
|
+
projectDir: string;
|
|
23
|
+
config: Config;
|
|
24
|
+
}) => Promise<SearchRecord[]>;
|
|
25
|
+
declare const buildSearchIndex: ({ projectDir, outDir, config, isServer, searchOutputPath }: BuildSearchIndexOptions) => Promise<{
|
|
26
|
+
records: number;
|
|
27
|
+
outputPath: string;
|
|
28
|
+
}>;
|
|
29
|
+
|
|
30
|
+
export { buildSearchIndex, collectSearchRecords, markdownToSearchText };
|