@webiny/pulumi-aws 5.30.0-beta.1 → 5.31.0-beta.1

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.
Files changed (56) hide show
  1. package/apps/admin/createAdminPulumiApp.d.ts +8 -6
  2. package/apps/admin/createAdminPulumiApp.js +4 -86
  3. package/apps/admin/createAdminPulumiApp.js.map +1 -1
  4. package/apps/api/ApiFileManager.js +7 -3
  5. package/apps/api/ApiFileManager.js.map +1 -1
  6. package/apps/api/ApiGraphql.d.ts +9 -0
  7. package/apps/api/ApiGraphql.js +24 -1
  8. package/apps/api/ApiGraphql.js.map +1 -1
  9. package/apps/api/ApiOutput.d.ts +15 -0
  10. package/apps/api/ApiOutput.js +43 -0
  11. package/apps/api/ApiOutput.js.map +1 -0
  12. package/apps/api/ApiPageBuilder.js +0 -1
  13. package/apps/api/ApiPageBuilder.js.map +1 -1
  14. package/apps/api/createApiPulumiApp.d.ts +1 -0
  15. package/apps/api/createApiPulumiApp.js +12 -2
  16. package/apps/api/createApiPulumiApp.js.map +1 -1
  17. package/apps/api/index.d.ts +1 -0
  18. package/apps/api/index.js +13 -0
  19. package/apps/api/index.js.map +1 -1
  20. package/apps/core/CoreFileManager.d.ts +4 -1
  21. package/apps/core/CoreFileManager.js +20 -3
  22. package/apps/core/CoreFileManager.js.map +1 -1
  23. package/apps/core/createCorePulumiApp.js +3 -1
  24. package/apps/core/createCorePulumiApp.js.map +1 -1
  25. package/apps/createAppBucket.js +4 -3
  26. package/apps/createAppBucket.js.map +1 -1
  27. package/apps/index.d.ts +1 -0
  28. package/apps/index.js +14 -0
  29. package/apps/index.js.map +1 -1
  30. package/apps/lambdaUtils.js +10 -11
  31. package/apps/lambdaUtils.js.map +1 -1
  32. package/apps/react/createReactPulumiApp.d.ts +29 -0
  33. package/apps/react/createReactPulumiApp.js +111 -0
  34. package/apps/react/createReactPulumiApp.js.map +1 -0
  35. package/apps/react/index.d.ts +1 -0
  36. package/apps/react/index.js +18 -0
  37. package/apps/react/index.js.map +1 -0
  38. package/apps/website/WebsitePrerendering.js +6 -14
  39. package/apps/website/WebsitePrerendering.js.map +1 -1
  40. package/apps/website/createWebsitePulumiApp.d.ts +6 -0
  41. package/apps/website/createWebsitePulumiApp.js +23 -3
  42. package/apps/website/createWebsitePulumiApp.js.map +1 -1
  43. package/apps/website/deliveryViewerRequest.d.ts +2 -0
  44. package/apps/website/deliveryViewerRequest.js +32 -0
  45. package/apps/website/deliveryViewerRequest.js.map +1 -0
  46. package/components/tenantRouter/functions/origin/request.js +3 -1
  47. package/components/tenantRouter/functions/origin/request.js.map +1 -1
  48. package/package.json +10 -8
  49. package/utils/getPresignedPost.d.ts +11 -0
  50. package/utils/getPresignedPost.js +46 -0
  51. package/utils/getPresignedPost.js.map +1 -0
  52. package/utils/lambdaEnvVariables.js +3 -1
  53. package/utils/lambdaEnvVariables.js.map +1 -1
  54. package/utils/uploadFolderToS3.d.ts +3 -4
  55. package/utils/uploadFolderToS3.js +51 -13
  56. package/utils/uploadFolderToS3.js.map +1 -1
@@ -41,7 +41,7 @@ function createPrerenderingService(app, params) {
41
41
  fifoQueue: true
42
42
  }
43
43
  });
44
- const policy = createLambdaPolicy(app, queue.output);
44
+ const policy = createLambdaPolicy(app, queue.output, params);
45
45
  const renderer = createRenderer(app, queue.output, policy.output, params);
46
46
  const subscriber = createRenderSubscriber(app, policy.output, params);
47
47
  const flush = createFlushService(app, policy.output, params);
