@ez4/aws-bucket 0.13.0 → 0.15.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/README.md CHANGED
@@ -30,6 +30,7 @@ Ensure the user performing deployments has the permissions below:
30
30
  "s3:DeleteObject",
31
31
  "s3:PutBucketCORS",
32
32
  "s3:PutLifecycleConfiguration",
33
+ "s3:PutBucketNotification",
33
34
  "s3:PutBucketPolicy",
34
35
  "s3:DeleteBucketPolicy",
35
36
  "s3:PutBucketTagging",
@@ -1,15 +1,23 @@
1
- import type { ResourceTags } from '@ez4/aws-common';
1
+ import type { Arn, ResourceTags } from '@ez4/aws-common';
2
2
  import type { Bucket } from '@ez4/storage';
3
+ import { Event } from '@aws-sdk/client-s3';
3
4
  export type CreateRequest = {
4
5
  bucketName: string;
5
6
  };
6
7
  export type CreateResponse = {
7
8
  bucketName: string;
8
9
  };
10
+ export type UpdateNotificationRequest = {
11
+ functionArn?: Arn;
12
+ eventsPath?: string;
13
+ eventsType: Event[];
14
+ };
15
+ export declare const isBucketEmpty: (bucketName: string) => Promise<boolean>;
9
16
  export declare const createBucket: (request: CreateRequest) => Promise<CreateResponse>;
17
+ export declare const deleteBucket: (bucketName: string) => Promise<void>;
10
18
  export declare const tagBucket: (bucketName: string, tags: ResourceTags) => Promise<void>;
11
19
  export declare const updateCorsConfiguration: (bucketName: string, cors: Bucket.Cors) => Promise<void>;
12
20
  export declare const deleteCorsConfiguration: (bucketName: string) => Promise<void>;
13
21
  export declare const createLifecycle: (bucketName: string, autoExpireDays: number) => Promise<void>;
14
22
  export declare const deleteLifecycle: (bucketName: string) => Promise<void>;
15
- export declare const deleteBucket: (bucketName: string) => Promise<void>;
23
+ export declare const updateEventNotifications: (bucketName: string, request: UpdateNotificationRequest) => Promise<void>;
@@ -0,0 +1,3 @@
1
+ import type { EntryState } from '@ez4/stateful';
2
+ import type { BucketEventFunctionParameters } from './types.js';
3
+ export declare const bundleBucketEventFunction: (dependencies: EntryState[], parameters: BucketEventFunctionParameters) => Promise<string>;
@@ -0,0 +1,4 @@
1
+ import type { RoleState } from '@ez4/aws-identity';
2
+ import type { EntryState, EntryStates } from '@ez4/stateful';
3
+ import type { BucketEventFunctionParameters } from './types.js';
4
+ export declare const createBucketEventFunction: <E extends EntryState>(state: EntryStates<E>, roleState: RoleState, parameters: BucketEventFunctionParameters) => import("@ez4/aws-function").FunctionState;
@@ -0,0 +1,12 @@
1
+ import type { FunctionParameters } from '@ez4/aws-function';
2
+ import type { ExtraSource } from '@ez4/project/library';
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;
10
+ extras?: Record<string, ExtraSource>;
11
+ debug?: boolean;
12
+ };
@@ -1,3 +1,4 @@
1
1
  import type { EntryState, EntryStates } from '@ez4/stateful';
2
+ import type { FunctionState } from '@ez4/aws-function';
2
3
  import type { BucketParameters, BucketState } from './types.js';
3
- export declare const createBucket: <E extends EntryState>(state: EntryStates<E>, parameters: BucketParameters) => BucketState;
4
+ export declare const createBucket: <E extends EntryState>(state: EntryStates<E>, functionState: FunctionState | undefined, parameters: BucketParameters) => BucketState;
@@ -1,16 +1,19 @@
1
+ import type { Arn, ResourceTags } from '@ez4/aws-common';
1
2
  import type { EntryState } from '@ez4/stateful';
2
- import type { ResourceTags } from '@ez4/aws-common';
3
3
  import type { Bucket } from '@ez4/storage';
4
4
  import type { CreateRequest, CreateResponse } from './client.js';
5
5
  export declare const BucketServiceName = "AWS:S3/Bucket";
6
6
  export declare const BucketServiceType = "aws:s3.bucket";
7
7
  export type BucketParameters = CreateRequest & {
8
+ eventsPath?: string;
8
9
  autoExpireDays?: number;
9
10
  localPath?: string;
10
11
  tags?: ResourceTags;
11
12
  cors?: Bucket.Cors;
12
13
  };
