1 | /**
|
2 | * This plugin adds the following libraries to the requirements:
|
3 | *
|
4 | * - GraphQL: npm install --save apollo-client apollo-cache-inmemory apollo-link-http graphql-tag graphql
|
5 | * - React Apollo: npm install --save react-apollo
|
6 | * //- isomorphic-fetch: npm install --save isomorphic-fetch es6-promise
|
7 | * - AWS SDK: npm install --save aws-sdk
|
8 | *
|
9 | *
|
10 | */
|
11 |
|
12 |
|
13 |
|
14 | import { IConfigParseResult } from '../libs/config-parse-result';
|
15 | import {
|
16 | IPlugin, forwardChildWebpackConfigs, forwardChildPostBuilds, forwardChildIamRoleStatements
|
17 | } from '../libs/plugin';
|
18 | import { isDataLayer } from './datalayer-component'
|
19 | import * as deepmerge from 'deepmerge';
|
20 | import {PARSER_MODES} from "../libs/parser";
|
21 |
|
22 | /**
|
23 | * Parameters that apply to the whole Plugin, passed by other plugins
|
24 | *
|
25 | * The DataLayer is supported by:
|
26 | * - `IsomorphicApp`
|
27 | */
|
28 | export interface IDataLayerPlugin {
|
29 |
|
30 | /**
|
31 | * path to a directory where we put the final bundles
|
32 | */
|
33 | buildPath: string,
|
34 |
|
35 | /**
|
36 | * path to the main config file
|
37 | */
|
38 | configFilePath: string,
|
39 | }
|
40 |
|
41 | /**
|
42 | * The Data
|
43 | *
|
44 | * @param props
|
45 | */
|
46 | export const DataLayerPlugin = (props: IDataLayerPlugin): IPlugin => {
|
47 | const path = require('path');
|
48 |
|
49 | const result: IPlugin = {
|
50 | applies: (component):boolean => {
|
51 |
|
52 | return isDataLayer(component);
|
53 | },
|
54 |
|
55 | // convert the component into configuration parts
|
56 | // while the component is of Type `any`, its props must be of type `IDataLayerArgs` | `IDataLayerProps`
|
57 | process: (
|
58 | component: any,
|
59 | childConfigs: Array<IConfigParseResult>,
|
60 | infrastructureMode: string | undefined
|
61 | ):IConfigParseResult => {
|
62 |
|
63 | // the datalayer has a (query) server application
|
64 | /*const queryWebPack = (args) => require("../../../infrastructure-scripts/dist/infra-comp-utils/webpack-libs").complementWebpackConfig(
|
65 | require("../../../infrastructure-scripts/dist/infra-comp-utils/webpack-libs").createServerWebpackConfig(
|
66 | "./"+path.join("node_modules", "infrastructure-components", "dist" , "assets", "data-layer.js"), //entryPath: string,
|
67 | path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), props.buildPath), //use the buildpath from the parent plugin
|
68 | component.id, // name of the server
|
69 |
|
70 | // aliasesDict
|
71 | {
|
72 | __CONFIG_FILE_PATH__: require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").pathToConfigFile(props.configFilePath), // replace the IsoConfig-Placeholder with the real path to the main-config-bundle
|
73 |
|
74 |
|
75 | },
|
76 |
|
77 | // replacementsDict
|
78 | {
|
79 | __DATALAYER_ID__: `"${component.id}"`,
|
80 |
|
81 | /*,
|
82 | __ASSETS_PATH__: `"${component.assetsPath}"`,
|
83 | __RESOLVED_ASSETS_PATH__: `"${resolveAssetsPath(
|
84 | component.buildPath,
|
85 | serverName,
|
86 | component.assetsPath )
|
87 | }"`* /
|
88 | }
|
89 | )
|
90 | );*/
|
91 |
|
92 | /**
|
93 | * setup a database and a handler
|
94 | */
|
95 | const dataLayerConfig = {
|
96 | /*functions: {
|
97 |
|
98 | /*
|
99 | query: {
|
100 | // index.default refers to the default export of the file, points to the output of the queryWebpack-bundle
|
101 | handler: path.join(props.buildPath, component.id, `${component.id}.default`),
|
102 | role: "DataLayerLambdaRole",
|
103 | events: [
|
104 | {
|
105 | http: {
|
106 | //this path must match the path specified in the environment below
|
107 | path: "query",
|
108 |
|
109 | // the Apollo Api usually works via POST, mutations always use POST
|
110 | method: "POST",
|
111 |
|
112 | cors: "true"
|
113 | }
|
114 | },
|
115 | ]
|
116 | }
|
117 |
|
118 | },*/
|
119 |
|
120 | plugins: ["serverless-dynamodb-local"],
|
121 |
|
122 | /* see: https://www.npmjs.com/package/serverless-dynamodb-local */
|
123 | custom: {
|
124 | "dynamodb": {
|
125 | stages: ["${self:provider.stage}", "dev"],
|
126 | start: {
|
127 | port: 8000,
|
128 | //inMemory: "true",
|
129 | /*dbPath: path.join(
|
130 | require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(),".s3"
|
131 | ),*/
|
132 | heapInitial: "200m",
|
133 | heapMax: "1g",
|
134 | migrate: "true",
|
135 | //seed: "true",
|
136 | convertEmptyValues: "true",
|
137 | //cors: ['localhost:3000', 'localhost:3001']
|
138 | },
|
139 | }
|
140 | },
|
141 |
|
142 | provider: {
|
143 | environment: {
|
144 | // set the table name in an environment variable
|
145 | TABLE_NAME: "${self:service}-${self:provider.stage, env:STAGE, 'dev'}-data-layer",
|
146 |
|
147 | // must match the http-path from the function-event
|
148 | GRAPHQL_PATH: "query"
|
149 | }
|
150 | },
|
151 |
|
152 | resources: {
|
153 | Resources: {
|
154 | ApplicationDynamoDBTable: {
|
155 | Type: "AWS::DynamoDB::Table",
|
156 | Properties: {
|
157 | TableName: "${self:service}-${self:provider.stage, env:STAGE, 'dev'}-data-layer",
|
158 | BillingMode: "PAY_PER_REQUEST",
|
159 | AttributeDefinitions: [
|
160 | {
|
161 | AttributeName: "pk",
|
162 | AttributeType: "S"
|
163 | }, {
|
164 | AttributeName: "sk",
|
165 | AttributeType: "S"
|
166 | }
|
167 | ],
|
168 | KeySchema: [
|
169 | {
|
170 | AttributeName: "pk",
|
171 | KeyType: "HASH"
|
172 | }, {
|
173 | AttributeName: "sk",
|
174 | KeyType: "RANGE"
|
175 | }
|
176 | ],
|
177 | GlobalSecondaryIndexes: [
|
178 | {
|
179 | IndexName: "reverse",
|
180 | KeySchema: [
|
181 | {
|
182 | AttributeName: "sk",
|
183 | KeyType: "HASH"
|
184 | }, {
|
185 | AttributeName: "pk",
|
186 | KeyType: "RANGE"
|
187 | }
|
188 | ],
|
189 | Projection: {
|
190 | ProjectionType: "ALL"
|
191 | }
|
192 |
|
193 | }
|
194 | ]
|
195 | }
|
196 | }
|
197 | }
|
198 | }
|
199 | };
|
200 |
|
201 |
|
202 | const iamRoleStatements = [
|
203 | {
|
204 | Effect: "Allow",
|
205 | Action: [
|
206 | "dynamodb:GetItem",
|
207 | "dynamodb:UpdateItem",
|
208 | "dynamodb:DeleteItem",
|
209 | "dynamodb:PutItem",
|
210 | "dynamodb:Scan",
|
211 | "dynamodb:Query"
|
212 | ],
|
213 | Resource: [
|
214 | '"arn:aws:dynamodb:${self:provider.region}:*:table/${self:service}-${self:provider.stage, env:STAGE, \'dev\'}-data-layer"',
|
215 | '"arn:aws:dynamodb:${self:provider.region}:*:table/${self:service}-${self:provider.stage, env:STAGE, \'dev\'}-data-layer/*"'
|
216 | ]
|
217 | }
|
218 | ].concat(forwardChildIamRoleStatements(childConfigs));
|
219 |
|
220 |
|
221 | //console.log("datalayer iamStatements: ", iamRoleStatements);
|
222 |
|
223 |
|
224 | return {
|
225 | slsConfigs: deepmerge.all([
|
226 | dataLayerConfig
|
227 | ].concat(childConfigs.map(config => config.slsConfigs))),
|
228 |
|
229 | // forward the webpacks (of the WebApps) as-is, add the queryApp-Webpack-bundle
|
230 | webpackConfigs: /*[queryWebPack].concat(*/forwardChildWebpackConfigs(childConfigs).map(
|
231 | // complement the args with the datalayer-id
|
232 | fWp => (args) => fWp(Object.assign({ datalayerid : component.id}, args))
|
233 | )/*)*/,
|
234 |
|
235 | postBuilds: forwardChildPostBuilds(childConfigs),
|
236 |
|
237 | iamRoleStatements: iamRoleStatements
|
238 |
|
239 |
|
240 | }
|
241 | }
|
242 | };
|
243 |
|
244 |
|
245 | return result;
|
246 |
|
247 | }; |
\ | No newline at end of file |