rtfct 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.
- package/.project/adrs/001-use-bun-typescript.md +52 -0
- package/.project/guardrails.md +65 -0
- package/.project/kanban/backlog.md +7 -0
- package/.project/kanban/done.md +240 -0
- package/.project/kanban/in-progress.md +11 -0
- package/.project/kickstart.md +63 -0
- package/.project/protocol.md +134 -0
- package/.project/specs/requirements.md +152 -0
- package/.project/testing/strategy.md +123 -0
- package/.project/theology.md +125 -0
- package/CLAUDE.md +119 -0
- package/README.md +143 -0
- package/package.json +31 -0
- package/src/args.ts +104 -0
- package/src/commands/add.ts +78 -0
- package/src/commands/init.ts +128 -0
- package/src/commands/praise.ts +19 -0
- package/src/commands/regenerate.ts +122 -0
- package/src/commands/status.ts +163 -0
- package/src/help.ts +52 -0
- package/src/index.ts +102 -0
- package/src/kanban.ts +83 -0
- package/src/manifest.ts +67 -0
- package/src/presets/base.ts +195 -0
- package/src/presets/elixir.ts +118 -0
- package/src/presets/github.ts +194 -0
- package/src/presets/index.ts +154 -0
- package/src/presets/typescript.ts +589 -0
- package/src/presets/zig.ts +494 -0
- package/tests/integration/add.test.ts +104 -0
- package/tests/integration/init.test.ts +197 -0
- package/tests/integration/praise.test.ts +36 -0
- package/tests/integration/regenerate.test.ts +154 -0
- package/tests/integration/status.test.ts +165 -0
- package/tests/unit/args.test.ts +144 -0
- package/tests/unit/kanban.test.ts +162 -0
- package/tests/unit/manifest.test.ts +155 -0
- package/tests/unit/presets.test.ts +295 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TypeScript Codex — Sacred Patterns for TypeScript Development
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Preset } from "./index";
|
|
6
|
+
|
|
7
|
+
const TESTING_STRATEGY_MD = `# TypeScript Testing Strategy
|
|
8
|
+
|
|
9
|
+
*The Rites of Verification for TypeScript*
|
|
10
|
+
|
|
11
|
+
## The Sacred Command
|
|
12
|
+
|
|
13
|
+
\`\`\`bash
|
|
14
|
+
npx vitest # Watch mode — the Machine Spirit watches
|
|
15
|
+
npx vitest run # Single run — for CI/CD
|
|
16
|
+
npx vitest --ui # Visual interface — for deep investigation
|
|
17
|
+
\`\`\`
|
|
18
|
+
|
|
19
|
+
## Why Vitest
|
|
20
|
+
|
|
21
|
+
Vitest is the sacred choice for TypeScript testing:
|
|
22
|
+
- Native ESM support
|
|
23
|
+
- TypeScript out of the box
|
|
24
|
+
- Jest-compatible API
|
|
25
|
+
- Blazingly fast with Vite
|
|
26
|
+
|
|
27
|
+
## Test Organization
|
|
28
|
+
|
|
29
|
+
\`\`\`
|
|
30
|
+
tests/
|
|
31
|
+
├── unit/ # Pure function tests
|
|
32
|
+
│ ├── utils.test.ts
|
|
33
|
+
│ └── validators.test.ts
|
|
34
|
+
├── integration/ # Module interaction tests
|
|
35
|
+
│ ├── api.test.ts
|
|
36
|
+
│ └── database.test.ts
|
|
37
|
+
├── e2e/ # End-to-end tests (if applicable)
|
|
38
|
+
└── fixtures/ # Shared test data
|
|
39
|
+
└── users.json
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
## The Sacred Pattern
|
|
43
|
+
|
|
44
|
+
\`\`\`typescript
|
|
45
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
46
|
+
import { UserService } from '../src/services/user';
|
|
47
|
+
import { Database } from '../src/database';
|
|
48
|
+
|
|
49
|
+
// Mock external dependencies
|
|
50
|
+
vi.mock('../src/database');
|
|
51
|
+
|
|
52
|
+
describe('UserService', () => {
|
|
53
|
+
let service: UserService;
|
|
54
|
+
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
vi.clearAllMocks();
|
|
57
|
+
service = new UserService();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('getUser', () => {
|
|
61
|
+
it('returns user when found', async () => {
|
|
62
|
+
const mockUser = { id: '1', name: 'Tech-Priest' };
|
|
63
|
+
vi.mocked(Database.findUser).mockResolvedValue(mockUser);
|
|
64
|
+
|
|
65
|
+
const result = await service.getUser('1');
|
|
66
|
+
|
|
67
|
+
expect(result).toEqual(mockUser);
|
|
68
|
+
expect(Database.findUser).toHaveBeenCalledWith('1');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('throws when user not found', async () => {
|
|
72
|
+
vi.mocked(Database.findUser).mockResolvedValue(null);
|
|
73
|
+
|
|
74
|
+
await expect(service.getUser('999')).rejects.toThrow('User not found');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
## Testing Async Code
|
|
81
|
+
|
|
82
|
+
\`\`\`typescript
|
|
83
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
84
|
+
|
|
85
|
+
describe('async operations', () => {
|
|
86
|
+
it('handles promises correctly', async () => {
|
|
87
|
+
const result = await fetchData();
|
|
88
|
+
expect(result).toBeDefined();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('handles promise rejection', async () => {
|
|
92
|
+
await expect(failingOperation()).rejects.toThrow('Expected error');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('uses fake timers for delays', async () => {
|
|
96
|
+
vi.useFakeTimers();
|
|
97
|
+
|
|
98
|
+
const promise = delayedOperation(1000);
|
|
99
|
+
vi.advanceTimersByTime(1000);
|
|
100
|
+
|
|
101
|
+
await expect(promise).resolves.toBe('done');
|
|
102
|
+
|
|
103
|
+
vi.useRealTimers();
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
\`\`\`
|
|
107
|
+
|
|
108
|
+
## Type Testing
|
|
109
|
+
|
|
110
|
+
\`\`\`typescript
|
|
111
|
+
import { describe, it, expectTypeOf } from 'vitest';
|
|
112
|
+
import { processData } from '../src/utils';
|
|
113
|
+
|
|
114
|
+
describe('type safety', () => {
|
|
115
|
+
it('returns correct type', () => {
|
|
116
|
+
const result = processData({ value: 42 });
|
|
117
|
+
expectTypeOf(result).toEqualTypeOf<{ processed: number }>();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('accepts correct input type', () => {
|
|
121
|
+
expectTypeOf(processData).parameter(0).toMatchTypeOf<{ value: number }>();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
\`\`\`
|
|
125
|
+
|
|
126
|
+
## Vitest Configuration
|
|
127
|
+
|
|
128
|
+
\`\`\`typescript
|
|
129
|
+
// vitest.config.ts
|
|
130
|
+
import { defineConfig } from 'vitest/config';
|
|
131
|
+
|
|
132
|
+
export default defineConfig({
|
|
133
|
+
test: {
|
|
134
|
+
globals: true,
|
|
135
|
+
environment: 'node',
|
|
136
|
+
include: ['tests/**/*.test.ts'],
|
|
137
|
+
coverage: {
|
|
138
|
+
provider: 'v8',
|
|
139
|
+
reporter: ['text', 'json', 'html'],
|
|
140
|
+
exclude: ['node_modules/', 'tests/'],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
## Coverage Doctrine
|
|
147
|
+
|
|
148
|
+
- All exported functions must have tests
|
|
149
|
+
- Edge cases (null, undefined, empty, boundary values) tested explicitly
|
|
150
|
+
- Error paths tested — verify errors are thrown correctly
|
|
151
|
+
- Mocks used only for external dependencies, not for internal modules
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
*The tests do not lie. Praise the Machine Spirit.*
|
|
156
|
+
`;
|
|
157
|
+
|
|
158
|
+
const GUARDRAILS_MD = `# TypeScript Guardrails — Forbidden Heresies
|
|
159
|
+
|
|
160
|
+
*TypeScript-specific patterns to avoid*
|
|
161
|
+
|
|
162
|
+
## Type Heresies
|
|
163
|
+
|
|
164
|
+
### 1. The \`any\` Heresy
|
|
165
|
+
Every \`any\` is a failure of imagination. Use \`unknown\` and narrow:
|
|
166
|
+
|
|
167
|
+
\`\`\`typescript
|
|
168
|
+
// HERESY
|
|
169
|
+
function process(data: any) {
|
|
170
|
+
return data.value; // No safety!
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// SACRED
|
|
174
|
+
function process(data: unknown) {
|
|
175
|
+
if (isValidData(data)) {
|
|
176
|
+
return data.value; // Type-safe!
|
|
177
|
+
}
|
|
178
|
+
throw new Error('Invalid data');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function isValidData(data: unknown): data is { value: string } {
|
|
182
|
+
return typeof data === 'object' && data !== null && 'value' in data;
|
|
183
|
+
}
|
|
184
|
+
\`\`\`
|
|
185
|
+
|
|
186
|
+
### 2. Type Assertion Abuse
|
|
187
|
+
\`as Type\` bypasses the compiler. Prefer type guards:
|
|
188
|
+
|
|
189
|
+
\`\`\`typescript
|
|
190
|
+
// HERESY
|
|
191
|
+
const user = response.data as User; // Hope it's right!
|
|
192
|
+
|
|
193
|
+
// SACRED
|
|
194
|
+
function isUser(data: unknown): data is User {
|
|
195
|
+
return (
|
|
196
|
+
typeof data === 'object' &&
|
|
197
|
+
data !== null &&
|
|
198
|
+
'id' in data &&
|
|
199
|
+
'name' in data
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (isUser(response.data)) {
|
|
204
|
+
const user = response.data; // Compiler verified!
|
|
205
|
+
}
|
|
206
|
+
\`\`\`
|
|
207
|
+
|
|
208
|
+
### 3. Non-null Assertion
|
|
209
|
+
\`foo!\` is a lie waiting to happen:
|
|
210
|
+
|
|
211
|
+
\`\`\`typescript
|
|
212
|
+
// HERESY
|
|
213
|
+
const name = user.profile!.name!; // Runtime error waiting
|
|
214
|
+
|
|
215
|
+
// SACRED
|
|
216
|
+
const name = user.profile?.name ?? 'Unknown';
|
|
217
|
+
|
|
218
|
+
// Or with explicit check
|
|
219
|
+
if (user.profile?.name) {
|
|
220
|
+
const name = user.profile.name; // Safe!
|
|
221
|
+
}
|
|
222
|
+
\`\`\`
|
|
223
|
+
|
|
224
|
+
### 4. Implicit Any in Callbacks
|
|
225
|
+
Always type your parameters:
|
|
226
|
+
|
|
227
|
+
\`\`\`typescript
|
|
228
|
+
// HERESY
|
|
229
|
+
items.map(item => item.value); // item is implicitly any
|
|
230
|
+
|
|
231
|
+
// SACRED
|
|
232
|
+
items.map((item: Item) => item.value);
|
|
233
|
+
// Or better, ensure items is properly typed: Item[]
|
|
234
|
+
\`\`\`
|
|
235
|
+
|
|
236
|
+
## Async Heresies
|
|
237
|
+
|
|
238
|
+
### 1. Floating Promises
|
|
239
|
+
Every promise must be handled:
|
|
240
|
+
|
|
241
|
+
\`\`\`typescript
|
|
242
|
+
// HERESY
|
|
243
|
+
saveData(data); // Promise ignored!
|
|
244
|
+
|
|
245
|
+
// SACRED
|
|
246
|
+
await saveData(data);
|
|
247
|
+
// Or if you truly don't care about the result:
|
|
248
|
+
void saveData(data); // Explicit intention
|
|
249
|
+
\`\`\`
|
|
250
|
+
|
|
251
|
+
### 2. Missing Error Handling
|
|
252
|
+
|
|
253
|
+
\`\`\`typescript
|
|
254
|
+
// HERESY
|
|
255
|
+
const data = await fetchData(); // What if it fails?
|
|
256
|
+
|
|
257
|
+
// SACRED
|
|
258
|
+
try {
|
|
259
|
+
const data = await fetchData();
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (error instanceof NetworkError) {
|
|
262
|
+
// Handle network issues
|
|
263
|
+
}
|
|
264
|
+
throw error; // Re-throw if unhandled
|
|
265
|
+
}
|
|
266
|
+
\`\`\`
|
|
267
|
+
|
|
268
|
+
### 3. Async in Constructors
|
|
269
|
+
|
|
270
|
+
\`\`\`typescript
|
|
271
|
+
// HERESY
|
|
272
|
+
class Service {
|
|
273
|
+
constructor() {
|
|
274
|
+
this.init(); // Async operation in constructor!
|
|
275
|
+
}
|
|
276
|
+
private async init() { ... }
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// SACRED — Use factory pattern
|
|
280
|
+
class Service {
|
|
281
|
+
private constructor() {}
|
|
282
|
+
|
|
283
|
+
static async create(): Promise<Service> {
|
|
284
|
+
const service = new Service();
|
|
285
|
+
await service.init();
|
|
286
|
+
return service;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
\`\`\`
|
|
290
|
+
|
|
291
|
+
## Import Heresies
|
|
292
|
+
|
|
293
|
+
### 1. Circular Dependencies
|
|
294
|
+
If A imports B and B imports A, restructure:
|
|
295
|
+
|
|
296
|
+
\`\`\`typescript
|
|
297
|
+
// HERESY
|
|
298
|
+
// user.ts imports role.ts, role.ts imports user.ts
|
|
299
|
+
|
|
300
|
+
// SACRED — Extract shared types
|
|
301
|
+
// types.ts — shared types
|
|
302
|
+
// user.ts — imports types.ts
|
|
303
|
+
// role.ts — imports types.ts
|
|
304
|
+
\`\`\`
|
|
305
|
+
|
|
306
|
+
### 2. Default Export Abuse
|
|
307
|
+
|
|
308
|
+
\`\`\`typescript
|
|
309
|
+
// HERESY
|
|
310
|
+
export default class UserService { }
|
|
311
|
+
import UserService from './user-service'; // Can be renamed silently
|
|
312
|
+
|
|
313
|
+
// SACRED
|
|
314
|
+
export class UserService { }
|
|
315
|
+
import { UserService } from './user-service'; // Refactor-safe
|
|
316
|
+
\`\`\`
|
|
317
|
+
|
|
318
|
+
### 3. Barrel File Overuse
|
|
319
|
+
|
|
320
|
+
\`\`\`typescript
|
|
321
|
+
// HERESY — Re-exports everything, slows bundling
|
|
322
|
+
// index.ts
|
|
323
|
+
export * from './user';
|
|
324
|
+
export * from './role';
|
|
325
|
+
export * from './permission';
|
|
326
|
+
|
|
327
|
+
// SACRED — Import directly
|
|
328
|
+
import { UserService } from './services/user';
|
|
329
|
+
\`\`\`
|
|
330
|
+
|
|
331
|
+
## Null Safety
|
|
332
|
+
|
|
333
|
+
### Always Use Nullish Coalescing
|
|
334
|
+
|
|
335
|
+
\`\`\`typescript
|
|
336
|
+
// HERESY — falsy values cause bugs
|
|
337
|
+
const value = config.timeout || 3000; // 0 becomes 3000!
|
|
338
|
+
|
|
339
|
+
// SACRED
|
|
340
|
+
const value = config.timeout ?? 3000; // Only null/undefined trigger default
|
|
341
|
+
\`\`\`
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
*The compiler is wise. Enable strict mode. Praise the Machine Spirit.*
|
|
346
|
+
`;
|
|
347
|
+
|
|
348
|
+
const TSCONFIG_PATTERNS_MD = `# TypeScript tsconfig Patterns
|
|
349
|
+
|
|
350
|
+
*Sacred configurations for the TypeScript compiler*
|
|
351
|
+
|
|
352
|
+
## The Strict Foundation
|
|
353
|
+
|
|
354
|
+
Every project must start with strict mode:
|
|
355
|
+
|
|
356
|
+
\`\`\`json
|
|
357
|
+
{
|
|
358
|
+
"compilerOptions": {
|
|
359
|
+
"strict": true
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
\`\`\`
|
|
363
|
+
|
|
364
|
+
This enables all strict type-checking options:
|
|
365
|
+
- \`strictNullChecks\` — null and undefined are distinct types
|
|
366
|
+
- \`strictFunctionTypes\` — stricter function type checking
|
|
367
|
+
- \`strictBindCallApply\` — strict bind, call, apply methods
|
|
368
|
+
- \`strictPropertyInitialization\` — class properties must be initialized
|
|
369
|
+
- \`noImplicitAny\` — error on expressions with implied any
|
|
370
|
+
- \`noImplicitThis\` — error on this with implied any type
|
|
371
|
+
|
|
372
|
+
## The Recommended Base
|
|
373
|
+
|
|
374
|
+
\`\`\`json
|
|
375
|
+
{
|
|
376
|
+
"compilerOptions": {
|
|
377
|
+
// Strict Type Checking
|
|
378
|
+
"strict": true,
|
|
379
|
+
"noUncheckedIndexedAccess": true,
|
|
380
|
+
"noImplicitReturns": true,
|
|
381
|
+
"noFallthroughCasesInSwitch": true,
|
|
382
|
+
"noImplicitOverride": true,
|
|
383
|
+
"exactOptionalPropertyTypes": true,
|
|
384
|
+
|
|
385
|
+
// Module Resolution
|
|
386
|
+
"module": "ESNext",
|
|
387
|
+
"moduleResolution": "bundler",
|
|
388
|
+
"resolveJsonModule": true,
|
|
389
|
+
"esModuleInterop": true,
|
|
390
|
+
"isolatedModules": true,
|
|
391
|
+
|
|
392
|
+
// Output
|
|
393
|
+
"target": "ES2022",
|
|
394
|
+
"lib": ["ES2022"],
|
|
395
|
+
"declaration": true,
|
|
396
|
+
"declarationMap": true,
|
|
397
|
+
"sourceMap": true,
|
|
398
|
+
|
|
399
|
+
// Quality
|
|
400
|
+
"skipLibCheck": true,
|
|
401
|
+
"forceConsistentCasingInFileNames": true
|
|
402
|
+
},
|
|
403
|
+
"include": ["src/**/*"],
|
|
404
|
+
"exclude": ["node_modules", "dist"]
|
|
405
|
+
}
|
|
406
|
+
\`\`\`
|
|
407
|
+
|
|
408
|
+
## Node.js Application
|
|
409
|
+
|
|
410
|
+
\`\`\`json
|
|
411
|
+
{
|
|
412
|
+
"compilerOptions": {
|
|
413
|
+
"strict": true,
|
|
414
|
+
"noUncheckedIndexedAccess": true,
|
|
415
|
+
|
|
416
|
+
"module": "NodeNext",
|
|
417
|
+
"moduleResolution": "NodeNext",
|
|
418
|
+
"target": "ES2022",
|
|
419
|
+
"lib": ["ES2022"],
|
|
420
|
+
|
|
421
|
+
"outDir": "./dist",
|
|
422
|
+
"rootDir": "./src",
|
|
423
|
+
"declaration": true,
|
|
424
|
+
"sourceMap": true,
|
|
425
|
+
|
|
426
|
+
"esModuleInterop": true,
|
|
427
|
+
"skipLibCheck": true,
|
|
428
|
+
"forceConsistentCasingInFileNames": true
|
|
429
|
+
},
|
|
430
|
+
"include": ["src/**/*"],
|
|
431
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
432
|
+
}
|
|
433
|
+
\`\`\`
|
|
434
|
+
|
|
435
|
+
## Library Configuration
|
|
436
|
+
|
|
437
|
+
\`\`\`json
|
|
438
|
+
{
|
|
439
|
+
"compilerOptions": {
|
|
440
|
+
"strict": true,
|
|
441
|
+
"noUncheckedIndexedAccess": true,
|
|
442
|
+
"declaration": true,
|
|
443
|
+
"declarationMap": true,
|
|
444
|
+
|
|
445
|
+
"module": "ESNext",
|
|
446
|
+
"moduleResolution": "bundler",
|
|
447
|
+
"target": "ES2020",
|
|
448
|
+
"lib": ["ES2020"],
|
|
449
|
+
|
|
450
|
+
"outDir": "./dist",
|
|
451
|
+
"rootDir": "./src",
|
|
452
|
+
|
|
453
|
+
// Don't emit — let bundler handle it
|
|
454
|
+
"noEmit": true
|
|
455
|
+
},
|
|
456
|
+
"include": ["src/**/*"]
|
|
457
|
+
}
|
|
458
|
+
\`\`\`
|
|
459
|
+
|
|
460
|
+
## React Application
|
|
461
|
+
|
|
462
|
+
\`\`\`json
|
|
463
|
+
{
|
|
464
|
+
"compilerOptions": {
|
|
465
|
+
"strict": true,
|
|
466
|
+
"noUncheckedIndexedAccess": true,
|
|
467
|
+
|
|
468
|
+
"target": "ES2020",
|
|
469
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
470
|
+
"module": "ESNext",
|
|
471
|
+
"moduleResolution": "bundler",
|
|
472
|
+
|
|
473
|
+
"jsx": "react-jsx",
|
|
474
|
+
"jsxImportSource": "react",
|
|
475
|
+
|
|
476
|
+
"noEmit": true,
|
|
477
|
+
"isolatedModules": true,
|
|
478
|
+
"skipLibCheck": true,
|
|
479
|
+
"forceConsistentCasingInFileNames": true
|
|
480
|
+
},
|
|
481
|
+
"include": ["src"]
|
|
482
|
+
}
|
|
483
|
+
\`\`\`
|
|
484
|
+
|
|
485
|
+
## Monorepo Base Config
|
|
486
|
+
|
|
487
|
+
\`\`\`json
|
|
488
|
+
// packages/tsconfig.base.json
|
|
489
|
+
{
|
|
490
|
+
"compilerOptions": {
|
|
491
|
+
"strict": true,
|
|
492
|
+
"noUncheckedIndexedAccess": true,
|
|
493
|
+
"noImplicitReturns": true,
|
|
494
|
+
|
|
495
|
+
"module": "ESNext",
|
|
496
|
+
"moduleResolution": "bundler",
|
|
497
|
+
"target": "ES2022",
|
|
498
|
+
|
|
499
|
+
"declaration": true,
|
|
500
|
+
"declarationMap": true,
|
|
501
|
+
"sourceMap": true,
|
|
502
|
+
"composite": true,
|
|
503
|
+
|
|
504
|
+
"skipLibCheck": true,
|
|
505
|
+
"forceConsistentCasingInFileNames": true
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// packages/core/tsconfig.json
|
|
510
|
+
{
|
|
511
|
+
"extends": "../tsconfig.base.json",
|
|
512
|
+
"compilerOptions": {
|
|
513
|
+
"outDir": "./dist",
|
|
514
|
+
"rootDir": "./src"
|
|
515
|
+
},
|
|
516
|
+
"include": ["src/**/*"],
|
|
517
|
+
"references": []
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// packages/api/tsconfig.json
|
|
521
|
+
{
|
|
522
|
+
"extends": "../tsconfig.base.json",
|
|
523
|
+
"compilerOptions": {
|
|
524
|
+
"outDir": "./dist",
|
|
525
|
+
"rootDir": "./src"
|
|
526
|
+
},
|
|
527
|
+
"include": ["src/**/*"],
|
|
528
|
+
"references": [
|
|
529
|
+
{ "path": "../core" }
|
|
530
|
+
]
|
|
531
|
+
}
|
|
532
|
+
\`\`\`
|
|
533
|
+
|
|
534
|
+
## The Forbidden Options
|
|
535
|
+
|
|
536
|
+
Never enable these in production:
|
|
537
|
+
|
|
538
|
+
\`\`\`json
|
|
539
|
+
{
|
|
540
|
+
"compilerOptions": {
|
|
541
|
+
// HERESY — Disables type safety
|
|
542
|
+
"strict": false,
|
|
543
|
+
"noImplicitAny": false,
|
|
544
|
+
"strictNullChecks": false,
|
|
545
|
+
|
|
546
|
+
// HERESY — Ignores errors
|
|
547
|
+
"suppressImplicitAnyIndexErrors": true,
|
|
548
|
+
"suppressExcessPropertyErrors": true
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
\`\`\`
|
|
552
|
+
|
|
553
|
+
## Path Aliases
|
|
554
|
+
|
|
555
|
+
\`\`\`json
|
|
556
|
+
{
|
|
557
|
+
"compilerOptions": {
|
|
558
|
+
"baseUrl": ".",
|
|
559
|
+
"paths": {
|
|
560
|
+
"@/*": ["src/*"],
|
|
561
|
+
"@utils/*": ["src/utils/*"],
|
|
562
|
+
"@types/*": ["src/types/*"]
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
\`\`\`
|
|
567
|
+
|
|
568
|
+
Remember to configure your bundler (Vite, webpack, etc.) to resolve these paths.
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
*The compiler configuration is sacred. Praise the Machine Spirit.*
|
|
573
|
+
`;
|
|
574
|
+
|
|
575
|
+
export const TYPESCRIPT_PRESET: Preset = {
|
|
576
|
+
name: "typescript",
|
|
577
|
+
manifest: {
|
|
578
|
+
name: "typescript",
|
|
579
|
+
version: "0.1.0",
|
|
580
|
+
description: "The TypeScript Codex — Type-safe JavaScript",
|
|
581
|
+
depends: ["base"],
|
|
582
|
+
generated_paths: ["src/", "tests/", "dist/"],
|
|
583
|
+
},
|
|
584
|
+
files: [
|
|
585
|
+
{ path: "testing/strategy.md", content: TESTING_STRATEGY_MD },
|
|
586
|
+
{ path: "guardrails.md", content: GUARDRAILS_MD },
|
|
587
|
+
{ path: "design/patterns.md", content: TSCONFIG_PATTERNS_MD },
|
|
588
|
+
],
|
|
589
|
+
};
|