@golemio/core 3.1.0-dev.2542798507 → 3.1.0-dev.2556337509

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.
Files changed (40) hide show
  1. package/dist/helpers/data-access/azure/AzureBearerTokenProvider.d.ts +9 -0
  2. package/dist/helpers/data-access/azure/AzureBearerTokenProvider.js +27 -0
  3. package/dist/helpers/data-access/azure/AzureBearerTokenProvider.js.map +1 -0
  4. package/dist/helpers/data-access/azure/buildBearerTokenProvider.d.ts +12 -0
  5. package/dist/helpers/data-access/azure/buildBearerTokenProvider.js +30 -0
  6. package/dist/helpers/data-access/azure/buildBearerTokenProvider.js.map +1 -0
  7. package/dist/helpers/data-access/azure/index.d.ts +5 -0
  8. package/dist/helpers/data-access/azure/index.js +10 -0
  9. package/dist/helpers/data-access/azure/index.js.map +1 -0
  10. package/dist/helpers/data-access/opensearch/IOpenSearchConnector.d.ts +8 -0
  11. package/dist/helpers/data-access/opensearch/IOpenSearchConnector.js +3 -0
  12. package/dist/helpers/data-access/opensearch/IOpenSearchConnector.js.map +1 -0
  13. package/dist/helpers/data-access/opensearch/IOpenSearchInfo.d.ts +6 -0
  14. package/dist/helpers/data-access/opensearch/IOpenSearchInfo.js +3 -0
  15. package/dist/helpers/data-access/opensearch/IOpenSearchInfo.js.map +1 -0
  16. package/dist/helpers/data-access/opensearch/ISyncableIndex.d.ts +9 -0
  17. package/dist/helpers/data-access/opensearch/ISyncableIndex.js +3 -0
  18. package/dist/helpers/data-access/opensearch/ISyncableIndex.js.map +1 -0
  19. package/dist/helpers/data-access/opensearch/OpenSearchConnector.d.ts +21 -0
  20. package/dist/helpers/data-access/opensearch/OpenSearchConnector.js +113 -0
  21. package/dist/helpers/data-access/opensearch/OpenSearchConnector.js.map +1 -0
  22. package/dist/helpers/data-access/opensearch/OpenSearchService.d.ts +22 -0
  23. package/dist/helpers/data-access/opensearch/OpenSearchService.js +119 -0
  24. package/dist/helpers/data-access/opensearch/OpenSearchService.js.map +1 -0
  25. package/dist/helpers/data-access/opensearch/OpenSearchSyncOrchestrator.d.ts +14 -0
  26. package/dist/helpers/data-access/opensearch/OpenSearchSyncOrchestrator.js +78 -0
  27. package/dist/helpers/data-access/opensearch/OpenSearchSyncOrchestrator.js.map +1 -0
  28. package/dist/helpers/data-access/opensearch/czechAnalyzer.d.ts +6 -0
  29. package/dist/helpers/data-access/opensearch/czechAnalyzer.js +30 -0
  30. package/dist/helpers/data-access/opensearch/czechAnalyzer.js.map +1 -0
  31. package/dist/helpers/data-access/opensearch/index.d.ts +7 -0
  32. package/dist/helpers/data-access/opensearch/index.js +14 -0
  33. package/dist/helpers/data-access/opensearch/index.js.map +1 -0
  34. package/dist/index.d.ts +2 -0
  35. package/dist/index.js +3 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/shared/opensearch.d.ts +1 -0
  38. package/dist/shared/opensearch.js +18 -0
  39. package/dist/shared/opensearch.js.map +1 -0
  40. package/package.json +2 -1
