dynamodb-expression-builder 0.1.1 → 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 +615 -9
- package/dist/index.d.cts +51 -3
- package/dist/index.d.ts +51 -3
- package/dist/index.js +602 -10
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -153,6 +153,24 @@ const FILTER_OPERATORS = [
|
|
|
153
153
|
"L"
|
|
154
154
|
]
|
|
155
155
|
},
|
|
156
|
+
{
|
|
157
|
+
value: "not_contains",
|
|
158
|
+
label: "Not Contains",
|
|
159
|
+
symbol: "∌",
|
|
160
|
+
wireForm: "NOT_CONTAINS",
|
|
161
|
+
requiresValue: true,
|
|
162
|
+
requiresValue2: false,
|
|
163
|
+
typeOptional: false,
|
|
164
|
+
keyAllowedTypes: [],
|
|
165
|
+
scanAllowedTypes: [
|
|
166
|
+
"S",
|
|
167
|
+
"B",
|
|
168
|
+
"SS",
|
|
169
|
+
"NS",
|
|
170
|
+
"BS",
|
|
171
|
+
"L"
|
|
172
|
+
]
|
|
173
|
+
},
|
|
156
174
|
{
|
|
157
175
|
value: "begins_with",
|
|
158
176
|
label: "Begins With",
|
|
@@ -369,6 +387,9 @@ function buildOne(row, index, prefix, names, typedValues) {
|
|
|
369
387
|
case "CONTAINS":
|
|
370
388
|
typedValues[valueRef] = makeTypedValue(elementType(row.type), row.value);
|
|
371
389
|
return `contains(${nameRef}, ${valueRef})`;
|
|
390
|
+
case "NOT_CONTAINS":
|
|
391
|
+
typedValues[valueRef] = makeTypedValue(elementType(row.type), row.value);
|
|
392
|
+
return `NOT contains(${nameRef}, ${valueRef})`;
|
|
372
393
|
case "BEGINS_WITH":
|
|
373
394
|
typedValues[valueRef] = single$1(row);
|
|
374
395
|
return `begins_with(${nameRef}, ${valueRef})`;
|
|
@@ -725,7 +746,7 @@ function hasBinaryValue(request) {
|
|
|
725
746
|
//#endregion
|
|
726
747
|
//#region src/emit/sdk-v3.ts
|
|
727
748
|
/** Operation → the `@aws-sdk/client-dynamodb` command class name. */
|
|
728
|
-
const COMMAND_BY_OP = {
|
|
749
|
+
const COMMAND_BY_OP$1 = {
|
|
729
750
|
GetItem: "GetItemCommand",
|
|
730
751
|
Query: "QueryCommand",
|
|
731
752
|
Scan: "ScanCommand",
|
|
@@ -783,11 +804,11 @@ function jsLiteral(value, indent) {
|
|
|
783
804
|
}
|
|
784
805
|
/** Emit the `new <Op>Command({...})` source snippet for a canonical request. */
|
|
785
806
|
function emitSdkV3(request) {
|
|
786
|
-
return `new ${COMMAND_BY_OP[request.operation]}(${jsLiteral(buildSdkV3Params(request), 0)})`;
|
|
807
|
+
return `new ${COMMAND_BY_OP$1[request.operation]}(${jsLiteral(buildSdkV3Params(request), 0)})`;
|
|
787
808
|
}
|
|
788
809
|
/** The `@aws-sdk/client-dynamodb` command class name for an operation. */
|
|
789
810
|
function sdkV3CommandName(operation) {
|
|
790
|
-
return COMMAND_BY_OP[operation];
|
|
811
|
+
return COMMAND_BY_OP$1[operation];
|
|
791
812
|
}
|
|
792
813
|
/**
|
|
793
814
|
* Render an arbitrary params value as the same pretty-printed JS literal
|
|
@@ -966,6 +987,7 @@ function predicate(row) {
|
|
|
966
987
|
case "BETWEEN": return `${id} BETWEEN ${literal(makeTypedValue(row.type, row.value))} AND ${literal(makeTypedValue(row.type, row.value2 ?? ""))}`;
|
|
967
988
|
case "BEGINS_WITH": return `begins_with(${id}, ${literal(single(row))})`;
|
|
968
989
|
case "CONTAINS": return `contains(${id}, ${literal(makeTypedValue(elementType(row.type), row.value))})`;
|
|
990
|
+
case "NOT_CONTAINS": return `NOT contains(${id}, ${literal(makeTypedValue(elementType(row.type), row.value))})`;
|
|
969
991
|
case "IN": return `${id} IN (${(row.values ?? (row.value ? [row.value] : [])).map((m) => literal(makeTypedValue(row.type, m))).join(", ")})`;
|
|
970
992
|
case "EXISTS": return `${id} IS NOT MISSING`;
|
|
971
993
|
case "NOT_EXISTS": return `${id} IS MISSING`;
|
|
@@ -1094,7 +1116,7 @@ const REQUEST_CLASS_BY_OP$1 = {
|
|
|
1094
1116
|
Delete: "DeleteItemRequest"
|
|
1095
1117
|
};
|
|
1096
1118
|
/** Operation → the `DynamoDbClient` method. */
|
|
1097
|
-
const CLIENT_METHOD_BY_OP$
|
|
1119
|
+
const CLIENT_METHOD_BY_OP$6 = {
|
|
1098
1120
|
GetItem: "getItem",
|
|
1099
1121
|
Query: "query",
|
|
1100
1122
|
Scan: "scan",
|
|
@@ -1108,7 +1130,7 @@ function javaRequestClassName(operation) {
|
|
|
1108
1130
|
}
|
|
1109
1131
|
/** The `DynamoDbClient` method name for an operation (`query`, …). */
|
|
1110
1132
|
function javaClientMethodName(operation) {
|
|
1111
|
-
return CLIENT_METHOD_BY_OP$
|
|
1133
|
+
return CLIENT_METHOD_BY_OP$6[operation];
|
|
1112
1134
|
}
|
|
1113
1135
|
/** Java string literal — `JSON.stringify` escapes are all valid Java escapes. */
|
|
1114
1136
|
function javaString(value) {
|
|
@@ -1187,7 +1209,7 @@ const INPUT_TYPE_BY_OP = {
|
|
|
1187
1209
|
Delete: "DeleteItemInput"
|
|
1188
1210
|
};
|
|
1189
1211
|
/** Operation → the `dynamodb.Client` method. */
|
|
1190
|
-
const CLIENT_METHOD_BY_OP$
|
|
1212
|
+
const CLIENT_METHOD_BY_OP$5 = {
|
|
1191
1213
|
GetItem: "GetItem",
|
|
1192
1214
|
Query: "Query",
|
|
1193
1215
|
Scan: "Scan",
|
|
@@ -1201,7 +1223,7 @@ function goInputTypeName(operation) {
|
|
|
1201
1223
|
}
|
|
1202
1224
|
/** The `dynamodb.Client` method name for an operation. */
|
|
1203
1225
|
function goClientMethodName(operation) {
|
|
1204
|
-
return CLIENT_METHOD_BY_OP$
|
|
1226
|
+
return CLIENT_METHOD_BY_OP$5[operation];
|
|
1205
1227
|
}
|
|
1206
1228
|
/** Go string literal — `JSON.stringify` escapes are all valid Go escapes. */
|
|
1207
1229
|
function goString(value) {
|
|
@@ -1291,7 +1313,7 @@ const REQUEST_CLASS_BY_OP = {
|
|
|
1291
1313
|
Delete: "DeleteItemRequest"
|
|
1292
1314
|
};
|
|
1293
1315
|
/** Operation → the async `AmazonDynamoDBClient` method. */
|
|
1294
|
-
const CLIENT_METHOD_BY_OP = {
|
|
1316
|
+
const CLIENT_METHOD_BY_OP$4 = {
|
|
1295
1317
|
GetItem: "GetItemAsync",
|
|
1296
1318
|
Query: "QueryAsync",
|
|
1297
1319
|
Scan: "ScanAsync",
|
|
@@ -1305,7 +1327,7 @@ function dotnetRequestClassName(operation) {
|
|
|
1305
1327
|
}
|
|
1306
1328
|
/** The async client method name for an operation (`QueryAsync`, …). */
|
|
1307
1329
|
function dotnetClientMethodName(operation) {
|
|
1308
|
-
return CLIENT_METHOD_BY_OP[operation];
|
|
1330
|
+
return CLIENT_METHOD_BY_OP$4[operation];
|
|
1309
1331
|
}
|
|
1310
1332
|
/** C# string literal — `JSON.stringify` escapes are all valid C# escapes. */
|
|
1311
1333
|
function csString(value) {
|
|
@@ -1372,6 +1394,102 @@ function emitDotnet(request) {
|
|
|
1372
1394
|
return renderCsRequest(request, "");
|
|
1373
1395
|
}
|
|
1374
1396
|
|
|
1397
|
+
//#endregion
|
|
1398
|
+
//#region src/emit/rust.ts
|
|
1399
|
+
/** Operation → the `aws_sdk_dynamodb::Client` fluent method. */
|
|
1400
|
+
const CLIENT_METHOD_BY_OP$3 = {
|
|
1401
|
+
GetItem: "get_item",
|
|
1402
|
+
Query: "query",
|
|
1403
|
+
Scan: "scan",
|
|
1404
|
+
Update: "update_item",
|
|
1405
|
+
Put: "put_item",
|
|
1406
|
+
Delete: "delete_item"
|
|
1407
|
+
};
|
|
1408
|
+
/** The `Client` method name (snake_case) for an operation. */
|
|
1409
|
+
function rustClientMethodName(operation) {
|
|
1410
|
+
return CLIENT_METHOD_BY_OP$3[operation];
|
|
1411
|
+
}
|
|
1412
|
+
/** Rust string literal — JSON escapes with the three Rust-incompatible ones fixed. */
|
|
1413
|
+
function rustString(value) {
|
|
1414
|
+
return JSON.stringify(value).replace(/\\b/g, "\\u{0008}").replace(/\\f/g, "\\u{000c}").replace(/\\u([0-9a-fA-F]{4})/g, "\\u{$1}");
|
|
1415
|
+
}
|
|
1416
|
+
/** `"…".to_string()` — the owned String the AttributeValue constructors take. */
|
|
1417
|
+
function rustOwned(value) {
|
|
1418
|
+
return `${rustString(value)}.to_string()`;
|
|
1419
|
+
}
|
|
1420
|
+
/** Decode canonical base64 into a `Blob::new(vec![0x…])` (fail-loud on bad input). */
|
|
1421
|
+
function rustBlob(base64) {
|
|
1422
|
+
let raw;
|
|
1423
|
+
try {
|
|
1424
|
+
raw = atob(base64);
|
|
1425
|
+
} catch {
|
|
1426
|
+
throw new Error(`invalid base64 in a binary (B/BS) value: ${base64}`);
|
|
1427
|
+
}
|
|
1428
|
+
return `Blob::new(vec![${Array.from(raw, (c) => `0x${c.charCodeAt(0).toString(16).padStart(2, "0")}`).join(", ")}])`;
|
|
1429
|
+
}
|
|
1430
|
+
/** Render one wire AttributeValue as an `AttributeValue::…` constructor. */
|
|
1431
|
+
function renderRustAv(av) {
|
|
1432
|
+
if ("S" in av) return `AttributeValue::S(${rustOwned(av.S)})`;
|
|
1433
|
+
if ("N" in av) return `AttributeValue::N(${rustOwned(av.N)})`;
|
|
1434
|
+
if ("B" in av) return `AttributeValue::B(${rustBlob(av.B)})`;
|
|
1435
|
+
if ("BOOL" in av) return `AttributeValue::Bool(${av.BOOL})`;
|
|
1436
|
+
if ("SS" in av) return `AttributeValue::Ss(vec![${av.SS.map(rustOwned).join(", ")}])`;
|
|
1437
|
+
if ("NS" in av) return `AttributeValue::Ns(vec![${av.NS.map(rustOwned).join(", ")}])`;
|
|
1438
|
+
if ("BS" in av) return `AttributeValue::Bs(vec![${av.BS.map(rustBlob).join(", ")}])`;
|
|
1439
|
+
return "AttributeValue::Null(true)";
|
|
1440
|
+
}
|
|
1441
|
+
/** One `.method(key, av)` line per entry of a typed map. */
|
|
1442
|
+
function avEntryLines(method, map, indent) {
|
|
1443
|
+
return Object.entries(typedMapToAvMap(map)).map(([name, av]) => `${indent}.${method}(${rustString(name)}, ${renderRustAv(av)})`);
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Render the fluent builder chain for a request — every line at `indent`,
|
|
1447
|
+
* starting with `.{op}()` and ending BEFORE `.send()` so callers own the
|
|
1448
|
+
* terminal (the bare emitter awaits inline; the program emitter may hand the
|
|
1449
|
+
* chain to `into_paginator()` instead). Exported for the program emitter.
|
|
1450
|
+
*/
|
|
1451
|
+
function renderRustBuilder(request, indent) {
|
|
1452
|
+
const lines = [`${indent}.${CLIENT_METHOD_BY_OP$3[request.operation]}()`];
|
|
1453
|
+
lines.push(`${indent}.table_name(${rustString(request.tableName)})`);
|
|
1454
|
+
if (request.indexName) lines.push(`${indent}.index_name(${rustString(request.indexName)})`);
|
|
1455
|
+
if (request.key) lines.push(...avEntryLines("key", request.key, indent));
|
|
1456
|
+
if (request.item) lines.push(...avEntryLines("item", request.item, indent));
|
|
1457
|
+
if (request.keyConditionExpression) lines.push(`${indent}.key_condition_expression(${rustString(request.keyConditionExpression)})`);
|
|
1458
|
+
if (request.updateExpression) lines.push(`${indent}.update_expression(${rustString(request.updateExpression)})`);
|
|
1459
|
+
if (request.conditionExpression) lines.push(`${indent}.condition_expression(${rustString(request.conditionExpression)})`);
|
|
1460
|
+
if (request.filterExpression) lines.push(`${indent}.filter_expression(${rustString(request.filterExpression)})`);
|
|
1461
|
+
if (request.projectionExpression) lines.push(`${indent}.projection_expression(${rustString(request.projectionExpression)})`);
|
|
1462
|
+
if (request.names) lines.push(...Object.entries(request.names).map(([alias, name]) => `${indent}.expression_attribute_names(${rustString(alias)}, ${rustString(name)})`));
|
|
1463
|
+
if (request.typedValues) lines.push(...avEntryLines("expression_attribute_values", request.typedValues, indent));
|
|
1464
|
+
if (request.limit !== void 0) lines.push(`${indent}.limit(${request.limit})`);
|
|
1465
|
+
if (request.consistentRead) lines.push(`${indent}.consistent_read(true)`);
|
|
1466
|
+
if (request.scanIndexForward === false) lines.push(`${indent}.scan_index_forward(false)`);
|
|
1467
|
+
if (request.exclusiveStartKey) lines.push(...avEntryLines("exclusive_start_key", request.exclusiveStartKey, indent));
|
|
1468
|
+
return lines;
|
|
1469
|
+
}
|
|
1470
|
+
/** Does this request build any `AttributeValue`? Drives the program emitter's imports. */
|
|
1471
|
+
function rustUsesAttributeValue(request) {
|
|
1472
|
+
return request.key !== void 0 || request.item !== void 0 || request.typedValues !== void 0 || request.exclusiveStartKey !== void 0;
|
|
1473
|
+
}
|
|
1474
|
+
/** Does this request build any binary Blob? Drives the `primitives::Blob` import. */
|
|
1475
|
+
function rustUsesBlob(request) {
|
|
1476
|
+
return [
|
|
1477
|
+
request.key,
|
|
1478
|
+
request.item,
|
|
1479
|
+
request.typedValues,
|
|
1480
|
+
request.exclusiveStartKey
|
|
1481
|
+
].some((map) => map && Object.values(typedMapToAvMap(map)).some((av) => "B" in av || "BS" in av));
|
|
1482
|
+
}
|
|
1483
|
+
/** Emit the bare fluent call for a canonical request (awaited, `?`-propagated). */
|
|
1484
|
+
function emitRust(request) {
|
|
1485
|
+
return [
|
|
1486
|
+
"let response = client",
|
|
1487
|
+
...renderRustBuilder(request, " "),
|
|
1488
|
+
" .send()",
|
|
1489
|
+
" .await?;"
|
|
1490
|
+
].join("\n");
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1375
1493
|
//#endregion
|
|
1376
1494
|
//#region src/emit/ddbtoolbox.ts
|
|
1377
1495
|
/** Key attr DynamoDB type (S/N/B) → the Table `type` string dynamodb-toolbox wants. */
|
|
@@ -1437,6 +1555,7 @@ function renderCondition(f) {
|
|
|
1437
1555
|
if (f.operator === "exists") return `{ attr: ${attr}, exists: true }`;
|
|
1438
1556
|
if (f.operator === "not_exists") return `{ attr: ${attr}, exists: false }`;
|
|
1439
1557
|
if (f.operator === "contains") return `{ attr: ${attr}, contains: ${val()} }`;
|
|
1558
|
+
if (f.operator === "not_contains") return `{ not: { attr: ${attr}, contains: ${val()} } }`;
|
|
1440
1559
|
if (f.operator === "begins_with") return `{ attr: ${attr}, beginsWith: ${val()} }`;
|
|
1441
1560
|
if (f.operator === "between") return `{ attr: ${attr}, between: [${renderNativeValue(scalar(f.type, f.value))}, ${renderNativeValue(scalar(f.type, f.value2 ?? ""))}] }`;
|
|
1442
1561
|
if (f.operator === "in") return `{ attr: ${attr}, in: [${(f.values ?? []).map((v) => renderNativeValue(scalar(f.type, v))).join(", ")}] }`;
|
|
@@ -1582,6 +1701,292 @@ function emitDdbToolboxProgram(request, paginate) {
|
|
|
1582
1701
|
].filter((l) => l !== null).join("\n");
|
|
1583
1702
|
}
|
|
1584
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
|
+
|
|
1585
1990
|
//#endregion
|
|
1586
1991
|
//#region src/program.ts
|
|
1587
1992
|
/**
|
|
@@ -1626,6 +2031,26 @@ function emitQueryProgram(config, format) {
|
|
|
1626
2031
|
ok: true,
|
|
1627
2032
|
code: emitDotnetProgram(request, config.paginate === true)
|
|
1628
2033
|
};
|
|
2034
|
+
case "rust": return {
|
|
2035
|
+
ok: true,
|
|
2036
|
+
code: emitRustProgram(request, config.paginate === true)
|
|
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
|
+
};
|
|
1629
2054
|
case "ddbtoolbox": return {
|
|
1630
2055
|
ok: true,
|
|
1631
2056
|
code: emitDdbToolboxProgram(request, config.paginate === true)
|
|
@@ -1823,6 +2248,173 @@ function emitGoProgram(request, paginate) {
|
|
|
1823
2248
|
"}"
|
|
1824
2249
|
].join("\n");
|
|
1825
2250
|
}
|
|
2251
|
+
function emitRustProgram(request, paginate) {
|
|
2252
|
+
const usesAv = rustUsesAttributeValue(request);
|
|
2253
|
+
const usesBlob = rustUsesBlob(request);
|
|
2254
|
+
const header = [
|
|
2255
|
+
...[
|
|
2256
|
+
"// Cargo.toml: aws-config, aws-sdk-dynamodb, tokio (features = [\"full\"])",
|
|
2257
|
+
"use aws_sdk_dynamodb::Client;",
|
|
2258
|
+
...usesAv ? ["use aws_sdk_dynamodb::types::AttributeValue;"] : [],
|
|
2259
|
+
...usesBlob ? ["use aws_sdk_dynamodb::primitives::Blob;"] : []
|
|
2260
|
+
],
|
|
2261
|
+
"",
|
|
2262
|
+
"#[tokio::main]",
|
|
2263
|
+
"async fn main() -> Result<(), aws_sdk_dynamodb::Error> {",
|
|
2264
|
+
" let config = aws_config::load_from_env().await;",
|
|
2265
|
+
" let client = Client::new(&config);",
|
|
2266
|
+
""
|
|
2267
|
+
];
|
|
2268
|
+
const builder = renderRustBuilder(request, " ");
|
|
2269
|
+
if (!paginate) return [
|
|
2270
|
+
...header,
|
|
2271
|
+
" let response = client",
|
|
2272
|
+
...builder,
|
|
2273
|
+
" .send()",
|
|
2274
|
+
" .await?;",
|
|
2275
|
+
" println!(\"{:?}\", response.items());",
|
|
2276
|
+
"",
|
|
2277
|
+
" Ok(())",
|
|
2278
|
+
"}"
|
|
2279
|
+
].join("\n");
|
|
2280
|
+
return [
|
|
2281
|
+
...header,
|
|
2282
|
+
" let mut items = client",
|
|
2283
|
+
...builder,
|
|
2284
|
+
" .into_paginator()",
|
|
2285
|
+
" .items()",
|
|
2286
|
+
" .send();",
|
|
2287
|
+
"",
|
|
2288
|
+
" while let Some(item) = items.next().await {",
|
|
2289
|
+
" println!(\"{:?}\", item?);",
|
|
2290
|
+
" }",
|
|
2291
|
+
"",
|
|
2292
|
+
" Ok(())",
|
|
2293
|
+
"}"
|
|
2294
|
+
].join("\n");
|
|
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
|
+
}
|
|
1826
2418
|
function emitDotnetProgram(request, paginate) {
|
|
1827
2419
|
const method = dotnetClientMethodName(request.operation);
|
|
1828
2420
|
const binary = hasBinaryValue(request);
|
|
@@ -1868,4 +2460,4 @@ function emitDotnetProgram(request, paginate) {
|
|
|
1868
2460
|
}
|
|
1869
2461
|
|
|
1870
2462
|
//#endregion
|
|
1871
|
-
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, emitSdkV3, getCompatibleComparisonOperators, getCompatibleFilterOperators, goClientMethodName, goInputTypeName, hasBinaryValue, isSetType, javaClientMethodName, javaRequestClassName, makeTypedValue, renderJsValue, renderPyValue, 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 };
|