BREAKING CHANGE(core): Make API strict-by-default: remove *Strict variants, throw on not-found/exists conflicts, add explicit exists() methods, update docs/tests and bump deps
This commit is contained in:
102
changelog.md
102
changelog.md
@@ -1,5 +1,107 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-11-20 - 4.0.0 - BREAKING CHANGE(core)
|
||||
Make API strict-by-default: remove *Strict variants, throw on not-found/exists conflicts, add explicit exists() methods, update docs/tests and bump deps
|
||||
|
||||
- Breaking: Core API methods are strict by default and now throw errors instead of returning null when targets are missing or already exist (e.g. getBucketByName, getFile, getSubDirectoryByName, fastPut, fastPutStream).
|
||||
- Removed *Strict variants: fastPutStrict, getBucketByNameStrict, getFileStrict, getSubDirectoryByNameStrict — use the base methods which are now strict.
|
||||
- Added explicit existence checks: bucketExists (SmartBucket), fileExists (Directory/fileExists), directoryExists (Directory.directoryExists), and fastExists (Bucket.fastExists) to allow non-throwing checks before operations.
|
||||
- Return type updates: fastPut now returns Promise<File> (no null), getBucketByName/getFile/getSubDirectoryByName now return the respective objects or throw.
|
||||
- Improved error messages to guide callers (e.g. suggest setting overwrite:true on fastPut when object exists).
|
||||
- Updated README, changelog and tests to reflect the new strict semantics and usage patterns.
|
||||
- Developer/runtime dependency bumps: @git.zone/tsbuild, @git.zone/tsrun, @git.zone/tstest, @aws-sdk/client-s3, @push.rocks/smartstring, @tsclass/tsclass (version bumps recorded in package.json).
|
||||
- Major version bump to 4.0.0 to reflect breaking API changes.
|
||||
|
||||
## 2025-11-20 - 4.0.0 - BREAKING: Strict by default + exists methods
|
||||
Complete API overhaul: all methods throw by default, removed all *Strict variants, added dedicated exists methods
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
**Putters (Write Operations):**
|
||||
- `fastPut`: Return type `Promise<File | null>` → `Promise<File>`, throws when file exists and overwrite is false
|
||||
- `fastPutStream`: Now throws when file exists and overwrite is false (previously returned silently)
|
||||
- `fastPutStrict`: **Removed** - use `fastPut` directly
|
||||
|
||||
**Getters (Read Operations):**
|
||||
- `getBucketByName`: Return type `Promise<Bucket | null>` → `Promise<Bucket>`, throws when bucket not found
|
||||
- `getBucketByNameStrict`: **Removed** - use `getBucketByName` directly
|
||||
- `getFile`: Return type `Promise<File | null>` → `Promise<File>`, throws when file not found
|
||||
- `getFileStrict`: **Removed** - use `getFile` directly
|
||||
- `getSubDirectoryByName`: Return type `Promise<Directory | null>` → `Promise<Directory>`, throws when directory not found
|
||||
- `getSubDirectoryByNameStrict`: **Removed** - use `getSubDirectoryByName` directly
|
||||
|
||||
**New Methods (Existence Checks):**
|
||||
- `bucket.fastExists({ path })` - ✅ Already existed
|
||||
- `directory.fileExists({ path })` - **NEW** - Check if file exists
|
||||
- `directory.directoryExists(name)` - **NEW** - Check if subdirectory exists
|
||||
- `smartBucket.bucketExists(name)` - **NEW** - Check if bucket exists
|
||||
|
||||
**Benefits:**
|
||||
- ✅ **Simpler API**: Removed 4 redundant *Strict methods
|
||||
- ✅ **Type-safe**: No nullable returns - `Promise<T>` not `Promise<T | null>`
|
||||
- ✅ **Fail-fast**: Errors throw immediately with precise stack traces
|
||||
- ✅ **Consistent**: All methods behave the same way
|
||||
- ✅ **Explicit**: Use exists() to check, then get() to retrieve
|
||||
- ✅ **Better debugging**: Error location is always precise
|
||||
|
||||
**Migration Guide:**
|
||||
|
||||
```typescript
|
||||
// ============================================
|
||||
// Pattern 1: Check then Get (Recommended)
|
||||
// ============================================
|
||||
|
||||
// Before (v3.x):
|
||||
const bucket = await smartBucket.getBucketByName('my-bucket');
|
||||
if (bucket) {
|
||||
// use bucket
|
||||
}
|
||||
|
||||
// After (v4.0):
|
||||
if (await smartBucket.bucketExists('my-bucket')) {
|
||||
const bucket = await smartBucket.getBucketByName('my-bucket'); // guaranteed to exist
|
||||
// use bucket
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Pattern 2: Try/Catch
|
||||
// ============================================
|
||||
|
||||
// Before (v3.x):
|
||||
const file = await directory.getFile({ path: 'file.txt' });
|
||||
if (!file) {
|
||||
// Handle not found
|
||||
}
|
||||
|
||||
// After (v4.0):
|
||||
try {
|
||||
const file = await directory.getFile({ path: 'file.txt' });
|
||||
// use file
|
||||
} catch (error) {
|
||||
// Handle not found
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Pattern 3: Remove *Strict calls
|
||||
// ============================================
|
||||
|
||||
// Before (v3.x):
|
||||
const file = await directory.getFileStrict({ path: 'file.txt' });
|
||||
|
||||
// After (v4.0):
|
||||
const file = await directory.getFile({ path: 'file.txt' }); // already strict
|
||||
|
||||
// ============================================
|
||||
// Pattern 4: Write Operations
|
||||
// ============================================
|
||||
|
||||
// Before (v3.x):
|
||||
const file = await bucket.fastPutStrict({ path: 'file.txt', contents: 'data' });
|
||||
|
||||
// After (v4.0):
|
||||
const file = await bucket.fastPut({ path: 'file.txt', contents: 'data' }); // already strict
|
||||
```
|
||||
|
||||
## 2025-08-18 - 3.3.10 - fix(helpers)
|
||||
Normalize and robustly parse S3 endpoint configuration; use normalized descriptor in SmartBucket and update dev tooling
|
||||
|
||||
|
||||
Reference in New Issue
Block a user