@emkodev/emkore 1.0.3
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/CHANGELOG.md +269 -0
- package/DEVELOPER_GUIDE.md +227 -0
- package/LICENSE +21 -0
- package/README.md +126 -0
- package/bun.lock +22 -0
- package/example/README.md +200 -0
- package/example/create-user.interactor.ts +88 -0
- package/example/dto/user.dto.ts +34 -0
- package/example/entity/user.entity.ts +54 -0
- package/example/index.ts +18 -0
- package/example/interface/create-user.usecase.ts +93 -0
- package/example/interface/user.repository.ts +23 -0
- package/mod.ts +1 -0
- package/package.json +32 -0
- package/src/common/abstract.actor.ts +59 -0
- package/src/common/abstract.entity.ts +59 -0
- package/src/common/abstract.interceptor.ts +17 -0
- package/src/common/abstract.repository.ts +162 -0
- package/src/common/abstract.usecase.ts +113 -0
- package/src/common/config/config-registry.ts +190 -0
- package/src/common/config/config-section.ts +106 -0
- package/src/common/exception/authorization-exception.ts +28 -0
- package/src/common/exception/repository-exception.ts +46 -0
- package/src/common/interceptor/audit-log.interceptor.ts +181 -0
- package/src/common/interceptor/authorization.interceptor.ts +252 -0
- package/src/common/interceptor/performance.interceptor.ts +101 -0
- package/src/common/llm/api-definition.type.ts +185 -0
- package/src/common/pattern/unit-of-work.ts +78 -0
- package/src/common/platform/env.ts +38 -0
- package/src/common/registry/usecase-registry.ts +80 -0
- package/src/common/type/interceptor-context.type.ts +25 -0
- package/src/common/type/json-schema.type.ts +80 -0
- package/src/common/type/json.type.ts +5 -0
- package/src/common/type/lowercase.type.ts +48 -0
- package/src/common/type/metadata.type.ts +5 -0
- package/src/common/type/money.class.ts +384 -0
- package/src/common/type/permission.type.ts +43 -0
- package/src/common/validation/validation-result.ts +52 -0
- package/src/common/validation/validators.ts +441 -0
- package/src/index.ts +95 -0
- package/test/unit/abstract-actor.test.ts +608 -0
- package/test/unit/actor.test.ts +89 -0
- package/test/unit/api-definition.test.ts +628 -0
- package/test/unit/authorization.test.ts +101 -0
- package/test/unit/entity.test.ts +95 -0
- package/test/unit/money.test.ts +480 -0
- package/test/unit/validation.test.ts +138 -0
- package/tsconfig.json +18 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to
|
|
7
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
## [1.0.3] - 2026-01-20
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Authorization**: Added `PROJECT` resource scope for project-level
|
|
16
|
+
permissions
|
|
17
|
+
- `ResourceScope.PROJECT` is now available as a scope parallel to `TEAM` under
|
|
18
|
+
`BUSINESS`
|
|
19
|
+
- Project scope satisfies PROJECT and OWNED scopes
|
|
20
|
+
- BUSINESS scope now satisfies PROJECT scope (in addition to TEAM and OWNED)
|
|
21
|
+
- Added `projectId` field to `ResourceConstraints` for project-scoped
|
|
22
|
+
permissions
|
|
23
|
+
- Authorization interceptor now validates `projectId` constraints similar to
|
|
24
|
+
`teamId`
|
|
25
|
+
|
|
26
|
+
## [1.0.2] - 2026-01-19
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **Type Utilities**: Export `Lowercase`, `LowercaseArray`, and
|
|
31
|
+
`LowercaseArrayUnion` types for enforcing lowercase string literals in const
|
|
32
|
+
arrays
|
|
33
|
+
|
|
34
|
+
## [1.0.1] - 2026-01-16
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Documentation**: Removed unsubstantiated claims from README
|
|
39
|
+
- Fixed inconsistent test coverage claims
|
|
40
|
+
- Removed "minimal `any` usage" contradiction
|
|
41
|
+
- Clarified browser support (removed unverified browser claim)
|
|
42
|
+
- Simplified code quality metrics to avoid misleading claims
|
|
43
|
+
|
|
44
|
+
## [1.0.0] - 2026-01-15
|
|
45
|
+
|
|
46
|
+
### 🎉 Stable Release
|
|
47
|
+
|
|
48
|
+
First stable release of Emkore! The framework is now production-ready with a
|
|
49
|
+
stable API.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- **Type Safety Improvements**: Eliminated all `Record<string, any>` usage
|
|
54
|
+
- Replaced with proper `JsonSchema` and `MutableJsonSchema` types
|
|
55
|
+
- Added dedicated `Metadata` type for type-safe metadata handling
|
|
56
|
+
- Full TypeScript strict mode compliance with zero `any` types (except where
|
|
57
|
+
absolutely necessary)
|
|
58
|
+
|
|
59
|
+
- **Enhanced Examples**: Complete rewrite of examples to match production
|
|
60
|
+
patterns
|
|
61
|
+
- Separated concerns with Entity/DTO pattern
|
|
62
|
+
- Added proper validation functions
|
|
63
|
+
- Improved interface definitions
|
|
64
|
+
- Added comprehensive example documentation
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- **New Type Definitions**:
|
|
69
|
+
- `JsonSchema` and `MutableJsonSchema` for JSON Schema handling
|
|
70
|
+
- `Metadata` type for consistent metadata typing
|
|
71
|
+
- Proper type exports in main index
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- **TypeScript Compilation**: Resolved all type errors
|
|
76
|
+
- Fixed readonly vs mutable property assignments
|
|
77
|
+
- Corrected type incompatibilities in API definitions
|
|
78
|
+
- Fixed array spread operator issues with readonly arrays
|
|
79
|
+
|
|
80
|
+
- **Linting Issues**: Cleaned up entire codebase
|
|
81
|
+
- Removed unnecessary `async` keywords from synchronous methods
|
|
82
|
+
- Fixed import declarations (import type where appropriate)
|
|
83
|
+
- Corrected lint-ignore comment placement
|
|
84
|
+
- Cleaned up test imports
|
|
85
|
+
|
|
86
|
+
- **Performance Interceptor**: Fixed async method signatures to match interface
|
|
87
|
+
|
|
88
|
+
### Quality
|
|
89
|
+
|
|
90
|
+
- Zero linting errors across entire codebase
|
|
91
|
+
- All tests passing (100% success rate)
|
|
92
|
+
- Full TypeScript strict mode compliance
|
|
93
|
+
- Production-ready code quality
|
|
94
|
+
|
|
95
|
+
## [0.4.3] - 2026-01-14
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
|
|
99
|
+
- **BaseFilter<TDto>** type for repository query filtering
|
|
100
|
+
- Extracts business fields from DTO while adding type-safe date range queries
|
|
101
|
+
- Supports createdAt, updatedAt, and deletedAt range filtering
|
|
102
|
+
- Exported from main index for public API usage
|
|
103
|
+
|
|
104
|
+
- **Lowercase utility types** for compile-time validation
|
|
105
|
+
- `Lowercase<T>` type ensures string literals contain only lowercase
|
|
106
|
+
characters
|
|
107
|
+
- `LowercaseArray` ensures all array elements are lowercase strings
|
|
108
|
+
- `LowercaseArrayUnion<T>` helper to extract union types from lowercase arrays
|
|
109
|
+
- Enforces consistency with kebab-case naming conventions
|
|
110
|
+
|
|
111
|
+
## [0.4.2] - 2024-12-24
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
|
|
115
|
+
- **LlmParameter and LlmReturnValue**: Refactored to use type-safe discriminated
|
|
116
|
+
unions for JSON Schema 2020-12 compliance
|
|
117
|
+
- Added support for primitive types: `string`, `number`, `integer`, `boolean`,
|
|
118
|
+
`null`
|
|
119
|
+
- Array types now require `items` field with proper type definitions
|
|
120
|
+
- Object types now support optional `properties` and `required` fields
|
|
121
|
+
- TypeScript enforces correct fields based on type (e.g., `items` only on
|
|
122
|
+
arrays)
|
|
123
|
+
- **apiDefinitionToJsonSchema**: Updated to properly handle `items` for arrays
|
|
124
|
+
and `properties`/`required` for objects
|
|
125
|
+
- Moved test files to proper `test/unit/` directory structure
|
|
126
|
+
|
|
127
|
+
### Added
|
|
128
|
+
|
|
129
|
+
- Comprehensive test suite for `apiDefinitionToJsonSchema` with 19 test cases
|
|
130
|
+
covering all type variations
|
|
131
|
+
|
|
132
|
+
## [0.4.1] - 2025-12-21
|
|
133
|
+
|
|
134
|
+
### Added
|
|
135
|
+
|
|
136
|
+
- **Actor.getTeamIds()**: New method to extract unique team IDs from actor
|
|
137
|
+
permissions
|
|
138
|
+
- Returns array of team IDs based on permissions with `constraints.teamId`
|
|
139
|
+
- Implements caching for performance within actor lifetime (request scope)
|
|
140
|
+
- Cache automatically invalidates when permissions are modified
|
|
141
|
+
- Comprehensive test coverage with 15 test cases covering edge cases, caching
|
|
142
|
+
behavior, and real-world scenarios
|
|
143
|
+
|
|
144
|
+
## [0.4.0] - 2025-12-20
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
|
|
148
|
+
- **Money class**: Type-safe monetary value object with multi-currency support
|
|
149
|
+
- Stores amounts in cents (minor units) to avoid floating-point precision
|
|
150
|
+
errors
|
|
151
|
+
- Enforces currency consistency in all arithmetic operations (throws on USD +
|
|
152
|
+
EUR)
|
|
153
|
+
- Provides locale-aware formatting with Intl.NumberFormat
|
|
154
|
+
- Supports all common monetary operations: add, subtract, multiply, divide
|
|
155
|
+
- Immutable - all operations return new instances
|
|
156
|
+
- Comprehensive comparison methods (equals, lessThan, greaterThan, etc.)
|
|
157
|
+
- **Currency is REQUIRED** - no defaults to prevent accidental currency mixing
|
|
158
|
+
bugs
|
|
159
|
+
- **Cents type**: Type alias for monetary amounts in minor units
|
|
160
|
+
- Makes it explicit that values are in cents, not dollars/euros
|
|
161
|
+
- Use in DTOs and value objects for self-documenting code
|
|
162
|
+
- 67 comprehensive unit tests for Money class
|
|
163
|
+
- Full JSDoc documentation with examples for all Money methods
|
|
164
|
+
|
|
165
|
+
### Examples
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Basic usage
|
|
169
|
+
const price = Money.fromCents(14999, "USD"); // $149.99
|
|
170
|
+
const tax = price.multiply(0.08); // 8% tax
|
|
171
|
+
const total = price.add(tax); // $161.99
|
|
172
|
+
console.log(total.format()); // "$149.99"
|
|
173
|
+
|
|
174
|
+
// Currency safety
|
|
175
|
+
const usd = Money.fromCents(100, "USD");
|
|
176
|
+
const eur = Money.fromCents(100, "EUR");
|
|
177
|
+
usd.add(eur); // ❌ Throws: "Cannot operate on Money with different currencies"
|
|
178
|
+
|
|
179
|
+
// DTOs with Cents type
|
|
180
|
+
interface PriceDto {
|
|
181
|
+
unitPrice: Cents; // Explicit: this is in cents!
|
|
182
|
+
currency: string;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## [0.3.0] - 2025-12-20
|
|
187
|
+
|
|
188
|
+
### Fixed
|
|
189
|
+
|
|
190
|
+
- **SECURITY**: Removed hardcoded `AuthorizationInterceptor` from `Usecase`
|
|
191
|
+
global interceptors. This was a critical security flaw that forced
|
|
192
|
+
authorization on all usecases by default without explicit opt-in.
|
|
193
|
+
|
|
194
|
+
### BREAKING CHANGE (Security Fix)
|
|
195
|
+
|
|
196
|
+
**IMPORTANT**: If you were relying on automatic authorization, you MUST now
|
|
197
|
+
explicitly register the `AuthorizationInterceptor`:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { Usecase } from "@emkodev/emkore";
|
|
201
|
+
import { AuthorizationInterceptor } from "@emkodev/emkore";
|
|
202
|
+
|
|
203
|
+
// Add this at your application startup:
|
|
204
|
+
Usecase.use([new AuthorizationInterceptor()]);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Without this explicit registration, your usecases will NO LONGER have
|
|
208
|
+
authorization checks applied automatically. Review your security requirements
|
|
209
|
+
and update your code accordingly.
|
|
210
|
+
|
|
211
|
+
## [0.2.1] - 2024-12-26
|
|
212
|
+
|
|
213
|
+
### Changed
|
|
214
|
+
|
|
215
|
+
- Refactored UseCase registry system to dedicated module
|
|
216
|
+
- Moved `UseCaseRegistryEntry` and `UseCaseRegistryHelpers` to
|
|
217
|
+
`src/common/registry/usecase-registry.ts`
|
|
218
|
+
- Improved code organization and module structure
|
|
219
|
+
|
|
220
|
+
## [0.2.0] - 2024-12-26
|
|
221
|
+
|
|
222
|
+
### Added
|
|
223
|
+
|
|
224
|
+
- Cross-platform environment variable abstraction (`getEnv`, `getEnvOrDefault`)
|
|
225
|
+
- Support for Node.js, Deno, and browser environments
|
|
226
|
+
- UseCase registry system for auto-discovery and dynamic routing
|
|
227
|
+
- HTTP method and path mapping utilities for REST API generation
|
|
228
|
+
|
|
229
|
+
### Changed
|
|
230
|
+
|
|
231
|
+
- Replaced Deno-specific `Deno.env.get()` calls with platform-agnostic functions
|
|
232
|
+
- Enhanced JSR compatibility and cross-platform support
|
|
233
|
+
|
|
234
|
+
## [0.1.0] - 2024-12-25
|
|
235
|
+
|
|
236
|
+
### Added
|
|
237
|
+
|
|
238
|
+
- Initial release of Emkore Core
|
|
239
|
+
- Base `Entity` class with id generation, ownership tracking, and soft deletion
|
|
240
|
+
- Abstract `Usecase` class with interceptor support for authorization and
|
|
241
|
+
logging
|
|
242
|
+
- `Actor` class for representing users and systems
|
|
243
|
+
- Permission-based authorization system with resource scoping
|
|
244
|
+
- `Money` value object for type-safe monetary calculations
|
|
245
|
+
- Fluent `ValidatorBuilder` for input validation
|
|
246
|
+
- `BaseRepository` interface for data persistence patterns
|
|
247
|
+
- Unit of Work pattern interfaces
|
|
248
|
+
- Configuration management with `ConfigSection` and `ConfigRegistry`
|
|
249
|
+
- Comprehensive exception hierarchy
|
|
250
|
+
- Built-in interceptors for authorization, performance tracking, and audit
|
|
251
|
+
logging
|
|
252
|
+
- LLM API definition types for code generation
|
|
253
|
+
- Complete test suite with unit and integration tests
|
|
254
|
+
- Developer documentation with coding philosophy and best practices
|
|
255
|
+
|
|
256
|
+
### Features
|
|
257
|
+
|
|
258
|
+
- Zero external dependencies
|
|
259
|
+
- Strict TypeScript with no type casting
|
|
260
|
+
- Clean architecture patterns
|
|
261
|
+
- Extensible interceptor system
|
|
262
|
+
- 12-factor app configuration support
|
|
263
|
+
- Type-safe JSON handling
|
|
264
|
+
- Working examples and comprehensive documentation
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
_This project follows [Semantic Versioning](https://semver.org/). Breaking
|
|
269
|
+
changes will increment the major version._
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Developer Guide
|
|
2
|
+
|
|
3
|
+
## Philosophy & Vision
|
|
4
|
+
|
|
5
|
+
This codebase follows a pragmatic, clean code philosophy that prioritizes
|
|
6
|
+
simplicity, maintainability, and type safety without sacrificing developer
|
|
7
|
+
experience.
|
|
8
|
+
|
|
9
|
+
### Core Principles
|
|
10
|
+
|
|
11
|
+
#### 1. No Type Casting
|
|
12
|
+
|
|
13
|
+
- **Never use `as` type assertions** - If TypeScript can't infer it, the code
|
|
14
|
+
structure is wrong
|
|
15
|
+
- Avoid `any` types - Use `unknown` when type is genuinely unknown
|
|
16
|
+
- Let TypeScript's inference do the work - explicit types only when necessary
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
// ❌ Bad
|
|
20
|
+
const result = someFunction() as SomeType;
|
|
21
|
+
|
|
22
|
+
// ✅ Good
|
|
23
|
+
const result: SomeType = someFunction(); // Let it fail if types don't match
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
#### 2. Avoid `| undefined` Union Types
|
|
27
|
+
|
|
28
|
+
- Use optional properties (`?`) instead of union types with undefined
|
|
29
|
+
- Handle undefined cases through conditional logic, not type unions
|
|
30
|
+
- Keep types clean and readable
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// ❌ Bad
|
|
34
|
+
interface Entity {
|
|
35
|
+
deletedAt: Date | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ✅ Good
|
|
39
|
+
interface Entity {
|
|
40
|
+
deletedAt?: Date;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### 3. DRY (Don't Repeat Yourself)
|
|
45
|
+
|
|
46
|
+
- Never duplicate code for slight variations
|
|
47
|
+
- Use spread operators, destructuring, and composition
|
|
48
|
+
- If you're copying code, you're doing it wrong
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// ❌ Bad
|
|
52
|
+
if (condition) {
|
|
53
|
+
return { id, name, age, status: "active" };
|
|
54
|
+
} else {
|
|
55
|
+
return { id, name, age, status: "inactive" };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ✅ Good
|
|
59
|
+
return { id, name, age, status: condition ? "active" : "inactive" };
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### 4. Minimal External Dependencies
|
|
63
|
+
|
|
64
|
+
- Avoid third-party packages unless absolutely necessary
|
|
65
|
+
- Don't import a library to use one or two easily reproducible functions
|
|
66
|
+
- Every dependency is technical debt
|
|
67
|
+
|
|
68
|
+
#### 5. No Nullable Lists
|
|
69
|
+
|
|
70
|
+
- Lists/arrays should never be null or undefined
|
|
71
|
+
- Use empty arrays instead of null/undefined for collections
|
|
72
|
+
- This simplifies consumption and prevents null checks
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// ❌ Bad
|
|
76
|
+
interface Response {
|
|
77
|
+
items?: Item[] | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ✅ Good
|
|
81
|
+
interface Response {
|
|
82
|
+
items: Item[]; // Empty array when no items
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### 6. Clean Commit History
|
|
87
|
+
|
|
88
|
+
- No watermarks in code, comments, or commit messages
|
|
89
|
+
- Commit messages should be concise and meaningful
|
|
90
|
+
- No auto-generated signatures or unnecessary metadata
|
|
91
|
+
|
|
92
|
+
## Architecture Guidelines
|
|
93
|
+
|
|
94
|
+
### Emkore - The Foundation
|
|
95
|
+
|
|
96
|
+
- **Pure abstractions** - No implementation details
|
|
97
|
+
- **Zero dependencies** - Must remain dependency-free
|
|
98
|
+
- **Extensible interfaces** - Consumers implement their own specifics
|
|
99
|
+
- **Optional guidance** - Provide optional methods/properties as reminders
|
|
100
|
+
|
|
101
|
+
### Pattern Implementation
|
|
102
|
+
|
|
103
|
+
#### Repository Pattern
|
|
104
|
+
|
|
105
|
+
- Keep interfaces minimal
|
|
106
|
+
- Let consumers decide on implementation details
|
|
107
|
+
- Don't force specific database paradigms
|
|
108
|
+
|
|
109
|
+
#### Unit of Work
|
|
110
|
+
|
|
111
|
+
- Provide transaction boundaries
|
|
112
|
+
- Optional tracking methods for advanced implementations
|
|
113
|
+
- Don't prescribe how state management works
|
|
114
|
+
|
|
115
|
+
#### Validation
|
|
116
|
+
|
|
117
|
+
- Chainable, fluent API
|
|
118
|
+
- Return comprehensive results, not throw exceptions
|
|
119
|
+
- Let consumers decide how to handle validation failures
|
|
120
|
+
|
|
121
|
+
### Testing Philosophy
|
|
122
|
+
|
|
123
|
+
- **Unit tests for foundations** - Test core abstractions thoroughly
|
|
124
|
+
- **Integration tests for implementations** - Test real-world usage
|
|
125
|
+
- **No mocking for the sake of it** - Test real behavior when possible
|
|
126
|
+
- **Fast feedback** - Tests should run quickly
|
|
127
|
+
|
|
128
|
+
### Code Style
|
|
129
|
+
|
|
130
|
+
#### TypeScript Configuration
|
|
131
|
+
|
|
132
|
+
- Use strict mode - catch errors at compile time
|
|
133
|
+
- Enable all strict flags - better to be safe
|
|
134
|
+
- But handle strictness elegantly (no ugly workarounds)
|
|
135
|
+
|
|
136
|
+
#### Formatting
|
|
137
|
+
|
|
138
|
+
- Let tools handle formatting (Deno fmt)
|
|
139
|
+
- Focus on logic, not spaces
|
|
140
|
+
- Consistency through automation
|
|
141
|
+
|
|
142
|
+
### Performance Considerations
|
|
143
|
+
|
|
144
|
+
- **Optimize when measured** - Don't guess, profile
|
|
145
|
+
- **Use appropriate data structures** - Maps for lookups, Sets for uniqueness
|
|
146
|
+
- **Batch operations** - Reduce round trips
|
|
147
|
+
- **Cache computations** - But invalidate properly
|
|
148
|
+
|
|
149
|
+
### Error Handling
|
|
150
|
+
|
|
151
|
+
- **Be explicit about errors** - Use custom exception types
|
|
152
|
+
- **Fail fast** - Validate early
|
|
153
|
+
- **Provide context** - Error messages should be actionable
|
|
154
|
+
- **Don't swallow errors** - Let them bubble appropriately
|
|
155
|
+
|
|
156
|
+
## Contributing
|
|
157
|
+
|
|
158
|
+
When contributing to this codebase:
|
|
159
|
+
|
|
160
|
+
1. **Understand the existing patterns** - Read the code first
|
|
161
|
+
2. **Follow conventions** - Don't introduce new patterns without discussion
|
|
162
|
+
3. **Write tests** - Untested code is broken code
|
|
163
|
+
4. **Keep it simple** - Clever code is hard to maintain
|
|
164
|
+
5. **Document intentions** - Why, not what
|
|
165
|
+
|
|
166
|
+
## Examples of Good Code
|
|
167
|
+
|
|
168
|
+
### Clean Entity Implementation
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// Simple, no type casting, handles optional properly
|
|
172
|
+
constructor(dto: Dto) {
|
|
173
|
+
this.id = dto.id;
|
|
174
|
+
this.ownerId = dto.ownerId;
|
|
175
|
+
this.createdAt = new Date(dto.createdAt);
|
|
176
|
+
this.updatedAt = new Date(dto.updatedAt);
|
|
177
|
+
if (dto.deletedAt) {
|
|
178
|
+
this.deletedAt = new Date(dto.deletedAt);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Efficient Permission Checking
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// Pre-computed lookups, no repeated iterations
|
|
187
|
+
private static readonly SCOPE_SATISFIES = new Map<ResourceScope, Set<ResourceScope>>([
|
|
188
|
+
[ResourceScope.ALL, new Set([ResourceScope.ALL, ResourceScope.BUSINESS, ResourceScope.PROJECT, ResourceScope.TEAM, ResourceScope.OWNED])],
|
|
189
|
+
// ...
|
|
190
|
+
]);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Type-Safe Constants
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Derive types from constants, not the other way around
|
|
197
|
+
const COMMON_ACTIONS_ARRAY = [
|
|
198
|
+
"create",
|
|
199
|
+
"retrieve",
|
|
200
|
+
"list",
|
|
201
|
+
"count",
|
|
202
|
+
"update",
|
|
203
|
+
"delete",
|
|
204
|
+
] as const;
|
|
205
|
+
|
|
206
|
+
export type CommonAction = typeof COMMON_ACTIONS_ARRAY[number];
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## What We're Building
|
|
210
|
+
|
|
211
|
+
This is not just another framework. It's a foundation for building robust,
|
|
212
|
+
type-safe business applications with:
|
|
213
|
+
|
|
214
|
+
- **Clear separation of concerns** - Business logic separate from infrastructure
|
|
215
|
+
- **Testable by design** - Not by accident
|
|
216
|
+
- **Extensible without modification** - Open/closed principle
|
|
217
|
+
- **Performance when needed** - Not premature optimization
|
|
218
|
+
|
|
219
|
+
The goal is code that:
|
|
220
|
+
|
|
221
|
+
- A new developer can understand quickly
|
|
222
|
+
- Doesn't fight TypeScript's type system
|
|
223
|
+
- Scales without rewrites
|
|
224
|
+
- Makes the right thing easy and the wrong thing hard
|
|
225
|
+
|
|
226
|
+
Remember: We're building for the long term. Every line of code is a liability.
|
|
227
|
+
Make each one count.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Emkore Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Emkore
|
|
2
|
+
|
|
3
|
+
[](https://jsr.io/@emkodev/emkore)
|
|
4
|
+
[](https://jsr.io/@emkodev/emkore)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](./deno.json)
|
|
8
|
+
|
|
9
|
+
A TypeScript foundation framework for building robust, type-safe business
|
|
10
|
+
applications with clean architecture patterns.
|
|
11
|
+
|
|
12
|
+
## Why Emkore?
|
|
13
|
+
|
|
14
|
+
- **Clean architecture patterns** - Built on Domain-Driven Design and SOLID
|
|
15
|
+
principles
|
|
16
|
+
- **Type-safe** - TypeScript with strict mode
|
|
17
|
+
- **Framework agnostic** - Works with Deno, Node.js, and Bun
|
|
18
|
+
- **Zero dependencies** - No external dependencies, pure TypeScript
|
|
19
|
+
- **Comprehensive** - Complete framework with all essential building blocks
|
|
20
|
+
- **Developer-friendly** - Intuitive APIs with comprehensive documentation
|
|
21
|
+
|
|
22
|
+
## Philosophy
|
|
23
|
+
|
|
24
|
+
Emkore provides pure abstractions and patterns for building scalable business
|
|
25
|
+
applications without imposing implementation details. It follows a pragmatic,
|
|
26
|
+
clean code philosophy that prioritizes simplicity, maintainability, and type
|
|
27
|
+
safety.
|
|
28
|
+
|
|
29
|
+
## Key Features
|
|
30
|
+
|
|
31
|
+
- **Zero Dependencies**: Lightweight core with no external dependencies
|
|
32
|
+
- **Type Safety**: Strict TypeScript with comprehensive type checking
|
|
33
|
+
- **Clean Architecture**: Separation of business logic from infrastructure
|
|
34
|
+
- **Extensible**: Pure abstractions that you implement according to your needs
|
|
35
|
+
- **Testing-Friendly**: Built with testability in mind
|
|
36
|
+
|
|
37
|
+
## Code Quality Metrics
|
|
38
|
+
|
|
39
|
+
- 📊 **Pure TypeScript** - No JavaScript required
|
|
40
|
+
- ✅ **Comprehensive Tests** - Extensive unit and integration test suite
|
|
41
|
+
- 🚀 **Direct Execution** - No build step required, runs directly
|
|
42
|
+
- 📦 **Zero Dependencies** - No external packages to manage or audit
|
|
43
|
+
- 📐 **Strict Mode Compliant** - No warnings with strictest TypeScript settings
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
### Deno
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
deno add @emkodev/emkore
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Node.js / npm
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx jsr add @emkodev/emkore
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Bun
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bunx jsr add @emkodev/emkore
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
See the [example](./example/) directory for a complete working example of how
|
|
68
|
+
to:
|
|
69
|
+
|
|
70
|
+
- Create use cases with the `Usecase` base class
|
|
71
|
+
- Implement business logic with proper authorization
|
|
72
|
+
- Use the Entity pattern with DTOs
|
|
73
|
+
- Handle validation and permissions
|
|
74
|
+
|
|
75
|
+
## Core Concepts
|
|
76
|
+
|
|
77
|
+
### Entities
|
|
78
|
+
|
|
79
|
+
Base `Entity` class with built-in id generation, ownership tracking, and soft
|
|
80
|
+
deletion support.
|
|
81
|
+
|
|
82
|
+
### Use Cases
|
|
83
|
+
|
|
84
|
+
Abstract `Usecase<Input, Output>` class with interceptor support for
|
|
85
|
+
authorization, logging, and performance tracking.
|
|
86
|
+
|
|
87
|
+
### Validation
|
|
88
|
+
|
|
89
|
+
Fluent `ValidatorBuilder` for input validation with comprehensive error
|
|
90
|
+
reporting.
|
|
91
|
+
|
|
92
|
+
### Repository Pattern
|
|
93
|
+
|
|
94
|
+
`BaseRepository` interface for data persistence with Unit of Work support.
|
|
95
|
+
|
|
96
|
+
### Authorization
|
|
97
|
+
|
|
98
|
+
Permission-based authorization with `Actor` and resource scoping.
|
|
99
|
+
|
|
100
|
+
### Money Value Object
|
|
101
|
+
|
|
102
|
+
Type-safe `Money` class for monetary calculations.
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
- [Developer Guide](./DEVELOPER_GUIDE.md) - Philosophy, principles, and best
|
|
107
|
+
practices
|
|
108
|
+
- [TypeScript Guide](./TYPESCRIPT.md) - TypeScript-specific guidelines
|
|
109
|
+
- [Platform Dependencies](./PLATFORM-DEPENDENCIES.md) - Platform-specific
|
|
110
|
+
considerations
|
|
111
|
+
- [Examples](./example/) - Working code examples
|
|
112
|
+
|
|
113
|
+
## Contributing
|
|
114
|
+
|
|
115
|
+
1. Read the [Developer Guide](./DEVELOPER_GUIDE.md) to understand our philosophy
|
|
116
|
+
2. Follow existing code patterns and conventions
|
|
117
|
+
3. Write tests for new functionality
|
|
118
|
+
4. Keep it simple and maintainable
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
123
|
+
|
|
124
|
+
## Release Status
|
|
125
|
+
|
|
126
|
+
**Version 1.0.0** - Stable release with a mature, well-tested API.
|
package/bun.lock
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "@emkodev/emkore",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"bun-types": "^1.3.9",
|
|
9
|
+
"typescript": "^5.9.3",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
"packages": {
|
|
14
|
+
"@types/node": ["@types/node@25.3.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A=="],
|
|
15
|
+
|
|
16
|
+
"bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
|
17
|
+
|
|
18
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
19
|
+
|
|
20
|
+
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
|
21
|
+
}
|
|
22
|
+
}
|