|
1 | 1 | # Getting Started |
2 | 2 |
|
3 | | -Quick setup guide for contributing to `@socketregistry/packageurl-js`. |
| 3 | +**Quick start guide** — Get started with Package URL development in 5 minutes. |
4 | 4 |
|
5 | | -## Quick Start |
6 | | - |
7 | | -```bash |
8 | | -git clone https://github.com/SocketDev/socket-packageurl-js.git |
9 | | -cd socket-packageurl-js |
10 | | -pnpm install # Install dependencies |
11 | | -pnpm build # Build library |
12 | | -pnpm test # Run tests (100% coverage required) |
13 | | -``` |
14 | | - |
15 | | -**Requirements**: Node.js ≥18.20.4, pnpm ≥10.16.0 |
| 5 | +--- |
16 | 6 |
|
17 | | -## Repository Structure |
| 7 | +## 📋 Prerequisites |
18 | 8 |
|
19 | 9 | ``` |
20 | | -socket-packageurl-js/ |
21 | | -├── src/ # TypeScript source |
22 | | -│ ├── package-url.ts # Core PackageURL class |
23 | | -│ ├── package-url-builder.ts # Builder pattern |
24 | | -│ ├── purl-type.ts # Type-specific handlers |
25 | | -│ ├── validate.ts # Validation logic |
26 | | -│ └── normalize.ts # Normalization rules |
27 | | -├── test/ # Test suites (100% coverage) |
28 | | -├── docs/ # Documentation |
29 | | -├── .config/ # Build & lint configs |
30 | | -├── CLAUDE.md # Development guidelines |
31 | | -└── package.json # Scripts & dependencies |
| 10 | +Required: |
| 11 | + ✓ Node.js 20+ (LTS recommended) |
| 12 | + ✓ pnpm 9+ |
| 13 | + ✓ Git |
32 | 14 | ``` |
33 | 15 |
|
34 | | -## Essential Commands |
35 | | - |
36 | | -| Command | Purpose | |
37 | | -|---------|---------| |
38 | | -| `pnpm build` | Production build (CommonJS) | |
39 | | -| `pnpm build --watch` | Watch mode (68% faster: 9ms vs 27ms) | |
40 | | -| `pnpm test` | Run all tests | |
41 | | -| `pnpm test <file>` | Run specific test file | |
42 | | -| `pnpm cover` | Coverage report (must be 100%) | |
43 | | -| `pnpm check` | Lint + type check | |
44 | | -| `pnpm fix` | Auto-fix lint issues | |
| 16 | +--- |
45 | 17 |
|
46 | | -## Development Workflow |
| 18 | +## 🚀 Quick Start |
47 | 19 |
|
48 | | -### 1. Make Changes |
| 20 | +### 1. Clone & Setup |
49 | 21 |
|
50 | | -Edit source files in `src/`. Key areas: |
| 22 | +```bash |
| 23 | +# Clone |
| 24 | +git clone https://github.com/SocketDev/socket-packageurl-js.git |
| 25 | +cd socket-packageurl-js |
51 | 26 |
|
52 | | -| Task | File(s) | |
53 | | -|------|---------| |
54 | | -| Add package type | `src/purl-type.ts` | |
55 | | -| Add validation | `src/validate.ts` | |
56 | | -| Add normalization | `src/normalize.ts` | |
57 | | -| Update builder | `src/package-url-builder.ts` | |
| 27 | +# Install & verify |
| 28 | +pnpm install |
| 29 | +pnpm test |
| 30 | +``` |
58 | 31 |
|
59 | | -### 2. Write Tests |
| 32 | +**Expected:** ✓ 100% test coverage, ✓ 100% type coverage |
60 | 33 |
|
61 | | -Add tests in `test/`. Use test helpers: |
| 34 | +--- |
62 | 35 |
|
63 | | -```typescript |
64 | | -import { createTestPurl } from './utils/test-helpers.mts' |
| 36 | +### 2. Project Structure |
65 | 37 |
|
66 | | -// Before: new PackageURL('npm', undefined, 'lodash', '4.17.21', undefined, undefined) |
67 | | -// After: |
68 | | -const purl = createTestPurl('npm', 'lodash', { version: '4.17.21' }) |
69 | 38 | ``` |
70 | | - |
71 | | -**Coverage requirement**: 100% (strictly enforced) |
72 | | - |
73 | | -### 3. Verify Changes |
74 | | - |
75 | | -```bash |
76 | | -pnpm check # Lint + type check |
77 | | -pnpm test # All tests |
78 | | -pnpm cover # Verify 100% coverage |
| 39 | +socket-packageurl-js/ |
| 40 | +├── src/ # Source code |
| 41 | +│ ├── index.ts # Main PackageURL class |
| 42 | +│ ├── parse.ts # Parser implementation |
| 43 | +│ ├── builder.ts # Builder implementation |
| 44 | +│ └── types.ts # TypeScript definitions |
| 45 | +│ |
| 46 | +├── test/ # Tests (mirrors src/) |
| 47 | +├── scripts/ # Build scripts |
| 48 | +└── docs/ # Documentation |
| 49 | + ├── api-reference.md |
| 50 | + ├── usage-examples.md |
| 51 | + └── getting-started.md |
79 | 52 | ``` |
80 | 53 |
|
81 | | -### 4. Commit |
| 54 | +--- |
82 | 55 |
|
83 | | -Pre-commit hooks run automatically: |
84 | | -- Lint staged files |
85 | | -- Type check |
86 | | -- Security checks |
| 56 | +### 3. Essential Commands |
87 | 57 |
|
88 | | -**Commit format** ([Conventional Commits](https://www.conventionalcommits.org/)): |
| 58 | +```bash |
| 59 | +# Development |
| 60 | +pnpm run dev # Watch mode |
| 61 | +pnpm build # Build for production |
89 | 62 |
|
90 | | -``` |
91 | | -<type>(<scope>): <description> |
| 63 | +# Testing |
| 64 | +pnpm test # Run tests |
| 65 | +pnpm run cover # With coverage |
92 | 66 |
|
93 | | -[optional body] |
| 67 | +# Quality |
| 68 | +pnpm run check # Type check + lint |
| 69 | +pnpm run fix # Auto-fix issues |
94 | 70 | ``` |
95 | 71 |
|
96 | | -**Examples**: |
97 | | -- `feat(parser): add golang support` |
98 | | -- `fix(validate): handle empty namespace` |
99 | | -- `docs: update builder examples` |
| 72 | +--- |
100 | 73 |
|
101 | | -## Package URLs (PURLs) |
| 74 | +## 🧪 What is a Package URL? |
102 | 75 |
|
103 | | -**Format**: `pkg:<type>/<namespace>/<name>@<version>?<qualifiers>#<subpath>` |
| 76 | +A Package URL (purl) standardizes software package identification: |
104 | 77 |
|
105 | | -**Examples**: |
106 | 78 | ``` |
107 | 79 | pkg:npm/lodash@4.17.21 |
108 | | -pkg:npm/@babel/core@7.20.0 |
109 | | -pkg:pypi/requests@2.28.1 |
110 | | -pkg:maven/org.springframework/spring-core@5.3.21 |
| 80 | +│ │ │ │ |
| 81 | +│ │ │ └─ Version |
| 82 | +│ │ └──────── Name |
| 83 | +│ └──────────── Namespace (optional) |
| 84 | +└──────────────── Type (ecosystem) |
111 | 85 | ``` |
112 | 86 |
|
113 | | -**Supported ecosystems**: npm, pypi, maven, gem, cargo, nuget, composer, golang, docker, and [15+ more](../src/purl-type.ts) |
114 | | - |
115 | | -## Code Style |
116 | | - |
117 | | -**Key patterns** (see [CLAUDE.md](../CLAUDE.md) for full standards): |
| 87 | +**Supported ecosystems:** |
| 88 | +- npm, pypi, cargo, gem, maven, nuget, go, docker, etc. |
118 | 89 |
|
119 | | -| Rule | Example | |
120 | | -|------|---------| |
121 | | -| No semicolons | `const x = 5` ✓ | |
122 | | -| Type imports separate | `import type { Foo } from './types.js'` ✓ | |
123 | | -| Node imports with prefix | `import fs from 'node:fs'` ✓ | |
124 | | -| No `process.chdir()` | Use `{ cwd }` options ✓ | |
125 | | -| Bracket notation for index signatures | `obj['prop']` ✓ | |
126 | | - |
127 | | -**Error message format**: |
128 | | -- **Parser errors (PurlError)**: No period, lowercase |
129 | | - - ✓ `throw new PurlError('missing required "name" component')` |
130 | | -- **Arg validation (Error)**: Period, sentence case |
131 | | - - ✓ `throw new Error('JSON string argument is required.')` |
132 | | - |
133 | | -## Testing |
134 | | - |
135 | | -**Test organization**: |
| 90 | +--- |
136 | 91 |
|
137 | | -| File | Purpose | |
138 | | -|------|---------| |
139 | | -| `purl-spec.test.mts` | Spec compliance tests | |
140 | | -| `purl-edge-cases.test.mts` | Edge cases & coverage | |
141 | | -| `package-url.test.mts` | Core class tests | |
142 | | -| `package-url-builder.test.mts` | Builder pattern tests | |
| 92 | +## 💡 Development Workflow |
143 | 93 |
|
144 | | -**Run tests**: |
145 | | -```bash |
146 | | -pnpm test # All tests |
147 | | -pnpm test purl-spec.test.mts # Specific file |
148 | | -pnpm cover # With coverage |
| 94 | +``` |
| 95 | +1. Branch → git checkout -b feature/my-change |
| 96 | +2. Implement → Edit src/ files |
| 97 | +3. Test → pnpm test (100% coverage required) |
| 98 | +4. Verify → pnpm run fix && pnpm test |
| 99 | +5. Commit → Conventional commits |
| 100 | +6. PR → Submit pull request |
149 | 101 | ``` |
150 | 102 |
|
151 | | -**⚠ Never use `pnpm test -- <file>`** - runs ALL tests regardless of file argument |
152 | | - |
153 | | -## Troubleshooting |
| 103 | +--- |
154 | 104 |
|
155 | | -| Problem | Solution | |
156 | | -|---------|----------| |
157 | | -| Build fails | `pnpm run clean && pnpm build` | |
158 | | -| Coverage < 100% | `pnpm cover` to see uncovered lines | |
159 | | -| Type errors | `pnpm run type` for details | |
160 | | -| NPM data outdated | `pnpm run update:data:npm` | |
| 105 | +## 📚 Key Concepts |
161 | 106 |
|
162 | | -## Next Steps |
| 107 | +### 1. Spec Compliance |
163 | 108 |
|
164 | | -### Essential Reading |
| 109 | +This library implements the [Package URL specification](https://github.com/package-url/purl-spec). |
165 | 110 |
|
166 | | -1. **[CLAUDE.md](../CLAUDE.md)** - Project standards (MANDATORY) |
167 | | -2. **[Usage Examples](./usage-examples.md)** - Real-world patterns & builder guide |
168 | | -3. **[API Reference](./api-reference.md)** - Complete API documentation |
| 111 | +All changes must maintain spec compliance. |
169 | 112 |
|
170 | | -### Deep Dives |
| 113 | +### 2. Zero Dependencies |
171 | 114 |
|
172 | | -**Adding package type support**: |
| 115 | +Runtime has zero dependencies. All code is self-contained. |
173 | 116 |
|
174 | | -1. Add type to `src/purl-type.ts`: |
175 | | - ```typescript |
176 | | - export const PURL_Type = Object.freeze({ |
177 | | - NEWTYPE: 'newtype', |
178 | | - // ...existing types |
179 | | - } as const) |
180 | | - ``` |
| 117 | +### 3. Type Safety |
181 | 118 |
|
182 | | -2. Add validation in `src/validate.ts` |
183 | | -3. Add normalization in `src/normalize.ts` |
184 | | -4. Add builder method in `src/package-url-builder.ts` |
185 | | -5. Write comprehensive tests |
186 | | -6. Update documentation |
| 119 | +Full TypeScript support with 100% type coverage: |
187 | 120 |
|
188 | | -**Result type pattern**: |
189 | 121 | ```typescript |
190 | | -import { Result, Ok, Err } from './result.js' |
191 | | - |
192 | | -function parse(input: string): Result<PackageURL> { |
193 | | - if (!input) return Err(new PurlError('input required')) |
194 | | - return Ok(purl) |
195 | | -} |
196 | | - |
197 | | -if (result.ok) { |
198 | | - console.log(result.value) // Type-safe |
199 | | -} |
| 122 | +import { PackageURL } from '@socketregistry/packageurl-js' |
| 123 | + |
| 124 | +const purl = new PackageURL( |
| 125 | + 'npm', // type |
| 126 | + null, // namespace |
| 127 | + 'lodash', // name |
| 128 | + '4.17.21', // version |
| 129 | + null, // qualifiers |
| 130 | + null // subpath |
| 131 | +) |
200 | 132 | ``` |
201 | 133 |
|
202 | | -**URL conversion**: |
203 | | -```typescript |
204 | | -import { UrlConverter } from '@socketregistry/packageurl-js' |
| 134 | +--- |
205 | 135 |
|
206 | | -const repo = UrlConverter.toRepositoryUrl(purl) |
207 | | -// → { type: 'git', url: 'https://github.com/...' } |
| 136 | +## 📖 Additional Resources |
208 | 137 |
|
209 | | -const download = UrlConverter.toDownloadUrl(purl) |
210 | | -// → { type: 'tarball', url: 'https://registry.npmjs.org/...' } |
211 | | -``` |
| 138 | +- [API Reference](./api-reference.md) - Complete API docs |
| 139 | +- [Usage Examples](./usage-examples.md) - Common patterns |
| 140 | +- [Getting Started](./getting-started.md) - Detailed setup |
| 141 | +- [CLAUDE.md](../CLAUDE.md) - Development standards |
212 | 142 |
|
213 | | -## Community |
| 143 | +--- |
214 | 144 |
|
215 | | -- Follow [@SocketSecurity](https://twitter.com/SocketSecurity) on Twitter |
216 | | -- Follow [@socket.dev](https://bsky.app/profile/socket.dev) on Bluesky |
217 | | -- Report issues on [GitHub](https://github.com/SocketDev/socket-packageurl-js/issues) |
| 145 | +## ✅ Checklist |
218 | 146 |
|
219 | | ---- |
| 147 | +- [ ] Installed dependencies (`pnpm install`) |
| 148 | +- [ ] Tests passing (`pnpm test`) |
| 149 | +- [ ] Read [API Reference](./api-reference.md) |
| 150 | +- [ ] Understand Package URL spec |
| 151 | +- [ ] Know commit format (conventional commits) |
| 152 | +- [ ] Ready to contribute! |
220 | 153 |
|
221 | | -**Performance tip**: Use `pnpm build --watch` during development for 68% faster incremental builds (9ms vs 27ms) |
| 154 | +**Welcome!** 🎉 |
0 commit comments