@voxgig/build 3.1.0 → 4.1.0
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.
- package/build.ts +47 -480
- package/dist/build.d.ts +16 -3
- package/dist/build.js +39 -367
- package/dist/build.js.map +1 -1
- package/dist/env/lambda/generate.d.ts +13 -0
- package/dist/env/lambda/generate.js +86 -0
- package/dist/env/lambda/generate.js.map +1 -0
- package/dist/env/lambda/res_yml.d.ts +7 -0
- package/dist/env/lambda/res_yml.js +91 -0
- package/dist/env/lambda/res_yml.js.map +1 -0
- package/dist/env/lambda/srv_handler.d.ts +10 -0
- package/dist/env/lambda/srv_handler.js +101 -0
- package/dist/env/lambda/srv_handler.js.map +1 -0
- package/dist/env/lambda/srv_yml.d.ts +5 -0
- package/dist/env/lambda/srv_yml.js +165 -0
- package/dist/env/lambda/srv_yml.js.map +1 -0
- package/dist/shape/conf.d.ts +2 -2
- package/dist/shape/ent.d.ts +1 -1
- package/dist/shape/msg.d.ts +1 -1
- package/env/lambda/generate.ts +105 -0
- package/env/lambda/res_yml.ts +140 -0
- package/env/lambda/srv_handler.ts +132 -0
- package/env/lambda/srv_yml.ts +201 -0
- package/package.json +17 -7
- package/tm/lambda/res.queue.yml.frag +6 -0
- package/tm/lambda/res.role.yml.frag +35 -0
- package/tm/lambda/srv.yml.frag +6 -0
- package/tm/lambda/srv_handler.js.frag +17 -0
- package/tm/lambda/srv_handler.ts.frag +17 -0
package/build.ts
CHANGED
|
@@ -1,496 +1,63 @@
|
|
|
1
|
-
/* Copyright © 2022 Voxgig Ltd, MIT License. */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/* Copyright © 2022-2026 Voxgig Ltd, MIT License. */
|
|
2
|
+
|
|
3
|
+
// EnvLambda: generation of the Lambda deployment templates, built on the
|
|
4
|
+
// jostraca templating library. The templates live in env/lambda/, one file
|
|
5
|
+
// per output for convenience:
|
|
6
|
+
//
|
|
7
|
+
// env/lambda/srv_yml.ts gen srv.yml (Serverless function defs)
|
|
8
|
+
// env/lambda/srv_handler.ts handler source (one per lambda service)
|
|
9
|
+
// env/lambda/res_yml.ts gen res.yml (queues, dynamo, IAM role)
|
|
10
|
+
//
|
|
11
|
+
// The output is byte-identical to the pre-jostraca (<= 3.1.0) generator;
|
|
12
|
+
// test/fixture pins this. All generators are async (jostraca generation is
|
|
13
|
+
// async); existing callers that did not await still work, as the writes
|
|
14
|
+
// complete before the process exits.
|
|
15
|
+
|
|
16
|
+
import { srv_yml } from './env/lambda/srv_yml'
|
|
17
|
+
import { srv_handler } from './env/lambda/srv_handler'
|
|
18
|
+
import { resources_yml } from './env/lambda/res_yml'
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
generate, empty, TM,
|
|
22
|
+
loadFragment, renderFragment, listFragments, PKG_TM,
|
|
23
|
+
} from './env/lambda/generate'
|
|
7
24
|
|
|
8
25
|
import { MsgMetaShape } from './shape/msg'
|
|
9
26
|
import { CoreConfShape, CloudConfShape } from './shape/conf'
|
|
10
|
-
|
|
11
27
|
import { res_dynamo_yml } from './yml/res_dynamo_yml'
|
|
12
28
|
|
|
13
29
|
|
|
14
|
-
// console.log('BUILD 1')
|
|
15
|
-
|
|
16
30
|
const EnvLambda = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}) => {
|
|
21
|
-
|
|
22
|
-
const core = CoreConfShape(model.main.conf.core)
|
|
23
|
-
|
|
24
|
-
let appname = core.name
|
|
25
|
-
let AppName = camelify(appname)
|
|
26
|
-
|
|
27
|
-
let srv_yml_path = Path.join(spec.folder, 'srv.yml')
|
|
28
|
-
|
|
29
|
-
let srv_yml_prefix_path = Path.join(spec.folder, 'srv.prefix.yml')
|
|
30
|
-
let srv_yml_suffix_path = Path.join(spec.folder, 'srv.suffix.yml')
|
|
31
|
-
|
|
32
|
-
let prefixContent = Fs.existsSync(srv_yml_prefix_path) ?
|
|
33
|
-
Fs.readFileSync(srv_yml_prefix_path) : ''
|
|
34
|
-
let suffixContent = Fs.existsSync(srv_yml_suffix_path) ?
|
|
35
|
-
Fs.readFileSync(srv_yml_suffix_path) : ''
|
|
36
|
-
|
|
37
|
-
let content =
|
|
38
|
-
|
|
39
|
-
prefixContent +
|
|
40
|
-
Object
|
|
41
|
-
.entries(model.main.srv)
|
|
42
|
-
.filter((entry: any) => entry[1].env?.lambda?.active)
|
|
43
|
-
.map((entry: any) => {
|
|
44
|
-
const name = entry[0]
|
|
45
|
-
const srv = entry[1]
|
|
46
|
-
|
|
47
|
-
const lambda = srv.env.lambda
|
|
48
|
-
const handler = lambda.handler
|
|
49
|
-
|
|
50
|
-
// NOTE: gen.custom convention: allows for complete overwrite
|
|
51
|
-
// as a get-out-of-jail
|
|
52
|
-
if (srv.gen?.custom?.lambda?.srv_yml) {
|
|
53
|
-
return srv.gen.custom.lambda.srv_yml
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// TODO: this should be a JSON structure exported as YAML
|
|
57
|
-
let srvyml = `${name}:
|
|
58
|
-
handler: ${handler.path.prefix}${name}${handler.path.suffix}
|
|
59
|
-
role: Basic${AppName}LambdaRole
|
|
60
|
-
timeout: ${lambda.timeout}
|
|
61
|
-
memorySize: ${lambda.memory || 1024}
|
|
62
|
-
`
|
|
63
|
-
const web = srv.api.web
|
|
64
|
-
|
|
65
|
-
let events = ''
|
|
66
|
-
|
|
67
|
-
let onEvents = srv.on
|
|
68
|
-
|
|
69
|
-
if (onEvents) {
|
|
70
|
-
Object.entries(onEvents).forEach((entry: any[]) => {
|
|
71
|
-
// let name = entry[0]
|
|
72
|
-
let spec = entry[1]
|
|
73
|
-
|
|
74
|
-
if ('aws' === spec.provider) {
|
|
75
|
-
spec.events.forEach((ev: any) => {
|
|
76
|
-
if ('s3' === ev.source) {
|
|
77
|
-
events += TM(`
|
|
78
|
-
- s3:
|
|
79
|
-
bucket: ${ev.bucket}
|
|
80
|
-
event: ${ev.event}
|
|
81
|
-
existing: true
|
|
82
|
-
`)
|
|
83
|
-
if (ev.rules) {
|
|
84
|
-
events += TM(`
|
|
85
|
-
rules:
|
|
86
|
-
`)
|
|
87
|
-
if (ev.rules.prefix) {
|
|
88
|
-
events += TM(`
|
|
89
|
-
- prefix: ${ev.rules.prefix}
|
|
90
|
-
`)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (ev.rules.suffix) {
|
|
94
|
-
events += TM(`
|
|
95
|
-
- suffix: ${ev.rules.suffix}
|
|
96
|
-
`)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
else if ('schedule' === ev.source) {
|
|
101
|
-
let entries =
|
|
102
|
-
'string' === typeof ev.recur ? [ev.recur] : (ev.recur || [])
|
|
103
|
-
let recur = entries.map((entry: string) => {
|
|
104
|
-
let schedule = `
|
|
105
|
-
- schedule:
|
|
106
|
-
rate: ${entry}`
|
|
107
|
-
if (ev.msg) {
|
|
108
|
-
schedule += `
|
|
109
|
-
input:
|
|
110
|
-
msg: ${JSON.stringify(ev.msg)} `
|
|
111
|
-
}
|
|
112
|
-
return schedule
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
events += TM(`
|
|
116
|
-
${recur}
|
|
117
|
-
`)
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
else if ('sqs' === ev.source) {
|
|
121
|
-
events += TM(`
|
|
122
|
-
- sqs:
|
|
123
|
-
arn:
|
|
124
|
-
Fn::GetAtt:
|
|
125
|
-
- ${ev.qrn}
|
|
126
|
-
- Arn
|
|
127
|
-
batchSize: 1
|
|
128
|
-
`)
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
})
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// TODO: move to `on`
|
|
137
|
-
if (web.active) {
|
|
138
|
-
let prefix = web.path.prefix
|
|
139
|
-
let suffix = web.path.suffix
|
|
140
|
-
let area = web.path.area
|
|
141
|
-
let method = web.method
|
|
142
|
-
let corsflag = 'false'
|
|
143
|
-
let corsprops = ''
|
|
144
|
-
|
|
145
|
-
let methods = method.split(',')
|
|
146
|
-
// console.log('METHODS', methods)
|
|
147
|
-
|
|
148
|
-
if (web.cors.active) {
|
|
149
|
-
corsflag = 'true'
|
|
150
|
-
if (web.cors.props && !empty(web.cors.props)) {
|
|
151
|
-
corsflag = ''
|
|
152
|
-
corsprops = Object
|
|
153
|
-
.entries(web.cors.props)
|
|
154
|
-
.reduce(((a: any, nv: any) => (
|
|
155
|
-
a += ` ${nv[0]}: ${nv[1]}\n`
|
|
156
|
-
, a)), '')
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if ('v2' === web.lambda?.gateway) {
|
|
161
|
-
for (let method of methods) {
|
|
162
|
-
events += TM(`
|
|
163
|
-
- httpApi:
|
|
164
|
-
path: "${prefix}${area}${name}${suffix}"
|
|
165
|
-
method: ${method}
|
|
166
|
-
`)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
for (let method of methods) {
|
|
171
|
-
events += TM(`
|
|
172
|
-
- http:
|
|
173
|
-
path: "${prefix}${area}${name}${suffix}"
|
|
174
|
-
method: ${method}
|
|
175
|
-
cors: ${corsflag}
|
|
176
|
-
${corsprops}
|
|
177
|
-
`)
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if ('' !== events) {
|
|
185
|
-
srvyml += TM(`
|
|
186
|
-
events:
|
|
187
|
-
${events}
|
|
188
|
-
`)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return srvyml
|
|
193
|
-
}).join('\n\n\n') +
|
|
194
|
-
suffixContent
|
|
195
|
-
|
|
196
|
-
Fs.writeFileSync(srv_yml_path, content)
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// Only create if does not exist
|
|
201
|
-
srv_handler: (model: any, spec: {
|
|
202
|
-
folder: string
|
|
203
|
-
start?: string
|
|
204
|
-
env?: {
|
|
205
|
-
folder: string
|
|
206
|
-
}
|
|
207
|
-
lang?: string
|
|
208
|
-
}) => {
|
|
209
|
-
let lang = spec.lang || 'js'
|
|
210
|
-
let TS = 'ts' === lang
|
|
211
|
-
|
|
212
|
-
Object
|
|
213
|
-
.entries(model.main.srv)
|
|
214
|
-
.filter((entry: any) => entry[1].env?.lambda)
|
|
215
|
-
.forEach((entry: any) => {
|
|
216
|
-
const name = entry[0]
|
|
217
|
-
const srv = entry[1]
|
|
218
|
-
|
|
219
|
-
if ('custom' === srv.env.lambda.kind) {
|
|
220
|
-
return
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
let srv_handler_path = Path.join(spec.folder, name + '.' + lang)
|
|
224
|
-
|
|
225
|
-
let start = spec.start || 'setup'
|
|
226
|
-
let envFolder = spec.env?.folder || '../../../env/lambda'
|
|
227
|
-
|
|
228
|
-
let handler = 'handler'
|
|
229
|
-
let modify = ''
|
|
230
|
-
|
|
231
|
-
// if (!srv.api.web.active) {
|
|
232
|
-
// if (srv.on && 0 < Object.keys(srv.on).length) {
|
|
233
|
-
// handler = 'eventhandler'
|
|
234
|
-
// modify = `
|
|
235
|
-
// event = {
|
|
236
|
-
// ...event,
|
|
237
|
-
// // TODO: @voxgig/system? util needed to handle this dynamically
|
|
238
|
-
// seneca$: { msg: '${srv.on[Object.keys(srv.on)[0]].events[0].msg}' },
|
|
239
|
-
// }
|
|
240
|
-
// `
|
|
241
|
-
// }
|
|
242
|
-
// }
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
let prepare = ''
|
|
246
|
-
let complete = ''
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
dive(model.main.msg.aim[name], 128).map((entry: any) => {
|
|
250
|
-
let path = ['aim', name, ...entry[0]]
|
|
251
|
-
let msgMeta = MsgMetaShape(entry[1])
|
|
252
|
-
let pin = pinify(path)
|
|
253
|
-
if (msgMeta.transport?.queue?.active) {
|
|
254
|
-
complete += `
|
|
255
|
-
seneca.listen({type:'sqs',pin:'${pin}'})`
|
|
256
|
-
}
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
dive(model.main.srv[name].out, 128).map((entry: any) => {
|
|
261
|
-
let path = entry[0]
|
|
262
|
-
let msgMetaMaybe = get(model.main.msg, path)
|
|
263
|
-
// console.log(name, path, msgMetaMaybe)
|
|
264
|
-
if (msgMetaMaybe?.$) {
|
|
265
|
-
let msgMeta = MsgMetaShape(msgMetaMaybe?.$)
|
|
266
|
-
let pin = pinify(path)
|
|
267
|
-
|
|
268
|
-
if (msgMeta.transport?.queue?.active) {
|
|
269
|
-
complete += `
|
|
270
|
-
seneca.client({type:'sqs',pin:'${pin}'})`
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
let makeGatewayHandler = false
|
|
276
|
-
let onlist = model.main.srv[name].on || {}
|
|
277
|
-
Object.entries(onlist).map((onitem: any) => {
|
|
278
|
-
onitem[1].events.map((event: any) => {
|
|
279
|
-
if ('s3' === event.source) {
|
|
280
|
-
if (!makeGatewayHandler) {
|
|
281
|
-
complete += `
|
|
282
|
-
|
|
283
|
-
const makeGatewayHandler = seneca.export('s3-store/makeGatewayHandler')`
|
|
284
|
-
makeGatewayHandler = true
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
complete += `
|
|
288
|
-
seneca
|
|
289
|
-
.act('sys:gateway,kind:lambda,add:hook,hook:handler', {
|
|
290
|
-
handler: makeGatewayHandler('${event.msg}') })`
|
|
291
|
-
}
|
|
292
|
-
})
|
|
293
|
-
})
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
let content =
|
|
297
|
-
TS ? `import { getSeneca } from '${envFolder}/${start}'`
|
|
298
|
-
:
|
|
299
|
-
`const getSeneca = require('${envFolder}/${start}')`
|
|
300
|
-
|
|
301
|
-
content += `
|
|
302
|
-
|
|
303
|
-
function complete(seneca: any) {${complete}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
exports.handler = async (
|
|
307
|
-
event${TS ? ':any' : ''},
|
|
308
|
-
context${TS ? ':any' : ''}
|
|
309
|
-
) => {
|
|
310
|
-
${modify}
|
|
311
|
-
let seneca = await getSeneca('${name}', complete)
|
|
312
|
-
${prepare}
|
|
313
|
-
let handler = seneca.export('gateway-lambda/${handler}')
|
|
314
|
-
let res = await handler(event, context)
|
|
315
|
-
return res
|
|
31
|
+
srv_yml,
|
|
32
|
+
srv_handler,
|
|
33
|
+
resources_yml,
|
|
316
34
|
}
|
|
317
|
-
`
|
|
318
|
-
|
|
319
|
-
// TODO: make this an option
|
|
320
|
-
//if (!Fs.existsSync(srv_handler_path)) {
|
|
321
|
-
Fs.writeFileSync(srv_handler_path, content)
|
|
322
|
-
})
|
|
323
|
-
},
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
resources_yml: async (model: any, spec: {
|
|
327
|
-
folder: string,
|
|
328
|
-
filename: string
|
|
329
|
-
custom: string,
|
|
330
|
-
}) => {
|
|
331
|
-
|
|
332
|
-
const core = CoreConfShape(model.main.conf.core)
|
|
333
|
-
|
|
334
|
-
const appname = core.name
|
|
335
|
-
const AppName = camelify(appname)
|
|
336
|
-
|
|
337
|
-
const cloud = CloudConfShape(model.main.conf.cloud)
|
|
338
|
-
|
|
339
|
-
const region = cloud.aws.region
|
|
340
|
-
const accountid = cloud.aws.accountid
|
|
341
|
-
|
|
342
|
-
let filename = spec.filename || 'resources.yml'
|
|
343
|
-
let resources_yml_path = Path.join(spec.folder, filename)
|
|
344
|
-
|
|
345
|
-
let resources_yml_prefix_path = Path.join(spec.folder, 'res.prefix.yml')
|
|
346
|
-
let resources_yml_suffix_path = Path.join(spec.folder, 'res.suffix.yml')
|
|
347
|
-
|
|
348
|
-
let prefixContent = Fs.existsSync(resources_yml_prefix_path) ?
|
|
349
|
-
Fs.readFileSync(resources_yml_prefix_path) : ''
|
|
350
|
-
let suffixContent = Fs.existsSync(resources_yml_suffix_path) ?
|
|
351
|
-
Fs.readFileSync(resources_yml_suffix_path) : ''
|
|
352
|
-
|
|
353
|
-
const dynamoResources: { arn: string }[] = []
|
|
354
|
-
|
|
355
|
-
let content =
|
|
356
|
-
`# START
|
|
357
|
-
`
|
|
358
|
-
|
|
359
|
-
content +=
|
|
360
|
-
prefixContent +
|
|
361
|
-
|
|
362
|
-
await res_dynamo_yml(model, { dynamoResources, region, accountid })
|
|
363
|
-
|
|
364
|
-
// content +=
|
|
365
|
-
let queueDefs = dive(model.main.msg, 128).map((entry: any) => {
|
|
366
|
-
let path = entry[0]
|
|
367
|
-
let msgMeta = MsgMetaShape(entry[1])
|
|
368
|
-
|
|
369
|
-
let pathname = path
|
|
370
|
-
.map((p: string) =>
|
|
371
|
-
(p[0] + '').toUpperCase() + p.substring(1))
|
|
372
|
-
.join('')
|
|
373
|
-
|
|
374
|
-
// console.log('MQ', pathname, msgMeta)
|
|
375
|
-
|
|
376
|
-
if (msgMeta.transport?.queue?.active) {
|
|
377
|
-
// console.log('MM', path, msgMeta)
|
|
378
|
-
let queue = msgMeta.transport.queue
|
|
379
|
-
let name = queue.name || pathname
|
|
380
|
-
|
|
381
|
-
// TODO: aontu should do this, but needs recursive child conjuncts
|
|
382
|
-
let stage_suffix =
|
|
383
|
-
(false === queue.stage?.active) ? '' : '-${self:provider.stage,"dev"}'
|
|
384
|
-
|
|
385
|
-
let queue_suffix = (null == queue.suffix || '' == queue.suffix) ? '' :
|
|
386
|
-
'-' + queue.suffix
|
|
387
|
-
|
|
388
|
-
let resname = 'Queue' + name
|
|
389
|
-
|
|
390
|
-
let queueName =
|
|
391
|
-
(queue.prefix || '') +
|
|
392
|
-
path.reduce((s: string, p: string, i: number) =>
|
|
393
|
-
(s += p + (i % 2 ?
|
|
394
|
-
(i == path.length - 1 ? '' : '-') : '_')), '') +
|
|
395
|
-
(queue_suffix || '') +
|
|
396
|
-
(stage_suffix || '')
|
|
397
|
-
|
|
398
|
-
let queueTimeout = queue.timeout || 30
|
|
399
|
-
|
|
400
|
-
return `${resname}:
|
|
401
|
-
Type: "AWS::SQS::Queue"
|
|
402
|
-
Properties:
|
|
403
|
-
QueueName: '${queueName}'
|
|
404
|
-
VisibilityTimeout: ${queueTimeout}
|
|
405
|
-
`
|
|
406
|
-
}
|
|
407
|
-
return ''
|
|
408
|
-
}).filter(n => '' !== n).join('')
|
|
409
|
-
|
|
410
|
-
// console.log('queueDefs', queueDefs)
|
|
411
|
-
|
|
412
|
-
content += '\n\n' + queueDefs
|
|
413
|
-
|
|
414
|
-
let customLambdaPolicyStatementPath =
|
|
415
|
-
Path.join(spec.folder, 'res.lambda.policy.statements.yml')
|
|
416
|
-
let customLambdaPolicyStatementContent = Fs.existsSync(customLambdaPolicyStatementPath) ?
|
|
417
|
-
Fs.readFileSync(customLambdaPolicyStatementPath) : ''
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
content += `
|
|
422
|
-
Basic${AppName}LambdaRole:
|
|
423
|
-
Type: AWS::IAM::Role
|
|
424
|
-
Properties:
|
|
425
|
-
RoleName: Basic${AppName}LambdaRole\${self:custom.index.BasicLambdaRole,"01"}
|
|
426
|
-
AssumeRolePolicyDocument:
|
|
427
|
-
Version: '2012-10-17'
|
|
428
|
-
Statement:
|
|
429
|
-
- Effect: Allow
|
|
430
|
-
Principal:
|
|
431
|
-
Service:
|
|
432
|
-
- lambda.amazonaws.com
|
|
433
|
-
- events.amazonaws.com
|
|
434
|
-
- ecs-tasks.amazonaws.com
|
|
435
|
-
Action: sts:AssumeRole
|
|
436
|
-
Policies:
|
|
437
|
-
- PolicyName: LambdaServiceAccess
|
|
438
|
-
PolicyDocument:
|
|
439
|
-
Version: '2012-10-17'
|
|
440
|
-
Statement:
|
|
441
|
-
- Effect: Allow
|
|
442
|
-
Action:
|
|
443
|
-
- dynamodb:DescribeTable
|
|
444
|
-
- dynamodb:GetItem
|
|
445
|
-
- dynamodb:PutItem
|
|
446
|
-
- dynamodb:UpdateItem
|
|
447
|
-
- dynamodb:DeleteItem
|
|
448
|
-
- dynamodb:Query
|
|
449
|
-
- dynamodb:Scan
|
|
450
|
-
Resource:
|
|
451
|
-
${dynamoResources.map(r => ' - ' + r.arn).join('\n')}
|
|
452
|
-
${customLambdaPolicyStatementContent}
|
|
453
|
-
ManagedPolicyArns:
|
|
454
|
-
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
|
455
|
-
`
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (spec.custom) {
|
|
460
|
-
content = Fs.readFileSync(spec.custom).toString() + '\n\n\n' + content
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
content += suffixContent
|
|
464
|
-
|
|
465
|
-
content += `
|
|
466
|
-
# END
|
|
467
|
-
`
|
|
468
|
-
|
|
469
|
-
Fs.writeFileSync(resources_yml_path, content)
|
|
470
|
-
},
|
|
471
|
-
|
|
472
35
|
|
|
473
36
|
|
|
37
|
+
// Fragment tooling (used by voxgig-system template list/eject/diff, and
|
|
38
|
+
// available to project code).
|
|
39
|
+
const Fragments = {
|
|
40
|
+
load: loadFragment,
|
|
41
|
+
render: renderFragment,
|
|
42
|
+
list: listFragments,
|
|
43
|
+
folder: PKG_TM,
|
|
474
44
|
}
|
|
475
45
|
|
|
476
46
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
function empty(o: any) {
|
|
482
|
-
return null == o ? true : 0 === Object.keys(o).length
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// Strip inital newline
|
|
486
|
-
function TM(str: string) {
|
|
487
|
-
return str.replace(/^\n/, '')
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
47
|
export {
|
|
493
48
|
EnvLambda,
|
|
49
|
+
Fragments,
|
|
50
|
+
|
|
51
|
+
// Building blocks for ejected project templates (src/gen/<name>.ts
|
|
52
|
+
// copies import these from '@voxgig/build' instead of package
|
|
53
|
+
// internals - see voxgig-system template eject --code).
|
|
54
|
+
generate,
|
|
55
|
+
empty,
|
|
56
|
+
TM,
|
|
57
|
+
loadFragment,
|
|
58
|
+
renderFragment,
|
|
59
|
+
MsgMetaShape,
|
|
60
|
+
CoreConfShape,
|
|
61
|
+
CloudConfShape,
|
|
62
|
+
res_dynamo_yml,
|
|
494
63
|
}
|
|
495
|
-
|
|
496
|
-
|
package/dist/build.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { generate, empty, TM, loadFragment, renderFragment, listFragments } from './env/lambda/generate';
|
|
2
|
+
import { MsgMetaShape } from './shape/msg';
|
|
3
|
+
import { CoreConfShape, CloudConfShape } from './shape/conf';
|
|
4
|
+
import { res_dynamo_yml } from './yml/res_dynamo_yml';
|
|
1
5
|
declare const EnvLambda: {
|
|
2
6
|
srv_yml: (model: any, spec: {
|
|
3
7
|
folder: string;
|
|
4
|
-
|
|
8
|
+
tm?: string;
|
|
9
|
+
}) => Promise<void>;
|
|
5
10
|
srv_handler: (model: any, spec: {
|
|
6
11
|
folder: string;
|
|
7
12
|
start?: string;
|
|
@@ -9,11 +14,19 @@ declare const EnvLambda: {
|
|
|
9
14
|
folder: string;
|
|
10
15
|
};
|
|
11
16
|
lang?: string;
|
|
12
|
-
|
|
17
|
+
tm?: string;
|
|
18
|
+
}) => Promise<void>;
|
|
13
19
|
resources_yml: (model: any, spec: {
|
|
14
20
|
folder: string;
|
|
15
21
|
filename: string;
|
|
16
22
|
custom: string;
|
|
23
|
+
tm?: string;
|
|
17
24
|
}) => Promise<void>;
|
|
18
25
|
};
|
|
19
|
-
|
|
26
|
+
declare const Fragments: {
|
|
27
|
+
load: typeof loadFragment;
|
|
28
|
+
render: typeof renderFragment;
|
|
29
|
+
list: typeof listFragments;
|
|
30
|
+
folder: string;
|
|
31
|
+
};
|
|
32
|
+
export { EnvLambda, Fragments, generate, empty, TM, loadFragment, renderFragment, MsgMetaShape, CoreConfShape, CloudConfShape, res_dynamo_yml, };
|