@maroonedog/luq 0.1.0-alpha → 0.1.0

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.
Files changed (2) hide show
  1. package/README.md +109 -782
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -3,112 +3,32 @@
3
3
 
4
4
  # Luq - Universal Model & API Definition Platform
5
5
 
6
- **Alpha Release**: Single source of truth for API, types, validation, and business logic across all languages
6
+ [![npm version](https://img.shields.io/npm/v/@maroonedog/luq.svg)](https://www.npmjs.com/package/@maroonedog/luq)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
8
+ [![Documentation](https://img.shields.io/badge/docs-luq.dev-purple)](https://luq.dev)
7
9
 
8
- </div>
9
-
10
- ### The Vision: Define Once, Generate Everywhere
11
-
12
- **Luq is not just another validation library.** It's evolving into a unified platform where you define your API contracts, data models, validation rules, and business logic once—then generate type-safe implementations for any language.
13
-
14
- > **Note**: The roadmap and features described here represent our current vision and are subject to change. Nothing beyond the currently released TypeScript library (Phase 1) should be considered final. We'll adapt based on community feedback and technical discoveries.
15
-
16
- ### Who needs Luq?
17
-
18
- **Today (TypeScript Library)**:
19
- - Teams with existing TypeScript types who need validation
20
- - Applications requiring CSP-safe dynamic validation
21
- - Projects needing custom business rules as plugins
22
-
23
- **Tomorrow (.luq Format & Multi-language - 2026)**:
24
- - **Microservices** with different languages needing consistent validation
25
- - **API Gateways** requiring validation at multiple layers
26
- - **Mobile/Web/Backend** sharing the same business rules
27
- - **Enterprise systems** needing unified validation across platforms
28
-
29
- ### Overview
30
-
31
- **Current Release (Phase 1)**: A TypeScript validation library that serves as the foundation for something bigger:
32
- - **Type-first**: Learn from your existing code patterns
33
- - **Plugin Architecture**: Capture business logic as reusable components
34
- - **Production-ready**: CSP-compliant, tree-shakeable (19-23KB gzipped)
35
- - **JSON Schema compatible**: Bridge to existing standards
36
-
37
- **The Journey Ahead**:
38
- 1. **Phase 1** (Now): TypeScript library with plugin system
39
- 2. **Phase 2**: `.luq` language - TypeScript-like validation DSL with IDE support
40
- 3. **Phase 3**: AOT compilation for optimal performance
41
- 4. **Phase 4**: Generate validators for Go, Python, Java, Rust, and more
42
-
43
- ## The Problem We're Solving
44
-
45
- ```javascript
46
- // Current reality: Everything is duplicated across languages
47
-
48
- // Frontend API client (TypeScript)
49
- interface Order { /* manually typed */ }
50
- async function createOrder(order: Order) { /* manually coded */ }
51
- function validateOrder(order: Order) { /* validation duplicated */ }
10
+ **TypeScript validation today → Universal platform tomorrow**
52
11
 
53
- // Backend controller (Java)
54
- @RestController
55
- public class OrderController { /* manually coded */ }
56
- public class Order { /* manually typed */ }
57
- public ValidationResult validateOrder() { /* validation duplicated */ }
58
-
59
- // Mobile app (Swift)
60
- struct Order { /* manually typed */ }
61
- func createOrder() { /* manually coded */ }
62
- func validateOrder() { /* validation duplicated */ }
63
-
64
- // API Documentation
65
- openapi: 3.0.0 # manually maintained, often out of sync
66
- ```
67
-
68
- **The Luq Solution (Future - Single Source of Truth):**
69
- ```typescript
70
- // Define everything once in order.luq
71
- @endpoint("/api/orders")
72
- interface OrderAPI {
73
- @post("/")
74
- create(body: Order): OrderResponse;
75
- }
76
-
77
- interface Order {
78
- @min(0) @businessRule("calculateFromItems")
79
- total: number;
80
-
81
- @minLength(1)
82
- items: Product[];
83
- }
84
- ```
85
-
86
- Generate everything:
87
- ```bash
88
- luq generate order.luq --target=all
89
-
90
- ✓ Generated code for each language
91
- ✓ Type-safe API clients
92
- ✓ Models with validation
93
- ✓ API documentation
94
- ```
12
+ </div>
95
13
 
96
- ## Quick Start (Phase 1 - Available Now)
14
+ ## Quick Start
97
15
 
98
16
  ```bash
99
- npm install @maroonedog/luq
17
+ npm install @maroonedog/luq@alpha
100
18
  ```
101
19
 
102
20
  ```typescript
103
21
  import { Builder } from "@maroonedog/luq";
104
22
  import { requiredPlugin, stringMinPlugin, numberMinPlugin, stringEmailPlugin } from "@maroonedog/luq/plugins";
105
23
 
24
+ // Use your existing TypeScript types
106
25
  type User = {
107
26
  name: string;
108
27
  age: number;
109
28
  email: string;
110
29
  };
111
30
 
31
+ // Add validation without changing your types
112
32
  const validateUser = Builder()
113
33
  .use(requiredPlugin)
114
34
  .use(stringMinPlugin)
@@ -120,760 +40,167 @@ const validateUser = Builder()
120
40
  .v("email", (b) => b.string.required().email())
121
41
  .build();
122
42
 
123
- // This TypeScript code is learning your patterns
124
- // Soon, it will help generate validators for other languages
125
- ```
126
-
127
- ## Why Luq is Practical
128
-
129
- ### Why Not Use Existing Solutions?
130
-
131
- **Similar tools exist, but none provide a complete solution:**
132
-
133
- | Tool | What It Does | What's Missing |
134
- |------|-------------|----------------|
135
- | **TypeSpec** (Microsoft) | API-first contracts | Business logic, runtime validation, custom rules |
136
- | **Smithy** (AWS) | AWS service models | General-purpose use, frontend/mobile generation |
137
- | **JSON Schema** | Structure validation | API definitions, business logic, code generation |
138
- | **Protobuf/gRPC** | RPC & serialization | REST APIs, complex validation, business rules |
139
- | **OpenAPI** | API documentation | Implementation code, business logic, validation |
140
- | **tRPC/GraphQL** | Type-safe APIs | Multi-language support, validation rules |
141
-
142
- **Luq's Unified Approach (Progressive Abstraction Architecture):**
143
-
144
- | Level | What You Get | Status |
145
- |-------|-------------|--------|
146
- | **Level 1** | TypeScript validation library | ✅ Available Now |
147
- | **Level 2** | .luq format (models + validation) | 🚧 Q1-Q3 2026 |
148
- | **Level 3** | Full platform (API + models + validation) | 🔮 Vision |
149
-
150
- **Key Differentiators:**
151
- - **Progressive adoption**: Start with validation, evolve to full platform
152
- - **Single source of truth**: API, types, validation, and business logic together
153
- - **TypeScript-like syntax**: Familiar to millions of developers
154
- - **Generate everything**: Controllers, models, validators, docs, SDKs
155
-
156
- ### Luq's Practical Approach
157
-
158
- | Challenge | Other Libraries | Luq Solution |
159
- |-----------|----------------|--------------|
160
- | **CSP Restrictions** | AJV fails at runtime | ✅ No eval/Function usage |
161
- | **Dynamic Schemas** | AJV Standalone can't adapt | ✅ Full runtime flexibility |
162
- | **Existing Types** | Rewrite as schemas | ✅ Use types as-is |
163
- | **Custom Rules** | Copy-paste code | ✅ Type-safe plugins |
164
- | **Bundle Size** | All-or-nothing | ✅ Import only what you need |
165
-
166
- ## Why Invest in Luq Today?
167
-
168
- ### Immediate Benefits (Phase 1 - Now)
169
- | Feature | Value |
170
- |---------|-------|
171
- | **Type-First** | Use existing TypeScript types |
172
- | **Plugin Architecture** | Capture business logic once |
173
- | **Production-Ready** | CSP-safe, tree-shakeable |
174
- | **JSON Schema Support** | 100% Draft-07 compliance |
175
-
176
- ### Future Benefits (Phase 2-4)
177
- | Feature | Value |
178
- |---------|-------|
179
- | **Universal Validation** | One source of truth for all platforms |
180
- | **Business Logic Preservation** | Never duplicate complex rules |
181
- | **Language Agnostic** | Generate for any target language |
182
- | **Performance Optimized** | AOT compilation when needed |
183
-
184
- ### The Strategic Advantage
185
-
186
- **Start using Luq today to**:
187
- 1. Solve immediate TypeScript validation needs
188
- 2. Gradually capture your business rules as plugins
189
- 3. Prepare for automatic multi-language generation
190
- 4. Future-proof your validation strategy
191
-
192
- ## Motivation
193
-
194
- ### The Real Problem: Death by a Thousand Cuts
195
-
196
- Every application needs input validation. It's not optional—it's fundamental. Yet despite decades of software evolution, validation remains surprisingly painful:
197
-
198
- **The daily frustrations that sparked Luq:**
199
-
200
- ```typescript
201
- // Frontend (TypeScript)
202
- function validateOrder(order: Order) {
203
- // Write validation logic once...
43
+ const result = validateUser({ name: "John", age: 25, email: "john@example.com" });
44
+ if (!result.valid) {
45
+ console.log(result.issues); // Type-safe error details
204
46
  }
47
+ ```
205
48
 
206
- // BFF (Node.js)
207
- function validateOrder(order) {
208
- // Write it again, slightly different...
209
- }
49
+ ## Why Luq?
210
50
 
211
- // Backend (Java/Python/Go)
212
- public ValidationResult validateOrder(Order order) {
213
- // Write it yet again, hope it matches...
214
- }
51
+ ### Today's Problem
52
+ You write the same validation logic three times:
53
+ - Frontend (TypeScript)
54
+ - Backend (Java/Python/Go)
55
+ - Mobile (Swift/Kotlin)
215
56
 
216
- // Three implementations. Three chances for bugs. Zero consistency.
217
- ```
57
+ Each implementation drifts apart. Bugs multiply. Business rules become inconsistent.
218
58
 
219
- **The "solutions" that aren't:**
220
-
221
- 1. **JSON/YAML validation configs**: Trading code for configuration hell
222
- ```yaml
223
- # Expressing complex business logic in YAML? No thanks.
224
- rules:
225
- - field: discount
226
- when:
227
- customer.tier:
228
- not_in: [gold, platinum]
229
- max: 0
230
- ```
59
+ ### Luq's Solution
60
+ 1. **Today**: Type-safe TypeScript validation that works with your existing types
61
+ 2. **Tomorrow**: Define once in `.luq`, generate validators for every language
62
+ 3. **Future**: Complete API & model platform
231
63
 
232
- 2. **Runtime schema validators**: Losing type safety for "flexibility"
233
- ```javascript
234
- // Types and validation drift apart over time
235
- const schema = { /* 500 lines of schema */ }
236
- type User = any; // "We'll fix the types later"
237
- ```
238
-
239
- 3. **Code generation from specs**: One-way streets with no return
240
- ```bash
241
- # Generate once, customize, now you can never regenerate
242
- openapi-generator generate -i spec.yaml
243
- # Months later: spec and code are completely out of sync
244
- ```
245
-
246
- ### Why Luq Exists
247
-
248
- I searched for a solution that would let me:
249
- - Write validation logic in a code-like manner (not JSON/YAML)
250
- - Share the exact same rules across TypeScript, Java, Python, etc.
251
- - Keep my existing TypeScript types as the source of truth
252
- - Gradually evolve from simple validation to a complete platform
253
-
254
- No existing OSS project met these needs. They all forced compromises:
255
- - Use our schema format (forget your existing types)
256
- - Use our configuration language (goodbye type safety)
257
- - Use our specific stack (vendor lock-in)
258
- - Generate once and maintain forever (technical debt from day one)
259
-
260
- **So I built Luq with a simple philosophy:**
261
- 1. **Phase 1**: Solve today's validation pain in TypeScript
262
- 2. **Phase 2**: Define once in .luq, generate for every language
263
- 3. **Phase 3**: Expand to complete API/model/business logic platform
264
-
265
- This isn't about building another validation library. It's about ending the cycle of rewriting the same validation logic in every layer of every application.
266
-
267
- ### Migration Considerations
268
-
269
- Teams evaluating validation solutions often face practical constraints:
270
-
271
- | Constraint | Challenge | Luq's Approach |
272
- |------------|-----------|----------------|
273
- | **Organizational** | Established standards and architecture | Works with existing TypeScript types |
274
- | **Time** | Limited resources for refactoring | Incremental adoption possible |
275
- | **Risk** | Production stability requirements | Non-breaking additive changes |
276
-
277
- **Optional Progressive Path:**
278
-
279
- 1. Start with Builder pattern using existing types
280
- 2. Convert to declarative `.luq` format when beneficial
281
- 3. Generate optimized validators via AOT compilation
282
- 4. Future: Cross-language code generation
283
-
284
- ### Validation Scope Comparison
285
-
286
- | Tool Category | Focus | Capabilities |
287
- |---------------|-------|-------------|
288
- | **API Specs** (OpenAPI, GraphQL) | Structure & Types | Basic constraints |
289
- | **Schema Validators** | Type Safety | Type + simple rules |
290
- | **Luq (.luq format)** | Complete Validation | Type + constraints + relationships + business logic |
291
-
292
- Luq's planned `.luq` format aims to capture:
293
- - Field-level constraints (min, max, patterns)
294
- - Cross-field relationships
295
- - Contextual validation rules
296
- - Domain-specific business logic
297
-
298
- ### Choosing Between Approaches
299
-
300
- | Factor | Schema-First | Type-First |
301
- |--------|--------------|------------|
302
- | **Best For** | New projects | Existing codebases |
303
- | **Type Source** | Generated from schema | Already defined |
304
- | **Migration Effort** | Rewrite types as schemas | Add validation to existing types |
305
- | **Type Safety** | Schema drives types | Types drive validation |
306
-
307
- Both approaches are valid. The choice depends on your project's context and constraints.
308
-
309
- ### Technical Design Decisions
310
-
311
- **Architecture Choices:**
312
-
313
- | Decision | Trade-off | Rationale |
314
- |----------|-----------|-----------|
315
- | **Plugin System** | Performance vs Extensibility | Prioritizes customization and tree-shaking |
316
- | **Type-First** | Learning curve vs Migration ease | Reduces friction for existing projects |
317
- | **Zero Dependencies** | Features vs Bundle size | Ensures predictable bundle size |
318
-
319
- **Performance Considerations:**
320
- - Optimized for common validation patterns (required fields, length checks, ranges)
321
- - Plugin system adds ~15-20% overhead vs monolithic code
322
- - AOT compilation planned to eliminate runtime overhead
323
-
324
- **Note:** Different projects have different needs. Luq is one option among many excellent validation libraries in the ecosystem.
325
-
326
- ## Performance & Bundle Size
327
-
328
- ### Bundle Size Comparison (gzipped, measured 2025-08-14)
329
-
330
- | Library | Simple Schema | Complex Schema | Notes |
331
- |---------|---------------|----------------|-------|
332
- | **AJV Standalone** | 1.03 KB | 4.63 KB | Pre-compiled validation |
333
- | **Valibot** | 1.31 KB | 2.49 KB | Modular design |
334
- | **Yup** | 12.80 KB | 13.40 KB | Simple API |
335
- | **Luq** | 19.10 KB | 22.47 KB | Tree-shakable plugins |
336
- | **Luq (JsonSchema)** | 26.06 KB | 29.07 KB | JSON Schema with individual plugins |
337
- | **Luq (JsonSchema Full)** | 31.75 KB | 32.32 KB | All JSON Schema features |
338
- | **AJV** | 37.78 KB | 38.33 KB | Full JSON Schema |
339
- | **Joi** | 44.44 KB | 45.00 KB | Server-focused |
340
- | **Zod** | 47.45 KB | 48.12 KB | Feature-rich |
341
-
342
- ### Performance Benchmarks (ops/sec)
343
-
344
- > **Context**: Raw speed isn't everything. AJV achieves top performance using `new Function()` which fails in CSP-restricted environments. AJV Standalone requires build-time compilation, preventing dynamic schemas. Luq provides the best balance for real-world production use.
345
-
346
- #### Simple Schema
347
- | Library | Operations/sec | Relative | CSP Safe | Dynamic |
348
- |---------|---------------|----------|----------|---------|
349
- | **AJV Standalone** | 3,307,131 | 267.6x | ✅ | ❌ |
350
- | **AJV** | 2,480,209 | 200.6x | ❌ | ✅ |
351
- | **Luq (JsonSchema)** | 1,684,363 | 136.2x | ✅ | ✅ |
352
- | **Luq (JsonSchema Full)** | 1,586,665 | 128.3x | ✅ | ✅ |
353
- | **Luq** | 1,235,123 | 100.0x | ✅ | ✅ |
354
- | **Valibot** | 902,700 | 73.0x | ✅ | ✅ |
355
- | **Zod** | 486,275 | 39.3x | ✅ | ✅ |
356
- | **Joi** | 175,362 | 14.2x | ✅ | ✅ |
357
- | **Yup** | 130,129 | 10.5x | ✅ | ✅ |
358
-
359
- #### Complex Schema
360
- | Library | Operations/sec | Relative | CSP Safe | Dynamic |
361
- |---------|---------------|----------|----------|---------|
362
- | **AJV Standalone** | 239,848 | 5.51x | ✅ | ❌ |
363
- | **AJV** | 232,378 | 5.34x | ❌ | ✅ |
364
- | **Valibot** | 171,352 | 3.94x | ✅ | ✅ |
365
- | **Zod** | 61,488 | 1.41x | ✅ | ✅ |
366
- | **Luq** | 43,524 | 1.00x | ✅ | ✅ |
367
- | **Luq (JsonSchema Full)** | 31,462 | 0.72x | ✅ | ✅ |
368
- | **Luq (JsonSchema)** | 29,257 | 0.67x | ✅ | ✅ |
369
- | **Joi** | 23,552 | 0.54x | ✅ | ✅ |
370
- | **Yup** | 5,841 | 0.13x | ✅ | ✅ |
371
-
372
- *Test Environment: AMD Ryzen 7 5825U, 5.8GB RAM, Node.js v22.12.0*
373
-
374
- ### The Practical Choice
375
-
376
- **For production environments where you need:**
377
- - ✅ Dynamic validation rules (from API/CMS)
378
- - ✅ CSP compliance (no eval/Function)
379
- - ✅ Type safety with existing TypeScript types
380
- - ✅ Reasonable performance (faster than Yup/Joi)
381
-
382
- **Luq is the most practical choice.**
383
-
384
- **Note**: Performance numbers may vary with strict key validation. AJV's speed advantage comes at the cost of CSP compatibility.
64
+ ### Key Features
65
+ ✅ **Works with existing TypeScript types** - No schema rewriting
66
+ **CSP-safe** - No eval/Function, works everywhere (unlike AJV)
67
+ **Dynamic validation** - Load rules from API/CMS at runtime
68
+ **Tree-shakeable plugins** - Only pay for what you use (19-23KB gzipped)
69
+ ✅ **100% JSON Schema compatible** - Easy migration path
70
+ ✅ **Business logic as plugins** - Reusable, type-safe validation rules
385
71
 
386
72
  ## JSON Schema Support
387
73
 
388
- Luq provides 100% JSON Schema Draft-07 support through a modular plugin system. You can import all necessary plugins at once or cherry-pick specific features.
389
-
390
- ### Quick Setup
391
-
392
74
  ```typescript
393
- import { Builder } from "@maroonedog/luq";
394
75
  import { jsonSchemaFullFeaturePlugin } from "@maroonedog/luq/plugins/jsonSchemaFullFeature";
395
76
 
396
- // Single plugin import for full JSON Schema support
77
+ // Full JSON Schema Draft-07 support with one plugin
397
78
  const validator = Builder()
398
79
  .use(jsonSchemaFullFeaturePlugin)
399
80
  .fromJsonSchema({
400
81
  type: "object",
401
82
  properties: {
402
83
  email: { type: "string", format: "email" },
403
- age: { type: "number", minimum: 18 },
84
+ age: { type: "number", minimum: 18 }
404
85
  },
405
- required: ["email"],
86
+ required: ["email"]
406
87
  })
407
88
  .build();
408
89
  ```
409
90
 
410
- ### JSON Schema Support Summary
411
-
412
- Luq provides **100% JSON Schema Draft-07 compliance** through modular plugins:
413
-
414
- | Category | Coverage | Examples |
415
- |----------|----------|----------|
416
- | **Core Types** | ✅ Complete | string, number, boolean, null, array, object |
417
- | **String Formats** | ✅ 15+ formats | email, url, uuid, date-time, ipv4/ipv6 |
418
- | **Constraints** | ✅ All standard | min/max, pattern, unique, required |
419
- | **Schema Composition** | ✅ Full support | allOf, anyOf, oneOf, not |
420
- | **Advanced Features** | ✅ Complete | $ref, conditional validation, dependencies |
421
-
422
91
  📖 **[View complete JSON Schema mapping →](https://luq.dev/json-schema)**
423
92
 
424
- ### Using Individual Plugins
425
-
426
- If you prefer to import only the plugins you need:
427
-
428
- ```typescript
429
- import { Builder } from "@maroonedog/luq";
430
- import { jsonSchemaPlugin } from "@maroonedog/luq/plugins/jsonSchema";
431
- import { requiredPlugin } from "@maroonedog/luq/plugins/required";
432
- import { stringMinPlugin } from "@maroonedog/luq/plugins/stringMin";
433
- import { stringEmailPlugin } from "@maroonedog/luq/plugins/stringEmail";
434
- import { numberMinPlugin } from "@maroonedog/luq/plugins/numberMin";
435
-
436
- const validator = Builder()
437
- .use(jsonSchemaPlugin)
438
- .use(requiredPlugin)
439
- .use(stringMinPlugin)
440
- .use(stringEmailPlugin)
441
- .use(numberMinPlugin)
442
- .fromJsonSchema(schema)
443
- .build();
444
- ```
445
-
446
- ## The Journey to Universal Platform (Progressive Abstraction Architecture)
447
-
448
- | Phase | Timeline | What We're Building | Impact |
449
- |-------|----------|-------------------|---------|
450
- | **Level 1** | ✅ Now | TypeScript validation library | **Foundation**: Type-first validation with plugin architecture |
451
- | **Level 2** | Q1-Q3 2026 | .luq format & infrastructure | **Transformation**: Single source for models & validation |
452
- | **v1.0** | Q4 2026 | Java support + production ready | **Expansion**: First multi-language release |
453
- | **Level 3** | Beyond 2026 | Unified platform | **Vision**: API + models + validation + business logic |
454
-
455
- ### Roadmap Highlights
456
-
457
- **Q4 2025**: Frontend framework integration (React hooks, etc.)
458
- **Q1-Q3 2026**: .luq format specification, VSCode extension, Language Server
459
- **Q4 2026**: **v1.0 Release with Java support & production toolchain**
460
- **2027+**: Python, Go, C#, Rust + expanded platform features
461
-
462
- ### Current Capabilities (Phase 1)
463
-
464
- ```typescript
465
- // Use existing TypeScript types
466
- type User = {
467
- name: string;
468
- email: string;
469
- age: number;
470
- };
471
-
472
- // Add validation incrementally
473
- const validator = Builder()
474
- .use(requiredPlugin)
475
- .use(stringMinPlugin)
476
- .use(stringEmailPlugin)
477
- .use(numberMinPlugin)
478
- .for<User>()
479
- .v("name", (b) => b.string.required().min(3))
480
- .v("email", (b) => b.string.required().email())
481
- .v("age", (b) => b.number.required().min(18))
482
- .build();
483
- ```
484
-
485
- ### The .luq Format: Unified Model Definition Language (Phase 2)
486
-
487
- **⚠️ CRITICAL DISTINCTION**: `.luq` is **NOT TypeScript**. It's a **TypeScript-like** language with its own syntax, compiler, and toolchain.
488
-
489
- **What .luq actually is:**
490
- - **Independent Language**: A domain-specific language (DSL) for API/model/validation definition
491
- - **TypeScript-like Syntax**: Familiar syntax to reduce learning curve, but NOT TypeScript
492
- - **Custom Compiler**: Our own parser, type checker, and code generator
493
- - **No TypeScript Runtime**: Cannot import TypeScript modules or use TypeScript features directly
494
- - **Purpose-Built**: Designed specifically for cross-language validation and API generation
93
+ ## Dynamic Validation (Production Ready)
495
94
 
496
- **Why TypeScript-like (not TypeScript):**
497
95
  ```typescript
498
- // This is NOT valid .luq (TypeScript features won't work)
499
- interface Order {
500
- items: Array<Product>; // TypeScript generics
501
- total: number | null; // ❌ TypeScript union types
502
- created: Date; // ❌ TypeScript Date type
503
- }
504
-
505
- // ✅ This is valid .luq (TypeScript-like but different)
506
- interface Order {
507
- @array(Product)
508
- items: Product[]; // .luq array syntax
96
+ // Load validation rules from API/CMS at runtime
97
+ async function loadValidator() {
98
+ const schema = await fetch('/api/validation-rules').then(r => r.json());
509
99
 
510
- @nullable
511
- total: number; // .luq nullable decorator
512
-
513
- @datetime
514
- created: string; // .luq uses string with format decorators
100
+ // ✅ Works in CSP-restricted environments (unlike AJV)
101
+ // Adapts to dynamic schemas at runtime
102
+ return Builder()
103
+ .use(jsonSchemaFullFeaturePlugin)
104
+ .fromJsonSchema(schema)
105
+ .build();
515
106
  }
516
107
  ```
517
108
 
518
- **What we're building:**
519
- - **Custom VSCode extension**: NOT a TypeScript extension, but a completely new language support
520
- - **Independent Language Server**: Our own LSP implementation, not TypeScript's
521
- - **Dedicated Compiler**: .luq → multi-language code generation pipeline
522
- - **Separate Type System**: Similar to TypeScript but with validation-specific semantics
523
-
524
- **Key Language Features:**
525
- - **Built-in adapters**: Standard database, cache, queue abstractions (primary approach)
526
- - **Escape hatch imports**: Direct import of existing code when needed (language-specific)
527
- - **Type checking**: Our own type system optimized for validation and code generation
528
- - **Decorators**: First-class citizens in .luq (not experimental like TypeScript)
529
- - **Validator functions**: Built into the language semantics
530
- - **Cross-language semantics**: Designed to map cleanly to Java, Python, Go, etc.
531
-
532
- **Primary Approach: Built-in Adapters (90% of use cases)**
533
- ```typescript
534
- // order.luq - Use generated, standardized adapters
535
-
536
- // Database adapter - generated for each target language
537
- @database("postgresql")
538
- adapter db {
539
- orders: Order[];
540
- customers: Customer[];
541
- }
542
-
543
- // Cache adapter
544
- @cache("redis")
545
- adapter cache {
546
- ttl: 3600;
547
- }
109
+ ## Custom Business Logic
548
110
 
549
- // Use standardized interfaces in validation
550
- @crossField
551
- async function validateCustomerCredit(this: Order): Promise<ValidationResult> {
552
- // db.select() is generated in every target language
553
- const customer = await db.select(Customer)
554
- .where("id", this.customer.id)
555
- .first();
556
-
557
- const orderTotal = await db.select(Order)
558
- .where("customerId", customer.id)
559
- .sum("total");
560
-
561
- if (orderTotal + this.total > customer.creditLimit) {
562
- return error("Exceeds credit limit");
111
+ ```typescript
112
+ // Create reusable, type-safe business rules
113
+ const customPlugin = plugin({
114
+ name: "businessRules",
115
+ validators: {
116
+ productCode: {
117
+ validate: (value: string) =>
118
+ value.startsWith("PROD-") && value.length === 10,
119
+ message: "Invalid product code format"
120
+ }
563
121
  }
564
- return ok();
565
- }
122
+ });
566
123
 
567
- // Generated standardized code for each language
568
- // Each language uses its idiomatic patterns
569
- // Users can choose their preferred framework
124
+ // Use across your application
125
+ const validator = Builder()
126
+ .use(customPlugin)
127
+ .for<Product>()
128
+ .v("code", b => b.string.productCode())
129
+ .build();
570
130
  ```
571
131
 
572
- **Escape Hatch: Direct Imports (10% special cases)**
573
- ```typescript
574
- // Only when you need existing business logic that can't be standardized
132
+ ## Roadmap
575
133
 
576
- // Import existing Java service (escape hatch)
577
- @importJava("../legacy/ComplexBusinessLogic.java")
578
- import ComplexBusinessLogic;
134
+ | Phase | Timeline | Status | What |
135
+ |-------|----------|--------|------|
136
+ | **Level 1** | Now | ✅ Released | TypeScript validation library |
137
+ | **Level 2** | Q1-Q3 2026 | 🚧 Development | `.luq` format - TypeScript-like DSL |
138
+ | **v1.0** | Q4 2026 | 📅 Planned | Java support + production tooling |
139
+ | **Level 3** | 2027+ | 🔮 Vision | Complete API/model platform |
579
140
 
580
- @validator
581
- async function validateComplexRule(this: Order): Promise<ValidationResult> {
582
- // Use existing complex logic that can't be easily migrated
583
- return await ComplexBusinessLogic.validateWithLegacyRules(this);
584
- }
585
- ```
586
-
587
- **Why create a TypeScript-like language instead of using TypeScript?**
588
- - **Familiar syntax**: Reduces learning curve for millions of developers
589
- - **Purpose-built semantics**: Validation and API features as first-class citizens
590
- - **Cross-language mapping**: Designed to generate clean code in Java, Python, Go, etc.
591
- - **No JavaScript baggage**: Free from JS/TS runtime limitations and quirks
592
- - **Validation-optimized**: Type system designed specifically for validation use cases
141
+ ### Future Vision: .luq Format (2026)
593
142
 
594
143
  ```typescript
595
- // order.luq - Complete API & model definition in one place
596
-
597
- // Standard adapters (recommended approach)
598
- @database("postgresql")
599
- adapter db {
600
- orders: Order[];
601
- customers: Customer[];
602
- products: Product[];
603
- }
604
-
605
- @cache("redis")
606
- adapter cache {
607
- ttl: 3600;
608
- }
609
-
610
- // Import only for special cases (escape hatch)
611
- import { calculateTotalFromItems } from "./business-logic"; // Legacy TypeScript
612
- @importJava("../legacy/TaxCalculator.java") // Legacy Java that can't be migrated
613
- import TaxCalculator;
614
-
615
- // API endpoint definition
616
- @endpoint("/api/orders")
617
- @authenticated
618
- interface OrderAPI {
619
- @post("/")
620
- @rateLimit(100)
621
- create(body: CreateOrderRequest): OrderResponse;
622
-
623
- @get("/:id")
624
- @cache(300)
625
- getById(id: string): Order;
626
- }
627
-
628
- // Data model with validation
144
+ // order.luq - Define once, generate everywhere
629
145
  interface Order {
630
- @uuid()
631
- id: string;
632
-
633
- @required() @min(0)
634
- @computed(calculateTotalFromItems) // Use imported function
146
+ @min(0) @computed(calculateTotal)
635
147
  total: number;
636
148
 
637
- @minLength(1) @maxLength(100)
638
- items: OrderItem[];
149
+ @minLength(1)
150
+ items: Product[];
639
151
 
640
- @required()
641
- customer: {
642
- @required()
643
- id: string;
644
-
645
- @oneOf(["active", "suspended", "closed"])
646
- @validate(isActiveCustomer) // Type-safe function reference
647
- status: string;
648
- };
649
- }
650
-
651
- // Cross-field validation - 'this' parameter for model context
652
- @crossField
653
- function validateDiscountEligibility(this: Order): ValidationResult {
654
- if (this.discount > 0 && !["gold", "platinum"].includes(this.customer.tier)) {
655
- return error("Discount requires gold or platinum tier");
152
+ @crossField
153
+ validateDiscount(this: Order): ValidationResult {
154
+ if (this.discount > 0 && this.customer.tier !== "gold") {
155
+ return error("Discount requires gold tier");
156
+ }
157
+ return ok();
656
158
  }
657
- return ok();
658
- }
659
-
660
- // Field-level validation with parameters
661
- interface Product {
662
- @min(0) @max(1000000) // Simple decorators with arguments
663
- price: number;
664
-
665
- @validate(validatePriceRange, 100, 50000) // Function with additional params
666
- premiumPrice: number;
667
- }
668
-
669
- // Validator function that accepts additional parameters
670
- function validatePriceRange(value: number, min: number, max: number): ValidationResult {
671
- if (value < min || value > max) {
672
- return error(`Price must be between ${min} and ${max}`);
673
- }
674
- return ok();
675
- }
676
-
677
- // Cross-field with async and this context
678
- @crossField
679
- async function validateInventory(this: Order): Promise<ValidationResult> {
680
- const available = await checkInventory(this.items);
681
- return available ? ok() : error("Insufficient inventory");
682
- }
683
-
684
- // Recommended: Use standard adapter
685
- @crossField
686
- async function validateCustomerCredit(this: Order): Promise<ValidationResult> {
687
- // Standard query interface - same in all generated languages
688
- const customer = await db.select(Customer)
689
- .where("id", this.customer.id)
690
- .include("orders") // Eager loading
691
- .first();
692
-
693
- const totalOrders = customer.orders.reduce((sum, o) => sum + o.total, 0);
694
- return totalOrders + this.total <= customer.creditLimit
695
- ? ok()
696
- : error("Exceeds credit limit");
697
- }
698
-
699
- // Escape hatch: When you must use existing service
700
- @crossField
701
- async function validateTax(this: Order): Promise<ValidationResult> {
702
- // Use legacy Java service that can't be standardized
703
- const tax = await TaxCalculator.calculateComplexTax(this);
704
- return tax > 0 ? ok() : error("Invalid tax calculation");
705
159
  }
706
160
  ```
707
161
 
708
- **Decorator Signature Patterns:**
709
- ```typescript
710
- // Pattern 1: Simple decorators with direct values
711
- @min(0) @max(100) // Built-in decorators
712
- price: number;
713
-
714
- // Pattern 2: Field validator with value as first parameter
715
- @validate(isValidSKU) // (value: string) => ValidationResult
716
- sku: string;
717
-
718
- // Pattern 3: Field validator with additional parameters
719
- @validate(matchesPattern, /^SKU-\d{6}$/) // (value: string, pattern: RegExp) => ValidationResult
720
- productCode: string;
721
-
722
- // Pattern 4: Cross-field validator with 'this' context
723
- @crossField
724
- function validateRelatedFields(this: Order): ValidationResult {
725
- // Access entire model via 'this'
726
- if (this.endDate <= this.startDate) {
727
- return error("End date must be after start date");
728
- }
729
- return ok();
730
- }
731
-
732
- // Pattern 5: Computed field with 'this' context
733
- @computed
734
- function calculateTotal(this: Order): number {
735
- return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
736
- }
737
- ```
738
-
739
- **What the .luq toolchain generates**:
740
- - **Backend code**: Controllers, models, validators
741
- - **Client SDKs**: Type-safe API clients
742
- - **Documentation**: API specs in standard formats
743
- - **Adapters**: Database and service integrations
744
- - **Business logic**: Consistent across all platforms
745
-
746
- ## Real-World Example: Dynamic Validation
747
-
748
- ```typescript
749
- // Common scenario: Load validation rules from API or CMS
750
- async function loadValidationRules() {
751
- const rules = await fetch('/api/validation-rules').then(r => r.json());
752
-
753
- // ❌ AJV: Fails in production with CSP
754
- // const ajv = new Ajv();
755
- // const validate = ajv.compile(rules); // Uses new Function() internally
756
-
757
- // ❌ AJV Standalone: Can't handle dynamic schemas
758
- // Pre-compiled at build time, can't adapt to API response
759
-
760
- // ✅ Luq: Works everywhere, adapts at runtime
761
- const validator = Builder()
762
- .use(jsonSchemaFullFeaturePlugin)
763
- .fromJsonSchema(rules)
764
- .build();
765
-
766
- return validator;
767
- }
768
-
769
- // Multi-tenant SaaS with per-customer rules
770
- async function getCustomerValidator(customerId: string) {
771
- const config = await getCustomerConfig(customerId);
772
-
773
- // Luq can safely build validators at runtime
774
- return Builder()
775
- .use(requiredPlugin)
776
- .use(customBusinessPlugin)
777
- .for<Order>()
778
- .v("total", b => b.number.min(config.minOrderValue))
779
- .v("items", b => b.array.maxLength(config.maxItems))
780
- .build();
781
- }
162
+ Generate for any language:
163
+ ```bash
164
+ luq generate order.luq --lang=java --out=backend/
165
+ luq generate order.luq --lang=typescript --out=frontend/
782
166
  ```
783
167
 
784
- ## Technical Specifications
785
-
786
- ### Architecture Features
787
-
788
- | Feature | Description | Impact |
789
- |---------|-------------|--------|
790
- | **AOT Compilation** | Pre-compile validators at build time | Eliminates runtime overhead |
791
- | **Plugin System** | Modular validation rules | Tree-shaking support |
792
- | **Zero Dependencies** | No external runtime dependencies | Predictable bundle size |
793
- | **Type Safety** | Full TypeScript type inference | Compile-time error detection |
794
-
795
- ### Use Case Recommendations
168
+ > **Note**: `.luq` is a TypeScript-like DSL, not TypeScript. Custom toolchain with VSCode extension coming in 2026.
796
169
 
797
- | Scenario | Recommended Configuration | Rationale |
798
- |----------|---------------------------|-----------|
799
- | **CSP-restricted environments** | **Luq** | No eval/Function, full features |
800
- | **Dynamic schema loading** | **Luq** | Safe runtime validation |
801
- | **Existing TypeScript types** | **Luq** | No schema rewriting needed |
802
- | **Custom business rules** | **Luq** | Type-safe plugin architecture |
803
- | **JSON Schema migration** | Luq JsonSchema | Full compatibility, safe runtime |
804
- | **Minimal bundle critical** | Valibot | 1-2KB solution |
805
- | **Pre-compiled validation** | AJV Standalone | If schemas never change |
170
+ ## Performance
806
171
 
807
- ### Benchmark Methodology
172
+ **Bundle size**: 19-23KB gzipped (tree-shakeable)
173
+ **Speed**: 1.2M ops/sec (simple), 43K ops/sec (complex)
174
+ **CSP-safe**: Works in all environments (no eval/Function)
175
+ **Dynamic**: Can load validation rules at runtime
808
176
 
809
- - Test data: Simple (3 fields) and Complex (nested objects, arrays) schemas
810
- - Iterations: 1,000,000 operations per benchmark
811
- - Environment: AMD Ryzen 7 5825U, 5.8GB RAM, Node.js v22.12.0
812
- - Details: See `bundle-size-comparison` directory
177
+ 📊 **[View detailed benchmarks →](https://luq.dev/benchmarks)**
813
178
 
814
- ## Your Migration Path to Universal Platform
179
+ ## Documentation
815
180
 
816
- ### Today - Level 1 (Available Now)
817
- ```typescript
818
- // Start with validation using your existing TypeScript types
819
- import { Builder } from "@maroonedog/luq";
820
- const validator = Builder().for<Order>()
821
- .v("total", b => b.number.min(0))
822
- .build();
823
- ```
181
+ 📖 **[Complete Documentation](https://luq.dev)** - Guides, API reference, examples
182
+ 🚀 **[Getting Started](https://luq.dev/docs/getting-started)** - Step-by-step tutorial
183
+ 🧩 **[Plugin Catalog](https://luq.dev/plugins)** - Browse 40+ built-in plugins
184
+ 💡 **[Examples](https://luq.dev/examples)** - Real-world usage patterns
185
+ 🗺️ **[Roadmap](https://luq.dev/roadmap)** - Detailed timeline and vision
824
186
 
825
- ### 2026 Q1-Q3 - Level 2 (.luq Format)
826
- ```typescript
827
- // Unified model & validation definitions
828
- // order.luq
829
- interface Order {
830
- @min(0) @businessRule("calculateTotal")
831
- total: number;
832
- }
833
- ```
187
+ ## Installation Options
834
188
 
835
- ### 2026 Q4 - v1.0 (Java Support)
836
189
  ```bash
837
- # Generate for TypeScript & Java
838
- luq generate order.luq --lang=typescript --out=frontend/
839
- luq generate order.luq --lang=java --out=backend/
190
+ # Core library only
191
+ npm install @maroonedog/luq@alpha
840
192
 
841
- # Generated code integrates with your existing stack
842
- # No framework lock-in - use what you prefer
193
+ # With specific plugins
194
+ npm install @maroonedog/luq@alpha
195
+ # Then import only what you need:
196
+ # import { requiredPlugin } from "@maroonedog/luq/plugins/required"
197
+ # import { stringEmailPlugin } from "@maroonedog/luq/plugins/stringEmail"
843
198
  ```
844
199
 
845
- ### Future - Level 3 (Unified Platform)
846
- ```typescript
847
- // Complete API & model definition
848
- // api.luq
849
- @endpoint("/api/orders")
850
- interface OrderAPI {
851
- @post("/") create(body: Order): OrderResponse;
852
- @get("/:id") getById(id: string): Order;
853
- }
854
- ```
855
-
856
- ```bash
857
- # Generate everything
858
- luq generate api.luq --target=all
859
-
860
- ✓ Backend code generation
861
- ✓ Client SDK generation
862
- ✓ API documentation
863
- ✓ Complete type safety across all targets
864
- ```
865
-
866
- **Progressive Abstraction Architecture: Start simple, evolve to comprehensive.**
867
-
868
- ## Learn More
869
-
870
- For detailed documentation, advanced examples, and roadmap:
871
-
872
- **📖 [Documentation](https://luq.dev)** - Complete guides and API reference
873
- **🚀 [Roadmap](https://luq.dev/roadmap)** - Development timeline and future plans
874
- **🧩 [Plugins](https://luq.dev/plugins)** - Browse available plugins
875
- **💡 [Examples](https://luq.dev/guides)** - Real-world usage patterns
876
-
877
200
  ## License
878
201
 
879
202
  MIT
203
+
204
+ ---
205
+
206
+ <sub>Built with ❤️ for developers tired of writing validation three times</sub>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maroonedog/luq",
3
- "version": "0.1.0-alpha",
3
+ "version": "0.1.0",
4
4
  "description": "Universal Model & API Definition Platform - TypeScript validation library evolving into cross-language code generation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",