Skip to content

Commit 3b2c36a

Browse files
brentragerRoux
andauthored
Adding fully tested File library ready for publishing. (#1)
* Currently in a good state so saving progress. * Tests are running. * Added metadata getters. * Made some good progress with the tests for new changes. * All tests passing. * Integration test working. * Adding fully tested File library ready for publishing. --------- Co-authored-by: Roux <roux@smoo.ai>
1 parent adf46d6 commit 3b2c36a

20 files changed

+4285
-493
lines changed

.changeset/puny-ravens-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@smooai/file': patch
3+
---
4+
5+
Adding fully tested File library ready for publishing.

.github/workflows/pr-checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Setup Node.js
1616
uses: actions/setup-node@v4
1717
with:
18-
node-version: '20'
18+
node-version: 22
1919

2020
- uses: pnpm/action-setup@v2
2121
with:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Setup node.js
2929
uses: actions/setup-node@v4
3030
with:
31-
node-version: 20
31+
node-version: 22
3232
cache: 'pnpm'
3333

3434
- name: Install dependencies

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v20.13.0
1+
v22.14.0

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# @smooai/library-template
1+
# @smooai/file
22

33
## 1.0.2
44

README.md

Lines changed: 178 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,52 +35,202 @@ SmooAI is a platform for building and deploying AI-powered apps.
3535

3636
Learn more on [smoo.ai](https://smoo.ai)
3737

38-
## About @smooai/library-template
38+
## About @smooai/file
3939

40-
A template repository for creating new SmooAI libraries with standardized tooling, configuration, and best practices.
40+
A powerful file handling library for Node.js that provides a unified interface for working with files from local filesystem, S3, URLs, and more. Built with streaming in mind, it handles file bytes lazily where possible to minimize memory usage and improve performance.
4141

42-
![GitHub License](https://img.shields.io/github/license/SmooAI/library-template?style=for-the-badge)
43-
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/SmooAI/library-template/release.yml?style=for-the-badge)
44-
![GitHub Repo stars](https://img.shields.io/github/stars/SmooAI/library-template?style=for-the-badge)
42+
![NPM Version](https://img.shields.io/npm/v/%40smooai%2Ffile?style=for-the-badge)
43+
![NPM Downloads](https://img.shields.io/npm/dw/%40smooai%2Ffile?style=for-the-badge)
44+
![NPM Last Update](https://img.shields.io/npm/last-update/%40smooai%2Ffile?style=for-the-badge)
45+
46+
![GitHub License](https://img.shields.io/github/license/SmooAI/file?style=for-the-badge)
47+
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/SmooAI/file/release.yml?style=for-the-badge)
48+
![GitHub Repo stars](https://img.shields.io/github/stars/SmooAI/file?style=for-the-badge)
49+
50+
### Install
51+
52+
```sh
53+
pnpm add @smooai/file
54+
```
4555

4656
### Key Features
4757

48-
- 📦 Preconfigured development environment with TypeScript, ESLint, and Prettier
49-
- 🧪 Testing setup with Vitest
50-
- 🔄 Changesets for version management
51-
- 📚 Integration with SmooAI core utilities
58+
#### 🚀 Stream-First Design
5259

53-
### Dependencies
60+
- Lazy loading of file contents
61+
- Memory-efficient processing
62+
- Automatic stream handling
63+
- Support for both Node.js and Web streams
5464

55-
This template comes pre-configured with essential SmooAI packages:
65+
#### 📦 Multiple File Sources
5666

57-
#### @smooai/logger
67+
- **Local Filesystem**
5868

59-
A structured logging utility for SmooAI applications that provides:
69+
- Read and write operations
70+
- File system checks
71+
- Metadata extraction
6072

61-
- Standardized log formatting
62-
- Log level management
63-
- Integration with SmooAI's logging infrastructure
73+
- **URLs**
6474

65-
#### @smooai/utils
75+
- Automatic download
76+
- Stream-based transfer
77+
- Header metadata extraction
6678

67-
Common utility functions and helpers used across SmooAI applications.
79+
- **S3 Objects**
6880

69-
### Development Setup
81+
- Direct S3 integration (download and upload)
82+
- Stream-based transfer
83+
- Header metadata extraction
84+
- Signed URL generation
7085

71-
1. Clone the repository
72-
2. Install dependencies:
86+
- **FormData**
87+
- Ease of use for Multipart FormData upload
7388

74-
```sh
75-
pnpm install
89+
#### 🔍 Intelligent File Type Detection
90+
91+
Powered by [file-type](https://github.com/sindresorhus/file-type), providing:
92+
93+
- Magic number detection
94+
- MIME type inference
95+
- File extension detection
96+
- Support for 100+ file types
97+
98+
#### 📝 Rich Metadata
99+
100+
- File name and extension
101+
- MIME type detection
102+
- File size
103+
- Last modified date
104+
- Creation date
105+
- File hash/checksum
106+
- URL and path information
107+
- Source type
108+
109+
### Examples
110+
111+
- [Basic Usage](#basic-usage)
112+
- [Streaming Operations](#streaming-operations)
113+
- [S3 Integration](#s3-integration)
114+
- [File Type Detection](#file-type-detection)
115+
- [FormData Support](#formdata-support)
116+
117+
#### Basic Usage <a name="basic-usage"></a>
118+
119+
```typescript
120+
import File from '@smooai/file';
121+
122+
// Create a file from a local path
123+
const file = await File.createFromFile('path/to/file.txt');
124+
125+
// Read file contents (streams automatically)
126+
const content = await file.readFileString();
127+
console.log(content);
128+
129+
// Get file metadata
130+
console.log(file.metadata);
131+
// {
132+
// name: 'file.txt',
133+
// mimeType: 'text/plain',
134+
// size: 1234,
135+
// extension: 'txt',
136+
// path: 'path/to/file.txt',
137+
// lastModified: Date,
138+
// createdAt: Date
139+
// }
140+
```
141+
142+
<p align="right">(<a href="#examples">back to examples</a>)</p>
143+
144+
#### Streaming Operations <a name="streaming-operations"></a>
145+
146+
```typescript
147+
import File from '@smooai/file';
148+
149+
// Create a file from a URL (streams automatically)
150+
const file = await File.createFromUrl('https://example.com/large-file.zip');
151+
152+
// Pipe to a destination (streams without loading entire file)
153+
await file.pipeTo(someWritableStream);
154+
155+
// Read as bytes (streams in chunks)
156+
const bytes = await file.readFileBytes();
157+
158+
// Save to filesystem (streams directly)
159+
const { original, newFile } = await file.saveToFile('downloads/file.zip');
76160
```
77161

78-
### Available Scripts
162+
<p align="right">(<a href="#examples">back to examples</a>)</p>
163+
164+
#### S3 Integration <a name="s3-integration"></a>
165+
166+
```typescript
167+
import File from '@smooai/file';
168+
169+
// Create from S3 (streams automatically)
170+
const file = await File.createFromS3('my-bucket', 'path/to/file.jpg');
171+
172+
// Upload to S3 (streams directly)
173+
await file.uploadToS3('my-bucket', 'remote/file.jpg');
174+
175+
// Save to S3 (creates new file instance)
176+
const { original, newFile } = await file.saveToS3('my-bucket', 'remote/file.jpg');
177+
178+
// Move to S3 (deletes local file if source was local)
179+
const s3File = await file.moveToS3('my-bucket', 'remote/file.jpg');
180+
181+
// Generate signed URL
182+
const signedUrl = await s3File.getSignedUrl(3600); // URL expires in 1 hour
183+
```
184+
185+
<p align="right">(<a href="#examples">back to examples</a>)</p>
186+
187+
#### File Type Detection <a name="file-type-detection"></a>
188+
189+
```typescript
190+
import File from '@smooai/file';
191+
192+
const file = await File.createFromFile('document.xml');
193+
194+
// Get file type information (detected via magic numbers)
195+
console.log(file.mimeType); // 'application/xml'
196+
console.log(file.extension); // 'xml'
197+
198+
// File type is automatically detected from:
199+
// - Magic numbers (via file-type)
200+
// - MIME type headers
201+
// - File extension
202+
// - Custom detectors
203+
```
204+
205+
<p align="right">(<a href="#examples">back to examples</a>)</p>
206+
207+
#### FormData Support <a name="formdata-support"></a>
208+
209+
```typescript
210+
import File from '@smooai/file';
211+
212+
const file = await File.createFromFile('document.pdf');
213+
214+
// Convert to FormData for uploads
215+
const formData = await file.toFormData('document');
216+
217+
// Use with fetch or other HTTP clients
218+
await fetch('https://api.example.com/upload', {
219+
method: 'POST',
220+
body: formData,
221+
});
222+
```
223+
224+
<p align="right">(<a href="#examples">back to examples</a>)</p>
225+
226+
### Built With
79227

80-
- `pnpm test` - Run tests using Vitest
81-
- `pnpm build` - Build the library using tsup
82-
- `pnpm lint` - Run ESLint
83-
- `pnpm format` - Format code with Prettier
228+
- TypeScript
229+
- Node.js File System API
230+
- AWS SDK v3
231+
- [file-type](https://github.com/sindresorhus/file-type) for magic number-based MIME type detection
232+
- [@smooai/fetch](https://github.com/SmooAI/fetch) for URL downloads
233+
- [@smooai/logger](https://github.com/SmooAI/logger) for structured logging
84234

85235
## Contributing
86236

package.json

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
11
{
2-
"name": "@smooai/library-template",
2+
"name": "@smooai/file",
33
"version": "1.0.2",
44
"private": true,
5-
"description": "SmooAI Library Template",
6-
"homepage": "https://github.com/SmooAI/library-template#readme",
5+
"description": "A powerful file handling library for Node.js that provides a unified interface for working with files from local filesystem, S3, URLs, and more. Built with streaming in mind, it handles file bytes lazily where possible to minimize memory usage and improve performance.",
6+
"homepage": "https://github.com/SmooAI/file#readme",
77
"bugs": {
8-
"url": "https://github.com/SmooAI/library-template/issues"
8+
"url": "https://github.com/SmooAI/file/issues"
99
},
1010
"repository": {
1111
"type": "git",
12-
"url": "https://github.com/SmooAI/library-template.git"
12+
"url": "https://github.com/SmooAI/file.git"
1313
},
1414
"license": "MIT",
1515
"author": {
1616
"name": "SmooAI",
1717
"email": "brent@smooai.com",
1818
"url": "https://smooai.com"
1919
},
20-
"exports": {},
21-
"main": "index.js",
20+
"exports": {
21+
"./File": {
22+
"types": "./dist/File.d.ts",
23+
"import": "./dist/File.mjs",
24+
"require": "./dist/File.js",
25+
"default": "./dist/File.js"
26+
},
27+
".": {
28+
"types": "./dist/index.d.ts",
29+
"import": "./dist/index.mjs",
30+
"require": "./dist/index.js",
31+
"default": "./dist/index.js"
32+
}
33+
},
34+
"main": "./dist/index.js",
35+
"module": "./dist/index.mjs",
36+
"types": "./dist/index.d.ts",
37+
"files": [
38+
"dist/**"
39+
],
2240
"scripts": {
2341
"build": "pnpm create-entry-points -i \"src/**/*.ts\" && pnpm tsup",
2442
"check-all": "pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run build",
@@ -27,30 +45,47 @@
2745
"lint": "eslint src/",
2846
"lint:fix": "eslint src/ --fix",
2947
"prepare": "husky",
30-
"test": "vitest run --passWithNoTests",
48+
"test": "vitest run",
49+
"test:integration": "vitest run File.integration.spec",
3150
"typecheck": "tsc --noEmit --skipLibCheck",
3251
"watch": "tsup --watch"
3352
},
3453
"dependencies": {
35-
"@smooai/logger": "^1.0.14",
36-
"@smooai/utils": "^1.0.12"
54+
"@aws-sdk/client-s3": "^3.777.0",
55+
"@aws-sdk/s3-request-presigner": "^3.777.0",
56+
"@file-type/xml": "^0.4.1",
57+
"@smooai/fetch": "^1.0.7",
58+
"@smooai/logger": "^1.0.19",
59+
"@smooai/utils": "^1.0.18",
60+
"content-disposition": "^0.5.4",
61+
"file-type": "^20.4.1",
62+
"formdata-node": "^6.0.3",
63+
"mime-types": "^2.1.35",
64+
"tiny-invariant": "^1.3.3"
3765
},
3866
"devDependencies": {
3967
"@changesets/cli": "^2.28.1",
40-
"@smooai/config-eslint": "^1.0.9",
41-
"@smooai/config-typescript": "^1.0.13",
42-
"@types/node": "^20.13.0",
68+
"@smooai/config-eslint": "^1.0.12",
69+
"@smooai/config-typescript": "^1.0.16",
70+
"@types/content-disposition": "^0.5.8",
71+
"@types/mime-types": "^2.1.4",
72+
"@types/node": "^22.13.10",
4373
"@vercel/style-guide": "^6.0.0",
4474
"eslint": "^9.21.0",
4575
"husky": "^9.1.7",
4676
"lint-staged": "^15.4.3",
77+
"msw": "^2.7.3",
4778
"prettier": "^3.5.3",
4879
"prettier-plugin-packagejson": "^2.5.10",
4980
"tsup": "^8.4.0",
50-
"vite": "^5.4.14",
51-
"vite-node": "^3.0.8",
81+
"vite": "^6.2.3",
82+
"vite-node": "^3.0.9",
5283
"vite-tsconfig-paths": "^5.1.4",
53-
"vitest": "^3.0.7"
84+
"vitest": "^3.0.9",
85+
"vitest-tsconfig-paths": "^3.4.1"
5486
},
55-
"packageManager": "pnpm@10.6.1+sha512.40ee09af407fa9fbb5fbfb8e1cb40fbb74c0af0c3e10e9224d7b53c7658528615b2c92450e74cfad91e3a2dcafe3ce4050d80bda71d757756d2ce2b66213e9a3"
87+
"packageManager": "pnpm@10.6.1+sha512.40ee09af407fa9fbb5fbfb8e1cb40fbb74c0af0c3e10e9224d7b53c7658528615b2c92450e74cfad91e3a2dcafe3ce4050d80bda71d757756d2ce2b66213e9a3",
88+
"publishConfig": {
89+
"access": "public"
90+
}
5691
}

0 commit comments

Comments
 (0)