@@ -0,0 +1,9 @@
1
+ import type { AccessToken } from "@azure/core-auth";
2
+ import { AbstractAzureService } from "./AbstractAzureService";
3
+ import { IAzureServiceConfig } from "./IAzureServiceConfig";
4
+ export declare class AzureBearerTokenProvider extends AbstractAzureService {
5
+ protected readonly config: IAzureServiceConfig;
6
+ private readonly scope;
7
+ constructor(config: IAzureServiceConfig, scope: string);
8
+ getToken: () => Promise<AccessToken>;
9
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AzureBearerTokenProvider = void 0;
4
+ const errors_1 = require("@golemio/errors");
5
+ const AbstractAzureService_1 = require("./AbstractAzureService");
6
+ class AzureBearerTokenProvider extends AbstractAzureService_1.AbstractAzureService {
7
+ constructor(config, scope) {
8
+ super();
9
+ this.config = config;
10
+ this.scope = scope;
11
+ this.getToken = async () => {
12
+ try {
13
+ const credential = this.getCredential();
14
+ const accessToken = await credential.getToken(this.scope);
15
+ if (!accessToken) {
16
+ throw new errors_1.RecoverableError(`We received an empty access token (null) for ${this.scope}`, this.constructor.name);
17
+ }
18
+ return accessToken;
19
+ }
20
+ catch (error) {
21
+ throw new errors_1.RecoverableError(`Failed to acquire Azure AD token for scope ${this.scope}: ${error instanceof Error ? error.message : String(error)}`, this.constructor.name, error instanceof Error ? error : new Error(String(error)));
22
+ }
23
+ };
24
+ }
25
+ }
26
+ exports.AzureBearerTokenProvider = AzureBearerTokenProvider;
27
+ //# sourceMappingURL=AzureBearerTokenProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AzureBearerTokenProvider.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/azure/AzureBearerTokenProvider.ts"],"names":[],"mappings":";;;AAAA,4CAAmD;AAEnD,iEAA8D;AAG9D,MAAa,wBAAyB,SAAQ,2CAAoB;IAC9D,YAA+B,MAA2B,EAAmB,KAAa;QACtF,KAAK,EAAE,CAAC;QADmB,WAAM,GAAN,MAAM,CAAqB;QAAmB,UAAK,GAAL,KAAK,CAAQ;QAInF,aAAQ,GAAG,KAAK,IAA0B,EAAE;YAC/C,IAAI;gBACA,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxC,MAAM,WAAW,GAAuB,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9E,IAAI,CAAC,WAAW,EAAE;oBACd,MAAM,IAAI,yBAAgB,CAAC,gDAAgD,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;iBACnH;gBACD,OAAO,WAAW,CAAC;aACtB;YAAC,OAAO,KAAK,EAAE;gBACZ,MAAM,IAAI,yBAAgB,CACtB,8CAA8C,IAAI,CAAC,KAAK,KACpD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACzD,EAAE,EACF,IAAI,CAAC,WAAW,CAAC,IAAI,EACrB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC5D,CAAC;aACL;QACL,CAAC,CAAC;IAnBF,CAAC;CAoBJ;AAvBD,4DAuBC"}
@@ -0,0 +1,12 @@
1
+ import { ISimpleConfig } from "../../configuration/ISimpleConfig";
2
+ import { ILogger } from "../../logger";
3
+ import type { AccessToken } from "@azure/core-auth";
4
+ export interface IBearerTokenProviderOptions {
5
+ scopeEnvVar: string;
6
+ logLabel?: string;
7
+ tokenFileEnvVar?: string;
8
+ clientIdEnvVar?: string;
9
+ tenantIdEnvVar?: string;
10
+ clientSecretEnvVar?: string;
11
+ }
12
+ export declare const buildBearerTokenProvider: (config: ISimpleConfig, logger: ILogger, options: IBearerTokenProviderOptions) => (() => Promise<AccessToken>) | undefined;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildBearerTokenProvider = void 0;
4
+ const AzureBearerTokenProvider_1 = require("./AzureBearerTokenProvider");
5
+ const DEFAULT_ENV_VARS = {
6
+ TOKEN_FILE: "AZURE_FEDERATED_TOKEN_FILE",
7
+ CLIENT_ID: "AZURE_CLIENT_ID",
8
+ TENANT_ID: "AZURE_TENANT_ID",
9
+ CLIENT_SECRET: "AZURE_CLIENT_SECRET",
10
+ };
11
+ const buildBearerTokenProvider = (config, logger, options) => {
12
+ const env = (key) => config.getValue(`env.${key}`, null);
13
+ const tokenFile = env(options.tokenFileEnvVar ?? DEFAULT_ENV_VARS.TOKEN_FILE);
14
+ const clientId = env(options.clientIdEnvVar ?? DEFAULT_ENV_VARS.CLIENT_ID);
15
+ const tenantId = env(options.tenantIdEnvVar ?? DEFAULT_ENV_VARS.TENANT_ID);
16
+ const clientSecret = env(options.clientSecretEnvVar ?? DEFAULT_ENV_VARS.CLIENT_SECRET);
17
+ // What app I need access to - opensearch
18
+ const scope = env(options.scopeEnvVar);
19
+ const label = options.logLabel ?? "Bearer";
20
+ const hasIdentity = Boolean(tenantId && clientId && scope);
21
+ const hasCredentialSource = Boolean(tokenFile || clientSecret);
22
+ if (!hasIdentity || !hasCredentialSource) {
23
+ logger.info(`${label} auth: anonymous (no Azure credentials configured)`);
24
+ return undefined;
25
+ }
26
+ const provider = new AzureBearerTokenProvider_1.AzureBearerTokenProvider({ clientId, tenantId, clientSecret, azureFederatedTokenFile: tokenFile }, scope);
27
+ return () => provider.getToken();
28
+ };
29
+ exports.buildBearerTokenProvider = buildBearerTokenProvider;
30
+ //# sourceMappingURL=buildBearerTokenProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildBearerTokenProvider.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/azure/buildBearerTokenProvider.ts"],"names":[],"mappings":";;;AAGA,yEAAsE;AAEtE,MAAM,gBAAgB,GAAG;IACrB,UAAU,EAAE,4BAA4B;IACxC,SAAS,EAAE,iBAAiB;IAC5B,SAAS,EAAE,iBAAiB;IAC5B,aAAa,EAAE,qBAAqB;CAC9B,CAAC;AAWJ,MAAM,wBAAwB,GAAG,CACpC,MAAqB,EACrB,MAAe,EACf,OAAoC,EACI,EAAE;IAC1C,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAgB,OAAO,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAEhF,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACvF,yCAAyC;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAE3C,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,IAAI,KAAK,CAAC,CAAC;IAC3D,MAAM,mBAAmB,GAAG,OAAO,CAAC,SAAS,IAAI,YAAY,CAAC,CAAC;IAE/D,IAAI,CAAC,WAAW,IAAI,CAAC,mBAAmB,EAAE;QACtC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,oDAAoD,CAAC,CAAC;QAC1E,OAAO,SAAS,CAAC;KACpB;IAED,MAAM,QAAQ,GAAG,IAAI,mDAAwB,CACzC,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,uBAAuB,EAAE,SAAS,EAAE,EACxE,KAAe,CAClB,CAAC;IACF,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;AACrC,CAAC,CAAC;AA5BW,QAAA,wBAAwB,4BA4BnC"}
@@ -0,0 +1,5 @@
1
+ export { buildBearerTokenProvider } from "./buildBearerTokenProvider";
2
+ export type { IBearerTokenProviderOptions } from "./buildBearerTokenProvider";
3
+ export { AzureBearerTokenProvider } from "./AzureBearerTokenProvider";
4
+ export { AbstractAzureService } from "./AbstractAzureService";
5
+ export type { IAzureServiceConfig } from "./IAzureServiceConfig";
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractAzureService = exports.AzureBearerTokenProvider = exports.buildBearerTokenProvider = void 0;
4
+ var buildBearerTokenProvider_1 = require("./buildBearerTokenProvider");
5
+ Object.defineProperty(exports, "buildBearerTokenProvider", { enumerable: true, get: function () { return buildBearerTokenProvider_1.buildBearerTokenProvider; } });
6
+ var AzureBearerTokenProvider_1 = require("./AzureBearerTokenProvider");
7
+ Object.defineProperty(exports, "AzureBearerTokenProvider", { enumerable: true, get: function () { return AzureBearerTokenProvider_1.AzureBearerTokenProvider; } });
8
+ var AbstractAzureService_1 = require("./AbstractAzureService");
9
+ Object.defineProperty(exports, "AbstractAzureService", { enumerable: true, get: function () { return AbstractAzureService_1.AbstractAzureService; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/azure/index.ts"],"names":[],"mappings":";;;AAAA,uEAAsE;AAA7D,oIAAA,wBAAwB,OAAA;AAEjC,uEAAsE;AAA7D,oIAAA,wBAAwB,OAAA;AACjC,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,8 @@
1
+ import { Client } from "@opensearch-project/opensearch";
2
+ import { Disposable } from "tsyringe";
3
+ export interface IOpenSearchConnector extends Disposable {
4
+ connect(): Promise<Client>;
5
+ getConnection(): Client;
6
+ isConnected(): Promise<boolean>;
7
+ disconnect(): Promise<void>;
8
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=IOpenSearchConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IOpenSearchConnector.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/IOpenSearchConnector.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { AccessToken } from "@azure/core-auth";
2
+ export interface IOpenSearchInfo {
3
+ url: string;
4
+ rejectUnauthorized?: boolean;
5
+ getBearerToken?: () => Promise<AccessToken>;
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=IOpenSearchInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IOpenSearchInfo.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/IOpenSearchInfo.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ export interface ISyncableDoc {
2
+ id: string;
3
+ [key: string]: unknown;
4
+ }
5
+ export interface ISyncableIndex {
6
+ readonly baseName: string;
7
+ readonly mapping: Record<string, unknown>;
8
+ fetchAll(): Promise<ISyncableDoc[]>;
9
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=ISyncableIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISyncableIndex.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/ISyncableIndex.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { ILogger } from "../../logger";
2
+ import { Client, ClientOptions } from "@opensearch-project/opensearch";
3
+ import { IOpenSearchConnector } from "./IOpenSearchConnector";
4
+ import { IOpenSearchInfo } from "./IOpenSearchInfo";
5
+ export declare class OpenSearchConnector implements IOpenSearchConnector {
6
+ private readonly openSearchInfo;
7
+ private readonly log;
8
+ private readonly clientOptions?;
9
+ private static readonly REFRESH_SAFETY_MARGIN_MS;
10
+ private connection?;
11
+ private tokenExpiresAt?;
12
+ constructor(openSearchInfo: IOpenSearchInfo, log: ILogger, clientOptions?: ClientOptions | undefined);
13
+ connect: (additionalOptions?: ClientOptions) => Promise<Client>;
14
+ getConnection: () => Client;
15
+ isConnected: () => Promise<boolean>;
16
+ disconnect: () => Promise<void>;
17
+ dispose: () => Promise<void>;
18
+ private getOptions;
19
+ private clearConnection;
20
+ private isTokenStale;
21
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenSearchConnector = void 0;
4
+ const opensearch_1 = require("@opensearch-project/opensearch");
5
+ const errors_1 = require("@golemio/errors");
6
+ class OpenSearchConnector {
7
+ constructor(openSearchInfo, log, clientOptions) {
8
+ this.openSearchInfo = openSearchInfo;
9
+ this.log = log;
10
+ this.clientOptions = clientOptions;
11
+ this.connect = async (additionalOptions) => {
12
+ if (!this.openSearchInfo.url) {
13
+ throw new errors_1.RecoverableError("The OpenSearch URL cannot be undefined.", this.constructor.name);
14
+ }
15
+ if (this.connection && !this.isTokenStale()) {
16
+ return this.connection;
17
+ }
18
+ if (this.connection && this.isTokenStale()) {
19
+ this.log.info("OpenSearch connection recreated due to stale Bearer token");
20
+ await this.disconnect();
21
+ }
22
+ try {
23
+ const options = await this.getOptions(additionalOptions);
24
+ this.connection = new opensearch_1.Client(options);
25
+ await this.connection.ping();
26
+ this.log.info("Connected to OpenSearch!");
27
+ return this.connection;
28
+ }
29
+ catch (err) {
30
+ if (this.connection) {
31
+ try {
32
+ await this.connection.close();
33
+ }
34
+ catch (closeErr) {
35
+ this.log.warn(`Failed to close OpenSearch connection during error cleanup: ${closeErr.message}`);
36
+ }
37
+ }
38
+ this.clearConnection();
39
+ throw new errors_1.RecoverableError("Error while connecting to OpenSearch.", this.constructor.name, err);
40
+ }
41
+ };
42
+ this.getConnection = () => {
43
+ if (!this.connection) {
44
+ throw new errors_1.RecoverableError("OpenSearch connection does not exist. First call connect() method.", this.constructor.name);
45
+ }
46
+ return this.connection;
47
+ };
48
+ this.isConnected = async () => {
49
+ if (!this.connection) {
50
+ return false;
51
+ }
52
+ try {
53
+ await this.connection.ping();
54
+ return true;
55
+ }
56
+ catch (err) {
57
+ this.log.info(`Unable to test connection to OpenSearch due to: "${err.message}".`);
58
+ try {
59
+ await this.connection.close();
60
+ }
61
+ catch (closeErr) {
62
+ this.log.warn(`Failed to close OpenSearch connection during cleanup: ${closeErr.message}`);
63
+ }
64
+ this.clearConnection();
65
+ return false;
66
+ }
67
+ };
68
+ this.disconnect = async () => {
69
+ this.log.info("OpenSearch disconnect called");
70
+ if (this.connection) {
71
+ await this.connection.close();
72
+ this.clearConnection();
73
+ }
74
+ };
75
+ this.dispose = async () => {
76
+ await this.disconnect();
77
+ };
78
+ }
79
+ async getOptions(additionalOptions) {
80
+ const { url, rejectUnauthorized, getBearerToken } = this.openSearchInfo;
81
+ const merged = {
82
+ node: url,
83
+ maxRetries: 3,
84
+ ssl: { rejectUnauthorized: rejectUnauthorized ?? true },
85
+ ...this.clientOptions,
86
+ ...additionalOptions,
87
+ };
88
+ if (getBearerToken) {
89
+ const accessToken = await getBearerToken();
90
+ merged.headers = {
91
+ ...merged.headers,
92
+ Authorization: `Bearer ${accessToken.token}`,
93
+ };
94
+ this.tokenExpiresAt =
95
+ accessToken.refreshAfterTimestamp ??
96
+ accessToken.expiresOnTimestamp - OpenSearchConnector.REFRESH_SAFETY_MARGIN_MS;
97
+ }
98
+ return merged;
99
+ }
100
+ clearConnection() {
101
+ this.connection = undefined;
102
+ this.tokenExpiresAt = undefined;
103
+ }
104
+ isTokenStale() {
105
+ if (this.tokenExpiresAt === undefined) {
106
+ return false;
107
+ }
108
+ return Date.now() >= this.tokenExpiresAt;
109
+ }
110
+ }
111
+ exports.OpenSearchConnector = OpenSearchConnector;
112
+ OpenSearchConnector.REFRESH_SAFETY_MARGIN_MS = 5 * 60 * 1000;
113
+ //# sourceMappingURL=OpenSearchConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenSearchConnector.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/OpenSearchConnector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { ILogger } from "../../logger";
2
+ import { IOpenSearchConnector } from "./IOpenSearchConnector";
3
+ import { ISyncableDoc } from "./ISyncableIndex";
4
+ export type IndexCount = number | "not_initialized";
5
+ export type HealthStatus = "ok" | "unreachable" | "disabled";
6
+ export interface IOpenSearchServiceConfig {
7
+ namespace: string;
8
+ enabled: boolean;
9
+ }
10
+ export declare class OpenSearchService {
11
+ private readonly connector;
12
+ private readonly logger;
13
+ readonly namespace: string;
14
+ readonly enabled: boolean;
15
+ constructor(connector: IOpenSearchConnector, logger: ILogger, config: IOpenSearchServiceConfig);
16
+ healthCheck(): Promise<HealthStatus>;
17
+ createIndex(baseName: string, mapping: Record<string, unknown>): Promise<"created" | "exists">;
18
+ bulkIndex(baseName: string, documents: ISyncableDoc[]): Promise<void>;
19
+ retainOnly(baseName: string, keepIds: Set<string>): Promise<IndexCount>;
20
+ count(baseName: string): Promise<IndexCount>;
21
+ private indexName;
22
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenSearchService = void 0;
4
+ const errors_1 = require("@golemio/errors");
5
+ const opensearch_1 = require("@opensearch-project/opensearch");
6
+ class OpenSearchService {
7
+ constructor(connector, logger, config) {
8
+ this.connector = connector;
9
+ this.logger = logger;
10
+ this.enabled = config.enabled;
11
+ this.namespace = config.namespace;
12
+ if (this.enabled && !this.namespace) {
13
+ throw new errors_1.GeneralError("OpenSearchService: namespace is required when enabled=true. Set OPENSEARCH_NAMESPACE env var.", this.constructor.name, undefined, 500);
14
+ }
15
+ if (this.enabled) {
16
+ this.logger.info(`OpenSearchService initialized (namespace=${this.namespace})`);
17
+ }
18
+ }
19
+ async healthCheck() {
20
+ if (!this.enabled)
21
+ return "disabled";
22
+ try {
23
+ const client = await this.connector.connect();
24
+ await client.ping();
25
+ return "ok";
26
+ }
27
+ catch (error) {
28
+ this.logger.warn("OpenSearchService healthCheck failed", error);
29
+ return "unreachable";
30
+ }
31
+ }
32
+ async createIndex(baseName, mapping) {
33
+ const index = this.indexName(baseName);
34
+ try {
35
+ const client = await this.connector.connect();
36
+ await client.indices.create({ index, body: mapping });
37
+ this.logger.info(`OpenSearchService index ${index} created`);
38
+ return "created";
39
+ }
40
+ catch (error) {
41
+ if (error instanceof opensearch_1.errors.ResponseError &&
42
+ error.body?.error?.type === "resource_already_exists_exception") {
43
+ return "exists";
44
+ }
45
+ throw new errors_1.RecoverableError(`Failed to create index ${index}`, this.constructor.name, error, 500);
46
+ }
47
+ }
48
+ async bulkIndex(baseName, documents) {
49
+ if (documents.length === 0)
50
+ return;
51
+ const index = this.indexName(baseName);
52
+ try {
53
+ const client = await this.connector.connect();
54
+ const stats = await client.helpers.bulk({
55
+ datasource: documents,
56
+ onDocument: (doc) => ({
57
+ index: { _index: index, _id: String(doc.id) },
58
+ }),
59
+ });
60
+ if (stats.failed > 0) {
61
+ this.logger.warn(`OpenSearchService bulk save had ${stats.failed} failed items in ${index} ` +
62
+ `(${stats.retry} retried, ${stats.time}ms)`);
63
+ }
64
+ }
65
+ catch (error) {
66
+ throw new errors_1.RecoverableError(`Failed to bulk index ${index}`, this.constructor.name, error, 500);
67
+ }
68
+ }
69
+ async retainOnly(baseName, keepIds) {
70
+ if (keepIds.size === 0) {
71
+ this.logger.warn(`OpenSearchService retainOnly called with empty keepIds for ${baseName}, ` + "skipping to prevent full index wipe");
72
+ return 0;
73
+ }
74
+ const index = this.indexName(baseName);
75
+ const idsToKeep = Array.from(keepIds);
76
+ try {
77
+ const client = await this.connector.connect();
78
+ const response = await client.deleteByQuery({
79
+ index,
80
+ body: {
81
+ query: {
82
+ bool: {
83
+ must_not: [{ ids: { values: idsToKeep } }],
84
+ },
85
+ },
86
+ },
87
+ }, { ignore: [404] });
88
+ if (response.statusCode === 404)
89
+ return "not_initialized";
90
+ const responseBody = response.body;
91
+ const deletedCount = responseBody.deleted ?? 0;
92
+ if (deletedCount > 0) {
93
+ this.logger.info(`OpenSearchService deleted ${deletedCount} orphans from ${index}`);
94
+ }
95
+ return deletedCount;
96
+ }
97
+ catch (error) {
98
+ throw new errors_1.RecoverableError(`Failed to prune ${index}`, this.constructor.name, error, 500);
99
+ }
100
+ }
101
+ async count(baseName) {
102
+ const index = this.indexName(baseName);
103
+ try {
104
+ const client = await this.connector.connect();
105
+ const response = await client.count({ index }, { ignore: [404] });
106
+ if (response.statusCode === 404)
107
+ return "not_initialized";
108
+ return response.body.count;
109
+ }
110
+ catch (error) {
111
+ throw new errors_1.RecoverableError(`Failed to count ${index}`, this.constructor.name, error, 500);
112
+ }
113
+ }
114
+ indexName(baseName) {
115
+ return `${this.namespace}_${baseName}`;
116
+ }
117
+ }
118
+ exports.OpenSearchService = OpenSearchService;
119
+ //# sourceMappingURL=OpenSearchService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenSearchService.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/OpenSearchService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ILogger } from "../../logger";
2
+ import { OpenSearchService } from "./OpenSearchService";
3
+ import { ISyncableIndex } from "./ISyncableIndex";
4
+ export declare class OpenSearchSyncOrchestrator {
5
+ private readonly openSearchService;
6
+ private readonly syncableIndexes;
7
+ private readonly logger;
8
+ private isRunning;
9
+ constructor(openSearchService: OpenSearchService, syncableIndexes: ISyncableIndex[], logger: ILogger);
10
+ execute: () => Promise<void>;
11
+ initIndexes(): Promise<void>;
12
+ private syncIndex;
13
+ private extractIdsToKeep;
14
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenSearchSyncOrchestrator = void 0;
4
+ const errors_1 = require("@golemio/errors");
5
+ class OpenSearchSyncOrchestrator {
6
+ constructor(openSearchService, syncableIndexes, logger) {
7
+ this.openSearchService = openSearchService;
8
+ this.syncableIndexes = syncableIndexes;
9
+ this.logger = logger;
10
+ this.isRunning = false;
11
+ this.execute = async () => {
12
+ if (!this.openSearchService.enabled) {
13
+ this.logger.warn("OpenSearchSyncOrchestrator skipped, OpenSearch sync is disabled");
14
+ return;
15
+ }
16
+ if (this.isRunning) {
17
+ this.logger.warn("OpenSearchSyncOrchestrator previous run still in progress, skipping");
18
+ return;
19
+ }
20
+ this.isRunning = true;
21
+ this.logger.debug("OpenSearchSyncOrchestrator executed");
22
+ const startTime = Date.now();
23
+ try {
24
+ for (const syncableIndex of this.syncableIndexes) {
25
+ await this.syncIndex(syncableIndex);
26
+ }
27
+ this.logger.info(`OpenSearchSyncOrchestrator completed in ${Date.now() - startTime}ms`);
28
+ }
29
+ finally {
30
+ this.isRunning = false;
31
+ this.logger.debug("OpenSearchSyncOrchestrator done");
32
+ }
33
+ };
34
+ }
35
+ async initIndexes() {
36
+ if (!this.openSearchService.enabled)
37
+ return;
38
+ const failed = [];
39
+ for (const syncableIndex of this.syncableIndexes) {
40
+ try {
41
+ await this.openSearchService.createIndex(syncableIndex.baseName, syncableIndex.mapping);
42
+ const count = await this.openSearchService.count(syncableIndex.baseName);
43
+ if (count === 0 || count === "not_initialized") {
44
+ this.logger.info(`OpenSearchSyncOrchestrator ${syncableIndex.baseName} is empty (count=${count}), seeding from source`);
45
+ await this.syncIndex(syncableIndex);
46
+ }
47
+ }
48
+ catch (error) {
49
+ const wrappedError = new errors_1.RecoverableError(`initIndexes(${syncableIndex.baseName}) failed`, this.constructor.name, error);
50
+ this.logger.error(wrappedError.message, wrappedError);
51
+ failed.push(syncableIndex.baseName);
52
+ }
53
+ }
54
+ if (failed.length > 0) {
55
+ throw new errors_1.RecoverableError(`Failed to initialize OpenSearch indexes: ${failed.join(", ")}`, this.constructor.name);
56
+ }
57
+ this.logger.info("OpenSearchSyncOrchestrator indexes initialized");
58
+ }
59
+ async syncIndex(syncableIndex) {
60
+ const startTime = Date.now();
61
+ try {
62
+ const documents = await syncableIndex.fetchAll();
63
+ await this.openSearchService.bulkIndex(syncableIndex.baseName, documents);
64
+ await this.openSearchService.retainOnly(syncableIndex.baseName, this.extractIdsToKeep(documents));
65
+ this.logger.info(`OpenSearchSyncOrchestrator synced ${syncableIndex.baseName} = ${documents.length} docs ` +
66
+ `in ${Date.now() - startTime}ms`);
67
+ }
68
+ catch (error) {
69
+ this.logger.error(`OpenSearchSyncOrchestrator syncIndex(${syncableIndex.baseName}) was not successful ` +
70
+ (error instanceof Error ? error.message : String(error)), error);
71
+ }
72
+ }
73
+ extractIdsToKeep(documents) {
74
+ return new Set(documents.map((document) => document.id));
75
+ }
76
+ }
77
+ exports.OpenSearchSyncOrchestrator = OpenSearchSyncOrchestrator;
78
+ //# sourceMappingURL=OpenSearchSyncOrchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenSearchSyncOrchestrator.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/OpenSearchSyncOrchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Types } from "@opensearch-project/opensearch";
2
+ export declare const czechAnalysis: {
3
+ analysis: Types.Indices_Common.IndexSettingsAnalysis;
4
+ };
5
+ export declare const defaultIndexSettings: Types.Indices_Common.IndexSettings;
6
+ export declare const czechText: () => Types.Common_Mapping.TextProperty;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.czechText = exports.defaultIndexSettings = exports.czechAnalysis = void 0;
4
+ exports.czechAnalysis = {
5
+ analysis: {
6
+ filter: {
7
+ czech_stop: { type: "stop", stopwords: "_czech_" },
8
+ czech_stem: { type: "stemmer", language: "czech" },
9
+ czech_ascii: { type: "asciifolding", preserve_original: true },
10
+ },
11
+ analyzer: {
12
+ czech_analyzer: {
13
+ type: "custom",
14
+ tokenizer: "standard",
15
+ // pořadí záleží: stemming musí být před asciifolding
16
+ filter: ["lowercase", "czech_stop", "czech_stem", "czech_ascii"],
17
+ },
18
+ },
19
+ },
20
+ };
21
+ exports.defaultIndexSettings = {
22
+ number_of_shards: 1,
23
+ ...exports.czechAnalysis,
24
+ };
25
+ const czechText = () => ({
26
+ type: "text",
27
+ analyzer: "czech_analyzer",
28
+ });
29
+ exports.czechText = czechText;
30
+ //# sourceMappingURL=czechAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"czechAnalyzer.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/czechAnalyzer.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAA6D;IACnF,QAAQ,EAAE;QACN,MAAM,EAAE;YACJ,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE;YAClD,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE;YAClD,WAAW,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,iBAAiB,EAAE,IAAI,EAAE;SACjE;QACD,QAAQ,EAAE;YACN,cAAc,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,UAAU;gBACrB,qDAAqD;gBACrD,MAAM,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,CAAC;aACnE;SACJ;KACJ;CACJ,CAAC;AAEW,QAAA,oBAAoB,GAAuC;IACpE,gBAAgB,EAAE,CAAC;IACnB,GAAG,qBAAa;CACnB,CAAC;AAEK,MAAM,SAAS,GAAG,GAAsC,EAAE,CAAC,CAAC;IAC/D,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,gBAAgB;CAC7B,CAAC,CAAC;AAHU,QAAA,SAAS,aAGnB"}
@@ -0,0 +1,7 @@
1
+ export { czechAnalysis, defaultIndexSettings, czechText } from "./czechAnalyzer";
2
+ export { OpenSearchConnector } from "./OpenSearchConnector";
3
+ export type { IOpenSearchConnector } from "./IOpenSearchConnector";
4
+ export { OpenSearchService } from "./OpenSearchService";
5
+ export type { IOpenSearchInfo } from "./IOpenSearchInfo";
6
+ export { OpenSearchSyncOrchestrator } from "./OpenSearchSyncOrchestrator";
7
+ export type { ISyncableIndex, ISyncableDoc } from "./ISyncableIndex";
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenSearchSyncOrchestrator = exports.OpenSearchService = exports.OpenSearchConnector = exports.czechText = exports.defaultIndexSettings = exports.czechAnalysis = void 0;
4
+ var czechAnalyzer_1 = require("./czechAnalyzer");
5
+ Object.defineProperty(exports, "czechAnalysis", { enumerable: true, get: function () { return czechAnalyzer_1.czechAnalysis; } });
6
+ Object.defineProperty(exports, "defaultIndexSettings", { enumerable: true, get: function () { return czechAnalyzer_1.defaultIndexSettings; } });
7
+ Object.defineProperty(exports, "czechText", { enumerable: true, get: function () { return czechAnalyzer_1.czechText; } });
8
+ var OpenSearchConnector_1 = require("./OpenSearchConnector");
9
+ Object.defineProperty(exports, "OpenSearchConnector", { enumerable: true, get: function () { return OpenSearchConnector_1.OpenSearchConnector; } });
10
+ var OpenSearchService_1 = require("./OpenSearchService");
11
+ Object.defineProperty(exports, "OpenSearchService", { enumerable: true, get: function () { return OpenSearchService_1.OpenSearchService; } });
12
+ var OpenSearchSyncOrchestrator_1 = require("./OpenSearchSyncOrchestrator");
13
+ Object.defineProperty(exports, "OpenSearchSyncOrchestrator", { enumerable: true, get: function () { return OpenSearchSyncOrchestrator_1.OpenSearchSyncOrchestrator; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/helpers/data-access/opensearch/index.ts"],"names":[],"mappings":";;;AAAA,iDAAiF;AAAxE,8GAAA,aAAa,OAAA;AAAE,qHAAA,oBAAoB,OAAA;AAAE,0GAAA,SAAS,OAAA;AACvD,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAE5B,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA;AAE1B,2EAA0E;AAAjE,wIAAA,0BAA0B,OAAA"}
package/dist/index.d.ts CHANGED
@@ -2,3 +2,5 @@ export * as InputGateway from "./input-gateway/index";
2
2
  export * as IntegrationEngine from "./integration-engine/index";
3
3
  export * as OutputGateway from "./output-gateway/index";
4
4
  export * as SchemaDefinitions from "./schema-definitions/index";
5
+ export * as AzureHelpers from "./helpers/data-access/azure/index";
6
+ export * as OpenSearchHelpers from "./helpers/data-access/opensearch/index";
package/dist/index.js CHANGED
@@ -23,10 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.SchemaDefinitions = exports.OutputGateway = exports.IntegrationEngine = exports.InputGateway = void 0;
26
+ exports.OpenSearchHelpers = exports.AzureHelpers = exports.SchemaDefinitions = exports.OutputGateway = exports.IntegrationEngine = exports.InputGateway = void 0;
27
27
  // Library exports
28
28
  exports.InputGateway = __importStar(require("./input-gateway/index"));
29
29
  exports.IntegrationEngine = __importStar(require("./integration-engine/index"));
30
30
  exports.OutputGateway = __importStar(require("./output-gateway/index"));
31
31
  exports.SchemaDefinitions = __importStar(require("./schema-definitions/index"));
32
+ exports.AzureHelpers = __importStar(require("./helpers/data-access/azure/index"));
33
+ exports.OpenSearchHelpers = __importStar(require("./helpers/data-access/opensearch/index"));
32
34
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kBAAkB;AAClB,sEAA0C;AAC1C,gFAA+C;AAC/C,wEAA2C;AAC3C,gFAAgD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kBAAkB;AAClB,sEAA0C;AAC1C,gFAA+C;AAC/C,wEAA2C;AAC3C,gFAAgD;AAChD,kFAAiE;AACjE,4FAA2E"}
@@ -0,0 +1 @@
1
+ export * from "@opensearch-project/opensearch";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("@opensearch-project/opensearch"), exports);
18
+ //# sourceMappingURL=opensearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opensearch.js","sourceRoot":"","sources":["../../src/shared/opensearch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golemio/core",
3
- "version": "3.1.0-dev.2542798507",
3
+ "version": "3.1.0-dev.2556337509",
4
4
  "description": "Golemio Core Module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -77,6 +77,7 @@
77
77
  "@golemio/errors": "2.0.7",
78
78
  "@golemio/validator": "0.3.6",
79
79
  "@google-cloud/storage": "^7.19.0",
80
+ "@opensearch-project/opensearch": "^3.6.0",
80
81
  "@opentelemetry/api": "^1.9.0",
81
82
  "@opentelemetry/exporter-trace-otlp-grpc": "^0.214.0",
82
83
  "@opentelemetry/instrumentation-amqplib": "^0.50.0",