Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge queue: embarking main (5296f94) and #4194 together #4223

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions docs/docs/04-standard-library/01-cloud/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ let ApiCorsOptions = cloud.ApiCorsOptions{ ... };
| <code><a href="#@winglang/sdk.cloud.ApiCorsOptions.property.allowMethods">allowMethods</a></code> | <code>MutArray&lt;<a href="#@winglang/sdk.cloud.HttpMethod">HttpMethod</a>&gt;</code> | The list of allowed methods. |
| <code><a href="#@winglang/sdk.cloud.ApiCorsOptions.property.allowOrigin">allowOrigin</a></code> | <code>MutArray&lt;str&gt;</code> | The list of allowed allowOrigin. |
| <code><a href="#@winglang/sdk.cloud.ApiCorsOptions.property.exposeHeaders">exposeHeaders</a></code> | <code>MutArray&lt;str&gt;</code> | The list of exposed headers. |
| <code><a href="#@winglang/sdk.cloud.ApiCorsOptions.property.maxAge">maxAge</a></code> | <code><a href="#@winglang/sdk.std.Duration">duration</a></code> | How long the browser should cache preflight request results. |

---

Expand Down Expand Up @@ -584,6 +585,19 @@ The list of exposed headers.
```


##### `maxAge`<sup>Optional</sup> <a name="maxAge" id="@winglang/sdk.cloud.ApiCorsOptions.property.maxAge"></a>

```wing
maxAge: duration;
```

- *Type:* <a href="#@winglang/sdk.std.Duration">duration</a>
- *Default:* 300 seconds

How long the browser should cache preflight request results.

---

### ApiDeleteProps <a name="ApiDeleteProps" id="@winglang/sdk.cloud.ApiDeleteProps"></a>

Options for Api put endpoint.
Expand Down
3 changes: 2 additions & 1 deletion examples/tests/valid/website_with_api.main.w
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ let api = new cloud.Api(
allowMethods: [cloud.HttpMethod.GET, cloud.HttpMethod.POST, cloud.HttpMethod.OPTIONS],
allowHeaders: ["Content-Type"],
allowCredentials: false,
exposeHeaders: ["Content-Type"]
exposeHeaders: ["Content-Type"],
maxAge: 600s
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ApiCorsOptions\n```\n---\nCors Options for `Api`.\n### Fields\n- `allowCredentials?` — Whether to allow credentials.\n- `allowHeaders?` — The list of allowed headers.\n- `allowMethods?` — The list of allowed methods.\n- `allowOrigin?` — The list of allowed allowOrigin.\n- `exposeHeaders?` — The list of exposed headers."
value: "```wing\nstruct ApiCorsOptions\n```\n---\nCors Options for `Api`.\n### Fields\n- `allowCredentials?` — Whether to allow credentials.\n- `allowHeaders?` — The list of allowed headers.\n- `allowMethods?` — The list of allowed methods.\n- `allowOrigin?` — The list of allowed allowOrigin.\n- `exposeHeaders?` — The list of exposed headers.\n- `maxAge?` — How long the browser should cache preflight request results."
sortText: hh|ApiCorsOptions
- label: ApiDeleteProps
kind: 22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ApiCorsOptions\n```\n---\nCors Options for `Api`.\n### Fields\n- `allowCredentials?` — Whether to allow credentials.\n- `allowHeaders?` — The list of allowed headers.\n- `allowMethods?` — The list of allowed methods.\n- `allowOrigin?` — The list of allowed allowOrigin.\n- `exposeHeaders?` — The list of exposed headers."
value: "```wing\nstruct ApiCorsOptions\n```\n---\nCors Options for `Api`.\n### Fields\n- `allowCredentials?` — Whether to allow credentials.\n- `allowHeaders?` — The list of allowed headers.\n- `allowMethods?` — The list of allowed methods.\n- `allowOrigin?` — The list of allowed allowOrigin.\n- `exposeHeaders?` — The list of exposed headers.\n- `maxAge?` — How long the browser should cache preflight request results."
sortText: hh|ApiCorsOptions
- label: ApiDeleteProps
kind: 22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ source: libs/wingc/src/lsp/completions.rs
kind: 22
documentation:
kind: markdown
value: "```wing\nstruct ApiCorsOptions\n```\n---\nCors Options for `Api`.\n### Fields\n- `allowCredentials?` — Whether to allow credentials.\n- `allowHeaders?` — The list of allowed headers.\n- `allowMethods?` — The list of allowed methods.\n- `allowOrigin?` — The list of allowed allowOrigin.\n- `exposeHeaders?` — The list of exposed headers."
value: "```wing\nstruct ApiCorsOptions\n```\n---\nCors Options for `Api`.\n### Fields\n- `allowCredentials?` — Whether to allow credentials.\n- `allowHeaders?` — The list of allowed headers.\n- `allowMethods?` — The list of allowed methods.\n- `allowOrigin?` — The list of allowed allowOrigin.\n- `exposeHeaders?` — The list of exposed headers.\n- `maxAge?` — How long the browser should cache preflight request results."
sortText: hh|ApiCorsOptions
- label: ApiDeleteProps
kind: 22
Expand Down
32 changes: 24 additions & 8 deletions libs/wingsdk/src/cloud/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Construct } from "constructs";
import { fqnForType } from "../constants";
import { App } from "../core";
import { IResource, Node, Resource } from "../std";
import { IResource, Node, Resource, Duration } from "../std";

/**
* Global identifier for `Api`.
Expand Down Expand Up @@ -46,6 +46,12 @@ export interface ApiCorsOptions {
* @default - false
*/
readonly allowCredentials?: boolean;

/**
* How long the browser should cache preflight request results.
* @default - 300 seconds
*/
readonly maxAge?: Duration;
}

/**
Expand Down Expand Up @@ -93,7 +99,7 @@ export type OpenApiSpec = any;

/**
* The OpenAPI spec extension for a route.
* see https://spec.openapis.org/oas/v3.0.3
* @see https://spec.openapis.org/oas/v3.0.3
* */
export type OpenApiSpecExtension = any;

Expand All @@ -108,20 +114,20 @@ export type OpenApiCorsHeaders = Record<string, { schema: { type: string } }>;
type CorsDefaultResponseHeaders = {
/**
* Specifies the origin that is allowed to access the resource.
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*/
"Access-Control-Allow-Origin": string;

/**
* Lists the headers that the client can access.
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
*/
"Access-Control-Expose-Headers": string;

/**
* Indicates whether the response to the request can
* be exposed when the credentials flag is true.
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
*/
"Access-Control-Allow-Credentials": string;
};
Expand All @@ -132,21 +138,27 @@ type CorsDefaultResponseHeaders = {
type CorsOptionsResponseHeaders = {
/**
* Specifies the origin that is allowed to access the resource.
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*/
"Access-Control-Allow-Origin": string;

/**
* Specifies the headers that are allowed in a request.
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
*/
"Access-Control-Allow-Headers": string;

/**
* Specifies the methods that are allowed in a request.
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
*/
"Access-Control-Allow-Methods": string;

/**
* Indicates how long the results of a preflight request can be cached.
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
*/
"Access-Control-Max-Age": string;
};

/**
Expand Down Expand Up @@ -198,6 +210,7 @@ export abstract class Api extends Resource {
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
exposeHeaders: [],
allowCredentials: false,
maxAge: Duration.fromMinutes(5),
};

/**
Expand Down Expand Up @@ -363,6 +376,7 @@ export abstract class Api extends Resource {
corsHeaders["Access-Control-Allow-Origin"] = corsHeaderSchema;
corsHeaders["Access-Control-Allow-Methods"] = corsHeaderSchema;
corsHeaders["Access-Control-Allow-Headers"] = corsHeaderSchema;
corsHeaders["Access-Control-Max-Age"] = corsHeaderSchema;
}
return corsHeaders;
}
Expand All @@ -386,6 +400,7 @@ export abstract class Api extends Resource {
allowMethods = [],
exposeHeaders = [],
allowCredentials = false,
maxAge = Duration.fromMinutes(5),
} = corsOptions;

const defaultHeaders: CorsDefaultResponseHeaders = {
Expand All @@ -398,6 +413,7 @@ export abstract class Api extends Resource {
"Access-Control-Allow-Origin": allowOrigin.join(",") || "",
"Access-Control-Allow-Headers": allowHeaders.join(",") || "",
"Access-Control-Allow-Methods": allowMethods.join(",") || "",
"Access-Control-Max-Age": maxAge.seconds.toString(),
};

return {
Expand Down
1 change: 1 addition & 0 deletions libs/wingsdk/test/target-sim/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -686,4 +686,5 @@ test("api with CORS settings responds to OPTIONS request", async () => {
expect(response.headers.get("access-control-allow-methods")).toEqual(
"GET,POST,PUT,DELETE,HEAD,OPTIONS"
);
expect(response.headers.get("access-control-max-age")).toEqual("300");
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ exports[`api configured for cors 1`] = `
"type": "string",
},
},
"Access-Control-Max-Age": {
"schema": {
"type": "string",
},
},
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ module.exports = function({ $api_url, $http_Util }) {
"uniqueId": "cloudApi_api_2B334D75"
}
},
"body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path\":{\"get\":{\"operationId\":\"get-path\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{},\"headers\":{\"Access-Control-Allow-Origin\":{\"schema\":{\"type\":\"string\"}},\"Access-Control-Allow-Methods\":{\"schema\":{\"type\":\"string\"}},\"Access-Control-Allow-Headers\":{\"schema\":{\"type\":\"string\"}}}}},\"parameters\":[],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.Region.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.cloudApi_cloudApi-OnRequest-cdafee6e_A6C8366F.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}},\"/{proxy+}\":{\"x-amazon-apigateway-any-method\":{\"produces\":[\"application/json\"],\"x-amazon-apigateway-integration\":{\"type\":\"mock\",\"requestTemplates\":{\"application/json\":\"\\n #if ($context.httpMethod == \\\"OPTIONS\\\")\\n {\\\"statusCode\\\": 204}\\n #else\\n {\\\"statusCode\\\": 404}\\n #end\\n \"},\"passthroughBehavior\":\"never\",\"responses\":{\"204\":{\"statusCode\":\"204\",\"responseParameters\":{\"method.response.header.Content-Type\":\"'application/json'\",\"method.response.header.Access-Control-Allow-Origin\":\"'*'\",\"method.response.header.Access-Control-Allow-Methods\":\"'GET,POST,PUT,DELETE,HEAD,OPTIONS'\",\"method.response.header.Access-Control-Allow-Headers\":\"'Content-Type,Authorization,X-Requested-With'\"},\"responseTemplates\":{\"application/json\":\"{}\"}},\"404\":{\"statusCode\":\"404\",\"responseParameters\":{\"method.response.header.Content-Type\":\"'application/json'\"},\"responseTemplates\":{\"application/json\":\"{\\\"statusCode\\\": 404, \\\"message\\\": \\\"Error: Resource not found\\\"}\"}},\"default\":{\"statusCode\":\"404\",\"responseParameters\":{\"method.response.header.Content-Type\":\"'application/json'\"},\"responseTemplates\":{\"application/json\":\"{\\\"statusCode\\\": 404, \\\"message\\\": \\\"Error: Resource not found\\\"}\"}}}},\"responses\":{\"204\":{\"description\":\"204 response\",\"headers\":{\"Content-Type\":{\"type\":\"string\"},\"Access-Control-Allow-Origin\":{\"type\":\"string\"},\"Access-Control-Allow-Methods\":{\"type\":\"string\"},\"Access-Control-Allow-Headers\":{\"type\":\"string\"}}},\"404\":{\"description\":\"404 response\",\"headers\":{\"Content-Type\":{\"type\":\"string\"}}}}}}}}",
"body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path\":{\"get\":{\"operationId\":\"get-path\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{},\"headers\":{\"Access-Control-Allow-Origin\":{\"schema\":{\"type\":\"string\"}},\"Access-Control-Allow-Methods\":{\"schema\":{\"type\":\"string\"}},\"Access-Control-Allow-Headers\":{\"schema\":{\"type\":\"string\"}},\"Access-Control-Max-Age\":{\"schema\":{\"type\":\"string\"}}}}},\"parameters\":[],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.Region.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.cloudApi_cloudApi-OnRequest-cdafee6e_A6C8366F.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}},\"/{proxy+}\":{\"x-amazon-apigateway-any-method\":{\"produces\":[\"application/json\"],\"x-amazon-apigateway-integration\":{\"type\":\"mock\",\"requestTemplates\":{\"application/json\":\"\\n #if ($context.httpMethod == \\\"OPTIONS\\\")\\n {\\\"statusCode\\\": 204}\\n #else\\n {\\\"statusCode\\\": 404}\\n #end\\n \"},\"passthroughBehavior\":\"never\",\"responses\":{\"204\":{\"statusCode\":\"204\",\"responseParameters\":{\"method.response.header.Content-Type\":\"'application/json'\",\"method.response.header.Access-Control-Allow-Origin\":\"'*'\",\"method.response.header.Access-Control-Allow-Methods\":\"'GET,POST,PUT,DELETE,HEAD,OPTIONS'\",\"method.response.header.Access-Control-Allow-Headers\":\"'Content-Type,Authorization,X-Requested-With'\"},\"responseTemplates\":{\"application/json\":\"{}\"}},\"404\":{\"statusCode\":\"404\",\"responseParameters\":{\"method.response.header.Content-Type\":\"'application/json'\"},\"responseTemplates\":{\"application/json\":\"{\\\"statusCode\\\": 404, \\\"message\\\": \\\"Error: Resource not found\\\"}\"}},\"default\":{\"statusCode\":\"404\",\"responseParameters\":{\"method.response.header.Content-Type\":\"'application/json'\"},\"responseTemplates\":{\"application/json\":\"{\\\"statusCode\\\": 404, \\\"message\\\": \\\"Error: Resource not found\\\"}\"}}}},\"responses\":{\"204\":{\"description\":\"204 response\",\"headers\":{\"Content-Type\":{\"type\":\"string\"},\"Access-Control-Allow-Origin\":{\"type\":\"string\"},\"Access-Control-Allow-Methods\":{\"type\":\"string\"},\"Access-Control-Allow-Headers\":{\"type\":\"string\"}}},\"404\":{\"description\":\"404 response\",\"headers\":{\"Content-Type\":{\"type\":\"string\"}}}}}}}}",
"name": "api-c895068c"
}
},
Expand Down
Loading
Loading