@suss/packs 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +205 -0
- package/README.md +29 -0
- package/dist/activerecord.d.ts +30 -0
- package/dist/activerecord.js +45 -0
- package/dist/apollo-client.d.ts +1 -0
- package/dist/apollo-client.js +137 -0
- package/dist/apollo.d.ts +1 -0
- package/dist/apollo.js +90 -0
- package/dist/aws-dynamodb.d.ts +1 -0
- package/dist/aws-dynamodb.js +386 -0
- package/dist/aws-eventbridge.d.ts +1 -0
- package/dist/aws-eventbridge.js +240 -0
- package/dist/aws-lambda.d.ts +1 -0
- package/dist/aws-lambda.js +382 -0
- package/dist/aws-s3.d.ts +1 -0
- package/dist/aws-s3.js +120 -0
- package/dist/aws-sqs.d.ts +1 -0
- package/dist/aws-sqs.js +296 -0
- package/dist/axios.d.ts +1 -0
- package/dist/axios.js +107 -0
- package/dist/cloudflare-workers.d.ts +1 -0
- package/dist/cloudflare-workers.js +562 -0
- package/dist/drizzle.d.ts +1 -0
- package/dist/drizzle.js +383 -0
- package/dist/express.d.ts +1 -0
- package/dist/express.js +124 -0
- package/dist/fastapi.d.ts +1 -0
- package/dist/fastapi.js +42 -0
- package/dist/fastify.d.ts +1 -0
- package/dist/fastify.js +116 -0
- package/dist/fetch.d.ts +1 -0
- package/dist/fetch.js +64 -0
- package/dist/flask-restx.d.ts +1 -0
- package/dist/flask-restx.js +59 -0
- package/dist/gcs.d.ts +1 -0
- package/dist/gcs.js +134 -0
- package/dist/graphql-ruby.d.ts +1 -0
- package/dist/graphql-ruby.js +84 -0
- package/dist/hono.d.ts +1 -0
- package/dist/hono.js +184 -0
- package/dist/mongoose.d.ts +1 -0
- package/dist/mongoose.js +379 -0
- package/dist/nestjs-graphql.d.ts +1 -0
- package/dist/nestjs-graphql.js +77 -0
- package/dist/nestjs-rest.d.ts +1 -0
- package/dist/nestjs-rest.js +89 -0
- package/dist/nextjs.d.ts +1 -0
- package/dist/nextjs.js +154 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.js +667 -0
- package/dist/prisma.d.ts +1 -0
- package/dist/prisma.js +448 -0
- package/dist/react-router.d.ts +1 -0
- package/dist/react-router.js +197 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +221 -0
- package/dist/redis.d.ts +1 -0
- package/dist/redis.js +93 -0
- package/dist/sqlalchemy.d.ts +1 -0
- package/dist/sqlalchemy.js +48 -0
- package/dist/ts-rest.d.ts +1 -0
- package/dist/ts-rest.js +89 -0
- package/package.json +208 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
// ../framework/aws-dynamodb/dist/index.js
|
|
2
|
+
import { Node as N } from "ts-morph";
|
|
3
|
+
import { readName, rootIdentifier } from "@suss/adapter-typescript";
|
|
4
|
+
import { storageBinding } from "@suss/behavioral-ir";
|
|
5
|
+
var COMMAND_MODULES = [
|
|
6
|
+
"@aws-sdk/lib-dynamodb",
|
|
7
|
+
"@aws-sdk/client-dynamodb"
|
|
8
|
+
];
|
|
9
|
+
var RECOGNITION = "@suss/framework-aws-dynamodb";
|
|
10
|
+
var COMMANDS = {
|
|
11
|
+
GetCommand: "read",
|
|
12
|
+
GetItemCommand: "read",
|
|
13
|
+
QueryCommand: "read",
|
|
14
|
+
ScanCommand: "read",
|
|
15
|
+
BatchGetCommand: "read",
|
|
16
|
+
BatchGetItemCommand: "read",
|
|
17
|
+
PutCommand: "write",
|
|
18
|
+
PutItemCommand: "write",
|
|
19
|
+
UpdateCommand: "write",
|
|
20
|
+
UpdateItemCommand: "write",
|
|
21
|
+
DeleteCommand: "write",
|
|
22
|
+
DeleteItemCommand: "write",
|
|
23
|
+
BatchWriteCommand: "write",
|
|
24
|
+
BatchWriteItemCommand: "write"
|
|
25
|
+
};
|
|
26
|
+
function dynamoRecognizer(call, ctx) {
|
|
27
|
+
const callNode = call;
|
|
28
|
+
const recognizerCtx = ctx;
|
|
29
|
+
const resolve = recognizerCtx.resolveWrittenValue ?? (() => null);
|
|
30
|
+
const callee = callNode.getExpression();
|
|
31
|
+
if (!N.isPropertyAccessExpression(callee) || callee.getName() !== "send") {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const firstArg = callNode.getArguments()[0];
|
|
35
|
+
if (firstArg === void 0) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const built = N.isNewExpression(firstArg) ? firstArg : asNewExpression(resolve(firstArg));
|
|
39
|
+
if (built === null) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const ctorExpr = built.getExpression();
|
|
43
|
+
const commandName = N.isPropertyAccessExpression(ctorExpr) ? ctorExpr.getName() : ctorExpr.getText();
|
|
44
|
+
const kind = COMMANDS[commandName];
|
|
45
|
+
if (kind === void 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (!fromDynamoModule(ctorExpr, recognizerCtx)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const input = built.getArguments()[0];
|
|
52
|
+
if (input === void 0 || !N.isObjectLiteralExpression(input)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return requestEffects({
|
|
56
|
+
input,
|
|
57
|
+
kind,
|
|
58
|
+
operation: commandName,
|
|
59
|
+
callee: callee.getText(),
|
|
60
|
+
transport: "aws-sdk",
|
|
61
|
+
resolve
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function requestEffects(read) {
|
|
65
|
+
const { input, kind, operation, callee, resolve } = read;
|
|
66
|
+
const requestItems = property(input, "RequestItems");
|
|
67
|
+
if (requestItems !== null) {
|
|
68
|
+
return batchEffects(requestItems, read);
|
|
69
|
+
}
|
|
70
|
+
const picked = selector(input);
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
type: "interaction",
|
|
74
|
+
binding: dynamoBinding(read, {
|
|
75
|
+
container: nameOfProperty(input, "TableName", resolve),
|
|
76
|
+
accessPath: nameOfProperty(input, "IndexName", resolve)
|
|
77
|
+
}),
|
|
78
|
+
callee,
|
|
79
|
+
interaction: {
|
|
80
|
+
class: "storage-access",
|
|
81
|
+
kind,
|
|
82
|
+
fields: fieldsOf(input, kind),
|
|
83
|
+
operation,
|
|
84
|
+
...picked.length > 0 ? { selector: picked } : {}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
function dynamoBinding(read, addressed) {
|
|
90
|
+
return storageBinding({
|
|
91
|
+
recognition: RECOGNITION,
|
|
92
|
+
storageSystem: "aws.dynamodb",
|
|
93
|
+
...read.transport === void 0 ? {} : { transport: read.transport },
|
|
94
|
+
scope: "default",
|
|
95
|
+
container: addressed.container,
|
|
96
|
+
accessPath: addressed.accessPath
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function batchEffects(requestItems, read) {
|
|
100
|
+
const { kind, operation, callee, resolve } = read;
|
|
101
|
+
if (!N.isObjectLiteralExpression(requestItems)) {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
const effects = [];
|
|
105
|
+
for (const entry of requestItems.getProperties()) {
|
|
106
|
+
if (!N.isPropertyAssignment(entry)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const requests = entry.getInitializer();
|
|
110
|
+
effects.push({
|
|
111
|
+
type: "interaction",
|
|
112
|
+
binding: dynamoBinding(read, {
|
|
113
|
+
container: entryName(entry, resolve),
|
|
114
|
+
accessPath: null
|
|
115
|
+
}),
|
|
116
|
+
callee,
|
|
117
|
+
interaction: {
|
|
118
|
+
class: "storage-access",
|
|
119
|
+
kind,
|
|
120
|
+
fields: requests === void 0 ? [] : requestedFields(requests, kind),
|
|
121
|
+
operation
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return effects;
|
|
126
|
+
}
|
|
127
|
+
function entryName(entry, resolve) {
|
|
128
|
+
if (!N.isPropertyAssignment(entry)) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const nameNode = entry.getNameNode();
|
|
132
|
+
if (N.isComputedPropertyName(nameNode)) {
|
|
133
|
+
return readName(nameNode.getExpression(), { resolve });
|
|
134
|
+
}
|
|
135
|
+
if (N.isStringLiteral(nameNode) || N.isIdentifier(nameNode)) {
|
|
136
|
+
return nameNode.getText().replace(/^["']|["']$/g, "");
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
function requestedFields(requests, kind) {
|
|
141
|
+
const found = /* @__PURE__ */ new Set();
|
|
142
|
+
requests.forEachDescendant((node) => {
|
|
143
|
+
if (!N.isPropertyAssignment(node)) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const name = node.getName();
|
|
147
|
+
if (name !== "Item" && name !== "Key" && name !== "Keys") {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const value = node.getInitializer();
|
|
151
|
+
if (value === void 0) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
for (const key of N.isArrayLiteralExpression(value) ? value.getElements().flatMap((element) => objectKeys(element)) : objectKeys(value)) {
|
|
155
|
+
found.add(key);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return found.size > 0 ? [...found] : kind === "read" ? ["*"] : [];
|
|
159
|
+
}
|
|
160
|
+
function asNewExpression(resolved) {
|
|
161
|
+
return resolved !== null && N.isNewExpression(resolved) ? resolved : null;
|
|
162
|
+
}
|
|
163
|
+
function fromDynamoModule(ctorExpr, ctx) {
|
|
164
|
+
const target = N.isPropertyAccessExpression(ctorExpr) ? rootIdentifier(ctorExpr) : ctorExpr;
|
|
165
|
+
if (target === null) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return COMMAND_MODULES.some((module) => ctx.isImportedFrom(target, module));
|
|
169
|
+
}
|
|
170
|
+
function property(input, name) {
|
|
171
|
+
if (!N.isObjectLiteralExpression(input)) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
for (const prop of input.getProperties()) {
|
|
175
|
+
if (N.isPropertyAssignment(prop) && prop.getName() === name) {
|
|
176
|
+
return prop.getInitializer() ?? null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
function nameOfProperty(input, name, resolve) {
|
|
182
|
+
const written = property(input, name);
|
|
183
|
+
return written === null ? null : readName(written, { resolve, unsettled: "reference" });
|
|
184
|
+
}
|
|
185
|
+
function fieldsOf(input, kind) {
|
|
186
|
+
const projection = property(input, "ProjectionExpression");
|
|
187
|
+
if (projection !== null) {
|
|
188
|
+
const text = literalText(projection);
|
|
189
|
+
if (text !== null) {
|
|
190
|
+
const aliases = expressionNames(input);
|
|
191
|
+
return text.split(",").map((field) => field.trim()).filter((field) => field !== "").map((field) => aliases.get(field) ?? field);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (kind === "write") {
|
|
195
|
+
const item = property(input, "Item");
|
|
196
|
+
if (item !== null && N.isObjectLiteralExpression(item)) {
|
|
197
|
+
return objectKeys(item);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return kind === "read" ? ["*"] : [];
|
|
201
|
+
}
|
|
202
|
+
function selector(input) {
|
|
203
|
+
const key = property(input, "Key");
|
|
204
|
+
if (key !== null && N.isObjectLiteralExpression(key)) {
|
|
205
|
+
return objectKeys(key);
|
|
206
|
+
}
|
|
207
|
+
const condition = property(input, "KeyConditionExpression");
|
|
208
|
+
const text = condition === null ? null : literalText(condition);
|
|
209
|
+
if (text === null) {
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
212
|
+
return keyConditionAttributes(text, expressionNames(input));
|
|
213
|
+
}
|
|
214
|
+
function expressionNames(input) {
|
|
215
|
+
const names = /* @__PURE__ */ new Map();
|
|
216
|
+
const declared = property(input, "ExpressionAttributeNames");
|
|
217
|
+
if (declared === null || !N.isObjectLiteralExpression(declared)) {
|
|
218
|
+
return names;
|
|
219
|
+
}
|
|
220
|
+
for (const prop of declared.getProperties()) {
|
|
221
|
+
if (!N.isPropertyAssignment(prop)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const value = prop.getInitializer();
|
|
225
|
+
const written = value === void 0 ? null : literalText(value);
|
|
226
|
+
if (written === null) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
names.set(prop.getName().replace(/^["']|["']$/g, ""), written);
|
|
230
|
+
}
|
|
231
|
+
return names;
|
|
232
|
+
}
|
|
233
|
+
function literalText(value) {
|
|
234
|
+
return N.isStringLiteral(value) || N.isNoSubstitutionTemplateLiteral(value) ? value.getLiteralValue() : null;
|
|
235
|
+
}
|
|
236
|
+
var ATTRIBUTE_POSITIONS = [
|
|
237
|
+
/([#\w.]+)\s*(?:<>|<=|>=|=|<|>)/g,
|
|
238
|
+
/\(\s*([#\w.]+)\s*,/g,
|
|
239
|
+
/([#\w.]+)\s+[A-Za-z_]+\s+:/g
|
|
240
|
+
];
|
|
241
|
+
function keyConditionAttributes(expression, names) {
|
|
242
|
+
const found = [];
|
|
243
|
+
const add = (token) => {
|
|
244
|
+
if (token === void 0) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const name = token.startsWith("#") ? names.get(token) : token;
|
|
248
|
+
if (name !== void 0 && !found.includes(name)) {
|
|
249
|
+
found.push(name);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
for (const pattern of ATTRIBUTE_POSITIONS) {
|
|
253
|
+
for (const match of expression.matchAll(pattern)) {
|
|
254
|
+
add(match[1]);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return found;
|
|
258
|
+
}
|
|
259
|
+
function objectKeys(literal) {
|
|
260
|
+
if (!N.isObjectLiteralExpression(literal)) {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
const keys = [];
|
|
264
|
+
for (const prop of literal.getProperties()) {
|
|
265
|
+
if (N.isPropertyAssignment(prop) || N.isShorthandPropertyAssignment(prop)) {
|
|
266
|
+
keys.push(prop.getName().replace(/^["']|["']$/g, ""));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return keys;
|
|
270
|
+
}
|
|
271
|
+
function requestFunctionRecognizer(spec) {
|
|
272
|
+
return ((call, ctx) => {
|
|
273
|
+
const callNode = call;
|
|
274
|
+
const recognizerCtx = ctx;
|
|
275
|
+
const resolve = recognizerCtx.resolveWrittenValue ?? (() => null);
|
|
276
|
+
const callee = callNode.getExpression();
|
|
277
|
+
if (calledName(callee) !== spec.name) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
if (spec.module !== void 0 && !declaredIn(callee, spec.module, recognizerCtx)) {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
const args = callNode.getArguments();
|
|
284
|
+
const operation = argumentText(args[spec.operationArg], resolve);
|
|
285
|
+
if (operation === null) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
const kind = spec.operations[operation];
|
|
289
|
+
if (kind === void 0) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
const input = objectArgument(args[spec.requestArg], resolve);
|
|
293
|
+
if (input === null) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
return requestEffects({
|
|
297
|
+
input,
|
|
298
|
+
kind,
|
|
299
|
+
operation,
|
|
300
|
+
callee: callee.getText(),
|
|
301
|
+
resolve
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
function calledName(callee) {
|
|
306
|
+
if (N.isPropertyAccessExpression(callee)) {
|
|
307
|
+
return callee.getName();
|
|
308
|
+
}
|
|
309
|
+
return N.isIdentifier(callee) ? callee.getText() : null;
|
|
310
|
+
}
|
|
311
|
+
function declaredIn(callee, module, ctx) {
|
|
312
|
+
const target = N.isPropertyAccessExpression(callee) ? rootIdentifier(callee) : callee;
|
|
313
|
+
return target !== null && ctx.isImportedFrom(target, module);
|
|
314
|
+
}
|
|
315
|
+
function argumentText(arg, resolve) {
|
|
316
|
+
if (arg === void 0) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
const direct = literalText(arg);
|
|
320
|
+
if (direct !== null) {
|
|
321
|
+
return direct;
|
|
322
|
+
}
|
|
323
|
+
const written = resolve(arg);
|
|
324
|
+
return written === null ? null : literalText(written);
|
|
325
|
+
}
|
|
326
|
+
function objectArgument(arg, resolve) {
|
|
327
|
+
if (arg === void 0) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
if (N.isObjectLiteralExpression(arg)) {
|
|
331
|
+
return arg;
|
|
332
|
+
}
|
|
333
|
+
const written = resolve(arg);
|
|
334
|
+
return written !== null && N.isObjectLiteralExpression(written) ? written : null;
|
|
335
|
+
}
|
|
336
|
+
var isArgumentPosition = (index) => Number.isInteger(index) && index >= 0;
|
|
337
|
+
function checkRequestFunction(spec, at) {
|
|
338
|
+
const complain = (problem) => {
|
|
339
|
+
throw new Error(`requestFunctions[${at}] ${problem}`);
|
|
340
|
+
};
|
|
341
|
+
if (typeof spec.name !== "string" || spec.name === "") {
|
|
342
|
+
complain("needs the name of a function to read.");
|
|
343
|
+
}
|
|
344
|
+
if (!isArgumentPosition(spec.operationArg)) {
|
|
345
|
+
complain("needs operationArg: which argument says the operation, from 0.");
|
|
346
|
+
}
|
|
347
|
+
if (!isArgumentPosition(spec.requestArg)) {
|
|
348
|
+
complain("needs requestArg: which argument is the request, from 0.");
|
|
349
|
+
}
|
|
350
|
+
const operations = Object.entries(spec.operations ?? {});
|
|
351
|
+
if (operations.length === 0) {
|
|
352
|
+
complain("needs operations, saying what each one does to the table.");
|
|
353
|
+
}
|
|
354
|
+
for (const [operation, kind] of operations) {
|
|
355
|
+
if (kind !== "read" && kind !== "write") {
|
|
356
|
+
complain(`gives ${operation} as ${String(kind)}, not read or write.`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function dynamoFramework(options = {}) {
|
|
361
|
+
const requestFunctions = options.requestFunctions ?? [];
|
|
362
|
+
requestFunctions.forEach(checkRequestFunction);
|
|
363
|
+
return {
|
|
364
|
+
name: "aws-dynamodb",
|
|
365
|
+
protocol: "dynamodb",
|
|
366
|
+
languages: ["typescript", "javascript"],
|
|
367
|
+
discovery: [],
|
|
368
|
+
terminals: [],
|
|
369
|
+
inputMapping: { type: "positionalParams", params: [] },
|
|
370
|
+
requiresImport: [
|
|
371
|
+
.../* @__PURE__ */ new Set([
|
|
372
|
+
...COMMAND_MODULES,
|
|
373
|
+
...options.requiresImport ?? [],
|
|
374
|
+
...requestFunctions.map((spec) => spec.module).filter((module) => module !== void 0)
|
|
375
|
+
])
|
|
376
|
+
],
|
|
377
|
+
invocationRecognizers: [
|
|
378
|
+
dynamoRecognizer,
|
|
379
|
+
...requestFunctions.map(requestFunctionRecognizer)
|
|
380
|
+
]
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
var index_default = dynamoFramework;
|
|
384
|
+
export {
|
|
385
|
+
index_default as default
|
|
386
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-aws-eventbridge';
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
// ../framework/aws-eventbridge/dist/index.js
|
|
2
|
+
import {
|
|
3
|
+
Node as N
|
|
4
|
+
} from "ts-morph";
|
|
5
|
+
import { readConfiguredCall, rootIdentifier } from "@suss/adapter-typescript";
|
|
6
|
+
import { formatChannel, messageBusBinding } from "@suss/behavioral-ir";
|
|
7
|
+
import { unwrapJsonStringify } from "@suss/extractor";
|
|
8
|
+
var SEND_COMMANDS = {
|
|
9
|
+
PutEventsCommand: "putEvents"
|
|
10
|
+
};
|
|
11
|
+
function eventBridgeRecognizer(call, ctx) {
|
|
12
|
+
const callNode = call;
|
|
13
|
+
const recognizerCtx = ctx;
|
|
14
|
+
const resolveValue = recognizerCtx.resolveWrittenValue ?? (() => null);
|
|
15
|
+
const calleeExpr = callNode.getExpression();
|
|
16
|
+
if (!N.isPropertyAccessExpression(calleeExpr)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
if (calleeExpr.getName() !== "send") {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const args = callNode.getArguments();
|
|
23
|
+
if (args.length === 0) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const firstArg = args[0];
|
|
27
|
+
if (!N.isNewExpression(firstArg)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const ctorExpr = firstArg.getExpression();
|
|
31
|
+
const ctorLeafName = N.isPropertyAccessExpression(ctorExpr) ? ctorExpr.getName() : ctorExpr.getText();
|
|
32
|
+
if (SEND_COMMANDS[ctorLeafName] === void 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const importCheckTarget = N.isPropertyAccessExpression(ctorExpr) ? rootIdentifier(ctorExpr) : ctorExpr;
|
|
36
|
+
if (importCheckTarget === null || !recognizerCtx.isImportedFrom(
|
|
37
|
+
importCheckTarget,
|
|
38
|
+
"@aws-sdk/client-eventbridge"
|
|
39
|
+
)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const callArgs = recognizerCtx.extractArgs();
|
|
43
|
+
const entries = readEntries(callArgs);
|
|
44
|
+
if (entries === null) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const callee = callNode.getExpression().getText();
|
|
48
|
+
const astEntries = readAstEntries(firstArg);
|
|
49
|
+
const effects = [];
|
|
50
|
+
for (const [index, entry] of entries.entries()) {
|
|
51
|
+
const effect = buildEntryEffect(
|
|
52
|
+
entry,
|
|
53
|
+
callee,
|
|
54
|
+
astEntries?.[index],
|
|
55
|
+
resolveValue
|
|
56
|
+
);
|
|
57
|
+
if (effect !== null) {
|
|
58
|
+
effects.push(effect);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return effects.length > 0 ? effects : null;
|
|
62
|
+
}
|
|
63
|
+
function readAstEntries(command) {
|
|
64
|
+
if (!N.isNewExpression(command)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const input = command.getArguments()[0];
|
|
68
|
+
if (input === void 0 || !N.isObjectLiteralExpression(input)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
for (const prop of input.getProperties()) {
|
|
72
|
+
if (!N.isPropertyAssignment(prop) || prop.getName() !== "Entries") {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const init = prop.getInitializer();
|
|
76
|
+
if (init === void 0 || !N.isArrayLiteralExpression(init)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return init.getElements();
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function astField(entry, name) {
|
|
84
|
+
if (entry === void 0 || !N.isObjectLiteralExpression(entry)) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
for (const prop of entry.getProperties()) {
|
|
88
|
+
if (N.isPropertyAssignment(prop) && prop.getName() === name) {
|
|
89
|
+
return prop.getInitializer() ?? null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
function busTokenOf(expr) {
|
|
95
|
+
if (N.isStringLiteral(expr)) {
|
|
96
|
+
const value = expr.getLiteralValue();
|
|
97
|
+
return value === "" ? null : value;
|
|
98
|
+
}
|
|
99
|
+
const match = expr.getText().match(/^process\.env\.(\w+)$/);
|
|
100
|
+
return match === null ? null : match[1] ?? null;
|
|
101
|
+
}
|
|
102
|
+
function detailTypeOf(expr) {
|
|
103
|
+
if (!N.isStringLiteral(expr)) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const value = expr.getLiteralValue();
|
|
107
|
+
return value === "" ? null : value;
|
|
108
|
+
}
|
|
109
|
+
function resolvedHalf(entry, name, readToken, resolve) {
|
|
110
|
+
const expr = astField(entry, name);
|
|
111
|
+
if (expr === null) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const direct = readToken(expr);
|
|
115
|
+
if (direct !== null) {
|
|
116
|
+
return direct;
|
|
117
|
+
}
|
|
118
|
+
const resolved = resolve(expr);
|
|
119
|
+
return resolved === null ? null : readToken(resolved);
|
|
120
|
+
}
|
|
121
|
+
function readEntries(callArgs) {
|
|
122
|
+
const commandArg = callArgs[0];
|
|
123
|
+
if (!isEffectArgOfKind(commandArg, "call")) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const ctorArgs = commandArg.args ?? [];
|
|
127
|
+
const inputArg = ctorArgs[0];
|
|
128
|
+
if (!isEffectArgOfKind(inputArg, "object")) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const fields = inputArg.fields;
|
|
132
|
+
const entriesArg = fields?.Entries;
|
|
133
|
+
if (!isEffectArgOfKind(entriesArg, "array")) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return entriesArg.items ?? [];
|
|
137
|
+
}
|
|
138
|
+
function buildEntryEffect(entry, callee, astEntry, resolve) {
|
|
139
|
+
if (!isEffectArgOfKind(entry, "object")) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const fields = entry.fields;
|
|
143
|
+
const bus = fields.EventBusName === void 0 ? readBusToken(void 0) : resolvedHalf(astEntry, "EventBusName", busTokenOf, resolve) ?? readBusToken(fields.EventBusName);
|
|
144
|
+
const detailType = resolvedHalf(astEntry, "DetailType", detailTypeOf, resolve) ?? readLiteralString(fields.DetailType);
|
|
145
|
+
const channel = bus === null || detailType === null ? null : formatChannel(bus, detailType);
|
|
146
|
+
const body = unwrapJsonStringify(fields.Detail ?? null);
|
|
147
|
+
const source = readLiteralString(fields.Source);
|
|
148
|
+
return {
|
|
149
|
+
type: "interaction",
|
|
150
|
+
binding: messageBusBinding({
|
|
151
|
+
recognition: "@suss/framework-aws-eventbridge",
|
|
152
|
+
messageBus: "eventbridge",
|
|
153
|
+
channel
|
|
154
|
+
}),
|
|
155
|
+
callee,
|
|
156
|
+
interaction: {
|
|
157
|
+
class: "message-send",
|
|
158
|
+
...body !== null ? { body } : {},
|
|
159
|
+
...source !== null ? { routingKey: source } : {}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function readBusToken(arg) {
|
|
164
|
+
if (arg === void 0) {
|
|
165
|
+
return "default";
|
|
166
|
+
}
|
|
167
|
+
if (isEffectArgOfKind(arg, "string")) {
|
|
168
|
+
const value = arg.value;
|
|
169
|
+
return value === "" ? null : value;
|
|
170
|
+
}
|
|
171
|
+
if (isEffectArgOfKind(arg, "identifier")) {
|
|
172
|
+
const name = arg.name;
|
|
173
|
+
const match = name.match(/^process\.env\.(\w+)$/);
|
|
174
|
+
return match !== null ? match[1] : null;
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
function readLiteralString(arg) {
|
|
179
|
+
if (isEffectArgOfKind(arg, "string")) {
|
|
180
|
+
const value = arg.value;
|
|
181
|
+
return value === "" ? null : value;
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
function isEffectArgOfKind(arg, kind) {
|
|
186
|
+
return arg !== null && arg !== void 0 && typeof arg === "object" && arg.kind === kind;
|
|
187
|
+
}
|
|
188
|
+
function configuredProducerRecognizer(spec) {
|
|
189
|
+
return ((call, ctx) => {
|
|
190
|
+
const read = readConfiguredCall(
|
|
191
|
+
call,
|
|
192
|
+
ctx,
|
|
193
|
+
spec
|
|
194
|
+
);
|
|
195
|
+
if (read === null) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
return [
|
|
199
|
+
{
|
|
200
|
+
type: "interaction",
|
|
201
|
+
binding: messageBusBinding({
|
|
202
|
+
recognition: "@suss/framework-aws-eventbridge",
|
|
203
|
+
messageBus: "eventbridge",
|
|
204
|
+
channel: read.subject
|
|
205
|
+
}),
|
|
206
|
+
callee: read.callee,
|
|
207
|
+
interaction: {
|
|
208
|
+
class: "message-send",
|
|
209
|
+
...read.body !== null ? { body: read.body } : {}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function eventBridgeFramework(options = {}) {
|
|
216
|
+
const producers = options.producers ?? [];
|
|
217
|
+
return {
|
|
218
|
+
name: "eventbridge",
|
|
219
|
+
protocol: "eventbridge",
|
|
220
|
+
languages: ["typescript", "javascript"],
|
|
221
|
+
discovery: [],
|
|
222
|
+
terminals: [],
|
|
223
|
+
inputMapping: { type: "positionalParams", params: [] },
|
|
224
|
+
// Skip files that don't import `@aws-sdk/client-eventbridge`.
|
|
225
|
+
requiresImport: [
|
|
226
|
+
.../* @__PURE__ */ new Set([
|
|
227
|
+
"@aws-sdk/client-eventbridge",
|
|
228
|
+
...producers.map((p) => p.module)
|
|
229
|
+
])
|
|
230
|
+
],
|
|
231
|
+
invocationRecognizers: [
|
|
232
|
+
eventBridgeRecognizer,
|
|
233
|
+
...producers.map(configuredProducerRecognizer)
|
|
234
|
+
]
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
var index_default = eventBridgeFramework;
|
|
238
|
+
export {
|
|
239
|
+
index_default as default
|
|
240
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@suss/framework-aws-lambda';
|