@zigrivers/scaffold 3.6.0 → 3.8.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/README.md +127 -12
- package/content/knowledge/backend/backend-api-design.md +103 -0
- package/content/knowledge/backend/backend-architecture.md +100 -0
- package/content/knowledge/backend/backend-async-patterns.md +101 -0
- package/content/knowledge/backend/backend-auth-patterns.md +100 -0
- package/content/knowledge/backend/backend-conventions.md +105 -0
- package/content/knowledge/backend/backend-data-modeling.md +102 -0
- package/content/knowledge/backend/backend-deployment.md +100 -0
- package/content/knowledge/backend/backend-dev-environment.md +102 -0
- package/content/knowledge/backend/backend-observability.md +102 -0
- package/content/knowledge/backend/backend-project-structure.md +100 -0
- package/content/knowledge/backend/backend-requirements.md +103 -0
- package/content/knowledge/backend/backend-security.md +104 -0
- package/content/knowledge/backend/backend-testing.md +101 -0
- package/content/knowledge/backend/backend-worker-patterns.md +100 -0
- package/content/knowledge/cli/cli-architecture.md +101 -0
- package/content/knowledge/cli/cli-conventions.md +117 -0
- package/content/knowledge/cli/cli-dev-environment.md +121 -0
- package/content/knowledge/cli/cli-distribution-patterns.md +106 -0
- package/content/knowledge/cli/cli-interactivity-patterns.md +116 -0
- package/content/knowledge/cli/cli-output-patterns.md +107 -0
- package/content/knowledge/cli/cli-project-structure.md +124 -0
- package/content/knowledge/cli/cli-requirements.md +101 -0
- package/content/knowledge/cli/cli-shell-integration.md +130 -0
- package/content/knowledge/cli/cli-testing.md +134 -0
- package/content/knowledge/library/library-api-design.md +306 -0
- package/content/knowledge/library/library-architecture.md +247 -0
- package/content/knowledge/library/library-bundling.md +244 -0
- package/content/knowledge/library/library-conventions.md +229 -0
- package/content/knowledge/library/library-dev-environment.md +220 -0
- package/content/knowledge/library/library-documentation.md +300 -0
- package/content/knowledge/library/library-project-structure.md +237 -0
- package/content/knowledge/library/library-requirements.md +173 -0
- package/content/knowledge/library/library-security.md +257 -0
- package/content/knowledge/library/library-testing.md +319 -0
- package/content/knowledge/library/library-type-definitions.md +284 -0
- package/content/knowledge/library/library-versioning.md +300 -0
- package/content/knowledge/mobile-app/mobile-app-architecture.md +283 -0
- package/content/knowledge/mobile-app/mobile-app-conventions.md +180 -0
- package/content/knowledge/mobile-app/mobile-app-deployment.md +298 -0
- package/content/knowledge/mobile-app/mobile-app-dev-environment.md +257 -0
- package/content/knowledge/mobile-app/mobile-app-distribution.md +264 -0
- package/content/knowledge/mobile-app/mobile-app-observability.md +317 -0
- package/content/knowledge/mobile-app/mobile-app-offline-patterns.md +311 -0
- package/content/knowledge/mobile-app/mobile-app-project-structure.md +245 -0
- package/content/knowledge/mobile-app/mobile-app-push-notifications.md +321 -0
- package/content/knowledge/mobile-app/mobile-app-requirements.md +147 -0
- package/content/knowledge/mobile-app/mobile-app-security.md +338 -0
- package/content/knowledge/mobile-app/mobile-app-testing.md +400 -0
- package/content/knowledge/web-app/web-app-api-patterns.md +224 -0
- package/content/knowledge/web-app/web-app-architecture.md +116 -0
- package/content/knowledge/web-app/web-app-auth-patterns.md +256 -0
- package/content/knowledge/web-app/web-app-conventions.md +121 -0
- package/content/knowledge/web-app/web-app-data-patterns.md +218 -0
- package/content/knowledge/web-app/web-app-deployment-workflow.md +143 -0
- package/content/knowledge/web-app/web-app-deployment.md +134 -0
- package/content/knowledge/web-app/web-app-design-system.md +158 -0
- package/content/knowledge/web-app/web-app-dev-environment.md +173 -0
- package/content/knowledge/web-app/web-app-observability.md +221 -0
- package/content/knowledge/web-app/web-app-project-structure.md +160 -0
- package/content/knowledge/web-app/web-app-rendering-strategies.md +133 -0
- package/content/knowledge/web-app/web-app-requirements.md +112 -0
- package/content/knowledge/web-app/web-app-security.md +193 -0
- package/content/knowledge/web-app/web-app-session-patterns.md +214 -0
- package/content/knowledge/web-app/web-app-testing.md +249 -0
- package/content/knowledge/web-app/web-app-ux-patterns.md +162 -0
- package/content/methodology/backend-overlay.yml +73 -0
- package/content/methodology/cli-overlay.yml +69 -0
- package/content/methodology/library-overlay.yml +67 -0
- package/content/methodology/mobile-app-overlay.yml +71 -0
- package/content/methodology/web-app-overlay.yml +79 -0
- package/dist/cli/commands/init.d.ts +21 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +261 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +206 -0
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/config/schema.d.ts +1392 -64
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +82 -5
- package/dist/config/schema.js.map +1 -1
- package/dist/config/schema.test.js +302 -1
- package/dist/config/schema.test.js.map +1 -1
- package/dist/core/assembly/overlay-loader.d.ts.map +1 -1
- package/dist/core/assembly/overlay-loader.js +2 -1
- package/dist/core/assembly/overlay-loader.js.map +1 -1
- package/dist/core/assembly/overlay-loader.test.js +56 -0
- package/dist/core/assembly/overlay-loader.test.js.map +1 -1
- package/dist/e2e/game-pipeline.test.js +1 -0
- package/dist/e2e/game-pipeline.test.js.map +1 -1
- package/dist/e2e/project-type-overlays.test.d.ts +16 -0
- package/dist/e2e/project-type-overlays.test.d.ts.map +1 -0
- package/dist/e2e/project-type-overlays.test.js +834 -0
- package/dist/e2e/project-type-overlays.test.js.map +1 -0
- package/dist/types/config.d.ts +19 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/wizard/questions.d.ts +27 -1
- package/dist/wizard/questions.d.ts.map +1 -1
- package/dist/wizard/questions.js +142 -3
- package/dist/wizard/questions.js.map +1 -1
- package/dist/wizard/questions.test.js +206 -8
- package/dist/wizard/questions.test.js.map +1 -1
- package/dist/wizard/wizard.d.ts +21 -0
- package/dist/wizard/wizard.d.ts.map +1 -1
- package/dist/wizard/wizard.js +27 -1
- package/dist/wizard/wizard.js.map +1 -1
- package/package.json +1 -1
- package/dist/types/wizard.d.ts +0 -14
- package/dist/types/wizard.d.ts.map +0 -1
- package/dist/types/wizard.js +0 -2
- package/dist/types/wizard.js.map +0 -1
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: library-documentation
|
|
3
|
+
description: TypeDoc/JSDoc setup, README structure, example code, migration guides, and API reference for published libraries
|
|
4
|
+
topics: [library, documentation, typedoc, jsdoc, readme, examples, migration-guides, api-reference]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Library documentation is the primary onboarding surface for new consumers and the support surface for existing ones. Poor documentation causes consumers to misuse the API, open avoidable issues, and ultimately abandon the library for better-documented alternatives. Good documentation reduces support burden, increases adoption, and communicates the library's quality and professionalism. Documentation must be treated as a first-class deliverable, not an afterthought after code is complete.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Every library needs four documentation layers: a README for discovery and quick start, API reference generated from JSDoc (TypeDoc), example code that is runnable and tested, and migration guides for each major version. The README structure follows a standard pattern: badges, one-line description, install, quick start, core concepts, API overview with links to full reference, and contributing. JSDoc comments are the source of truth for the API reference — they must be maintained alongside code.
|
|
12
|
+
|
|
13
|
+
Documentation layers:
|
|
14
|
+
- README.md: discovery, install, quick start (< 5 minutes to first working code)
|
|
15
|
+
- JSDoc inline: function descriptions, parameter docs, examples, throws
|
|
16
|
+
- TypeDoc site: full API reference with types, overloads, inheritance
|
|
17
|
+
- examples/: runnable, tested example projects per major use case
|
|
18
|
+
- Migration guides: step-by-step for every major version bump
|
|
19
|
+
|
|
20
|
+
## Deep Guidance
|
|
21
|
+
|
|
22
|
+
### README Structure
|
|
23
|
+
|
|
24
|
+
The README must answer four questions in order: What is it? How do I install it? How do I use it? Where do I learn more?
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
# my-library
|
|
28
|
+
|
|
29
|
+
[](https://npmjs.com/package/my-library)
|
|
30
|
+
[](...)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
|
|
33
|
+
One-sentence description of what the library does and the problem it solves.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
\`\`\`bash
|
|
38
|
+
npm install my-library
|
|
39
|
+
\`\`\`
|
|
40
|
+
|
|
41
|
+
Requires Node.js 18+. TypeScript 5.0+ recommended.
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
\`\`\`typescript
|
|
46
|
+
import { parseConfig, createClient } from 'my-library'
|
|
47
|
+
|
|
48
|
+
const config = parseConfig(`
|
|
49
|
+
[server]
|
|
50
|
+
host = "localhost"
|
|
51
|
+
port = 3000
|
|
52
|
+
`)
|
|
53
|
+
|
|
54
|
+
const client = createClient({ config })
|
|
55
|
+
const result = await client.query('SELECT 1')
|
|
56
|
+
\`\`\`
|
|
57
|
+
|
|
58
|
+
## Core Concepts
|
|
59
|
+
|
|
60
|
+
Brief explanation of the 2-3 key concepts consumers need to understand before using the API:
|
|
61
|
+
- **Config**: The parsed configuration object. Passed to all client methods.
|
|
62
|
+
- **Client**: Stateful connection to a service. Create once per application.
|
|
63
|
+
- **Query**: An operation executed against the client.
|
|
64
|
+
|
|
65
|
+
## API Reference
|
|
66
|
+
|
|
67
|
+
Full API documentation: [https://my-library.dev/api](https://my-library.dev/api)
|
|
68
|
+
|
|
69
|
+
Key exports:
|
|
70
|
+
| Export | Description |
|
|
71
|
+
|--------|-------------|
|
|
72
|
+
| `parseConfig(input)` | Parse a TOML string into a Config object |
|
|
73
|
+
| `createClient(options)` | Create a connected Client instance |
|
|
74
|
+
| `ParseError` | Thrown when input is not valid TOML |
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
See [examples/](examples/) for runnable examples:
|
|
79
|
+
- [Basic usage](examples/basic-usage/) — Parse a config and run a query
|
|
80
|
+
- [Custom transport](examples/custom-transport/) — Inject a custom HTTP transport
|
|
81
|
+
|
|
82
|
+
## Contributing
|
|
83
|
+
|
|
84
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**README anti-patterns to avoid:**
|
|
92
|
+
- Feature lists without usage examples
|
|
93
|
+
- Installation section that assumes npm — show the command explicitly
|
|
94
|
+
- API "documentation" that only lists function names without signatures
|
|
95
|
+
- No error handling in examples (shows only the happy path)
|
|
96
|
+
- Out-of-date examples (the most common and damaging README failure)
|
|
97
|
+
|
|
98
|
+
### JSDoc Standards
|
|
99
|
+
|
|
100
|
+
JSDoc comments are compiled into the generated API reference. Write them for the consumer who has never read the source:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
/**
|
|
104
|
+
* Parse a TOML-formatted configuration string.
|
|
105
|
+
*
|
|
106
|
+
* Parses `input` as TOML and validates the result against the expected Config
|
|
107
|
+
* schema. Returns a fully typed Config object on success.
|
|
108
|
+
*
|
|
109
|
+
* @param input - TOML-formatted string. Must be valid TOML 1.0.
|
|
110
|
+
* @param options - Optional parsing configuration.
|
|
111
|
+
* @param options.strict - When true, unknown fields cause a ValidationError.
|
|
112
|
+
* Defaults to false (unknown fields are ignored).
|
|
113
|
+
* @param options.encoding - Character encoding. Defaults to 'utf-8'.
|
|
114
|
+
*
|
|
115
|
+
* @returns Parsed Config object with all fields typed.
|
|
116
|
+
*
|
|
117
|
+
* @throws {ParseError} If `input` is not valid TOML. The error includes
|
|
118
|
+
* `line` and `column` properties indicating the error location.
|
|
119
|
+
* @throws {ValidationError} If `options.strict` is true and the parsed config
|
|
120
|
+
* contains unknown fields.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* Basic usage:
|
|
124
|
+
* ```typescript
|
|
125
|
+
* const config = parseConfig('[server]\nhost = "localhost"')
|
|
126
|
+
* console.log(config.server.host) // "localhost"
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* With strict mode:
|
|
131
|
+
* ```typescript
|
|
132
|
+
* try {
|
|
133
|
+
* const config = parseConfig(input, { strict: true })
|
|
134
|
+
* } catch (err) {
|
|
135
|
+
* if (err instanceof ValidationError) {
|
|
136
|
+
* console.error('Unknown fields:', err.unknownFields)
|
|
137
|
+
* }
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @since 1.0.0
|
|
142
|
+
*/
|
|
143
|
+
export function parseConfig(input: string, options?: ParseOptions): Config
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Minimum JSDoc for every public export:**
|
|
147
|
+
- One-sentence description (what it does, not how)
|
|
148
|
+
- `@param` for each parameter with type context and constraints
|
|
149
|
+
- `@returns` describing the return value
|
|
150
|
+
- `@throws` for every error type that can be thrown
|
|
151
|
+
- At least one `@example` showing realistic usage
|
|
152
|
+
- `@since` for when the export was added (helps with migration)
|
|
153
|
+
- `@deprecated` with replacement and removal version when applicable
|
|
154
|
+
|
|
155
|
+
### TypeDoc Setup
|
|
156
|
+
|
|
157
|
+
TypeDoc generates HTML API reference from JSDoc comments:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm install --save-dev typedoc typedoc-plugin-markdown
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
// typedoc.json
|
|
165
|
+
{
|
|
166
|
+
"entryPoints": ["src/index.ts"],
|
|
167
|
+
"out": "docs/api",
|
|
168
|
+
"plugin": ["typedoc-plugin-markdown"],
|
|
169
|
+
"readme": "none",
|
|
170
|
+
"excludePrivate": true,
|
|
171
|
+
"excludeInternal": true,
|
|
172
|
+
"categorizeByGroup": true,
|
|
173
|
+
"categoryOrder": ["Core", "Types", "Errors", "*"],
|
|
174
|
+
"gitRemote": "origin",
|
|
175
|
+
"githubPages": true
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Generate docs
|
|
181
|
+
npm run docs
|
|
182
|
+
# Or: npx typedoc
|
|
183
|
+
|
|
184
|
+
# Deploy to GitHub Pages (in CI)
|
|
185
|
+
# Add to your GitHub Actions workflow:
|
|
186
|
+
- uses: actions/upload-pages-artifact@v3
|
|
187
|
+
with:
|
|
188
|
+
path: docs/api
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Run TypeDoc in CI to catch documentation failures (missing exports, broken references) before they reach consumers.
|
|
192
|
+
|
|
193
|
+
### Example Code Standards
|
|
194
|
+
|
|
195
|
+
Examples are documentation that can be run and tested. They must:
|
|
196
|
+
|
|
197
|
+
1. **Be complete and runnable:**
|
|
198
|
+
```typescript
|
|
199
|
+
// examples/basic-usage/index.ts
|
|
200
|
+
// This file runs standalone: `node index.js`
|
|
201
|
+
import { parseConfig, createClient } from 'my-library'
|
|
202
|
+
|
|
203
|
+
const raw = `
|
|
204
|
+
[server]
|
|
205
|
+
host = "localhost"
|
|
206
|
+
port = 3000
|
|
207
|
+
`
|
|
208
|
+
|
|
209
|
+
const config = parseConfig(raw)
|
|
210
|
+
const client = createClient({ config })
|
|
211
|
+
|
|
212
|
+
async function main() {
|
|
213
|
+
const result = await client.query('SELECT 1')
|
|
214
|
+
console.log('Connected:', result)
|
|
215
|
+
await client.close()
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
main().catch((err) => {
|
|
219
|
+
console.error('Example failed:', err)
|
|
220
|
+
process.exit(1)
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
2. **Show error handling:**
|
|
225
|
+
```typescript
|
|
226
|
+
// Don't just show the happy path
|
|
227
|
+
try {
|
|
228
|
+
const config = parseConfig(invalidInput)
|
|
229
|
+
} catch (err) {
|
|
230
|
+
if (err instanceof ParseError) {
|
|
231
|
+
console.error(`Syntax error at line ${err.line}, column ${err.column}`)
|
|
232
|
+
console.error(err.message)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
3. **Be tested in CI:**
|
|
238
|
+
```yaml
|
|
239
|
+
# .github/workflows/ci.yml
|
|
240
|
+
- name: Test examples
|
|
241
|
+
run: |
|
|
242
|
+
cd examples/basic-usage && npm install && node index.js
|
|
243
|
+
cd examples/custom-transport && npm install && node index.js
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Migration Guides
|
|
247
|
+
|
|
248
|
+
Every major version must have a migration guide. The guide must be findable from the CHANGELOG and README:
|
|
249
|
+
|
|
250
|
+
```markdown
|
|
251
|
+
<!-- docs/guides/migration-v2-to-v3.md -->
|
|
252
|
+
# Migrating from v2 to v3
|
|
253
|
+
|
|
254
|
+
## Breaking Changes
|
|
255
|
+
|
|
256
|
+
### `parse()` removed
|
|
257
|
+
`parse()` was deprecated in v2.3. Replace with `parseConfig()`:
|
|
258
|
+
|
|
259
|
+
**Before (v2):**
|
|
260
|
+
\`\`\`typescript
|
|
261
|
+
import { parse } from 'my-library'
|
|
262
|
+
const config = parse(input)
|
|
263
|
+
\`\`\`
|
|
264
|
+
|
|
265
|
+
**After (v3):**
|
|
266
|
+
\`\`\`typescript
|
|
267
|
+
import { parseConfig } from 'my-library'
|
|
268
|
+
const config = parseConfig(input)
|
|
269
|
+
\`\`\`
|
|
270
|
+
|
|
271
|
+
### `Config.timeout` is now milliseconds
|
|
272
|
+
The `timeout` field was previously in seconds. Multiply by 1000:
|
|
273
|
+
|
|
274
|
+
**Before (v2):**
|
|
275
|
+
\`\`\`typescript
|
|
276
|
+
const config = parseConfig(input)
|
|
277
|
+
// config.timeout === 30 (seconds)
|
|
278
|
+
\`\`\`
|
|
279
|
+
|
|
280
|
+
**After (v3):**
|
|
281
|
+
\`\`\`typescript
|
|
282
|
+
const config = parseConfig(input)
|
|
283
|
+
// config.timeout === 30000 (milliseconds)
|
|
284
|
+
// Adjust your code: config.timeout * 1000 is no longer needed
|
|
285
|
+
\`\`\`
|
|
286
|
+
|
|
287
|
+
## Automated Migration
|
|
288
|
+
|
|
289
|
+
A codemod is available to automate common patterns:
|
|
290
|
+
\`\`\`bash
|
|
291
|
+
npx @my-library/codemod v2-to-v3 ./src
|
|
292
|
+
\`\`\`
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Migration guide checklist:**
|
|
296
|
+
- Every breaking change has a before/after code example
|
|
297
|
+
- Every renamed export has an explicit replacement
|
|
298
|
+
- Behavior changes are explained, not just listed
|
|
299
|
+
- A codemod is provided for mechanical changes (optional but appreciated)
|
|
300
|
+
- Link to the migration guide from the CHANGELOG entry
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: library-project-structure
|
|
3
|
+
description: Directory layout, package.json exports map, tsconfig for declarations, and examples/ structure for published libraries
|
|
4
|
+
topics: [library, project-structure, package-json, tsconfig, exports, declarations]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Library project structure must serve two audiences simultaneously: contributors who need to navigate and modify the source, and consumers who install the package and expect predictable module resolution. The structure of the source directory, the `dist/` output, the `package.json` exports map, and the TypeScript configuration all interlock. Getting any one of them wrong produces libraries that fail to tree-shake, ship broken types, or cause dual-package hazards.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
A well-structured library has `src/` for source, `dist/` for built output (gitignored), `examples/` for runnable consumer examples, and `docs/` for API reference. The `package.json` exports map is the definitive module resolution contract. The TypeScript configuration must emit declaration files alongside compiled output. Internal implementation details live under `src/internal/` and are never exported from the root index.
|
|
12
|
+
|
|
13
|
+
Standard layout:
|
|
14
|
+
- `src/index.ts` — public API barrel (explicit named exports only)
|
|
15
|
+
- `src/internal/` — implementation details, never publicly exported
|
|
16
|
+
- `src/types.ts` — shared type definitions
|
|
17
|
+
- `examples/` — standalone runnable examples (one per major use case)
|
|
18
|
+
- `dist/` — build output (gitignored, published to npm)
|
|
19
|
+
- `docs/` — generated API reference and hand-written guides
|
|
20
|
+
|
|
21
|
+
## Deep Guidance
|
|
22
|
+
|
|
23
|
+
### Source Directory Layout
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
my-library/
|
|
27
|
+
├── src/
|
|
28
|
+
│ ├── index.ts # Public API — only named exports here
|
|
29
|
+
│ ├── types.ts # Shared types/interfaces used across modules
|
|
30
|
+
│ ├── errors.ts # All custom error classes
|
|
31
|
+
│ ├── parser.ts # Feature module
|
|
32
|
+
│ ├── validator.ts # Feature module
|
|
33
|
+
│ ├── client.ts # Feature module
|
|
34
|
+
│ └── internal/ # Implementation details — NEVER export from root
|
|
35
|
+
│ ├── utils.ts
|
|
36
|
+
│ ├── cache.ts
|
|
37
|
+
│ └── http.ts
|
|
38
|
+
├── examples/
|
|
39
|
+
│ ├── basic-usage/
|
|
40
|
+
│ │ ├── index.ts # Standalone example, uses installed package
|
|
41
|
+
│ │ └── package.json # Depends on "my-library": "file:../../"
|
|
42
|
+
│ └── advanced-plugin/
|
|
43
|
+
│ ├── index.ts
|
|
44
|
+
│ └── package.json
|
|
45
|
+
├── tests/
|
|
46
|
+
│ ├── unit/ # Unit tests mirroring src/ structure
|
|
47
|
+
│ ├── integration/ # Consumer-perspective integration tests
|
|
48
|
+
│ └── types/ # Type-level tests (tsd or expect-type)
|
|
49
|
+
├── docs/
|
|
50
|
+
│ ├── api/ # Generated by TypeDoc
|
|
51
|
+
│ └── guides/ # Hand-written usage guides
|
|
52
|
+
├── dist/ # Build output (gitignored)
|
|
53
|
+
├── package.json
|
|
54
|
+
├── tsconfig.json # Build config (emits to dist/)
|
|
55
|
+
├── tsconfig.dev.json # Dev/test config (no emit)
|
|
56
|
+
├── CHANGELOG.md
|
|
57
|
+
└── README.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### package.json Structure
|
|
61
|
+
|
|
62
|
+
The full `package.json` for a dual ESM/CJS library:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"name": "my-library",
|
|
67
|
+
"version": "1.0.0",
|
|
68
|
+
"description": "One-line description",
|
|
69
|
+
"license": "MIT",
|
|
70
|
+
"author": "Name <email>",
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "https://github.com/org/my-library.git"
|
|
74
|
+
},
|
|
75
|
+
"type": "module",
|
|
76
|
+
"main": "./dist/cjs/index.cjs",
|
|
77
|
+
"module": "./dist/esm/index.js",
|
|
78
|
+
"types": "./dist/types/index.d.ts",
|
|
79
|
+
"exports": {
|
|
80
|
+
".": {
|
|
81
|
+
"import": {
|
|
82
|
+
"types": "./dist/types/index.d.ts",
|
|
83
|
+
"default": "./dist/esm/index.js"
|
|
84
|
+
},
|
|
85
|
+
"require": {
|
|
86
|
+
"types": "./dist/types/index.d.cts",
|
|
87
|
+
"default": "./dist/cjs/index.cjs"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"./plugins": {
|
|
91
|
+
"import": {
|
|
92
|
+
"types": "./dist/types/plugins/index.d.ts",
|
|
93
|
+
"default": "./dist/esm/plugins/index.js"
|
|
94
|
+
},
|
|
95
|
+
"require": {
|
|
96
|
+
"types": "./dist/types/plugins/index.d.cts",
|
|
97
|
+
"default": "./dist/cjs/plugins/index.cjs"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"./testing": {
|
|
101
|
+
"import": {
|
|
102
|
+
"types": "./dist/types/testing/index.d.ts",
|
|
103
|
+
"default": "./dist/esm/testing/index.js"
|
|
104
|
+
},
|
|
105
|
+
"require": {
|
|
106
|
+
"types": "./dist/types/testing/index.d.cts",
|
|
107
|
+
"default": "./dist/cjs/testing/index.cjs"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"./package.json": "./package.json"
|
|
111
|
+
},
|
|
112
|
+
"files": [
|
|
113
|
+
"dist/",
|
|
114
|
+
"README.md",
|
|
115
|
+
"CHANGELOG.md",
|
|
116
|
+
"LICENSE"
|
|
117
|
+
],
|
|
118
|
+
"scripts": {
|
|
119
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json",
|
|
120
|
+
"build:watch": "tsc -p tsconfig.json --watch",
|
|
121
|
+
"test": "vitest run",
|
|
122
|
+
"test:watch": "vitest",
|
|
123
|
+
"test:types": "tsd",
|
|
124
|
+
"lint": "eslint src/ tests/",
|
|
125
|
+
"typecheck": "tsc --noEmit",
|
|
126
|
+
"docs": "typedoc src/index.ts",
|
|
127
|
+
"prepublishOnly": "npm run build && npm test"
|
|
128
|
+
},
|
|
129
|
+
"devDependencies": {
|
|
130
|
+
"typescript": "^5.4.0",
|
|
131
|
+
"vitest": "^1.4.0",
|
|
132
|
+
"tsd": "^0.31.0",
|
|
133
|
+
"typedoc": "^0.25.0",
|
|
134
|
+
"eslint": "^8.57.0"
|
|
135
|
+
},
|
|
136
|
+
"engines": {
|
|
137
|
+
"node": ">=18.0.0"
|
|
138
|
+
},
|
|
139
|
+
"sideEffects": false
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The `"sideEffects": false` field tells bundlers this library is fully tree-shakeable. Only set this if true — if the library registers globals or patches prototypes on import, this must be `true` or an array of files with side effects.
|
|
144
|
+
|
|
145
|
+
### TypeScript Configuration
|
|
146
|
+
|
|
147
|
+
Two tsconfig files: one for building (emit), one for development (no emit, strict checking).
|
|
148
|
+
|
|
149
|
+
**tsconfig.json (build — ESM output):**
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"compilerOptions": {
|
|
153
|
+
"target": "ES2020",
|
|
154
|
+
"module": "ESNext",
|
|
155
|
+
"moduleResolution": "Bundler",
|
|
156
|
+
"lib": ["ES2020"],
|
|
157
|
+
"outDir": "./dist/esm",
|
|
158
|
+
"declarationDir": "./dist/types",
|
|
159
|
+
"declaration": true,
|
|
160
|
+
"declarationMap": true,
|
|
161
|
+
"sourceMap": true,
|
|
162
|
+
"strict": true,
|
|
163
|
+
"exactOptionalPropertyTypes": true,
|
|
164
|
+
"noUncheckedIndexedAccess": true,
|
|
165
|
+
"noImplicitReturns": true,
|
|
166
|
+
"noFallthroughCasesInSwitch": true,
|
|
167
|
+
"isolatedModules": true,
|
|
168
|
+
"verbatimModuleSyntax": true,
|
|
169
|
+
"esModuleInterop": false,
|
|
170
|
+
"skipLibCheck": false
|
|
171
|
+
},
|
|
172
|
+
"include": ["src"],
|
|
173
|
+
"exclude": ["src/**/*.test.ts", "tests/", "examples/", "dist/"]
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**tsconfig.cjs.json (CJS output — extends build config):**
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"extends": "./tsconfig.json",
|
|
181
|
+
"compilerOptions": {
|
|
182
|
+
"module": "CommonJS",
|
|
183
|
+
"moduleResolution": "Node",
|
|
184
|
+
"outDir": "./dist/cjs",
|
|
185
|
+
"declaration": false
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**tsconfig.dev.json (development — no emit):**
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"extends": "./tsconfig.json",
|
|
194
|
+
"compilerOptions": {
|
|
195
|
+
"noEmit": true,
|
|
196
|
+
"moduleResolution": "Bundler"
|
|
197
|
+
},
|
|
198
|
+
"include": ["src", "tests", "examples"]
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Examples Directory
|
|
203
|
+
|
|
204
|
+
Each example must be a standalone project that installs the library as a dependency:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
// examples/basic-usage/package.json
|
|
208
|
+
{
|
|
209
|
+
"name": "basic-usage-example",
|
|
210
|
+
"private": true,
|
|
211
|
+
"type": "module",
|
|
212
|
+
"dependencies": {
|
|
213
|
+
"my-library": "file:../../"
|
|
214
|
+
},
|
|
215
|
+
"scripts": {
|
|
216
|
+
"start": "node index.js",
|
|
217
|
+
"build": "tsc"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
This ensures examples test the actual published API surface, not the source. If an example breaks, the public API is broken. Run examples in CI.
|
|
223
|
+
|
|
224
|
+
### .npmignore and `files` Field
|
|
225
|
+
|
|
226
|
+
Use the `files` field in `package.json` to allowlist what gets published. This is safer than `.npmignore` (which is a denylist and can accidentally publish source, tests, or secrets):
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
"files": [
|
|
230
|
+
"dist/",
|
|
231
|
+
"README.md",
|
|
232
|
+
"CHANGELOG.md",
|
|
233
|
+
"LICENSE"
|
|
234
|
+
]
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Explicitly excluded from publish: `src/`, `tests/`, `examples/`, `docs/`, `.github/`, `tsconfig*.json`, `*.config.*`. Consumers never need source files — they use the compiled dist output and type declarations.
|