UNPKG

13.4 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10var __importStar = (this && this.__importStar) || function (mod) {
11 if (mod && mod.__esModule) return mod;
12 var result = {};
13 if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
14 result["default"] = mod;
15 return result;
16};
17var __importDefault = (this && this.__importDefault) || function (mod) {
18 return (mod && mod.__esModule) ? mod : { "default": mod };
19};
20Object.defineProperty(exports, "__esModule", { value: true });
21/**
22 * This module must not import anything globally not workin in web-mode! if needed, require it within the functions
23 *
24 * NOTE, we Ignore the infrastructure-scripts libraries when bundling, so these can be used ...
25 * We also put fs to empty! If you need other libs, add them to `node: { fs: empty }`
26 */
27const spa_component_1 = require("./spa-component");
28const deepmerge = __importStar(require("deepmerge"));
29const parser_1 = require("../libs/parser");
30const extract_domain_1 = __importDefault(require("extract-domain"));
31/**
32 * A Plugin to detect SinglePage-App-Components
33 * @param props
34 */
35exports.SpaPlugin = (props) => {
36 //console.log("configFilePath: " , props.configFilePath);
37 const result = {
38 // identify Isomorphic-App-Components
39 applies: (component) => {
40 return spa_component_1.isSinglePageApp(component);
41 },
42 // convert the component into configuration parts
43 process: (component, childConfigs, infrastructureMode) => {
44 const path = require('path');
45 const webappBuildPath = path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), props.buildPath);
46 const spaWebPack = require("../../../infrastructure-scripts/dist/infra-comp-utils/webpack-libs")
47 .complementWebpackConfig(require("../../../infrastructure-scripts/dist/infra-comp-utils/webpack-libs")
48 .createClientWebpackConfig("./" + path.join("node_modules", "infrastructure-components", "dist", "assets", "spa.js"), //entryPath: string,
49 path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), props.buildPath), //use the buildpath from the parent plugin
50 component.id, //appName
51 undefined, //assetsPath
52 undefined, // stagePath: TODO take from Environment!
53 {
54 __CONFIG_FILE_PATH__: require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").pathToConfigFile(props.configFilePath),
55 // required of the routed-app
56 "react-router-dom": path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), "node_modules", "react-router-dom"),
57 // required of the data-layer / apollo
58 "react-apollo": path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), "node_modules", "react-apollo"),
59 }, {}), props.parserMode === parser_1.PARSER_MODES.MODE_DEPLOY //isProd
60 );
61 // provide all client configs in a flat list
62 const webpackConfigs = childConfigs.reduce((result, config) => result.concat(config.webpackConfigs), []);
63 const createHtml = () => {
64 //console.log("check for >>copyAssetsPostBuild<<");
65 //if (props.parserMode == PARSER_MODES.MODE_BUILD) {
66 console.log("write the index.html!");
67 require('fs').writeFileSync(path.join(webappBuildPath, component.stackName, "index.html"), `<!DOCTYPE html>
68<html lang="en">
69 <head>
70 <meta charset="utf-8" />
71 <title>${component.stackName}</title>
72 <style>
73 body {
74 display: block;
75 margin: 0px;
76 }
77 </style>
78 </head>
79 <body>
80 <noscript>You need to enable JavaScript to run this app.</noscript>
81 <div id="root"></div>
82 <script src="${component.stackName}.bundle.js"></script>
83 </body>
84</html>`);
85 };
86 // check whether we already created the domain of this environment
87 const deployedDomain = process.env[`DOMAIN_${props.stage}`] !== undefined;
88 const domain = childConfigs.map(config => config.domain).reduce((result, domain) => result !== undefined ? result : domain, undefined);
89 const certArn = childConfigs.map(config => config.certArn).reduce((result, certArn) => result !== undefined ? result : certArn, undefined);
90 const invalidateCloudFrontCache = () => {
91 if (deployedDomain && props.parserMode === parser_1.PARSER_MODES.MODE_DEPLOY) {
92 require("../../../infrastructure-scripts/dist/infra-comp-utils/sls-libs").invalidateCloudFrontCache(domain);
93 }
94 };
95 const hostedZoneName = domain !== undefined ? extract_domain_1.default(domain.toString()) : {};
96 /** post build function to write to the .env file that the domain has been deployed */
97 const writeDomainEnv = () => {
98 //console.log("check for >>writeDomainEnv<<");
99 // we only write to the .env file when we are in domain mode, i.e. this script creates the domain
100 // and we did not yet deployed the domain previously
101 if (!deployedDomain && props.parserMode === parser_1.PARSER_MODES.MODE_DOMAIN) {
102 require('fs').appendFileSync(path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), ".env"), `\nDOMAIN_${props.stage}=TRUE`);
103 }
104 };
105 /*
106 const postDeploy = async () => {
107 //console.log("check for >>showStaticPageName<<");
108 if (props.parserMode === PARSER_MODES.MODE_DEPLOY) {
109
110
111 await require('../libs/scripts-libs').fetchData("deploy", {
112 proj: component.stackName,
113 envi: props.stage,
114 domain: domain,
115 endp: `http://${component.stackName}-${props.stage}.s3-website-${component.region}.amazonaws.com`
116 });
117
118 console.log(`Your SinglePageApp is now available at: http://${component.stackName}-${props.stage}.s3-website-${component.region}.amazonaws.com`);
119 }
120
121
122 };*/
123 function deployWithDomain() {
124 return __awaiter(this, void 0, void 0, function* () {
125 // start the sls-config
126 if (props.parserMode === parser_1.PARSER_MODES.MODE_DOMAIN) {
127 yield require("../../../infrastructure-scripts/dist/infra-comp-utils/sls-libs").deploySls(component.stackName);
128 }
129 });
130 }
131 /**
132 * ONLY add the domain config if we are in domain mode!
133 * TODO once the domain has been added, we need to add this with every deployment
134 */
135 const domainConfig = (props.parserMode === parser_1.PARSER_MODES.MODE_DOMAIN || deployedDomain) &&
136 domain !== undefined && certArn !== undefined ? {
137 // required of the SPA-domain-alias
138 provider: {
139 customDomainName: domain,
140 hostedZoneName: hostedZoneName,
141 certArn: certArn
142 },
143 resources: {
144 Resources: {
145 WebAppCloudFrontDistribution: {
146 Type: "AWS::CloudFront::Distribution",
147 Properties: {
148 DistributionConfig: {
149 Origins: [
150 {
151 DomainName: "${self:provider.staticBucket}.s3.amazonaws.com",
152 Id: component.stackName,
153 CustomOriginConfig: {
154 HTTPPort: 80,
155 HTTPSPort: 443,
156 OriginProtocolPolicy: "https-only",
157 }
158 }
159 ],
160 Enabled: "'true'",
161 DefaultRootObject: "index.html",
162 CustomErrorResponses: [{
163 ErrorCode: 404,
164 ResponseCode: 200,
165 ResponsePagePath: "/index.html"
166 }],
167 DefaultCacheBehavior: {
168 AllowedMethods: [
169 "DELETE",
170 "GET",
171 "HEAD",
172 "OPTIONS",
173 "PATCH",
174 "POST",
175 "PUT"
176 ],
177 TargetOriginId: component.stackName,
178 ForwardedValues: {
179 QueryString: "'false'",
180 Cookies: {
181 Forward: "none"
182 }
183 },
184 ViewerProtocolPolicy: "redirect-to-https"
185 },
186 ViewerCertificate: {
187 AcmCertificateArn: "${self:provider.certArn}",
188 SslSupportMethod: "sni-only",
189 },
190 Aliases: ["${self:provider.customDomainName}"]
191 }
192 }
193 },
194 DnsRecord: {
195 Type: "AWS::Route53::RecordSet",
196 Properties: {
197 AliasTarget: {
198 DNSName: "!GetAtt WebAppCloudFrontDistribution.DomainName",
199 HostedZoneId: "Z2FDTNDATAQYW2"
200 },
201 HostedZoneName: "${self:provider.hostedZoneName}.",
202 Name: "${self:provider.customDomainName}.",
203 Type: "'A'"
204 }
205 }
206 },
207 Outputs: {
208 WebAppCloudFrontDistributionOutput: {
209 Value: {
210 "Fn::GetAtt": "[ WebAppCloudFrontDistribution, DomainName ]"
211 }
212 }
213 }
214 }
215 } : {};
216 return {
217 stackType: "SPA",
218 slsConfigs: deepmerge.all([
219 require("../../../infrastructure-scripts/dist/infra-comp-utils/sls-libs").toSpaSlsConfig(component.stackName, component.buildPath, component.region, domain),
220 domainConfig,
221 ...childConfigs.map(config => config.slsConfigs)
222 ]),
223 // add the server config
224 webpackConfigs: webpackConfigs.concat([spaWebPack]),
225 postBuilds: childConfigs.reduce((result, config) => result.concat(config.postBuilds), [createHtml, writeDomainEnv, deployWithDomain, invalidateCloudFrontCache /*, postDeploy*/]),
226 iamRoleStatements: [],
227 environments: childConfigs.reduce((result, config) => (result !== undefined ? result : []).concat(config.environments !== undefined ? config.environments : []), []),
228 stackName: component.stackName,
229 assetsPath: undefined,
230 buildPath: component.buildPath,
231 region: component.region,
232 domain: domain,
233 certArn: certArn,
234 // start the sls-stack offline does not work and does make sense either, we can use the hot-dev-mode
235 supportOfflineStart: false,
236 supportCreateDomain: true
237 };
238 }
239 };
240 return result;
241};
242//# sourceMappingURL=spa-plugin.js.map
\No newline at end of file