dynamodb-expression-builder 0.2.0 → 0.3.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/README.md +4 -4
- package/dist/index.cjs +447 -12
- package/dist/index.d.cts +32 -2
- package/dist/index.d.ts +32 -2
- package/dist/index.js +437 -13
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dynamodb-expression-builder
|
|
2
2
|
|
|
3
|
-
DynamoDB expression builder and code generator. Build update, condition, filter and key condition expressions with automatic `ExpressionAttributeNames` / `ExpressionAttributeValues` aliasing — then emit the whole request as runnable code for the JavaScript SDK v3, AWS CLI, boto3 (Python), Java, Go, .NET, Rust, PartiQL or [dynamodb-toolbox](https://github.com/dynamodb-toolbox/dynamodb-toolbox). Zero dependencies.
|
|
3
|
+
DynamoDB expression builder and code generator. Build update, condition, filter and key condition expressions with automatic `ExpressionAttributeNames` / `ExpressionAttributeValues` aliasing — then emit the whole request as runnable code for the JavaScript SDK v3 (low-level or DocumentClient), AWS CLI, boto3 (Python), Java, Go, .NET, Rust, Kotlin, PHP, Ruby, PartiQL or [dynamodb-toolbox](https://github.com/dynamodb-toolbox/dynamodb-toolbox). Zero dependencies.
|
|
4
4
|
|
|
5
5
|
Hand-writing DynamoDB expressions means juggling three coupled structures — the expression string, the `#name` aliases (mandatory whenever an attribute name is one of DynamoDB's 573 reserved words), and the typed `:value` placeholders — and keeping them consistent across every operation. The AWS SDKs for [Go](https://docs.aws.amazon.com/sdk-for-go/) and [Java](https://docs.aws.amazon.com/sdk-for-java/) ship expression builders for this; the JavaScript SDK v3 [does not](https://github.com/aws/aws-sdk-js-v3/issues/3165). This package is that builder, plus something the official ones don't do in any language: code generation, so one structured request becomes a paste-ready command in whichever SDK your team actually runs.
|
|
6
6
|
|
|
@@ -45,7 +45,7 @@ emitSdkV3(request);
|
|
|
45
45
|
// })
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
The same `request` feeds every emitter — `emitCli(request)` gives the `aws dynamodb query \ …` command, `emitBoto3(request)` the Python, `emitJava` / `emitGo` / `emitDotnet` / `emitRust` the typed AttributeValue constructors for those SDKs, and `emitPartiql(request)` the equivalent `SELECT` statement (or an honest `{ok: false, reason}` where PartiQL can't express the request).
|
|
48
|
+
The same `request` feeds every emitter — `emitCli(request)` gives the `aws dynamodb query \ …` command, `emitBoto3(request)` the Python, `emitJava` / `emitGo` / `emitDotnet` / `emitRust` / `emitKotlin` / `emitPhp` the typed AttributeValue constructors for those SDKs, `emitDocClient` / `emitRuby` the native-value shapes their SDKs marshal themselves, and `emitPartiql(request)` the equivalent `SELECT` statement (or an honest `{ok: false, reason}` where PartiQL can't express the request).
|
|
49
49
|
|
|
50
50
|
Update expressions compile from a list of actions:
|
|
51
51
|
|
|
@@ -66,7 +66,7 @@ buildUpdateExpression([
|
|
|
66
66
|
|
|
67
67
|
SET idioms are first-class: `assign`, `if_not_exists`, atomic counters (`add`/`subtract`), `list_append`/`list_prepend`, plus `REMOVE` (including list elements by index) and `ADD`/`DELETE` for numbers and sets.
|
|
68
68
|
|
|
69
|
-
And `emitQueryProgram(config, format)` wraps a Query/Scan request into a complete runnable program — client setup, the request, and a `LastEvaluatedKey` pagination loop — with `format` one of `'sdk' | 'cli' | 'boto3' | 'partiql' | 'java' | 'go' | 'dotnet' | 'rust' | 'ddbtoolbox'`
|
|
69
|
+
And `emitQueryProgram(config, format)` wraps a Query/Scan request into a complete runnable program — client setup, the request, and a `LastEvaluatedKey` pagination loop — with `format` one of `'sdk' | 'docclient' | 'cli' | 'boto3' | 'partiql' | 'java' | 'go' | 'dotnet' | 'rust' | 'kotlin' | 'php' | 'ruby' | 'ddbtoolbox'` — each paginated program uses its SDK's own idiom (`paginateQuery`, `into_paginator()`, `queryPaginated` flows, `getPaginator`, pageable responses).
|
|
70
70
|
|
|
71
71
|
## API
|
|
72
72
|
|
|
@@ -76,7 +76,7 @@ Three layers, each usable on its own:
|
|
|
76
76
|
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
77
|
| Model | `TypedValue`, `makeTypedValue`, `FilterRow`, `KeyAttr`, `RangeKeyCondition`, `UpdateAction`, the `FILTER_OPERATORS` registry + per-type compatibility helpers |
|
|
78
78
|
| Builders | `buildRequest(config)` → one `CanonicalRequest` for any of GetItem/Query/Scan/Update/Put/Delete · `buildFilterExpressions` · `buildKeyConditionExpression` · `buildUpdateExpression` |
|
|
79
|
-
| Emitters | `emitSdkV3` · `emitCli` · `emitBoto3` · `emitJava` · `emitGo` · `emitDotnet` · `emitRust` · `emitPartiql` · `emitDdbToolboxProgram` · `emitQueryProgram` · `typedMapToAvMap` (tag-driven marshal) |
|
|
79
|
+
| Emitters | `emitSdkV3` · `emitDocClient` · `emitCli` · `emitBoto3` · `emitJava` · `emitGo` · `emitDotnet` · `emitRust` · `emitKotlin` · `emitPhp` · `emitRuby` · `emitPartiql` · `emitDdbToolboxProgram` · `emitQueryProgram` · `typedMapToAvMap` (tag-driven marshal) |
|
|
80
80
|
|
|
81
81
|
Placeholder namespaces never collide: keys use `#hashKey`/`#rangeKey`, filters `#filter{i}`, conditions `#cond{i}`, updates `#upd{i}` — one request can carry a key condition, a filter, a write condition and an update expression simultaneously.
|
|
82
82
|
|
package/dist/index.cjs
CHANGED
|
@@ -747,7 +747,7 @@ function hasBinaryValue(request) {
|
|
|
747
747
|
//#endregion
|
|
748
748
|
//#region src/emit/sdk-v3.ts
|
|
749
749
|
/** Operation → the `@aws-sdk/client-dynamodb` command class name. */
|
|
750
|
-
const COMMAND_BY_OP = {
|
|
750
|
+
const COMMAND_BY_OP$1 = {
|
|
751
751
|
GetItem: "GetItemCommand",
|
|
752
752
|
Query: "QueryCommand",
|
|
753
753
|
Scan: "ScanCommand",
|
|
@@ -805,11 +805,11 @@ function jsLiteral(value, indent) {
|
|
|
805
805
|
}
|
|
806
806
|
/** Emit the `new <Op>Command({...})` source snippet for a canonical request. */
|
|
807
807
|
function emitSdkV3(request) {
|
|
808
|
-
return `new ${COMMAND_BY_OP[request.operation]}(${jsLiteral(buildSdkV3Params(request), 0)})`;
|
|
808
|
+
return `new ${COMMAND_BY_OP$1[request.operation]}(${jsLiteral(buildSdkV3Params(request), 0)})`;
|
|
809
809
|
}
|
|
810
810
|
/** The `@aws-sdk/client-dynamodb` command class name for an operation. */
|
|
811
811
|
function sdkV3CommandName(operation) {
|
|
812
|
-
return COMMAND_BY_OP[operation];
|
|
812
|
+
return COMMAND_BY_OP$1[operation];
|
|
813
813
|
}
|
|
814
814
|
/**
|
|
815
815
|
* Render an arbitrary params value as the same pretty-printed JS literal
|
|
@@ -1117,7 +1117,7 @@ const REQUEST_CLASS_BY_OP$1 = {
|
|
|
1117
1117
|
Delete: "DeleteItemRequest"
|
|
1118
1118
|
};
|
|
1119
1119
|
/** Operation → the `DynamoDbClient` method. */
|
|
1120
|
-
const CLIENT_METHOD_BY_OP$
|
|
1120
|
+
const CLIENT_METHOD_BY_OP$6 = {
|
|
1121
1121
|
GetItem: "getItem",
|
|
1122
1122
|
Query: "query",
|
|
1123
1123
|
Scan: "scan",
|
|
@@ -1131,7 +1131,7 @@ function javaRequestClassName(operation) {
|
|
|
1131
1131
|
}
|
|
1132
1132
|
/** The `DynamoDbClient` method name for an operation (`query`, …). */
|
|
1133
1133
|
function javaClientMethodName(operation) {
|
|
1134
|
-
return CLIENT_METHOD_BY_OP$
|
|
1134
|
+
return CLIENT_METHOD_BY_OP$6[operation];
|
|
1135
1135
|
}
|
|
1136
1136
|
/** Java string literal — `JSON.stringify` escapes are all valid Java escapes. */
|
|
1137
1137
|
function javaString(value) {
|
|
@@ -1210,7 +1210,7 @@ const INPUT_TYPE_BY_OP = {
|
|
|
1210
1210
|
Delete: "DeleteItemInput"
|
|
1211
1211
|
};
|
|
1212
1212
|
/** Operation → the `dynamodb.Client` method. */
|
|
1213
|
-
const CLIENT_METHOD_BY_OP$
|
|
1213
|
+
const CLIENT_METHOD_BY_OP$5 = {
|
|
1214
1214
|
GetItem: "GetItem",
|
|
1215
1215
|
Query: "Query",
|
|
1216
1216
|
Scan: "Scan",
|
|
@@ -1224,7 +1224,7 @@ function goInputTypeName(operation) {
|
|
|
1224
1224
|
}
|
|
1225
1225
|
/** The `dynamodb.Client` method name for an operation. */
|
|
1226
1226
|
function goClientMethodName(operation) {
|
|
1227
|
-
return CLIENT_METHOD_BY_OP$
|
|
1227
|
+
return CLIENT_METHOD_BY_OP$5[operation];
|
|
1228
1228
|
}
|
|
1229
1229
|
/** Go string literal — `JSON.stringify` escapes are all valid Go escapes. */
|
|
1230
1230
|
function goString(value) {
|
|
@@ -1314,7 +1314,7 @@ const REQUEST_CLASS_BY_OP = {
|
|
|
1314
1314
|
Delete: "DeleteItemRequest"
|
|
1315
1315
|
};
|
|
1316
1316
|
/** Operation → the async `AmazonDynamoDBClient` method. */
|
|
1317
|
-
const CLIENT_METHOD_BY_OP$
|
|
1317
|
+
const CLIENT_METHOD_BY_OP$4 = {
|
|
1318
1318
|
GetItem: "GetItemAsync",
|
|
1319
1319
|
Query: "QueryAsync",
|
|
1320
1320
|
Scan: "ScanAsync",
|
|
@@ -1328,7 +1328,7 @@ function dotnetRequestClassName(operation) {
|
|
|
1328
1328
|
}
|
|
1329
1329
|
/** The async client method name for an operation (`QueryAsync`, …). */
|
|
1330
1330
|
function dotnetClientMethodName(operation) {
|
|
1331
|
-
return CLIENT_METHOD_BY_OP$
|
|
1331
|
+
return CLIENT_METHOD_BY_OP$4[operation];
|
|
1332
1332
|
}
|
|
1333
1333
|
/** C# string literal — `JSON.stringify` escapes are all valid C# escapes. */
|
|
1334
1334
|
function csString(value) {
|
|
@@ -1398,7 +1398,7 @@ function emitDotnet(request) {
|
|
|
1398
1398
|
//#endregion
|
|
1399
1399
|
//#region src/emit/rust.ts
|
|
1400
1400
|
/** Operation → the `aws_sdk_dynamodb::Client` fluent method. */
|
|
1401
|
-
const CLIENT_METHOD_BY_OP = {
|
|
1401
|
+
const CLIENT_METHOD_BY_OP$3 = {
|
|
1402
1402
|
GetItem: "get_item",
|
|
1403
1403
|
Query: "query",
|
|
1404
1404
|
Scan: "scan",
|
|
@@ -1408,7 +1408,7 @@ const CLIENT_METHOD_BY_OP = {
|
|
|
1408
1408
|
};
|
|
1409
1409
|
/** The `Client` method name (snake_case) for an operation. */
|
|
1410
1410
|
function rustClientMethodName(operation) {
|
|
1411
|
-
return CLIENT_METHOD_BY_OP[operation];
|
|
1411
|
+
return CLIENT_METHOD_BY_OP$3[operation];
|
|
1412
1412
|
}
|
|
1413
1413
|
/** Rust string literal — JSON escapes with the three Rust-incompatible ones fixed. */
|
|
1414
1414
|
function rustString(value) {
|
|
@@ -1450,7 +1450,7 @@ function avEntryLines(method, map, indent) {
|
|
|
1450
1450
|
* chain to `into_paginator()` instead). Exported for the program emitter.
|
|
1451
1451
|
*/
|
|
1452
1452
|
function renderRustBuilder(request, indent) {
|
|
1453
|
-
const lines = [`${indent}.${CLIENT_METHOD_BY_OP[request.operation]}()`];
|
|
1453
|
+
const lines = [`${indent}.${CLIENT_METHOD_BY_OP$3[request.operation]}()`];
|
|
1454
1454
|
lines.push(`${indent}.table_name(${rustString(request.tableName)})`);
|
|
1455
1455
|
if (request.indexName) lines.push(`${indent}.index_name(${rustString(request.indexName)})`);
|
|
1456
1456
|
if (request.key) lines.push(...avEntryLines("key", request.key, indent));
|
|
@@ -1702,6 +1702,292 @@ function emitDdbToolboxProgram(request, paginate) {
|
|
|
1702
1702
|
].filter((l) => l !== null).join("\n");
|
|
1703
1703
|
}
|
|
1704
1704
|
|
|
1705
|
+
//#endregion
|
|
1706
|
+
//#region src/emit/docclient.ts
|
|
1707
|
+
/** Operation → the `@aws-sdk/lib-dynamodb` command class. */
|
|
1708
|
+
const COMMAND_BY_OP = {
|
|
1709
|
+
GetItem: "GetCommand",
|
|
1710
|
+
Query: "QueryCommand",
|
|
1711
|
+
Scan: "ScanCommand",
|
|
1712
|
+
Update: "UpdateCommand",
|
|
1713
|
+
Put: "PutCommand",
|
|
1714
|
+
Delete: "DeleteCommand"
|
|
1715
|
+
};
|
|
1716
|
+
/** The lib-dynamodb command class name for an operation. */
|
|
1717
|
+
function docClientCommandName(operation) {
|
|
1718
|
+
return COMMAND_BY_OP[operation];
|
|
1719
|
+
}
|
|
1720
|
+
/** Render a typed map as a native-value object literal, one entry per line. */
|
|
1721
|
+
function renderNativeMap(map, indent) {
|
|
1722
|
+
const inner = `${indent} `;
|
|
1723
|
+
return `{\n${Object.entries(map).map(([name, tv]) => `${inner}${JSON.stringify(name)}: ${renderNativeValue(tv)},`).join("\n")}\n${indent}}`;
|
|
1724
|
+
}
|
|
1725
|
+
/** Render the plain string map (`ExpressionAttributeNames`). */
|
|
1726
|
+
function renderNameMap$3(map, indent) {
|
|
1727
|
+
const inner = `${indent} `;
|
|
1728
|
+
return `{\n${Object.entries(map).map(([alias, name]) => `${inner}${JSON.stringify(alias)}: ${JSON.stringify(name)},`).join("\n")}\n${indent}}`;
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Render the command's params object literal, one field per line at
|
|
1732
|
+
* `indent + 2`. Exported for the program emitter.
|
|
1733
|
+
*/
|
|
1734
|
+
function renderDocClientParams(request, indent) {
|
|
1735
|
+
const pad = `${indent} `;
|
|
1736
|
+
const fields = [`TableName: ${JSON.stringify(request.tableName)},`];
|
|
1737
|
+
if (request.indexName) fields.push(`IndexName: ${JSON.stringify(request.indexName)},`);
|
|
1738
|
+
if (request.key) fields.push(`Key: ${renderNativeMap(request.key, pad)},`);
|
|
1739
|
+
if (request.item) fields.push(`Item: ${renderNativeMap(request.item, pad)},`);
|
|
1740
|
+
if (request.keyConditionExpression) fields.push(`KeyConditionExpression: ${JSON.stringify(request.keyConditionExpression)},`);
|
|
1741
|
+
if (request.updateExpression) fields.push(`UpdateExpression: ${JSON.stringify(request.updateExpression)},`);
|
|
1742
|
+
if (request.conditionExpression) fields.push(`ConditionExpression: ${JSON.stringify(request.conditionExpression)},`);
|
|
1743
|
+
if (request.filterExpression) fields.push(`FilterExpression: ${JSON.stringify(request.filterExpression)},`);
|
|
1744
|
+
if (request.projectionExpression) fields.push(`ProjectionExpression: ${JSON.stringify(request.projectionExpression)},`);
|
|
1745
|
+
if (request.names) fields.push(`ExpressionAttributeNames: ${renderNameMap$3(request.names, pad)},`);
|
|
1746
|
+
if (request.typedValues) fields.push(`ExpressionAttributeValues: ${renderNativeMap(request.typedValues, pad)},`);
|
|
1747
|
+
if (request.limit !== void 0) fields.push(`Limit: ${request.limit},`);
|
|
1748
|
+
if (request.consistentRead) fields.push("ConsistentRead: true,");
|
|
1749
|
+
if (request.scanIndexForward === false) fields.push("ScanIndexForward: false,");
|
|
1750
|
+
if (request.exclusiveStartKey) fields.push(`ExclusiveStartKey: ${renderNativeMap(request.exclusiveStartKey, pad)},`);
|
|
1751
|
+
return [
|
|
1752
|
+
"{",
|
|
1753
|
+
...fields.map((f) => `${pad}${f}`),
|
|
1754
|
+
`${indent}}`
|
|
1755
|
+
].join("\n");
|
|
1756
|
+
}
|
|
1757
|
+
/** Emit the bare `new XCommand({…})` snippet with native values. */
|
|
1758
|
+
function emitDocClient(request) {
|
|
1759
|
+
return `new ${COMMAND_BY_OP[request.operation]}(${renderDocClientParams(request, "")})`;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
//#endregion
|
|
1763
|
+
//#region src/emit/kotlin.ts
|
|
1764
|
+
/** Operation → the `DynamoDbClient` suspend function. */
|
|
1765
|
+
const CLIENT_METHOD_BY_OP$2 = {
|
|
1766
|
+
GetItem: "getItem",
|
|
1767
|
+
Query: "query",
|
|
1768
|
+
Scan: "scan",
|
|
1769
|
+
Update: "updateItem",
|
|
1770
|
+
Put: "putItem",
|
|
1771
|
+
Delete: "deleteItem"
|
|
1772
|
+
};
|
|
1773
|
+
/** The client method name (camelCase) for an operation. */
|
|
1774
|
+
function kotlinClientMethodName(operation) {
|
|
1775
|
+
return CLIENT_METHOD_BY_OP$2[operation];
|
|
1776
|
+
}
|
|
1777
|
+
/** Kotlin string literal — JSON escapes are valid Kotlin escapes, plus `$` must
|
|
1778
|
+
* be escaped (string templates). */
|
|
1779
|
+
function ktString(value) {
|
|
1780
|
+
return JSON.stringify(value).replace(/\$/g, "\\$");
|
|
1781
|
+
}
|
|
1782
|
+
/** Decode canonical base64 into a `byteArrayOf(0x…)` literal (fail-loud). */
|
|
1783
|
+
function ktBytes(base64) {
|
|
1784
|
+
let raw;
|
|
1785
|
+
try {
|
|
1786
|
+
raw = atob(base64);
|
|
1787
|
+
} catch {
|
|
1788
|
+
throw new Error(`invalid base64 in a binary (B/BS) value: ${base64}`);
|
|
1789
|
+
}
|
|
1790
|
+
return `byteArrayOf(${Array.from(raw, (c) => `0x${c.charCodeAt(0).toString(16).padStart(2, "0")}`).join(", ")})`;
|
|
1791
|
+
}
|
|
1792
|
+
/** Render one wire AttributeValue as an `AttributeValue.…` constructor. */
|
|
1793
|
+
function renderKotlinAv(av) {
|
|
1794
|
+
if ("S" in av) return `AttributeValue.S(${ktString(av.S)})`;
|
|
1795
|
+
if ("N" in av) return `AttributeValue.N(${ktString(av.N)})`;
|
|
1796
|
+
if ("B" in av) return `AttributeValue.B(${ktBytes(av.B)})`;
|
|
1797
|
+
if ("BOOL" in av) return `AttributeValue.Bool(${av.BOOL})`;
|
|
1798
|
+
if ("SS" in av) return `AttributeValue.Ss(listOf(${av.SS.map(ktString).join(", ")}))`;
|
|
1799
|
+
if ("NS" in av) return `AttributeValue.Ns(listOf(${av.NS.map(ktString).join(", ")}))`;
|
|
1800
|
+
if ("BS" in av) return `AttributeValue.Bs(listOf(${av.BS.map(ktBytes).join(", ")}))`;
|
|
1801
|
+
return "AttributeValue.Null(true)";
|
|
1802
|
+
}
|
|
1803
|
+
/** Render a typed map as `mapOf("k" to AttributeValue.…)`, one entry per line. */
|
|
1804
|
+
function renderAvMap$1(map, indent) {
|
|
1805
|
+
const inner = `${indent} `;
|
|
1806
|
+
return `mapOf(\n${Object.entries(typedMapToAvMap(map)).map(([name, av]) => `${inner}${ktString(name)} to ${renderKotlinAv(av)},`).join("\n")}\n${indent})`;
|
|
1807
|
+
}
|
|
1808
|
+
/** Render the plain string map (`expressionAttributeNames`). */
|
|
1809
|
+
function renderNameMap$2(map, indent) {
|
|
1810
|
+
const inner = `${indent} `;
|
|
1811
|
+
return `mapOf(\n${Object.entries(map).map(([alias, name]) => `${inner}${ktString(alias)} to ${ktString(name)},`).join("\n")}\n${indent})`;
|
|
1812
|
+
}
|
|
1813
|
+
/**
|
|
1814
|
+
* Render the builder-lambda body — one property assignment per line at
|
|
1815
|
+
* `indent`. Exported for the program emitter, which wraps the same body in
|
|
1816
|
+
* either the plain suspend call or the `Paginated` flow variant.
|
|
1817
|
+
*/
|
|
1818
|
+
function renderKotlinBuilder(request, indent) {
|
|
1819
|
+
const lines = [`${indent}tableName = ${ktString(request.tableName)}`];
|
|
1820
|
+
if (request.indexName) lines.push(`${indent}indexName = ${ktString(request.indexName)}`);
|
|
1821
|
+
if (request.key) lines.push(`${indent}key = ${renderAvMap$1(request.key, indent)}`);
|
|
1822
|
+
if (request.item) lines.push(`${indent}item = ${renderAvMap$1(request.item, indent)}`);
|
|
1823
|
+
if (request.keyConditionExpression) lines.push(`${indent}keyConditionExpression = ${ktString(request.keyConditionExpression)}`);
|
|
1824
|
+
if (request.updateExpression) lines.push(`${indent}updateExpression = ${ktString(request.updateExpression)}`);
|
|
1825
|
+
if (request.conditionExpression) lines.push(`${indent}conditionExpression = ${ktString(request.conditionExpression)}`);
|
|
1826
|
+
if (request.filterExpression) lines.push(`${indent}filterExpression = ${ktString(request.filterExpression)}`);
|
|
1827
|
+
if (request.projectionExpression) lines.push(`${indent}projectionExpression = ${ktString(request.projectionExpression)}`);
|
|
1828
|
+
if (request.names) lines.push(`${indent}expressionAttributeNames = ${renderNameMap$2(request.names, indent)}`);
|
|
1829
|
+
if (request.typedValues) lines.push(`${indent}expressionAttributeValues = ${renderAvMap$1(request.typedValues, indent)}`);
|
|
1830
|
+
if (request.limit !== void 0) lines.push(`${indent}limit = ${request.limit}`);
|
|
1831
|
+
if (request.consistentRead) lines.push(`${indent}consistentRead = true`);
|
|
1832
|
+
if (request.scanIndexForward === false) lines.push(`${indent}scanIndexForward = false`);
|
|
1833
|
+
if (request.exclusiveStartKey) lines.push(`${indent}exclusiveStartKey = ${renderAvMap$1(request.exclusiveStartKey, indent)}`);
|
|
1834
|
+
return lines;
|
|
1835
|
+
}
|
|
1836
|
+
/** Emit the bare `val response = client.…{ … }` call for a canonical request. */
|
|
1837
|
+
function emitKotlin(request) {
|
|
1838
|
+
return [
|
|
1839
|
+
`val response = client.${CLIENT_METHOD_BY_OP$2[request.operation]} {`,
|
|
1840
|
+
...renderKotlinBuilder(request, " "),
|
|
1841
|
+
"}"
|
|
1842
|
+
].join("\n");
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
//#endregion
|
|
1846
|
+
//#region src/emit/php.ts
|
|
1847
|
+
/** Operation → the `DynamoDbClient` method. */
|
|
1848
|
+
const CLIENT_METHOD_BY_OP$1 = {
|
|
1849
|
+
GetItem: "getItem",
|
|
1850
|
+
Query: "query",
|
|
1851
|
+
Scan: "scan",
|
|
1852
|
+
Update: "updateItem",
|
|
1853
|
+
Put: "putItem",
|
|
1854
|
+
Delete: "deleteItem"
|
|
1855
|
+
};
|
|
1856
|
+
/** The client method name (camelCase) for an operation. */
|
|
1857
|
+
function phpClientMethodName(operation) {
|
|
1858
|
+
return CLIENT_METHOD_BY_OP$1[operation];
|
|
1859
|
+
}
|
|
1860
|
+
/** PHP single-quoted string — only `\` and `'` need escaping. */
|
|
1861
|
+
function phpString(value) {
|
|
1862
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
1863
|
+
}
|
|
1864
|
+
/** Render one wire AttributeValue as a nested `['TAG' => …]` literal. */
|
|
1865
|
+
function renderPhpAv(av) {
|
|
1866
|
+
if ("S" in av) return `['S' => ${phpString(av.S)}]`;
|
|
1867
|
+
if ("N" in av) return `['N' => ${phpString(av.N)}]`;
|
|
1868
|
+
if ("B" in av) return `['B' => base64_decode(${phpString(av.B)})]`;
|
|
1869
|
+
if ("BOOL" in av) return `['BOOL' => ${av.BOOL}]`;
|
|
1870
|
+
if ("SS" in av) return `['SS' => [${av.SS.map(phpString).join(", ")}]]`;
|
|
1871
|
+
if ("NS" in av) return `['NS' => [${av.NS.map(phpString).join(", ")}]]`;
|
|
1872
|
+
if ("BS" in av) return `['BS' => [${av.BS.map((b) => `base64_decode(${phpString(b)})`).join(", ")}]]`;
|
|
1873
|
+
return "['NULL' => true]";
|
|
1874
|
+
}
|
|
1875
|
+
/** Render a typed map as a PHP array of AV literals, one entry per line. */
|
|
1876
|
+
function renderAvMap(map, indent) {
|
|
1877
|
+
const inner = `${indent} `;
|
|
1878
|
+
return `[\n${Object.entries(typedMapToAvMap(map)).map(([name, av]) => `${inner}${phpString(name)} => ${renderPhpAv(av)},`).join("\n")}\n${indent}]`;
|
|
1879
|
+
}
|
|
1880
|
+
/** Render the plain string map (`ExpressionAttributeNames`). */
|
|
1881
|
+
function renderNameMap$1(map, indent) {
|
|
1882
|
+
const inner = `${indent} `;
|
|
1883
|
+
return `[\n${Object.entries(map).map(([alias, name]) => `${inner}${phpString(alias)} => ${phpString(name)},`).join("\n")}\n${indent}]`;
|
|
1884
|
+
}
|
|
1885
|
+
/**
|
|
1886
|
+
* Render the request array literal, one field per line at `indent + 4`.
|
|
1887
|
+
* Exported for the program emitter.
|
|
1888
|
+
*/
|
|
1889
|
+
function renderPhpParams(request, indent) {
|
|
1890
|
+
const pad = `${indent} `;
|
|
1891
|
+
const fields = [`'TableName' => ${phpString(request.tableName)},`];
|
|
1892
|
+
if (request.indexName) fields.push(`'IndexName' => ${phpString(request.indexName)},`);
|
|
1893
|
+
if (request.key) fields.push(`'Key' => ${renderAvMap(request.key, pad)},`);
|
|
1894
|
+
if (request.item) fields.push(`'Item' => ${renderAvMap(request.item, pad)},`);
|
|
1895
|
+
if (request.keyConditionExpression) fields.push(`'KeyConditionExpression' => ${phpString(request.keyConditionExpression)},`);
|
|
1896
|
+
if (request.updateExpression) fields.push(`'UpdateExpression' => ${phpString(request.updateExpression)},`);
|
|
1897
|
+
if (request.conditionExpression) fields.push(`'ConditionExpression' => ${phpString(request.conditionExpression)},`);
|
|
1898
|
+
if (request.filterExpression) fields.push(`'FilterExpression' => ${phpString(request.filterExpression)},`);
|
|
1899
|
+
if (request.projectionExpression) fields.push(`'ProjectionExpression' => ${phpString(request.projectionExpression)},`);
|
|
1900
|
+
if (request.names) fields.push(`'ExpressionAttributeNames' => ${renderNameMap$1(request.names, pad)},`);
|
|
1901
|
+
if (request.typedValues) fields.push(`'ExpressionAttributeValues' => ${renderAvMap(request.typedValues, pad)},`);
|
|
1902
|
+
if (request.limit !== void 0) fields.push(`'Limit' => ${request.limit},`);
|
|
1903
|
+
if (request.consistentRead) fields.push("'ConsistentRead' => true,");
|
|
1904
|
+
if (request.scanIndexForward === false) fields.push("'ScanIndexForward' => false,");
|
|
1905
|
+
if (request.exclusiveStartKey) fields.push(`'ExclusiveStartKey' => ${renderAvMap(request.exclusiveStartKey, pad)},`);
|
|
1906
|
+
return [
|
|
1907
|
+
"[",
|
|
1908
|
+
...fields.map((f) => `${pad}${f}`),
|
|
1909
|
+
`${indent}]`
|
|
1910
|
+
].join("\n");
|
|
1911
|
+
}
|
|
1912
|
+
/** Emit the bare `$response = $client->…([…]);` call for a canonical request. */
|
|
1913
|
+
function emitPhp(request) {
|
|
1914
|
+
return `$response = $client->${CLIENT_METHOD_BY_OP$1[request.operation]}(${renderPhpParams(request, "")});`;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
//#endregion
|
|
1918
|
+
//#region src/emit/ruby.ts
|
|
1919
|
+
/** Operation → the `Aws::DynamoDB::Client` method (snake_case). */
|
|
1920
|
+
const CLIENT_METHOD_BY_OP = {
|
|
1921
|
+
GetItem: "get_item",
|
|
1922
|
+
Query: "query",
|
|
1923
|
+
Scan: "scan",
|
|
1924
|
+
Update: "update_item",
|
|
1925
|
+
Put: "put_item",
|
|
1926
|
+
Delete: "delete_item"
|
|
1927
|
+
};
|
|
1928
|
+
/** The client method name (snake_case) for an operation. */
|
|
1929
|
+
function rubyClientMethodName(operation) {
|
|
1930
|
+
return CLIENT_METHOD_BY_OP[operation];
|
|
1931
|
+
}
|
|
1932
|
+
/** Ruby single-quoted string — only `\` and `'` need escaping. */
|
|
1933
|
+
function rubyString(value) {
|
|
1934
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
1935
|
+
}
|
|
1936
|
+
/** Render one typed value as the native Ruby literal the SDK marshals. */
|
|
1937
|
+
function renderRubyValue(tv) {
|
|
1938
|
+
switch (tv.type) {
|
|
1939
|
+
case "S": return rubyString(tv.value);
|
|
1940
|
+
case "N": return tv.value;
|
|
1941
|
+
case "B": return `Base64.decode64(${rubyString(tv.value)})`;
|
|
1942
|
+
case "BOOL": return tv.value === "true" ? "true" : "false";
|
|
1943
|
+
case "NULL": return "nil";
|
|
1944
|
+
case "SS": return `Set.new([${(tv.values ?? []).map(rubyString).join(", ")}])`;
|
|
1945
|
+
case "NS": return `Set.new([${(tv.values ?? []).join(", ")}])`;
|
|
1946
|
+
case "BS": return `Set.new([${(tv.values ?? []).map((b) => `Base64.decode64(${rubyString(b)})`).join(", ")}])`;
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
/** Render a typed map as a Ruby hash of native values, one entry per line. */
|
|
1950
|
+
function renderValueMap(map, indent) {
|
|
1951
|
+
const inner = `${indent} `;
|
|
1952
|
+
return `{\n${Object.entries(map).map(([name, tv]) => `${inner}${rubyString(name)} => ${renderRubyValue(tv)},`).join("\n")}\n${indent}}`;
|
|
1953
|
+
}
|
|
1954
|
+
/** Render the plain string map (`expression_attribute_names`). */
|
|
1955
|
+
function renderNameMap(map, indent) {
|
|
1956
|
+
const inner = `${indent} `;
|
|
1957
|
+
return `{\n${Object.entries(map).map(([alias, name]) => `${inner}${rubyString(alias)} => ${rubyString(name)},`).join("\n")}\n${indent}}`;
|
|
1958
|
+
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Render the request keyword-argument hash, one field per line at `indent + 2`.
|
|
1961
|
+
* Exported for the program emitter.
|
|
1962
|
+
*/
|
|
1963
|
+
function renderRubyParams(request, indent) {
|
|
1964
|
+
const pad = `${indent} `;
|
|
1965
|
+
const fields = [`table_name: ${rubyString(request.tableName)},`];
|
|
1966
|
+
if (request.indexName) fields.push(`index_name: ${rubyString(request.indexName)},`);
|
|
1967
|
+
if (request.key) fields.push(`key: ${renderValueMap(request.key, pad)},`);
|
|
1968
|
+
if (request.item) fields.push(`item: ${renderValueMap(request.item, pad)},`);
|
|
1969
|
+
if (request.keyConditionExpression) fields.push(`key_condition_expression: ${rubyString(request.keyConditionExpression)},`);
|
|
1970
|
+
if (request.updateExpression) fields.push(`update_expression: ${rubyString(request.updateExpression)},`);
|
|
1971
|
+
if (request.conditionExpression) fields.push(`condition_expression: ${rubyString(request.conditionExpression)},`);
|
|
1972
|
+
if (request.filterExpression) fields.push(`filter_expression: ${rubyString(request.filterExpression)},`);
|
|
1973
|
+
if (request.projectionExpression) fields.push(`projection_expression: ${rubyString(request.projectionExpression)},`);
|
|
1974
|
+
if (request.names) fields.push(`expression_attribute_names: ${renderNameMap(request.names, pad)},`);
|
|
1975
|
+
if (request.typedValues) fields.push(`expression_attribute_values: ${renderValueMap(request.typedValues, pad)},`);
|
|
1976
|
+
if (request.limit !== void 0) fields.push(`limit: ${request.limit},`);
|
|
1977
|
+
if (request.consistentRead) fields.push("consistent_read: true,");
|
|
1978
|
+
if (request.scanIndexForward === false) fields.push("scan_index_forward: false,");
|
|
1979
|
+
if (request.exclusiveStartKey) fields.push(`exclusive_start_key: ${renderValueMap(request.exclusiveStartKey, pad)},`);
|
|
1980
|
+
return [
|
|
1981
|
+
"{",
|
|
1982
|
+
...fields.map((f) => `${pad}${f}`),
|
|
1983
|
+
`${indent}}`
|
|
1984
|
+
].join("\n");
|
|
1985
|
+
}
|
|
1986
|
+
/** Emit the bare `response = client.…(…)` call for a canonical request. */
|
|
1987
|
+
function emitRuby(request) {
|
|
1988
|
+
return `response = client.${CLIENT_METHOD_BY_OP[request.operation]}(${renderRubyParams(request, "")})`;
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1705
1991
|
//#endregion
|
|
1706
1992
|
//#region src/program.ts
|
|
1707
1993
|
/**
|
|
@@ -1750,6 +2036,22 @@ function emitQueryProgram(config, format) {
|
|
|
1750
2036
|
ok: true,
|
|
1751
2037
|
code: emitRustProgram(request, config.paginate === true)
|
|
1752
2038
|
};
|
|
2039
|
+
case "docclient": return {
|
|
2040
|
+
ok: true,
|
|
2041
|
+
code: emitDocClientProgram(request, config.paginate === true)
|
|
2042
|
+
};
|
|
2043
|
+
case "kotlin": return {
|
|
2044
|
+
ok: true,
|
|
2045
|
+
code: emitKotlinProgram(request, config.paginate === true)
|
|
2046
|
+
};
|
|
2047
|
+
case "php": return {
|
|
2048
|
+
ok: true,
|
|
2049
|
+
code: emitPhpProgram(request, config.paginate === true)
|
|
2050
|
+
};
|
|
2051
|
+
case "ruby": return {
|
|
2052
|
+
ok: true,
|
|
2053
|
+
code: emitRubyProgram(request, config.paginate === true)
|
|
2054
|
+
};
|
|
1753
2055
|
case "ddbtoolbox": return {
|
|
1754
2056
|
ok: true,
|
|
1755
2057
|
code: emitDdbToolboxProgram(request, config.paginate === true)
|
|
@@ -1992,6 +2294,128 @@ function emitRustProgram(request, paginate) {
|
|
|
1992
2294
|
"}"
|
|
1993
2295
|
].join("\n");
|
|
1994
2296
|
}
|
|
2297
|
+
function emitDocClientProgram(request, paginate) {
|
|
2298
|
+
const command = docClientCommandName(request.operation);
|
|
2299
|
+
renderDocClientParams(request, "");
|
|
2300
|
+
if (!paginate) return [
|
|
2301
|
+
"import { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";",
|
|
2302
|
+
`import { DynamoDBDocumentClient, ${command} } from "@aws-sdk/lib-dynamodb";`,
|
|
2303
|
+
"",
|
|
2304
|
+
"const client = DynamoDBDocumentClient.from(new DynamoDBClient({}));",
|
|
2305
|
+
"",
|
|
2306
|
+
"const response = await client.send(",
|
|
2307
|
+
` new ${command}(${renderDocClientParams(request, " ")})`,
|
|
2308
|
+
");",
|
|
2309
|
+
"",
|
|
2310
|
+
"console.log(response.Items);"
|
|
2311
|
+
].join("\n");
|
|
2312
|
+
const paginator = request.operation === "Scan" ? "paginateScan" : "paginateQuery";
|
|
2313
|
+
return [
|
|
2314
|
+
"import { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";",
|
|
2315
|
+
`import { DynamoDBDocumentClient, ${paginator} } from "@aws-sdk/lib-dynamodb";`,
|
|
2316
|
+
"",
|
|
2317
|
+
"const client = DynamoDBDocumentClient.from(new DynamoDBClient({}));",
|
|
2318
|
+
"",
|
|
2319
|
+
`const paginator = ${paginator}(`,
|
|
2320
|
+
" { client },",
|
|
2321
|
+
` ${renderDocClientParams(request, " ")}`,
|
|
2322
|
+
");",
|
|
2323
|
+
"",
|
|
2324
|
+
"for await (const page of paginator) {",
|
|
2325
|
+
" console.log(page.Items);",
|
|
2326
|
+
"}"
|
|
2327
|
+
].join("\n");
|
|
2328
|
+
}
|
|
2329
|
+
function emitKotlinProgram(request, paginate) {
|
|
2330
|
+
const method = kotlinClientMethodName(request.operation);
|
|
2331
|
+
const header = [
|
|
2332
|
+
"import aws.sdk.kotlin.services.dynamodb.DynamoDbClient",
|
|
2333
|
+
"import aws.sdk.kotlin.services.dynamodb.model.AttributeValue",
|
|
2334
|
+
...paginate ? [
|
|
2335
|
+
`import aws.sdk.kotlin.services.dynamodb.paginators.${method}Paginated`,
|
|
2336
|
+
"import aws.sdk.kotlin.services.dynamodb.paginators.items",
|
|
2337
|
+
"import kotlinx.coroutines.flow.collect"
|
|
2338
|
+
] : [],
|
|
2339
|
+
"",
|
|
2340
|
+
"suspend fun main() {",
|
|
2341
|
+
" DynamoDbClient.fromEnvironment().use { client ->"
|
|
2342
|
+
];
|
|
2343
|
+
const body = renderKotlinBuilder(request, " ");
|
|
2344
|
+
if (!paginate) return [
|
|
2345
|
+
...header,
|
|
2346
|
+
` val response = client.${method} {`,
|
|
2347
|
+
...body,
|
|
2348
|
+
" }",
|
|
2349
|
+
" println(response.items)",
|
|
2350
|
+
" }",
|
|
2351
|
+
"}"
|
|
2352
|
+
].join("\n");
|
|
2353
|
+
return [
|
|
2354
|
+
...header,
|
|
2355
|
+
` client.${method}Paginated {`,
|
|
2356
|
+
...body,
|
|
2357
|
+
" }",
|
|
2358
|
+
" .items()",
|
|
2359
|
+
" .collect { item -> println(item) }",
|
|
2360
|
+
" }",
|
|
2361
|
+
"}"
|
|
2362
|
+
].join("\n");
|
|
2363
|
+
}
|
|
2364
|
+
function emitPhpProgram(request, paginate) {
|
|
2365
|
+
const method = phpClientMethodName(request.operation);
|
|
2366
|
+
const header = [
|
|
2367
|
+
"<?php",
|
|
2368
|
+
"",
|
|
2369
|
+
"require 'vendor/autoload.php';",
|
|
2370
|
+
"",
|
|
2371
|
+
"use Aws\\DynamoDb\\DynamoDbClient;",
|
|
2372
|
+
"",
|
|
2373
|
+
"$client = new DynamoDbClient(['region' => 'us-east-1', 'version' => 'latest']);",
|
|
2374
|
+
""
|
|
2375
|
+
];
|
|
2376
|
+
if (!paginate) return [
|
|
2377
|
+
...header,
|
|
2378
|
+
`$response = $client->${method}(${renderPhpParams(request, "")});`,
|
|
2379
|
+
"",
|
|
2380
|
+
"print_r($response['Items']);"
|
|
2381
|
+
].join("\n");
|
|
2382
|
+
const operation = request.operation === "Scan" ? "Scan" : "Query";
|
|
2383
|
+
return [
|
|
2384
|
+
...header,
|
|
2385
|
+
`$pages = $client->getPaginator('${operation}', ${renderPhpParams(request, "")});`,
|
|
2386
|
+
"",
|
|
2387
|
+
"foreach ($pages as $page) {",
|
|
2388
|
+
" print_r($page['Items']);",
|
|
2389
|
+
"}"
|
|
2390
|
+
].join("\n");
|
|
2391
|
+
}
|
|
2392
|
+
function emitRubyProgram(request, paginate) {
|
|
2393
|
+
const method = rubyClientMethodName(request.operation);
|
|
2394
|
+
const usesSets = /Set\.new\(/.test(renderRubyParams(request, ""));
|
|
2395
|
+
const usesBase64 = /Base64\.decode64\(/.test(renderRubyParams(request, ""));
|
|
2396
|
+
const header = [
|
|
2397
|
+
"require 'aws-sdk-dynamodb'",
|
|
2398
|
+
...usesSets ? ["require 'set'"] : [],
|
|
2399
|
+
...usesBase64 ? ["require 'base64'"] : [],
|
|
2400
|
+
"",
|
|
2401
|
+
"client = Aws::DynamoDB::Client.new",
|
|
2402
|
+
""
|
|
2403
|
+
];
|
|
2404
|
+
if (!paginate) return [
|
|
2405
|
+
...header,
|
|
2406
|
+
`response = client.${method}(${renderRubyParams(request, "")})`,
|
|
2407
|
+
"",
|
|
2408
|
+
"puts response.items"
|
|
2409
|
+
].join("\n");
|
|
2410
|
+
return [
|
|
2411
|
+
...header,
|
|
2412
|
+
`response = client.${method}(${renderRubyParams(request, "")})`,
|
|
2413
|
+
"",
|
|
2414
|
+
"response.each do |page|",
|
|
2415
|
+
" puts page.items",
|
|
2416
|
+
"end"
|
|
2417
|
+
].join("\n");
|
|
2418
|
+
}
|
|
1995
2419
|
function emitDotnetProgram(request, paginate) {
|
|
1996
2420
|
const method = dotnetClientMethodName(request.operation);
|
|
1997
2421
|
const binary = hasBinaryValue(request);
|
|
@@ -2048,17 +2472,22 @@ exports.buildKeyMap = buildKeyMap;
|
|
|
2048
2472
|
exports.buildRequest = buildRequest;
|
|
2049
2473
|
exports.buildSdkV3Params = buildSdkV3Params;
|
|
2050
2474
|
exports.buildUpdateExpression = buildUpdateExpression;
|
|
2475
|
+
exports.docClientCommandName = docClientCommandName;
|
|
2051
2476
|
exports.dotnetClientMethodName = dotnetClientMethodName;
|
|
2052
2477
|
exports.dotnetRequestClassName = dotnetRequestClassName;
|
|
2053
2478
|
exports.elementType = elementType;
|
|
2054
2479
|
exports.emitBoto3 = emitBoto3;
|
|
2055
2480
|
exports.emitCli = emitCli;
|
|
2056
2481
|
exports.emitDdbToolboxProgram = emitDdbToolboxProgram;
|
|
2482
|
+
exports.emitDocClient = emitDocClient;
|
|
2057
2483
|
exports.emitDotnet = emitDotnet;
|
|
2058
2484
|
exports.emitGo = emitGo;
|
|
2059
2485
|
exports.emitJava = emitJava;
|
|
2486
|
+
exports.emitKotlin = emitKotlin;
|
|
2060
2487
|
exports.emitPartiql = emitPartiql;
|
|
2488
|
+
exports.emitPhp = emitPhp;
|
|
2061
2489
|
exports.emitQueryProgram = emitQueryProgram;
|
|
2490
|
+
exports.emitRuby = emitRuby;
|
|
2062
2491
|
exports.emitRust = emitRust;
|
|
2063
2492
|
exports.emitSdkV3 = emitSdkV3;
|
|
2064
2493
|
exports.getCompatibleComparisonOperators = getCompatibleComparisonOperators;
|
|
@@ -2069,10 +2498,16 @@ exports.hasBinaryValue = hasBinaryValue;
|
|
|
2069
2498
|
exports.isSetType = isSetType;
|
|
2070
2499
|
exports.javaClientMethodName = javaClientMethodName;
|
|
2071
2500
|
exports.javaRequestClassName = javaRequestClassName;
|
|
2501
|
+
exports.kotlinClientMethodName = kotlinClientMethodName;
|
|
2072
2502
|
exports.makeTypedValue = makeTypedValue;
|
|
2503
|
+
exports.phpClientMethodName = phpClientMethodName;
|
|
2073
2504
|
exports.renderJsValue = renderJsValue;
|
|
2505
|
+
exports.renderKotlinAv = renderKotlinAv;
|
|
2506
|
+
exports.renderPhpAv = renderPhpAv;
|
|
2074
2507
|
exports.renderPyValue = renderPyValue;
|
|
2508
|
+
exports.renderRubyValue = renderRubyValue;
|
|
2075
2509
|
exports.renderRustAv = renderRustAv;
|
|
2510
|
+
exports.rubyClientMethodName = rubyClientMethodName;
|
|
2076
2511
|
exports.rustClientMethodName = rustClientMethodName;
|
|
2077
2512
|
exports.sdkV3CommandName = sdkV3CommandName;
|
|
2078
2513
|
exports.typedMapToAvMap = typedMapToAvMap;
|
package/dist/index.d.cts
CHANGED
|
@@ -618,6 +618,36 @@ declare function renderRustAv(av: AttributeValue): string;
|
|
|
618
618
|
/** Emit the bare fluent call for a canonical request (awaited, `?`-propagated). */
|
|
619
619
|
declare function emitRust(request: CanonicalRequest): string;
|
|
620
620
|
//#endregion
|
|
621
|
+
//#region src/emit/docclient.d.ts
|
|
622
|
+
/** The lib-dynamodb command class name for an operation. */
|
|
623
|
+
declare function docClientCommandName(operation: DdbOperation): string;
|
|
624
|
+
/** Emit the bare `new XCommand({…})` snippet with native values. */
|
|
625
|
+
declare function emitDocClient(request: CanonicalRequest): string;
|
|
626
|
+
//#endregion
|
|
627
|
+
//#region src/emit/kotlin.d.ts
|
|
628
|
+
/** The client method name (camelCase) for an operation. */
|
|
629
|
+
declare function kotlinClientMethodName(operation: DdbOperation): string;
|
|
630
|
+
/** Render one wire AttributeValue as an `AttributeValue.…` constructor. */
|
|
631
|
+
declare function renderKotlinAv(av: AttributeValue): string;
|
|
632
|
+
/** Emit the bare `val response = client.…{ … }` call for a canonical request. */
|
|
633
|
+
declare function emitKotlin(request: CanonicalRequest): string;
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region src/emit/php.d.ts
|
|
636
|
+
/** The client method name (camelCase) for an operation. */
|
|
637
|
+
declare function phpClientMethodName(operation: DdbOperation): string;
|
|
638
|
+
/** Render one wire AttributeValue as a nested `['TAG' => …]` literal. */
|
|
639
|
+
declare function renderPhpAv(av: AttributeValue): string;
|
|
640
|
+
/** Emit the bare `$response = $client->…([…]);` call for a canonical request. */
|
|
641
|
+
declare function emitPhp(request: CanonicalRequest): string;
|
|
642
|
+
//#endregion
|
|
643
|
+
//#region src/emit/ruby.d.ts
|
|
644
|
+
/** The client method name (snake_case) for an operation. */
|
|
645
|
+
declare function rubyClientMethodName(operation: DdbOperation): string;
|
|
646
|
+
/** Render one typed value as the native Ruby literal the SDK marshals. */
|
|
647
|
+
declare function renderRubyValue(tv: TypedValue): string;
|
|
648
|
+
/** Emit the bare `response = client.…(…)` call for a canonical request. */
|
|
649
|
+
declare function emitRuby(request: CanonicalRequest): string;
|
|
650
|
+
//#endregion
|
|
621
651
|
//#region src/emit/ddbtoolbox.d.ts
|
|
622
652
|
/**
|
|
623
653
|
* Emit the runnable dynamodb-toolbox program for a Query/Scan canonical request.
|
|
@@ -636,7 +666,7 @@ interface QueryToolConfig extends BuilderConfig {
|
|
|
636
666
|
/** Emit the fetch-all-pages pagination loop (default: single request). */
|
|
637
667
|
paginate?: boolean;
|
|
638
668
|
}
|
|
639
|
-
type QueryProgramFormat = 'sdk' | 'cli' | 'boto3' | 'partiql' | 'java' | 'go' | 'dotnet' | 'rust' | 'ddbtoolbox';
|
|
669
|
+
type QueryProgramFormat = 'sdk' | 'docclient' | 'cli' | 'boto3' | 'partiql' | 'java' | 'go' | 'dotnet' | 'rust' | 'kotlin' | 'php' | 'ruby' | 'ddbtoolbox';
|
|
640
670
|
/** A runnable program, or an honest reason the format can't express it. */
|
|
641
671
|
type ProgramResult = {
|
|
642
672
|
ok: true;
|
|
@@ -654,4 +684,4 @@ type ProgramResult = {
|
|
|
654
684
|
*/
|
|
655
685
|
declare function emitQueryProgram(config: QueryToolConfig, format: QueryProgramFormat): ProgramResult;
|
|
656
686
|
//#endregion
|
|
657
|
-
export { type AttributeValue, type BuilderConfig, type CanonicalRequest, type DdbOperation, type DdbScalarType, FILTER_OPERATORS, type FilterDataType, type FilterOperatorOption, type FilterRow, type ItemAttr, KEY_OPERATORS, type KeyAttr, type KeyConditionResult, OPERATOR_BY_VALUE, type OperatorDef, type OperatorValue, type PartiqlResult, type PredicateExpression, type PredicatePrefix, type ProgramResult, type QueryProgramFormat, type QueryToolConfig, type RangeKeyCondition, SET_TYPES, type SetOperation, type SetType, type TypedValue, type UpdateAction, type UpdateActionKind, type UpdateExpressionResult, type WireFilterOperator, boto3MethodName, buildFilterExpressions, buildKeyConditionExpression, buildKeyMap, buildRequest, buildSdkV3Params, buildUpdateExpression, dotnetClientMethodName, dotnetRequestClassName, elementType, emitBoto3, emitCli, emitDdbToolboxProgram, emitDotnet, emitGo, emitJava, emitPartiql, emitQueryProgram, emitRust, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, makeTypedValue, renderJsValue, renderPyValue, renderRustAv, rustClientMethodName, sdkV3CommandName, typedMapToAvMap, typedValueToAv };
|
|
687
|
+
export { type AttributeValue, type BuilderConfig, type CanonicalRequest, type DdbOperation, type DdbScalarType, FILTER_OPERATORS, type FilterDataType, type FilterOperatorOption, type FilterRow, type ItemAttr, KEY_OPERATORS, type KeyAttr, type KeyConditionResult, OPERATOR_BY_VALUE, type OperatorDef, type OperatorValue, type PartiqlResult, type PredicateExpression, type PredicatePrefix, type ProgramResult, type QueryProgramFormat, type QueryToolConfig, type RangeKeyCondition, SET_TYPES, type SetOperation, type SetType, type TypedValue, type UpdateAction, type UpdateActionKind, type UpdateExpressionResult, type WireFilterOperator, boto3MethodName, buildFilterExpressions, buildKeyConditionExpression, buildKeyMap, buildRequest, buildSdkV3Params, buildUpdateExpression, docClientCommandName, dotnetClientMethodName, dotnetRequestClassName, elementType, emitBoto3, emitCli, emitDdbToolboxProgram, emitDocClient, emitDotnet, emitGo, emitJava, emitKotlin, emitPartiql, emitPhp, emitQueryProgram, emitRuby, emitRust, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, kotlinClientMethodName, makeTypedValue, phpClientMethodName, renderJsValue, renderKotlinAv, renderPhpAv, renderPyValue, renderRubyValue, renderRustAv, rubyClientMethodName, rustClientMethodName, sdkV3CommandName, typedMapToAvMap, typedValueToAv };
|
package/dist/index.d.ts
CHANGED
|
@@ -618,6 +618,36 @@ declare function renderRustAv(av: AttributeValue): string;
|
|
|
618
618
|
/** Emit the bare fluent call for a canonical request (awaited, `?`-propagated). */
|
|
619
619
|
declare function emitRust(request: CanonicalRequest): string;
|
|
620
620
|
//#endregion
|
|
621
|
+
//#region src/emit/docclient.d.ts
|
|
622
|
+
/** The lib-dynamodb command class name for an operation. */
|
|
623
|
+
declare function docClientCommandName(operation: DdbOperation): string;
|
|
624
|
+
/** Emit the bare `new XCommand({…})` snippet with native values. */
|
|
625
|
+
declare function emitDocClient(request: CanonicalRequest): string;
|
|
626
|
+
//#endregion
|
|
627
|
+
//#region src/emit/kotlin.d.ts
|
|
628
|
+
/** The client method name (camelCase) for an operation. */
|
|
629
|
+
declare function kotlinClientMethodName(operation: DdbOperation): string;
|
|
630
|
+
/** Render one wire AttributeValue as an `AttributeValue.…` constructor. */
|
|
631
|
+
declare function renderKotlinAv(av: AttributeValue): string;
|
|
632
|
+
/** Emit the bare `val response = client.…{ … }` call for a canonical request. */
|
|
633
|
+
declare function emitKotlin(request: CanonicalRequest): string;
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region src/emit/php.d.ts
|
|
636
|
+
/** The client method name (camelCase) for an operation. */
|
|
637
|
+
declare function phpClientMethodName(operation: DdbOperation): string;
|
|
638
|
+
/** Render one wire AttributeValue as a nested `['TAG' => …]` literal. */
|
|
639
|
+
declare function renderPhpAv(av: AttributeValue): string;
|
|
640
|
+
/** Emit the bare `$response = $client->…([…]);` call for a canonical request. */
|
|
641
|
+
declare function emitPhp(request: CanonicalRequest): string;
|
|
642
|
+
//#endregion
|
|
643
|
+
//#region src/emit/ruby.d.ts
|
|
644
|
+
/** The client method name (snake_case) for an operation. */
|
|
645
|
+
declare function rubyClientMethodName(operation: DdbOperation): string;
|
|
646
|
+
/** Render one typed value as the native Ruby literal the SDK marshals. */
|
|
647
|
+
declare function renderRubyValue(tv: TypedValue): string;
|
|
648
|
+
/** Emit the bare `response = client.…(…)` call for a canonical request. */
|
|
649
|
+
declare function emitRuby(request: CanonicalRequest): string;
|
|
650
|
+
//#endregion
|
|
621
651
|
//#region src/emit/ddbtoolbox.d.ts
|
|
622
652
|
/**
|
|
623
653
|
* Emit the runnable dynamodb-toolbox program for a Query/Scan canonical request.
|
|
@@ -636,7 +666,7 @@ interface QueryToolConfig extends BuilderConfig {
|
|
|
636
666
|
/** Emit the fetch-all-pages pagination loop (default: single request). */
|
|
637
667
|
paginate?: boolean;
|
|
638
668
|
}
|
|
639
|
-
type QueryProgramFormat = 'sdk' | 'cli' | 'boto3' | 'partiql' | 'java' | 'go' | 'dotnet' | 'rust' | 'ddbtoolbox';
|
|
669
|
+
type QueryProgramFormat = 'sdk' | 'docclient' | 'cli' | 'boto3' | 'partiql' | 'java' | 'go' | 'dotnet' | 'rust' | 'kotlin' | 'php' | 'ruby' | 'ddbtoolbox';
|
|
640
670
|
/** A runnable program, or an honest reason the format can't express it. */
|
|
641
671
|
type ProgramResult = {
|
|
642
672
|
ok: true;
|
|
@@ -654,4 +684,4 @@ type ProgramResult = {
|
|
|
654
684
|
*/
|
|
655
685
|
declare function emitQueryProgram(config: QueryToolConfig, format: QueryProgramFormat): ProgramResult;
|
|
656
686
|
//#endregion
|
|
657
|
-
export { type AttributeValue, type BuilderConfig, type CanonicalRequest, type DdbOperation, type DdbScalarType, FILTER_OPERATORS, type FilterDataType, type FilterOperatorOption, type FilterRow, type ItemAttr, KEY_OPERATORS, type KeyAttr, type KeyConditionResult, OPERATOR_BY_VALUE, type OperatorDef, type OperatorValue, type PartiqlResult, type PredicateExpression, type PredicatePrefix, type ProgramResult, type QueryProgramFormat, type QueryToolConfig, type RangeKeyCondition, SET_TYPES, type SetOperation, type SetType, type TypedValue, type UpdateAction, type UpdateActionKind, type UpdateExpressionResult, type WireFilterOperator, boto3MethodName, buildFilterExpressions, buildKeyConditionExpression, buildKeyMap, buildRequest, buildSdkV3Params, buildUpdateExpression, dotnetClientMethodName, dotnetRequestClassName, elementType, emitBoto3, emitCli, emitDdbToolboxProgram, emitDotnet, emitGo, emitJava, emitPartiql, emitQueryProgram, emitRust, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, makeTypedValue, renderJsValue, renderPyValue, renderRustAv, rustClientMethodName, sdkV3CommandName, typedMapToAvMap, typedValueToAv };
|
|
687
|
+
export { type AttributeValue, type BuilderConfig, type CanonicalRequest, type DdbOperation, type DdbScalarType, FILTER_OPERATORS, type FilterDataType, type FilterOperatorOption, type FilterRow, type ItemAttr, KEY_OPERATORS, type KeyAttr, type KeyConditionResult, OPERATOR_BY_VALUE, type OperatorDef, type OperatorValue, type PartiqlResult, type PredicateExpression, type PredicatePrefix, type ProgramResult, type QueryProgramFormat, type QueryToolConfig, type RangeKeyCondition, SET_TYPES, type SetOperation, type SetType, type TypedValue, type UpdateAction, type UpdateActionKind, type UpdateExpressionResult, type WireFilterOperator, boto3MethodName, buildFilterExpressions, buildKeyConditionExpression, buildKeyMap, buildRequest, buildSdkV3Params, buildUpdateExpression, docClientCommandName, dotnetClientMethodName, dotnetRequestClassName, elementType, emitBoto3, emitCli, emitDdbToolboxProgram, emitDocClient, emitDotnet, emitGo, emitJava, emitKotlin, emitPartiql, emitPhp, emitQueryProgram, emitRuby, emitRust, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, kotlinClientMethodName, makeTypedValue, phpClientMethodName, renderJsValue, renderKotlinAv, renderPhpAv, renderPyValue, renderRubyValue, renderRustAv, rubyClientMethodName, rustClientMethodName, sdkV3CommandName, typedMapToAvMap, typedValueToAv };
|
package/dist/index.js
CHANGED
|
@@ -746,7 +746,7 @@ function hasBinaryValue(request) {
|
|
|
746
746
|
//#endregion
|
|
747
747
|
//#region src/emit/sdk-v3.ts
|
|
748
748
|
/** Operation → the `@aws-sdk/client-dynamodb` command class name. */
|
|
749
|
-
const COMMAND_BY_OP = {
|
|
749
|
+
const COMMAND_BY_OP$1 = {
|
|
750
750
|
GetItem: "GetItemCommand",
|
|
751
751
|
Query: "QueryCommand",
|
|
752
752
|
Scan: "ScanCommand",
|
|
@@ -804,11 +804,11 @@ function jsLiteral(value, indent) {
|
|
|
804
804
|
}
|
|
805
805
|
/** Emit the `new <Op>Command({...})` source snippet for a canonical request. */
|
|
806
806
|
function emitSdkV3(request) {
|
|
807
|
-
return `new ${COMMAND_BY_OP[request.operation]}(${jsLiteral(buildSdkV3Params(request), 0)})`;
|
|
807
|
+
return `new ${COMMAND_BY_OP$1[request.operation]}(${jsLiteral(buildSdkV3Params(request), 0)})`;
|
|
808
808
|
}
|
|
809
809
|
/** The `@aws-sdk/client-dynamodb` command class name for an operation. */
|
|
810
810
|
function sdkV3CommandName(operation) {
|
|
811
|
-
return COMMAND_BY_OP[operation];
|
|
811
|
+
return COMMAND_BY_OP$1[operation];
|
|
812
812
|
}
|
|
813
813
|
/**
|
|
814
814
|
* Render an arbitrary params value as the same pretty-printed JS literal
|
|
@@ -1116,7 +1116,7 @@ const REQUEST_CLASS_BY_OP$1 = {
|
|
|
1116
1116
|
Delete: "DeleteItemRequest"
|
|
1117
1117
|
};
|
|
1118
1118
|
/** Operation → the `DynamoDbClient` method. */
|
|
1119
|
-
const CLIENT_METHOD_BY_OP$
|
|
1119
|
+
const CLIENT_METHOD_BY_OP$6 = {
|
|
1120
1120
|
GetItem: "getItem",
|
|
1121
1121
|
Query: "query",
|
|
1122
1122
|
Scan: "scan",
|
|
@@ -1130,7 +1130,7 @@ function javaRequestClassName(operation) {
|
|
|
1130
1130
|
}
|
|
1131
1131
|
/** The `DynamoDbClient` method name for an operation (`query`, …). */
|
|
1132
1132
|
function javaClientMethodName(operation) {
|
|
1133
|
-
return CLIENT_METHOD_BY_OP$
|
|
1133
|
+
return CLIENT_METHOD_BY_OP$6[operation];
|
|
1134
1134
|
}
|
|
1135
1135
|
/** Java string literal — `JSON.stringify` escapes are all valid Java escapes. */
|
|
1136
1136
|
function javaString(value) {
|
|
@@ -1209,7 +1209,7 @@ const INPUT_TYPE_BY_OP = {
|
|
|
1209
1209
|
Delete: "DeleteItemInput"
|
|
1210
1210
|
};
|
|
1211
1211
|
/** Operation → the `dynamodb.Client` method. */
|
|
1212
|
-
const CLIENT_METHOD_BY_OP$
|
|
1212
|
+
const CLIENT_METHOD_BY_OP$5 = {
|
|
1213
1213
|
GetItem: "GetItem",
|
|
1214
1214
|
Query: "Query",
|
|
1215
1215
|
Scan: "Scan",
|
|
@@ -1223,7 +1223,7 @@ function goInputTypeName(operation) {
|
|
|
1223
1223
|
}
|
|
1224
1224
|
/** The `dynamodb.Client` method name for an operation. */
|
|
1225
1225
|
function goClientMethodName(operation) {
|
|
1226
|
-
return CLIENT_METHOD_BY_OP$
|
|
1226
|
+
return CLIENT_METHOD_BY_OP$5[operation];
|
|
1227
1227
|
}
|
|
1228
1228
|
/** Go string literal — `JSON.stringify` escapes are all valid Go escapes. */
|
|
1229
1229
|
function goString(value) {
|
|
@@ -1313,7 +1313,7 @@ const REQUEST_CLASS_BY_OP = {
|
|
|
1313
1313
|
Delete: "DeleteItemRequest"
|
|
1314
1314
|
};
|
|
1315
1315
|
/** Operation → the async `AmazonDynamoDBClient` method. */
|
|
1316
|
-
const CLIENT_METHOD_BY_OP$
|
|
1316
|
+
const CLIENT_METHOD_BY_OP$4 = {
|
|
1317
1317
|
GetItem: "GetItemAsync",
|
|
1318
1318
|
Query: "QueryAsync",
|
|
1319
1319
|
Scan: "ScanAsync",
|
|
@@ -1327,7 +1327,7 @@ function dotnetRequestClassName(operation) {
|
|
|
1327
1327
|
}
|
|
1328
1328
|
/** The async client method name for an operation (`QueryAsync`, …). */
|
|
1329
1329
|
function dotnetClientMethodName(operation) {
|
|
1330
|
-
return CLIENT_METHOD_BY_OP$
|
|
1330
|
+
return CLIENT_METHOD_BY_OP$4[operation];
|
|
1331
1331
|
}
|
|
1332
1332
|
/** C# string literal — `JSON.stringify` escapes are all valid C# escapes. */
|
|
1333
1333
|
function csString(value) {
|
|
@@ -1397,7 +1397,7 @@ function emitDotnet(request) {
|
|
|
1397
1397
|
//#endregion
|
|
1398
1398
|
//#region src/emit/rust.ts
|
|
1399
1399
|
/** Operation → the `aws_sdk_dynamodb::Client` fluent method. */
|
|
1400
|
-
const CLIENT_METHOD_BY_OP = {
|
|
1400
|
+
const CLIENT_METHOD_BY_OP$3 = {
|
|
1401
1401
|
GetItem: "get_item",
|
|
1402
1402
|
Query: "query",
|
|
1403
1403
|
Scan: "scan",
|
|
@@ -1407,7 +1407,7 @@ const CLIENT_METHOD_BY_OP = {
|
|
|
1407
1407
|
};
|
|
1408
1408
|
/** The `Client` method name (snake_case) for an operation. */
|
|
1409
1409
|
function rustClientMethodName(operation) {
|
|
1410
|
-
return CLIENT_METHOD_BY_OP[operation];
|
|
1410
|
+
return CLIENT_METHOD_BY_OP$3[operation];
|
|
1411
1411
|
}
|
|
1412
1412
|
/** Rust string literal — JSON escapes with the three Rust-incompatible ones fixed. */
|
|
1413
1413
|
function rustString(value) {
|
|
@@ -1449,7 +1449,7 @@ function avEntryLines(method, map, indent) {
|
|
|
1449
1449
|
* chain to `into_paginator()` instead). Exported for the program emitter.
|
|
1450
1450
|
*/
|
|
1451
1451
|
function renderRustBuilder(request, indent) {
|
|
1452
|
-
const lines = [`${indent}.${CLIENT_METHOD_BY_OP[request.operation]}()`];
|
|
1452
|
+
const lines = [`${indent}.${CLIENT_METHOD_BY_OP$3[request.operation]}()`];
|
|
1453
1453
|
lines.push(`${indent}.table_name(${rustString(request.tableName)})`);
|
|
1454
1454
|
if (request.indexName) lines.push(`${indent}.index_name(${rustString(request.indexName)})`);
|
|
1455
1455
|
if (request.key) lines.push(...avEntryLines("key", request.key, indent));
|
|
@@ -1701,6 +1701,292 @@ function emitDdbToolboxProgram(request, paginate) {
|
|
|
1701
1701
|
].filter((l) => l !== null).join("\n");
|
|
1702
1702
|
}
|
|
1703
1703
|
|
|
1704
|
+
//#endregion
|
|
1705
|
+
//#region src/emit/docclient.ts
|
|
1706
|
+
/** Operation → the `@aws-sdk/lib-dynamodb` command class. */
|
|
1707
|
+
const COMMAND_BY_OP = {
|
|
1708
|
+
GetItem: "GetCommand",
|
|
1709
|
+
Query: "QueryCommand",
|
|
1710
|
+
Scan: "ScanCommand",
|
|
1711
|
+
Update: "UpdateCommand",
|
|
1712
|
+
Put: "PutCommand",
|
|
1713
|
+
Delete: "DeleteCommand"
|
|
1714
|
+
};
|
|
1715
|
+
/** The lib-dynamodb command class name for an operation. */
|
|
1716
|
+
function docClientCommandName(operation) {
|
|
1717
|
+
return COMMAND_BY_OP[operation];
|
|
1718
|
+
}
|
|
1719
|
+
/** Render a typed map as a native-value object literal, one entry per line. */
|
|
1720
|
+
function renderNativeMap(map, indent) {
|
|
1721
|
+
const inner = `${indent} `;
|
|
1722
|
+
return `{\n${Object.entries(map).map(([name, tv]) => `${inner}${JSON.stringify(name)}: ${renderNativeValue(tv)},`).join("\n")}\n${indent}}`;
|
|
1723
|
+
}
|
|
1724
|
+
/** Render the plain string map (`ExpressionAttributeNames`). */
|
|
1725
|
+
function renderNameMap$3(map, indent) {
|
|
1726
|
+
const inner = `${indent} `;
|
|
1727
|
+
return `{\n${Object.entries(map).map(([alias, name]) => `${inner}${JSON.stringify(alias)}: ${JSON.stringify(name)},`).join("\n")}\n${indent}}`;
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Render the command's params object literal, one field per line at
|
|
1731
|
+
* `indent + 2`. Exported for the program emitter.
|
|
1732
|
+
*/
|
|
1733
|
+
function renderDocClientParams(request, indent) {
|
|
1734
|
+
const pad = `${indent} `;
|
|
1735
|
+
const fields = [`TableName: ${JSON.stringify(request.tableName)},`];
|
|
1736
|
+
if (request.indexName) fields.push(`IndexName: ${JSON.stringify(request.indexName)},`);
|
|
1737
|
+
if (request.key) fields.push(`Key: ${renderNativeMap(request.key, pad)},`);
|
|
1738
|
+
if (request.item) fields.push(`Item: ${renderNativeMap(request.item, pad)},`);
|
|
1739
|
+
if (request.keyConditionExpression) fields.push(`KeyConditionExpression: ${JSON.stringify(request.keyConditionExpression)},`);
|
|
1740
|
+
if (request.updateExpression) fields.push(`UpdateExpression: ${JSON.stringify(request.updateExpression)},`);
|
|
1741
|
+
if (request.conditionExpression) fields.push(`ConditionExpression: ${JSON.stringify(request.conditionExpression)},`);
|
|
1742
|
+
if (request.filterExpression) fields.push(`FilterExpression: ${JSON.stringify(request.filterExpression)},`);
|
|
1743
|
+
if (request.projectionExpression) fields.push(`ProjectionExpression: ${JSON.stringify(request.projectionExpression)},`);
|
|
1744
|
+
if (request.names) fields.push(`ExpressionAttributeNames: ${renderNameMap$3(request.names, pad)},`);
|
|
1745
|
+
if (request.typedValues) fields.push(`ExpressionAttributeValues: ${renderNativeMap(request.typedValues, pad)},`);
|
|
1746
|
+
if (request.limit !== void 0) fields.push(`Limit: ${request.limit},`);
|
|
1747
|
+
if (request.consistentRead) fields.push("ConsistentRead: true,");
|
|
1748
|
+
if (request.scanIndexForward === false) fields.push("ScanIndexForward: false,");
|
|
1749
|
+
if (request.exclusiveStartKey) fields.push(`ExclusiveStartKey: ${renderNativeMap(request.exclusiveStartKey, pad)},`);
|
|
1750
|
+
return [
|
|
1751
|
+
"{",
|
|
1752
|
+
...fields.map((f) => `${pad}${f}`),
|
|
1753
|
+
`${indent}}`
|
|
1754
|
+
].join("\n");
|
|
1755
|
+
}
|
|
1756
|
+
/** Emit the bare `new XCommand({…})` snippet with native values. */
|
|
1757
|
+
function emitDocClient(request) {
|
|
1758
|
+
return `new ${COMMAND_BY_OP[request.operation]}(${renderDocClientParams(request, "")})`;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
//#endregion
|
|
1762
|
+
//#region src/emit/kotlin.ts
|
|
1763
|
+
/** Operation → the `DynamoDbClient` suspend function. */
|
|
1764
|
+
const CLIENT_METHOD_BY_OP$2 = {
|
|
1765
|
+
GetItem: "getItem",
|
|
1766
|
+
Query: "query",
|
|
1767
|
+
Scan: "scan",
|
|
1768
|
+
Update: "updateItem",
|
|
1769
|
+
Put: "putItem",
|
|
1770
|
+
Delete: "deleteItem"
|
|
1771
|
+
};
|
|
1772
|
+
/** The client method name (camelCase) for an operation. */
|
|
1773
|
+
function kotlinClientMethodName(operation) {
|
|
1774
|
+
return CLIENT_METHOD_BY_OP$2[operation];
|
|
1775
|
+
}
|
|
1776
|
+
/** Kotlin string literal — JSON escapes are valid Kotlin escapes, plus `$` must
|
|
1777
|
+
* be escaped (string templates). */
|
|
1778
|
+
function ktString(value) {
|
|
1779
|
+
return JSON.stringify(value).replace(/\$/g, "\\$");
|
|
1780
|
+
}
|
|
1781
|
+
/** Decode canonical base64 into a `byteArrayOf(0x…)` literal (fail-loud). */
|
|
1782
|
+
function ktBytes(base64) {
|
|
1783
|
+
let raw;
|
|
1784
|
+
try {
|
|
1785
|
+
raw = atob(base64);
|
|
1786
|
+
} catch {
|
|
1787
|
+
throw new Error(`invalid base64 in a binary (B/BS) value: ${base64}`);
|
|
1788
|
+
}
|
|
1789
|
+
return `byteArrayOf(${Array.from(raw, (c) => `0x${c.charCodeAt(0).toString(16).padStart(2, "0")}`).join(", ")})`;
|
|
1790
|
+
}
|
|
1791
|
+
/** Render one wire AttributeValue as an `AttributeValue.…` constructor. */
|
|
1792
|
+
function renderKotlinAv(av) {
|
|
1793
|
+
if ("S" in av) return `AttributeValue.S(${ktString(av.S)})`;
|
|
1794
|
+
if ("N" in av) return `AttributeValue.N(${ktString(av.N)})`;
|
|
1795
|
+
if ("B" in av) return `AttributeValue.B(${ktBytes(av.B)})`;
|
|
1796
|
+
if ("BOOL" in av) return `AttributeValue.Bool(${av.BOOL})`;
|
|
1797
|
+
if ("SS" in av) return `AttributeValue.Ss(listOf(${av.SS.map(ktString).join(", ")}))`;
|
|
1798
|
+
if ("NS" in av) return `AttributeValue.Ns(listOf(${av.NS.map(ktString).join(", ")}))`;
|
|
1799
|
+
if ("BS" in av) return `AttributeValue.Bs(listOf(${av.BS.map(ktBytes).join(", ")}))`;
|
|
1800
|
+
return "AttributeValue.Null(true)";
|
|
1801
|
+
}
|
|
1802
|
+
/** Render a typed map as `mapOf("k" to AttributeValue.…)`, one entry per line. */
|
|
1803
|
+
function renderAvMap$1(map, indent) {
|
|
1804
|
+
const inner = `${indent} `;
|
|
1805
|
+
return `mapOf(\n${Object.entries(typedMapToAvMap(map)).map(([name, av]) => `${inner}${ktString(name)} to ${renderKotlinAv(av)},`).join("\n")}\n${indent})`;
|
|
1806
|
+
}
|
|
1807
|
+
/** Render the plain string map (`expressionAttributeNames`). */
|
|
1808
|
+
function renderNameMap$2(map, indent) {
|
|
1809
|
+
const inner = `${indent} `;
|
|
1810
|
+
return `mapOf(\n${Object.entries(map).map(([alias, name]) => `${inner}${ktString(alias)} to ${ktString(name)},`).join("\n")}\n${indent})`;
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Render the builder-lambda body — one property assignment per line at
|
|
1814
|
+
* `indent`. Exported for the program emitter, which wraps the same body in
|
|
1815
|
+
* either the plain suspend call or the `Paginated` flow variant.
|
|
1816
|
+
*/
|
|
1817
|
+
function renderKotlinBuilder(request, indent) {
|
|
1818
|
+
const lines = [`${indent}tableName = ${ktString(request.tableName)}`];
|
|
1819
|
+
if (request.indexName) lines.push(`${indent}indexName = ${ktString(request.indexName)}`);
|
|
1820
|
+
if (request.key) lines.push(`${indent}key = ${renderAvMap$1(request.key, indent)}`);
|
|
1821
|
+
if (request.item) lines.push(`${indent}item = ${renderAvMap$1(request.item, indent)}`);
|
|
1822
|
+
if (request.keyConditionExpression) lines.push(`${indent}keyConditionExpression = ${ktString(request.keyConditionExpression)}`);
|
|
1823
|
+
if (request.updateExpression) lines.push(`${indent}updateExpression = ${ktString(request.updateExpression)}`);
|
|
1824
|
+
if (request.conditionExpression) lines.push(`${indent}conditionExpression = ${ktString(request.conditionExpression)}`);
|
|
1825
|
+
if (request.filterExpression) lines.push(`${indent}filterExpression = ${ktString(request.filterExpression)}`);
|
|
1826
|
+
if (request.projectionExpression) lines.push(`${indent}projectionExpression = ${ktString(request.projectionExpression)}`);
|
|
1827
|
+
if (request.names) lines.push(`${indent}expressionAttributeNames = ${renderNameMap$2(request.names, indent)}`);
|
|
1828
|
+
if (request.typedValues) lines.push(`${indent}expressionAttributeValues = ${renderAvMap$1(request.typedValues, indent)}`);
|
|
1829
|
+
if (request.limit !== void 0) lines.push(`${indent}limit = ${request.limit}`);
|
|
1830
|
+
if (request.consistentRead) lines.push(`${indent}consistentRead = true`);
|
|
1831
|
+
if (request.scanIndexForward === false) lines.push(`${indent}scanIndexForward = false`);
|
|
1832
|
+
if (request.exclusiveStartKey) lines.push(`${indent}exclusiveStartKey = ${renderAvMap$1(request.exclusiveStartKey, indent)}`);
|
|
1833
|
+
return lines;
|
|
1834
|
+
}
|
|
1835
|
+
/** Emit the bare `val response = client.…{ … }` call for a canonical request. */
|
|
1836
|
+
function emitKotlin(request) {
|
|
1837
|
+
return [
|
|
1838
|
+
`val response = client.${CLIENT_METHOD_BY_OP$2[request.operation]} {`,
|
|
1839
|
+
...renderKotlinBuilder(request, " "),
|
|
1840
|
+
"}"
|
|
1841
|
+
].join("\n");
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
//#endregion
|
|
1845
|
+
//#region src/emit/php.ts
|
|
1846
|
+
/** Operation → the `DynamoDbClient` method. */
|
|
1847
|
+
const CLIENT_METHOD_BY_OP$1 = {
|
|
1848
|
+
GetItem: "getItem",
|
|
1849
|
+
Query: "query",
|
|
1850
|
+
Scan: "scan",
|
|
1851
|
+
Update: "updateItem",
|
|
1852
|
+
Put: "putItem",
|
|
1853
|
+
Delete: "deleteItem"
|
|
1854
|
+
};
|
|
1855
|
+
/** The client method name (camelCase) for an operation. */
|
|
1856
|
+
function phpClientMethodName(operation) {
|
|
1857
|
+
return CLIENT_METHOD_BY_OP$1[operation];
|
|
1858
|
+
}
|
|
1859
|
+
/** PHP single-quoted string — only `\` and `'` need escaping. */
|
|
1860
|
+
function phpString(value) {
|
|
1861
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
1862
|
+
}
|
|
1863
|
+
/** Render one wire AttributeValue as a nested `['TAG' => …]` literal. */
|
|
1864
|
+
function renderPhpAv(av) {
|
|
1865
|
+
if ("S" in av) return `['S' => ${phpString(av.S)}]`;
|
|
1866
|
+
if ("N" in av) return `['N' => ${phpString(av.N)}]`;
|
|
1867
|
+
if ("B" in av) return `['B' => base64_decode(${phpString(av.B)})]`;
|
|
1868
|
+
if ("BOOL" in av) return `['BOOL' => ${av.BOOL}]`;
|
|
1869
|
+
if ("SS" in av) return `['SS' => [${av.SS.map(phpString).join(", ")}]]`;
|
|
1870
|
+
if ("NS" in av) return `['NS' => [${av.NS.map(phpString).join(", ")}]]`;
|
|
1871
|
+
if ("BS" in av) return `['BS' => [${av.BS.map((b) => `base64_decode(${phpString(b)})`).join(", ")}]]`;
|
|
1872
|
+
return "['NULL' => true]";
|
|
1873
|
+
}
|
|
1874
|
+
/** Render a typed map as a PHP array of AV literals, one entry per line. */
|
|
1875
|
+
function renderAvMap(map, indent) {
|
|
1876
|
+
const inner = `${indent} `;
|
|
1877
|
+
return `[\n${Object.entries(typedMapToAvMap(map)).map(([name, av]) => `${inner}${phpString(name)} => ${renderPhpAv(av)},`).join("\n")}\n${indent}]`;
|
|
1878
|
+
}
|
|
1879
|
+
/** Render the plain string map (`ExpressionAttributeNames`). */
|
|
1880
|
+
function renderNameMap$1(map, indent) {
|
|
1881
|
+
const inner = `${indent} `;
|
|
1882
|
+
return `[\n${Object.entries(map).map(([alias, name]) => `${inner}${phpString(alias)} => ${phpString(name)},`).join("\n")}\n${indent}]`;
|
|
1883
|
+
}
|
|
1884
|
+
/**
|
|
1885
|
+
* Render the request array literal, one field per line at `indent + 4`.
|
|
1886
|
+
* Exported for the program emitter.
|
|
1887
|
+
*/
|
|
1888
|
+
function renderPhpParams(request, indent) {
|
|
1889
|
+
const pad = `${indent} `;
|
|
1890
|
+
const fields = [`'TableName' => ${phpString(request.tableName)},`];
|
|
1891
|
+
if (request.indexName) fields.push(`'IndexName' => ${phpString(request.indexName)},`);
|
|
1892
|
+
if (request.key) fields.push(`'Key' => ${renderAvMap(request.key, pad)},`);
|
|
1893
|
+
if (request.item) fields.push(`'Item' => ${renderAvMap(request.item, pad)},`);
|
|
1894
|
+
if (request.keyConditionExpression) fields.push(`'KeyConditionExpression' => ${phpString(request.keyConditionExpression)},`);
|
|
1895
|
+
if (request.updateExpression) fields.push(`'UpdateExpression' => ${phpString(request.updateExpression)},`);
|
|
1896
|
+
if (request.conditionExpression) fields.push(`'ConditionExpression' => ${phpString(request.conditionExpression)},`);
|
|
1897
|
+
if (request.filterExpression) fields.push(`'FilterExpression' => ${phpString(request.filterExpression)},`);
|
|
1898
|
+
if (request.projectionExpression) fields.push(`'ProjectionExpression' => ${phpString(request.projectionExpression)},`);
|
|
1899
|
+
if (request.names) fields.push(`'ExpressionAttributeNames' => ${renderNameMap$1(request.names, pad)},`);
|
|
1900
|
+
if (request.typedValues) fields.push(`'ExpressionAttributeValues' => ${renderAvMap(request.typedValues, pad)},`);
|
|
1901
|
+
if (request.limit !== void 0) fields.push(`'Limit' => ${request.limit},`);
|
|
1902
|
+
if (request.consistentRead) fields.push("'ConsistentRead' => true,");
|
|
1903
|
+
if (request.scanIndexForward === false) fields.push("'ScanIndexForward' => false,");
|
|
1904
|
+
if (request.exclusiveStartKey) fields.push(`'ExclusiveStartKey' => ${renderAvMap(request.exclusiveStartKey, pad)},`);
|
|
1905
|
+
return [
|
|
1906
|
+
"[",
|
|
1907
|
+
...fields.map((f) => `${pad}${f}`),
|
|
1908
|
+
`${indent}]`
|
|
1909
|
+
].join("\n");
|
|
1910
|
+
}
|
|
1911
|
+
/** Emit the bare `$response = $client->…([…]);` call for a canonical request. */
|
|
1912
|
+
function emitPhp(request) {
|
|
1913
|
+
return `$response = $client->${CLIENT_METHOD_BY_OP$1[request.operation]}(${renderPhpParams(request, "")});`;
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
//#endregion
|
|
1917
|
+
//#region src/emit/ruby.ts
|
|
1918
|
+
/** Operation → the `Aws::DynamoDB::Client` method (snake_case). */
|
|
1919
|
+
const CLIENT_METHOD_BY_OP = {
|
|
1920
|
+
GetItem: "get_item",
|
|
1921
|
+
Query: "query",
|
|
1922
|
+
Scan: "scan",
|
|
1923
|
+
Update: "update_item",
|
|
1924
|
+
Put: "put_item",
|
|
1925
|
+
Delete: "delete_item"
|
|
1926
|
+
};
|
|
1927
|
+
/** The client method name (snake_case) for an operation. */
|
|
1928
|
+
function rubyClientMethodName(operation) {
|
|
1929
|
+
return CLIENT_METHOD_BY_OP[operation];
|
|
1930
|
+
}
|
|
1931
|
+
/** Ruby single-quoted string — only `\` and `'` need escaping. */
|
|
1932
|
+
function rubyString(value) {
|
|
1933
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
1934
|
+
}
|
|
1935
|
+
/** Render one typed value as the native Ruby literal the SDK marshals. */
|
|
1936
|
+
function renderRubyValue(tv) {
|
|
1937
|
+
switch (tv.type) {
|
|
1938
|
+
case "S": return rubyString(tv.value);
|
|
1939
|
+
case "N": return tv.value;
|
|
1940
|
+
case "B": return `Base64.decode64(${rubyString(tv.value)})`;
|
|
1941
|
+
case "BOOL": return tv.value === "true" ? "true" : "false";
|
|
1942
|
+
case "NULL": return "nil";
|
|
1943
|
+
case "SS": return `Set.new([${(tv.values ?? []).map(rubyString).join(", ")}])`;
|
|
1944
|
+
case "NS": return `Set.new([${(tv.values ?? []).join(", ")}])`;
|
|
1945
|
+
case "BS": return `Set.new([${(tv.values ?? []).map((b) => `Base64.decode64(${rubyString(b)})`).join(", ")}])`;
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
/** Render a typed map as a Ruby hash of native values, one entry per line. */
|
|
1949
|
+
function renderValueMap(map, indent) {
|
|
1950
|
+
const inner = `${indent} `;
|
|
1951
|
+
return `{\n${Object.entries(map).map(([name, tv]) => `${inner}${rubyString(name)} => ${renderRubyValue(tv)},`).join("\n")}\n${indent}}`;
|
|
1952
|
+
}
|
|
1953
|
+
/** Render the plain string map (`expression_attribute_names`). */
|
|
1954
|
+
function renderNameMap(map, indent) {
|
|
1955
|
+
const inner = `${indent} `;
|
|
1956
|
+
return `{\n${Object.entries(map).map(([alias, name]) => `${inner}${rubyString(alias)} => ${rubyString(name)},`).join("\n")}\n${indent}}`;
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Render the request keyword-argument hash, one field per line at `indent + 2`.
|
|
1960
|
+
* Exported for the program emitter.
|
|
1961
|
+
*/
|
|
1962
|
+
function renderRubyParams(request, indent) {
|
|
1963
|
+
const pad = `${indent} `;
|
|
1964
|
+
const fields = [`table_name: ${rubyString(request.tableName)},`];
|
|
1965
|
+
if (request.indexName) fields.push(`index_name: ${rubyString(request.indexName)},`);
|
|
1966
|
+
if (request.key) fields.push(`key: ${renderValueMap(request.key, pad)},`);
|
|
1967
|
+
if (request.item) fields.push(`item: ${renderValueMap(request.item, pad)},`);
|
|
1968
|
+
if (request.keyConditionExpression) fields.push(`key_condition_expression: ${rubyString(request.keyConditionExpression)},`);
|
|
1969
|
+
if (request.updateExpression) fields.push(`update_expression: ${rubyString(request.updateExpression)},`);
|
|
1970
|
+
if (request.conditionExpression) fields.push(`condition_expression: ${rubyString(request.conditionExpression)},`);
|
|
1971
|
+
if (request.filterExpression) fields.push(`filter_expression: ${rubyString(request.filterExpression)},`);
|
|
1972
|
+
if (request.projectionExpression) fields.push(`projection_expression: ${rubyString(request.projectionExpression)},`);
|
|
1973
|
+
if (request.names) fields.push(`expression_attribute_names: ${renderNameMap(request.names, pad)},`);
|
|
1974
|
+
if (request.typedValues) fields.push(`expression_attribute_values: ${renderValueMap(request.typedValues, pad)},`);
|
|
1975
|
+
if (request.limit !== void 0) fields.push(`limit: ${request.limit},`);
|
|
1976
|
+
if (request.consistentRead) fields.push("consistent_read: true,");
|
|
1977
|
+
if (request.scanIndexForward === false) fields.push("scan_index_forward: false,");
|
|
1978
|
+
if (request.exclusiveStartKey) fields.push(`exclusive_start_key: ${renderValueMap(request.exclusiveStartKey, pad)},`);
|
|
1979
|
+
return [
|
|
1980
|
+
"{",
|
|
1981
|
+
...fields.map((f) => `${pad}${f}`),
|
|
1982
|
+
`${indent}}`
|
|
1983
|
+
].join("\n");
|
|
1984
|
+
}
|
|
1985
|
+
/** Emit the bare `response = client.…(…)` call for a canonical request. */
|
|
1986
|
+
function emitRuby(request) {
|
|
1987
|
+
return `response = client.${CLIENT_METHOD_BY_OP[request.operation]}(${renderRubyParams(request, "")})`;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1704
1990
|
//#endregion
|
|
1705
1991
|
//#region src/program.ts
|
|
1706
1992
|
/**
|
|
@@ -1749,6 +2035,22 @@ function emitQueryProgram(config, format) {
|
|
|
1749
2035
|
ok: true,
|
|
1750
2036
|
code: emitRustProgram(request, config.paginate === true)
|
|
1751
2037
|
};
|
|
2038
|
+
case "docclient": return {
|
|
2039
|
+
ok: true,
|
|
2040
|
+
code: emitDocClientProgram(request, config.paginate === true)
|
|
2041
|
+
};
|
|
2042
|
+
case "kotlin": return {
|
|
2043
|
+
ok: true,
|
|
2044
|
+
code: emitKotlinProgram(request, config.paginate === true)
|
|
2045
|
+
};
|
|
2046
|
+
case "php": return {
|
|
2047
|
+
ok: true,
|
|
2048
|
+
code: emitPhpProgram(request, config.paginate === true)
|
|
2049
|
+
};
|
|
2050
|
+
case "ruby": return {
|
|
2051
|
+
ok: true,
|
|
2052
|
+
code: emitRubyProgram(request, config.paginate === true)
|
|
2053
|
+
};
|
|
1752
2054
|
case "ddbtoolbox": return {
|
|
1753
2055
|
ok: true,
|
|
1754
2056
|
code: emitDdbToolboxProgram(request, config.paginate === true)
|
|
@@ -1991,6 +2293,128 @@ function emitRustProgram(request, paginate) {
|
|
|
1991
2293
|
"}"
|
|
1992
2294
|
].join("\n");
|
|
1993
2295
|
}
|
|
2296
|
+
function emitDocClientProgram(request, paginate) {
|
|
2297
|
+
const command = docClientCommandName(request.operation);
|
|
2298
|
+
renderDocClientParams(request, "");
|
|
2299
|
+
if (!paginate) return [
|
|
2300
|
+
"import { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";",
|
|
2301
|
+
`import { DynamoDBDocumentClient, ${command} } from "@aws-sdk/lib-dynamodb";`,
|
|
2302
|
+
"",
|
|
2303
|
+
"const client = DynamoDBDocumentClient.from(new DynamoDBClient({}));",
|
|
2304
|
+
"",
|
|
2305
|
+
"const response = await client.send(",
|
|
2306
|
+
` new ${command}(${renderDocClientParams(request, " ")})`,
|
|
2307
|
+
");",
|
|
2308
|
+
"",
|
|
2309
|
+
"console.log(response.Items);"
|
|
2310
|
+
].join("\n");
|
|
2311
|
+
const paginator = request.operation === "Scan" ? "paginateScan" : "paginateQuery";
|
|
2312
|
+
return [
|
|
2313
|
+
"import { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";",
|
|
2314
|
+
`import { DynamoDBDocumentClient, ${paginator} } from "@aws-sdk/lib-dynamodb";`,
|
|
2315
|
+
"",
|
|
2316
|
+
"const client = DynamoDBDocumentClient.from(new DynamoDBClient({}));",
|
|
2317
|
+
"",
|
|
2318
|
+
`const paginator = ${paginator}(`,
|
|
2319
|
+
" { client },",
|
|
2320
|
+
` ${renderDocClientParams(request, " ")}`,
|
|
2321
|
+
");",
|
|
2322
|
+
"",
|
|
2323
|
+
"for await (const page of paginator) {",
|
|
2324
|
+
" console.log(page.Items);",
|
|
2325
|
+
"}"
|
|
2326
|
+
].join("\n");
|
|
2327
|
+
}
|
|
2328
|
+
function emitKotlinProgram(request, paginate) {
|
|
2329
|
+
const method = kotlinClientMethodName(request.operation);
|
|
2330
|
+
const header = [
|
|
2331
|
+
"import aws.sdk.kotlin.services.dynamodb.DynamoDbClient",
|
|
2332
|
+
"import aws.sdk.kotlin.services.dynamodb.model.AttributeValue",
|
|
2333
|
+
...paginate ? [
|
|
2334
|
+
`import aws.sdk.kotlin.services.dynamodb.paginators.${method}Paginated`,
|
|
2335
|
+
"import aws.sdk.kotlin.services.dynamodb.paginators.items",
|
|
2336
|
+
"import kotlinx.coroutines.flow.collect"
|
|
2337
|
+
] : [],
|
|
2338
|
+
"",
|
|
2339
|
+
"suspend fun main() {",
|
|
2340
|
+
" DynamoDbClient.fromEnvironment().use { client ->"
|
|
2341
|
+
];
|
|
2342
|
+
const body = renderKotlinBuilder(request, " ");
|
|
2343
|
+
if (!paginate) return [
|
|
2344
|
+
...header,
|
|
2345
|
+
` val response = client.${method} {`,
|
|
2346
|
+
...body,
|
|
2347
|
+
" }",
|
|
2348
|
+
" println(response.items)",
|
|
2349
|
+
" }",
|
|
2350
|
+
"}"
|
|
2351
|
+
].join("\n");
|
|
2352
|
+
return [
|
|
2353
|
+
...header,
|
|
2354
|
+
` client.${method}Paginated {`,
|
|
2355
|
+
...body,
|
|
2356
|
+
" }",
|
|
2357
|
+
" .items()",
|
|
2358
|
+
" .collect { item -> println(item) }",
|
|
2359
|
+
" }",
|
|
2360
|
+
"}"
|
|
2361
|
+
].join("\n");
|
|
2362
|
+
}
|
|
2363
|
+
function emitPhpProgram(request, paginate) {
|
|
2364
|
+
const method = phpClientMethodName(request.operation);
|
|
2365
|
+
const header = [
|
|
2366
|
+
"<?php",
|
|
2367
|
+
"",
|
|
2368
|
+
"require 'vendor/autoload.php';",
|
|
2369
|
+
"",
|
|
2370
|
+
"use Aws\\DynamoDb\\DynamoDbClient;",
|
|
2371
|
+
"",
|
|
2372
|
+
"$client = new DynamoDbClient(['region' => 'us-east-1', 'version' => 'latest']);",
|
|
2373
|
+
""
|
|
2374
|
+
];
|
|
2375
|
+
if (!paginate) return [
|
|
2376
|
+
...header,
|
|
2377
|
+
`$response = $client->${method}(${renderPhpParams(request, "")});`,
|
|
2378
|
+
"",
|
|
2379
|
+
"print_r($response['Items']);"
|
|
2380
|
+
].join("\n");
|
|
2381
|
+
const operation = request.operation === "Scan" ? "Scan" : "Query";
|
|
2382
|
+
return [
|
|
2383
|
+
...header,
|
|
2384
|
+
`$pages = $client->getPaginator('${operation}', ${renderPhpParams(request, "")});`,
|
|
2385
|
+
"",
|
|
2386
|
+
"foreach ($pages as $page) {",
|
|
2387
|
+
" print_r($page['Items']);",
|
|
2388
|
+
"}"
|
|
2389
|
+
].join("\n");
|
|
2390
|
+
}
|
|
2391
|
+
function emitRubyProgram(request, paginate) {
|
|
2392
|
+
const method = rubyClientMethodName(request.operation);
|
|
2393
|
+
const usesSets = /Set\.new\(/.test(renderRubyParams(request, ""));
|
|
2394
|
+
const usesBase64 = /Base64\.decode64\(/.test(renderRubyParams(request, ""));
|
|
2395
|
+
const header = [
|
|
2396
|
+
"require 'aws-sdk-dynamodb'",
|
|
2397
|
+
...usesSets ? ["require 'set'"] : [],
|
|
2398
|
+
...usesBase64 ? ["require 'base64'"] : [],
|
|
2399
|
+
"",
|
|
2400
|
+
"client = Aws::DynamoDB::Client.new",
|
|
2401
|
+
""
|
|
2402
|
+
];
|
|
2403
|
+
if (!paginate) return [
|
|
2404
|
+
...header,
|
|
2405
|
+
`response = client.${method}(${renderRubyParams(request, "")})`,
|
|
2406
|
+
"",
|
|
2407
|
+
"puts response.items"
|
|
2408
|
+
].join("\n");
|
|
2409
|
+
return [
|
|
2410
|
+
...header,
|
|
2411
|
+
`response = client.${method}(${renderRubyParams(request, "")})`,
|
|
2412
|
+
"",
|
|
2413
|
+
"response.each do |page|",
|
|
2414
|
+
" puts page.items",
|
|
2415
|
+
"end"
|
|
2416
|
+
].join("\n");
|
|
2417
|
+
}
|
|
1994
2418
|
function emitDotnetProgram(request, paginate) {
|
|
1995
2419
|
const method = dotnetClientMethodName(request.operation);
|
|
1996
2420
|
const binary = hasBinaryValue(request);
|
|
@@ -2036,4 +2460,4 @@ function emitDotnetProgram(request, paginate) {
|
|
|
2036
2460
|
}
|
|
2037
2461
|
|
|
2038
2462
|
//#endregion
|
|
2039
|
-
export { FILTER_OPERATORS, KEY_OPERATORS, OPERATOR_BY_VALUE, SET_TYPES, boto3MethodName, buildFilterExpressions, buildKeyConditionExpression, buildKeyMap, buildRequest, buildSdkV3Params, buildUpdateExpression, dotnetClientMethodName, dotnetRequestClassName, elementType, emitBoto3, emitCli, emitDdbToolboxProgram, emitDotnet, emitGo, emitJava, emitPartiql, emitQueryProgram, emitRust, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, makeTypedValue, renderJsValue, renderPyValue, renderRustAv, rustClientMethodName, sdkV3CommandName, typedMapToAvMap, typedValueToAv };
|
|
2463
|
+
export { FILTER_OPERATORS, KEY_OPERATORS, OPERATOR_BY_VALUE, SET_TYPES, boto3MethodName, buildFilterExpressions, buildKeyConditionExpression, buildKeyMap, buildRequest, buildSdkV3Params, buildUpdateExpression, docClientCommandName, dotnetClientMethodName, dotnetRequestClassName, elementType, emitBoto3, emitCli, emitDdbToolboxProgram, emitDocClient, emitDotnet, emitGo, emitJava, emitKotlin, emitPartiql, emitPhp, emitQueryProgram, emitRuby, emitRust, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, kotlinClientMethodName, makeTypedValue, phpClientMethodName, renderJsValue, renderKotlinAv, renderPhpAv, renderPyValue, renderRubyValue, renderRustAv, rubyClientMethodName, rustClientMethodName, sdkV3CommandName, typedMapToAvMap, typedValueToAv };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dynamodb-expression-builder",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "DynamoDB expression builder and code generator: build update, condition, filter and key condition expressions with automatic ExpressionAttributeNames/Values aliasing, then emit runnable code for the JavaScript SDK v3, AWS CLI, boto3, Java, Go, .NET, Rust, PartiQL and dynamodb-toolbox. Zero dependencies.",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "DynamoDB expression builder and code generator: build update, condition, filter and key condition expressions with automatic ExpressionAttributeNames/Values aliasing, then emit runnable code for the JavaScript SDK v3 and DocumentClient, AWS CLI, boto3, Java, Go, .NET, Rust, Kotlin, PHP, Ruby, PartiQL and dynamodb-toolbox. Zero dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dynamodb",
|
|
7
7
|
"expression",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"query-builder",
|
|
17
17
|
"boto3",
|
|
18
18
|
"rust",
|
|
19
|
+
"kotlin",
|
|
20
|
+
"php",
|
|
21
|
+
"ruby",
|
|
22
|
+
"documentclient",
|
|
19
23
|
"aws"
|
|
20
24
|
],
|
|
21
25
|
"license": "MIT",
|