@@ -91,8 +91,7 @@ function createRenderSubscriber(app, policy, params) {
91
91
  const core = app.getModule(_common.CoreOutput);
92
92
  const role = (0, _lambdaUtils.createLambdaRole)(app, {
93
93
  name: "ps-render-subscriber-role",
94
- policy: policy,
95
- executionRole: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole
94
+ policy: policy
96
95
  });
97
96
  const lambda = app.addResource(aws.lambda.Function, {
98
97
  name: "ps-render-subscriber-lambda",
@@ -203,8 +202,7 @@ function createFlushService(app, policy, params) {
203
202
  const core = app.getModule(_common.CoreOutput);
204
203
  const role = (0, _lambdaUtils.createLambdaRole)(app, {
205
204
  name: "ps-flush-lambda-role",
206
- policy: policy,
207
- executionRole: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole
205
+ policy: policy
208
206
  });
209
207
  const lambda = app.addResource(aws.lambda.Function, {
210
208
  name: "ps-flush-lambda",
@@ -262,7 +260,7 @@ function createFlushService(app, policy, params) {
262
260
  };
263
261
  }
264
262
 
265
- function createLambdaPolicy(app, queue) {
263
+ function createLambdaPolicy(app, queue, params) {
266
264
  const core = app.getModule(_common.CoreOutput);
267
265
  const awsAccountId = (0, _awsUtils.getAwsAccountId)(app);
268
266
  return app.addResource(aws.iam.Policy, {
@@ -288,14 +286,8 @@ function createLambdaPolicy(app, queue) {
288
286
  }, {
289
287
  Sid: "PermissionForS3",
290
288
  Effect: "Allow",
291
- Action: ["s3:DeleteObject", "s3:GetObject", "s3:GetObjectAcl", "s3:PutObject", "s3:PutObjectAcl"],
292
- Resource: [pulumi.interpolate`arn:aws:s3:::${core.fileManagerBucketId}/*`,
293
- /**
294
- * We're using the hard-coded value for "delivery" S3 bucket because;
295
- * It is created during deployment of the `apps/website` stack which is after the api stack,
296
- * so, we don't know its ARN.
297
- */
298
- "arn:aws:s3:::delivery-*/*"]
289
+ Action: ["s3:DeleteObject", "s3:GetObject", "s3:PutObject"],
290
+ Resource: [pulumi.interpolate`arn:aws:s3:::${params.bucket}/*`]
299
291
  }, {
300
292
  Sid: "PermissionForCloudfront",
301
293
  Effect: "Allow",
@@ -1 +1 @@
1
- {"version":3,"names":["createPrerenderingService","app","params","queue","addResource","aws","sqs","Queue","name","config","visibilityTimeoutSeconds","fifoQueue","policy","createLambdaPolicy","output","renderer","createRenderer","subscriber","createRenderSubscriber","flush","createFlushService","settings","createPrerenderingSettingsDbItem","tableItem","dynamodb","TableItem","tableName","dbTableName","hashKey","dbTableHashKey","rangeKey","dbTableRangeKey","item","pulumi","interpolate","run","variant","appUrl","deliveryUrl","bucket","cloudfrontId","url","apply","v","JSON","stringify","Converter","marshall","parse","core","getModule","CoreOutput","role","createLambdaRole","executionRole","iam","ManagedPolicy","AWSLambdaBasicExecutionRole","lambda","Function","arn","runtime","handler","timeout","memorySize","environment","variables","getCommonLambdaEnvVariables","value","DB_TABLE","description","code","asset","AssetArchive","FileArchive","path","join","paths","workspace","vpcConfig","VpcConfig","functionVpcConfig","eventRule","cloudwatch","EventRule","eventBusName","eventBusArn","eventPattern","eventPermission","Permission","action","function","principal","sourceArn","eventTarget","EventTarget","rule","AWSLambdaSQSQueueExecutionRole","layers","getLayerArn","eventSourceMapping","EventSourceMapping","functionName","eventSourceArn","batchSize","awsAccountId","getAwsAccountId","Policy","Version","Statement","Sid","Effect","Action","Resource","s","resources","primaryDynamodbTableArn","elasticsearchDynamodbTableArn","push","fileManagerBucketId"],"sources":["WebsitePrerendering.ts"],"sourcesContent":["import * as path from \"path\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { Converter } from \"aws-sdk/clients/dynamodb\";\n\nimport { PulumiApp } from \"@webiny/pulumi\";\n// @ts-ignore\nimport { getLayerArn } from \"@webiny/aws-layers\";\n\nimport { createLambdaRole, getCommonLambdaEnvVariables } from \"../lambdaUtils\";\nimport { CoreOutput, VpcConfig } from \"../common\";\nimport { getAwsAccountId } from \"../awsUtils\";\n\ninterface PreRenderingServiceParams {\n dbTableName: pulumi.Output<string>;\n dbTableHashKey: pulumi.Output<string>;\n dbTableRangeKey: pulumi.Output<string>;\n appUrl: pulumi.Output<string>;\n deliveryUrl: pulumi.Output<string>;\n bucket: pulumi.Output<string>;\n cloudfrontId: pulumi.Output<string>;\n}\n\nexport function createPrerenderingService(app: PulumiApp, params: PreRenderingServiceParams) {\n const queue = app.addResource(aws.sqs.Queue, {\n name: \"ps-render-queue\",\n config: {\n visibilityTimeoutSeconds: 300,\n fifoQueue: true\n }\n });\n\n const policy = createLambdaPolicy(app, queue.output);\n const renderer = createRenderer(app, queue.output, policy.output, params);\n const subscriber = createRenderSubscriber(app, policy.output, params);\n const flush = createFlushService(app, policy.output, params);\n const settings = createPrerenderingSettingsDbItem(app, queue.output, params);\n\n return {\n subscriber,\n renderer,\n flush,\n settings\n };\n}\n\nfunction createPrerenderingSettingsDbItem(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n params: PreRenderingServiceParams\n) {\n /**\n * To handle everything related to prerendering, we need the following information:\n * - appUrl - SPA URL used to prerender HTML\n * - bucket - name of the S3 bucket used for storage of HTML snapshots\n * - cloudfrontId - for cache invalidation\n * - sqsQueueUrl - an SQS queue for prerendering tasks (messages)\n */\n const tableItem = app.addResource(aws.dynamodb.TableItem, {\n name: \"psSettings\",\n config: {\n tableName: params.dbTableName,\n hashKey: params.dbTableHashKey,\n rangeKey: params.dbTableRangeKey,\n item: pulumi.interpolate`{\n \"PK\": \"PS#SETTINGS\",\n \"SK\": \"${app.params.run.variant || \"default\"}\",\n \"data\": {\n \"appUrl\": \"${params.appUrl}\",\n \"deliveryUrl\": \"${params.deliveryUrl}\",\n \"bucket\": \"${params.bucket}\",\n \"cloudfrontId\": \"${params.cloudfrontId}\",\n \"sqsQueueUrl\": \"${queue.url}\"\n }\n }`\n // We're using the native DynamoDB converter to avoid building those nested objects ourselves.\n .apply(v => JSON.stringify(Converter.marshall(JSON.parse(v))))\n }\n });\n\n return { tableItem };\n}\n\nfunction createRenderSubscriber(\n app: PulumiApp,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n\n const role = createLambdaRole(app, {\n name: \"ps-render-subscriber-role\",\n policy: policy,\n executionRole: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-render-subscriber-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 30,\n memorySize: 512,\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Subscribes to render events on event bus\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/subscribe/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n /**\n * TODO: when we get to staged rollouts and variants, maybe we can create per-variant event rules,\n * to avoid invocation of all variant lambdas just to do a `detail-type` check and exit early.\n * That way, we would be publishing events scoped to a variant, like \"RenderPages-{variant}\".\n */\n\n const eventRule = app.addResource(aws.cloudwatch.EventRule, {\n name: \"ps-render-subscriber-event-rule\",\n config: {\n eventBusName: core.eventBusArn,\n eventPattern: JSON.stringify({\n \"detail-type\": [\"RenderPages\"]\n })\n }\n });\n\n const eventPermission = app.addResource(aws.lambda.Permission, {\n name: \"ps-render-subscriber-event-permission\",\n config: {\n action: \"lambda:InvokeFunction\",\n function: lambda.output.arn,\n principal: \"events.amazonaws.com\",\n sourceArn: eventRule.output.arn\n }\n });\n\n const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {\n name: \"ps-render-subscriber-event-target\",\n config: {\n rule: eventRule.output.name,\n eventBusName: core.eventBusArn,\n arn: lambda.output.arn\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventRule,\n eventPermission,\n eventTarget\n };\n}\n\nfunction createRenderer(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const role = createLambdaRole(app, {\n name: \"ps-render-lambda-role\",\n policy: policy,\n executionRole: aws.iam.ManagedPolicy.AWSLambdaSQSQueueExecutionRole\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-render-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 300,\n memorySize: 2048,\n layers: [getLayerArn(\"shelf-io-chrome-aws-lambda-layer\")],\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Renders pages and stores output in an S3 bucket of choice.\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/render/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n const eventSourceMapping = app.addResource(aws.lambda.EventSourceMapping, {\n name: \"ps-render-event-source-mapping\",\n config: {\n functionName: lambda.output.arn,\n eventSourceArn: queue.arn,\n batchSize: 1\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventSourceMapping\n };\n}\n\nfunction createFlushService(\n app: PulumiApp,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n\n const role = createLambdaRole(app, {\n name: \"ps-flush-lambda-role\",\n policy: policy,\n executionRole: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-flush-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 30,\n memorySize: 512,\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Subscribes to flush events on event bus\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/flush/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n const eventRule = app.addResource(aws.cloudwatch.EventRule, {\n name: \"ps-flush-event-rule\",\n config: {\n eventBusName: core.eventBusArn,\n eventPattern: JSON.stringify({\n \"detail-type\": [\"FlushPages\"]\n })\n }\n });\n\n const eventPermission = app.addResource(aws.lambda.Permission, {\n name: \"ps-flush-event-permission\",\n config: {\n action: \"lambda:InvokeFunction\",\n function: lambda.output.arn,\n principal: \"events.amazonaws.com\",\n sourceArn: eventRule.output.arn\n }\n });\n\n const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {\n name: \"ps-flush-event-target\",\n config: {\n rule: eventRule.output.name,\n eventBusName: core.eventBusArn,\n arn: lambda.output.arn\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventRule,\n eventPermission,\n eventTarget\n };\n}\n\nfunction createLambdaPolicy(app: PulumiApp, queue: pulumi.Output<aws.sqs.Queue>) {\n const core = app.getModule(CoreOutput);\n const awsAccountId = getAwsAccountId(app);\n\n return app.addResource(aws.iam.Policy, {\n name: \"ps-lambda-policy\",\n config: {\n description: \"This policy enables access to Lambda, S3, Cloudfront, SQS and Dynamodb\",\n policy: {\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PermissionForDynamodb\",\n Effect: \"Allow\",\n Action: [\n \"dynamodb:BatchGetItem\",\n \"dynamodb:BatchWriteItem\",\n \"dynamodb:DeleteItem\",\n \"dynamodb:GetItem\",\n \"dynamodb:PutItem\",\n \"dynamodb:Query\",\n \"dynamodb:Scan\",\n \"dynamodb:UpdateItem\"\n ],\n Resource: core.apply(s => {\n // Add permissions to DynamoDB table\n const resources = [\n `${s.primaryDynamodbTableArn}`,\n `${s.primaryDynamodbTableArn}/*`\n ];\n\n // Attach permissions for elastic search dynamo as well (if ES is enabled).\n if (s.elasticsearchDynamodbTableArn) {\n resources.push(\n `${s.elasticsearchDynamodbTableArn}`,\n `${s.elasticsearchDynamodbTableArn}/*`\n );\n }\n\n return resources;\n })\n },\n {\n Sid: \"PermissionForS3\",\n Effect: \"Allow\",\n Action: [\n \"s3:DeleteObject\",\n \"s3:GetObject\",\n \"s3:GetObjectAcl\",\n \"s3:PutObject\",\n \"s3:PutObjectAcl\"\n ],\n Resource: [\n pulumi.interpolate`arn:aws:s3:::${core.fileManagerBucketId}/*`,\n /**\n * We're using the hard-coded value for \"delivery\" S3 bucket because;\n * It is created during deployment of the `apps/website` stack which is after the api stack,\n * so, we don't know its ARN.\n */\n \"arn:aws:s3:::delivery-*/*\"\n ]\n },\n {\n Sid: \"PermissionForCloudfront\",\n Effect: \"Allow\",\n Action: \"cloudfront:CreateInvalidation\",\n Resource: pulumi.interpolate`arn:aws:cloudfront::${awsAccountId}:distribution/*`\n },\n {\n Sid: \"PermissionForSQS\",\n Effect: \"Allow\",\n Action: [\"sqs:SendMessage\", \"sqs:SendMessageBatch\"],\n Resource: queue.arn\n }\n ]\n }\n }\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["createPrerenderingService","app","params","queue","addResource","aws","sqs","Queue","name","config","visibilityTimeoutSeconds","fifoQueue","policy","createLambdaPolicy","output","renderer","createRenderer","subscriber","createRenderSubscriber","flush","createFlushService","settings","createPrerenderingSettingsDbItem","tableItem","dynamodb","TableItem","tableName","dbTableName","hashKey","dbTableHashKey","rangeKey","dbTableRangeKey","item","pulumi","interpolate","run","variant","appUrl","deliveryUrl","bucket","cloudfrontId","url","apply","v","JSON","stringify","Converter","marshall","parse","core","getModule","CoreOutput","role","createLambdaRole","lambda","Function","arn","runtime","handler","timeout","memorySize","environment","variables","getCommonLambdaEnvVariables","value","DB_TABLE","description","code","asset","AssetArchive","FileArchive","path","join","paths","workspace","vpcConfig","VpcConfig","functionVpcConfig","eventRule","cloudwatch","EventRule","eventBusName","eventBusArn","eventPattern","eventPermission","Permission","action","function","principal","sourceArn","eventTarget","EventTarget","rule","executionRole","iam","ManagedPolicy","AWSLambdaSQSQueueExecutionRole","layers","getLayerArn","eventSourceMapping","EventSourceMapping","functionName","eventSourceArn","batchSize","awsAccountId","getAwsAccountId","Policy","Version","Statement","Sid","Effect","Action","Resource","s","resources","primaryDynamodbTableArn","elasticsearchDynamodbTableArn","push"],"sources":["WebsitePrerendering.ts"],"sourcesContent":["import * as path from \"path\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { Converter } from \"aws-sdk/clients/dynamodb\";\n\nimport { PulumiApp } from \"@webiny/pulumi\";\n// @ts-ignore\nimport { getLayerArn } from \"@webiny/aws-layers\";\n\nimport { createLambdaRole, getCommonLambdaEnvVariables } from \"../lambdaUtils\";\nimport { CoreOutput, VpcConfig } from \"../common\";\nimport { getAwsAccountId } from \"../awsUtils\";\n\ninterface PreRenderingServiceParams {\n dbTableName: pulumi.Output<string>;\n dbTableHashKey: pulumi.Output<string>;\n dbTableRangeKey: pulumi.Output<string>;\n appUrl: pulumi.Output<string>;\n deliveryUrl: pulumi.Output<string>;\n bucket: pulumi.Output<string>;\n cloudfrontId: pulumi.Output<string>;\n}\n\nexport function createPrerenderingService(app: PulumiApp, params: PreRenderingServiceParams) {\n const queue = app.addResource(aws.sqs.Queue, {\n name: \"ps-render-queue\",\n config: {\n visibilityTimeoutSeconds: 300,\n fifoQueue: true\n }\n });\n\n const policy = createLambdaPolicy(app, queue.output, params);\n const renderer = createRenderer(app, queue.output, policy.output, params);\n const subscriber = createRenderSubscriber(app, policy.output, params);\n const flush = createFlushService(app, policy.output, params);\n const settings = createPrerenderingSettingsDbItem(app, queue.output, params);\n\n return {\n subscriber,\n renderer,\n flush,\n settings\n };\n}\n\nfunction createPrerenderingSettingsDbItem(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n params: PreRenderingServiceParams\n) {\n /**\n * To handle everything related to prerendering, we need the following information:\n * - appUrl - SPA URL used to prerender HTML\n * - bucket - name of the S3 bucket used for storage of HTML snapshots\n * - cloudfrontId - for cache invalidation\n * - sqsQueueUrl - an SQS queue for prerendering tasks (messages)\n */\n const tableItem = app.addResource(aws.dynamodb.TableItem, {\n name: \"psSettings\",\n config: {\n tableName: params.dbTableName,\n hashKey: params.dbTableHashKey,\n rangeKey: params.dbTableRangeKey,\n item: pulumi.interpolate`{\n \"PK\": \"PS#SETTINGS\",\n \"SK\": \"${app.params.run.variant || \"default\"}\",\n \"data\": {\n \"appUrl\": \"${params.appUrl}\",\n \"deliveryUrl\": \"${params.deliveryUrl}\",\n \"bucket\": \"${params.bucket}\",\n \"cloudfrontId\": \"${params.cloudfrontId}\",\n \"sqsQueueUrl\": \"${queue.url}\"\n }\n }`\n // We're using the native DynamoDB converter to avoid building those nested objects ourselves.\n .apply(v => JSON.stringify(Converter.marshall(JSON.parse(v))))\n }\n });\n\n return { tableItem };\n}\n\nfunction createRenderSubscriber(\n app: PulumiApp,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n\n const role = createLambdaRole(app, {\n name: \"ps-render-subscriber-role\",\n policy: policy\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-render-subscriber-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 30,\n memorySize: 512,\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Subscribes to render events on event bus\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/subscribe/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n /**\n * TODO: when we get to staged rollouts and variants, maybe we can create per-variant event rules,\n * to avoid invocation of all variant lambdas just to do a `detail-type` check and exit early.\n * That way, we would be publishing events scoped to a variant, like \"RenderPages-{variant}\".\n */\n\n const eventRule = app.addResource(aws.cloudwatch.EventRule, {\n name: \"ps-render-subscriber-event-rule\",\n config: {\n eventBusName: core.eventBusArn,\n eventPattern: JSON.stringify({\n \"detail-type\": [\"RenderPages\"]\n })\n }\n });\n\n const eventPermission = app.addResource(aws.lambda.Permission, {\n name: \"ps-render-subscriber-event-permission\",\n config: {\n action: \"lambda:InvokeFunction\",\n function: lambda.output.arn,\n principal: \"events.amazonaws.com\",\n sourceArn: eventRule.output.arn\n }\n });\n\n const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {\n name: \"ps-render-subscriber-event-target\",\n config: {\n rule: eventRule.output.name,\n eventBusName: core.eventBusArn,\n arn: lambda.output.arn\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventRule,\n eventPermission,\n eventTarget\n };\n}\n\nfunction createRenderer(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const role = createLambdaRole(app, {\n name: \"ps-render-lambda-role\",\n policy: policy,\n executionRole: aws.iam.ManagedPolicy.AWSLambdaSQSQueueExecutionRole\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-render-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 300,\n memorySize: 2048,\n layers: [getLayerArn(\"shelf-io-chrome-aws-lambda-layer\")],\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Renders pages and stores output in an S3 bucket of choice.\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/render/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n const eventSourceMapping = app.addResource(aws.lambda.EventSourceMapping, {\n name: \"ps-render-event-source-mapping\",\n config: {\n functionName: lambda.output.arn,\n eventSourceArn: queue.arn,\n batchSize: 1\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventSourceMapping\n };\n}\n\nfunction createFlushService(\n app: PulumiApp,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n\n const role = createLambdaRole(app, {\n name: \"ps-flush-lambda-role\",\n policy: policy\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-flush-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 30,\n memorySize: 512,\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Subscribes to flush events on event bus\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/flush/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n const eventRule = app.addResource(aws.cloudwatch.EventRule, {\n name: \"ps-flush-event-rule\",\n config: {\n eventBusName: core.eventBusArn,\n eventPattern: JSON.stringify({\n \"detail-type\": [\"FlushPages\"]\n })\n }\n });\n\n const eventPermission = app.addResource(aws.lambda.Permission, {\n name: \"ps-flush-event-permission\",\n config: {\n action: \"lambda:InvokeFunction\",\n function: lambda.output.arn,\n principal: \"events.amazonaws.com\",\n sourceArn: eventRule.output.arn\n }\n });\n\n const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {\n name: \"ps-flush-event-target\",\n config: {\n rule: eventRule.output.name,\n eventBusName: core.eventBusArn,\n arn: lambda.output.arn\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventRule,\n eventPermission,\n eventTarget\n };\n}\n\nfunction createLambdaPolicy(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n const awsAccountId = getAwsAccountId(app);\n\n return app.addResource(aws.iam.Policy, {\n name: \"ps-lambda-policy\",\n config: {\n description: \"This policy enables access to Lambda, S3, Cloudfront, SQS and Dynamodb\",\n policy: {\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PermissionForDynamodb\",\n Effect: \"Allow\",\n Action: [\n \"dynamodb:BatchGetItem\",\n \"dynamodb:BatchWriteItem\",\n \"dynamodb:DeleteItem\",\n \"dynamodb:GetItem\",\n \"dynamodb:PutItem\",\n \"dynamodb:Query\",\n \"dynamodb:Scan\",\n \"dynamodb:UpdateItem\"\n ],\n Resource: core.apply(s => {\n // Add permissions to DynamoDB table\n const resources = [\n `${s.primaryDynamodbTableArn}`,\n `${s.primaryDynamodbTableArn}/*`\n ];\n\n // Attach permissions for elastic search dynamo as well (if ES is enabled).\n if (s.elasticsearchDynamodbTableArn) {\n resources.push(\n `${s.elasticsearchDynamodbTableArn}`,\n `${s.elasticsearchDynamodbTableArn}/*`\n );\n }\n\n return resources;\n })\n },\n {\n Sid: \"PermissionForS3\",\n Effect: \"Allow\",\n Action: [\"s3:DeleteObject\", \"s3:GetObject\", \"s3:PutObject\"],\n Resource: [pulumi.interpolate`arn:aws:s3:::${params.bucket}/*`]\n },\n {\n Sid: \"PermissionForCloudfront\",\n Effect: \"Allow\",\n Action: \"cloudfront:CreateInvalidation\",\n Resource: pulumi.interpolate`arn:aws:cloudfront::${awsAccountId}:distribution/*`\n },\n {\n Sid: \"PermissionForSQS\",\n Effect: \"Allow\",\n Action: [\"sqs:SendMessage\", \"sqs:SendMessageBatch\"],\n Resource: queue.arn\n }\n ]\n }\n }\n });\n}\n"],"mappings":"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"}
@@ -48,11 +48,17 @@ export declare const createWebsitePulumiApp: (projectAppParams?: CreateWebsitePu
48
48
  app: {
49
49
  cloudfront: import("@webiny/pulumi").PulumiAppResource<typeof aws.cloudfront.Distribution>;
50
50
  bucket: import("@webiny/pulumi").PulumiAppResource<typeof aws.s3.Bucket>;
51
+ originIdentity: import("@webiny/pulumi").PulumiAppResource<typeof aws.cloudfront.OriginAccessIdentity>;
51
52
  origin: aws.types.input.cloudfront.DistributionOrigin;
53
+ bucketPublicAccessBlock: import("@webiny/pulumi").PulumiAppResource<typeof aws.s3.BucketPublicAccessBlock>;
54
+ bucketPolicy: import("@webiny/pulumi").PulumiAppResource<typeof aws.s3.BucketPolicy>;
52
55
  };
53
56
  delivery: {
54
57
  cloudfront: import("@webiny/pulumi").PulumiAppResource<typeof aws.cloudfront.Distribution>;
55
58
  bucket: import("@webiny/pulumi").PulumiAppResource<typeof aws.s3.Bucket>;
59
+ originIdentity: import("@webiny/pulumi").PulumiAppResource<typeof aws.cloudfront.OriginAccessIdentity>;
56
60
  origin: aws.types.input.cloudfront.DistributionOrigin;
61
+ bucketPublicAccessBlock: import("@webiny/pulumi").PulumiAppResource<typeof aws.s3.BucketPublicAccessBlock>;
62
+ bucketPolicy: import("@webiny/pulumi").PulumiAppResource<typeof aws.s3.BucketPolicy>;
57
63
  };
58
64
  }> & import("../lambdaUtils").WithCommonLambdaEnvVariables;
@@ -13,6 +13,8 @@ var pulumi = _interopRequireWildcard(require("@pulumi/pulumi"));
13
13
 
14
14
  var aws = _interopRequireWildcard(require("@pulumi/aws"));
15
15
 
16
+ var _fs = _interopRequireDefault(require("fs"));
17
+
16
18
  var _pulumi2 = require("@webiny/pulumi");
17
19
 
18
20
  var _createAppBucket = require("../createAppBucket");
@@ -55,7 +57,7 @@ const createWebsitePulumiApp = (projectAppParams = {}) => {
55
57
  app.addModule(_.VpcConfig, {
56
58
  enabled: app.getParam(projectAppParams.vpc)
57
59
  });
58
- const appBucket = (0, _createAppBucket.createPublicAppBucket)(app, "app");
60
+ const appBucket = (0, _createAppBucket.createPrivateAppBucket)(app, "app");
59
61
  const appCloudfront = app.addResource(aws.cloudfront.Distribution, {
60
62
  name: "app",
61
63
  config: {
@@ -96,7 +98,21 @@ const createWebsitePulumiApp = (projectAppParams = {}) => {
96
98
  }
97
99
  }
98
100
  });
99
- const deliveryBucket = (0, _createAppBucket.createPublicAppBucket)(app, "delivery");
101
+ const deliveryBucket = (0, _createAppBucket.createPrivateAppBucket)(app, "delivery");
102
+ /**
103
+ * We need to have a Cloudfront Function to perform a simple request rewrite, so the request always includes
104
+ * an "/index.html". This is necessary because our buckets are not "website" buckets, and we need to
105
+ * have an exact object key when requesting page paths.
106
+ */
107
+
108
+ const viewerRequest = app.addResource(aws.cloudfront.Function, {
109
+ name: "cfViewerRequest",
110
+ config: {
111
+ runtime: "cloudfront-js-1.0",
112
+ publish: true,
113
+ code: _fs.default.readFileSync(__dirname + `/deliveryViewerRequest.js`, "utf8")
114
+ }
115
+ });
100
116
  const deliveryCloudfront = app.addResource(aws.cloudfront.Distribution, {
101
117
  name: "delivery",
102
118
  config: {
@@ -120,7 +136,11 @@ const createWebsitePulumiApp = (projectAppParams = {}) => {
120
136
  // MinTTL <= DefaultTTL <= MaxTTL
121
137
  minTtl: 0,
122
138
  defaultTtl: 30,
123
- maxTtl: 30
139
+ maxTtl: 30,
140
+ functionAssociations: [{
141
+ functionArn: viewerRequest.output.arn,
142
+ eventType: "viewer-request"
143
+ }]
124
144
  },
125
145
  orderedCacheBehaviors: [{
126
146
  compress: true,
@@ -1 +1 @@
1
- {"version":3,"names":["createWebsitePulumiApp","projectAppParams","app","createPulumiApp","name","path","config","program","pulumi","addHandler","core","addModule","CoreOutput","VpcConfig","enabled","getParam","vpc","appBucket","createPublicAppBucket","appCloudfront","addResource","aws","cloudfront","Distribution","waitForDeployment","origins","origin","defaultRootObject","defaultCacheBehavior","compress","targetOriginId","originId","viewerProtocolPolicy","allowedMethods","cachedMethods","forwardedValues","cookies","forward","queryString","minTtl","defaultTtl","maxTtl","priceClass","customErrorResponses","errorCode","responseCode","responsePagePath","restrictions","geoRestriction","restrictionType","viewerCertificate","cloudfrontDefaultCertificate","deliveryBucket","deliveryCloudfront","originRequestPolicyId","orderedCacheBehaviors","headers","pathPattern","prerendering","createPrerenderingService","dbTableName","primaryDynamodbTableName","dbTableHashKey","primaryDynamodbTableHashKey","dbTableRangeKey","primaryDynamodbTableRangeKey","appUrl","interpolate","output","domainName","deliveryUrl","bucket","cloudfrontId","id","domains","applyCustomDomain","process","env","WCP_PROJECT_ENVIRONMENT","applyTenantRouter","addOutputs","appId","appStorage","apply","value","appDomain","deliveryId","deliveryStorage","deliveryDomain","tagResources","WbyProjectName","String","WbyEnvironment","delivery","withCommonLambdaEnvVariables"],"sources":["createWebsitePulumiApp.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { createPulumiApp, PulumiAppParamCallback, PulumiAppParam } from \"@webiny/pulumi\";\nimport { createPublicAppBucket } from \"../createAppBucket\";\nimport { applyCustomDomain, CustomDomainParams } from \"../customDomain\";\nimport { createPrerenderingService } from \"./WebsitePrerendering\";\nimport { CoreOutput, VpcConfig } from \"~/apps\";\nimport { tagResources, withCommonLambdaEnvVariables } from \"~/utils\";\nimport { applyTenantRouter } from \"~/apps/tenantRouter\";\n\nexport type WebsitePulumiApp = ReturnType<typeof createWebsitePulumiApp>;\n\nexport interface CreateWebsitePulumiAppParams {\n /** Custom domain configuration */\n domains?: PulumiAppParamCallback<CustomDomainParams>;\n\n /**\n * Enables or disables VPC for the API.\n * For VPC to work you also have to enable it in the `core` application.\n */\n vpc?: PulumiAppParam<boolean | undefined>;\n\n /**\n * Provides a way to adjust existing Pulumi code (cloud infrastructure resources)\n * or add additional ones into the mix.\n */\n pulumi?: (app: WebsitePulumiApp) => void | Promise<void>;\n}\n\nexport const createWebsitePulumiApp = (projectAppParams: CreateWebsitePulumiAppParams = {}) => {\n const app = createPulumiApp({\n name: \"website\",\n path: \"apps/website\",\n config: projectAppParams,\n program: async app => {\n // Overrides must be applied via a handler, registered at the very start of the program.\n // By doing this, we're ensuring user's adjustments are not applied to late.\n if (projectAppParams.pulumi) {\n app.addHandler(() => {\n return projectAppParams.pulumi!(app as WebsitePulumiApp);\n });\n }\n\n // Register core output as a module available for all other modules\n const core = app.addModule(CoreOutput);\n\n // Register VPC config module to be available to other modules\n app.addModule(VpcConfig, {\n enabled: app.getParam(projectAppParams.vpc)\n });\n\n const appBucket = createPublicAppBucket(app, \"app\");\n\n const appCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"app\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: appBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: false\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 0,\n maxTtl: 0\n },\n priceClass: \"PriceClass_100\",\n customErrorResponses: [\n { errorCode: 404, responseCode: 404, responsePagePath: \"/index.html\" }\n ],\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n }\n });\n\n const deliveryBucket = createPublicAppBucket(app, \"delivery\");\n\n const deliveryCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"delivery\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [deliveryBucket.origin, appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: deliveryBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n originRequestPolicyId: \"\",\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: true\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 30,\n maxTtl: 30\n },\n orderedCacheBehaviors: [\n {\n compress: true,\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: {\n forward: \"none\"\n },\n headers: [],\n queryString: false\n },\n pathPattern: \"/static/*\",\n viewerProtocolPolicy: \"allow-all\",\n targetOriginId: appBucket.origin.originId,\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 2592000, // 30 days\n maxTtl: 2592000\n }\n ],\n customErrorResponses: [\n {\n errorCode: 404,\n responseCode: 404,\n responsePagePath: \"/_NOT_FOUND_PAGE_/index.html\"\n }\n ],\n priceClass: \"PriceClass_100\",\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n }\n });\n\n const prerendering = createPrerenderingService(app, {\n dbTableName: core.primaryDynamodbTableName,\n dbTableHashKey: core.primaryDynamodbTableHashKey,\n dbTableRangeKey: core.primaryDynamodbTableRangeKey,\n appUrl: pulumi.interpolate`https://${appCloudfront.output.domainName}`,\n deliveryUrl: pulumi.interpolate`https://${deliveryCloudfront.output.domainName}`,\n bucket: deliveryBucket.bucket.output.bucket,\n cloudfrontId: deliveryCloudfront.output.id\n });\n\n const domains = app.getParam(projectAppParams.domains);\n if (domains) {\n applyCustomDomain(deliveryCloudfront, domains);\n }\n\n if (process.env.WCP_PROJECT_ENVIRONMENT) {\n applyTenantRouter(app, deliveryCloudfront);\n }\n\n app.addOutputs({\n // Cloudfront and S3 bucket used to host the single-page application (SPA). The URL of the distribution is mainly\n // utilized by the Page Builder app's prerendering engine. Using this URL, it accesses the SPA and creates HTML snapshots.\n // The files that are generated in that process are stored in the `deliveryStorage` S3 bucket further below.\n appId: appCloudfront.output.id,\n appStorage: appBucket.bucket.output.id,\n appUrl: appCloudfront.output.domainName.apply(value => `https://${value}`),\n appDomain: appCloudfront.output.domainName,\n // These are the Cloudfront and S3 bucket that will deliver static pages to the actual website visitors.\n // The static HTML snapshots delivered from them still rely on the app's S3 bucket\n // defined above, for serving static assets (JS, CSS, images).\n deliveryId: deliveryCloudfront.output.id,\n deliveryStorage: deliveryBucket.bucket.output.id,\n deliveryDomain: deliveryCloudfront.output.domainName,\n deliveryUrl: deliveryCloudfront.output.domainName.apply(value => `https://${value}`)\n });\n\n tagResources({\n WbyProjectName: String(process.env[\"WEBINY_PROJECT_NAME\"]),\n WbyEnvironment: String(process.env[\"WEBINY_ENV\"])\n });\n\n return {\n prerendering,\n app: {\n ...appBucket,\n cloudfront: appCloudfront\n },\n delivery: {\n ...deliveryBucket,\n cloudfront: deliveryCloudfront\n }\n };\n }\n });\n\n return withCommonLambdaEnvVariables(app);\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["createWebsitePulumiApp","projectAppParams","app","createPulumiApp","name","path","config","program","pulumi","addHandler","core","addModule","CoreOutput","VpcConfig","enabled","getParam","vpc","appBucket","createPrivateAppBucket","appCloudfront","addResource","aws","cloudfront","Distribution","waitForDeployment","origins","origin","defaultRootObject","defaultCacheBehavior","compress","targetOriginId","originId","viewerProtocolPolicy","allowedMethods","cachedMethods","forwardedValues","cookies","forward","queryString","minTtl","defaultTtl","maxTtl","priceClass","customErrorResponses","errorCode","responseCode","responsePagePath","restrictions","geoRestriction","restrictionType","viewerCertificate","cloudfrontDefaultCertificate","deliveryBucket","viewerRequest","Function","runtime","publish","code","fs","readFileSync","__dirname","deliveryCloudfront","originRequestPolicyId","functionAssociations","functionArn","output","arn","eventType","orderedCacheBehaviors","headers","pathPattern","prerendering","createPrerenderingService","dbTableName","primaryDynamodbTableName","dbTableHashKey","primaryDynamodbTableHashKey","dbTableRangeKey","primaryDynamodbTableRangeKey","appUrl","interpolate","domainName","deliveryUrl","bucket","cloudfrontId","id","domains","applyCustomDomain","process","env","WCP_PROJECT_ENVIRONMENT","applyTenantRouter","addOutputs","appId","appStorage","apply","value","appDomain","deliveryId","deliveryStorage","deliveryDomain","tagResources","WbyProjectName","String","WbyEnvironment","delivery","withCommonLambdaEnvVariables"],"sources":["createWebsitePulumiApp.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport fs from \"fs\";\nimport { createPulumiApp, PulumiAppParamCallback, PulumiAppParam } from \"@webiny/pulumi\";\nimport { createPrivateAppBucket } from \"../createAppBucket\";\nimport { applyCustomDomain, CustomDomainParams } from \"../customDomain\";\nimport { createPrerenderingService } from \"./WebsitePrerendering\";\nimport { CoreOutput, VpcConfig } from \"~/apps\";\nimport { tagResources, withCommonLambdaEnvVariables } from \"~/utils\";\nimport { applyTenantRouter } from \"~/apps/tenantRouter\";\n\nexport type WebsitePulumiApp = ReturnType<typeof createWebsitePulumiApp>;\n\nexport interface CreateWebsitePulumiAppParams {\n /** Custom domain configuration */\n domains?: PulumiAppParamCallback<CustomDomainParams>;\n\n /**\n * Enables or disables VPC for the API.\n * For VPC to work you also have to enable it in the `core` application.\n */\n vpc?: PulumiAppParam<boolean | undefined>;\n\n /**\n * Provides a way to adjust existing Pulumi code (cloud infrastructure resources)\n * or add additional ones into the mix.\n */\n pulumi?: (app: WebsitePulumiApp) => void | Promise<void>;\n}\n\nexport const createWebsitePulumiApp = (projectAppParams: CreateWebsitePulumiAppParams = {}) => {\n const app = createPulumiApp({\n name: \"website\",\n path: \"apps/website\",\n config: projectAppParams,\n program: async app => {\n // Overrides must be applied via a handler, registered at the very start of the program.\n // By doing this, we're ensuring user's adjustments are not applied to late.\n if (projectAppParams.pulumi) {\n app.addHandler(() => {\n return projectAppParams.pulumi!(app as WebsitePulumiApp);\n });\n }\n\n // Register core output as a module available for all other modules\n const core = app.addModule(CoreOutput);\n\n // Register VPC config module to be available to other modules\n app.addModule(VpcConfig, {\n enabled: app.getParam(projectAppParams.vpc)\n });\n\n const appBucket = createPrivateAppBucket(app, \"app\");\n\n const appCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"app\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: appBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: false\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 0,\n maxTtl: 0\n },\n priceClass: \"PriceClass_100\",\n customErrorResponses: [\n { errorCode: 404, responseCode: 404, responsePagePath: \"/index.html\" }\n ],\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n }\n });\n\n const deliveryBucket = createPrivateAppBucket(app, \"delivery\");\n\n /**\n * We need to have a Cloudfront Function to perform a simple request rewrite, so the request always includes\n * an \"/index.html\". This is necessary because our buckets are not \"website\" buckets, and we need to\n * have an exact object key when requesting page paths.\n */\n const viewerRequest = app.addResource(aws.cloudfront.Function, {\n name: \"cfViewerRequest\",\n config: {\n runtime: \"cloudfront-js-1.0\",\n publish: true,\n code: fs.readFileSync(__dirname + `/deliveryViewerRequest.js`, \"utf8\")\n }\n });\n\n const deliveryCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"delivery\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [deliveryBucket.origin, appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: deliveryBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n originRequestPolicyId: \"\",\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: true\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 30,\n maxTtl: 30,\n functionAssociations: [\n { functionArn: viewerRequest.output.arn, eventType: \"viewer-request\" }\n ]\n },\n orderedCacheBehaviors: [\n {\n compress: true,\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: {\n forward: \"none\"\n },\n headers: [],\n queryString: false\n },\n pathPattern: \"/static/*\",\n viewerProtocolPolicy: \"allow-all\",\n targetOriginId: appBucket.origin.originId,\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 2592000, // 30 days\n maxTtl: 2592000\n }\n ],\n customErrorResponses: [\n {\n errorCode: 404,\n responseCode: 404,\n responsePagePath: \"/_NOT_FOUND_PAGE_/index.html\"\n }\n ],\n priceClass: \"PriceClass_100\",\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n }\n });\n\n const prerendering = createPrerenderingService(app, {\n dbTableName: core.primaryDynamodbTableName,\n dbTableHashKey: core.primaryDynamodbTableHashKey,\n dbTableRangeKey: core.primaryDynamodbTableRangeKey,\n appUrl: pulumi.interpolate`https://${appCloudfront.output.domainName}`,\n deliveryUrl: pulumi.interpolate`https://${deliveryCloudfront.output.domainName}`,\n bucket: deliveryBucket.bucket.output.bucket,\n cloudfrontId: deliveryCloudfront.output.id\n });\n\n const domains = app.getParam(projectAppParams.domains);\n if (domains) {\n applyCustomDomain(deliveryCloudfront, domains);\n }\n\n if (process.env.WCP_PROJECT_ENVIRONMENT) {\n applyTenantRouter(app, deliveryCloudfront);\n }\n\n app.addOutputs({\n // Cloudfront and S3 bucket used to host the single-page application (SPA). The URL of the distribution is mainly\n // utilized by the Page Builder app's prerendering engine. Using this URL, it accesses the SPA and creates HTML snapshots.\n // The files that are generated in that process are stored in the `deliveryStorage` S3 bucket further below.\n appId: appCloudfront.output.id,\n appStorage: appBucket.bucket.output.id,\n appUrl: appCloudfront.output.domainName.apply(value => `https://${value}`),\n appDomain: appCloudfront.output.domainName,\n // These are the Cloudfront and S3 bucket that will deliver static pages to the actual website visitors.\n // The static HTML snapshots delivered from them still rely on the app's S3 bucket\n // defined above, for serving static assets (JS, CSS, images).\n deliveryId: deliveryCloudfront.output.id,\n deliveryStorage: deliveryBucket.bucket.output.id,\n deliveryDomain: deliveryCloudfront.output.domainName,\n deliveryUrl: deliveryCloudfront.output.domainName.apply(value => `https://${value}`)\n });\n\n tagResources({\n WbyProjectName: String(process.env[\"WEBINY_PROJECT_NAME\"]),\n WbyEnvironment: String(process.env[\"WEBINY_ENV\"])\n });\n\n return {\n prerendering,\n app: {\n ...appBucket,\n cloudfront: appCloudfront\n },\n delivery: {\n ...deliveryBucket,\n cloudfront: deliveryCloudfront\n }\n };\n }\n });\n\n return withCommonLambdaEnvVariables(app);\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ declare function sanitizeRequestURI(uri: any): string;
2
+ declare function handler(event: any): any;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ function sanitizeRequestURI(uri) {
4
+ // Make sure that `/` is not appended to index.html, or any path with extension.
5
+ // We remove all slashes, filter out empty values, and reconstruct the path following
6
+ // the fact that every page (slug) has a dedicated folder in the S3 bucket, and an `index.html`
7
+ // file with the actual page HTML.
8
+ var parts = uri.split("/").filter(Boolean); // This means that a `/` (homepage) was requested. When the homepage is prerendered, we place its files
9
+ // into the root of the bucket, or in the tenant subfolder, if it's a multi-tenant system, e.g., `/root/index.html`.
10
+
11
+ if (!parts.length) {
12
+ return "/index.html";
13
+ }
14
+
15
+ var lastPart = parts[parts.length - 1]; // If there's a `.` in the last part of the path, we assume it's a file extension.
16
+ // In this case, we can reconstruct the path by joining parts with slashes.
17
+
18
+ if (lastPart.includes(".")) {
19
+ return [""].concat(parts).join("/");
20
+ } // Otherwise, we assume it's a page slug, which needs to point to page's subfolder.
21
+ // We construct a valid S3 bucket path to an HTML file.
22
+
23
+
24
+ return [""].concat(parts).concat("index.html").join("/");
25
+ } // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
+
27
+
28
+ function handler(event) {
29
+ var request = event.request;
30
+ request.uri = sanitizeRequestURI(request.uri);
31
+ return request;
32
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"names":["sanitizeRequestURI","uri","parts","split","filter","Boolean","length","lastPart","includes","concat","join","handler","event","request"],"sources":["deliveryViewerRequest.js"],"sourcesContent":["function sanitizeRequestURI(uri) {\n // Make sure that `/` is not appended to index.html, or any path with extension.\n // We remove all slashes, filter out empty values, and reconstruct the path following\n // the fact that every page (slug) has a dedicated folder in the S3 bucket, and an `index.html`\n // file with the actual page HTML.\n var parts = uri.split(\"/\").filter(Boolean);\n\n // This means that a `/` (homepage) was requested. When the homepage is prerendered, we place its files\n // into the root of the bucket, or in the tenant subfolder, if it's a multi-tenant system, e.g., `/root/index.html`.\n if (!parts.length) {\n return \"/index.html\";\n }\n\n var lastPart = parts[parts.length - 1];\n\n // If there's a `.` in the last part of the path, we assume it's a file extension.\n // In this case, we can reconstruct the path by joining parts with slashes.\n if (lastPart.includes(\".\")) {\n return [\"\"].concat(parts).join(\"/\");\n }\n\n // Otherwise, we assume it's a page slug, which needs to point to page's subfolder.\n // We construct a valid S3 bucket path to an HTML file.\n return [\"\"].concat(parts).concat(\"index.html\").join(\"/\");\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction handler(event) {\n var request = event.request;\n\n request.uri = sanitizeRequestURI(request.uri);\n\n return request;\n}\n"],"mappings":";;AAAA,SAASA,kBAAT,CAA4BC,GAA5B,EAAiC;EAC7B;EACA;EACA;EACA;EACA,IAAIC,KAAK,GAAGD,GAAG,CAACE,KAAJ,CAAU,GAAV,EAAeC,MAAf,CAAsBC,OAAtB,CAAZ,CAL6B,CAO7B;EACA;;EACA,IAAI,CAACH,KAAK,CAACI,MAAX,EAAmB;IACf,OAAO,aAAP;EACH;;EAED,IAAIC,QAAQ,GAAGL,KAAK,CAACA,KAAK,CAACI,MAAN,GAAe,CAAhB,CAApB,CAb6B,CAe7B;EACA;;EACA,IAAIC,QAAQ,CAACC,QAAT,CAAkB,GAAlB,CAAJ,EAA4B;IACxB,OAAO,CAAC,EAAD,EAAKC,MAAL,CAAYP,KAAZ,EAAmBQ,IAAnB,CAAwB,GAAxB,CAAP;EACH,CAnB4B,CAqB7B;EACA;;;EACA,OAAO,CAAC,EAAD,EAAKD,MAAL,CAAYP,KAAZ,EAAmBO,MAAnB,CAA0B,YAA1B,EAAwCC,IAAxC,CAA6C,GAA7C,CAAP;AACH,C,CAED;;;AACA,SAASC,OAAT,CAAiBC,KAAjB,EAAwB;EACpB,IAAIC,OAAO,GAAGD,KAAK,CAACC,OAApB;EAEAA,OAAO,CAACZ,GAAR,GAAcD,kBAAkB,CAACa,OAAO,CAACZ,GAAT,CAAhC;EAEA,OAAOY,OAAP;AACH"}
@@ -73,8 +73,10 @@ async function hasMultipleTenants() {
73
73
  }
74
74
 
75
75
  async function handleOriginRequest(request) {
76
+ const origin = request.origin;
77
+ const isCustomOrigin = Boolean(origin.custom);
76
78
  const requestedDomain = request.headers.host[0].value;
77
- const originDomain = request.origin.custom.domainName;
79
+ const originDomain = isCustomOrigin ? origin.custom.domainName : origin.s3.domainName;
78
80
  let tenant;
79
81
 
80
82
  if (await hasMultipleTenants()) {
@@ -1 +1 @@
1
- {"version":3,"names":["DocumentClient","require","DB_TABLE_NAME","DB_TABLE_REGION","documentClient","convertEmptyValues","region","sanitizeRequestURI","uri","parts","split","filter","Boolean","length","lastPart","includes","join","getTenantIdByDomain","domain","params","TableName","Key","PK","SK","Item","get","promise","tenant","undefined","hasMultipleTenants","Count","query","IndexName","Limit","Select","KeyConditionExpression","ExpressionAttributeValues","handleOriginRequest","request","requestedDomain","headers","host","value","originDomain","origin","custom","domainName","console","log","startsWith","status","statusDescription","exports","handler","event","config","Records","cf","eventType"],"sources":["request.js"],"sourcesContent":["const { DocumentClient } = require(\"aws-sdk/clients/dynamodb\");\n\n// Since Lambda@Edge doesn't support ENV variables, the easiest way to pass\n// config values to it is to inject them into the source code before deploy.\nconst DB_TABLE_NAME = \"{DB_TABLE_NAME}\";\nconst DB_TABLE_REGION = \"{DB_TABLE_REGION}\";\n\nconst documentClient = new DocumentClient({\n convertEmptyValues: true,\n region: DB_TABLE_REGION\n});\n\nfunction sanitizeRequestURI(uri) {\n // Make sure that `/` is not appended to index.html, or any path with extension.\n // We remove all slashes, filter out empty values, and reconstruct the path following\n // the fact that every page (slug) has a dedicated folder in the S3 bucket, and an `index.html`\n // file with the actual page HTML.\n const parts = uri.split(\"/\").filter(Boolean);\n\n // This means that a `/` (homepage) was requested. When the homepage is prerendered, we place its files\n // into the root of the tenant subfolder, e.g., `/root/index.html`.\n if (!parts.length) {\n return \"/index.html\";\n }\n\n const lastPart = parts[parts.length - 1];\n\n // If there's a `.` in the last part of the path, we assume it's a file extension.\n // In this case, we can reconstruct the path by joining parts with slashes.\n if (lastPart.includes(\".\")) {\n return [\"\", ...parts].join(\"/\");\n }\n\n // Otherwise, we assume it's a page slug, which needs to point to page's subfolder.\n // We construct a valid S3 bucket path to an HTML file.\n return [\"\", ...parts, \"index.html\"].join(\"/\");\n}\n\nasync function getTenantIdByDomain(domain) {\n const params = {\n TableName: DB_TABLE_NAME,\n Key: {\n PK: `DOMAIN#${domain}`,\n SK: \"A\"\n }\n };\n const { Item } = await documentClient.get(params).promise();\n\n return Item ? Item.tenant : undefined;\n}\n\n/**\n * Check if \"root\" tenant has at least one child tenant.\n */\nasync function hasMultipleTenants() {\n const { Count } = await documentClient\n .query({\n TableName: DB_TABLE_NAME,\n IndexName: \"GSI1\",\n Limit: 1,\n Select: \"COUNT\",\n KeyConditionExpression: \"GSI1_PK = :GSI1_PK and begins_with(GSI1_SK, :GSI1_SK)\",\n ExpressionAttributeValues: {\n \":GSI1_PK\": \"TENANTS\",\n \":GSI1_SK\": \"T#root#\"\n }\n })\n .promise();\n\n return Count > 0;\n}\n\nasync function handleOriginRequest(request) {\n const requestedDomain = request.headers.host[0].value;\n const originDomain = request.origin.custom.domainName;\n\n let tenant;\n if (await hasMultipleTenants()) {\n // Find tenant by domain. This record is stored to the DB using the Tenant Manager app.\n console.log(`Multiple tenants are present; loading by domain...`);\n tenant = await getTenantIdByDomain(requestedDomain);\n } else {\n console.log(`Only one tenant is present; falling back to \"root\".`);\n // If the system only has one tenant, we don't need to map by domain at all.\n tenant = \"root\";\n }\n\n if (tenant) {\n const uri = sanitizeRequestURI(request.uri);\n\n // To be on the safe side, make sure the requested uri doesn't already include the tenant ID.\n if (uri.startsWith(`/${tenant}/`)) {\n request.uri = uri;\n } else {\n // Prepend the tenant ID, to point to the correct S3 bucket folder.\n request.uri = `/${tenant}${uri}`;\n }\n\n console.log(`Rewriting request from \"${uri}\" to \"${request.uri}\"`);\n } else {\n console.log(`Failed to find a tenant for domain \"${requestedDomain}\"`);\n return {\n status: 400,\n statusDescription: \"Unable to map tenant. Check your tenant to domain mapping.\"\n };\n }\n\n // At this point, the value of the `Host` header is set to the custom domain.\n // Before forwarding the request to the S3 bucket, we need to set the `Host` header\n // to the value of the origin (S3 bucket URL).\n request.headers.host[0].value = originDomain;\n\n return request;\n}\n\nexports.handler = async event => {\n const { request, config } = event.Records[0].cf;\n\n if (config.eventType === \"origin-request\") {\n return handleOriginRequest(request);\n }\n\n return request;\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["DocumentClient","require","DB_TABLE_NAME","DB_TABLE_REGION","documentClient","convertEmptyValues","region","sanitizeRequestURI","uri","parts","split","filter","Boolean","length","lastPart","includes","join","getTenantIdByDomain","domain","params","TableName","Key","PK","SK","Item","get","promise","tenant","undefined","hasMultipleTenants","Count","query","IndexName","Limit","Select","KeyConditionExpression","ExpressionAttributeValues","handleOriginRequest","request","origin","isCustomOrigin","custom","requestedDomain","headers","host","value","originDomain","domainName","s3","console","log","startsWith","status","statusDescription","exports","handler","event","config","Records","cf","eventType"],"sources":["request.js"],"sourcesContent":["const { DocumentClient } = require(\"aws-sdk/clients/dynamodb\");\n\n// Since Lambda@Edge doesn't support ENV variables, the easiest way to pass\n// config values to it is to inject them into the source code before deploy.\nconst DB_TABLE_NAME = \"{DB_TABLE_NAME}\";\nconst DB_TABLE_REGION = \"{DB_TABLE_REGION}\";\n\nconst documentClient = new DocumentClient({\n convertEmptyValues: true,\n region: DB_TABLE_REGION\n});\n\nfunction sanitizeRequestURI(uri) {\n // Make sure that `/` is not appended to index.html, or any path with extension.\n // We remove all slashes, filter out empty values, and reconstruct the path following\n // the fact that every page (slug) has a dedicated folder in the S3 bucket, and an `index.html`\n // file with the actual page HTML.\n const parts = uri.split(\"/\").filter(Boolean);\n\n // This means that a `/` (homepage) was requested. When the homepage is prerendered, we place its files\n // into the root of the tenant subfolder, e.g., `/root/index.html`.\n if (!parts.length) {\n return \"/index.html\";\n }\n\n const lastPart = parts[parts.length - 1];\n\n // If there's a `.` in the last part of the path, we assume it's a file extension.\n // In this case, we can reconstruct the path by joining parts with slashes.\n if (lastPart.includes(\".\")) {\n return [\"\", ...parts].join(\"/\");\n }\n\n // Otherwise, we assume it's a page slug, which needs to point to page's subfolder.\n // We construct a valid S3 bucket path to an HTML file.\n return [\"\", ...parts, \"index.html\"].join(\"/\");\n}\n\nasync function getTenantIdByDomain(domain) {\n const params = {\n TableName: DB_TABLE_NAME,\n Key: {\n PK: `DOMAIN#${domain}`,\n SK: \"A\"\n }\n };\n const { Item } = await documentClient.get(params).promise();\n\n return Item ? Item.tenant : undefined;\n}\n\n/**\n * Check if \"root\" tenant has at least one child tenant.\n */\nasync function hasMultipleTenants() {\n const { Count } = await documentClient\n .query({\n TableName: DB_TABLE_NAME,\n IndexName: \"GSI1\",\n Limit: 1,\n Select: \"COUNT\",\n KeyConditionExpression: \"GSI1_PK = :GSI1_PK and begins_with(GSI1_SK, :GSI1_SK)\",\n ExpressionAttributeValues: {\n \":GSI1_PK\": \"TENANTS\",\n \":GSI1_SK\": \"T#root#\"\n }\n })\n .promise();\n\n return Count > 0;\n}\n\nasync function handleOriginRequest(request) {\n const origin = request.origin;\n const isCustomOrigin = Boolean(origin.custom);\n const requestedDomain = request.headers.host[0].value;\n const originDomain = isCustomOrigin ? origin.custom.domainName : origin.s3.domainName;\n\n let tenant;\n if (await hasMultipleTenants()) {\n // Find tenant by domain. This record is stored to the DB using the Tenant Manager app.\n console.log(`Multiple tenants are present; loading by domain...`);\n tenant = await getTenantIdByDomain(requestedDomain);\n } else {\n console.log(`Only one tenant is present; falling back to \"root\".`);\n // If the system only has one tenant, we don't need to map by domain at all.\n tenant = \"root\";\n }\n\n if (tenant) {\n const uri = sanitizeRequestURI(request.uri);\n\n // To be on the safe side, make sure the requested uri doesn't already include the tenant ID.\n if (uri.startsWith(`/${tenant}/`)) {\n request.uri = uri;\n } else {\n // Prepend the tenant ID, to point to the correct S3 bucket folder.\n request.uri = `/${tenant}${uri}`;\n }\n\n console.log(`Rewriting request from \"${uri}\" to \"${request.uri}\"`);\n } else {\n console.log(`Failed to find a tenant for domain \"${requestedDomain}\"`);\n return {\n status: 400,\n statusDescription: \"Unable to map tenant. Check your tenant to domain mapping.\"\n };\n }\n\n // At this point, the value of the `Host` header is set to the custom domain.\n // Before forwarding the request to the S3 bucket, we need to set the `Host` header\n // to the value of the origin (S3 bucket URL).\n request.headers.host[0].value = originDomain;\n\n return request;\n}\n\nexports.handler = async event => {\n const { request, config } = event.Records[0].cf;\n\n if (config.eventType === \"origin-request\") {\n return handleOriginRequest(request);\n }\n\n return request;\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/pulumi-aws",
3
- "version": "5.30.0-beta.1",
3
+ "version": "5.31.0-beta.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/webiny/webiny-js.git"
@@ -15,8 +15,10 @@
15
15
  "dependencies": {
16
16
  "@pulumi/aws": "^5.8.0",
17
17
  "@pulumi/pulumi": "^3.34.0",
18
- "@webiny/cli-plugin-deploy-pulumi": "5.30.0-beta.1",
19
- "@webiny/pulumi": "5.30.0-beta.1"
18
+ "@webiny/cli-plugin-deploy-pulumi": "5.31.0-beta.1",
19
+ "@webiny/pulumi": "5.31.0-beta.1",
20
+ "form-data": "4.0.0",
21
+ "node-fetch": "2.6.7"
20
22
  },
21
23
  "devDependencies": {
22
24
  "@babel/cli": "^7.16.0",
@@ -24,10 +26,10 @@
24
26
  "@babel/preset-env": "^7.16.4",
25
27
  "@babel/preset-typescript": "^7.16.0",
26
28
  "@babel/runtime": "^7.16.3",
27
- "@webiny/api-page-builder": "^5.30.0-beta.1",
28
- "@webiny/aws-layers": "^5.30.0-beta.1",
29
- "@webiny/cli": "^5.30.0-beta.1",
30
- "@webiny/project-utils": "^5.30.0-beta.1",
29
+ "@webiny/api-page-builder": "^5.31.0-beta.1",
30
+ "@webiny/aws-layers": "^5.31.0-beta.1",
31
+ "@webiny/cli": "^5.31.0-beta.1",
32
+ "@webiny/project-utils": "^5.31.0-beta.1",
31
33
  "chalk": "^4.1.0",
32
34
  "lodash": "^4.5.0",
33
35
  "mime": "2.5.2",
@@ -47,5 +49,5 @@
47
49
  ]
48
50
  }
49
51
  },
50
- "gitHead": "d3b1e74ec1077a608fe40dfd3aba237b1b29a458"
52
+ "gitHead": "b29a1cdd4c7cba5af3b9b993a78f4561525a9201"
51
53
  }
@@ -0,0 +1,11 @@
1
+ import S3Client from "aws-sdk/clients/s3";
2
+ interface GetPresignedPostParams {
3
+ bucket: string;
4
+ key: string;
5
+ acl: string;
6
+ checksum: string;
7
+ contentType: string | null;
8
+ cacheControl: string | undefined;
9
+ }
10
+ export declare const getPresignedPost: ({ bucket, key, acl, checksum, cacheControl, contentType }: GetPresignedPostParams) => Promise<S3Client.PresignedPost>;
11
+ export {};
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.getPresignedPost = void 0;
9
+
10
+ var _s = _interopRequireDefault(require("aws-sdk/clients/s3"));
11
+
12
+ const getPresignedPost = async ({
13
+ bucket,
14
+ key,
15
+ acl,
16
+ checksum,
17
+ cacheControl,
18
+ contentType
19
+ }) => {
20
+ const fields = {
21
+ key,
22
+ "X-Amz-Meta-Checksum": checksum,
23
+ acl
24
+ };
25
+
26
+ if (contentType) {
27
+ fields["Content-Type"] = contentType;
28
+ }
29
+
30
+ if (cacheControl) {
31
+ fields["Cache-Control"] = cacheControl;
32
+ }
33
+
34
+ const s3Params = {
35
+ Expires: 20,
36
+ Bucket: bucket,
37
+ Conditions: [["content-length-range", 0, 26214400], {
38
+ acl
39
+ }],
40
+ Fields: fields
41
+ };
42
+ const s3 = new _s.default();
43
+ return s3.createPresignedPost(s3Params);
44
+ };
45
+
46
+ exports.getPresignedPost = getPresignedPost;
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getPresignedPost","bucket","key","acl","checksum","cacheControl","contentType","fields","s3Params","Expires","Bucket","Conditions","Fields","s3","S3Client","createPresignedPost"],"sources":["getPresignedPost.ts"],"sourcesContent":["import S3Client from \"aws-sdk/clients/s3\";\n\ninterface GetPresignedPostParams {\n bucket: string;\n key: string;\n acl: string;\n checksum: string;\n contentType: string | null;\n cacheControl: string | undefined;\n}\n\nexport const getPresignedPost = async ({\n bucket,\n key,\n acl,\n checksum,\n cacheControl,\n contentType\n}: GetPresignedPostParams) => {\n const fields: Record<string, string> = { key, \"X-Amz-Meta-Checksum\": checksum, acl };\n\n if (contentType) {\n fields[\"Content-Type\"] = contentType;\n }\n\n if (cacheControl) {\n fields[\"Cache-Control\"] = cacheControl;\n }\n\n const s3Params = {\n Expires: 20,\n Bucket: bucket,\n Conditions: [[\"content-length-range\", 0, 26214400], { acl }],\n Fields: fields\n };\n\n const s3 = new S3Client();\n\n return s3.createPresignedPost(s3Params);\n};\n"],"mappings":";;;;;;;;;AAAA;;AAWO,MAAMA,gBAAgB,GAAG,OAAO;EACnCC,MADmC;EAEnCC,GAFmC;EAGnCC,GAHmC;EAInCC,QAJmC;EAKnCC,YALmC;EAMnCC;AANmC,CAAP,KAOF;EAC1B,MAAMC,MAA8B,GAAG;IAAEL,GAAF;IAAO,uBAAuBE,QAA9B;IAAwCD;EAAxC,CAAvC;;EAEA,IAAIG,WAAJ,EAAiB;IACbC,MAAM,CAAC,cAAD,CAAN,GAAyBD,WAAzB;EACH;;EAED,IAAID,YAAJ,EAAkB;IACdE,MAAM,CAAC,eAAD,CAAN,GAA0BF,YAA1B;EACH;;EAED,MAAMG,QAAQ,GAAG;IACbC,OAAO,EAAE,EADI;IAEbC,MAAM,EAAET,MAFK;IAGbU,UAAU,EAAE,CAAC,CAAC,sBAAD,EAAyB,CAAzB,EAA4B,QAA5B,CAAD,EAAwC;MAAER;IAAF,CAAxC,CAHC;IAIbS,MAAM,EAAEL;EAJK,CAAjB;EAOA,MAAMM,EAAE,GAAG,IAAIC,UAAJ,EAAX;EAEA,OAAOD,EAAE,CAACE,mBAAH,CAAuBP,QAAvB,CAAP;AACH,CA5BM"}
@@ -41,7 +41,9 @@ const variablesPromise = new Promise(resolve => {
41
41
  // STAGED_ROLLOUTS_VARIANT: app.ctx.variant || "",
42
42
  // Among other things, this determines the amount of information we reveal on runtime errors.
43
43
  // https://www.webiny.com/docs/how-to-guides/environment-variables/#debug-environment-variable
44
- DEBUG: String(process.env.DEBUG)
44
+ DEBUG: String(process.env.DEBUG),
45
+ // This flag means that Lambda was deployed using the new Pulumi Apps architecture.
46
+ PULUMI_APPS: "true"
45
47
  });
46
48
  resolve(Object.assign({}, baseVariables, variablesRegistry));
47
49
  };
@@ -1 +1 @@
1
- {"version":3,"names":["variablesRegistry","sealEnvVariables","variablesPromise","Promise","resolve","baseVariables","Object","keys","process","env","reduce","current","environmentVariableName","startsWithWebiny","startsWith","startsWithWcp","undefined","String","DEBUG","assign","getCommonLambdaEnvVariables","pulumi","output","setCommonLambdaEnvVariables","variables","withCommonLambdaEnvVariables","app","originalProgram","program","resources","addHandler"],"sources":["lambdaEnvVariables.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { PulumiApp } from \"@webiny/pulumi\";\n\ntype EnvVariables = Record<string, string>;\n\nconst variablesRegistry: EnvVariables = {};\n\nexport let sealEnvVariables: () => void;\n\nconst variablesPromise = new Promise<EnvVariables>(resolve => {\n sealEnvVariables = () => {\n // Apart from a couple of basic environment variables like STAGED_ROLLOUTS_VARIANT and DEBUG,\n // we also take into consideration variables that have `WEBINY_` and `WCP_` prefix in their names.\n const baseVariables = Object.keys(process.env).reduce<EnvVariables>(\n (current, environmentVariableName) => {\n const startsWithWebiny = environmentVariableName.startsWith(\"WEBINY_\");\n const startsWithWcp = environmentVariableName.startsWith(\"WCP_\");\n\n if (\n (startsWithWebiny || startsWithWcp) &&\n process.env[environmentVariableName] !== undefined\n ) {\n current[environmentVariableName] = String(process.env[environmentVariableName]);\n }\n return current;\n },\n {\n // STAGED_ROLLOUTS_VARIANT: app.ctx.variant || \"\",\n // Among other things, this determines the amount of information we reveal on runtime errors.\n // https://www.webiny.com/docs/how-to-guides/environment-variables/#debug-environment-variable\n DEBUG: String(process.env.DEBUG)\n }\n );\n\n resolve(Object.assign({}, baseVariables, variablesRegistry));\n };\n});\n\nexport function getCommonLambdaEnvVariables(): pulumi.Output<EnvVariables> {\n return pulumi.output(variablesPromise);\n}\n\nfunction setCommonLambdaEnvVariables(variables: EnvVariables) {\n Object.assign(variablesRegistry, variables);\n}\n\nexport interface SetCommonLambdaEnvVariables {\n (variables: EnvVariables): void;\n}\n\nexport interface WithCommonLambdaEnvVariables {\n /**\n * Set ENV variables that wil be assigned to all Lambda functions in the current Pulumi app.\n */\n setCommonLambdaEnvVariables: SetCommonLambdaEnvVariables;\n}\n\n/**\n * Augment the given app with `setCommonLambdaEnvVariables` functionality.\n * @param {PulumiApp} app\n */\nexport function withCommonLambdaEnvVariables<T extends PulumiApp>(\n app: T\n): T & WithCommonLambdaEnvVariables {\n const originalProgram = app.program;\n app.program = async app => {\n // We must first execute the original program, and pass in the augmented app.\n const resources = await originalProgram({\n ...app,\n // @ts-ignore because currently, we don't have a way of passing in a custom app type.\n setCommonLambdaEnvVariables\n });\n\n // Once the program is executed, we need to seal the variables (this will resolve the pulumi.output promise).\n app.addHandler(() => {\n sealEnvVariables();\n });\n\n return resources;\n };\n\n // Augment the original PulumiApp.\n return {\n ...app,\n setCommonLambdaEnvVariables\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAAA;;;;;;;;;;AAKA,MAAMA,iBAA+B,GAAG,EAAxC;AAEO,IAAIC,gBAAJ;;AAEP,MAAMC,gBAAgB,GAAG,IAAIC,OAAJ,CAA0BC,OAAO,IAAI;EAC1D,2BAAAH,gBAAgB,GAAG,MAAM;IACrB;IACA;IACA,MAAMI,aAAa,GAAGC,MAAM,CAACC,IAAP,CAAYC,OAAO,CAACC,GAApB,EAAyBC,MAAzB,CAClB,CAACC,OAAD,EAAUC,uBAAV,KAAsC;MAClC,MAAMC,gBAAgB,GAAGD,uBAAuB,CAACE,UAAxB,CAAmC,SAAnC,CAAzB;MACA,MAAMC,aAAa,GAAGH,uBAAuB,CAACE,UAAxB,CAAmC,MAAnC,CAAtB;;MAEA,IACI,CAACD,gBAAgB,IAAIE,aAArB,KACAP,OAAO,CAACC,GAAR,CAAYG,uBAAZ,MAAyCI,SAF7C,EAGE;QACEL,OAAO,CAACC,uBAAD,CAAP,GAAmCK,MAAM,CAACT,OAAO,CAACC,GAAR,CAAYG,uBAAZ,CAAD,CAAzC;MACH;;MACD,OAAOD,OAAP;IACH,CAZiB,EAalB;MACI;MACA;MACA;MACAO,KAAK,EAAED,MAAM,CAACT,OAAO,CAACC,GAAR,CAAYS,KAAb;IAJjB,CAbkB,CAAtB;IAqBAd,OAAO,CAACE,MAAM,CAACa,MAAP,CAAc,EAAd,EAAkBd,aAAlB,EAAiCL,iBAAjC,CAAD,CAAP;EACH,CAzBD;AA0BH,CA3BwB,CAAzB;;AA6BO,SAASoB,2BAAT,GAAoE;EACvE,OAAOC,MAAM,CAACC,MAAP,CAAcpB,gBAAd,CAAP;AACH;;AAED,SAASqB,2BAAT,CAAqCC,SAArC,EAA8D;EAC1DlB,MAAM,CAACa,MAAP,CAAcnB,iBAAd,EAAiCwB,SAAjC;AACH;;AAaD;AACA;AACA;AACA;AACO,SAASC,4BAAT,CACHC,GADG,EAE6B;EAChC,MAAMC,eAAe,GAAGD,GAAG,CAACE,OAA5B;;EACAF,GAAG,CAACE,OAAJ,GAAc,MAAMF,GAAN,IAAa;IACvB;IACA,MAAMG,SAAS,GAAG,MAAMF,eAAe,iCAChCD,GADgC;MAEnC;MACAH;IAHmC,GAAvC,CAFuB,CAQvB;;IACAG,GAAG,CAACI,UAAJ,CAAe,MAAM;MACjB7B,gBAAgB;IACnB,CAFD;IAIA,OAAO4B,SAAP;EACH,CAdD,CAFgC,CAkBhC;;;EACA,uCACOH,GADP;IAEIH;EAFJ;AAIH"}
1
+ {"version":3,"names":["variablesRegistry","sealEnvVariables","variablesPromise","Promise","resolve","baseVariables","Object","keys","process","env","reduce","current","environmentVariableName","startsWithWebiny","startsWith","startsWithWcp","undefined","String","DEBUG","PULUMI_APPS","assign","getCommonLambdaEnvVariables","pulumi","output","setCommonLambdaEnvVariables","variables","withCommonLambdaEnvVariables","app","originalProgram","program","resources","addHandler"],"sources":["lambdaEnvVariables.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { PulumiApp } from \"@webiny/pulumi\";\n\ntype EnvVariables = Record<string, string>;\n\nconst variablesRegistry: EnvVariables = {};\n\nexport let sealEnvVariables: () => void;\n\nconst variablesPromise = new Promise<EnvVariables>(resolve => {\n sealEnvVariables = () => {\n // Apart from a couple of basic environment variables like STAGED_ROLLOUTS_VARIANT and DEBUG,\n // we also take into consideration variables that have `WEBINY_` and `WCP_` prefix in their names.\n const baseVariables = Object.keys(process.env).reduce<EnvVariables>(\n (current, environmentVariableName) => {\n const startsWithWebiny = environmentVariableName.startsWith(\"WEBINY_\");\n const startsWithWcp = environmentVariableName.startsWith(\"WCP_\");\n\n if (\n (startsWithWebiny || startsWithWcp) &&\n process.env[environmentVariableName] !== undefined\n ) {\n current[environmentVariableName] = String(process.env[environmentVariableName]);\n }\n return current;\n },\n {\n // STAGED_ROLLOUTS_VARIANT: app.ctx.variant || \"\",\n // Among other things, this determines the amount of information we reveal on runtime errors.\n // https://www.webiny.com/docs/how-to-guides/environment-variables/#debug-environment-variable\n DEBUG: String(process.env.DEBUG),\n // This flag means that Lambda was deployed using the new Pulumi Apps architecture.\n PULUMI_APPS: \"true\"\n }\n );\n\n resolve(Object.assign({}, baseVariables, variablesRegistry));\n };\n});\n\nexport function getCommonLambdaEnvVariables(): pulumi.Output<EnvVariables> {\n return pulumi.output(variablesPromise);\n}\n\nfunction setCommonLambdaEnvVariables(variables: EnvVariables) {\n Object.assign(variablesRegistry, variables);\n}\n\nexport interface SetCommonLambdaEnvVariables {\n (variables: EnvVariables): void;\n}\n\nexport interface WithCommonLambdaEnvVariables {\n /**\n * Set ENV variables that wil be assigned to all Lambda functions in the current Pulumi app.\n */\n setCommonLambdaEnvVariables: SetCommonLambdaEnvVariables;\n}\n\n/**\n * Augment the given app with `setCommonLambdaEnvVariables` functionality.\n * @param {PulumiApp} app\n */\nexport function withCommonLambdaEnvVariables<T extends PulumiApp>(\n app: T\n): T & WithCommonLambdaEnvVariables {\n const originalProgram = app.program;\n app.program = async app => {\n // We must first execute the original program, and pass in the augmented app.\n const resources = await originalProgram({\n ...app,\n // @ts-ignore because currently, we don't have a way of passing in a custom app type.\n setCommonLambdaEnvVariables\n });\n\n // Once the program is executed, we need to seal the variables (this will resolve the pulumi.output promise).\n app.addHandler(() => {\n sealEnvVariables();\n });\n\n return resources;\n };\n\n // Augment the original PulumiApp.\n return {\n ...app,\n setCommonLambdaEnvVariables\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAAA;;;;;;;;;;AAKA,MAAMA,iBAA+B,GAAG,EAAxC;AAEO,IAAIC,gBAAJ;;AAEP,MAAMC,gBAAgB,GAAG,IAAIC,OAAJ,CAA0BC,OAAO,IAAI;EAC1D,2BAAAH,gBAAgB,GAAG,MAAM;IACrB;IACA;IACA,MAAMI,aAAa,GAAGC,MAAM,CAACC,IAAP,CAAYC,OAAO,CAACC,GAApB,EAAyBC,MAAzB,CAClB,CAACC,OAAD,EAAUC,uBAAV,KAAsC;MAClC,MAAMC,gBAAgB,GAAGD,uBAAuB,CAACE,UAAxB,CAAmC,SAAnC,CAAzB;MACA,MAAMC,aAAa,GAAGH,uBAAuB,CAACE,UAAxB,CAAmC,MAAnC,CAAtB;;MAEA,IACI,CAACD,gBAAgB,IAAIE,aAArB,KACAP,OAAO,CAACC,GAAR,CAAYG,uBAAZ,MAAyCI,SAF7C,EAGE;QACEL,OAAO,CAACC,uBAAD,CAAP,GAAmCK,MAAM,CAACT,OAAO,CAACC,GAAR,CAAYG,uBAAZ,CAAD,CAAzC;MACH;;MACD,OAAOD,OAAP;IACH,CAZiB,EAalB;MACI;MACA;MACA;MACAO,KAAK,EAAED,MAAM,CAACT,OAAO,CAACC,GAAR,CAAYS,KAAb,CAJjB;MAKI;MACAC,WAAW,EAAE;IANjB,CAbkB,CAAtB;IAuBAf,OAAO,CAACE,MAAM,CAACc,MAAP,CAAc,EAAd,EAAkBf,aAAlB,EAAiCL,iBAAjC,CAAD,CAAP;EACH,CA3BD;AA4BH,CA7BwB,CAAzB;;AA+BO,SAASqB,2BAAT,GAAoE;EACvE,OAAOC,MAAM,CAACC,MAAP,CAAcrB,gBAAd,CAAP;AACH;;AAED,SAASsB,2BAAT,CAAqCC,SAArC,EAA8D;EAC1DnB,MAAM,CAACc,MAAP,CAAcpB,iBAAd,EAAiCyB,SAAjC;AACH;;AAaD;AACA;AACA;AACA;AACO,SAASC,4BAAT,CACHC,GADG,EAE6B;EAChC,MAAMC,eAAe,GAAGD,GAAG,CAACE,OAA5B;;EACAF,GAAG,CAACE,OAAJ,GAAc,MAAMF,GAAN,IAAa;IACvB;IACA,MAAMG,SAAS,GAAG,MAAMF,eAAe,iCAChCD,GADgC;MAEnC;MACAH;IAHmC,GAAvC,CAFuB,CAQvB;;IACAG,GAAG,CAACI,UAAJ,CAAe,MAAM;MACjB9B,gBAAgB;IACnB,CAFD;IAIA,OAAO6B,SAAP;EACH,CAdD,CAFgC,CAkBhC;;;EACA,uCACOH,GADP;IAEIH;EAFJ;AAIH"}
@@ -1,14 +1,15 @@
1
- import { BucketName, ObjectCannedACL, CacheControl } from "aws-sdk/clients/s3";
1
+ import { BucketName, CacheControl } from "aws-sdk/clients/s3";
2
2
  export interface Paths {
3
3
  full: string;
4
4
  relative: string;
5
5
  }
6
- declare type CacheControls = Array<{
6
+ export declare type CacheControls = Array<{
7
7
  pattern: RegExp;
8
8
  value: CacheControl;
9
9
  }>;
10
10
  export interface UploadFolderToS3Params {
11
11
  path: string;
12
+ acl: string;
12
13
  onFileUploadSuccess: (params: {
13
14
  paths: Paths;
14
15
  }) => void;
@@ -20,8 +21,6 @@ export interface UploadFolderToS3Params {
20
21
  paths: Paths;
21
22
  }) => void;
22
23
  bucket: BucketName;
23
- acl?: ObjectCannedACL;
24
24
  cacheControl?: CacheControl | CacheControls;
25
25
  }
26
26
  export declare const uploadFolderToS3: ({ path: root, bucket, onFileUploadSuccess, onFileUploadError, onFileUploadSkip, acl, cacheControl }: UploadFolderToS3Params) => Promise<void>;
27
- export {};