scopey
v1.0.1
Published
A lightweight, type-safe TypeScript utility for building complex objects through method chaining
Maintainers
Readme
Scopey
A lightweight, type-safe TypeScript utility for building complex objects through method chaining with full type inference.
Features
- 🎯 Type-safe: Full TypeScript support with automatic type inference
- 🔗 Chainable API: Intuitive method chaining for building complex objects
- 🪶 Lightweight: Zero dependencies, minimal footprint
- 🧩 Flexible: Works with primitives, objects, arrays, and functions
- 📦 CommonJS: Maximum compatibility with existing projects
Installation
npm install scopeyor
yarn add scopeyUsage
Basic Example
import { scope } from "scopey";
const config = scope(3000)
.with((port) => ({ port, host: "localhost" }))
.with(({ port, host }) => ({ url: `http://${host}:${port}` }))
.with(({ port }) => ({ isSecure: port === 443 }))
.value();
console.log(config);
// {
// port: 3000,
// host: 'localhost',
// url: 'http://localhost:3000',
// isSecure: false
// }API
scope<T>(value: T)
Creates a new scope with an initial value.
const result = scope(42).value(); // 42
const result2 = scope({ name: "John" }).value(); // { name: 'John' }.with(transformer)
Transforms the current value. If both the current value and the transformation result are objects, they are merged. Otherwise, the value is replaced.
// Object merging
scope({ a: 1 })
.with(() => ({ b: 2 }))
.value(); // { a: 1, b: 2 }
// Value replacement
scope("hello")
.with(() => ({ message: "world" }))
.value(); // { message: 'world' }
// Property overwriting
scope({ a: 1, b: 2 })
.with(() => ({ b: 3, c: 4 }))
.value(); // { a: 1, b: 3, c: 4 }.only(transformer)
Replaces the entire value with the transformation result, regardless of types.
scope({ a: 1, b: 2 })
.only(() => ({ c: 3 }))
.value(); // { c: 3 }
scope(10)
.only((x) => x * 2)
.value(); // 20.value()
Returns the final value after all transformations.
const result = scope("hello")
.with((msg) => ({ message: msg }))
.value(); // { message: 'hello' }Type Safety
Scopey provides full type inference throughout the chain:
const config = scope(3000)
.with((port) => ({ port, host: "localhost" }))
// TypeScript knows the value is now { port: 3000, host: "localhost" }
.with(({ port, host }) => ({ url: `http://${host}:${port}` }))
// TypeScript knows the value is now { port: 3000, host: "localhost,
// url: "http://localhost:3000" }
.value();
// TypeScript error: Property 'invalid' does not exist
// .with(({ invalid }) => ({ ... }))Development
Setup
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Build the project
npm run build
# Run linting
npm run lint
# Type checking
npm run typecheckProject Structure
scopey/
├── src/
│ ├── index.ts # Main implementation
│ └── index.test.ts # Test suite
├── dist/ # Compiled output (generated)
├── coverage/ # Test coverage reports (generated)
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI configuration
├── package.json
├── tsconfig.json # TypeScript configuration
├── jest.config.js # Jest configuration
└── README.mdTesting
The project uses Jest for testing with ts-jest for TypeScript support. Tests are located alongside source files with .test.ts extension.
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverageContributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please make sure to update tests as appropriate and ensure all tests pass before submitting a PR.
License
MIT
