@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.
@@ -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<void>;
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<void>;
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<void>;
22
+ export declare const deleteLifecycle: (bucketName: string) => Promise<boolean>;
23
23
  export declare const updateEventNotifications: (bucketName: string, request: UpdateNotificationRequest) => Promise<void>;
@@ -0,0 +1,3 @@
1
+ export declare class BucketNotFoundError extends Error {
2
+ constructor(bucketName: string);
3
+ }
@@ -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 BucketEventFunctionParameters = Omit<FunctionParameters, 'getFunctionBundle'> & {
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
  };
@@ -1,6 +1,7 @@
1
- import type { EntryState, EntryStates, StepContext } from '@ez4/stateful';
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 getBucketStateId: (bucketName: string) => string;
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 dt=Object.create;var v=Object.defineProperty;var St=Object.getOwnPropertyDescriptor;var kt=Object.getOwnPropertyNames;var bt=Object.getPrototypeOf,Pt=Object.prototype.hasOwnProperty;var xt=(e,t)=>{for(var r in t)v(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 kt(t))!Pt.call(e,n)&&n!==r&&
3
- v(e,n,{get:()=>t[n],enumerable:!(o=St(t,n))||o.enumerable});return e};var Bt=(e,t,r)=>(r=e!=null?dt(bt(e)):{},W(t||!e||!e.__esModule?v(r,"default",{value:e,
4
- enumerable:!0}):r,e)),wt=e=>W(v({},"__esModule",{value:!0}),e);var Jt={};xt(Jt,{BucketServiceName:()=>i,BucketServiceType:()=>m,ObjectServiceName:()=>g,
5
- ObjectServiceType:()=>y,PolicyServiceName:()=>S,PolicyServiceType:()=>f,buildBucketArn:()=>q,
6
- createBucket:()=>M,createBucketEventFunction:()=>H,createBucketObject:()=>Zt,createBucketPolicy:()=>Vt,
7
- getBucketDomain:()=>Gt,getBucketName:()=>B,getBucketObjectFiles:()=>At,getBucketObjectPath:()=>w,
8
- getBucketState:()=>Ot,getBucketStateId:()=>b,getPolicyDocument:()=>K,isBucketDomain:()=>_t,
9
- isBucketObjectState:()=>Ft,isBucketPolicyState:()=>Wt,isBucketState:()=>fe,registerTriggers:()=>Ut});
10
- module.exports=wt(Jt);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",m="aws:s3.bucket";var u=new c.S3Client({}),Z=async e=>(p.Logger.logFetch(i,e),!(await u.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 u.send(new c.CreateBucketCommand({Bucket:t})),{bucketName:t}},
14
- Q=async e=>{p.Logger.logDelete(i,e),await u.send(new c.DeleteBucketCommand({Bucket:e}))},
15
- X=async(e,t)=>{p.Logger.logTag(i,e),await u.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 u.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 u.send(new c.DeleteBucketCorsCommand(
21
- {Bucket:e}))},te=async(e,t)=>{p.Logger.logCreate(i,`${e} lifecycle`),await u.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 u.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 u.send(new c.PutBucketNotificationConfigurationCommand(
27
- {Bucket:e,SkipDestinationValidation:!0,NotificationConfiguration:{...r&&{LambdaFunctionConfigurations:[
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 se=()=>({equals:Rt,create:ce,replace:vt,preview:Et,update:Ct,delete:jt}),Rt=(e,t)=>!!e.
30
- result&&e.result.bucketName===t.result?.bucketName,Et=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}},vt=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}},Ct=async(e,t,r)=>{let{result:o,parameters:n}=e;
37
- if(!o)return;let s=o.bucketName,a=(0,z.tryGetFunctionArn)(r),l=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 N={eventsPath:n.eventsPath,functionArn:a},D={eventsPath:t.parameters.eventsPath,
40
- functionArn:l};return await me(s,N,D),{...o,functionArn:a}},jt=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)(m,se())};var xe=require("@ez4/aws-common");var ke=require("@ez4/aws-common");var C=require("@ez4/stateful"),le=require("@ez4/aws-common"),j=require("@ez4/utils");var fe=e=>e.type===m,b=e=>(0,j.hashData)(m,(0,j.toKebabCase)(e)),Ot=(e,t)=>{let r=(0,C.getEntry)(
48
- e,b(t));if(!fe(r))throw new C.EntryNotFoundError(r.entryId);return r},B=(e,t,r)=>{
49
- let o=r.getDependencies(m).at(0)?.result;if(!o?.bucketName)throw new le.IncompleteResourceError(
50
- e,t,"bucketName");return o.bucketName};var F=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 F.Logger.
51
- logCreate(S,t),await ge.send(new P.PutBucketPolicyCommand({Bucket:t,Policy:JSON.
52
- stringify(r)})),{bucketName:t}},Se=async e=>{F.Logger.logDelete(S,e),await ge.send(
53
- new P.DeleteBucketPolicyCommand({Bucket:e}))};var be=()=>({equals:ht,create:Pe,replace:Nt,preview:Tt,update:Dt,delete:zt}),ht=(e,t)=>!!e.
54
- result&&e.result.bucketName===t.result?.bucketName,Tt=async()=>{},Nt=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=B(S,"policy",t),n=await r.getRole(t);return await de(
57
- {bucketName:o,role:n}),{bucketName:o}},Dt=async()=>{},zt=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"),O=require("@ez4/utils");var x=require("@ez4/aws-common"),we=require("node:fs"),Re=Bt(require("mime"),1),
59
- d=require("@aws-sdk/client-s3");var g="AWS:S3/Object",y="aws:s3.object";var Ft=e=>e.type===y,w=(e,t)=>`${e}/${t}`,At=e=>e.getDependencies(y).map(({result:r})=>({
60
- lastModified:r?.lastModified,objectKey:r?.objectKey}));var A=new d.S3Client({}),I=async(e,t)=>{let{objectKey:r,filePath:o}=t;x.Logger.logCreate(
61
- g,w(e,r));let n=Re.default.getType(o);return await A.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,w(e,t)),await A.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,w(e,t)),await A.send(new d.DeleteObjectCommand({Bucket:e,Key:t}))};var Oe=()=>({equals:It,create:he,replace:qt,preview:Lt,update:Kt,delete:Mt}),It=(e,t)=>!!e.
66
- result&&e.result.objectKey===t.result?.objectKey,Lt=async(e,t)=>{let r=e.parameters,
67
- o=t.parameters,n=(0,O.deepCompare)({...r,dependencies:e.dependencies,lastModified:await L(
68
- r.filePath)},{...o,dependencies:t.dependencies,lastModified:e.result?.lastModified});
69
- if(n.counts)return{...n,name:r.objectKey}},qt=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=B(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}},Kt=async(e,t)=>{
73
- let{result:r,parameters:o}=e;if(!r)return;let{bucketName:n,objectKey:s}=r,a=Ht(r,
74
- o,t.parameters);return await Te(n,s,o.tags,t.parameters.tags),a},Mt=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()},Ht=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,O.deepEqual)(n,o??{})&&await Ee(e,t,n)};var De=()=>{(0,Ne.registerProvider)(y,Oe())};var G=require("@ez4/aws-identity"),T=require("@ez4/storage/library"),Ze=require("@ez4/project/library"),
80
- V=require("@ez4/aws-function");var Fe=require("@ez4/aws-function"),h=require("@ez4/stateful"),Ae=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,Ae.toKebabCase)(r.bucketName),n=b(r.bucketName),s=(0,h.attachEntry)(
83
- e,{type:m,entryId:n,dependencies:[],parameters:{...r,bucketName:o}});return t&&((0,Fe.createPermission)(
84
- e,s,t,{getPermission:()=>({principal:"s3.amazonaws.com",sourceArn:q(o)})}),(0,h.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 r=(0,Le.getDefinitionsObject)(
87
- e);return(0,Ke.bundleFunction)(qe.MappingServiceName,{sourceFile:t.sourceFile,wrapperFile:(0,Ie.join)(
88
- __dirname,"../lib/function.ts"),handlerName:t.handlerName,extras:t.extras,debug:t.
89
- debug,filePrefix:"s3",define:{...r}})};var H=(e,t,r)=>(0,He.createFunction)(e,t,{handlerName:"s3EntryPoint",functionName:r.
90
- functionName,sourceFile:r.sourceFile,variables:r.variables,description:r.description,
91
- timeout:r.timeout,memory:r.memory,tags:r.tags,getFunctionBundle:o=>{let n=o.getDependencies();
92
- return Me(n,r)}});var $=require("@ez4/project/library"),$e=require("@ez4/aws-common"),Ue=require("@ez4/utils"),
93
- U=async(e,t)=>{let r=(0,$.getServiceName)(e,t).substring(0,46),o=await(0,$e.getRandomName)(
94
- 16);return`${r}-${o}`},_=(e,t,r)=>`${(0,$.getServiceName)(e,r)}-${(0,Ue.toKebabCase)(
95
- t)}`;var _e=require("node:fs/promises"),R=require("node:path"),Ge=require("@ez4/aws-bucket"),
96
- Ve=async(e,t,r)=>{let o=(0,R.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,R.join)(s.parentPath,
98
- s.name),l=(0,R.relative)(o,a);(0,Ge.createBucketObject)(e,t,{objectKey:l,filePath:a})}};var We=e=>({entryId:b(e),constructor:`make('${e}')`,from:"@ez4/aws-bucket/client",
99
- module:"Client"});var E=class extends Error{constructor(){super("Execution role for S3 is missing.")}};var Je=async e=>{let{service:t,options:r}=e;if(!(0,T.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,T.isBucketService)(r))return;if(!o||!(0,G.isRoleState)(o))throw new E;let{
102
- globalName:s,localPath:a,autoExpireDays:l,events:N,cors:D}=r,lt=s??await U(r,n),
103
- ft=$t(t,r,o,n),gt=M(t,ft,{eventsPath:N?.path,bucketName:lt,autoExpireDays:l,localPath:a,
104
- cors:D});a&&await Ve(t,gt,a)},Xe=e=>{let{state:t,service:r,role:o,options:n}=e;if(!(0,T.isBucketService)(
105
- r)||!r.extras||!r.events)return;if(!o||!(0,G.isRoleState)(o))throw new E;let s=r.
106
- events.handler,a=_(r,s.name,n),l=(0,V.getFunction)(t,o,a);l&&(0,Ze.linkServiceExtras)(
107
- t,l.entryId,r.extras)},$t=(e,t,r,o)=>{if(!t.events)return;let n=t.events,s=n.handler,
108
- a=_(t,s.name,o);return(0,V.getFunction)(e,r,a)??H(e,r,{functionName:a,description:s.
109
- description,handlerName:s.name,sourceFile:s.file,timeout:n.timeout??15,memory:n.
110
- memory??192,extras:t.extras,debug:o.debug,variables:{...t.variables}})};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)(
111
- t,{policyName:`${o}-bucket-policy`,policyDocument:K(o)})};var rt=!1,Ut=()=>{rt||((0,ot.registerTriggers)(),(0,nt.registerTriggers)(),(0,st.registerTriggers)(),
112
- (0,ct.registerTriggers)(),(0,at.createTrigger)("@ez4/aws-bucket",{"deploy:prepar\
113
- eExecutionPolicy":tt,"deploy:prepareLinkedService":Je,"deploy:prepareResources":Qe,
114
- "deploy:connectResources":Xe}),ye(),Be(),De(),rt=!0)};var it=require("@ez4/aws-identity"),_t=e=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.test(
115
- e),Gt=async e=>{let t=await(0,it.getRegion)();return`${e}.s3.${t}.amazonaws.com`};var pt=require("@ez4/stateful"),mt=require("@ez4/utils");var Vt=(e,t,r,o)=>{let n=(0,mt.hashData)(f,t.entryId,r.entryId);return(0,pt.attachEntry)(
116
- e,{type:f,entryId:n,dependencies:[t.entryId,r.entryId],parameters:o})};var Wt=e=>e.type===f;var ut=require("@ez4/stateful"),yt=require("@ez4/utils");var Zt=(e,t,r)=>{let o=r.objectKey,n=(0,yt.hashData)(y,t.entryId,o);return(0,ut.attachEntry)(
117
- e,{type:y,entryId:n,dependencies:[t.entryId],parameters:r})};0&&(module.exports={BucketServiceName,BucketServiceType,ObjectServiceName,ObjectServiceType,
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,getBucketObjectFiles,
120
- getBucketObjectPath,getBucketState,getBucketStateId,getPolicyDocument,isBucketDomain,
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 Ut}from"@ez4/aws-common";import{registerTriggers as _t}from"@ez4/aws-identity";
2
- import{registerTriggers as Gt}from"@ez4/aws-function";import{registerTriggers as Vt}from"@ez4/storage/library";
3
- import{createTrigger as Wt}from"@ez4/project/library";import{registerProvider as Ue}from"@ez4/aws-common";import{ReplaceResourceError as Ie}from"@ez4/aws-common";import{tryGetFunctionArn as q}from"@ez4/aws-function";
4
- import{deepCompare as Le,deepEqual as B}from"@ez4/utils";import{getTagList as Ee,Logger as i}from"@ez4/aws-common";import{S3Client as ve,
5
- ListObjectsV2Command as Ce,CreateBucketCommand as je,DeleteBucketCommand as Oe,PutBucketTaggingCommand as he,
6
- PutBucketCorsCommand as Te,DeleteBucketCorsCommand as Ne,PutBucketLifecycleConfigurationCommand as De,
7
- DeleteBucketLifecycleCommand as ze,PutBucketNotificationConfigurationCommand as Fe,
8
- ExpirationStatus as Ae}from"@aws-sdk/client-s3";var a="AWS:S3/Bucket",u="aws:s3.bucket";var p=new ve({}),h=async e=>(i.logFetch(a,e),!(await p.send(new Ce({Bucket:e,MaxKeys:1}))).
9
- Contents?.length),T=async e=>{let{bucketName:t}=e;return i.logCreate(a,t),await p.
10
- send(new je({Bucket:t})),{bucketName:t}},N=async e=>{i.logDelete(a,e),await p.send(
11
- new Oe({Bucket:e}))},D=async(e,t)=>{i.logTag(a,e),await p.send(new he({Bucket:e,
12
- Tagging:{TagSet:Ee({...t,ManagedBy:"EZ4"})}}))},z=async(e,t)=>{i.logUpdate(a,`${e}\
13
- CORS`),await p.send(new Te({Bucket:e,CORSConfiguration:{CORSRules:[{ID:"ID0",AllowedOrigins:t.
14
- allowOrigins,AllowedMethods:t.allowMethods,AllowedHeaders:t.allowHeaders,ExposeHeaders:t.
15
- exposeHeaders,MaxAgeSeconds:t.maxAge}]}}))},F=async e=>{i.logDelete(a,`${e} CORS`),
16
- await p.send(new Ne({Bucket:e}))},A=async(e,t)=>{i.logCreate(a,`${e} lifecycle`),
17
- await p.send(new De({Bucket:e,LifecycleConfiguration:{Rules:[{ID:"ID0",Status:Ae.
18
- Enabled,Filter:{Prefix:"*"},Expiration:{Days:t}}]}}))},I=async e=>{i.logDelete(a,
19
- `${e} lifecycle`),await p.send(new ze({Bucket:e}))},L=async(e,t)=>{i.logUpdate(a,
20
- `${e} event notifications`);let{functionArn:r,eventsPath:o,eventsType:n}=t;await p.
21
- send(new Fe({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:qe,create:M,replace:Me,preview:Ke,update:He,delete:$e}),qe=(e,t)=>!!e.
24
- result&&e.result.bucketName===t.result?.bucketName,Ke=async(e,t)=>{let r={...e.parameters,
25
- dependencies:e.dependencies},o={...t.parameters,dependencies:t.dependencies},n=Le(
26
- r,o);if(n.counts)return{...n,name:r.bucketName}},Me=async(e,t,r)=>{if(t.result)throw new Ie(
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}},He=async(e,t,r)=>{let{result:o,parameters:n}=e;if(!o)return;let s=o.
31
- bucketName,c=q(r),m=t.result?.functionArn;await H(s,n,t.parameters),await $(s,n,
32
- t.parameters),await U(s,n.tags,t.parameters.tags);let P={eventsPath:n.eventsPath,
33
- functionArn:c},x={eventsPath:t.parameters.eventsPath,functionArn:m};return await _(
34
- s,P,x),{...o,functionArn:c}},$e=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 F(e)}},$=async(e,t,r)=>{if(t.autoExpireDays!==
37
- r?.autoExpireDays){if(t.autoExpireDays)return A(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=()=>{Ue(u,K())};import{registerProvider as ct}from"@ez4/aws-common";import{ReplaceResourceError as et}from"@ez4/aws-common";import{EntryNotFoundError as _e,getEntry as Ge}from"@ez4/stateful";import{IncompleteResourceError as Ve}from"@ez4/aws-common";
40
- import{hashData as We,toKebabCase as Ze}from"@ez4/utils";var Je=e=>e.type===u,d=e=>We(u,Ze(e)),Pr=(e,t)=>{let r=Ge(e,d(t));if(!Je(r))throw new _e(
41
- r.entryId);return r},k=(e,t,r)=>{let o=r.getDependencies(u).at(0)?.result;if(!o?.
42
- bucketName)throw new Ve(e,t,"bucketName");return o.bucketName};import{Logger as V}from"@ez4/aws-common";import{S3Client as Qe,PutBucketPolicyCommand as Xe,
43
- DeleteBucketPolicyCommand as Ye}from"@aws-sdk/client-s3";var g="AWS:S3/Policy",l="aws:s3.policy";var W=new Qe({}),Z=async e=>{let{bucketName:t,role:r}=e;return V.logCreate(g,t),
44
- await W.send(new Xe({Bucket:t,Policy:JSON.stringify(r)})),{bucketName:t}},J=async e=>{
45
- V.logDelete(g,e),await W.send(new Ye({Bucket:e}))};var Q=()=>({equals:tt,create:X,replace:ot,preview:rt,update:nt,delete:st}),tt=(e,t)=>!!e.
46
- result&&e.result.bucketName===t.result?.bucketName,rt=async()=>{},ot=async(e,t,r)=>{
47
- if(t.result)throw new et(g,e.entryId,t.entryId);return X(e,r)},X=async(e,t)=>{let r=e.
48
- parameters,o=k(g,"policy",t),n=await r.getRole(t);return await Z({bucketName:o,role:n}),
49
- {bucketName:o}},nt=async()=>{},st=async e=>{let t=e.result;t&&await J(t.bucketName)};var Y=()=>{ct(l,Q())};import{registerProvider as Rt}from"@ez4/aws-common";import{stat as ft}from"node:fs/promises";import{ReplaceResourceError as gt}from"@ez4/aws-common";
50
- import{deepCompare as dt,deepEqual as St}from"@ez4/utils";import{getTagList as at,Logger as w}from"@ez4/aws-common";import{createReadStream as it}from"node:fs";
51
- import pt from"mime";import{S3Client as mt,PutObjectCommand as ut,PutObjectTaggingCommand as yt,
52
- DeleteObjectCommand as lt}from"@aws-sdk/client-s3";var f="AWS:S3/Object",y="aws:s3.object";var qr=e=>e.type===y,b=(e,t)=>`${e}/${t}`,Kr=e=>e.getDependencies(y).map(({result:r})=>({
53
- lastModified:r?.lastModified,objectKey:r?.objectKey}));var R=new mt({}),E=async(e,t)=>{let{objectKey:r,filePath:o}=t;w.logCreate(f,b(e,
54
- r));let n=pt.getType(o);return await R.send(new ut({Bucket:e,Key:r,Body:it(o),...n&&
55
- {ContentType:n}})),{objectKey:r}},ee=async(e,t,r)=>{w.logTag(f,b(e,t)),await R.send(
56
- new yt({Bucket:e,Key:t,Tagging:{TagSet:at({...r,ManagedBy:"EZ4"})}}))},te=async(e,t)=>{
57
- w.logDelete(f,b(e,t)),await R.send(new lt({Bucket:e,Key:t}))};var re=()=>({equals:kt,create:oe,replace:Pt,preview:bt,update:xt,delete:Bt}),kt=(e,t)=>!!e.
58
- result&&e.result.objectKey===t.result?.objectKey,bt=async(e,t)=>{let r=e.parameters,
59
- o=t.parameters,n=dt({...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}},Pt=async(e,t,r)=>{if(t.result)throw new gt(f,e.entryId,
62
- t.entryId);return oe(e,r)},oe=async(e,t)=>{let r=e.parameters,o=k(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}},xt=async(e,t)=>{let{result:r,parameters:o}=e;
65
- if(!r)return;let{bucketName:n,objectKey:s}=r,c=wt(r,o,t.parameters);return await ne(
66
- n,s,o.tags,t.parameters.tags),c},Bt=async e=>{let t=e.result;t&&await te(t.bucketName,
67
- t.objectKey)},v=async e=>{let{mtime:t}=await ft(e);return t.getTime()},wt=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??{};!St(n,o??{})&&await ee(
71
- e,t,n)};var se=()=>{Rt(y,re())};import{isRoleState as ge}from"@ez4/aws-identity";import{isBucketService as O}from"@ez4/storage/library";
72
- import{linkServiceExtras as Kt}from"@ez4/project/library";import{getFunction as de}from"@ez4/aws-function";import{createPermission as vt}from"@ez4/aws-function";import{attachEntry as Ct,linkDependency as jt}from"@ez4/stateful";
73
- import{toKebabCase as Ot}from"@ez4/utils";import{createPolicyDocument as Et}from"@ez4/aws-identity";var ce=e=>`arn:aws:s3:\
74
- ::${e}`,ae=e=>Et([{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=Ot(r.bucketName),n=d(r.bucketName),s=Ct(e,{type:u,entryId:n,
76
- dependencies:[],parameters:{...r,bucketName:o}});return t&&(vt(e,s,t,{getPermission:()=>({
77
- principal:"s3.amazonaws.com",sourceArn:ce(o)})}),jt(e,s.entryId,t.entryId)),s};import{createFunction as zt}from"@ez4/aws-function";import{join as ht}from"node:path";import{getDefinitionsObject as Tt}from"@ez4/project/library";
78
- import{MappingServiceName as Nt}from"@ez4/aws-function";import{bundleFunction as Dt}from"@ez4/aws-common";
79
- var pe=async(e,t)=>{let r=Tt(e);return Dt(Nt,{sourceFile:t.sourceFile,wrapperFile:ht(
80
- import.meta.dirname,"../lib/function.ts"),handlerName:t.handlerName,extras:t.extras,
81
- debug:t.debug,filePrefix:"s3",define:{...r}})};var me=(e,t,r)=>zt(e,t,{handlerName:"s3EntryPoint",functionName:r.functionName,sourceFile:r.
82
- sourceFile,variables:r.variables,description:r.description,timeout:r.timeout,memory:r.
83
- memory,tags:r.tags,getFunctionBundle:o=>{let n=o.getDependencies();return pe(n,r)}});import{getServiceName as ue}from"@ez4/project/library";import{getRandomName as Ft}from"@ez4/aws-common";
84
- import{toKebabCase as At}from"@ez4/utils";var C=async(e,t)=>{let r=ue(e,t).substring(
85
- 0,46),o=await Ft(16);return`${r}-${o}`},j=(e,t,r)=>`${ue(e,r)}-${At(t)}`;import{readdir as It}from"node:fs/promises";import{join as ye,relative as Lt}from"node:path";
86
- import{createBucketObject as qt}from"@ez4/aws-bucket";var le=async(e,t,r)=>{let o=ye(
87
- process.cwd(),r),n=await It(o,{withFileTypes:!0,recursive:!0});for(let s of n){if(!s.
88
- isFile())continue;let c=ye(s.parentPath,s.name),m=Lt(o,c);qt(e,t,{objectKey:m,filePath:c})}};var fe=e=>({entryId:d(e),constructor:`make('${e}')`,from:"@ez4/aws-bucket/client",
89
- module:"Client"});var S=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,
90
- r);return fe(o)},ke=async e=>{let{state:t,service:r,role:o,options:n}=e;if(!O(r))
91
- return;if(!o||!ge(o))throw new S;let{globalName:s,localPath:c,autoExpireDays:m,events:P,
92
- cors:x}=r,Be=s??await C(r,n),we=Mt(t,r,o,n),Re=ie(t,we,{eventsPath:P?.path,bucketName:Be,
93
- autoExpireDays:m,localPath:c,cors:x});c&&await le(t,Re,c)},be=e=>{let{state:t,service:r,
94
- role:o,options:n}=e;if(!O(r)||!r.extras||!r.events)return;if(!o||!ge(o))throw new S;
95
- let s=r.events.handler,c=j(r,s.name,n),m=de(t,o,c);m&&Kt(t,m.entryId,r.extras)},
96
- Mt=(e,t,r,o)=>{if(!t.events)return;let n=t.events,s=n.handler,c=j(t,s.name,o);return de(
97
- e,r,c)??me(e,r,{functionName:c,description:s.description,handlerName:s.name,sourceFile:s.
98
- file,timeout:n.timeout??15,memory:n.memory??192,extras:t.extras,debug:o.debug,variables:{
99
- ...t.variables}})};import{getServiceName as Ht}from"@ez4/project/library";import{createPolicy as $t}from"@ez4/aws-identity";var Pe=e=>{let{state:t,options:r}=e,o=Ht("",r);return $t(t,{policyName:`${o}-buc\
100
- ket-policy`,policyDocument:ae(o)})};var xe=!1,an=()=>{xe||(Ut(),_t(),Gt(),Vt(),Wt("@ez4/aws-bucket",{"deploy:prepare\
101
- ExecutionPolicy":Pe,"deploy:prepareLinkedService":Se,"deploy:prepareResources":ke,
102
- "deploy:connectResources":be}),G(),Y(),se(),xe=!0)};import{getRegion as Zt}from"@ez4/aws-identity";var un=e=>/(.+)\.s3\.(.+)\.amazonaws\.com/i.
103
- test(e),yn=async e=>{let t=await Zt();return`${e}.s3.${t}.amazonaws.com`};import{attachEntry as Jt}from"@ez4/stateful";import{hashData as Qt}from"@ez4/utils";var Sn=(e,t,r,o)=>{let n=Qt(l,t.entryId,r.entryId);return Jt(e,{type:l,entryId:n,
104
- dependencies:[t.entryId,r.entryId],parameters:o})};var Pn=e=>e.type===l;import{attachEntry as Xt}from"@ez4/stateful";import{hashData as Yt}from"@ez4/utils";var En=(e,t,r)=>{let o=r.objectKey,n=Yt(y,t.entryId,o);return Xt(e,{type:y,entryId:n,
105
- dependencies:[t.entryId],parameters:r})};export{a as BucketServiceName,u as BucketServiceType,f as ObjectServiceName,y as ObjectServiceType,
106
- g as PolicyServiceName,l as PolicyServiceType,ce as buildBucketArn,ie as createBucket,
107
- me as createBucketEventFunction,En as createBucketObject,Sn as createBucketPolicy,
108
- yn as getBucketDomain,k as getBucketName,Kr as getBucketObjectFiles,b as getBucketObjectPath,
109
- Pr as getBucketState,d as getBucketStateId,ae as getPolicyDocument,un as isBucketDomain,
110
- qr as isBucketObjectState,Pn as isBucketPolicyState,Je as isBucketState,an as registerTriggers};
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};
@@ -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<void>;
11
+ export declare const deleteObject: (bucketName: string, objectKey: string) => Promise<boolean>;
@@ -1,12 +1,12 @@
1
- import type { EntryState } from '@ez4/stateful';
2
1
  import type { ResourceTags } from '@ez4/aws-common';
3
- import type { CreateRequest, CreateResponse } from './client.js';
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 = CreateResponse & {
9
+ export type ObjectResult = {
10
10
  lastModified: number;
11
11
  bucketName: string;
12
12
  };
@@ -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 | undefined;
7
+ objectKey: string;
8
8
  }[];
@@ -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<void>;
10
+ export declare const deletePolicy: (bucketName: string) => Promise<boolean>;
@@ -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
- export declare const prepareLinkedClient: (bucketName: string) => ExtraSource;
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/aws-identity").PolicyState;
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) => Promise<import("@ez4/project/library").ExtraSource | null>;
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;
@@ -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 getNewBucketName: (service: BucketService, options: DeployOptions) => Promise<string>;
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.14.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": ">=20.15.0"
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.14.0",
52
- "@ez4/aws-function": "^0.14.0",
53
- "@ez4/aws-identity": "^0.14.0",
54
- "@ez4/project": "^0.14.0",
55
- "@ez4/stateful": "^0.14.0",
56
- "@ez4/storage": "^0.14.0",
57
- "@ez4/utils": "^0.14.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
- };