Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4387809
feat: add missing AST nodes to FunctionlessAST for 1:1 parity with TS
Jul 22, 2022
5d925cd
feat: add SuperExpr
Jul 22, 2022
9be9ca2
feat: update visitor logic and interpreters for new node types
Jul 22, 2022
bc5f7da
feat: add EmptyStmt and WithStmt
Jul 22, 2022
96d0624
Merge branch 'main' into samg-one-to-one-ast
Jul 22, 2022
767135b
feat: add PrivateIdentifier
Jul 22, 2022
d52d79c
chore: refactor common pattern of flattening array of returned nodes …
Jul 22, 2022
276ed52
feat: add YieldExpr
Jul 22, 2022
e1e3474
feat: add BigIntExpr and RegexExpr
Jul 22, 2022
d332831
chore: feedback
Jul 22, 2022
595b5f2
feat: VoidExpr and DeleteExpr
Jul 22, 2022
182047e
feat: add VoidExpr and DeleteExpr
Jul 22, 2022
1dd27f3
feat: add ParenthesizedExpr
Jul 23, 2022
25e0159
feat: remove name from Argument and no more var-args
Jul 25, 2022
c15bd0b
fix: tests
Jul 25, 2022
24a8ceb
Merge branch 'main' into samg-one-to-one-ast
Jul 25, 2022
05bac62
chore: self mutation
invalid-email-address Jul 26, 2022
45a5725
chore: add docs for throwing error in step function
Jul 26, 2022
f7911df
feat: add Identifier and PrivateIdentifier to PropAccessExpr
Jul 26, 2022
e3fd163
feat: add PrivateIdentifier to PropName and generalize setParent
Jul 26, 2022
9df92f3
Merge branch 'main' into samg-one-to-one-ast
Jul 26, 2022
2d8ddb0
chore: feedback on mutability
Jul 26, 2022
d732e43
fix: MethodDeclaration parsing
Jul 26, 2022
1a059ca
feat: make name in VariableDecl a BindingName
Jul 27, 2022
d25baec
feat: add initializer to ParameterDecl
Jul 27, 2022
2ffb226
feat: rename variableDecl in for-loops to initializer. Simplify ASL c…
Jul 27, 2022
0e52b1e
fix: don't parse Identifier in VariableDecl
Jul 27, 2022
bcf5429
fix: remove getName() and update PropName to include NumberLiteralExpr
Jul 27, 2022
3c758a6
chore: feedback
Jul 27, 2022
360586f
chore: feedback
Jul 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 33 additions & 10 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import {
} from "aws-lambda";
import { FunctionDecl, validateFunctionDecl } from "./declaration";
import { ErrorCodes, SynthError } from "./error-code";
import { CallExpr, Expr, Identifier, ReferenceExpr } from "./expression";
import {
CallExpr,
Expr,
Identifier,
ReferenceExpr,
ThisExpr,
} from "./expression";
import { Function } from "./function";
import {
isReturnStmt,
Expand All @@ -28,7 +34,9 @@ import {
isReferenceExpr,
isAwaitExpr,
isPromiseExpr,
isThisExpr,
isVariableDecl,
isParenthesizedExpr,
} from "./guards";
import { Integration, IntegrationImpl, isIntegration } from "./integration";
import { Stmt } from "./statement";
Expand Down Expand Up @@ -643,8 +651,9 @@ export class APIGatewayVTL extends VTL {
return this.add(this.exprToJson(node.expr));
} else if (
isPropAccessExpr(node) &&
isIdentifier(node.name) &&
isInputBody(node.expr) &&
node.name === "data"
node.name.name === "data"
) {
// $input.data maps to `$input.path('$')`
// this returns a VTL object representing the root payload data
Expand Down Expand Up @@ -695,6 +704,8 @@ export class APIGatewayVTL extends VTL {
const jsonPath = toJsonPath(expr);
if (jsonPath) {
return `$input.json('${jsonPath}')`;
} else if (isParenthesizedExpr(expr)) {
return this.exprToJson(expr.expr);
} else if (isNullLiteralExpr(expr) || isUndefinedLiteralExpr(expr)) {
// Undefined is not the same as null. In JSON terms, `undefined` is the absence of a value where-as `null` is a present null value.
return "null";
Expand All @@ -715,7 +726,7 @@ export class APIGatewayVTL extends VTL {
return this.exprToJson(expr.expr);
}
} else if (isCallExpr(expr)) {
if (isReferenceExpr(expr.expr)) {
if (isReferenceExpr(expr.expr) || isThisExpr(expr.expr)) {
const ref = expr.expr.ref();
if (isIntegration<Integration>(ref)) {
const serviceCall = new IntegrationImpl(ref);
Expand All @@ -730,7 +741,11 @@ export class APIGatewayVTL extends VTL {
}
} else if (isIdentifier(expr.expr) && expr.expr.name === "Number") {
return this.exprToJson(expr.args[0]);
} else if (isPropAccessExpr(expr.expr) && expr.expr.name === "params") {
} else if (
isPropAccessExpr(expr.expr) &&
isIdentifier(expr.expr.name) &&
expr.expr.name.name === "params"
) {
if (isIdentifier(expr.expr.expr)) {
const ref = expr.expr.expr.lookup();
if (
Expand All @@ -740,7 +755,7 @@ export class APIGatewayVTL extends VTL {
ref.parent.parameters.findIndex((param) => param === ref) === 0
) {
// the first argument of the FunctionDecl is the `$input`, regardless of what it is named
if (expr.args.length === 0 || expr.args[0]?.expr === undefined) {
if (expr.args.length === 0 || expr.args[0].expr === undefined) {
const key = this.newLocalVarName();
return `{#foreach(${key} in $input.params().keySet())"${key}": "$input.params("${key}")"#if($foreach.hasNext),#end#end}`;
} else if (expr.args.length === 1) {
Expand Down Expand Up @@ -819,18 +834,24 @@ export class APIGatewayVTL extends VTL {
* @returns a JSON Path `string` if this {@link Expr} can be evaluated as a JSON Path from the `$input`, otherwise `undefined`.
*/
function toJsonPath(expr: Expr): string | undefined {
if (isInputBody(expr)) {
if (isParenthesizedExpr(expr)) {
return toJsonPath(expr.expr);
} else if (isInputBody(expr)) {
return "$";
} else if (isIdentifier(expr)) {
// this is a reference to an intermediate value, cannot be expressed as JSON Path
return undefined;
} else if (isPropAccessExpr(expr)) {
if (expr.name === "data" && isInputBody(expr.expr)) {
if (
isIdentifier(expr.name) &&
expr.name.name === "data" &&
isInputBody(expr.expr)
) {
return "$";
}
const exprJsonPath = toJsonPath(expr.expr);
if (exprJsonPath !== undefined) {
return `${exprJsonPath}.${expr.name}`;
return `${exprJsonPath}.${expr.name.name}`;
}
} else if (
isElementAccessExpr(expr) &&
Expand Down Expand Up @@ -883,8 +904,10 @@ ${reference}
* @param id the {@link Identifier} expression.
* @returns a VTL string that points to the value at runtime.
*/
public override dereference(id: Identifier | ReferenceExpr): string {
if (isReferenceExpr(id)) {
public override dereference(
id: Identifier | ReferenceExpr | ThisExpr
): string {
if (isReferenceExpr(id) || isThisExpr(id)) {
throw new SynthError(ErrorCodes.ApiGateway_Unsupported_Reference);
} else {
const ref = id.lookup();
Expand Down
28 changes: 20 additions & 8 deletions src/appsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import {
FunctionDecl,
validateFunctionDecl,
VariableDecl,
VariableDeclList,
} from "./declaration";
import { ErrorCodes, SynthError } from "./error-code";
Expand All @@ -22,6 +23,7 @@ import {
PropAccessExpr,
ReferenceExpr,
StringLiteralExpr,
ThisExpr,
} from "./expression";
import {
isVariableStmt,
Expand All @@ -43,7 +45,9 @@ import {
isBindingElem,
isBindingPattern,
isReferenceExpr,
isThisExpr,
isVariableDecl,
isIdentifier,
} from "./guards";
import {
findDeepIntegrations,
Expand Down Expand Up @@ -146,8 +150,8 @@ export class AppsyncVTL extends VTL {
}
}

protected dereference(id: Identifier | ReferenceExpr): string {
if (isReferenceExpr(id)) {
protected dereference(id: Identifier | ReferenceExpr | ThisExpr): string {
if (isReferenceExpr(id) || isThisExpr(id)) {
const ref = id.ref();
if (ref === $util) {
return "$util";
Expand Down Expand Up @@ -585,13 +589,21 @@ function synthesizeFunctions(api: appsync.GraphqlApi, decl: FunctionDecl) {
stmt.declList.decls[0].initializer &&
isIntegrationCallPattern(stmt.declList.decls[0].initializer)
) {
const decl = stmt.declList.decls[0];

const decl: VariableDecl | undefined = stmt.declList.decls[0];
const varName = isIdentifier(decl?.name) ? decl.name.name : undefined;
if (varName === undefined) {
throw new SynthError(
ErrorCodes.Unsupported_Feature,
"Destructured parameter declarations are not yet supported by Appsync. https://github.com/functionless/functionless/issues/364"
);
}
return createStage(
service,
`${pre ? `${pre}\n` : ""}#set( $context.stash.${
decl.name
} = ${getResult(<IntegrationCallPattern>decl.initializer)} )\n{}`
`${
pre ? `${pre}\n` : ""
}#set( $context.stash.${varName} = ${getResult(
<IntegrationCallPattern>decl.initializer
)} )\n{}`
);
} else {
throw new SynthError(
Expand Down Expand Up @@ -621,7 +633,7 @@ function synthesizeFunctions(api: appsync.GraphqlApi, decl: FunctionDecl) {
template.call(expr);
return returnValName;
} else if (isPropAccessExpr(expr)) {
return `${getResult(expr.expr)}.${expr.name}`;
return `${getResult(expr.expr)}.${expr.name.name}`;
} else if (isElementAccessExpr(expr)) {
return `${getResult(expr.expr)}[${getResult(expr.element)}]`;
} else if (isPromiseExpr(expr)) {
Expand Down
Loading