13
- export type BucketResult = CreateResponse;
14
+ export type BucketResult = CreateResponse & {
15
+ functionArn: Arn | undefined;
16
+ };
14
17
  export type BucketState = EntryState & {
15
18
  type: typeof BucketServiceType;
16
19
  parameters: BucketParameters;
package/dist/main.cjs CHANGED
@@ -1,88 +1,122 @@
1
- "use strict";var Ae=Object.create;var w=Object.defineProperty;var Fe=Object.getOwnPropertyDescriptor;var Ue=Object.getOwnPropertyNames;var Ge=Object.getPrototypeOf,We=Object.prototype.hasOwnProperty;var Ze=(e,t)=>{for(var r in t)w(e,r,{get:t[r],enumerable:!0})},I=(e,t,r,o)=>{if(t&&
2
- typeof t=="object"||typeof t=="function")for(let s of Ue(t))!We.call(e,s)&&s!==r&&
3
- w(e,s,{get:()=>t[s],enumerable:!(o=Fe(t,s))||o.enumerable});return e};var Je=(e,t,r)=>(r=e!=null?Ae(Ge(e)):{},I(t||!e||!e.__esModule?w(r,"default",{value:e,
4
- enumerable:!0}):r,e)),Qe=e=>I(w({},"__esModule",{value:!0}),e);var Bt={};Ze(Bt,{BucketServiceName:()=>n,BucketServiceType:()=>p,ObjectServiceName:()=>y,
5
- ObjectServiceType:()=>m,PolicyServiceName:()=>g,PolicyServiceType:()=>u,createBucket:()=>z,
6
- createBucketObject:()=>bt,createBucketPolicy:()=>kt,getBucketDomain:()=>St,getBucketName:()=>b,
7
- getBucketObjectFiles:()=>it,getBucketObjectPath:()=>B,getBucketState:()=>tt,getBucketStateId:()=>C,
8
- getPolicyDocument:()=>N,isBucketDomain:()=>dt,isBucketObjectState:()=>nt,isBucketPolicyState:()=>Pt,
9
- isBucketState:()=>Y,registerTriggers:()=>gt});module.exports=Qe(Bt);var Ne=require("@ez4/aws-common"),ze=require("@ez4/aws-identity"),Ie=require("@ez4/storage/library"),
10
- Le=require("@ez4/project/library");var Q=require("@ez4/aws-common");var F=require("@ez4/aws-common"),P=require("@ez4/utils");var i=require("@ez4/aws-common"),a=require("@aws-sdk/client-s3");var n="AWS:S3/Bucket",p="aws:s3.bucket";var f=new a.S3Client({}),L=async e=>{let{bucketName:t}=e;return i.Logger.logCreate(
11
- n,t),await f.send(new a.CreateBucketCommand({Bucket:t})),{bucketName:t}},q=async(e,t)=>{
12
- i.Logger.logTag(n,e),await f.send(new a.PutBucketTaggingCommand({Bucket:e,Tagging:{
13
- TagSet:(0,i.getTagList)({...t,ManagedBy:"EZ4"})}}))},K=async(e,t)=>{i.Logger.logUpdate(
14
- n,`${e} CORS`),await f.send(new a.PutBucketCorsCommand({Bucket:e,CORSConfiguration:{
15
- CORSRules:[{ID:"ID0",AllowedOrigins:t.allowOrigins,AllowedMethods:t.allowMethods,
16
- AllowedHeaders:t.allowHeaders,ExposeHeaders:t.exposeHeaders,MaxAgeSeconds:t.maxAge}]}}))},
17
- H=async e=>{i.Logger.logDelete(n,`${e} CORS`),await f.send(new a.DeleteBucketCorsCommand(
18
- {Bucket:e}))},M=async(e,t)=>{i.Logger.logCreate(n,`${e} lifecycle`),await f.send(
19
- new a.PutBucketLifecycleConfigurationCommand({Bucket:e,LifecycleConfiguration:{Rules:[
20
- {ID:"ID0",Status:a.ExpirationStatus.Enabled,Filter:{Prefix:"*"},Expiration:{Days:t}}]}}))},
21
- $=async e=>{i.Logger.logDelete(n,`${e} lifecycle`),await f.send(new a.DeleteBucketLifecycleCommand(
22
- {Bucket:e}))},A=async e=>{i.Logger.logDelete(n,e),await f.send(new a.DeleteBucketCommand(
23
- {Bucket:e}))};var U=()=>({equals:Ve,create:G,replace:Ye,preview:Xe,update:_e,delete:et}),Ve=(e,t)=>!!e.
24
- result&&e.result.bucketName===t.result?.bucketName,Xe=async(e,t)=>{let r={...e.parameters,
25
- dependencies:e.dependencies},o={...t.parameters,dependencies:t.dependencies},s=(0,P.deepCompare)(
26
- r,o);if(s.counts)return{...s,name:r.bucketName}},Ye=async(e,t)=>{if(t.result)throw new F.ReplaceResourceError(
27
- n,e.entryId,t.entryId);return G(e)},G=async e=>{let t=e.parameters,{bucketName:r}=await L(
28
- t);return await W(r,t,void 0),await Z(r,t,void 0),await J(r,t.tags,void 0),{bucketName:r}},
29
- _e=async(e,t)=>{let{result:r,parameters:o}=e;if(!r)return;let s=r.bucketName;await W(
30
- s,o,t.parameters),await Z(s,o,t.parameters),await J(s,o.tags,t.parameters.tags)},
31
- et=async e=>{let t=e.result;t&&await A(t.bucketName)},W=async(e,t,r)=>{if(!(t.cors&&
32
- r?.cors&&(0,P.deepEqual)(t.cors,r.cors))){if(t.cors)return K(e,t.cors);if(r?.cors)
33
- return H(e)}},Z=async(e,t,r)=>{if(t.autoExpireDays!==r?.autoExpireDays){if(t.autoExpireDays)
34
- return M(e,t.autoExpireDays);if(r?.autoExpireDays)return $(e)}},J=async(e,t,r)=>{
35
- let o=t??{};!(0,P.deepEqual)(o,r??{})&&await q(e,o)};var V=()=>{(0,Q.registerProvider)(p,U())};var ce=require("@ez4/aws-common");var re=require("@ez4/aws-common");var R=require("@ez4/stateful"),X=require("@ez4/aws-common"),j=require("@ez4/utils");var Y=e=>e.type===p,C=e=>(0,j.hashData)(p,(0,j.toKebabCase)(e)),tt=(e,t)=>{let r=(0,R.getEntry)(
36
- e,C(t));if(!Y(r))throw new R.EntryNotFoundError(r.entryId);return r},b=(e,t,r)=>{
37
- let o=r.getDependencies(p).at(0)?.result;if(!o?.bucketName)throw new X.IncompleteResourceError(
38
- e,t,"bucketName");return o.bucketName};var v=require("@ez4/aws-common"),S=require("@aws-sdk/client-s3");var g="AWS:S3/Policy",u="aws:s3.policy";var _=new S.S3Client({}),ee=async e=>{let{bucketName:t,role:r}=e;return v.Logger.
39
- logCreate(g,t),await _.send(new S.PutBucketPolicyCommand({Bucket:t,Policy:JSON.stringify(
40
- r)})),{bucketName:t}},te=async e=>{v.Logger.logDelete(g,e),await _.send(new S.DeleteBucketPolicyCommand(
41
- {Bucket:e}))};var oe=()=>({equals:rt,create:se,replace:st,preview:ot,update:ct,delete:at}),rt=(e,t)=>!!e.
42
- result&&e.result.bucketName===t.result?.bucketName,ot=async()=>{},st=async(e,t,r)=>{
43
- if(t.result)throw new re.ReplaceResourceError(g,e.entryId,t.entryId);return se(e,
44
- r)},se=async(e,t)=>{let r=e.parameters,o=b(g,"policy",t),s=await r.getRole(t);return await ee(
45
- {bucketName:o,role:s}),{bucketName:o}},ct=async()=>{},at=async e=>{let t=e.result;
46
- t&&await te(t.bucketName)};var ae=()=>{(0,ce.registerProvider)(u,oe())};var de=require("@ez4/aws-common");var ue=require("node:fs/promises"),ye=require("@ez4/aws-common"),E=require("@ez4/utils");var k=require("@ez4/aws-common"),ne=require("node:fs"),ie=Je(require("mime"),1),
47
- l=require("@aws-sdk/client-s3");var y="AWS:S3/Object",m="aws:s3.object";var nt=e=>e.type===m,B=(e,t)=>`${e}/${t}`,it=e=>e.getDependencies(m).map(({result:r})=>({
48
- lastModified:r?.lastModified,objectKey:r?.objectKey}));var T=new l.S3Client({}),h=async(e,t)=>{let{objectKey:r,filePath:o}=t;k.Logger.logCreate(
49
- y,B(e,r));let s=ie.default.getType(o);return await T.send(new l.PutObjectCommand(
50
- {Bucket:e,Key:r,Body:(0,ne.createReadStream)(o),...s&&{ContentType:s}})),{objectKey:r}},
51
- pe=async(e,t,r)=>{k.Logger.logTag(y,B(e,t)),await T.send(new l.PutObjectTaggingCommand(
52
- {Bucket:e,Key:t,Tagging:{TagSet:(0,k.getTagList)({...r,ManagedBy:"EZ4"})}}))},me=async(e,t)=>{
53
- k.Logger.logDelete(y,B(e,t)),await T.send(new l.DeleteObjectCommand({Bucket:e,Key:t}))};var le=()=>({equals:pt,create:fe,replace:ut,preview:mt,update:yt,delete:lt}),pt=(e,t)=>!!e.
54
- result&&e.result.objectKey===t.result?.objectKey,mt=async(e,t)=>{let r=e.parameters,
55
- o=t.parameters,s=(0,E.deepCompare)({...r,dependencies:e.dependencies,lastModified:await D(
1
+ "use strict";var gt=Object.create;var j=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var St=Object.getOwnPropertyNames;var kt=Object.getPrototypeOf,bt=Object.prototype.hasOwnProperty;var Pt=(e,t)=>{for(var r in t)j(e,r,{get:t[r],enumerable:!0})},W=(e,t,r,o)=>{if(t&&
2
+ typeof t=="object"||typeof t=="function")for(let n of St(t))!bt.call(e,n)&&n!==r&&
3
+ j(e,n,{get:()=>t[n],enumerable:!(o=dt(t,n))||o.enumerable});return e};var xt=(e,t,r)=>(r=e!=null?gt(kt(e)):{},W(t||!e||!e.__esModule?j(r,"default",{value:e,
4
+ enumerable:!0}):r,e)),Bt=e=>W(j({},"__esModule",{value:!0}),e);var Zt={};Pt(Zt,{BucketServiceName:()=>i,BucketServiceType:()=>u,ObjectServiceName:()=>g,
5
+ ObjectServiceType:()=>l,PolicyServiceName:()=>S,PolicyServiceType:()=>f,buildBucketArn:()=>q,
6
+ createBucket:()=>M,createBucketEventFunction:()=>H,createBucketObject:()=>Wt,createBucketPolicy:()=>Gt,
7
+ getBucketDomain:()=>_t,getBucketName:()=>R,getBucketObjectFiles:()=>At,getBucketObjectPath:()=>E,
8
+ getBucketState:()=>jt,getBucketStateId:()=>b,getPolicyDocument:()=>K,isBucketDomain:()=>Ut,
9
+ isBucketObjectState:()=>zt,isBucketPolicyState:()=>Vt,isBucketState:()=>fe,registerTriggers:()=>$t});
10
+ module.exports=Bt(Zt);var ot=require("@ez4/aws-common"),nt=require("@ez4/aws-identity"),st=require("@ez4/aws-function"),
11
+ ct=require("@ez4/storage/library"),at=require("@ez4/project/library");var ue=require("@ez4/aws-common");var ne=require("@ez4/aws-common"),z=require("@ez4/aws-function"),k=require("@ez4/utils");var p=require("@ez4/aws-common"),c=require("@aws-sdk/client-s3");var i="AWS:S3/Bucket",u="aws:s3.bucket";var y=new c.S3Client({}),Z=async e=>(p.Logger.logFetch(i,e),!(await y.send(new c.ListObjectsV2Command(
12
+ {Bucket:e,MaxKeys:1}))).Contents?.length),J=async e=>{let{bucketName:t}=e;return p.Logger.
13
+ logCreate(i,t),await y.send(new c.CreateBucketCommand({Bucket:t})),{bucketName:t}},
14
+ Q=async e=>{p.Logger.logDelete(i,e),await y.send(new c.DeleteBucketCommand({Bucket:e}))},
15
+ X=async(e,t)=>{p.Logger.logTag(i,e),await y.send(new c.PutBucketTaggingCommand({
16
+ Bucket:e,Tagging:{TagSet:(0,p.getTagList)({...t,ManagedBy:"EZ4"})}}))},Y=async(e,t)=>{
17
+ p.Logger.logUpdate(i,`${e} CORS`),await y.send(new c.PutBucketCorsCommand({Bucket:e,
18
+ CORSConfiguration:{CORSRules:[{ID:"ID0",AllowedOrigins:t.allowOrigins,AllowedMethods:t.
19
+ allowMethods,AllowedHeaders:t.allowHeaders,ExposeHeaders:t.exposeHeaders,MaxAgeSeconds:t.
20
+ maxAge}]}}))},ee=async e=>{p.Logger.logDelete(i,`${e} CORS`),await y.send(new c.DeleteBucketCorsCommand(
21
+ {Bucket:e}))},te=async(e,t)=>{p.Logger.logCreate(i,`${e} lifecycle`),await y.send(
22
+ new c.PutBucketLifecycleConfigurationCommand({Bucket:e,LifecycleConfiguration:{Rules:[
23
+ {ID:"ID0",Status:c.ExpirationStatus.Enabled,Filter:{Prefix:"*"},Expiration:{Days:t}}]}}))},
24
+ re=async e=>{p.Logger.logDelete(i,`${e} lifecycle`),await y.send(new c.DeleteBucketLifecycleCommand(
25
+ {Bucket:e}))},oe=async(e,t)=>{p.Logger.logUpdate(i,`${e} event notifications`);let{
26
+ functionArn:r,eventsPath:o,eventsType:n}=t;await y.send(new c.PutBucketNotificationConfigurationCommand(
27
+ {Bucket:e,SkipDestinationValidation:!0,NotificationConfiguration:{...r&&{LambdaFunctionConfigurations:[
28
+ {Id:"ID0",LambdaFunctionArn:r,Events:n,...o&&{Filter:{Key:{FilterRules:[{Name:"p\
29
+ refix",Value:o}]}}}}]}}}))};var se=()=>({equals:wt,create:ce,replace:Et,preview:Rt,update:vt,delete:Ct}),wt=(e,t)=>!!e.
30
+ result&&e.result.bucketName===t.result?.bucketName,Rt=async(e,t)=>{let r={...e.parameters,
31
+ dependencies:e.dependencies},o={...t.parameters,dependencies:t.dependencies},n=(0,k.deepCompare)(
32
+ r,o);if(n.counts)return{...n,name:r.bucketName}},Et=async(e,t,r)=>{if(t.result)throw new ne.ReplaceResourceError(
33
+ i,e.entryId,t.entryId);return ce(e,r)},ce=async(e,t)=>{let r=e.parameters,o=(0,z.tryGetFunctionArn)(
34
+ t),{bucketName:n}=await J(r);await ae(n,r,void 0),await ie(n,r,void 0),await pe(
35
+ n,r.tags,void 0);let s={eventsPath:r.eventsPath,functionArn:o};return await me(n,
36
+ s,{}),{bucketName:n,functionArn:o}},vt=async(e,t,r)=>{let{result:o,parameters:n}=e;
37
+ if(!o)return;let s=o.bucketName,a=(0,z.tryGetFunctionArn)(r),m=t.result?.functionArn;
38
+ await ae(s,n,t.parameters),await ie(s,n,t.parameters),await pe(s,n.tags,t.parameters.
39
+ tags);let B={eventsPath:n.eventsPath,functionArn:a},w={eventsPath:t.parameters.eventsPath,
40
+ functionArn:m};return await me(s,B,w),{...o,functionArn:a}},Ct=async e=>{let t=e.
41
+ result;t&&await Z(t.bucketName)&&await Q(t.bucketName)},ae=async(e,t,r)=>{if(!(t.
42
+ cors&&r?.cors&&(0,k.deepEqual)(t.cors,r.cors))){if(t.cors)return Y(e,t.cors);if(r?.
43
+ cors)return ee(e)}},ie=async(e,t,r)=>{if(t.autoExpireDays!==r?.autoExpireDays){if(t.
44
+ autoExpireDays)return te(e,t.autoExpireDays);if(r?.autoExpireDays)return re(e)}},
45
+ pe=async(e,t,r)=>{let o=t??{};!(0,k.deepEqual)(o,r??{})&&await X(e,o)},me=async(e,t,r)=>{
46
+ !(0,k.deepEqual)(t,r)&&await oe(e,{eventsType:["s3:ObjectCreated:*","s3:ObjectRe\
47
+ moved:*"],...t})};var ye=()=>{(0,ue.registerProvider)(u,se())};var xe=require("@ez4/aws-common");var ke=require("@ez4/aws-common");var O=require("@ez4/stateful"),le=require("@ez4/aws-common"),h=require("@ez4/utils");var fe=e=>e.type===u,b=e=>(0,h.hashData)(u,(0,h.toKebabCase)(e)),jt=(e,t)=>{let r=(0,O.getEntry)(
48
+ e,b(t));if(!fe(r))throw new O.EntryNotFoundError(r.entryId);return r},R=(e,t,r)=>{
49
+ let o=r.getDependencies(u).at(0)?.result;if(!o?.bucketName)throw new le.IncompleteResourceError(
50
+ e,t,"bucketName");return o.bucketName};var A=require("@ez4/aws-common"),P=require("@aws-sdk/client-s3");var S="AWS:S3/Policy",f="aws:s3.policy";var ge=new P.S3Client({}),de=async e=>{let{bucketName:t,role:r}=e;return A.Logger.
51
+ logCreate(S,t),await ge.send(new P.PutBucketPolicyCommand({Bucket:t,Policy:JSON.
52
+ stringify(r)})),{bucketName:t}},Se=async e=>{A.Logger.logDelete(S,e),await ge.send(
53
+ new P.DeleteBucketPolicyCommand({Bucket:e}))};var be=()=>({equals:Ot,create:Pe,replace:Tt,preview:ht,update:Nt,delete:Dt}),Ot=(e,t)=>!!e.
54
+ result&&e.result.bucketName===t.result?.bucketName,ht=async()=>{},Tt=async(e,t,r)=>{
55
+ if(t.result)throw new ke.ReplaceResourceError(S,e.entryId,t.entryId);return Pe(e,
56
+ r)},Pe=async(e,t)=>{let r=e.parameters,o=R(S,"policy",t),n=await r.getRole(t);return await de(
57
+ {bucketName:o,role:n}),{bucketName:o}},Nt=async()=>{},Dt=async e=>{let t=e.result;
58
+ t&&await Se(t.bucketName)};var Be=()=>{(0,xe.registerProvider)(f,be())};var Ne=require("@ez4/aws-common");var Ce=require("node:fs/promises"),je=require("@ez4/aws-common"),T=require("@ez4/utils");var x=require("@ez4/aws-common"),we=require("node:fs"),Re=xt(require("mime"),1),
59
+ d=require("@aws-sdk/client-s3");var g="AWS:S3/Object",l="aws:s3.object";var zt=e=>e.type===l,E=(e,t)=>`${e}/${t}`,At=e=>e.getDependencies(l).map(({result:r})=>({
60
+ lastModified:r?.lastModified,objectKey:r?.objectKey}));var F=new d.S3Client({}),I=async(e,t)=>{let{objectKey:r,filePath:o}=t;x.Logger.logCreate(
61
+ g,E(e,r));let n=Re.default.getType(o);return await F.send(new d.PutObjectCommand(
62
+ {Bucket:e,Key:r,Body:(0,we.createReadStream)(o),...n&&{ContentType:n}})),{objectKey:r}},
63
+ Ee=async(e,t,r)=>{x.Logger.logTag(g,E(e,t)),await F.send(new d.PutObjectTaggingCommand(
64
+ {Bucket:e,Key:t,Tagging:{TagSet:(0,x.getTagList)({...r,ManagedBy:"EZ4"})}}))},ve=async(e,t)=>{
65
+ x.Logger.logDelete(g,E(e,t)),await F.send(new d.DeleteObjectCommand({Bucket:e,Key:t}))};var Oe=()=>({equals:Ft,create:he,replace:Lt,preview:It,update:qt,delete:Kt}),Ft=(e,t)=>!!e.
66
+ result&&e.result.objectKey===t.result?.objectKey,It=async(e,t)=>{let r=e.parameters,
67
+ o=t.parameters,n=(0,T.deepCompare)({...r,dependencies:e.dependencies,lastModified:await L(
56
68
  r.filePath)},{...o,dependencies:t.dependencies,lastModified:e.result?.lastModified});
57
- if(s.counts)return{...s,name:r.objectKey}},ut=async(e,t,r)=>{if(t.result)throw new ye.ReplaceResourceError(
58
- y,e.entryId,t.entryId);return fe(e,r)},fe=async(e,t)=>{let r=e.parameters,o=b(y,
59
- "bucket",t),s=await D(r.filePath),{objectKey:c}=await h(o,r);return await ge(o,c,
60
- r.tags,e.parameters.tags),{lastModified:s,bucketName:o,objectKey:c}},yt=async(e,t)=>{
61
- let{result:r,parameters:o}=e;if(!r)return;let{bucketName:s,objectKey:c}=r,d=ft(r,
62
- o,t.parameters);return await ge(s,c,o.tags,t.parameters.tags),d},lt=async e=>{let t=e.
63
- result;t&&await me(t.bucketName,t.objectKey)},D=async e=>{let{mtime:t}=await(0,ue.stat)(
64
- e);return t.getTime()},ft=async(e,t,r)=>{let o=await D(t.filePath);if(o<=e.lastModified&&
65
- t.filePath===r.filePath)return e;let{bucketName:s,objectKey:c}=e;return await h(
66
- s,{...t,objectKey:c}),{lastModified:o,bucketName:s,objectKey:c}},ge=async(e,t,r,o)=>{
67
- let s=r??{};!(0,E.deepEqual)(s,o??{})&&await pe(e,t,s)};var Se=()=>{(0,de.registerProvider)(m,le())};var Pe=require("@ez4/aws-identity");var ke=require("@ez4/aws-identity"),N=e=>(0,ke.createPolicyDocument)([{resourceIds:[
68
- `arn:aws:s3:::${e}-*`,`arn:aws:s3:::${e}-*/*`],permissions:["s3:ListBucket","s3:\
69
- PutObject","s3:GetObject","s3:DeleteObject"]}]);var be=async e=>{let{state:t,options:r}=e,{resourcePrefix:o,projectName:s}=r,c=`${o}\
70
- -${s}`;return(0,Pe.createPolicy)(t,{policyName:`${c}-bucket-policy`,policyDocument:N(
71
- c)})};var Ce=require("@ez4/project/library"),Ee=require("@ez4/storage/library");var Be=require("@ez4/utils"),xe=require("@ez4/stateful");var z=(e,t)=>{let r=(0,Be.toKebabCase)(t.bucketName),o=C(t.bucketName);return(0,xe.attachEntry)(
72
- e,{type:p,entryId:o,dependencies:[],parameters:{...t,bucketName:r}})};var we=require("node:fs/promises"),x=require("node:path"),Re=require("@ez4/aws-bucket"),
73
- je=async(e,t,r)=>{let o=(0,x.join)(process.cwd(),r),s=await(0,we.readdir)(o,{withFileTypes:!0,
74
- recursive:!0});for(let c of s){if(!c.isFile())continue;let d=(0,x.join)(c.parentPath,
75
- c.name),O=(0,x.relative)(o,d);(0,Re.createBucketObject)(e,t,{objectKey:O,filePath:d})}};var Oe=async e=>{let{state:t,service:r,options:o}=e;if(!(0,Ee.isBucketService)(r))
76
- return;let{autoExpireDays:s,localPath:c,cors:d}=r,O=z(t,{bucketName:(0,Ce.getServiceName)(
77
- r,o),autoExpireDays:s,localPath:c,cors:d});c&&await je(t,O,c)};var ve=require("@ez4/storage/library"),Te=require("@ez4/project/library"),he=async e=>{
78
- let{service:t,options:r}=e;return(0,ve.isBucketService)(t)?{constructor:`make('${(0,Te.getServiceName)(
79
- t,r)}')`,module:"Client",from:"@ez4/aws-bucket/client"}:null};var De=!1,gt=()=>{De||((0,Ne.registerTriggers)(),(0,ze.registerTriggers)(),(0,Ie.registerTriggers)(),
80
- (0,Le.createTrigger)("@ez4/aws-bucket",{"deploy:prepareExecutionPolicy":be,"depl\
81
- oy:prepareLinkedService":he,"deploy:prepareResources":Oe}),V(),ae(),Se(),De=!0)};var qe=require("@ez4/aws-identity"),dt=e=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.test(
82
- e),St=async e=>{let t=await(0,qe.getRegion)();return`${e}.s3.${t}.amazonaws.com`};var Ke=require("@ez4/stateful"),He=require("@ez4/utils");var kt=(e,t,r,o)=>{let s=(0,He.hashData)(u,t.entryId,r.entryId);return(0,Ke.attachEntry)(
83
- e,{type:u,entryId:s,dependencies:[t.entryId,r.entryId],parameters:o})};var Pt=e=>e.type===u;var Me=require("@ez4/stateful"),$e=require("@ez4/utils");var bt=(e,t,r)=>{let o=r.objectKey,s=(0,$e.hashData)(m,t.entryId,o);return(0,Me.attachEntry)(
84
- e,{type:m,entryId:s,dependencies:[t.entryId],parameters:r})};0&&(module.exports={BucketServiceName,BucketServiceType,ObjectServiceName,ObjectServiceType,
85
- PolicyServiceName,PolicyServiceType,createBucket,createBucketObject,createBucketPolicy,
86
- getBucketDomain,getBucketName,getBucketObjectFiles,getBucketObjectPath,getBucketState,
87
- getBucketStateId,getPolicyDocument,isBucketDomain,isBucketObjectState,isBucketPolicyState,
88
- isBucketState,registerTriggers});
69
+ if(n.counts)return{...n,name:r.objectKey}},Lt=async(e,t,r)=>{if(t.result)throw new je.ReplaceResourceError(
70
+ g,e.entryId,t.entryId);return he(e,r)},he=async(e,t)=>{let r=e.parameters,o=R(g,
71
+ "bucket",t),n=await L(r.filePath),{objectKey:s}=await I(o,r);return await Te(o,s,
72
+ r.tags,e.parameters.tags),{lastModified:n,bucketName:o,objectKey:s}},qt=async(e,t)=>{
73
+ let{result:r,parameters:o}=e;if(!r)return;let{bucketName:n,objectKey:s}=r,a=Mt(r,
74
+ o,t.parameters);return await Te(n,s,o.tags,t.parameters.tags),a},Kt=async e=>{let t=e.
75
+ result;t&&await ve(t.bucketName,t.objectKey)},L=async e=>{let{mtime:t}=await(0,Ce.stat)(
76
+ e);return t.getTime()},Mt=async(e,t,r)=>{let o=await L(t.filePath);if(o<=e.lastModified&&
77
+ t.filePath===r.filePath)return e;let{bucketName:n,objectKey:s}=e;return await I(
78
+ n,{...t,objectKey:s}),{lastModified:o,bucketName:n,objectKey:s}},Te=async(e,t,r,o)=>{
79
+ let n=r??{};!(0,T.deepEqual)(n,o??{})&&await Ee(e,t,n)};var De=()=>{(0,Ne.registerProvider)(l,Oe())};var G=require("@ez4/aws-identity"),D=require("@ez4/storage/library"),Ze=require("@ez4/project/library"),
80
+ V=require("@ez4/aws-function");var Ae=require("@ez4/aws-function"),N=require("@ez4/stateful"),Fe=require("@ez4/utils");var ze=require("@ez4/aws-identity"),q=e=>`arn:aws:s3:::${e}`,K=e=>(0,ze.createPolicyDocument)(
81
+ [{resourceIds:[`arn:aws:s3:::${e}-*`,`arn:aws:s3:::${e}-*/*`],permissions:["s3:L\
82
+ istBucket","s3:PutObject","s3:GetObject","s3:DeleteObject"]}]);var M=(e,t,r)=>{let o=(0,Fe.toKebabCase)(r.bucketName),n=b(r.bucketName),s=(0,N.attachEntry)(
83
+ e,{type:u,entryId:n,dependencies:[],parameters:{...r,bucketName:o}});return t&&((0,Ae.createPermission)(
84
+ e,s,t,{getPermission:()=>({principal:"s3.amazonaws.com",sourceArn:q(o)})}),(0,N.linkDependency)(
85
+ e,s.entryId,t.entryId)),s};var He=require("@ez4/aws-function");var Ie=require("node:path"),Le=require("@ez4/project/library"),qe=require("@ez4/aws-function"),
86
+ Ke=require("@ez4/aws-common"),Me=async(e,t)=>{let{extras:r,debug:o,handler:n,listener:s}=t,
87
+ a=(0,Le.getDefinitionsObject)(e);return(0,Ke.bundleFunction)(qe.MappingServiceName,
88
+ {templateFile:(0,Ie.join)(__dirname,"../lib/event.ts"),filePrefix:"s3",define:{...a},
89
+ handler:n,listener:s,extras:r,debug:o})};var H=(e,t,r)=>(0,He.createFunction)(e,t,{handlerName:"s3EntryPoint",functionName:r.
90
+ functionName,sourceFile:r.handler.sourceFile,description:r.description,variables:r.
91
+ variables,timeout:r.timeout,memory:r.memory,tags:r.tags,getFunctionBundle:o=>{let n=o.
92
+ getDependencies();return Me(n,r)}});var $=require("@ez4/project/library"),$e=require("@ez4/aws-common"),Ue=require("@ez4/utils"),
93
+ U=async(e,t)=>{if(e.globalName)return e.globalName;let r=(0,$.getServiceName)(e,
94
+ t).substring(0,46),o=await(0,$e.getRandomName)(16);return`${r}-${o}`},_=(e,t,r)=>`${(0,$.getServiceName)(
95
+ e,r)}-${(0,Ue.toKebabCase)(t)}`;var _e=require("node:fs/promises"),v=require("node:path"),Ge=require("@ez4/aws-bucket"),
96
+ Ve=async(e,t,r)=>{let o=(0,v.join)(process.cwd(),r),n=await(0,_e.readdir)(o,{withFileTypes:!0,
97
+ recursive:!0});for(let s of n){if(!s.isFile())continue;let a=(0,v.join)(s.parentPath,
98
+ s.name),m=(0,v.relative)(o,a);(0,Ge.createBucketObject)(e,t,{objectKey:m,filePath:a})}};var We=e=>({entryId:b(e),constructor:`make('${e}')`,from:"@ez4/aws-bucket/client",
99
+ module:"Client"});var C=class extends Error{constructor(){super("Execution role for S3 is missing.")}};var Je=async e=>{let{service:t,options:r}=e;if(!(0,D.isBucketService)(t))return null;
100
+ let o=await U(t,r);return We(o)},Qe=async e=>{let{state:t,service:r,role:o,options:n}=e;
101
+ if(!(0,D.isBucketService)(r))return;if(!o||!(0,G.isRoleState)(o))throw new C;let{
102
+ localPath:s,autoExpireDays:a,events:m,cors:B}=r,w=await U(r,n),lt=Ht(t,r,o,n),ft=M(
103
+ t,lt,{eventsPath:m?.path,bucketName:w,autoExpireDays:a,localPath:s,cors:B});s&&await Ve(
104
+ t,ft,s)},Xe=e=>{let{state:t,service:r,role:o,options:n}=e;if(!(0,D.isBucketService)(
105
+ r)||!r.extras||!r.events)return;if(!o||!(0,G.isRoleState)(o))throw new C;let s=r.
106
+ events.handler,a=_(r,s.name,n),m=(0,V.getFunction)(t,o,a);m&&(0,Ze.linkServiceExtras)(
107
+ t,m.entryId,r.extras)},Ht=(e,t,r,o)=>{if(!t.events)return;let n=t.events,{handler:s,
108
+ listener:a}=t.events,m=_(t,s.name,o),B=n.timeout??30,w=n.memory??192;return(0,V.getFunction)(
109
+ e,r,m)??H(e,r,{functionName:m,description:s.description,timeout:B,memory:w,extras:t.
110
+ extras,debug:o.debug,variables:{...t.variables},handler:{functionName:s.name,sourceFile:s.
111
+ file},...a&&{listener:{functionName:a.name,sourceFile:a.file}}})};var Ye=require("@ez4/project/library"),et=require("@ez4/aws-identity");var tt=e=>{let{state:t,options:r}=e,o=(0,Ye.getServiceName)("",r);return(0,et.createPolicy)(
112
+ t,{policyName:`${o}-bucket-policy`,policyDocument:K(o)})};var rt=!1,$t=()=>{rt||((0,ot.registerTriggers)(),(0,nt.registerTriggers)(),(0,st.registerTriggers)(),
113
+ (0,ct.registerTriggers)(),(0,at.createTrigger)("@ez4/aws-bucket",{"deploy:prepar\
114
+ eExecutionPolicy":tt,"deploy:prepareLinkedService":Je,"deploy:prepareResources":Qe,
115
+ "deploy:connectResources":Xe}),ye(),Be(),De(),rt=!0)};var it=require("@ez4/aws-identity"),Ut=e=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.test(
116
+ e),_t=async e=>{let t=await(0,it.getRegion)();return`${e}.s3.${t}.amazonaws.com`};var pt=require("@ez4/stateful"),mt=require("@ez4/utils");var Gt=(e,t,r,o)=>{let n=(0,mt.hashData)(f,t.entryId,r.entryId);return(0,pt.attachEntry)(
117
+ e,{type:f,entryId:n,dependencies:[t.entryId,r.entryId],parameters:o})};var Vt=e=>e.type===f;var ut=require("@ez4/stateful"),yt=require("@ez4/utils");var Wt=(e,t,r)=>{let o=r.objectKey,n=(0,yt.hashData)(l,t.entryId,o);return(0,ut.attachEntry)(
118
+ e,{type:l,entryId:n,dependencies:[t.entryId],parameters:r})};0&&(module.exports={BucketServiceName,BucketServiceType,ObjectServiceName,ObjectServiceType,
119
+ PolicyServiceName,PolicyServiceType,buildBucketArn,createBucket,createBucketEventFunction,
120
+ createBucketObject,createBucketPolicy,getBucketDomain,getBucketName,getBucketObjectFiles,
121
+ getBucketObjectPath,getBucketState,getBucketStateId,getPolicyDocument,isBucketDomain,
122
+ isBucketObjectState,isBucketPolicyState,isBucketState,registerTriggers});
package/dist/main.d.ts CHANGED
@@ -4,6 +4,8 @@ export * from './utils/policy.js';
4
4
  export * from './bucket/service.js';
5
5
  export * from './bucket/types.js';
6
6
  export * from './bucket/utils.js';
7
+ export * from './bucket/function/service.js';
8
+ export * from './bucket/function/types.js';
7
9
  export * from './policy/service.js';
8
10
  export * from './policy/types.js';
9
11
  export * from './policy/utils.js';
package/dist/main.mjs CHANGED
@@ -1,81 +1,113 @@
1
- import{registerTriggers as lt}from"@ez4/aws-common";import{registerTriggers as ft}from"@ez4/aws-identity";
2
- import{registerTriggers as gt}from"@ez4/storage/library";import{createTrigger as dt}from"@ez4/project/library";import{registerProvider as Be}from"@ez4/aws-common";import{ReplaceResourceError as fe}from"@ez4/aws-common";import{deepCompare as ge,
3
- deepEqual as T}from"@ez4/utils";import{getTagList as se,Logger as p}from"@ez4/aws-common";import{CreateBucketCommand as ce,
4
- DeleteBucketCommand as ae,PutBucketTaggingCommand as ne,PutBucketCorsCommand as ie,
5
- DeleteBucketCorsCommand as pe,PutBucketLifecycleConfigurationCommand as me,DeleteBucketLifecycleCommand as ue,
6
- ExpirationStatus as ye,S3Client as le}from"@aws-sdk/client-s3";var a="AWS:S3/Bucket",n="aws:s3.bucket";var m=new le({}),w=async e=>{let{bucketName:t}=e;return p.logCreate(a,t),await m.
7
- send(new ce({Bucket:t})),{bucketName:t}},R=async(e,t)=>{p.logTag(a,e),await m.send(
8
- new ne({Bucket:e,Tagging:{TagSet:se({...t,ManagedBy:"EZ4"})}}))},j=async(e,t)=>{
9
- p.logUpdate(a,`${e} CORS`),await m.send(new ie({Bucket:e,CORSConfiguration:{CORSRules:[
10
- {ID:"ID0",AllowedOrigins:t.allowOrigins,AllowedMethods:t.allowMethods,AllowedHeaders:t.
11
- allowHeaders,ExposeHeaders:t.exposeHeaders,MaxAgeSeconds:t.maxAge}]}}))},C=async e=>{
12
- p.logDelete(a,`${e} CORS`),await m.send(new pe({Bucket:e}))},E=async(e,t)=>{p.logCreate(
13
- a,`${e} lifecycle`),await m.send(new me({Bucket:e,LifecycleConfiguration:{Rules:[
14
- {ID:"ID0",Status:ye.Enabled,Filter:{Prefix:"*"},Expiration:{Days:t}}]}}))},O=async e=>{
15
- p.logDelete(a,`${e} lifecycle`),await m.send(new ue({Bucket:e}))},v=async e=>{p.
16
- logDelete(a,e),await m.send(new ae({Bucket:e}))};var h=()=>({equals:de,create:D,replace:ke,preview:Se,update:Pe,delete:be}),de=(e,t)=>!!e.
17
- result&&e.result.bucketName===t.result?.bucketName,Se=async(e,t)=>{let r={...e.parameters,
18
- dependencies:e.dependencies},o={...t.parameters,dependencies:t.dependencies},s=ge(
19
- r,o);if(s.counts)return{...s,name:r.bucketName}},ke=async(e,t)=>{if(t.result)throw new fe(
20
- a,e.entryId,t.entryId);return D(e)},D=async e=>{let t=e.parameters,{bucketName:r}=await w(
21
- t);return await N(r,t,void 0),await z(r,t,void 0),await I(r,t.tags,void 0),{bucketName:r}},
22
- Pe=async(e,t)=>{let{result:r,parameters:o}=e;if(!r)return;let s=r.bucketName;await N(
23
- s,o,t.parameters),await z(s,o,t.parameters),await I(s,o.tags,t.parameters.tags)},
24
- be=async e=>{let t=e.result;t&&await v(t.bucketName)},N=async(e,t,r)=>{if(!(t.cors&&
25
- r?.cors&&T(t.cors,r.cors))){if(t.cors)return j(e,t.cors);if(r?.cors)return C(e)}},
26
- z=async(e,t,r)=>{if(t.autoExpireDays!==r?.autoExpireDays){if(t.autoExpireDays)return E(
27
- e,t.autoExpireDays);if(r?.autoExpireDays)return O(e)}},I=async(e,t,r)=>{let o=t??
28
- {};!T(o,r??{})&&await R(e,o)};var L=()=>{Be(n,h())};import{registerProvider as qe}from"@ez4/aws-common";import{ReplaceResourceError as he}from"@ez4/aws-common";import{EntryNotFoundError as xe,getEntry as we}from"@ez4/stateful";import{IncompleteResourceError as Re}from"@ez4/aws-common";
29
- import{hashData as je,toKebabCase as Ce}from"@ez4/utils";var Ee=e=>e.type===n,k=e=>je(n,Ce(e)),Mt=(e,t)=>{let r=we(e,k(t));if(!Ee(r))throw new xe(
30
- r.entryId);return r},g=(e,t,r)=>{let o=r.getDependencies(n).at(0)?.result;if(!o?.
31
- bucketName)throw new Re(e,t,"bucketName");return o.bucketName};import{Logger as q}from"@ez4/aws-common";import{S3Client as Oe,PutBucketPolicyCommand as ve,
32
- DeleteBucketPolicyCommand as Te}from"@aws-sdk/client-s3";var f="AWS:S3/Policy",u="aws:s3.policy";var K=new Oe({}),H=async e=>{let{bucketName:t,role:r}=e;return q.logCreate(f,t),
33
- await K.send(new ve({Bucket:t,Policy:JSON.stringify(r)})),{bucketName:t}},M=async e=>{
34
- q.logDelete(f,e),await K.send(new Te({Bucket:e}))};var $=()=>({equals:De,create:A,replace:ze,preview:Ne,update:Ie,delete:Le}),De=(e,t)=>!!e.
35
- result&&e.result.bucketName===t.result?.bucketName,Ne=async()=>{},ze=async(e,t,r)=>{
36
- if(t.result)throw new he(f,e.entryId,t.entryId);return A(e,r)},A=async(e,t)=>{let r=e.
37
- parameters,o=g(f,"policy",t),s=await r.getRole(t);return await H({bucketName:o,role:s}),
38
- {bucketName:o}},Ie=async()=>{},Le=async e=>{let t=e.result;t&&await M(t.bucketName)};var F=()=>{qe(u,$())};import{registerProvider as tt}from"@ez4/aws-common";import{stat as Ge}from"node:fs/promises";import{ReplaceResourceError as We}from"@ez4/aws-common";
39
- import{deepCompare as Ze,deepEqual as Je}from"@ez4/utils";import{getTagList as Ke,Logger as P}from"@ez4/aws-common";import{createReadStream as He}from"node:fs";
40
- import Me from"mime";import{PutObjectCommand as $e,PutObjectTaggingCommand as Ae,
41
- DeleteObjectCommand as Fe,S3Client as Ue}from"@aws-sdk/client-s3";var y="AWS:S3/Object",i="aws:s3.object";var cr=e=>e.type===i,d=(e,t)=>`${e}/${t}`,ar=e=>e.getDependencies(i).map(({result:r})=>({
42
- lastModified:r?.lastModified,objectKey:r?.objectKey}));var b=new Ue({}),B=async(e,t)=>{let{objectKey:r,filePath:o}=t;P.logCreate(y,d(e,
43
- r));let s=Me.getType(o);return await b.send(new $e({Bucket:e,Key:r,Body:He(o),...s&&
44
- {ContentType:s}})),{objectKey:r}},U=async(e,t,r)=>{P.logTag(y,d(e,t)),await b.send(
45
- new Ae({Bucket:e,Key:t,Tagging:{TagSet:Ke({...r,ManagedBy:"EZ4"})}}))},G=async(e,t)=>{
46
- P.logDelete(y,d(e,t)),await b.send(new Fe({Bucket:e,Key:t}))};var W=()=>({equals:Qe,create:Z,replace:Xe,preview:Ve,update:Ye,delete:_e}),Qe=(e,t)=>!!e.
47
- result&&e.result.objectKey===t.result?.objectKey,Ve=async(e,t)=>{let r=e.parameters,
48
- o=t.parameters,s=Ze({...r,dependencies:e.dependencies,lastModified:await x(r.filePath)},
49
- {...o,dependencies:t.dependencies,lastModified:e.result?.lastModified});if(s.counts)
50
- return{...s,name:r.objectKey}},Xe=async(e,t,r)=>{if(t.result)throw new We(y,e.entryId,
51
- t.entryId);return Z(e,r)},Z=async(e,t)=>{let r=e.parameters,o=g(y,"bucket",t),s=await x(
52
- r.filePath),{objectKey:c}=await B(o,r);return await J(o,c,r.tags,e.parameters.tags),
53
- {lastModified:s,bucketName:o,objectKey:c}},Ye=async(e,t)=>{let{result:r,parameters:o}=e;
54
- if(!r)return;let{bucketName:s,objectKey:c}=r,l=et(r,o,t.parameters);return await J(
55
- s,c,o.tags,t.parameters.tags),l},_e=async e=>{let t=e.result;t&&await G(t.bucketName,
56
- t.objectKey)},x=async e=>{let{mtime:t}=await Ge(e);return t.getTime()},et=async(e,t,r)=>{
57
- let o=await x(t.filePath);if(o<=e.lastModified&&t.filePath===r.filePath)return e;
58
- let{bucketName:s,objectKey:c}=e;return await B(s,{...t,objectKey:c}),{lastModified:o,
59
- bucketName:s,objectKey:c}},J=async(e,t,r,o)=>{let s=r??{};!Je(s,o??{})&&await U(
60
- e,t,s)};var Q=()=>{tt(i,W())};import{createPolicy as ot}from"@ez4/aws-identity";import{createPolicyDocument as rt}from"@ez4/aws-identity";var V=e=>rt([{resourceIds:[
61
- `arn:aws:s3:::${e}-*`,`arn:aws:s3:::${e}-*/*`],permissions:["s3:ListBucket","s3:\
62
- PutObject","s3:GetObject","s3:DeleteObject"]}]);var X=async e=>{let{state:t,options:r}=e,{resourcePrefix:o,projectName:s}=r,c=`${o}\
63
- -${s}`;return ot(t,{policyName:`${c}-bucket-policy`,policyDocument:V(c)})};import{getServiceName as pt}from"@ez4/project/library";import{isBucketService as mt}from"@ez4/storage/library";import{toKebabCase as st}from"@ez4/utils";import{attachEntry as ct}from"@ez4/stateful";var Y=(e,t)=>{let r=st(t.bucketName),o=k(t.bucketName);return ct(e,{type:n,entryId:o,
64
- dependencies:[],parameters:{...t,bucketName:r}})};import{readdir as at}from"node:fs/promises";import{join as _,relative as nt}from"node:path";
65
- import{createBucketObject as it}from"@ez4/aws-bucket";var ee=async(e,t,r)=>{let o=_(
66
- process.cwd(),r),s=await at(o,{withFileTypes:!0,recursive:!0});for(let c of s){if(!c.
67
- isFile())continue;let l=_(c.parentPath,c.name),S=nt(o,l);it(e,t,{objectKey:S,filePath:l})}};var te=async e=>{let{state:t,service:r,options:o}=e;if(!mt(r))return;let{autoExpireDays:s,
68
- localPath:c,cors:l}=r,S=Y(t,{bucketName:pt(r,o),autoExpireDays:s,localPath:c,cors:l});
69
- c&&await ee(t,S,c)};import{isBucketService as ut}from"@ez4/storage/library";import{getServiceName as yt}from"@ez4/project/library";
70
- var re=async e=>{let{service:t,options:r}=e;return ut(t)?{constructor:`make('${yt(
71
- t,r)}')`,module:"Client",from:"@ez4/aws-bucket/client"}:null};var oe=!1,so=()=>{oe||(lt(),ft(),gt(),dt("@ez4/aws-bucket",{"deploy:prepareExecu\
72
- tionPolicy":X,"deploy:prepareLinkedService":re,"deploy:prepareResources":te}),L(),
73
- F(),Q(),oe=!0)};import{getRegion as St}from"@ez4/aws-identity";var no=e=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.
74
- test(e),io=async e=>{let t=await St();return`${e}.s3.${t}.amazonaws.com`};import{attachEntry as kt}from"@ez4/stateful";import{hashData as Pt}from"@ez4/utils";var lo=(e,t,r,o)=>{let s=Pt(u,t.entryId,r.entryId);return kt(e,{type:u,entryId:s,
75
- dependencies:[t.entryId,r.entryId],parameters:o})};var So=e=>e.type===u;import{attachEntry as bt}from"@ez4/stateful";import{hashData as Bt}from"@ez4/utils";var xo=(e,t,r)=>{let o=r.objectKey,s=Bt(i,t.entryId,o);return bt(e,{type:i,entryId:s,
76
- dependencies:[t.entryId],parameters:r})};export{a as BucketServiceName,n as BucketServiceType,y as ObjectServiceName,i as ObjectServiceType,
77
- f as PolicyServiceName,u as PolicyServiceType,Y as createBucket,xo as createBucketObject,
78
- lo as createBucketPolicy,io as getBucketDomain,g as getBucketName,ar as getBucketObjectFiles,
79
- d as getBucketObjectPath,Mt as getBucketState,k as getBucketStateId,V as getPolicyDocument,
80
- no as isBucketDomain,cr as isBucketObjectState,So as isBucketPolicyState,Ee as isBucketState,
81
- so as registerTriggers};
1
+ import{registerTriggers as $t}from"@ez4/aws-common";import{registerTriggers as Ut}from"@ez4/aws-identity";
2
+ import{registerTriggers as _t}from"@ez4/aws-function";import{registerTriggers as Gt}from"@ez4/storage/library";
3
+ import{createTrigger as Vt}from"@ez4/project/library";import{registerProvider as $e}from"@ez4/aws-common";import{ReplaceResourceError as Fe}from"@ez4/aws-common";import{tryGetFunctionArn as q}from"@ez4/aws-function";
4
+ import{deepCompare as Ie,deepEqual as B}from"@ez4/utils";import{getTagList as Re,Logger as p}from"@ez4/aws-common";import{S3Client as Ee,
5
+ ListObjectsV2Command as ve,CreateBucketCommand as Ce,DeleteBucketCommand as je,PutBucketTaggingCommand as Oe,
6
+ PutBucketCorsCommand as he,DeleteBucketCorsCommand as Te,PutBucketLifecycleConfigurationCommand as Ne,
7
+ DeleteBucketLifecycleCommand as De,PutBucketNotificationConfigurationCommand as ze,
8
+ ExpirationStatus as Ae}from"@aws-sdk/client-s3";var a="AWS:S3/Bucket",u="aws:s3.bucket";var m=new Ee({}),h=async e=>(p.logFetch(a,e),!(await m.send(new ve({Bucket:e,MaxKeys:1}))).
9
+ Contents?.length),T=async e=>{let{bucketName:t}=e;return p.logCreate(a,t),await m.
10
+ send(new Ce({Bucket:t})),{bucketName:t}},N=async e=>{p.logDelete(a,e),await m.send(
11
+ new je({Bucket:e}))},D=async(e,t)=>{p.logTag(a,e),await m.send(new Oe({Bucket:e,
12
+ Tagging:{TagSet:Re({...t,ManagedBy:"EZ4"})}}))},z=async(e,t)=>{p.logUpdate(a,`${e}\
13
+ CORS`),await m.send(new he({Bucket:e,CORSConfiguration:{CORSRules:[{ID:"ID0",AllowedOrigins:t.
14
+ allowOrigins,AllowedMethods:t.allowMethods,AllowedHeaders:t.allowHeaders,ExposeHeaders:t.
15
+ exposeHeaders,MaxAgeSeconds:t.maxAge}]}}))},A=async e=>{p.logDelete(a,`${e} CORS`),
16
+ await m.send(new Te({Bucket:e}))},F=async(e,t)=>{p.logCreate(a,`${e} lifecycle`),
17
+ await m.send(new Ne({Bucket:e,LifecycleConfiguration:{Rules:[{ID:"ID0",Status:Ae.
18
+ Enabled,Filter:{Prefix:"*"},Expiration:{Days:t}}]}}))},I=async e=>{p.logDelete(a,
19
+ `${e} lifecycle`),await m.send(new De({Bucket:e}))},L=async(e,t)=>{p.logUpdate(a,
20
+ `${e} event notifications`);let{functionArn:r,eventsPath:o,eventsType:n}=t;await m.
21
+ send(new ze({Bucket:e,SkipDestinationValidation:!0,NotificationConfiguration:{...r&&
22
+ {LambdaFunctionConfigurations:[{Id:"ID0",LambdaFunctionArn:r,Events:n,...o&&{Filter:{
23
+ Key:{FilterRules:[{Name:"prefix",Value:o}]}}}}]}}}))};var K=()=>({equals:Le,create:M,replace:Ke,preview:qe,update:Me,delete:He}),Le=(e,t)=>!!e.
24
+ result&&e.result.bucketName===t.result?.bucketName,qe=async(e,t)=>{let r={...e.parameters,
25
+ dependencies:e.dependencies},o={...t.parameters,dependencies:t.dependencies},n=Ie(
26
+ r,o);if(n.counts)return{...n,name:r.bucketName}},Ke=async(e,t,r)=>{if(t.result)throw new Fe(
27
+ a,e.entryId,t.entryId);return M(e,r)},M=async(e,t)=>{let r=e.parameters,o=q(t),{
28
+ bucketName:n}=await T(r);await H(n,r,void 0),await $(n,r,void 0),await U(n,r.tags,
29
+ void 0);let s={eventsPath:r.eventsPath,functionArn:o};return await _(n,s,{}),{bucketName:n,
30
+ functionArn:o}},Me=async(e,t,r)=>{let{result:o,parameters:n}=e;if(!o)return;let s=o.
31
+ bucketName,c=q(r),i=t.result?.functionArn;await H(s,n,t.parameters),await $(s,n,
32
+ t.parameters),await U(s,n.tags,t.parameters.tags);let d={eventsPath:n.eventsPath,
33
+ functionArn:c},S={eventsPath:t.parameters.eventsPath,functionArn:i};return await _(
34
+ s,d,S),{...o,functionArn:c}},He=async e=>{let t=e.result;t&&await h(t.bucketName)&&
35
+ await N(t.bucketName)},H=async(e,t,r)=>{if(!(t.cors&&r?.cors&&B(t.cors,r.cors))){
36
+ if(t.cors)return z(e,t.cors);if(r?.cors)return A(e)}},$=async(e,t,r)=>{if(t.autoExpireDays!==
37
+ r?.autoExpireDays){if(t.autoExpireDays)return F(e,t.autoExpireDays);if(r?.autoExpireDays)
38
+ return I(e)}},U=async(e,t,r)=>{let o=t??{};!B(o,r??{})&&await D(e,o)},_=async(e,t,r)=>{
39
+ !B(t,r)&&await L(e,{eventsType:["s3:ObjectCreated:*","s3:ObjectRemoved:*"],...t})};var G=()=>{$e(u,K())};import{registerProvider as st}from"@ez4/aws-common";import{ReplaceResourceError as Ye}from"@ez4/aws-common";import{EntryNotFoundError as Ue,getEntry as _e}from"@ez4/stateful";import{IncompleteResourceError as Ge}from"@ez4/aws-common";
40
+ import{hashData as Ve,toKebabCase as We}from"@ez4/utils";var Ze=e=>e.type===u,k=e=>Ve(u,We(e)),br=(e,t)=>{let r=_e(e,k(t));if(!Ze(r))throw new Ue(
41
+ r.entryId);return r},P=(e,t,r)=>{let o=r.getDependencies(u).at(0)?.result;if(!o?.
42
+ bucketName)throw new Ge(e,t,"bucketName");return o.bucketName};import{Logger as V}from"@ez4/aws-common";import{S3Client as Je,PutBucketPolicyCommand as Qe,
43
+ DeleteBucketPolicyCommand as Xe}from"@aws-sdk/client-s3";var g="AWS:S3/Policy",l="aws:s3.policy";var W=new Je({}),Z=async e=>{let{bucketName:t,role:r}=e;return V.logCreate(g,t),
44
+ await W.send(new Qe({Bucket:t,Policy:JSON.stringify(r)})),{bucketName:t}},J=async e=>{
45
+ V.logDelete(g,e),await W.send(new Xe({Bucket:e}))};var Q=()=>({equals:et,create:X,replace:rt,preview:tt,update:ot,delete:nt}),et=(e,t)=>!!e.
46
+ result&&e.result.bucketName===t.result?.bucketName,tt=async()=>{},rt=async(e,t,r)=>{
47
+ if(t.result)throw new Ye(g,e.entryId,t.entryId);return X(e,r)},X=async(e,t)=>{let r=e.
48
+ parameters,o=P(g,"policy",t),n=await r.getRole(t);return await Z({bucketName:o,role:n}),
49
+ {bucketName:o}},ot=async()=>{},nt=async e=>{let t=e.result;t&&await J(t.bucketName)};var Y=()=>{st(l,Q())};import{registerProvider as wt}from"@ez4/aws-common";import{stat as lt}from"node:fs/promises";import{ReplaceResourceError as ft}from"@ez4/aws-common";
50
+ import{deepCompare as gt,deepEqual as dt}from"@ez4/utils";import{getTagList as ct,Logger as w}from"@ez4/aws-common";import{createReadStream as at}from"node:fs";
51
+ import it from"mime";import{S3Client as pt,PutObjectCommand as mt,PutObjectTaggingCommand as ut,
52
+ DeleteObjectCommand as yt}from"@aws-sdk/client-s3";var f="AWS:S3/Object",y="aws:s3.object";var Lr=e=>e.type===y,x=(e,t)=>`${e}/${t}`,qr=e=>e.getDependencies(y).map(({result:r})=>({
53
+ lastModified:r?.lastModified,objectKey:r?.objectKey}));var R=new pt({}),E=async(e,t)=>{let{objectKey:r,filePath:o}=t;w.logCreate(f,x(e,
54
+ r));let n=it.getType(o);return await R.send(new mt({Bucket:e,Key:r,Body:at(o),...n&&
55
+ {ContentType:n}})),{objectKey:r}},ee=async(e,t,r)=>{w.logTag(f,x(e,t)),await R.send(
56
+ new ut({Bucket:e,Key:t,Tagging:{TagSet:ct({...r,ManagedBy:"EZ4"})}}))},te=async(e,t)=>{
57
+ w.logDelete(f,x(e,t)),await R.send(new yt({Bucket:e,Key:t}))};var re=()=>({equals:St,create:oe,replace:bt,preview:kt,update:Pt,delete:xt}),St=(e,t)=>!!e.
58
+ result&&e.result.objectKey===t.result?.objectKey,kt=async(e,t)=>{let r=e.parameters,
59
+ o=t.parameters,n=gt({...r,dependencies:e.dependencies,lastModified:await v(r.filePath)},
60
+ {...o,dependencies:t.dependencies,lastModified:e.result?.lastModified});if(n.counts)
61
+ return{...n,name:r.objectKey}},bt=async(e,t,r)=>{if(t.result)throw new ft(f,e.entryId,
62
+ t.entryId);return oe(e,r)},oe=async(e,t)=>{let r=e.parameters,o=P(f,"bucket",t),
63
+ n=await v(r.filePath),{objectKey:s}=await E(o,r);return await ne(o,s,r.tags,e.parameters.
64
+ tags),{lastModified:n,bucketName:o,objectKey:s}},Pt=async(e,t)=>{let{result:r,parameters:o}=e;
65
+ if(!r)return;let{bucketName:n,objectKey:s}=r,c=Bt(r,o,t.parameters);return await ne(
66
+ n,s,o.tags,t.parameters.tags),c},xt=async e=>{let t=e.result;t&&await te(t.bucketName,
67
+ t.objectKey)},v=async e=>{let{mtime:t}=await lt(e);return t.getTime()},Bt=async(e,t,r)=>{
68
+ let o=await v(t.filePath);if(o<=e.lastModified&&t.filePath===r.filePath)return e;
69
+ let{bucketName:n,objectKey:s}=e;return await E(n,{...t,objectKey:s}),{lastModified:o,
70
+ bucketName:n,objectKey:s}},ne=async(e,t,r,o)=>{let n=r??{};!dt(n,o??{})&&await ee(
71
+ e,t,n)};var se=()=>{wt(y,re())};import{isRoleState as ge}from"@ez4/aws-identity";import{isBucketService as O}from"@ez4/storage/library";
72
+ import{linkServiceExtras as qt}from"@ez4/project/library";import{getFunction as de}from"@ez4/aws-function";import{createPermission as Et}from"@ez4/aws-function";import{attachEntry as vt,linkDependency as Ct}from"@ez4/stateful";
73
+ import{toKebabCase as jt}from"@ez4/utils";import{createPolicyDocument as Rt}from"@ez4/aws-identity";var ce=e=>`arn:aws:s3:\
74
+ ::${e}`,ae=e=>Rt([{resourceIds:[`arn:aws:s3:::${e}-*`,`arn:aws:s3:::${e}-*/*`],permissions:[
75
+ "s3:ListBucket","s3:PutObject","s3:GetObject","s3:DeleteObject"]}]);var ie=(e,t,r)=>{let o=jt(r.bucketName),n=k(r.bucketName),s=vt(e,{type:u,entryId:n,
76
+ dependencies:[],parameters:{...r,bucketName:o}});return t&&(Et(e,s,t,{getPermission:()=>({
77
+ principal:"s3.amazonaws.com",sourceArn:ce(o)})}),Ct(e,s.entryId,t.entryId)),s};import{createFunction as Dt}from"@ez4/aws-function";import{join as Ot}from"node:path";import{getDefinitionsObject as ht}from"@ez4/project/library";
78
+ import{MappingServiceName as Tt}from"@ez4/aws-function";import{bundleFunction as Nt}from"@ez4/aws-common";
79
+ var pe=async(e,t)=>{let{extras:r,debug:o,handler:n,listener:s}=t,c=ht(e);return Nt(
80
+ Tt,{templateFile:Ot(import.meta.dirname,"../lib/event.ts"),filePrefix:"s3",define:{
81
+ ...c},handler:n,listener:s,extras:r,debug:o})};var me=(e,t,r)=>Dt(e,t,{handlerName:"s3EntryPoint",functionName:r.functionName,sourceFile:r.
82
+ handler.sourceFile,description:r.description,variables:r.variables,timeout:r.timeout,
83
+ memory:r.memory,tags:r.tags,getFunctionBundle:o=>{let n=o.getDependencies();return pe(
84
+ n,r)}});import{getServiceName as ue}from"@ez4/project/library";import{getRandomName as zt}from"@ez4/aws-common";
85
+ import{toKebabCase as At}from"@ez4/utils";var C=async(e,t)=>{if(e.globalName)return e.
86
+ globalName;let r=ue(e,t).substring(0,46),o=await zt(16);return`${r}-${o}`},j=(e,t,r)=>`${ue(
87
+ e,r)}-${At(t)}`;import{readdir as Ft}from"node:fs/promises";import{join as ye,relative as It}from"node:path";
88
+ import{createBucketObject as Lt}from"@ez4/aws-bucket";var le=async(e,t,r)=>{let o=ye(
89
+ process.cwd(),r),n=await Ft(o,{withFileTypes:!0,recursive:!0});for(let s of n){if(!s.
90
+ isFile())continue;let c=ye(s.parentPath,s.name),i=It(o,c);Lt(e,t,{objectKey:i,filePath:c})}};var fe=e=>({entryId:k(e),constructor:`make('${e}')`,from:"@ez4/aws-bucket/client",
91
+ module:"Client"});var b=class extends Error{constructor(){super("Execution role for S3 is missing.")}};var Se=async e=>{let{service:t,options:r}=e;if(!O(t))return null;let o=await C(t,
92
+ r);return fe(o)},ke=async e=>{let{state:t,service:r,role:o,options:n}=e;if(!O(r))
93
+ return;if(!o||!ge(o))throw new b;let{localPath:s,autoExpireDays:c,events:i,cors:d}=r,
94
+ S=await C(r,n),Be=Kt(t,r,o,n),we=ie(t,Be,{eventsPath:i?.path,bucketName:S,autoExpireDays:c,
95
+ localPath:s,cors:d});s&&await le(t,we,s)},be=e=>{let{state:t,service:r,role:o,options:n}=e;
96
+ if(!O(r)||!r.extras||!r.events)return;if(!o||!ge(o))throw new b;let s=r.events.handler,
97
+ c=j(r,s.name,n),i=de(t,o,c);i&&qt(t,i.entryId,r.extras)},Kt=(e,t,r,o)=>{if(!t.events)
98
+ return;let n=t.events,{handler:s,listener:c}=t.events,i=j(t,s.name,o),d=n.timeout??
99
+ 30,S=n.memory??192;return de(e,r,i)??me(e,r,{functionName:i,description:s.description,
100
+ timeout:d,memory:S,extras:t.extras,debug:o.debug,variables:{...t.variables},handler:{
101
+ functionName:s.name,sourceFile:s.file},...c&&{listener:{functionName:c.name,sourceFile:c.
102
+ file}}})};import{getServiceName as Mt}from"@ez4/project/library";import{createPolicy as Ht}from"@ez4/aws-identity";var Pe=e=>{let{state:t,options:r}=e,o=Mt("",r);return Ht(t,{policyName:`${o}-buc\
103
+ ket-policy`,policyDocument:ae(o)})};var xe=!1,cn=()=>{xe||($t(),Ut(),_t(),Gt(),Vt("@ez4/aws-bucket",{"deploy:prepare\
104
+ ExecutionPolicy":Pe,"deploy:prepareLinkedService":Se,"deploy:prepareResources":ke,
105
+ "deploy:connectResources":be}),G(),Y(),se(),xe=!0)};import{getRegion as Wt}from"@ez4/aws-identity";var mn=e=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.
106
+ test(e),un=async e=>{let t=await Wt();return`${e}.s3.${t}.amazonaws.com`};import{attachEntry as Zt}from"@ez4/stateful";import{hashData as Jt}from"@ez4/utils";var dn=(e,t,r,o)=>{let n=Jt(l,t.entryId,r.entryId);return Zt(e,{type:l,entryId:n,
107
+ dependencies:[t.entryId,r.entryId],parameters:o})};var bn=e=>e.type===l;import{attachEntry as Qt}from"@ez4/stateful";import{hashData as Xt}from"@ez4/utils";var Rn=(e,t,r)=>{let o=r.objectKey,n=Xt(y,t.entryId,o);return Qt(e,{type:y,entryId:n,
108
+ dependencies:[t.entryId],parameters:r})};export{a as BucketServiceName,u as BucketServiceType,f as ObjectServiceName,y as ObjectServiceType,
109
+ g as PolicyServiceName,l as PolicyServiceType,ce as buildBucketArn,ie as createBucket,
110
+ me as createBucketEventFunction,Rn as createBucketObject,dn as createBucketPolicy,
111
+ un as getBucketDomain,P as getBucketName,qr as getBucketObjectFiles,x as getBucketObjectPath,
112
+ br as getBucketState,k as getBucketStateId,ae as getPolicyDocument,mn as isBucketDomain,
113
+ Lr as isBucketObjectState,bn as isBucketPolicyState,Ze as isBucketState,cn as registerTriggers};
@@ -1,2 +1,4 @@
1
- import type { PrepareResourceEvent } from '@ez4/project/library';
1
+ import type { DeployOptions, PrepareResourceEvent } from '@ez4/project/library';
2
+ import { BucketService } from '@ez4/storage/library';
2
3
  export declare const prepareBucketServices: (event: PrepareResourceEvent) => Promise<void>;
4
+ export declare const getFunctionName: (service: BucketService, handlerName: string, options: DeployOptions) => string;
@@ -1,2 +1,2 @@
1
- import type { ExtraSource, ServiceEvent } from '@ez4/project/library';
2
- export declare const prepareLinkedService: (event: ServiceEvent) => Promise<ExtraSource | null>;
1
+ import type { ExtraSource } from '@ez4/project/library';
2
+ export declare const prepareLinkedClient: (bucketName: string) => ExtraSource;
@@ -0,0 +1,3 @@
1
+ export declare class RoleMissingError extends Error {
2
+ constructor();
3
+ }
@@ -1,2 +1,2 @@
1
1
  import type { PolicyResourceEvent } from '@ez4/project/library';
2
- export declare const prepareExecutionPolicy: (event: PolicyResourceEvent) => Promise<import("@ez4/aws-identity").PolicyState>;
2
+ export declare const prepareExecutionPolicy: (event: PolicyResourceEvent) => import("@ez4/aws-identity").PolicyState;
@@ -0,0 +1,4 @@
1
+ import type { ServiceEvent, ConnectResourceEvent, PrepareResourceEvent } from '@ez4/project/library';
2
+ export declare const prepareLinkedServices: (event: ServiceEvent) => Promise<import("@ez4/project/library").ExtraSource | null>;
3
+ export declare const prepareBucketServices: (event: PrepareResourceEvent) => Promise<void>;
4
+ export declare const connectBucketServices: (event: ConnectResourceEvent) => void;
@@ -0,0 +1,4 @@
1
+ import type { DeployOptions } from '@ez4/project/library';
2
+ import { BucketService } from '@ez4/storage/library';
3
+ export declare const getBucketName: (service: BucketService, options: DeployOptions) => Promise<string>;
4
+ export declare const getFunctionName: (service: BucketService, handlerName: string, options: DeployOptions) => string;
@@ -1,2 +1,3 @@
1
- import type { PolicyDocument } from '@ez4/aws-identity';
2
- export declare const getPolicyDocument: (prefix: string) => PolicyDocument;
1
+ import type { Arn } from '@ez4/aws-common';
2
+ export declare const buildBucketArn: (bucketName: string) => Arn;
3
+ export declare const getPolicyDocument: (prefix: string) => import("@ez4/aws-identity").PolicyDocument;
package/lib/event.ts ADDED
@@ -0,0 +1,103 @@
1
+ import type { S3Event, Context } from 'aws-lambda';
2
+ import type { Bucket } from '@ez4/storage';
3
+ import type { Service } from '@ez4/common';
4
+
5
+ import { BucketEventType } from '@ez4/storage';
6
+ import { ServiceEventType } from '@ez4/common';
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.13.0",
4
+ "version": "0.15.0",
5
5
  "author": "Silas B.",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -42,17 +42,20 @@
42
42
  "live:publish": "npm run test && npm publish --access public"
43
43
  },
44
44
  "devDependencies": {
45
+ "@types/aws-lambda": "^8.10.147",
45
46
  "@types/mime": "^3.0.0"
46
47
  },
47
48
  "dependencies": {
48
- "@aws-sdk/client-s3": "^3.614.0",
49
- "@aws-sdk/s3-request-presigner": "^3.651.0",
50
- "@ez4/aws-common": "^0.13.0",
51
- "@ez4/aws-identity": "^0.13.0",
52
- "@ez4/project": "^0.13.0",
53
- "@ez4/stateful": "^0.13.0",
54
- "@ez4/storage": "^0.13.0",
55
- "@ez4/utils": "^0.13.0",
49
+ "@aws-sdk/client-s3": "^3.758.0",
50
+ "@aws-sdk/s3-request-presigner": "^3.758.0",
51
+ "@ez4/aws-common": "^0.15.0",
52
+ "@ez4/aws-function": "^0.15.0",
53
+ "@ez4/aws-identity": "^0.15.0",
54
+ "@ez4/common": "^0.15.0",
55
+ "@ez4/project": "^0.15.0",
56
+ "@ez4/stateful": "^0.15.0",
57
+ "@ez4/storage": "^0.15.0",
58
+ "@ez4/utils": "^0.15.0",
56
59
  "mime": "^3.0.0"
57
60
  }
58
61
  }