@webiny/api-sync-ddb-to-opensearch 6.6.0-alpha.0
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/LICENSE +21 -0
- package/README.md +11 -0
- package/createDdbToOpenSearchStreamHandler.d.ts +4 -0
- package/createDdbToOpenSearchStreamHandler.js +28 -0
- package/createDdbToOpenSearchStreamHandler.js.map +1 -0
- package/features/DdbOperationsBuilder/DdbOperationsBuilder.d.ts +17 -0
- package/features/DdbOperationsBuilder/DdbOperationsBuilder.js +67 -0
- package/features/DdbOperationsBuilder/DdbOperationsBuilder.js.map +1 -0
- package/features/DdbOperationsBuilder/feature.d.ts +4 -0
- package/features/DdbOperationsBuilder/feature.js +11 -0
- package/features/DdbOperationsBuilder/feature.js.map +1 -0
- package/features/DdbToOpenSearchFeature.d.ts +8 -0
- package/features/DdbToOpenSearchFeature.js +25 -0
- package/features/DdbToOpenSearchFeature.js.map +1 -0
- package/features/DdbToOpenSearchHandler/DdbToOpenSearchHandler.d.ts +13 -0
- package/features/DdbToOpenSearchHandler/DdbToOpenSearchHandler.js +38 -0
- package/features/DdbToOpenSearchHandler/DdbToOpenSearchHandler.js.map +1 -0
- package/features/DdbToOpenSearchHandler/feature.d.ts +4 -0
- package/features/DdbToOpenSearchHandler/feature.js +11 -0
- package/features/DdbToOpenSearchHandler/feature.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/marshall.d.ts +7 -0
- package/marshall.js +12 -0
- package/marshall.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Webiny
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @webiny/api-sync-ddb-to-opensearch
|
|
2
|
+
|
|
3
|
+
> [!NOTE]
|
|
4
|
+
> This package is part of the [Webiny](https://www.webiny.com) monorepo.
|
|
5
|
+
> It’s **included in every Webiny project by default** and is not meant to be used as a standalone package.
|
|
6
|
+
|
|
7
|
+
📘 **Documentation:** [https://www.webiny.com/docs](https://www.webiny.com/docs)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
_This README file is automatically generated during the publish process._
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Client } from "@webiny/api-opensearch/client.js";
|
|
2
|
+
import type { DynamoDBStreamEvent } from "@webiny/aws-sdk/types/index.js";
|
|
3
|
+
export type DdbToOpenSearchStreamHandler = (event: DynamoDBStreamEvent) => Promise<void>;
|
|
4
|
+
export declare const createDdbToOpenSearchStreamHandler: (client: Client) => DdbToOpenSearchStreamHandler;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Container } from "@webiny/feature/api";
|
|
2
|
+
import { RequestContainer } from "@webiny/event-handler-core";
|
|
3
|
+
import { DynamoDBEventHandler } from "@webiny/event-handler-aws/abstractions/handlers/DynamoDBEventHandler.js";
|
|
4
|
+
import { TimerFeature } from "@webiny/utils/features/Timer/feature.js";
|
|
5
|
+
import { ProcessEnvFeature } from "@webiny/stdlib/node";
|
|
6
|
+
import { DdbToOpenSearchFeature } from "./features/DdbToOpenSearchFeature.js";
|
|
7
|
+
const createDdbToOpenSearchStreamHandler = (client)=>{
|
|
8
|
+
const container = new Container();
|
|
9
|
+
container.registerInstance(RequestContainer, container);
|
|
10
|
+
ProcessEnvFeature.register(container);
|
|
11
|
+
TimerFeature.register(container, {
|
|
12
|
+
getRemainingSeconds: ()=>900,
|
|
13
|
+
getRemainingMilliseconds: ()=>900000
|
|
14
|
+
});
|
|
15
|
+
DdbToOpenSearchFeature.register(container, {
|
|
16
|
+
client
|
|
17
|
+
});
|
|
18
|
+
const handler = container.resolve(DynamoDBEventHandler);
|
|
19
|
+
return async (event)=>{
|
|
20
|
+
await handler.execute({
|
|
21
|
+
event,
|
|
22
|
+
metadata: {}
|
|
23
|
+
}, ()=>Promise.resolve());
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export { createDdbToOpenSearchStreamHandler };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=createDdbToOpenSearchStreamHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createDdbToOpenSearchStreamHandler.js","sources":["../src/createDdbToOpenSearchStreamHandler.ts"],"sourcesContent":["import { Container } from \"@webiny/feature/api\";\nimport { RequestContainer } from \"@webiny/event-handler-core\";\nimport { DynamoDBEventHandler } from \"@webiny/event-handler-aws/abstractions/handlers/DynamoDBEventHandler.js\";\nimport { TimerFeature } from \"@webiny/utils/features/Timer/feature.js\";\nimport { ProcessEnvFeature } from \"@webiny/stdlib/node\";\nimport { DdbToOpenSearchFeature } from \"./features/DdbToOpenSearchFeature.js\";\nimport type { Client } from \"@webiny/api-opensearch/client.js\";\nimport type { DynamoDBStreamEvent } from \"@webiny/aws-sdk/types/index.js\";\n\nexport type DdbToOpenSearchStreamHandler = (event: DynamoDBStreamEvent) => Promise<void>;\n\nexport const createDdbToOpenSearchStreamHandler = (\n client: Client\n): DdbToOpenSearchStreamHandler => {\n const container = new Container();\n container.registerInstance(RequestContainer, container);\n\n // Existing behavior: MAX_RUNNING_TIME = 900 hardcoded.\n // In real Lambda deployments, the handler bootstrap should register a Timer\n // that wraps context.getRemainingTimeInMillis(). This factory matches current behavior.\n ProcessEnvFeature.register(container);\n TimerFeature.register(container, {\n getRemainingSeconds: () => 900,\n getRemainingMilliseconds: () => 900 * 1000\n });\n\n DdbToOpenSearchFeature.register(container, { client });\n\n const handler = container.resolve(DynamoDBEventHandler);\n\n return async (event: DynamoDBStreamEvent): Promise<void> => {\n await handler.execute({ event, metadata: {} }, () => Promise.resolve());\n };\n};\n"],"names":["createDdbToOpenSearchStreamHandler","client","container","Container","RequestContainer","ProcessEnvFeature","TimerFeature","DdbToOpenSearchFeature","handler","DynamoDBEventHandler","event","Promise"],"mappings":";;;;;;AAWO,MAAMA,qCAAqC,CAC9CC;IAEA,MAAMC,YAAY,IAAIC;IACtBD,UAAU,gBAAgB,CAACE,kBAAkBF;IAK7CG,kBAAkB,QAAQ,CAACH;IAC3BI,aAAa,QAAQ,CAACJ,WAAW;QAC7B,qBAAqB,IAAM;QAC3B,0BAA0B,IAAM;IACpC;IAEAK,uBAAuB,QAAQ,CAACL,WAAW;QAAED;IAAO;IAEpD,MAAMO,UAAUN,UAAU,OAAO,CAACO;IAElC,OAAO,OAAOC;QACV,MAAMF,QAAQ,OAAO,CAAC;YAAEE;YAAO,UAAU,CAAC;QAAE,GAAG,IAAMC,QAAQ,OAAO;IACxE;AACJ"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DynamoDBRecord } from "@webiny/aws-sdk/types/index.js";
|
|
2
|
+
import { OperationsBuilder } from "@webiny/api-sync-to-opensearch/features/OperationsBuilder/abstraction.js";
|
|
3
|
+
import type { Operations } from "@webiny/api-sync-to-opensearch/features/Operations/abstractions/Operations.js";
|
|
4
|
+
import { OperationsFactory } from "@webiny/api-sync-to-opensearch/features/Operations/abstractions/OperationsFactory.js";
|
|
5
|
+
import { CompressionHandler } from "@webiny/utils/exports/api.js";
|
|
6
|
+
declare class DdbOperationsBuilderImpl implements OperationsBuilder.Interface<DynamoDBRecord> {
|
|
7
|
+
private readonly compressor;
|
|
8
|
+
private readonly operationsFactory;
|
|
9
|
+
constructor(compressor: CompressionHandler.Interface, operationsFactory: OperationsFactory.Interface);
|
|
10
|
+
build(params: {
|
|
11
|
+
records: DynamoDBRecord[];
|
|
12
|
+
}): Promise<Operations.Interface>;
|
|
13
|
+
}
|
|
14
|
+
export declare const DdbOperationsBuilder: typeof DdbOperationsBuilderImpl & {
|
|
15
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/api-sync-to-opensearch/features/OperationsBuilder/abstraction.js").IOperationsBuilder<unknown>>;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { OperationsBuilder } from "@webiny/api-sync-to-opensearch/features/OperationsBuilder/abstraction.js";
|
|
2
|
+
import { OperationType } from "@webiny/api-sync-to-opensearch/features/Operations/Operations.js";
|
|
3
|
+
import { OperationsFactory } from "@webiny/api-sync-to-opensearch/features/Operations/abstractions/OperationsFactory.js";
|
|
4
|
+
import { unmarshall } from "../../marshall.js";
|
|
5
|
+
import { CompressionHandler } from "@webiny/utils/exports/api.js";
|
|
6
|
+
class DdbOperationsBuilderImpl {
|
|
7
|
+
constructor(compressor, operationsFactory){
|
|
8
|
+
this.compressor = compressor;
|
|
9
|
+
this.operationsFactory = operationsFactory;
|
|
10
|
+
}
|
|
11
|
+
async build(params) {
|
|
12
|
+
const operations = this.operationsFactory.create();
|
|
13
|
+
for (const record of params.records){
|
|
14
|
+
if (!record.dynamodb) continue;
|
|
15
|
+
if (!record.eventName) {
|
|
16
|
+
console.error(`Could not get operation from the record, skipping event "${record.eventID}".`);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const keys = unmarshall(record.dynamodb.Keys);
|
|
20
|
+
if (!keys?.PK || !keys.SK) {
|
|
21
|
+
console.error(`Could not get keys from the record, skipping event "${record.eventID}".`);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const id = `${keys.PK}:${keys.SK}`;
|
|
25
|
+
if (record.eventName === OperationType.INSERT || record.eventName === OperationType.MODIFY) {
|
|
26
|
+
const newImage = unmarshall(record.dynamodb.NewImage);
|
|
27
|
+
if (!newImage || "object" != typeof newImage || 0 === Object.keys(newImage).length) continue;
|
|
28
|
+
if (true === newImage.ignore) continue;
|
|
29
|
+
if (!newImage.index) {
|
|
30
|
+
console.error(`Could not get index from the new image, skipping event "${record.eventID}".`);
|
|
31
|
+
console.log({
|
|
32
|
+
newImage
|
|
33
|
+
});
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const data = await this.compressor.decompress(newImage.data);
|
|
37
|
+
if (null == data) {
|
|
38
|
+
console.error(`Could not get decompressed data, skipping ES operation "${record.eventName}", ID ${id}. Skipping...`);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
operations.insert({
|
|
42
|
+
id,
|
|
43
|
+
index: newImage.index,
|
|
44
|
+
data
|
|
45
|
+
});
|
|
46
|
+
} else if (record.eventName === OperationType.REMOVE) {
|
|
47
|
+
const oldImage = unmarshall(record.dynamodb.OldImage);
|
|
48
|
+
if (!oldImage?.index) continue;
|
|
49
|
+
operations.delete({
|
|
50
|
+
id,
|
|
51
|
+
index: oldImage.index
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return operations;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const DdbOperationsBuilder = OperationsBuilder.createImplementation({
|
|
59
|
+
implementation: DdbOperationsBuilderImpl,
|
|
60
|
+
dependencies: [
|
|
61
|
+
CompressionHandler,
|
|
62
|
+
OperationsFactory
|
|
63
|
+
]
|
|
64
|
+
});
|
|
65
|
+
export { DdbOperationsBuilder };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=DdbOperationsBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/DdbOperationsBuilder/DdbOperationsBuilder.js","sources":["../../../src/features/DdbOperationsBuilder/DdbOperationsBuilder.ts"],"sourcesContent":["import type { DynamoDBRecord } from \"@webiny/aws-sdk/types/index.js\";\nimport { OperationsBuilder } from \"@webiny/api-sync-to-opensearch/features/OperationsBuilder/abstraction.js\";\nimport { OperationType } from \"@webiny/api-sync-to-opensearch/features/Operations/Operations.js\";\nimport type { Operations } from \"@webiny/api-sync-to-opensearch/features/Operations/abstractions/Operations.js\";\nimport { OperationsFactory } from \"@webiny/api-sync-to-opensearch/features/Operations/abstractions/OperationsFactory.js\";\nimport { unmarshall } from \"~/marshall.js\";\nimport { CompressionHandler } from \"@webiny/utils/exports/api.js\";\n\ninterface RecordDynamoDbImage {\n data: {\n compression: string;\n value: string;\n };\n ignore?: boolean;\n index: string;\n}\n\ninterface RecordDynamoDbKeys {\n PK: string;\n SK: string;\n}\n\nclass DdbOperationsBuilderImpl implements OperationsBuilder.Interface<DynamoDBRecord> {\n public constructor(\n private readonly compressor: CompressionHandler.Interface,\n private readonly operationsFactory: OperationsFactory.Interface\n ) {}\n\n public async build(params: { records: DynamoDBRecord[] }): Promise<Operations.Interface> {\n const operations = this.operationsFactory.create();\n for (const record of params.records) {\n if (!record.dynamodb) {\n continue;\n } else if (!record.eventName) {\n console.error(\n `Could not get operation from the record, skipping event \"${record.eventID}\".`\n );\n continue;\n }\n\n const keys = unmarshall<RecordDynamoDbKeys>(record.dynamodb.Keys);\n if (!keys?.PK || !keys.SK) {\n console.error(\n `Could not get keys from the record, skipping event \"${record.eventID}\".`\n );\n continue;\n }\n\n const id = `${keys.PK}:${keys.SK}`;\n\n if (\n record.eventName === OperationType.INSERT ||\n record.eventName === OperationType.MODIFY\n ) {\n const newImage = unmarshall<RecordDynamoDbImage>(record.dynamodb.NewImage);\n if (\n !newImage ||\n typeof newImage !== \"object\" ||\n Object.keys(newImage).length === 0\n ) {\n continue;\n } else if (newImage.ignore === true) {\n continue;\n } else if (!newImage.index) {\n console.error(\n `Could not get index from the new image, skipping event \"${record.eventID}\".`\n );\n console.log({ newImage });\n continue;\n }\n const data = await this.compressor.decompress(newImage.data);\n if (data === undefined || data === null) {\n console.error(\n `Could not get decompressed data, skipping ES operation \"${record.eventName}\", ID ${id}. Skipping...`\n );\n continue;\n }\n\n operations.insert({\n id,\n index: newImage.index,\n data\n });\n } else if (record.eventName === OperationType.REMOVE) {\n const oldImage = unmarshall<RecordDynamoDbImage>(record.dynamodb.OldImage);\n if (!oldImage?.index) {\n continue;\n }\n operations.delete({\n id,\n index: oldImage.index\n });\n }\n }\n return operations;\n }\n}\n\nexport const DdbOperationsBuilder = OperationsBuilder.createImplementation({\n implementation: DdbOperationsBuilderImpl,\n dependencies: [CompressionHandler, OperationsFactory]\n});\n"],"names":["DdbOperationsBuilderImpl","compressor","operationsFactory","params","operations","record","console","keys","unmarshall","id","OperationType","newImage","Object","data","oldImage","DdbOperationsBuilder","OperationsBuilder","CompressionHandler","OperationsFactory"],"mappings":";;;;;AAsBA,MAAMA;IACF,YACqBC,UAAwC,EACxCC,iBAA8C,CACjE;aAFmBD,UAAU,GAAVA;aACAC,iBAAiB,GAAjBA;IAClB;IAEH,MAAa,MAAMC,MAAqC,EAAiC;QACrF,MAAMC,aAAa,IAAI,CAAC,iBAAiB,CAAC,MAAM;QAChD,KAAK,MAAMC,UAAUF,OAAO,OAAO,CAAE;YACjC,IAAI,CAACE,OAAO,QAAQ,EAChB;YACG,IAAI,CAACA,OAAO,SAAS,EAAE;gBAC1BC,QAAQ,KAAK,CACT,CAAC,yDAAyD,EAAED,OAAO,OAAO,CAAC,EAAE,CAAC;gBAElF;YACJ;YAEA,MAAME,OAAOC,WAA+BH,OAAO,QAAQ,CAAC,IAAI;YAChE,IAAI,CAACE,MAAM,MAAM,CAACA,KAAK,EAAE,EAAE;gBACvBD,QAAQ,KAAK,CACT,CAAC,oDAAoD,EAAED,OAAO,OAAO,CAAC,EAAE,CAAC;gBAE7E;YACJ;YAEA,MAAMI,KAAK,GAAGF,KAAK,EAAE,CAAC,CAAC,EAAEA,KAAK,EAAE,EAAE;YAElC,IACIF,OAAO,SAAS,KAAKK,cAAc,MAAM,IACzCL,OAAO,SAAS,KAAKK,cAAc,MAAM,EAC3C;gBACE,MAAMC,WAAWH,WAAgCH,OAAO,QAAQ,CAAC,QAAQ;gBACzE,IACI,CAACM,YACD,AAAoB,YAApB,OAAOA,YACPC,AAAiC,MAAjCA,OAAO,IAAI,CAACD,UAAU,MAAM,EAE5B;gBACG,IAAIA,AAAoB,SAApBA,SAAS,MAAM,EACtB;gBACG,IAAI,CAACA,SAAS,KAAK,EAAE;oBACxBL,QAAQ,KAAK,CACT,CAAC,wDAAwD,EAAED,OAAO,OAAO,CAAC,EAAE,CAAC;oBAEjFC,QAAQ,GAAG,CAAC;wBAAEK;oBAAS;oBACvB;gBACJ;gBACA,MAAME,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAACF,SAAS,IAAI;gBAC3D,IAAIE,QAAAA,MAAqC;oBACrCP,QAAQ,KAAK,CACT,CAAC,wDAAwD,EAAED,OAAO,SAAS,CAAC,MAAM,EAAEI,GAAG,aAAa,CAAC;oBAEzG;gBACJ;gBAEAL,WAAW,MAAM,CAAC;oBACdK;oBACA,OAAOE,SAAS,KAAK;oBACrBE;gBACJ;YACJ,OAAO,IAAIR,OAAO,SAAS,KAAKK,cAAc,MAAM,EAAE;gBAClD,MAAMI,WAAWN,WAAgCH,OAAO,QAAQ,CAAC,QAAQ;gBACzE,IAAI,CAACS,UAAU,OACX;gBAEJV,WAAW,MAAM,CAAC;oBACdK;oBACA,OAAOK,SAAS,KAAK;gBACzB;YACJ;QACJ;QACA,OAAOV;IACX;AACJ;AAEO,MAAMW,uBAAuBC,kBAAkB,oBAAoB,CAAC;IACvE,gBAAgBhB;IAChB,cAAc;QAACiB;QAAoBC;KAAkB;AACzD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { DdbOperationsBuilder } from "./DdbOperationsBuilder.js";
|
|
3
|
+
const DdbOperationsBuilderFeature = createFeature({
|
|
4
|
+
name: "sync.ddb.operationsBuilder",
|
|
5
|
+
register (container) {
|
|
6
|
+
container.register(DdbOperationsBuilder);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
export { DdbOperationsBuilderFeature };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/DdbOperationsBuilder/feature.js","sources":["../../../src/features/DdbOperationsBuilder/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { DdbOperationsBuilder } from \"./DdbOperationsBuilder.js\";\n\nexport const DdbOperationsBuilderFeature = createFeature({\n name: \"sync.ddb.operationsBuilder\",\n register(container) {\n container.register(DdbOperationsBuilder);\n }\n});\n"],"names":["DdbOperationsBuilderFeature","createFeature","container","DdbOperationsBuilder"],"mappings":";;AAGO,MAAMA,8BAA8BC,cAAc;IACrD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Client } from "@webiny/api-opensearch/client.js";
|
|
2
|
+
export interface DdbToOpenSearchFeatureConfig {
|
|
3
|
+
client: Client;
|
|
4
|
+
}
|
|
5
|
+
export declare const DdbToOpenSearchFeature: {
|
|
6
|
+
name: string;
|
|
7
|
+
register(container: import("@webiny/di").Container, context: DdbToOpenSearchFeatureConfig): void;
|
|
8
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { OperationsFactoryFeature } from "@webiny/api-sync-to-opensearch/features/Operations/feature.js";
|
|
3
|
+
import { ExecuteSyncFeature } from "@webiny/api-sync-to-opensearch/features/ExecuteSync/feature.js";
|
|
4
|
+
import { ExecuteSyncWithRetryFeature } from "@webiny/api-sync-to-opensearch/features/ExecuteSyncWithRetry/feature.js";
|
|
5
|
+
import { SynchronizationBuilderFeature } from "@webiny/api-sync-to-opensearch/features/SynchronizationBuilder/feature.js";
|
|
6
|
+
import { DdbOperationsBuilderFeature } from "./DdbOperationsBuilder/feature.js";
|
|
7
|
+
import { DdbToOpenSearchHandlerFeature } from "./DdbToOpenSearchHandler/feature.js";
|
|
8
|
+
import { OpenSearchClientFeature } from "@webiny/api-opensearch/features/OpenSearchClient/feature.js";
|
|
9
|
+
import { CompressionFeature } from "@webiny/utils/features/compression/feature.js";
|
|
10
|
+
const DdbToOpenSearchFeature = createFeature({
|
|
11
|
+
name: "sync.ddb-to-opensearch",
|
|
12
|
+
register (container, config) {
|
|
13
|
+
OpenSearchClientFeature.register(container, config.client);
|
|
14
|
+
CompressionFeature.register(container);
|
|
15
|
+
OperationsFactoryFeature.register(container);
|
|
16
|
+
ExecuteSyncFeature.register(container);
|
|
17
|
+
ExecuteSyncWithRetryFeature.register(container);
|
|
18
|
+
SynchronizationBuilderFeature.register(container);
|
|
19
|
+
DdbOperationsBuilderFeature.register(container);
|
|
20
|
+
DdbToOpenSearchHandlerFeature.register(container);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
export { DdbToOpenSearchFeature };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=DdbToOpenSearchFeature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/DdbToOpenSearchFeature.js","sources":["../../src/features/DdbToOpenSearchFeature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport type { Client } from \"@webiny/api-opensearch/client.js\";\nimport { OperationsFactoryFeature } from \"@webiny/api-sync-to-opensearch/features/Operations/feature.js\";\nimport { ExecuteSyncFeature } from \"@webiny/api-sync-to-opensearch/features/ExecuteSync/feature.js\";\nimport { ExecuteSyncWithRetryFeature } from \"@webiny/api-sync-to-opensearch/features/ExecuteSyncWithRetry/feature.js\";\nimport { SynchronizationBuilderFeature } from \"@webiny/api-sync-to-opensearch/features/SynchronizationBuilder/feature.js\";\nimport { DdbOperationsBuilderFeature } from \"./DdbOperationsBuilder/feature.js\";\nimport { DdbToOpenSearchHandlerFeature } from \"./DdbToOpenSearchHandler/feature.js\";\nimport { OpenSearchClientFeature } from \"@webiny/api-opensearch/features/OpenSearchClient/feature.js\";\nimport { CompressionFeature } from \"@webiny/utils/features/compression/feature.js\";\n\nexport interface DdbToOpenSearchFeatureConfig {\n client: Client;\n}\n\nexport const DdbToOpenSearchFeature = createFeature<DdbToOpenSearchFeatureConfig>({\n name: \"sync.ddb-to-opensearch\",\n register(container, config) {\n OpenSearchClientFeature.register(container, config.client);\n CompressionFeature.register(container);\n\n OperationsFactoryFeature.register(container);\n ExecuteSyncFeature.register(container);\n ExecuteSyncWithRetryFeature.register(container);\n SynchronizationBuilderFeature.register(container);\n\n DdbOperationsBuilderFeature.register(container);\n DdbToOpenSearchHandlerFeature.register(container);\n }\n});\n"],"names":["DdbToOpenSearchFeature","createFeature","container","config","OpenSearchClientFeature","CompressionFeature","OperationsFactoryFeature","ExecuteSyncFeature","ExecuteSyncWithRetryFeature","SynchronizationBuilderFeature","DdbOperationsBuilderFeature","DdbToOpenSearchHandlerFeature"],"mappings":";;;;;;;;;AAeO,MAAMA,yBAAyBC,cAA4C;IAC9E,MAAM;IACN,UAASC,SAAS,EAAEC,MAAM;QACtBC,wBAAwB,QAAQ,CAACF,WAAWC,OAAO,MAAM;QACzDE,mBAAmB,QAAQ,CAACH;QAE5BI,yBAAyB,QAAQ,CAACJ;QAClCK,mBAAmB,QAAQ,CAACL;QAC5BM,4BAA4B,QAAQ,CAACN;QACrCO,8BAA8B,QAAQ,CAACP;QAEvCQ,4BAA4B,QAAQ,CAACR;QACrCS,8BAA8B,QAAQ,CAACT;IAC3C;AACJ"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Container } from "@webiny/feature/api";
|
|
2
|
+
import type { DynamoDBStreamEvent } from "@webiny/aws-sdk/types/index.js";
|
|
3
|
+
import { DynamoDBEventHandler, type DynamoDBResult } from "@webiny/event-handler-aws/abstractions/handlers/DynamoDBEventHandler.js";
|
|
4
|
+
import type { EventContext, NextFunction } from "@webiny/event-handler-core";
|
|
5
|
+
declare class DdbToOpenSearchHandlerImpl implements DynamoDBEventHandler.Interface {
|
|
6
|
+
private container;
|
|
7
|
+
constructor(container: Container);
|
|
8
|
+
execute(eventCtx: EventContext<DynamoDBStreamEvent>, _next: NextFunction): Promise<DynamoDBResult>;
|
|
9
|
+
}
|
|
10
|
+
export declare const DdbToOpenSearchHandler: typeof DdbToOpenSearchHandlerImpl & {
|
|
11
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-aws/abstractions/handlers/DynamoDBEventHandler.js").IDynamoDBEventHandler>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DynamoDBEventHandler } from "@webiny/event-handler-aws/abstractions/handlers/DynamoDBEventHandler.js";
|
|
2
|
+
import { RequestContainer } from "@webiny/event-handler-core";
|
|
3
|
+
import { OperationsBuilder } from "@webiny/api-sync-to-opensearch/features/OperationsBuilder/abstraction.js";
|
|
4
|
+
import { ExecuteSyncWithRetry } from "@webiny/api-sync-to-opensearch/features/ExecuteSyncWithRetry/abstraction.js";
|
|
5
|
+
const MAX_RUNNING_TIME = 900;
|
|
6
|
+
class DdbToOpenSearchHandlerImpl {
|
|
7
|
+
constructor(container){
|
|
8
|
+
this.container = container;
|
|
9
|
+
}
|
|
10
|
+
async execute(eventCtx, _next) {
|
|
11
|
+
const builder = this.container.resolve(OperationsBuilder);
|
|
12
|
+
const operations = await builder.build({
|
|
13
|
+
records: eventCtx.event.Records
|
|
14
|
+
});
|
|
15
|
+
if (0 === operations.total) return {
|
|
16
|
+
success: true,
|
|
17
|
+
processedRecords: 0
|
|
18
|
+
};
|
|
19
|
+
const executeSyncWithRetry = this.container.resolve(ExecuteSyncWithRetry);
|
|
20
|
+
await executeSyncWithRetry.execute({
|
|
21
|
+
maxRunningTime: MAX_RUNNING_TIME,
|
|
22
|
+
operations
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
processedRecords: operations.count
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const DdbToOpenSearchHandler = DynamoDBEventHandler.createImplementation({
|
|
31
|
+
implementation: DdbToOpenSearchHandlerImpl,
|
|
32
|
+
dependencies: [
|
|
33
|
+
RequestContainer
|
|
34
|
+
]
|
|
35
|
+
});
|
|
36
|
+
export { DdbToOpenSearchHandler };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=DdbToOpenSearchHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/DdbToOpenSearchHandler/DdbToOpenSearchHandler.js","sources":["../../../src/features/DdbToOpenSearchHandler/DdbToOpenSearchHandler.ts"],"sourcesContent":["import type { Container } from \"@webiny/feature/api\";\nimport type { DynamoDBStreamEvent } from \"@webiny/aws-sdk/types/index.js\";\nimport {\n DynamoDBEventHandler,\n type DynamoDBResult\n} from \"@webiny/event-handler-aws/abstractions/handlers/DynamoDBEventHandler.js\";\nimport { RequestContainer } from \"@webiny/event-handler-core\";\nimport type { EventContext, NextFunction } from \"@webiny/event-handler-core\";\nimport { OperationsBuilder } from \"@webiny/api-sync-to-opensearch/features/OperationsBuilder/abstraction.js\";\nimport { ExecuteSyncWithRetry } from \"@webiny/api-sync-to-opensearch/features/ExecuteSyncWithRetry/abstraction.js\";\n\nconst MAX_RUNNING_TIME = 900;\n\nclass DdbToOpenSearchHandlerImpl implements DynamoDBEventHandler.Interface {\n constructor(private container: Container) {}\n\n async execute(\n eventCtx: EventContext<DynamoDBStreamEvent>,\n _next: NextFunction\n ): Promise<DynamoDBResult> {\n const builder = this.container.resolve(OperationsBuilder);\n const operations = await builder.build({ records: eventCtx.event.Records });\n\n if (operations.total === 0) {\n return { success: true, processedRecords: 0 };\n }\n\n const executeSyncWithRetry = this.container.resolve(ExecuteSyncWithRetry);\n\n await executeSyncWithRetry.execute({\n maxRunningTime: MAX_RUNNING_TIME,\n operations\n });\n\n return { success: true, processedRecords: operations.count };\n }\n}\n\nexport const DdbToOpenSearchHandler = DynamoDBEventHandler.createImplementation({\n implementation: DdbToOpenSearchHandlerImpl,\n dependencies: [RequestContainer]\n});\n"],"names":["MAX_RUNNING_TIME","DdbToOpenSearchHandlerImpl","container","eventCtx","_next","builder","OperationsBuilder","operations","executeSyncWithRetry","ExecuteSyncWithRetry","DdbToOpenSearchHandler","DynamoDBEventHandler","RequestContainer"],"mappings":";;;;AAWA,MAAMA,mBAAmB;AAEzB,MAAMC;IACF,YAAoBC,SAAoB,CAAE;aAAtBA,SAAS,GAATA;IAAuB;IAE3C,MAAM,QACFC,QAA2C,EAC3CC,KAAmB,EACI;QACvB,MAAMC,UAAU,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QACvC,MAAMC,aAAa,MAAMF,QAAQ,KAAK,CAAC;YAAE,SAASF,SAAS,KAAK,CAAC,OAAO;QAAC;QAEzE,IAAII,AAAqB,MAArBA,WAAW,KAAK,EAChB,OAAO;YAAE,SAAS;YAAM,kBAAkB;QAAE;QAGhD,MAAMC,uBAAuB,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QAEpD,MAAMD,qBAAqB,OAAO,CAAC;YAC/B,gBAAgBR;YAChBO;QACJ;QAEA,OAAO;YAAE,SAAS;YAAM,kBAAkBA,WAAW,KAAK;QAAC;IAC/D;AACJ;AAEO,MAAMG,yBAAyBC,qBAAqB,oBAAoB,CAAC;IAC5E,gBAAgBV;IAChB,cAAc;QAACW;KAAiB;AACpC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { DdbToOpenSearchHandler } from "./DdbToOpenSearchHandler.js";
|
|
3
|
+
const DdbToOpenSearchHandlerFeature = createFeature({
|
|
4
|
+
name: "sync.ddb.handler",
|
|
5
|
+
register (container) {
|
|
6
|
+
container.register(DdbToOpenSearchHandler);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
export { DdbToOpenSearchHandlerFeature };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/DdbToOpenSearchHandler/feature.js","sources":["../../../src/features/DdbToOpenSearchHandler/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { DdbToOpenSearchHandler } from \"./DdbToOpenSearchHandler.js\";\n\nexport const DdbToOpenSearchHandlerFeature = createFeature({\n name: \"sync.ddb.handler\",\n register(container) {\n container.register(DdbToOpenSearchHandler);\n }\n});\n"],"names":["DdbToOpenSearchHandlerFeature","createFeature","container","DdbToOpenSearchHandler"],"mappings":";;AAGO,MAAMA,gCAAgCC,cAAc;IACvD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createDdbToOpenSearchStreamHandler } from "./createDdbToOpenSearchStreamHandler.js";
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createDdbToOpenSearchStreamHandler } from "./createDdbToOpenSearchStreamHandler.js";
|
package/marshall.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GenericRecord } from "@webiny/api/types.js";
|
|
2
|
+
import type { AttributeValue } from "@webiny/aws-sdk/types/index.js";
|
|
3
|
+
export interface MarshalledValue {
|
|
4
|
+
[key: string]: AttributeValue;
|
|
5
|
+
}
|
|
6
|
+
export declare const marshall: (value: GenericRecord) => MarshalledValue;
|
|
7
|
+
export declare const unmarshall: <T>(value?: MarshalledValue) => T | undefined;
|
package/marshall.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { marshall, unmarshall } from "@webiny/aws-sdk/client-dynamodb/index.js";
|
|
2
|
+
const marshall_marshall = (value)=>{
|
|
3
|
+
if (!value) return value;
|
|
4
|
+
return marshall(value);
|
|
5
|
+
};
|
|
6
|
+
const marshall_unmarshall = (value)=>{
|
|
7
|
+
if (!value) return;
|
|
8
|
+
return unmarshall(value);
|
|
9
|
+
};
|
|
10
|
+
export { marshall_marshall as marshall, marshall_unmarshall as unmarshall };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=marshall.js.map
|
package/marshall.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marshall.js","sources":["../src/marshall.ts"],"sourcesContent":["import {\n marshall as baseMarshall,\n unmarshall as baseUnmarshall\n} from \"@webiny/aws-sdk/client-dynamodb/index.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\nimport type { AttributeValue } from \"@webiny/aws-sdk/types/index.js\";\n\nexport interface MarshalledValue {\n [key: string]: AttributeValue;\n}\n\nexport const marshall = (value: GenericRecord): MarshalledValue => {\n if (!value) {\n return value;\n }\n return baseMarshall(value) as MarshalledValue;\n};\n\nexport const unmarshall = <T>(value?: MarshalledValue): T | undefined => {\n if (!value) {\n return undefined;\n }\n // @ts-expect-error\n return baseUnmarshall(value) as T;\n};\n"],"names":["marshall","value","baseMarshall","unmarshall","baseUnmarshall"],"mappings":";AAYO,MAAMA,oBAAW,CAACC;IACrB,IAAI,CAACA,OACD,OAAOA;IAEX,OAAOC,SAAaD;AACxB;AAEO,MAAME,sBAAa,CAAIF;IAC1B,IAAI,CAACA,OACD;IAGJ,OAAOG,WAAeH;AAC1B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@webiny/api-sync-ddb-to-opensearch",
|
|
3
|
+
"version": "6.6.0-alpha.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": "./index.js",
|
|
7
|
+
"./*": "./*"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/webiny/webiny-js.git",
|
|
12
|
+
"directory": "packages/api-sync-ddb-to-opensearch"
|
|
13
|
+
},
|
|
14
|
+
"description": "DynamoDB to OpenSearch synchronization adapter.",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Webiny Ltd.",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@webiny/api": "6.6.0-alpha.0",
|
|
19
|
+
"@webiny/api-opensearch": "6.6.0-alpha.0",
|
|
20
|
+
"@webiny/api-sync-to-opensearch": "6.6.0-alpha.0",
|
|
21
|
+
"@webiny/aws-sdk": "6.6.0-alpha.0",
|
|
22
|
+
"@webiny/event-handler-aws": "6.6.0-alpha.0",
|
|
23
|
+
"@webiny/event-handler-core": "6.6.0-alpha.0",
|
|
24
|
+
"@webiny/feature": "6.6.0-alpha.0",
|
|
25
|
+
"@webiny/stdlib": "0.0.14",
|
|
26
|
+
"@webiny/utils": "6.6.0-alpha.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@webiny/build-tools": "6.6.0-alpha.0",
|
|
30
|
+
"typescript": "7.0.2"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"adio": {
|
|
36
|
+
"ignoreDirs": [
|
|
37
|
+
"__tests__"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"webiny": {
|
|
41
|
+
"publishFrom": "dist"
|
|
42
|
+
}
|
|
43
|
+
}
|