@ez4/aws-bucket 0.14.0 → 0.16.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/dist/bucket/client.d.ts +4 -4
- package/dist/bucket/errors.d.ts +3 -0
- package/dist/bucket/function/types.d.ts +7 -1
- package/dist/bucket/utils.d.ts +4 -3
- package/dist/main.cjs +131 -118
- package/dist/main.mjs +122 -110
- package/dist/object/client.d.ts +1 -1
- package/dist/object/types.d.ts +3 -3
- package/dist/object/utils.d.ts +1 -1
- package/dist/policy/client.d.ts +1 -1
- package/dist/policy/types.d.ts +1 -0
- package/dist/triggers/client.d.ts +3 -2
- package/dist/triggers/events.d.ts +5 -0
- package/dist/triggers/policy.d.ts +1 -1
- package/dist/triggers/service.d.ts +1 -1
- package/dist/triggers/utils.d.ts +2 -1
- package/lib/event.ts +103 -0
- package/package.json +9 -9
- package/dist/triggers/bucket.d.ts +0 -4
- package/lib/function.ts +0 -43
package/dist/bucket/client.d.ts
CHANGED
|
@@ -12,12 +12,12 @@ export type UpdateNotificationRequest = {
|
|
|
12
12
|
eventsPath?: string;
|
|
13
13
|
eventsType: Event[];
|
|
14
14
|
};
|
|
15
|
-
export declare const isBucketEmpty: (bucketName: string) => Promise<boolean>;
|
|
15
|
+
export declare const isBucketEmpty: (bucketName: string) => Promise<boolean | 0>;
|
|
16
16
|
export declare const createBucket: (request: CreateRequest) => Promise<CreateResponse>;
|
|
17
|
-
export declare const deleteBucket: (bucketName: string) => Promise<
|
|
17
|
+
export declare const deleteBucket: (bucketName: string) => Promise<boolean>;
|
|
18
18
|
export declare const tagBucket: (bucketName: string, tags: ResourceTags) => Promise<void>;
|
|
19
19
|
export declare const updateCorsConfiguration: (bucketName: string, cors: Bucket.Cors) => Promise<void>;
|
|
20
|
-
export declare const deleteCorsConfiguration: (bucketName: string) => Promise<
|
|
20
|
+
export declare const deleteCorsConfiguration: (bucketName: string) => Promise<boolean>;
|
|
21
21
|
export declare const createLifecycle: (bucketName: string, autoExpireDays: number) => Promise<void>;
|
|
22
|
-
export declare const deleteLifecycle: (bucketName: string) => Promise<
|
|
22
|
+
export declare const deleteLifecycle: (bucketName: string) => Promise<boolean>;
|
|
23
23
|
export declare const updateEventNotifications: (bucketName: string, request: UpdateNotificationRequest) => Promise<void>;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { FunctionParameters } from '@ez4/aws-function';
|
|
2
2
|
import type { ExtraSource } from '@ez4/project/library';
|
|
3
|
-
export type
|
|
3
|
+
export type BucketEventEntryPoint = {
|
|
4
|
+
functionName: string;
|
|
5
|
+
sourceFile: string;
|
|
6
|
+
};
|
|
7
|
+
export type BucketEventFunctionParameters = Omit<FunctionParameters, 'getFunctionBundle' | 'sourceFile' | 'handlerName'> & {
|
|
8
|
+
handler: BucketEventEntryPoint;
|
|
9
|
+
listener?: BucketEventEntryPoint;
|
|
4
10
|
extras?: Record<string, ExtraSource>;
|
|
5
11
|
debug?: boolean;
|
|
6
12
|
};
|
package/dist/bucket/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeployOptions, EventContext } from '@ez4/project/library';
|
|
2
|
+
import type { EntryState, StepContext } from '@ez4/stateful';
|
|
2
3
|
import type { BucketState } from './types.js';
|
|
4
|
+
export declare const createBucketStateId: (bucketName: string) => string;
|
|
3
5
|
export declare const isBucketState: (resource: EntryState) => resource is BucketState;
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const getBucketState: (state: EntryStates, bucketName: string) => BucketState;
|
|
6
|
+
export declare const getBucketState: (context: EventContext, bucketName: string, options: DeployOptions) => BucketState;
|
|
6
7
|
export declare const getBucketName: (serviceName: string, resourceId: string, context: StepContext) => string;
|
package/dist/main.cjs
CHANGED
|
@@ -1,121 +1,134 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
typeof
|
|
3
|
-
|
|
4
|
-
enumerable:!0}):r,
|
|
5
|
-
ObjectServiceType:()=>
|
|
6
|
-
createBucket:()=>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
isBucketObjectState:()=>
|
|
10
|
-
module.exports=
|
|
11
|
-
|
|
12
|
-
{Bucket:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Bucket:e
|
|
17
|
-
p.Logger.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
new c.
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
{Bucket:
|
|
26
|
-
|
|
27
|
-
{Bucket:
|
|
1
|
+
"use strict";var Pt=Object.create;var C=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var Bt=Object.getOwnPropertyNames;var wt=Object.getPrototypeOf,vt=Object.prototype.hasOwnProperty;var Et=(t,e)=>{for(var r in e)C(t,r,{get:e[r],enumerable:!0})},Q=(t,e,r,o)=>{if(e&&
|
|
2
|
+
typeof e=="object"||typeof e=="function")for(let n of Bt(e))!vt.call(t,n)&&n!==r&&
|
|
3
|
+
C(t,n,{get:()=>e[n],enumerable:!(o=xt(e,n))||o.enumerable});return t};var Rt=(t,e,r)=>(r=t!=null?Pt(wt(t)):{},Q(e||!t||!t.__esModule?C(r,"default",{value:t,
|
|
4
|
+
enumerable:!0}):r,t)),Ct=t=>Q(C({},"__esModule",{value:!0}),t);var Xt={};Et(Xt,{BucketServiceName:()=>i,BucketServiceType:()=>l,ObjectServiceName:()=>S,
|
|
5
|
+
ObjectServiceType:()=>f,PolicyServiceName:()=>k,PolicyServiceType:()=>d,buildBucketArn:()=>U,
|
|
6
|
+
createBucket:()=>_,createBucketEventFunction:()=>V,createBucketObject:()=>Qt,createBucketPolicy:()=>Zt,
|
|
7
|
+
createBucketStateId:()=>L,getBucketDomain:()=>Wt,getBucketName:()=>v,getBucketObjectFiles:()=>qt,
|
|
8
|
+
getBucketObjectPath:()=>E,getBucketState:()=>q,getPolicyDocument:()=>G,isBucketDomain:()=>Vt,
|
|
9
|
+
isBucketObjectState:()=>Lt,isBucketPolicyState:()=>Jt,isBucketState:()=>Se,registerTriggers:()=>_t});
|
|
10
|
+
module.exports=Ct(Xt);var pt=require("@ez4/aws-common"),mt=require("@ez4/aws-identity"),ut=require("@ez4/aws-function"),
|
|
11
|
+
lt=require("@ez4/storage/library"),yt=require("@ez4/project/library");var fe=require("@ez4/aws-common");var ae=require("@ez4/aws-common"),F=require("@ez4/aws-function"),x=require("@ez4/utils");var p=require("@ez4/aws-common"),c=require("@aws-sdk/client-s3");var i="AWS:S3/Bucket",l="aws:s3.bucket";var y=new c.S3Client({}),X=async t=>{p.Logger.logFetch(i,t);try{return!(await y.
|
|
12
|
+
send(new c.ListObjectsV2Command({Bucket:t,MaxKeys:1}))).Contents?.length}catch(e){
|
|
13
|
+
if(!(e instanceof c.NoSuchBucket))throw e;return 0}},Y=async t=>{let{bucketName:e}=t;
|
|
14
|
+
return p.Logger.logCreate(i,e),await y.send(new c.CreateBucketCommand({Bucket:e})),
|
|
15
|
+
{bucketName:e}},ee=async t=>{p.Logger.logDelete(i,t);try{return await y.send(new c.DeleteBucketCommand(
|
|
16
|
+
{Bucket:t})),!0}catch(e){if(!(e instanceof c.NoSuchBucket))throw e;return!1}},te=async(t,e)=>{
|
|
17
|
+
p.Logger.logTag(i,t),await y.send(new c.PutBucketTaggingCommand({Bucket:t,Tagging:{
|
|
18
|
+
TagSet:(0,p.getTagList)({...e,ManagedBy:"EZ4"})}}))},re=async(t,e)=>{p.Logger.logUpdate(
|
|
19
|
+
i,`${t} CORS`),await y.send(new c.PutBucketCorsCommand({Bucket:t,CORSConfiguration:{
|
|
20
|
+
CORSRules:[{ID:"ID0",AllowedOrigins:e.allowOrigins,AllowedMethods:e.allowMethods,
|
|
21
|
+
AllowedHeaders:e.allowHeaders,ExposeHeaders:e.exposeHeaders,MaxAgeSeconds:e.maxAge}]}}))},
|
|
22
|
+
oe=async t=>{p.Logger.logDelete(i,`${t} CORS`);try{return await y.send(new c.DeleteBucketCorsCommand(
|
|
23
|
+
{Bucket:t})),!0}catch(e){if(!(e instanceof c.NoSuchBucket))throw e;return!1}},ne=async(t,e)=>{
|
|
24
|
+
p.Logger.logCreate(i,`${t} lifecycle`),await y.send(new c.PutBucketLifecycleConfigurationCommand(
|
|
25
|
+
{Bucket:t,LifecycleConfiguration:{Rules:[{ID:"ID0",Status:c.ExpirationStatus.Enabled,
|
|
26
|
+
Filter:{Prefix:"*"},Expiration:{Days:e}}]}}))},se=async t=>{p.Logger.logDelete(i,
|
|
27
|
+
`${t} lifecycle`);try{return await y.send(new c.DeleteBucketLifecycleCommand({Bucket:t})),
|
|
28
|
+
!0}catch(e){if(!(e instanceof c.NoSuchBucket))throw e;return!1}},ce=async(t,e)=>{
|
|
29
|
+
p.Logger.logUpdate(i,`${t} event notifications`);let{functionArn:r,eventsPath:o,
|
|
30
|
+
eventsType:n}=e;await y.send(new c.PutBucketNotificationConfigurationCommand({Bucket:t,
|
|
31
|
+
SkipDestinationValidation:!0,NotificationConfiguration:{...r&&{LambdaFunctionConfigurations:[
|
|
28
32
|
{Id:"ID0",LambdaFunctionArn:r,Events:n,...o&&{Filter:{Key:{FilterRules:[{Name:"p\
|
|
29
|
-
refix",Value:o}]}}}}]}}}))};var
|
|
30
|
-
result&&
|
|
31
|
-
dependencies:
|
|
32
|
-
r,o);if(n.counts)return{...n,name:r.bucketName}},
|
|
33
|
-
i,
|
|
34
|
-
|
|
35
|
-
n,r.tags,void 0);let s={eventsPath:r.eventsPath,functionArn:o};return await
|
|
36
|
-
s,{}),{bucketName:n,functionArn:o}},
|
|
37
|
-
if(!o)return;let s=o.bucketName,a=(0,
|
|
38
|
-
await
|
|
39
|
-
tags);let
|
|
40
|
-
functionArn:
|
|
41
|
-
result;
|
|
42
|
-
cors&&r?.cors&&(0,
|
|
43
|
-
cors)return
|
|
44
|
-
autoExpireDays)return
|
|
45
|
-
|
|
46
|
-
!(0,
|
|
47
|
-
moved:*"],...
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
e)
|
|
77
|
-
t.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
e,{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
a=
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
(0,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
e,
|
|
117
|
-
|
|
33
|
+
refix",Value:o}]}}}}]}}}))};var ie=()=>({equals:jt,create:pe,replace:Ot,preview:ht,update:Tt,delete:Nt}),jt=(t,e)=>!!t.
|
|
34
|
+
result&&t.result.bucketName===e.result?.bucketName,ht=async(t,e)=>{let r={...t.parameters,
|
|
35
|
+
dependencies:t.dependencies},o={...e.parameters,dependencies:e.dependencies},n=(0,x.deepCompare)(
|
|
36
|
+
r,o);if(n.counts)return{...n,name:r.bucketName}},Ot=async(t,e,r)=>{if(e.result)throw new ae.ReplaceResourceError(
|
|
37
|
+
i,t.entryId,e.entryId);return pe(t,r)},pe=async(t,e)=>{let r=t.parameters,o=(0,F.tryGetFunctionArn)(
|
|
38
|
+
e),{bucketName:n}=await Y(r);await me(n,r,void 0),await ue(n,r,void 0),await le(
|
|
39
|
+
n,r.tags,void 0);let s={eventsPath:r.eventsPath,functionArn:o};return await ye(n,
|
|
40
|
+
s,{}),{bucketName:n,functionArn:o}},Tt=async(t,e,r)=>{let{result:o,parameters:n}=t;
|
|
41
|
+
if(!o)return;let s=o.bucketName,a=(0,F.tryGetFunctionArn)(r),u=e.result?.functionArn;
|
|
42
|
+
await me(s,n,e.parameters),await ue(s,n,e.parameters),await le(s,n.tags,e.parameters.
|
|
43
|
+
tags);let b={eventsPath:n.eventsPath,functionArn:a},P={eventsPath:e.parameters.eventsPath,
|
|
44
|
+
functionArn:u};return await ye(s,b,P),{...o,functionArn:a}},Nt=async t=>{let e=t.
|
|
45
|
+
result;e&&await X(e.bucketName)&&await ee(e.bucketName)},me=async(t,e,r)=>{if(!(e.
|
|
46
|
+
cors&&r?.cors&&(0,x.deepEqual)(e.cors,r.cors))){if(e.cors)return re(t,e.cors);if(r?.
|
|
47
|
+
cors)return oe(t)}},ue=async(t,e,r)=>{if(e.autoExpireDays!==r?.autoExpireDays){if(e.
|
|
48
|
+
autoExpireDays)return ne(t,e.autoExpireDays);if(r?.autoExpireDays)return se(t)}},
|
|
49
|
+
le=async(t,e,r)=>{let o=e??{};!(0,x.deepEqual)(o,r??{})&&await te(t,o)},ye=async(t,e,r)=>{
|
|
50
|
+
!(0,x.deepEqual)(e,r)&&await ce(t,{eventsType:["s3:ObjectCreated:*","s3:ObjectRe\
|
|
51
|
+
moved:*"],...e})};var de=()=>{(0,fe.registerProvider)(l,ie())};var Ee=require("@ez4/aws-common");var xe=require("@ez4/aws-common"),Be=require("@ez4/utils");var ge=require("@ez4/aws-common"),h=require("@ez4/utils");var j=class extends Error{constructor(e){super(`Bucket service ${e} wasn't found\
|
|
52
|
+
.`)}};var L=t=>(0,h.hashData)(l,(0,h.toKebabCase)(t)),Se=t=>t.type===l,q=(t,e,r)=>{let o=t.
|
|
53
|
+
getServiceState(e,r);if(!Se(o))throw new j(e);return o},v=(t,e,r)=>{let o=r.getDependencies(
|
|
54
|
+
l)[0]?.result;if(!o?.bucketName)throw new ge.IncompleteResourceError(t,e,"bucket\
|
|
55
|
+
Name");return o.bucketName};var g=require("@aws-sdk/client-s3"),M=require("@ez4/aws-common");var k="AWS:S3/Policy",d="aws:s3.policy";var ke=new g.S3Client({}),be=async t=>{let{bucketName:e,role:r}=t;return M.Logger.
|
|
56
|
+
logCreate(k,e),await ke.send(new g.PutBucketPolicyCommand({Bucket:e,Policy:JSON.
|
|
57
|
+
stringify(r)})),{bucketName:e}},Pe=async t=>{M.Logger.logDelete(k,t);try{return await ke.
|
|
58
|
+
send(new g.DeleteBucketPolicyCommand({Bucket:t})),!0}catch(e){if(!(e instanceof g.NoSuchBucket))
|
|
59
|
+
throw e;return!1}};var we=()=>({equals:Dt,create:ve,replace:At,preview:zt,update:It,delete:Ft}),Dt=(t,e)=>!!t.
|
|
60
|
+
result&&t.result.bucketName===e.result?.bucketName,zt=async(t,e)=>{let r={...t.parameters,
|
|
61
|
+
dependencies:t.dependencies},o={...e.parameters,dependencies:e.dependencies},n=(0,Be.deepCompare)(
|
|
62
|
+
r,o,{exclude:{getRole:!0}});if(n.counts)return{...n,name:r.fromService}},At=async(t,e,r)=>{
|
|
63
|
+
if(e.result)throw new xe.ReplaceResourceError(k,t.entryId,e.entryId);return ve(t,
|
|
64
|
+
r)},ve=async(t,e)=>{let r=t.parameters,o=v(k,"policy",e),n=await r.getRole(e);return await be(
|
|
65
|
+
{bucketName:o,role:n}),{bucketName:o}},It=async()=>{},Ft=async t=>{let e=t.result;
|
|
66
|
+
e&&await Pe(e.bucketName)};var Re=()=>{(0,Ee.registerProvider)(d,we())};var Ie=require("@ez4/aws-common");var Te=require("node:fs/promises"),Ne=require("@ez4/aws-common"),O=require("@ez4/utils");var Ce=require("node:fs"),m=require("@aws-sdk/client-s3"),B=require("@ez4/aws-common"),
|
|
67
|
+
je=Rt(require("mime"),1);var S="AWS:S3/Object",f="aws:s3.object";var Lt=t=>t.type===f,E=(t,e)=>`${t}/${e}`,qt=t=>t.getDependencies(f).map(({result:r,
|
|
68
|
+
parameters:o})=>({lastModified:r?.lastModified,objectKey:o.objectKey}));var $=new m.S3Client({}),H=async(t,e)=>{let{objectKey:r,filePath:o}=e;B.Logger.logCreate(
|
|
69
|
+
S,E(t,r));let n=je.default.getType(o);return await $.send(new m.PutObjectCommand(
|
|
70
|
+
{Bucket:t,Key:r,Body:(0,Ce.createReadStream)(o),...n&&{ContentType:n}})),{objectKey:r}},
|
|
71
|
+
he=async(t,e,r)=>{B.Logger.logTag(S,E(t,e)),await $.send(new m.PutObjectTaggingCommand(
|
|
72
|
+
{Bucket:t,Key:e,Tagging:{TagSet:(0,B.getTagList)({...r,ManagedBy:"EZ4"})}}))},Oe=async(t,e)=>{
|
|
73
|
+
B.Logger.logDelete(S,E(t,e));try{return await $.send(new m.DeleteObjectCommand({
|
|
74
|
+
Bucket:t,Key:e})),!0}catch(r){if(!(r instanceof m.NoSuchBucket))throw r;return!1}};var De=()=>({equals:Mt,create:ze,replace:Ht,preview:$t,update:Kt,delete:Ut}),Mt=(t,e)=>!!t.
|
|
75
|
+
result&&t.result.lastModified===e.result?.lastModified,$t=async(t,e)=>{let r=t.parameters,
|
|
76
|
+
o=e.parameters,n=(0,O.deepCompare)({...r,dependencies:t.dependencies,lastModified:await K(
|
|
77
|
+
r.filePath)},{...o,dependencies:e.dependencies,lastModified:t.result?.lastModified});
|
|
78
|
+
if(n.counts)return{...n,name:r.objectKey}},Ht=async(t,e,r)=>{if(e.result)throw new Ne.ReplaceResourceError(
|
|
79
|
+
S,t.entryId,e.entryId);return ze(t,r)},ze=async(t,e)=>{let r=t.parameters,o=v(S,
|
|
80
|
+
"bucket",e),n=await K(r.filePath),{objectKey:s}=await H(o,r);return await Ae(o,s,
|
|
81
|
+
r.tags,t.parameters.tags),{lastModified:n,bucketName:o}},Kt=async(t,e)=>{let{result:r,
|
|
82
|
+
parameters:o}=t;if(!r)return;let{objectKey:n,tags:s}=o,a=Gt(r,o,e.parameters);return await Ae(
|
|
83
|
+
r.bucketName,n,s,e.parameters.tags),a},Ut=async t=>{let{result:e,parameters:r}=t;
|
|
84
|
+
e&&await Oe(e.bucketName,r.objectKey)},K=async t=>{let{mtime:e}=await(0,Te.stat)(
|
|
85
|
+
t);return e.getTime()},Gt=async(t,e,r)=>{let o=await K(e.filePath);if(o<=t.lastModified&&
|
|
86
|
+
e.filePath===r.filePath)return t;let{bucketName:n}=t,{objectKey:s}=r;return await H(
|
|
87
|
+
n,{...e,objectKey:s}),{lastModified:o,bucketName:n}},Ae=async(t,e,r,o)=>{let n=r??
|
|
88
|
+
{};!(0,O.deepEqual)(n,o??{})&&await he(t,e,n)};var Fe=()=>{(0,Ie.registerProvider)(f,De())};var A=require("@ez4/storage/library");var qe=require("@ez4/aws-function"),T=require("@ez4/stateful");var Le=require("@ez4/aws-identity"),U=t=>`arn:aws:s3:::${t}`,G=t=>(0,Le.createPolicyDocument)(
|
|
89
|
+
[{resourceIds:[`arn:aws:s3:::${t}-*`,`arn:aws:s3:::${t}-*/*`],permissions:["s3:L\
|
|
90
|
+
istBucket","s3:PutObject","s3:GetObject","s3:DeleteObject"]}]);var _=(t,e,r)=>{let o=r.bucketName,n=L(o),s=(0,T.attachEntry)(t,{type:l,entryId:n,
|
|
91
|
+
dependencies:[],parameters:r});return e&&((0,qe.createPermission)(t,s,e,{fromService:r.
|
|
92
|
+
bucketName,getPermission:()=>({principal:"s3.amazonaws.com",sourceArn:U(o)})}),(0,T.linkDependency)(
|
|
93
|
+
t,s.entryId,e.entryId)),s};var Ze=require("@ez4/project/library"),z=require("@ez4/aws-function"),Z=require("@ez4/aws-identity");var Ge=require("@ez4/aws-function");var Me=require("node:path"),$e=require("@ez4/project/library"),He=require("@ez4/aws-function"),
|
|
94
|
+
Ke=require("@ez4/aws-common"),Ue=async(t,e)=>{let{extras:r,debug:o,handler:n,listener:s}=e,
|
|
95
|
+
a=(0,$e.getDefinitionsObject)(t);return(0,Ke.bundleFunction)(He.MappingServiceName,
|
|
96
|
+
{templateFile:(0,Me.join)(__dirname,"../lib/event.ts"),filePrefix:"s3",define:{...a},
|
|
97
|
+
handler:n,listener:s,extras:r,debug:o})};var V=(t,e,r)=>(0,Ge.createFunction)(t,e,{handlerName:"s3EntryPoint",functionName:r.
|
|
98
|
+
functionName,sourceFile:r.handler.sourceFile,description:r.description,variables:r.
|
|
99
|
+
variables,timeout:r.timeout,memory:r.memory,tags:r.tags,getFunctionBundle:o=>{let n=o.
|
|
100
|
+
getDependencies();return Ue(n,r)}});var N=require("@ez4/project/library"),_e=require("@ez4/aws-common"),D=require("@ez4/utils"),
|
|
101
|
+
Ve=async(t,e)=>{if(t.globalName)return(0,N.getServiceName)(t.globalName,e);let r=(0,N.getServiceName)(
|
|
102
|
+
t,e),o=await(0,_e.getRandomName)(16);return`${r.substring(0,46)}-${o}`},W=(t,e)=>`${(0,D.toKebabCase)(
|
|
103
|
+
t.name)}-${(0,D.toKebabCase)(e)}`,We=(t,e,r)=>`${(0,N.getServiceName)(t,r)}-${(0,D.toKebabCase)(
|
|
104
|
+
e)}`;var R=class extends Error{constructor(){super("Execution role for S3 is missing.")}};var Je=(t,e,r,o)=>{if(!e.events)return;if(!o.role||!(0,Z.isRoleState)(o.role))throw new R;
|
|
105
|
+
let{events:n}=e,{handler:s,listener:a}=n,u=W(e,s.name),b=(0,z.tryGetFunctionState)(
|
|
106
|
+
o,u,r);if(b)return b;let P=V(t,o.role,{functionName:We(e,s.name,r),description:s.
|
|
107
|
+
description,timeout:n.timeout??30,memory:n.memory??192,extras:e.extras,debug:r.debug,
|
|
108
|
+
variables:{...r.variables,...e.variables,...n.variables},handler:{functionName:s.
|
|
109
|
+
name,sourceFile:s.file},...a&&{listener:{functionName:a.name,sourceFile:a.file}}});
|
|
110
|
+
return o.setServiceState(P,u,r),P},Qe=(t,e,r,o)=>{if(!e.extras||!e.events)return;
|
|
111
|
+
if(!o.role||!(0,Z.isRoleState)(o.role))throw new R;let{handler:n}=e.events,s=W(e,
|
|
112
|
+
n.name),a=(0,z.getFunctionState)(o,s,r);(0,Ze.linkServiceExtras)(t,a.entryId,e.extras)};var Xe=require("node:fs/promises"),w=require("node:path"),Ye=require("@ez4/aws-bucket"),
|
|
113
|
+
et=async(t,e,r)=>{let o=process.cwd(),n=(0,w.join)(o,r),s=await(0,Xe.readdir)(n,
|
|
114
|
+
{withFileTypes:!0,recursive:!0});for(let a of s){if(!a.isFile())continue;let u=(0,w.join)(
|
|
115
|
+
a.parentPath,a.name);(0,Ye.createBucketObject)(t,e,{objectKey:(0,w.relative)(n,u),
|
|
116
|
+
filePath:(0,w.relative)(o,u)})}};var tt=(t,e,r)=>{let o=q(t,e.name,r);return{entryIds:[o.entryId],constructor:`ma\
|
|
117
|
+
ke('${o.parameters.bucketName}')`,from:"@ez4/aws-bucket/client",module:"Client"}};var rt=t=>{let{service:e,options:r,context:o}=t;return(0,A.isBucketService)(e)?tt(
|
|
118
|
+
o,e,r):null},ot=async t=>{let{state:e,service:r,options:o,context:n}=t;if(!(0,A.isBucketService)(
|
|
119
|
+
r))return;let{localPath:s,autoExpireDays:a,events:u,cors:b}=r,P=await Ve(r,o),bt=Je(
|
|
120
|
+
e,r,o,n),J=_(e,bt,{eventsPath:u?.path,bucketName:P,autoExpireDays:a,localPath:s,
|
|
121
|
+
cors:b});n.setServiceState(J,r,o),s&&await et(e,J,s)},nt=t=>{let{state:e,service:r,
|
|
122
|
+
options:o,context:n}=t;(0,A.isBucketService)(r)&&Qe(e,r,o,n)};var st=require("@ez4/storage/library"),I=require("@ez4/aws-identity"),ct=require("@ez4/project/library");var at=t=>{let{state:e,serviceType:r,options:o}=t;if(r!==st.ServiceType)return null;
|
|
123
|
+
let n=(0,ct.getServiceName)("",o),s=`${n}-bucket-policy`;return(0,I.tryGetPolicy)(
|
|
124
|
+
e,s)??(0,I.createPolicy)(e,{policyDocument:G(n),policyName:s})};var it=!1,_t=()=>{it||((0,pt.registerTriggers)(),(0,mt.registerTriggers)(),(0,ut.registerTriggers)(),
|
|
125
|
+
(0,lt.registerTriggers)(),(0,yt.createTrigger)("@ez4/aws-bucket",{"deploy:prepar\
|
|
126
|
+
eExecutionPolicy":at,"deploy:prepareLinkedService":rt,"deploy:prepareResources":ot,
|
|
127
|
+
"deploy:connectResources":nt}),de(),Re(),Fe(),it=!0)};var ft=require("@ez4/aws-identity"),Vt=t=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.test(
|
|
128
|
+
t),Wt=async t=>{let e=await(0,ft.getRegion)();return`${t}.s3.${e}.amazonaws.com`};var dt=require("@ez4/stateful"),gt=require("@ez4/utils");var Zt=(t,e,r,o)=>{let n=(0,gt.hashData)(d,e.entryId,r.entryId);return(0,dt.attachEntry)(
|
|
129
|
+
t,{type:d,entryId:n,dependencies:[e.entryId,r.entryId],parameters:o})};var Jt=t=>t.type===d;var St=require("@ez4/stateful"),kt=require("@ez4/utils");var Qt=(t,e,r)=>{let o=r.objectKey,n=(0,kt.hashData)(f,e.entryId,o);return(0,St.attachEntry)(
|
|
130
|
+
t,{type:f,entryId:n,dependencies:[e.entryId],parameters:r})};0&&(module.exports={BucketServiceName,BucketServiceType,ObjectServiceName,ObjectServiceType,
|
|
118
131
|
PolicyServiceName,PolicyServiceType,buildBucketArn,createBucket,createBucketEventFunction,
|
|
119
|
-
createBucketObject,createBucketPolicy,getBucketDomain,getBucketName,
|
|
120
|
-
getBucketObjectPath,getBucketState,
|
|
132
|
+
createBucketObject,createBucketPolicy,createBucketStateId,getBucketDomain,getBucketName,
|
|
133
|
+
getBucketObjectFiles,getBucketObjectPath,getBucketState,getPolicyDocument,isBucketDomain,
|
|
121
134
|
isBucketObjectState,isBucketPolicyState,isBucketState,registerTriggers});
|
package/dist/main.mjs
CHANGED
|
@@ -1,110 +1,122 @@
|
|
|
1
|
-
import{registerTriggers as
|
|
2
|
-
import{registerTriggers as
|
|
3
|
-
import{createTrigger as
|
|
4
|
-
import{deepCompare as
|
|
5
|
-
ListObjectsV2Command as
|
|
6
|
-
PutBucketCorsCommand as
|
|
7
|
-
DeleteBucketLifecycleCommand as
|
|
8
|
-
ExpirationStatus as
|
|
9
|
-
Contents?.length)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
await
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
send(new
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
t
|
|
33
|
-
|
|
34
|
-
s,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
r
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
r)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if(!r)return;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
var
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
import{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
r
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
1
|
+
import{registerTriggers as Qt}from"@ez4/aws-common";import{registerTriggers as Xt}from"@ez4/aws-identity";
|
|
2
|
+
import{registerTriggers as Yt}from"@ez4/aws-function";import{registerTriggers as er}from"@ez4/storage/library";
|
|
3
|
+
import{createTrigger as tr}from"@ez4/project/library";import{registerProvider as Je}from"@ez4/aws-common";import{ReplaceResourceError as Ke}from"@ez4/aws-common";import{tryGetFunctionArn as H}from"@ez4/aws-function";
|
|
4
|
+
import{deepCompare as Ue,deepEqual as w}from"@ez4/utils";import{getTagList as Te,Logger as p}from"@ez4/aws-common";import{S3Client as Ne,
|
|
5
|
+
ListObjectsV2Command as De,CreateBucketCommand as ze,DeleteBucketCommand as Ae,PutBucketTaggingCommand as Ie,
|
|
6
|
+
PutBucketCorsCommand as Fe,DeleteBucketCorsCommand as Le,PutBucketLifecycleConfigurationCommand as qe,
|
|
7
|
+
DeleteBucketLifecycleCommand as Me,PutBucketNotificationConfigurationCommand as $e,
|
|
8
|
+
ExpirationStatus as He,NoSuchBucket as b}from"@aws-sdk/client-s3";var a="AWS:S3/Bucket",u="aws:s3.bucket";var m=new Ne({}),D=async t=>{p.logFetch(a,t);try{return!(await m.send(new De({Bucket:t,
|
|
9
|
+
MaxKeys:1}))).Contents?.length}catch(e){if(!(e instanceof b))throw e;return 0}},
|
|
10
|
+
z=async t=>{let{bucketName:e}=t;return p.logCreate(a,e),await m.send(new ze({Bucket:e})),
|
|
11
|
+
{bucketName:e}},A=async t=>{p.logDelete(a,t);try{return await m.send(new Ae({Bucket:t})),
|
|
12
|
+
!0}catch(e){if(!(e instanceof b))throw e;return!1}},I=async(t,e)=>{p.logTag(a,t),
|
|
13
|
+
await m.send(new Ie({Bucket:t,Tagging:{TagSet:Te({...e,ManagedBy:"EZ4"})}}))},F=async(t,e)=>{
|
|
14
|
+
p.logUpdate(a,`${t} CORS`),await m.send(new Fe({Bucket:t,CORSConfiguration:{CORSRules:[
|
|
15
|
+
{ID:"ID0",AllowedOrigins:e.allowOrigins,AllowedMethods:e.allowMethods,AllowedHeaders:e.
|
|
16
|
+
allowHeaders,ExposeHeaders:e.exposeHeaders,MaxAgeSeconds:e.maxAge}]}}))},L=async t=>{
|
|
17
|
+
p.logDelete(a,`${t} CORS`);try{return await m.send(new Le({Bucket:t})),!0}catch(e){
|
|
18
|
+
if(!(e instanceof b))throw e;return!1}},q=async(t,e)=>{p.logCreate(a,`${t} lifec\
|
|
19
|
+
ycle`),await m.send(new qe({Bucket:t,LifecycleConfiguration:{Rules:[{ID:"ID0",Status:He.
|
|
20
|
+
Enabled,Filter:{Prefix:"*"},Expiration:{Days:e}}]}}))},M=async t=>{p.logDelete(a,
|
|
21
|
+
`${t} lifecycle`);try{return await m.send(new Me({Bucket:t})),!0}catch(e){if(!(e instanceof
|
|
22
|
+
b))throw e;return!1}},$=async(t,e)=>{p.logUpdate(a,`${t} event notifications`);let{
|
|
23
|
+
functionArn:r,eventsPath:o,eventsType:n}=e;await m.send(new $e({Bucket:t,SkipDestinationValidation:!0,
|
|
24
|
+
NotificationConfiguration:{...r&&{LambdaFunctionConfigurations:[{Id:"ID0",LambdaFunctionArn:r,
|
|
25
|
+
Events:n,...o&&{Filter:{Key:{FilterRules:[{Name:"prefix",Value:o}]}}}}]}}}))};var K=()=>({equals:Ge,create:U,replace:Ve,preview:_e,update:We,delete:Ze}),Ge=(t,e)=>!!t.
|
|
26
|
+
result&&t.result.bucketName===e.result?.bucketName,_e=async(t,e)=>{let r={...t.parameters,
|
|
27
|
+
dependencies:t.dependencies},o={...e.parameters,dependencies:e.dependencies},n=Ue(
|
|
28
|
+
r,o);if(n.counts)return{...n,name:r.bucketName}},Ve=async(t,e,r)=>{if(e.result)throw new Ke(
|
|
29
|
+
a,t.entryId,e.entryId);return U(t,r)},U=async(t,e)=>{let r=t.parameters,o=H(e),{
|
|
30
|
+
bucketName:n}=await z(r);await G(n,r,void 0),await _(n,r,void 0),await V(n,r.tags,
|
|
31
|
+
void 0);let s={eventsPath:r.eventsPath,functionArn:o};return await W(n,s,{}),{bucketName:n,
|
|
32
|
+
functionArn:o}},We=async(t,e,r)=>{let{result:o,parameters:n}=t;if(!o)return;let s=o.
|
|
33
|
+
bucketName,c=H(r),i=e.result?.functionArn;await G(s,n,e.parameters),await _(s,n,
|
|
34
|
+
e.parameters),await V(s,n.tags,e.parameters.tags);let d={eventsPath:n.eventsPath,
|
|
35
|
+
functionArn:c},g={eventsPath:e.parameters.eventsPath,functionArn:i};return await W(
|
|
36
|
+
s,d,g),{...o,functionArn:c}},Ze=async t=>{let e=t.result;e&&await D(e.bucketName)&&
|
|
37
|
+
await A(e.bucketName)},G=async(t,e,r)=>{if(!(e.cors&&r?.cors&&w(e.cors,r.cors))){
|
|
38
|
+
if(e.cors)return F(t,e.cors);if(r?.cors)return L(t)}},_=async(t,e,r)=>{if(e.autoExpireDays!==
|
|
39
|
+
r?.autoExpireDays){if(e.autoExpireDays)return q(t,e.autoExpireDays);if(r?.autoExpireDays)
|
|
40
|
+
return M(t)}},V=async(t,e,r)=>{let o=e??{};!w(o,r??{})&&await I(t,o)},W=async(t,e,r)=>{
|
|
41
|
+
!w(e,r)&&await $(t,{eventsType:["s3:ObjectCreated:*","s3:ObjectRemoved:*"],...e})};var Z=()=>{Je(u,K())};import{registerProvider as lt}from"@ez4/aws-common";import{ReplaceResourceError as st}from"@ez4/aws-common";import{deepCompare as ct}from"@ez4/utils";import{IncompleteResourceError as Qe}from"@ez4/aws-common";import{hashData as Xe,
|
|
42
|
+
toKebabCase as Ye}from"@ez4/utils";var P=class extends Error{constructor(e){super(`Bucket service ${e} wasn't found\
|
|
43
|
+
.`)}};var J=t=>Xe(u,Ye(t)),et=t=>t.type===u,Q=(t,e,r)=>{let o=t.getServiceState(e,r);if(!et(
|
|
44
|
+
o))throw new P(e);return o},x=(t,e,r)=>{let o=r.getDependencies(u)[0]?.result;if(!o?.
|
|
45
|
+
bucketName)throw new Qe(t,e,"bucketName");return o.bucketName};import{S3Client as tt,PutBucketPolicyCommand as rt,DeleteBucketPolicyCommand as ot,
|
|
46
|
+
NoSuchBucket as nt}from"@aws-sdk/client-s3";import{Logger as X}from"@ez4/aws-common";var S="AWS:S3/Policy",y="aws:s3.policy";var Y=new tt({}),ee=async t=>{let{bucketName:e,role:r}=t;return X.logCreate(S,e),
|
|
47
|
+
await Y.send(new rt({Bucket:e,Policy:JSON.stringify(r)})),{bucketName:e}},te=async t=>{
|
|
48
|
+
X.logDelete(S,t);try{return await Y.send(new ot({Bucket:t})),!0}catch(e){if(!(e instanceof
|
|
49
|
+
nt))throw e;return!1}};var re=()=>({equals:at,create:oe,replace:pt,preview:it,update:mt,delete:ut}),at=(t,e)=>!!t.
|
|
50
|
+
result&&t.result.bucketName===e.result?.bucketName,it=async(t,e)=>{let r={...t.parameters,
|
|
51
|
+
dependencies:t.dependencies},o={...e.parameters,dependencies:e.dependencies},n=ct(
|
|
52
|
+
r,o,{exclude:{getRole:!0}});if(n.counts)return{...n,name:r.fromService}},pt=async(t,e,r)=>{
|
|
53
|
+
if(e.result)throw new st(S,t.entryId,e.entryId);return oe(t,r)},oe=async(t,e)=>{
|
|
54
|
+
let r=t.parameters,o=x(S,"policy",e),n=await r.getRole(e);return await ee({bucketName:o,
|
|
55
|
+
role:n}),{bucketName:o}},mt=async()=>{},ut=async t=>{let e=t.result;e&&await te(
|
|
56
|
+
e.bucketName)};var ne=()=>{lt(y,re())};import{registerProvider as Tt}from"@ez4/aws-common";import{stat as xt}from"node:fs/promises";import{ReplaceResourceError as Bt}from"@ez4/aws-common";
|
|
57
|
+
import{deepCompare as wt,deepEqual as vt}from"@ez4/utils";import{createReadStream as yt}from"node:fs";import{S3Client as ft,PutObjectCommand as dt,
|
|
58
|
+
PutObjectTaggingCommand as gt,DeleteObjectCommand as St,NoSuchBucket as kt}from"@aws-sdk/client-s3";
|
|
59
|
+
import{getTagList as bt,Logger as v}from"@ez4/aws-common";import Pt from"mime";var f="AWS:S3/Object",l="aws:s3.object";var Vr=t=>t.type===l,B=(t,e)=>`${t}/${e}`,Wr=t=>t.getDependencies(l).map(({result:r,
|
|
60
|
+
parameters:o})=>({lastModified:r?.lastModified,objectKey:o.objectKey}));var E=new ft({}),R=async(t,e)=>{let{objectKey:r,filePath:o}=e;v.logCreate(f,B(t,
|
|
61
|
+
r));let n=Pt.getType(o);return await E.send(new dt({Bucket:t,Key:r,Body:yt(o),...n&&
|
|
62
|
+
{ContentType:n}})),{objectKey:r}},se=async(t,e,r)=>{v.logTag(f,B(t,e)),await E.send(
|
|
63
|
+
new gt({Bucket:t,Key:e,Tagging:{TagSet:bt({...r,ManagedBy:"EZ4"})}}))},ce=async(t,e)=>{
|
|
64
|
+
v.logDelete(f,B(t,e));try{return await E.send(new St({Bucket:t,Key:e})),!0}catch(r){
|
|
65
|
+
if(!(r instanceof kt))throw r;return!1}};var ae=()=>({equals:Et,create:ie,replace:Ct,preview:Rt,update:jt,delete:ht}),Et=(t,e)=>!!t.
|
|
66
|
+
result&&t.result.lastModified===e.result?.lastModified,Rt=async(t,e)=>{let r=t.parameters,
|
|
67
|
+
o=e.parameters,n=wt({...r,dependencies:t.dependencies,lastModified:await C(r.filePath)},
|
|
68
|
+
{...o,dependencies:e.dependencies,lastModified:t.result?.lastModified});if(n.counts)
|
|
69
|
+
return{...n,name:r.objectKey}},Ct=async(t,e,r)=>{if(e.result)throw new Bt(f,t.entryId,
|
|
70
|
+
e.entryId);return ie(t,r)},ie=async(t,e)=>{let r=t.parameters,o=x(f,"bucket",e),
|
|
71
|
+
n=await C(r.filePath),{objectKey:s}=await R(o,r);return await pe(o,s,r.tags,t.parameters.
|
|
72
|
+
tags),{lastModified:n,bucketName:o}},jt=async(t,e)=>{let{result:r,parameters:o}=t;
|
|
73
|
+
if(!r)return;let{objectKey:n,tags:s}=o,c=Ot(r,o,e.parameters);return await pe(r.
|
|
74
|
+
bucketName,n,s,e.parameters.tags),c},ht=async t=>{let{result:e,parameters:r}=t;e&&
|
|
75
|
+
await ce(e.bucketName,r.objectKey)},C=async t=>{let{mtime:e}=await xt(t);return e.
|
|
76
|
+
getTime()},Ot=async(t,e,r)=>{let o=await C(e.filePath);if(o<=t.lastModified&&e.filePath===
|
|
77
|
+
r.filePath)return t;let{bucketName:n}=t,{objectKey:s}=r;return await R(n,{...e,objectKey:s}),
|
|
78
|
+
{lastModified:o,bucketName:n}},pe=async(t,e,r,o)=>{let n=r??{};!vt(n,o??{})&&await se(
|
|
79
|
+
t,e,n)};var me=()=>{Tt(l,ae())};import{isBucketService as T}from"@ez4/storage/library";import{createPermission as Dt}from"@ez4/aws-function";import{attachEntry as zt,linkDependency as At}from"@ez4/stateful";import{createPolicyDocument as Nt}from"@ez4/aws-identity";var ue=t=>`arn:aws:s3:\
|
|
80
|
+
::${t}`,le=t=>Nt([{resourceIds:[`arn:aws:s3:::${t}-*`,`arn:aws:s3:::${t}-*/*`],permissions:[
|
|
81
|
+
"s3:ListBucket","s3:PutObject","s3:GetObject","s3:DeleteObject"]}]);var ye=(t,e,r)=>{let o=r.bucketName,n=J(o),s=zt(t,{type:u,entryId:n,dependencies:[],
|
|
82
|
+
parameters:r});return e&&(Dt(t,s,e,{fromService:r.bucketName,getPermission:()=>({
|
|
83
|
+
principal:"s3.amazonaws.com",sourceArn:ue(o)})}),At(t,s.entryId,e.entryId)),s};import{linkServiceExtras as Ht}from"@ez4/project/library";import{getFunctionState as Kt,
|
|
84
|
+
tryGetFunctionState as Ut}from"@ez4/aws-function";import{isRoleState as ke}from"@ez4/aws-identity";import{createFunction as Mt}from"@ez4/aws-function";import{join as It}from"node:path";import{getDefinitionsObject as Ft}from"@ez4/project/library";
|
|
85
|
+
import{MappingServiceName as Lt}from"@ez4/aws-function";import{bundleFunction as qt}from"@ez4/aws-common";
|
|
86
|
+
var fe=async(t,e)=>{let{extras:r,debug:o,handler:n,listener:s}=e,c=Ft(t);return qt(
|
|
87
|
+
Lt,{templateFile:It(import.meta.dirname,"../lib/event.ts"),filePrefix:"s3",define:{
|
|
88
|
+
...c},handler:n,listener:s,extras:r,debug:o})};var de=(t,e,r)=>Mt(t,e,{handlerName:"s3EntryPoint",functionName:r.functionName,sourceFile:r.
|
|
89
|
+
handler.sourceFile,description:r.description,variables:r.variables,timeout:r.timeout,
|
|
90
|
+
memory:r.memory,tags:r.tags,getFunctionBundle:o=>{let n=o.getDependencies();return fe(
|
|
91
|
+
n,r)}});import{getServiceName as j}from"@ez4/project/library";import{getRandomName as $t}from"@ez4/aws-common";
|
|
92
|
+
import{toKebabCase as h}from"@ez4/utils";var ge=async(t,e)=>{if(t.globalName)return j(
|
|
93
|
+
t.globalName,e);let r=j(t,e),o=await $t(16);return`${r.substring(0,46)}-${o}`},O=(t,e)=>`${h(
|
|
94
|
+
t.name)}-${h(e)}`,Se=(t,e,r)=>`${j(t,r)}-${h(e)}`;var k=class extends Error{constructor(){super("Execution role for S3 is missing.")}};var be=(t,e,r,o)=>{if(!e.events)return;if(!o.role||!ke(o.role))throw new k;let{events:n}=e,
|
|
95
|
+
{handler:s,listener:c}=n,i=O(e,s.name),d=Ut(o,i,r);if(d)return d;let g=de(t,o.role,
|
|
96
|
+
{functionName:Se(e,s.name,r),description:s.description,timeout:n.timeout??30,memory:n.
|
|
97
|
+
memory??192,extras:e.extras,debug:r.debug,variables:{...r.variables,...e.variables,
|
|
98
|
+
...n.variables},handler:{functionName:s.name,sourceFile:s.file},...c&&{listener:{
|
|
99
|
+
functionName:c.name,sourceFile:c.file}}});return o.setServiceState(g,i,r),g},Pe=(t,e,r,o)=>{
|
|
100
|
+
if(!e.extras||!e.events)return;if(!o.role||!ke(o.role))throw new k;let{handler:n}=e.
|
|
101
|
+
events,s=O(e,n.name),c=Kt(o,s,r);Ht(t,c.entryId,e.extras)};import{readdir as Gt}from"node:fs/promises";import{join as xe,relative as Be}from"node:path";
|
|
102
|
+
import{createBucketObject as _t}from"@ez4/aws-bucket";var we=async(t,e,r)=>{let o=process.
|
|
103
|
+
cwd(),n=xe(o,r),s=await Gt(n,{withFileTypes:!0,recursive:!0});for(let c of s){if(!c.
|
|
104
|
+
isFile())continue;let i=xe(c.parentPath,c.name);_t(t,e,{objectKey:Be(n,i),filePath:Be(
|
|
105
|
+
o,i)})}};var ve=(t,e,r)=>{let o=Q(t,e.name,r);return{entryIds:[o.entryId],constructor:`ma\
|
|
106
|
+
ke('${o.parameters.bucketName}')`,from:"@ez4/aws-bucket/client",module:"Client"}};var Ee=t=>{let{service:e,options:r,context:o}=t;return T(e)?ve(o,e,r):null},Re=async t=>{
|
|
107
|
+
let{state:e,service:r,options:o,context:n}=t;if(!T(r))return;let{localPath:s,autoExpireDays:c,
|
|
108
|
+
events:i,cors:d}=r,g=await ge(r,o),Oe=be(e,r,o,n),N=ye(e,Oe,{eventsPath:i?.path,
|
|
109
|
+
bucketName:g,autoExpireDays:c,localPath:s,cors:d});n.setServiceState(N,r,o),s&&await we(
|
|
110
|
+
e,N,s)},Ce=t=>{let{state:e,service:r,options:o,context:n}=t;T(r)&&Pe(e,r,o,n)};import{ServiceType as Vt}from"@ez4/storage/library";import{createPolicy as Wt,tryGetPolicy as Zt}from"@ez4/aws-identity";
|
|
111
|
+
import{getServiceName as Jt}from"@ez4/project/library";var je=t=>{let{state:e,serviceType:r,options:o}=t;if(r!==Vt)return null;let n=Jt(
|
|
112
|
+
"",o),s=`${n}-bucket-policy`;return Zt(e,s)??Wt(e,{policyDocument:le(n),policyName:s})};var he=!1,kn=()=>{he||(Qt(),Xt(),Yt(),er(),tr("@ez4/aws-bucket",{"deploy:prepare\
|
|
113
|
+
ExecutionPolicy":je,"deploy:prepareLinkedService":Ee,"deploy:prepareResources":Re,
|
|
114
|
+
"deploy:connectResources":Ce}),Z(),ne(),me(),he=!0)};import{getRegion as rr}from"@ez4/aws-identity";var xn=t=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.
|
|
115
|
+
test(t),Bn=async t=>{let e=await rr();return`${t}.s3.${e}.amazonaws.com`};import{attachEntry as or}from"@ez4/stateful";import{hashData as nr}from"@ez4/utils";var Cn=(t,e,r,o)=>{let n=nr(y,e.entryId,r.entryId);return or(t,{type:y,entryId:n,
|
|
116
|
+
dependencies:[e.entryId,r.entryId],parameters:o})};var On=t=>t.type===y;import{attachEntry as sr}from"@ez4/stateful";import{hashData as cr}from"@ez4/utils";var An=(t,e,r)=>{let o=r.objectKey,n=cr(l,e.entryId,o);return sr(t,{type:l,entryId:n,
|
|
117
|
+
dependencies:[e.entryId],parameters:r})};export{a as BucketServiceName,u as BucketServiceType,f as ObjectServiceName,l as ObjectServiceType,
|
|
118
|
+
S as PolicyServiceName,y as PolicyServiceType,ue as buildBucketArn,ye as createBucket,
|
|
119
|
+
de as createBucketEventFunction,An as createBucketObject,Cn as createBucketPolicy,
|
|
120
|
+
J as createBucketStateId,Bn as getBucketDomain,x as getBucketName,Wr as getBucketObjectFiles,
|
|
121
|
+
B as getBucketObjectPath,Q as getBucketState,le as getPolicyDocument,xn as isBucketDomain,
|
|
122
|
+
Vr as isBucketObjectState,On as isBucketPolicyState,et as isBucketState,kn as registerTriggers};
|
package/dist/object/client.d.ts
CHANGED
|
@@ -8,4 +8,4 @@ export type CreateResponse = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare const putObject: (bucketName: string, request: CreateRequest) => Promise<CreateResponse>;
|
|
10
10
|
export declare const tagObject: (bucketName: string, objectKey: string, tags: ResourceTags) => Promise<void>;
|
|
11
|
-
export declare const deleteObject: (bucketName: string, objectKey: string) => Promise<
|
|
11
|
+
export declare const deleteObject: (bucketName: string, objectKey: string) => Promise<boolean>;
|
package/dist/object/types.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { EntryState } from '@ez4/stateful';
|
|
2
1
|
import type { ResourceTags } from '@ez4/aws-common';
|
|
3
|
-
import type {
|
|
2
|
+
import type { EntryState } from '@ez4/stateful';
|
|
3
|
+
import type { CreateRequest } from './client.js';
|
|
4
4
|
export declare const ObjectServiceName = "AWS:S3/Object";
|
|
5
5
|
export declare const ObjectServiceType = "aws:s3.object";
|
|
6
6
|
export type ObjectParameters = CreateRequest & {
|
|
7
7
|
tags?: ResourceTags;
|
|
8
8
|
};
|
|
9
|
-
export type ObjectResult =
|
|
9
|
+
export type ObjectResult = {
|
|
10
10
|
lastModified: number;
|
|
11
11
|
bucketName: string;
|
|
12
12
|
};
|
package/dist/object/utils.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export declare const isBucketObjectState: (resource: EntryState) => resource is
|
|
|
4
4
|
export declare const getBucketObjectPath: (bucketName: string, objectKey: string) => string;
|
|
5
5
|
export declare const getBucketObjectFiles: (context: StepContext) => {
|
|
6
6
|
lastModified: number | undefined;
|
|
7
|
-
objectKey: string
|
|
7
|
+
objectKey: string;
|
|
8
8
|
}[];
|
package/dist/policy/client.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export type CreateResponse = {
|
|
|
7
7
|
bucketName: string;
|
|
8
8
|
};
|
|
9
9
|
export declare const createPolicy: (request: CreateRequest) => Promise<CreateResponse>;
|
|
10
|
-
export declare const deletePolicy: (bucketName: string) => Promise<
|
|
10
|
+
export declare const deletePolicy: (bucketName: string) => Promise<boolean>;
|
package/dist/policy/types.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const PolicyServiceName = "AWS:S3/Policy";
|
|
|
5
5
|
export declare const PolicyServiceType = "aws:s3.policy";
|
|
6
6
|
export type GetRole = (context: StepContext) => Promise<RoleDocument> | RoleDocument;
|
|
7
7
|
export type PolicyParameters = {
|
|
8
|
+
fromService: string;
|
|
8
9
|
getRole: GetRole;
|
|
9
10
|
};
|
|
10
11
|
export type PolicyResult = CreateResponse;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { ExtraSource } from '@ez4/project/library';
|
|
2
|
-
|
|
1
|
+
import type { DeployOptions, EventContext, ExtraSource } from '@ez4/project/library';
|
|
2
|
+
import type { BucketService } from '@ez4/storage/library';
|
|
3
|
+
export declare const prepareLinkedClient: (context: EventContext, service: BucketService, options: DeployOptions) => ExtraSource;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DeployOptions, EventContext } from '@ez4/project/library';
|
|
2
|
+
import type { BucketService } from '@ez4/storage/library';
|
|
3
|
+
import type { EntryStates } from '@ez4/stateful';
|
|
4
|
+
export declare const prepareEvents: (state: EntryStates, service: BucketService, options: DeployOptions, context: EventContext) => import("@ez4/aws-function").FunctionState | undefined;
|
|
5
|
+
export declare const connectEvents: (state: EntryStates, service: BucketService, options: DeployOptions, context: EventContext) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { PolicyResourceEvent } from '@ez4/project/library';
|
|
2
|
-
export declare const prepareExecutionPolicy: (event: PolicyResourceEvent) => import("@ez4/
|
|
2
|
+
export declare const prepareExecutionPolicy: (event: PolicyResourceEvent) => import("@ez4/stateful").EntryState<string> | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ServiceEvent, ConnectResourceEvent, PrepareResourceEvent } from '@ez4/project/library';
|
|
2
|
-
export declare const prepareLinkedServices: (event: ServiceEvent) =>
|
|
2
|
+
export declare const prepareLinkedServices: (event: ServiceEvent) => import("@ez4/project/library").ExtraSource | null;
|
|
3
3
|
export declare const prepareBucketServices: (event: PrepareResourceEvent) => Promise<void>;
|
|
4
4
|
export declare const connectBucketServices: (event: ConnectResourceEvent) => void;
|
package/dist/triggers/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DeployOptions } from '@ez4/project/library';
|
|
2
2
|
import { BucketService } from '@ez4/storage/library';
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const getBucketName: (service: BucketService, options: DeployOptions) => Promise<string>;
|
|
4
|
+
export declare const getInternalName: (service: BucketService, suffixName: string) => string;
|
|
4
5
|
export declare const getFunctionName: (service: BucketService, handlerName: string, options: DeployOptions) => string;
|
package/lib/event.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { S3Event, Context } from 'aws-lambda';
|
|
2
|
+
import type { Service } from '@ez4/common';
|
|
3
|
+
import type { Bucket } from '@ez4/storage';
|
|
4
|
+
|
|
5
|
+
import { ServiceEventType } from '@ez4/common';
|
|
6
|
+
import { BucketEventType } from '@ez4/storage';
|
|
7
|
+
|
|
8
|
+
declare const __EZ4_CONTEXT: object;
|
|
9
|
+
|
|
10
|
+
declare function handle(event: Bucket.Event, context: object): Promise<any>;
|
|
11
|
+
declare function dispatch(event: Service.Event<Bucket.Event>, context: object): Promise<void>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Entrypoint to handle S3 notifications.
|
|
15
|
+
*/
|
|
16
|
+
export async function s3EntryPoint(event: S3Event, context: Context): Promise<void> {
|
|
17
|
+
let currentRequest: Bucket.Event | undefined;
|
|
18
|
+
|
|
19
|
+
const request = {
|
|
20
|
+
requestId: context.awsRequestId
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
await onBegin(request);
|
|
25
|
+
|
|
26
|
+
for (const record of event.Records) {
|
|
27
|
+
const eventType = getKnownEventType(record.eventName);
|
|
28
|
+
|
|
29
|
+
const { bucket, object } = record.s3;
|
|
30
|
+
|
|
31
|
+
currentRequest = {
|
|
32
|
+
...request,
|
|
33
|
+
eventType,
|
|
34
|
+
bucketName: bucket.name,
|
|
35
|
+
objectSize: object.size,
|
|
36
|
+
objectKey: object.key
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
await onReady(currentRequest);
|
|
40
|
+
|
|
41
|
+
await handle(currentRequest, __EZ4_CONTEXT);
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
await onError(error, currentRequest ?? request);
|
|
45
|
+
} finally {
|
|
46
|
+
await onEnd(request);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const getKnownEventType = (eventName: string) => {
|
|
51
|
+
if (eventName.startsWith('ObjectCreated:')) {
|
|
52
|
+
return BucketEventType.Create;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (eventName.startsWith('ObjectRemoved:')) {
|
|
56
|
+
return BucketEventType.Delete;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
throw new Error(`Event type ${eventName} isn't supported.`);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const onBegin = async (request: Partial<Bucket.Incoming>) => {
|
|
63
|
+
return dispatch(
|
|
64
|
+
{
|
|
65
|
+
type: ServiceEventType.Begin,
|
|
66
|
+
request
|
|
67
|
+
},
|
|
68
|
+
__EZ4_CONTEXT
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const onReady = async (request: Partial<Bucket.Incoming>) => {
|
|
73
|
+
return dispatch(
|
|
74
|
+
{
|
|
75
|
+
type: ServiceEventType.Ready,
|
|
76
|
+
request
|
|
77
|
+
},
|
|
78
|
+
__EZ4_CONTEXT
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const onError = async (error: Error, request: Partial<Bucket.Incoming>) => {
|
|
83
|
+
console.error(error);
|
|
84
|
+
|
|
85
|
+
return dispatch(
|
|
86
|
+
{
|
|
87
|
+
type: ServiceEventType.Error,
|
|
88
|
+
request,
|
|
89
|
+
error
|
|
90
|
+
},
|
|
91
|
+
__EZ4_CONTEXT
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const onEnd = async (request: Partial<Bucket.Incoming>) => {
|
|
96
|
+
return dispatch(
|
|
97
|
+
{
|
|
98
|
+
type: ServiceEventType.End,
|
|
99
|
+
request
|
|
100
|
+
},
|
|
101
|
+
__EZ4_CONTEXT
|
|
102
|
+
);
|
|
103
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ez4/aws-bucket",
|
|
3
3
|
"description": "EZ4: Self-managed AWS S3 bucket provider",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.16.0",
|
|
5
5
|
"author": "Silas B.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"directory": "packages/aws-bucket"
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
|
-
"node": ">=
|
|
17
|
+
"node": ">=22.3.0"
|
|
18
18
|
},
|
|
19
19
|
"exports": {
|
|
20
20
|
".": {
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@aws-sdk/client-s3": "^3.758.0",
|
|
50
50
|
"@aws-sdk/s3-request-presigner": "^3.758.0",
|
|
51
|
-
"@ez4/aws-common": "^0.
|
|
52
|
-
"@ez4/aws-function": "^0.
|
|
53
|
-
"@ez4/aws-identity": "^0.
|
|
54
|
-
"@ez4/project": "^0.
|
|
55
|
-
"@ez4/stateful": "^0.
|
|
56
|
-
"@ez4/storage": "^0.
|
|
57
|
-
"@ez4/utils": "^0.
|
|
51
|
+
"@ez4/aws-common": "^0.16.0",
|
|
52
|
+
"@ez4/aws-function": "^0.16.0",
|
|
53
|
+
"@ez4/aws-identity": "^0.16.0",
|
|
54
|
+
"@ez4/project": "^0.16.0",
|
|
55
|
+
"@ez4/stateful": "^0.16.0",
|
|
56
|
+
"@ez4/storage": "^0.16.0",
|
|
57
|
+
"@ez4/utils": "^0.16.0",
|
|
58
58
|
"mime": "^3.0.0"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { DeployOptions, PrepareResourceEvent } from '@ez4/project/library';
|
|
2
|
-
import { BucketService } from '@ez4/storage/library';
|
|
3
|
-
export declare const prepareBucketServices: (event: PrepareResourceEvent) => Promise<void>;
|
|
4
|
-
export declare const getFunctionName: (service: BucketService, handlerName: string, options: DeployOptions) => string;
|
package/lib/function.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { S3Event, Context } from 'aws-lambda';
|
|
2
|
-
import { BucketEvent, BucketEventType } from '@ez4/storage';
|
|
3
|
-
|
|
4
|
-
declare function next(event: BucketEvent, context: object): Promise<any>;
|
|
5
|
-
|
|
6
|
-
declare const __EZ4_CONTEXT: object;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Entrypoint to handle S3 notifications.
|
|
10
|
-
*/
|
|
11
|
-
export async function s3EntryPoint(event: S3Event, context: Context): Promise<void> {
|
|
12
|
-
for (const record of event.Records) {
|
|
13
|
-
const eventType = getKnownEventType(record.eventName);
|
|
14
|
-
|
|
15
|
-
if (!eventType) {
|
|
16
|
-
throw new Error(`Event type ${eventType} isn't supported.`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const { bucket, object } = record.s3;
|
|
20
|
-
|
|
21
|
-
const request = {
|
|
22
|
-
requestId: context.awsRequestId,
|
|
23
|
-
bucketName: bucket.name,
|
|
24
|
-
objectSize: object.size,
|
|
25
|
-
objectKey: object.key,
|
|
26
|
-
eventType
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
await next(request, __EZ4_CONTEXT);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const getKnownEventType = (eventName: string) => {
|
|
34
|
-
if (eventName.startsWith('ObjectCreated:')) {
|
|
35
|
-
return BucketEventType.Create;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (eventName.startsWith('ObjectRemoved:')) {
|
|
39
|
-
return BucketEventType.Delete;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return undefined;
|
|
43
|
-
};
|