@kirkelliott/zap 0.1.20 → 0.1.22
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/README.md +60 -25
- package/dist/cli.js +68 -40
- package/dist/init.js +21 -14
- package/package.json +1 -1
- package/demo/live.zap +0 -4
package/README.md
CHANGED
|
@@ -211,15 +211,69 @@ Both pages share `lib/page.zap`. Update that one file in S3 — both pages chang
|
|
|
211
211
|
|
|
212
212
|
---
|
|
213
213
|
|
|
214
|
+
## Environments
|
|
215
|
+
|
|
216
|
+
Each environment is a fully isolated AWS stack — its own S3 bucket, Lambda function, KV table, and URL. `prod` is the default. No flags needed for prod.
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# spin up staging (takes ~30 seconds, same as init)
|
|
220
|
+
zap init --env staging
|
|
221
|
+
|
|
222
|
+
# deploy and test there
|
|
223
|
+
zap deploy --env staging api.zap
|
|
224
|
+
curl https://staging-url.lambda-url.us-east-1.on.aws/api
|
|
225
|
+
|
|
226
|
+
# promote to prod when ready
|
|
227
|
+
zap promote api --from staging --to prod
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`promote` copies the file from one bucket to the other. The prod URL is live instantly.
|
|
231
|
+
|
|
232
|
+
`.zaprc` stores each environment under its own key:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"prod": { "bucket": "zap-a3f2b8c1", "url": "https://abc.lambda-url…", … },
|
|
237
|
+
"staging": { "bucket": "zap-f9e2d4c7", "url": "https://xyz.lambda-url…", … }
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Every command accepts `--env`:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
zap ls --env staging
|
|
245
|
+
zap rollback api --env staging
|
|
246
|
+
zap rm old-handler --env staging
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## rollback — undo a deploy
|
|
252
|
+
|
|
253
|
+
Every `zap deploy` creates a new S3 version. Roll back to the previous one instantly:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
zap rollback hello
|
|
257
|
+
# ↩ hello restored to 2026-02-28T19:35:00.000Z
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Works per-environment: `zap rollback hello --env staging`
|
|
261
|
+
|
|
262
|
+
No revert commits. No redeploy. The old code is live immediately.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
214
266
|
## CLI
|
|
215
267
|
|
|
216
268
|
```
|
|
217
|
-
zap init
|
|
218
|
-
zap deploy <file|
|
|
219
|
-
zap
|
|
220
|
-
zap
|
|
221
|
-
zap
|
|
222
|
-
zap
|
|
269
|
+
zap init [--env <env>] Provision AWS and deploy the runtime
|
|
270
|
+
zap deploy <file|dir> [--env <env>] Upload .zap file(s) to S3
|
|
271
|
+
zap promote <name> [--from] [--to] Copy a handler between environments
|
|
272
|
+
zap rollback <name> [--env <env>] Restore the previous version of a handler
|
|
273
|
+
zap rm <name> [--env <env>] Remove a handler (and its cron rule)
|
|
274
|
+
zap ls [--env <env>] List deployed handlers
|
|
275
|
+
zap demo [--env <env>] Deploy the built-in demo handlers
|
|
276
|
+
zap repair [--env <env>] Fix Lambda permissions if the URL stops working
|
|
223
277
|
```
|
|
224
278
|
|
|
225
279
|
`init` writes a `.zaprc` to the project directory. All other commands read bucket and region from it — no flags needed.
|
|
@@ -272,23 +326,4 @@ MIT
|
|
|
272
326
|
|
|
273
327
|
---
|
|
274
328
|
|
|
275
|
-
The file in S3 is just a carrier. You don't need it.
|
|
276
|
-
|
|
277
|
-
```js
|
|
278
|
-
// live.zap
|
|
279
|
-
export default async (req) => {
|
|
280
|
-
if (!req.body) return { status: 400, body: 'POST a function' }
|
|
281
|
-
return { body: await eval(`(${req.body})`)({ kv, fetch }) }
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
curl -X POST https://your-endpoint/live \
|
|
287
|
-
-d 'async ({ kv }) => kv.get("visits")'
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
Deploy `live.zap` once. Then POST JavaScript directly — no S3, no CLI, no deploy step. The runtime running inside itself.
|
|
291
|
-
|
|
292
|
-
---
|
|
293
|
-
|
|
294
329
|
**[live demo →](https://zn2qgaqlofvauxmoncf36m4ynq0pfarj.lambda-url.us-east-1.on.aws/)**
|
package/dist/cli.js
CHANGED
|
@@ -42,18 +42,21 @@ const node_fs_1 = require("node:fs");
|
|
|
42
42
|
const node_path_1 = require("node:path");
|
|
43
43
|
const cron_1 = require("./cron");
|
|
44
44
|
const s3 = new client_s3_1.S3Client({});
|
|
45
|
-
function readConfig() {
|
|
45
|
+
function readConfig(env = 'prod') {
|
|
46
46
|
try {
|
|
47
|
-
|
|
47
|
+
const raw = JSON.parse((0, node_fs_1.readFileSync)('.zaprc', 'utf8'));
|
|
48
|
+
if (raw.bucket)
|
|
49
|
+
return raw; // old flat format — treat as prod
|
|
50
|
+
return raw[env] ?? {};
|
|
48
51
|
}
|
|
49
52
|
catch {
|
|
50
53
|
return {};
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
function bucket(opts) {
|
|
54
|
-
const b = opts.bucket ?? process.env.ZAP_BUCKET ?? readConfig().bucket;
|
|
57
|
+
const b = opts.bucket ?? process.env.ZAP_BUCKET ?? readConfig(opts.env).bucket;
|
|
55
58
|
if (!b) {
|
|
56
|
-
console.error('error: bucket required (--bucket, ZAP_BUCKET, or run:
|
|
59
|
+
console.error('error: bucket required (--bucket, ZAP_BUCKET, or run: zap init)');
|
|
57
60
|
process.exit(1);
|
|
58
61
|
}
|
|
59
62
|
return b;
|
|
@@ -79,7 +82,7 @@ async function deployFile(b, filePath, key, baseUrl) {
|
|
|
79
82
|
if (cronExpr) {
|
|
80
83
|
const { functionArn } = readConfig();
|
|
81
84
|
if (!functionArn) {
|
|
82
|
-
console.error('run
|
|
85
|
+
console.error('run zap init first');
|
|
83
86
|
process.exit(1);
|
|
84
87
|
}
|
|
85
88
|
await (0, cron_1.upsertCron)(name, cronExpr, functionArn);
|
|
@@ -98,14 +101,16 @@ program
|
|
|
98
101
|
.command('init')
|
|
99
102
|
.description('provision AWS infrastructure and deploy the runtime')
|
|
100
103
|
.option('-r, --region <region>', 'AWS region', 'us-east-1')
|
|
104
|
+
.option('-e, --env <env>', 'environment name', 'prod')
|
|
101
105
|
.action(async (opts) => {
|
|
102
106
|
const { init } = await Promise.resolve().then(() => __importStar(require('./init')));
|
|
103
|
-
await init(opts.region);
|
|
107
|
+
await init(opts.region, opts.env);
|
|
104
108
|
});
|
|
105
109
|
program
|
|
106
110
|
.command('deploy <path>')
|
|
107
111
|
.description('upload a .zap file or directory to S3')
|
|
108
112
|
.option('-b, --bucket <bucket>', 'S3 bucket (or set ZAP_BUCKET)')
|
|
113
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
109
114
|
.action(async (path, opts) => {
|
|
110
115
|
const b = bucket(opts);
|
|
111
116
|
const info = await (0, promises_1.stat)(path);
|
|
@@ -118,15 +123,60 @@ program
|
|
|
118
123
|
await deployFile(b, path, key);
|
|
119
124
|
}
|
|
120
125
|
});
|
|
126
|
+
program
|
|
127
|
+
.command('promote <name>')
|
|
128
|
+
.description('copy a handler from one environment to another')
|
|
129
|
+
.option('--from <env>', 'source environment', 'staging')
|
|
130
|
+
.option('--to <env>', 'target environment', 'prod')
|
|
131
|
+
.action(async (name, opts) => {
|
|
132
|
+
const srcCfg = readConfig(opts.from);
|
|
133
|
+
const dstCfg = readConfig(opts.to);
|
|
134
|
+
if (!srcCfg.bucket) {
|
|
135
|
+
console.error(`no config for env: ${opts.from}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
if (!dstCfg.bucket) {
|
|
139
|
+
console.error(`no config for env: ${opts.to}`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
const key = name.endsWith('.zap') ? name : `${name}.zap`;
|
|
143
|
+
const { Body } = await s3.send(new client_s3_1.GetObjectCommand({ Bucket: srcCfg.bucket, Key: key }));
|
|
144
|
+
const source = await Body.transformToString();
|
|
145
|
+
await s3.send(new client_s3_1.PutObjectCommand({ Bucket: dstCfg.bucket, Key: key, Body: source, ContentType: 'application/javascript' }));
|
|
146
|
+
console.log(`↑ ${name} ${opts.from} → ${opts.to}`);
|
|
147
|
+
});
|
|
148
|
+
program
|
|
149
|
+
.command('rollback <name>')
|
|
150
|
+
.description('restore the previous version of a handler')
|
|
151
|
+
.option('-b, --bucket <bucket>', 'S3 bucket (or set ZAP_BUCKET)')
|
|
152
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
153
|
+
.action(async (name, opts) => {
|
|
154
|
+
const b = bucket(opts);
|
|
155
|
+
const key = name.endsWith('.zap') ? name : `${name}.zap`;
|
|
156
|
+
const { Versions = [] } = await s3.send(new client_s3_1.ListObjectVersionsCommand({ Bucket: b, Prefix: key }));
|
|
157
|
+
const sorted = Versions
|
|
158
|
+
.filter(v => v.Key === key)
|
|
159
|
+
.sort((a, b) => (b.LastModified?.getTime() ?? 0) - (a.LastModified?.getTime() ?? 0));
|
|
160
|
+
if (sorted.length < 2) {
|
|
161
|
+
console.error(`no previous version found for ${name}`);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
const prev = sorted[1];
|
|
165
|
+
const { Body } = await s3.send(new client_s3_1.GetObjectCommand({ Bucket: b, Key: key, VersionId: prev.VersionId }));
|
|
166
|
+
const source = await Body.transformToString();
|
|
167
|
+
await s3.send(new client_s3_1.PutObjectCommand({ Bucket: b, Key: key, Body: source, ContentType: 'application/javascript' }));
|
|
168
|
+
console.log(`↩ ${name} restored to ${prev.LastModified?.toISOString()}`);
|
|
169
|
+
});
|
|
121
170
|
program
|
|
122
171
|
.command('rm <name>')
|
|
123
172
|
.description('remove a handler from S3')
|
|
124
173
|
.option('-b, --bucket <bucket>', 'S3 bucket (or set ZAP_BUCKET)')
|
|
174
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
125
175
|
.action(async (name, opts) => {
|
|
126
176
|
const b = bucket(opts);
|
|
127
177
|
const key = name.endsWith('.zap') ? name : `${name}.zap`;
|
|
128
178
|
await s3.send(new client_s3_1.DeleteObjectCommand({ Bucket: b, Key: key }));
|
|
129
|
-
const { functionArn } = readConfig();
|
|
179
|
+
const { functionArn } = readConfig(opts.env);
|
|
130
180
|
if (functionArn)
|
|
131
181
|
await (0, cron_1.removeCron)(name.replace(/\.zap$/, ''), functionArn);
|
|
132
182
|
console.log(`- ${name.replace(/\.zap$/, '')}`);
|
|
@@ -135,6 +185,7 @@ program
|
|
|
135
185
|
.command('ls')
|
|
136
186
|
.description('list deployed handlers')
|
|
137
187
|
.option('-b, --bucket <bucket>', 'S3 bucket (or set ZAP_BUCKET)')
|
|
188
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
138
189
|
.action(async (opts) => {
|
|
139
190
|
const b = bucket(opts);
|
|
140
191
|
const { Contents = [] } = await s3.send(new client_s3_1.ListObjectsV2Command({ Bucket: b }));
|
|
@@ -147,9 +198,10 @@ program
|
|
|
147
198
|
.command('demo')
|
|
148
199
|
.description('deploy the built-in demo handlers')
|
|
149
200
|
.option('-b, --bucket <bucket>', 'S3 bucket (or set ZAP_BUCKET)')
|
|
201
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
150
202
|
.action(async (opts) => {
|
|
151
203
|
const b = bucket(opts);
|
|
152
|
-
const { url } = readConfig();
|
|
204
|
+
const { url } = readConfig(opts.env);
|
|
153
205
|
const demoDir = (0, node_path_1.resolve)(__dirname, '..', 'demo');
|
|
154
206
|
const files = await walkZap(demoDir, 'demo');
|
|
155
207
|
const remapped = files.map(f => f.key === 'demo/index.zap' ? { ...f, key: 'index.zap' } : f);
|
|
@@ -160,8 +212,9 @@ program
|
|
|
160
212
|
program
|
|
161
213
|
.command('debug')
|
|
162
214
|
.description('show Lambda function URL auth config and resource-based policy')
|
|
163
|
-
.
|
|
164
|
-
|
|
215
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
216
|
+
.action(async (opts) => {
|
|
217
|
+
const cfg = readConfig(opts.env);
|
|
165
218
|
const region = cfg.region ?? 'us-east-1';
|
|
166
219
|
const fn = cfg.functionArn ?? cfg.function ?? 'zap-runtime';
|
|
167
220
|
const lambda = new client_lambda_1.LambdaClient({ region });
|
|
@@ -198,10 +251,9 @@ program
|
|
|
198
251
|
catch (err) {
|
|
199
252
|
console.log('\ndirect invoke failed:', err.message);
|
|
200
253
|
}
|
|
201
|
-
|
|
202
|
-
if (urlCfg.url) {
|
|
254
|
+
if (cfg.url) {
|
|
203
255
|
try {
|
|
204
|
-
const res = await fetch(
|
|
256
|
+
const res = await fetch(cfg.url);
|
|
205
257
|
console.log(`\nurl fetch: HTTP ${res.status}`);
|
|
206
258
|
console.log('headers:', Object.fromEntries([...res.headers.entries()].filter(([k]) => k.startsWith('x-amzn') || k === 'content-type')));
|
|
207
259
|
console.log('body:', await res.text());
|
|
@@ -214,16 +266,13 @@ program
|
|
|
214
266
|
program
|
|
215
267
|
.command('repair')
|
|
216
268
|
.description('re-apply Lambda Function URL public access permissions')
|
|
217
|
-
.
|
|
218
|
-
|
|
269
|
+
.option('-e, --env <env>', 'environment', 'prod')
|
|
270
|
+
.action(async (opts) => {
|
|
271
|
+
const cfg = readConfig(opts.env);
|
|
219
272
|
const region = cfg.region ?? 'us-east-1';
|
|
220
273
|
const fn = cfg.functionArn ?? cfg.function ?? 'zap-runtime';
|
|
221
274
|
const lambda = new client_lambda_1.LambdaClient({ region });
|
|
222
275
|
await lambda.send(new client_lambda_1.UpdateFunctionUrlConfigCommand({ FunctionName: fn, AuthType: 'NONE', Cors: { AllowOrigins: ['*'], AllowMethods: ['*'], AllowHeaders: ['*'] } }));
|
|
223
|
-
try {
|
|
224
|
-
await lambda.send(new client_lambda_1.RemovePermissionCommand({ FunctionName: fn, StatementId: 'public-access' }));
|
|
225
|
-
}
|
|
226
|
-
catch { }
|
|
227
276
|
for (const sid of ['public-access', 'public-invoke', 'FunctionURLAllowPublicAccess']) {
|
|
228
277
|
try {
|
|
229
278
|
await lambda.send(new client_lambda_1.RemovePermissionCommand({ FunctionName: fn, StatementId: sid }));
|
|
@@ -236,25 +285,4 @@ program
|
|
|
236
285
|
if (cfg.url)
|
|
237
286
|
console.log(`\n → ${cfg.url.trim()}\n`);
|
|
238
287
|
});
|
|
239
|
-
program
|
|
240
|
-
.command('rollback <name>')
|
|
241
|
-
.description('restore the previous version of a handler')
|
|
242
|
-
.option('-b, --bucket <bucket>', 'S3 bucket (or set ZAP_BUCKET)')
|
|
243
|
-
.action(async (name, opts) => {
|
|
244
|
-
const b = bucket(opts);
|
|
245
|
-
const key = name.endsWith('.zap') ? name : `${name}.zap`;
|
|
246
|
-
const { Versions = [] } = await s3.send(new client_s3_1.ListObjectVersionsCommand({ Bucket: b, Prefix: key }));
|
|
247
|
-
const sorted = Versions
|
|
248
|
-
.filter(v => v.Key === key)
|
|
249
|
-
.sort((a, b) => (b.LastModified?.getTime() ?? 0) - (a.LastModified?.getTime() ?? 0));
|
|
250
|
-
if (sorted.length < 2) {
|
|
251
|
-
console.error(`no previous version found for ${name}`);
|
|
252
|
-
process.exit(1);
|
|
253
|
-
}
|
|
254
|
-
const prev = sorted[1];
|
|
255
|
-
const { Body } = await s3.send(new client_s3_1.GetObjectCommand({ Bucket: b, Key: key, VersionId: prev.VersionId }));
|
|
256
|
-
const source = await Body.transformToString();
|
|
257
|
-
await s3.send(new client_s3_1.PutObjectCommand({ Bucket: b, Key: key, Body: source, ContentType: 'application/javascript' }));
|
|
258
|
-
console.log(`↩ ${name} restored to ${prev.LastModified?.toISOString()}`);
|
|
259
|
-
});
|
|
260
288
|
program.parse();
|
package/dist/init.js
CHANGED
|
@@ -10,18 +10,16 @@ const node_crypto_1 = require("node:crypto");
|
|
|
10
10
|
const node_fs_1 = require("node:fs");
|
|
11
11
|
const node_path_1 = require("node:path");
|
|
12
12
|
const node_os_1 = require("node:os");
|
|
13
|
-
const
|
|
14
|
-
const FUNCTION = 'zap-runtime';
|
|
15
|
-
const TABLE = 'zap-kv';
|
|
13
|
+
const sfx = (env) => env === 'prod' ? '' : `-${env}`;
|
|
16
14
|
const TRUST = JSON.stringify({
|
|
17
15
|
Version: '2012-10-17',
|
|
18
16
|
Statement: [{ Effect: 'Allow', Principal: { Service: 'lambda.amazonaws.com' }, Action: 'sts:AssumeRole' }],
|
|
19
17
|
});
|
|
20
|
-
const policy = (bucket) => JSON.stringify({
|
|
18
|
+
const policy = (bucket, table) => JSON.stringify({
|
|
21
19
|
Version: '2012-10-17',
|
|
22
20
|
Statement: [
|
|
23
21
|
{ Effect: 'Allow', Action: ['s3:GetObject', 's3:ListBucket'], Resource: [`arn:aws:s3:::${bucket}`, `arn:aws:s3:::${bucket}/*`] },
|
|
24
|
-
{ Effect: 'Allow', Action: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:DeleteItem'], Resource: `arn:aws:dynamodb:*:*:table/${
|
|
22
|
+
{ Effect: 'Allow', Action: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:DeleteItem'], Resource: `arn:aws:dynamodb:*:*:table/${table}` },
|
|
25
23
|
],
|
|
26
24
|
});
|
|
27
25
|
async function allowPublicUrl(lambda, functionArn) {
|
|
@@ -49,16 +47,22 @@ function step(label) {
|
|
|
49
47
|
process.stdout.write(` ${label.padEnd(24)}`);
|
|
50
48
|
return (note = '') => console.log(`✓${note ? ' ' + note : ''}`);
|
|
51
49
|
}
|
|
52
|
-
async function init(region) {
|
|
50
|
+
async function init(region, env = 'prod') {
|
|
51
|
+
const ROLE = `zap-runtime-role${sfx(env)}`;
|
|
52
|
+
const FUNCTION = `zap-runtime${sfx(env)}`;
|
|
53
|
+
const TABLE = `zap-kv${sfx(env)}`;
|
|
53
54
|
const s3 = new client_s3_1.S3Client({ region });
|
|
54
55
|
const iam = new client_iam_1.IAMClient({ region: 'us-east-1' });
|
|
55
56
|
const lambda = new client_lambda_1.LambdaClient({ region });
|
|
56
57
|
const dynamo = new client_dynamodb_1.DynamoDBClient({ region });
|
|
57
|
-
|
|
58
|
+
// Load existing config — migrate old flat format to per-env format
|
|
59
|
+
let allConfig = {};
|
|
58
60
|
try {
|
|
59
|
-
|
|
61
|
+
const raw = JSON.parse((0, node_fs_1.readFileSync)('.zaprc', 'utf8'));
|
|
62
|
+
allConfig = raw.bucket ? { prod: raw } : raw;
|
|
60
63
|
}
|
|
61
64
|
catch { }
|
|
65
|
+
const config = allConfig[env] ?? {};
|
|
62
66
|
// Build — compile from source if running in the repo, otherwise use pre-built dist
|
|
63
67
|
let done = step('packaging runtime');
|
|
64
68
|
const distDir = (0, node_path_1.join)(__dirname, '.');
|
|
@@ -107,7 +111,7 @@ async function init(region) {
|
|
|
107
111
|
try {
|
|
108
112
|
const { Role } = await iam.send(new client_iam_1.GetRoleCommand({ RoleName: ROLE }));
|
|
109
113
|
roleArn = Role.Arn;
|
|
110
|
-
await iam.send(new client_iam_1.PutRolePolicyCommand({ RoleName: ROLE, PolicyName: 'zap-access', PolicyDocument: policy(bucket) }));
|
|
114
|
+
await iam.send(new client_iam_1.PutRolePolicyCommand({ RoleName: ROLE, PolicyName: 'zap-access', PolicyDocument: policy(bucket, TABLE) }));
|
|
111
115
|
}
|
|
112
116
|
catch (err) {
|
|
113
117
|
if (err.name !== 'NoSuchEntityException')
|
|
@@ -116,7 +120,7 @@ async function init(region) {
|
|
|
116
120
|
const { Role } = await iam.send(new client_iam_1.CreateRoleCommand({ RoleName: ROLE, AssumeRolePolicyDocument: TRUST }));
|
|
117
121
|
roleArn = Role.Arn;
|
|
118
122
|
await iam.send(new client_iam_1.AttachRolePolicyCommand({ RoleName: ROLE, PolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' }));
|
|
119
|
-
await iam.send(new client_iam_1.PutRolePolicyCommand({ RoleName: ROLE, PolicyName: 'zap-access', PolicyDocument: policy(bucket) }));
|
|
123
|
+
await iam.send(new client_iam_1.PutRolePolicyCommand({ RoleName: ROLE, PolicyName: 'zap-access', PolicyDocument: policy(bucket, TABLE) }));
|
|
120
124
|
}
|
|
121
125
|
if (isNew) {
|
|
122
126
|
process.stdout.write('propagating...');
|
|
@@ -127,7 +131,7 @@ async function init(region) {
|
|
|
127
131
|
// Lambda
|
|
128
132
|
done = step('deploying lambda');
|
|
129
133
|
const zip = (0, node_fs_1.readFileSync)(zipPath);
|
|
130
|
-
const
|
|
134
|
+
const lambdaEnv = { ZAP_BUCKET: bucket, ZAP_TABLE: TABLE };
|
|
131
135
|
let functionArn;
|
|
132
136
|
try {
|
|
133
137
|
const { Configuration } = await lambda.send(new client_lambda_1.GetFunctionCommand({ FunctionName: FUNCTION }));
|
|
@@ -135,7 +139,7 @@ async function init(region) {
|
|
|
135
139
|
await (0, client_lambda_1.waitUntilFunctionUpdated)({ client: lambda, maxWaitTime: 60 }, { FunctionName: FUNCTION });
|
|
136
140
|
await lambda.send(new client_lambda_1.UpdateFunctionCodeCommand({ FunctionName: FUNCTION, ZipFile: zip }));
|
|
137
141
|
await (0, client_lambda_1.waitUntilFunctionUpdated)({ client: lambda, maxWaitTime: 60 }, { FunctionName: FUNCTION });
|
|
138
|
-
await lambda.send(new client_lambda_1.UpdateFunctionConfigurationCommand({ FunctionName: FUNCTION, Environment: { Variables:
|
|
142
|
+
await lambda.send(new client_lambda_1.UpdateFunctionConfigurationCommand({ FunctionName: FUNCTION, Environment: { Variables: lambdaEnv } }));
|
|
139
143
|
}
|
|
140
144
|
catch (err) {
|
|
141
145
|
if (err.name !== 'ResourceNotFoundException')
|
|
@@ -146,7 +150,7 @@ async function init(region) {
|
|
|
146
150
|
Role: roleArn,
|
|
147
151
|
Handler: 'handler.handler',
|
|
148
152
|
Code: { ZipFile: zip },
|
|
149
|
-
Environment: { Variables:
|
|
153
|
+
Environment: { Variables: lambdaEnv },
|
|
150
154
|
Timeout: 30,
|
|
151
155
|
MemorySize: 256,
|
|
152
156
|
}));
|
|
@@ -173,6 +177,9 @@ async function init(region) {
|
|
|
173
177
|
}
|
|
174
178
|
await allowPublicUrl(lambda, functionArn);
|
|
175
179
|
done();
|
|
176
|
-
|
|
180
|
+
allConfig[env] = { bucket, function: FUNCTION, table: TABLE, region, url, functionArn };
|
|
181
|
+
(0, node_fs_1.writeFileSync)('.zaprc', JSON.stringify(allConfig, null, 2));
|
|
182
|
+
if (env !== 'prod')
|
|
183
|
+
process.stdout.write(`\n env: ${env}`);
|
|
177
184
|
console.log(`\n → ${url.trim()}\n`);
|
|
178
185
|
}
|
package/package.json
CHANGED
package/demo/live.zap
DELETED