@stacksjs/storage 0.70.332 → 0.70.333

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export type { ProvisionOptions, ProvisionResult } from './provision';
1
2
  export type { ServeFileOptions } from './static-serve';
2
3
  export type { DiskConfig, FilesystemConfig, LocalDiskConfig, S3DiskConfig } from './facade';
3
4
  export type { FilenameStrategy, PutFileOptions, UploadedFileLike } from './put-file';
@@ -26,6 +27,7 @@ export * from './hash';
26
27
  export * from './helpers';
27
28
  export * as storage from './storage';
28
29
  export * from './zip';
30
+ export { ensureBucket, ensureConfiguredBuckets } from './provision';
29
31
  // Storage adapters and types
30
32
  export * from './adapters/index';
31
33
  export * from './types';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./copy";export*from"./delete";export*from"./files";export*from"./folders";export*from"./fs";export*from"./glob";export*from"./hash";export*from"./helpers";export* as storage from"./storage";export*from"./zip";export*from"./adapters";export*from"./types";export*from"./drivers";export{serveFile}from"./static-serve";export{Storage,StorageManager}from"./facade";export{UploadedFile,uploadedFile,uploadedFiles}from"./uploaded-file";export{backblazeDisk,configFromEnv,filebaseDisk,hetznerDisk,localDisk,r2Disk,s3Disk}from"./types/filesystem";export{clearRevokedSignedStorageTokens,createSignedStorageToken,isSignedStorageTokenRevoked,revokeSignedStorageToken,verifySignedStorageToken}from"./signed-url";export{parseDiskPath,PathSanitizeError,sanitizePresignedDir,sanitizePresignedFilename}from"./path-sanitize";export{detectMimeFromMagicBytes,verifyUploadedMime}from"./mime-verify";export{signS3PresignedPost}from"./s3-presigned-post";
1
+ export*from"./copy";export*from"./delete";export*from"./files";export*from"./folders";export*from"./fs";export*from"./glob";export*from"./hash";export*from"./helpers";export* as storage from"./storage";export*from"./zip";export{ensureBucket,ensureConfiguredBuckets}from"./provision";export*from"./adapters";export*from"./types";export*from"./drivers";export{serveFile}from"./static-serve";export{Storage,StorageManager}from"./facade";export{UploadedFile,uploadedFile,uploadedFiles}from"./uploaded-file";export{backblazeDisk,configFromEnv,filebaseDisk,hetznerDisk,localDisk,r2Disk,s3Disk}from"./types/filesystem";export{clearRevokedSignedStorageTokens,createSignedStorageToken,isSignedStorageTokenRevoked,revokeSignedStorageToken,verifySignedStorageToken}from"./signed-url";export{parseDiskPath,PathSanitizeError,sanitizePresignedDir,sanitizePresignedFilename}from"./path-sanitize";export{detectMimeFromMagicBytes,verifyUploadedMime}from"./mime-verify";export{signS3PresignedPost}from"./s3-presigned-post";
@@ -0,0 +1,45 @@
1
+ import type { ObjectStorageProvider } from '@stacksjs/ts-cloud';
2
+ /**
3
+ * Make sure `bucket` exists, creating it if it does not.
4
+ *
5
+ * Idempotent: an existing bucket is reported rather than treated as an error,
6
+ * so this is safe to call on every deploy and on every boot.
7
+ */
8
+ export declare function ensureBucket(bucket: string, options?: ProvisionOptions): Promise<ProvisionResult>;
9
+ /**
10
+ * Ensure every bucket the app's filesystem config names.
11
+ *
12
+ * Reads `filesystems.s3.bucket` plus any bucket named by a configured disk, so
13
+ * a deploy provisions what the app is actually configured to use rather than a
14
+ * list maintained separately.
15
+ */
16
+ export declare function ensureConfiguredBuckets(options?: ProvisionOptions): Promise<ProvisionResult[]>;
17
+ /**
18
+ * Bucket provisioning.
19
+ *
20
+ * An app that writes to object storage should not fail on its first upload
21
+ * because nobody created the bucket by hand, and it should not require a
22
+ * separate infrastructure step for something the app already knows the name of.
23
+ * Vapor provisions the bucket as part of deploying; this is the same idea,
24
+ * available both as an explicit call and as an on-demand check before a write.
25
+ *
26
+ * Creation is deliberately *not* implicit on every write. `ensureBucket` is
27
+ * cheap but not free, and silently creating buckets from a typo'd config name
28
+ * is how an account ends up with a dozen near-identical buckets and data
29
+ * spread across them. Apps opt in via `filesystems.autoCreateBuckets`.
30
+ */
31
+ export declare interface ProvisionOptions {
32
+ provider?: ObjectStorageProvider
33
+ region?: string
34
+ endpoint?: string
35
+ credentials?: { accessKeyId: string, secretAccessKey: string }
36
+ acl?: string
37
+ }
38
+ export declare interface ProvisionResult {
39
+ bucket: string
40
+ status: 'created' | 'exists'
41
+ provider: ObjectStorageProvider
42
+ region: string
43
+ endpoint?: string
44
+ publicUrl: string
45
+ }
@@ -0,0 +1 @@
1
+ export async function ensureBucket(bucket,options={}){if(!bucket)throw Error("ensureBucket requires a bucket name.");const{createObjectStorageClient,resolveObjectStorage}=await import("@stacksjs/ts-cloud"),resolved=resolveObjectStorage(options),client=createObjectStorageClient(options),base={bucket,provider:resolved.provider,region:resolved.region,endpoint:resolved.endpoint,publicUrl:resolved.publicBaseUrl(bucket)};if(await client.bucketExists(bucket))return{...base,status:"exists"};try{await client.createBucket(bucket,{acl:options.acl??"private"});return{...base,status:"created"}}catch(error){const message=error instanceof Error?error.message:String(error);if(/BucketAlreadyOwnedByYou|BucketAlreadyExists|already exists/i.test(message))return{...base,status:"exists"};throw Error(`Could not create bucket "${bucket}" on ${resolved.provider}: ${message}`)}}export async function ensureConfiguredBuckets(options={}){const{filesystems}=await import("@stacksjs/config"),names=new Set;if(filesystems?.s3?.bucket)names.add(filesystems.s3.bucket);for(const disk of Object.values(filesystems?.disks??{})){const candidate=disk;if(candidate?.driver==="s3"&&candidate.bucket)names.add(candidate.bucket)}if(names.size===0)return[];const results=[];for(const name of names)results.push(await ensureBucket(name,options));return results}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/storage",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.70.332",
5
+ "version": "0.70.333",
6
6
  "description": "The Stacks file system.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -65,11 +65,11 @@
65
65
  "ts-images": "^0.2.8"
66
66
  },
67
67
  "devDependencies": {
68
- "@stacksjs/arrays": "0.70.332",
68
+ "@stacksjs/arrays": "0.70.333",
69
69
  "better-dx": "^0.2.17",
70
- "@stacksjs/error-handling": "0.70.332",
71
- "@stacksjs/path": "0.70.332",
72
- "@stacksjs/strings": "0.70.332",
73
- "@stacksjs/types": "0.70.332"
70
+ "@stacksjs/error-handling": "0.70.333",
71
+ "@stacksjs/path": "0.70.333",
72
+ "@stacksjs/strings": "0.70.333",
73
+ "@stacksjs/types": "0.70.333"
74
74
  }
75
75
  }