@mytechtoday/url-reference-mapper 1.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2026-01-28
9
+
10
+ ### Added
11
+ - Initial release of @mytechtoday/url-reference-mapper
12
+ - Core `UrlReferenceMapper` class with bidirectional lookup
13
+ - Support for JSON and YAML configuration files
14
+ - CLI commands: `init`, `add`, `get-url`, `get-path`, `validate`, `export`
15
+ - TypeScript declarations for full type safety
16
+ - Seed data with 4 copper mining blog post mappings
17
+ - Export functionality to JSON, YAML, and CSV formats
18
+ - Comprehensive validation with errors and warnings
19
+ - MIT License
20
+
21
+ ### Features
22
+ - Bidirectional mapping between local paths and published URLs
23
+ - Auto-save functionality for programmatic updates
24
+ - Duplicate detection for URLs and paths
25
+ - Path normalization for cross-platform compatibility
26
+ - ISO 8601 timestamps for tracking updates
27
+ - Integration-ready for Augment AI, OpenSpec, and beads workflows
28
+
29
+ [1.0.0]: https://github.com/mytech-today-now/url-reference-mapper/releases/tag/v1.0.0
30
+
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MyTech.Today
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,397 @@
1
+ # @mytechtoday/url-reference
2
+
3
+ **Bidirectional mapping between local filesystem paths and published internet URLs for Augment AI workflows.**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@mytechtoday/url-reference.svg)](https://www.npmjs.com/package/@mytechtoday/url-reference)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## 🎯 Purpose
9
+
10
+ Eliminate broken local-file links in AI-generated content when publishing to the web. This package provides a clean, reusable solution for mapping local development paths to published URLs, specifically designed for:
11
+
12
+ - **Augment AI** workflows
13
+ - **OpenSpec** spec-driven development
14
+ - **Beads** issue tracking integration
15
+ - WordPress publishing
16
+ - Static site generation
17
+
18
+ ## 🚀 Quick Start
19
+
20
+ ### Installation
21
+
22
+ ```bash
23
+ npm install @mytechtoday/url-reference
24
+ ```
25
+
26
+ ### Initialize Configuration
27
+
28
+ ```bash
29
+ npx url-ref-mapper init
30
+ ```
31
+
32
+ This creates a `url-references.json` file with seed data for 4 copper mining blog posts.
33
+
34
+ ### Programmatic Usage
35
+
36
+ ```typescript
37
+ import { UrlReferenceMapper } from '@mytechtoday/url-reference';
38
+
39
+ const mapper = new UrlReferenceMapper({
40
+ configPath: './url-references.json'
41
+ });
42
+
43
+ // Get published URL from local path
44
+ // Windows
45
+ const url = mapper.getUrlFromLocalPath("C:\\projects\\blog\\post.html");
46
+ // macOS/Linux
47
+ const url = mapper.getUrlFromLocalPath("/home/user/projects/blog/post.html");
48
+ // → "https://mytech.today/published-url/"
49
+
50
+ // Reverse lookup
51
+ const path = mapper.getLocalPathFromUrl("https://mytech.today/published-url/");
52
+ // → "C:\\projects\\blog\\post.html" (Windows)
53
+ // → "/home/user/projects/blog/post.html" (macOS/Linux)
54
+
55
+ // Add new mapping
56
+ mapper.addMapping({
57
+ title: "New Blog Post",
58
+ url: "https://mytech.today/new-post/",
59
+ localPath: "C:\\projects\\blog\\new-post.html" // Windows
60
+ // localPath: "/home/user/projects/blog/new-post.html" // macOS/Linux
61
+ });
62
+
63
+ mapper.save();
64
+ ```
65
+
66
+ ## 📖 API Documentation
67
+
68
+ ### `UrlReferenceMapper`
69
+
70
+ #### Constructor
71
+
72
+ ```typescript
73
+ new UrlReferenceMapper(config?: UrlReferenceMapperConfig)
74
+ ```
75
+
76
+ **Config Options:**
77
+ - `configPath?: string` - Path to JSON/YAML configuration file
78
+ - `mappings?: UrlMapping[]` - Inline mappings for testing
79
+ - `autoSave?: boolean` - Auto-save changes to config file (default: false)
80
+
81
+ #### Methods
82
+
83
+ ##### `getUrlFromLocalPath(localPath: string): string | null`
84
+ Get published URL from local filesystem path.
85
+
86
+ ##### `getLocalPathFromUrl(url: string): string | null`
87
+ Get local filesystem path from published URL.
88
+
89
+ ##### `addMapping(mapping: UrlMapping): void`
90
+ Add a new URL-to-path mapping. Throws error if URL or path already exists.
91
+
92
+ ##### `updateMapping(url: string, updates: Partial<UrlMapping>): void`
93
+ Update an existing mapping by URL.
94
+
95
+ ##### `removeMapping(url: string): boolean`
96
+ Remove a mapping by URL. Returns true if removed.
97
+
98
+ ##### `getAllMappings(): UrlMapping[]`
99
+ Get all mappings as an array.
100
+
101
+ ##### `save(filePath?: string): void`
102
+ Save mappings to file (JSON or YAML based on extension).
103
+
104
+ ##### `validate(): ValidationResult`
105
+ Validate all mappings. Returns errors and warnings.
106
+
107
+ ##### `export(format: ExportFormat): string`
108
+ Export mappings to JSON, YAML, or CSV format.
109
+
110
+ ### Types
111
+
112
+ ```typescript
113
+ interface UrlMapping {
114
+ title: string;
115
+ url: string;
116
+ localPath: string;
117
+ lastUpdated?: string;
118
+ }
119
+
120
+ interface ValidationResult {
121
+ valid: boolean;
122
+ errors: string[];
123
+ warnings: string[];
124
+ }
125
+
126
+ type ExportFormat = 'json' | 'yaml' | 'csv';
127
+ ```
128
+
129
+ ## 🔧 CLI Commands
130
+
131
+ ### `init`
132
+ Create a default configuration file with seed data.
133
+
134
+ ```bash
135
+ npx url-ref-mapper init
136
+ npx url-ref-mapper init --format yaml --path custom-path.yaml
137
+ ```
138
+
139
+ ### `add`
140
+ Add a new mapping.
141
+
142
+ **Windows:**
143
+ ```bash
144
+ npx url-ref-mapper add ^
145
+ --title "My Blog Post" ^
146
+ --url "https://example.com/post/" ^
147
+ --path "C:\projects\blog\post.html"
148
+ ```
149
+
150
+ **macOS/Linux:**
151
+ ```bash
152
+ npx url-ref-mapper add \
153
+ --title "My Blog Post" \
154
+ --url "https://example.com/post/" \
155
+ --path "/home/user/projects/blog/post.html"
156
+ ```
157
+
158
+ ### `get-url`
159
+ Get published URL from local path.
160
+
161
+ **Windows:**
162
+ ```bash
163
+ npx url-ref-mapper get-url "C:\projects\blog\post.html"
164
+ ```
165
+
166
+ **macOS/Linux:**
167
+ ```bash
168
+ npx url-ref-mapper get-url "/home/user/projects/blog/post.html"
169
+ ```
170
+
171
+ ### `get-path`
172
+ Get local path from published URL.
173
+
174
+ ```bash
175
+ npx url-ref-mapper get-path "https://example.com/post/"
176
+ ```
177
+
178
+ ### `validate`
179
+ Validate all mappings.
180
+
181
+ ```bash
182
+ npx url-ref-mapper validate
183
+ ```
184
+
185
+ ### `export`
186
+ Export mappings to different formats.
187
+
188
+ ```bash
189
+ npx url-ref-mapper export --format csv --output mappings.csv
190
+ npx url-ref-mapper export --format yaml
191
+ ```
192
+
193
+ ## 🤖 Augment AI Integration
194
+
195
+ This package is designed to work seamlessly with Augment AI workflows:
196
+
197
+ ### In OpenSpec Documents
198
+
199
+ Reference the package in your spec files:
200
+
201
+ ```markdown
202
+ Use @mytechtoday/url-reference to resolve local paths to published URLs.
203
+ ```
204
+
205
+ ### In Beads Tasks
206
+
207
+ ```bash
208
+ # Create a task that uses the mapper
209
+ bd create "Update URL mappings for new blog posts"
210
+
211
+ # In your code
212
+ import { UrlReferenceMapper } from '@mytechtoday/url-reference';
213
+ const mapper = new UrlReferenceMapper({ configPath: './url-references.json' });
214
+ ```
215
+
216
+ ### With Augment Extensions
217
+
218
+ This package works alongside `@mytechtoday/augment-extensions`:
219
+
220
+ ```bash
221
+ # Install both
222
+ npm install -g @mytechtoday/augment-extensions
223
+ npm install @mytechtoday/url-reference
224
+
225
+ # Use together in your project
226
+ augx link coding-standards/typescript
227
+ ```
228
+
229
+ ## 📁 Configuration File Format
230
+
231
+ ### JSON Format (default)
232
+
233
+ **Windows:**
234
+ ```json
235
+ [
236
+ {
237
+ "title": "Copper ETFs and Investment Vehicles: 2026",
238
+ "url": "https://mytech.today/copper-etfs-and-investment-vehicles-2026/",
239
+ "localPath": "C:\\projects\\blogs\\copper-mining-part-4-etf-investment-vehicles.html",
240
+ "lastUpdated": "2026-01-27T17:04:00-06:00"
241
+ }
242
+ ]
243
+ ```
244
+
245
+ **macOS/Linux:**
246
+ ```json
247
+ [
248
+ {
249
+ "title": "Copper ETFs and Investment Vehicles: 2026",
250
+ "url": "https://mytech.today/copper-etfs-and-investment-vehicles-2026/",
251
+ "localPath": "/home/user/projects/blogs/copper-mining-part-4-etf-investment-vehicles.html",
252
+ "lastUpdated": "2026-01-27T17:04:00-06:00"
253
+ }
254
+ ]
255
+ ```
256
+
257
+ ### YAML Format
258
+
259
+ **Windows:**
260
+ ```yaml
261
+ - title: Copper ETFs and Investment Vehicles: 2026
262
+ url: https://mytech.today/copper-etfs-and-investment-vehicles-2026/
263
+ localPath: C:\projects\blogs\copper-mining-part-4-etf-investment-vehicles.html
264
+ lastUpdated: '2026-01-27T17:04:00-06:00'
265
+ ```
266
+
267
+ **macOS/Linux:**
268
+ ```yaml
269
+ - title: Copper ETFs and Investment Vehicles: 2026
270
+ url: https://mytech.today/copper-etfs-and-investment-vehicles-2026/
271
+ localPath: /home/user/projects/blogs/copper-mining-part-4-etf-investment-vehicles.html
272
+ lastUpdated: '2026-01-27T17:04:00-06:00'
273
+ ```
274
+
275
+ ## 🌍 Cross-Platform Support
276
+
277
+ This package works seamlessly across **Windows**, **macOS**, and **Linux** platforms.
278
+
279
+ ### Path Format Guidelines
280
+
281
+ **Windows:**
282
+ - Use backslashes: `C:\projects\blog\post.html`
283
+ - Or forward slashes: `C:/projects/blog/post.html`
284
+ - Both formats are supported and normalized internally
285
+
286
+ **macOS/Linux:**
287
+ - Use forward slashes: `/home/user/projects/blog/post.html`
288
+ - Absolute paths recommended for consistency
289
+
290
+ ### Platform-Specific Examples
291
+
292
+ **Windows (PowerShell):**
293
+ ```powershell
294
+ # Initialize config
295
+ npx url-ref-mapper init
296
+
297
+ # Add mapping
298
+ npx url-ref-mapper add `
299
+ --title "My Post" `
300
+ --url "https://example.com/post/" `
301
+ --path "C:\projects\blog\post.html"
302
+
303
+ # Get URL
304
+ npx url-ref-mapper get-url "C:\projects\blog\post.html"
305
+ ```
306
+
307
+ **macOS/Linux (Bash/Zsh):**
308
+ ```bash
309
+ # Initialize config
310
+ npx url-ref-mapper init
311
+
312
+ # Add mapping
313
+ npx url-ref-mapper add \
314
+ --title "My Post" \
315
+ --url "https://example.com/post/" \
316
+ --path "/home/user/projects/blog/post.html"
317
+
318
+ # Get URL
319
+ npx url-ref-mapper get-url "/home/user/projects/blog/post.html"
320
+ ```
321
+
322
+ ## 🧪 Testing
323
+
324
+ ```bash
325
+ npm test
326
+ npm run test:coverage
327
+ ```
328
+
329
+ ## 🛠 Development
330
+
331
+ ```bash
332
+ # Clone the repository
333
+ git clone https://github.com/mytech-today-now/url-reference.git
334
+ cd url-reference
335
+
336
+ # Install dependencies
337
+ npm install
338
+
339
+ # Build
340
+ npm run build
341
+
342
+ # Run in development mode
343
+ npm run dev
344
+
345
+ # Lint
346
+ npm run lint
347
+ npm run lint:fix
348
+
349
+ # Format
350
+ npm run format
351
+ ```
352
+
353
+ ## 📦 Publishing
354
+
355
+ ```bash
356
+ # Build and test
357
+ npm run build
358
+ npm test
359
+
360
+ # Publish to npm
361
+ npm publish
362
+ ```
363
+
364
+ ## 🤝 Contributing
365
+
366
+ Contributions are welcome! Please:
367
+
368
+ 1. Fork the repository
369
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
370
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
371
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
372
+ 5. Open a Pull Request
373
+
374
+ ## 📄 License
375
+
376
+ MIT License - see [LICENSE](LICENSE) file for details.
377
+
378
+ ## 🔗 Related Projects
379
+
380
+ - [Augment Code AI](https://www.augmentcode.com/) - AI coding assistant
381
+ - [OpenSpec](https://github.com/Fission-AI/OpenSpec) - Spec-driven development
382
+ - [Beads](https://github.com/steveyegge/beads) - Distributed issue tracker
383
+ - [Augment Extensions](https://github.com/mytech-today-now/augment) - Extension modules for Augment AI
384
+
385
+ ## 📞 Support
386
+
387
+ - **Issues**: [GitHub Issues](https://github.com/mytech-today-now/url-reference/issues)
388
+ - **Discussions**: [GitHub Discussions](https://github.com/mytech-today-now/url-reference/discussions)
389
+
390
+ ## 🌟 Acknowledgments
391
+
392
+ Built for the Augment AI community to solve the common problem of broken local file references in AI-generated content.
393
+
394
+ ---
395
+
396
+ **Status**: Production Ready | **Version**: 1.0.0 | **Maintainer**: MyTech.Today
397
+
@@ -0,0 +1,23 @@
1
+ import { UrlMapping, UrlReferenceMapperConfig, ValidationResult, ExportFormat } from './types';
2
+ export declare class UrlReferenceMapper {
3
+ private mappings;
4
+ private urlToMapping;
5
+ private pathToMapping;
6
+ private configPath?;
7
+ private autoSave;
8
+ private validateOnLoad;
9
+ private allowDuplicates;
10
+ constructor(config?: UrlReferenceMapperConfig);
11
+ private rebuildIndexes;
12
+ private loadFromFile;
13
+ getUrlFromLocalPath(localPath: string): string | null;
14
+ getLocalPathFromUrl(url: string): string | null;
15
+ addMapping(mapping: UrlMapping): void;
16
+ updateMapping(url: string, updates: Partial<UrlMapping>): void;
17
+ removeMapping(url: string): boolean;
18
+ getAllMappings(): UrlMapping[];
19
+ save(filePath?: string): void;
20
+ validate(): ValidationResult;
21
+ export(format: ExportFormat): string;
22
+ }
23
+ //# sourceMappingURL=UrlReferenceMapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UrlReferenceMapper.d.ts","sourceRoot":"","sources":["../src/UrlReferenceMapper.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,gBAAgB,EAAsC,YAAY,EAAE,MAAM,SAAS,CAAC;AAKnI,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,YAAY,CAAsC;IAC1D,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAU;gBAErB,MAAM,GAAE,wBAA6B;IA4BjD,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,YAAY;IAsBpB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASrD,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQ/C,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAiCrC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI;IAsC9D,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAwBnC,cAAc,IAAI,UAAU,EAAE;IAO9B,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAuB7B,QAAQ,IAAI,gBAAgB;IAuG5B,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;CAoBrC"}
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.UrlReferenceMapper = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ const yaml = __importStar(require("js-yaml"));
30
+ class UrlReferenceMapper {
31
+ constructor(config = {}) {
32
+ this.mappings = [];
33
+ this.urlToMapping = new Map();
34
+ this.pathToMapping = new Map();
35
+ this.configPath = config.configPath;
36
+ this.autoSave = config.autoSave ?? false;
37
+ this.validateOnLoad = config.validateOnLoad ?? true;
38
+ this.allowDuplicates = config.allowDuplicates ?? false;
39
+ if (config.mappings) {
40
+ this.mappings = config.mappings;
41
+ this.rebuildIndexes();
42
+ }
43
+ else if (config.configPath) {
44
+ this.loadFromFile(config.configPath);
45
+ }
46
+ if (this.validateOnLoad && this.mappings.length > 0) {
47
+ const validationResult = this.validate();
48
+ if (!validationResult.valid) {
49
+ throw new Error(`Validation failed on load:\n` +
50
+ validationResult.errors.map(e => ` - [${e.type}] ${e.message}`).join('\n'));
51
+ }
52
+ }
53
+ }
54
+ rebuildIndexes() {
55
+ this.urlToMapping.clear();
56
+ this.pathToMapping.clear();
57
+ for (const mapping of this.mappings) {
58
+ this.urlToMapping.set(mapping.url, mapping);
59
+ const normalizedPath = path.normalize(mapping.localPath);
60
+ this.pathToMapping.set(normalizedPath, mapping);
61
+ }
62
+ }
63
+ loadFromFile(filePath) {
64
+ if (!fs.existsSync(filePath)) {
65
+ throw new Error(`Configuration file not found: ${filePath}`);
66
+ }
67
+ const content = fs.readFileSync(filePath, 'utf-8');
68
+ const ext = path.extname(filePath).toLowerCase();
69
+ if (ext === '.json') {
70
+ this.mappings = JSON.parse(content);
71
+ }
72
+ else if (ext === '.yaml' || ext === '.yml') {
73
+ this.mappings = yaml.load(content);
74
+ }
75
+ else {
76
+ throw new Error(`Unsupported file format: ${ext}. Use .json, .yaml, or .yml`);
77
+ }
78
+ this.rebuildIndexes();
79
+ }
80
+ getUrlFromLocalPath(localPath) {
81
+ const normalized = path.normalize(localPath);
82
+ const mapping = this.pathToMapping.get(normalized);
83
+ return mapping ? mapping.url : null;
84
+ }
85
+ getLocalPathFromUrl(url) {
86
+ const mapping = this.urlToMapping.get(url);
87
+ return mapping ? mapping.localPath : null;
88
+ }
89
+ addMapping(mapping) {
90
+ if (!this.allowDuplicates) {
91
+ const normalizedPath = path.normalize(mapping.localPath);
92
+ if (this.urlToMapping.has(mapping.url)) {
93
+ throw new Error(`URL already exists: ${mapping.url}`);
94
+ }
95
+ if (this.pathToMapping.has(normalizedPath)) {
96
+ throw new Error(`Local path already exists: ${mapping.localPath}`);
97
+ }
98
+ }
99
+ if (!mapping.lastUpdated) {
100
+ mapping.lastUpdated = new Date().toISOString();
101
+ }
102
+ this.mappings.push(mapping);
103
+ this.urlToMapping.set(mapping.url, mapping);
104
+ const normalizedPath = path.normalize(mapping.localPath);
105
+ this.pathToMapping.set(normalizedPath, mapping);
106
+ if (this.autoSave && this.configPath) {
107
+ this.save();
108
+ }
109
+ }
110
+ updateMapping(url, updates) {
111
+ const mapping = this.urlToMapping.get(url);
112
+ if (!mapping) {
113
+ throw new Error(`Mapping not found for URL: ${url}`);
114
+ }
115
+ if (updates.localPath && updates.localPath !== mapping.localPath) {
116
+ const oldNormalizedPath = path.normalize(mapping.localPath);
117
+ this.pathToMapping.delete(oldNormalizedPath);
118
+ }
119
+ const updatedMapping = {
120
+ ...mapping,
121
+ ...updates,
122
+ lastUpdated: new Date().toISOString()
123
+ };
124
+ const index = this.mappings.findIndex(m => m.url === url);
125
+ if (index !== -1) {
126
+ this.mappings[index] = updatedMapping;
127
+ }
128
+ this.urlToMapping.set(url, updatedMapping);
129
+ const newNormalizedPath = path.normalize(updatedMapping.localPath);
130
+ this.pathToMapping.set(newNormalizedPath, updatedMapping);
131
+ if (this.autoSave && this.configPath) {
132
+ this.save();
133
+ }
134
+ }
135
+ removeMapping(url) {
136
+ const mapping = this.urlToMapping.get(url);
137
+ if (!mapping) {
138
+ return false;
139
+ }
140
+ this.mappings = this.mappings.filter(m => m.url !== url);
141
+ this.urlToMapping.delete(url);
142
+ const normalizedPath = path.normalize(mapping.localPath);
143
+ this.pathToMapping.delete(normalizedPath);
144
+ if (this.autoSave && this.configPath) {
145
+ this.save();
146
+ }
147
+ return true;
148
+ }
149
+ getAllMappings() {
150
+ return [...this.mappings];
151
+ }
152
+ save(filePath) {
153
+ const targetPath = filePath || this.configPath;
154
+ if (!targetPath) {
155
+ throw new Error('No file path specified for saving');
156
+ }
157
+ const ext = path.extname(targetPath).toLowerCase();
158
+ let content;
159
+ if (ext === '.json') {
160
+ content = JSON.stringify(this.mappings, null, 2);
161
+ }
162
+ else if (ext === '.yaml' || ext === '.yml') {
163
+ content = yaml.dump(this.mappings);
164
+ }
165
+ else {
166
+ throw new Error(`Unsupported file format: ${ext}. Use .json, .yaml, or .yml`);
167
+ }
168
+ fs.writeFileSync(targetPath, content, 'utf-8');
169
+ }
170
+ validate() {
171
+ const errors = [];
172
+ const warnings = [];
173
+ const urls = new Set();
174
+ const paths = new Set();
175
+ for (const mapping of this.mappings) {
176
+ if (!mapping.title || !mapping.url || !mapping.localPath) {
177
+ errors.push({
178
+ type: 'invalid_format',
179
+ message: `Missing required fields in mapping: ${JSON.stringify(mapping)}`,
180
+ mapping
181
+ });
182
+ continue;
183
+ }
184
+ if (urls.has(mapping.url)) {
185
+ errors.push({
186
+ type: 'duplicate_url',
187
+ message: `Duplicate URL found: ${mapping.url}`,
188
+ mapping
189
+ });
190
+ }
191
+ urls.add(mapping.url);
192
+ const normalizedPath = path.normalize(mapping.localPath);
193
+ if (paths.has(normalizedPath)) {
194
+ errors.push({
195
+ type: 'duplicate_path',
196
+ message: `Duplicate local path found: ${mapping.localPath}`,
197
+ mapping
198
+ });
199
+ }
200
+ paths.add(normalizedPath);
201
+ try {
202
+ new URL(mapping.url);
203
+ }
204
+ catch {
205
+ errors.push({
206
+ type: 'invalid_url',
207
+ message: `Invalid URL format: ${mapping.url}`,
208
+ mapping
209
+ });
210
+ }
211
+ if (!fs.existsSync(mapping.localPath)) {
212
+ warnings.push({
213
+ type: 'missing_file',
214
+ message: `Local file not found: ${mapping.localPath}`,
215
+ mapping
216
+ });
217
+ }
218
+ if (!path.isAbsolute(mapping.localPath)) {
219
+ warnings.push({
220
+ type: 'relative_path',
221
+ message: `Relative path detected (absolute paths recommended): ${mapping.localPath}`,
222
+ mapping
223
+ });
224
+ }
225
+ if (!mapping.metadata || Object.keys(mapping.metadata).length === 0) {
226
+ warnings.push({
227
+ type: 'missing_metadata',
228
+ message: `Missing metadata for mapping: ${mapping.title}`,
229
+ mapping
230
+ });
231
+ }
232
+ if (mapping.lastUpdated) {
233
+ const lastUpdated = new Date(mapping.lastUpdated);
234
+ const now = new Date();
235
+ const daysDiff = (now.getTime() - lastUpdated.getTime()) / (1000 * 60 * 60 * 24);
236
+ if (daysDiff > 90) {
237
+ warnings.push({
238
+ type: 'outdated_timestamp',
239
+ message: `Mapping not updated in ${Math.floor(daysDiff)} days: ${mapping.title}`,
240
+ mapping
241
+ });
242
+ }
243
+ }
244
+ }
245
+ return {
246
+ valid: errors.length === 0,
247
+ errors,
248
+ warnings
249
+ };
250
+ }
251
+ export(format) {
252
+ switch (format) {
253
+ case 'json':
254
+ return JSON.stringify(this.mappings, null, 2);
255
+ case 'yaml':
256
+ return yaml.dump(this.mappings);
257
+ case 'csv': {
258
+ const headers = 'Title,URL,Local Path,Last Updated\n';
259
+ const rows = this.mappings.map(m => `"${m.title}","${m.url}","${m.localPath}","${m.lastUpdated || ''}"`).join('\n');
260
+ return headers + rows;
261
+ }
262
+ default:
263
+ throw new Error(`Unsupported export format: ${format}`);
264
+ }
265
+ }
266
+ }
267
+ exports.UrlReferenceMapper = UrlReferenceMapper;
268
+ //# sourceMappingURL=UrlReferenceMapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UrlReferenceMapper.js","sourceRoot":"","sources":["../src/UrlReferenceMapper.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ const commander_1 = require("commander");
28
+ const fs = __importStar(require("fs"));
29
+ const UrlReferenceMapper_1 = require("./UrlReferenceMapper");
30
+ const yaml = __importStar(require("js-yaml"));
31
+ const program = new commander_1.Command();
32
+ program
33
+ .name('url-ref-mapper')
34
+ .description('CLI tool for managing URL-to-path mappings')
35
+ .version('1.0.0');
36
+ program
37
+ .command('init')
38
+ .description('Create a default url-references.json configuration file')
39
+ .option('-f, --format <format>', 'File format (json or yaml)', 'json')
40
+ .option('-p, --path <path>', 'Output file path', 'url-references.json')
41
+ .action((options) => {
42
+ const filePath = options.path;
43
+ const format = options.format;
44
+ if (fs.existsSync(filePath)) {
45
+ console.error(`Error: File already exists: ${filePath}`);
46
+ process.exit(1);
47
+ }
48
+ const seedData = [
49
+ {
50
+ title: "Copper ETFs and Investment Vehicles: 2026",
51
+ url: "https://mytech.today/copper-etfs-and-investment-vehicles-2026/",
52
+ localPath: "C:\\projects\\blogs\\copper-mining-part-4-etf-investment-vehicles.html",
53
+ lastUpdated: new Date().toISOString()
54
+ },
55
+ {
56
+ title: "Mid-Tier & Junior Copper Miners: 2026 Analysis",
57
+ url: "https://mytech.today/mid-tier-junior-copper-miners-2026-analysis/",
58
+ localPath: "C:\\projects\\blogs\\copper-mining-part-3-mid-tier-junior-companies.html",
59
+ lastUpdated: new Date().toISOString()
60
+ },
61
+ {
62
+ title: "Copper Demand vs Supply: 2026-2040 Outlook",
63
+ url: "https://mytech.today/copper-demand-vs-supply-2026-2040-outlook/",
64
+ localPath: "C:\\projects\\blogs\\copper-mining-part-1-demand-supply-outlook.html",
65
+ lastUpdated: new Date().toISOString()
66
+ },
67
+ {
68
+ title: "Major Copper Mining Companies Analysis 2026",
69
+ url: "https://mytech.today/major-copper-mining-companies-analysis-2026/",
70
+ localPath: "C:\\projects\\blogs\\copper-mining-part-2-major-companies-analysis.html",
71
+ lastUpdated: new Date().toISOString()
72
+ }
73
+ ];
74
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({ mappings: seedData });
75
+ const outputPath = format === 'yaml' ? filePath.replace(/\.json$/, '.yaml') : filePath;
76
+ mapper.save(outputPath);
77
+ console.log(`✓ Created ${outputPath} with ${seedData.length} seed mappings`);
78
+ });
79
+ program
80
+ .command('add')
81
+ .description('Add a new URL-to-path mapping')
82
+ .requiredOption('-t, --title <title>', 'Title of the mapping')
83
+ .requiredOption('-u, --url <url>', 'Published URL')
84
+ .requiredOption('-p, --path <path>', 'Local filesystem path')
85
+ .option('-c, --config <config>', 'Config file path', 'url-references.json')
86
+ .action((options) => {
87
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({
88
+ configPath: options.config,
89
+ autoSave: true
90
+ });
91
+ const mapping = {
92
+ title: options.title,
93
+ url: options.url,
94
+ localPath: options.path,
95
+ lastUpdated: new Date().toISOString()
96
+ };
97
+ try {
98
+ mapper.addMapping(mapping);
99
+ console.log(`✓ Added mapping: ${options.title}`);
100
+ }
101
+ catch (error) {
102
+ console.error(`Error: ${error.message}`);
103
+ process.exit(1);
104
+ }
105
+ });
106
+ program
107
+ .command('get-url <localPath>')
108
+ .description('Get published URL from local path')
109
+ .option('-c, --config <config>', 'Config file path', 'url-references.json')
110
+ .action((localPath, options) => {
111
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({ configPath: options.config });
112
+ const url = mapper.getUrlFromLocalPath(localPath);
113
+ if (url) {
114
+ console.log(url);
115
+ }
116
+ else {
117
+ console.error(`No URL found for path: ${localPath}`);
118
+ process.exit(1);
119
+ }
120
+ });
121
+ program
122
+ .command('get-path <url>')
123
+ .description('Get local path from published URL')
124
+ .option('-c, --config <config>', 'Config file path', 'url-references.json')
125
+ .action((url, options) => {
126
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({ configPath: options.config });
127
+ const localPath = mapper.getLocalPathFromUrl(url);
128
+ if (localPath) {
129
+ console.log(localPath);
130
+ }
131
+ else {
132
+ console.error(`No local path found for URL: ${url}`);
133
+ process.exit(1);
134
+ }
135
+ });
136
+ program
137
+ .command('list')
138
+ .description('List all URL-to-path mappings')
139
+ .option('-c, --config <config>', 'Config file path', 'url-references.json')
140
+ .option('-f, --format <format>', 'Output format (table, json, yaml)', 'table')
141
+ .action((options) => {
142
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({ configPath: options.config });
143
+ const mappings = mapper.getAllMappings();
144
+ if (mappings.length === 0) {
145
+ console.log('No mappings found.');
146
+ return;
147
+ }
148
+ const format = options.format.toLowerCase();
149
+ if (format === 'json') {
150
+ console.log(JSON.stringify(mappings, null, 2));
151
+ }
152
+ else if (format === 'yaml') {
153
+ console.log(yaml.dump(mappings));
154
+ }
155
+ else if (format === 'table') {
156
+ console.log('\nURL Mappings:\n');
157
+ mappings.forEach((mapping, index) => {
158
+ console.log(`${index + 1}. ${mapping.title}`);
159
+ console.log(` URL: ${mapping.url}`);
160
+ console.log(` Path: ${mapping.localPath}`);
161
+ if (mapping.lastUpdated) {
162
+ console.log(` Last Updated: ${mapping.lastUpdated}`);
163
+ }
164
+ console.log('');
165
+ });
166
+ console.log(`Total: ${mappings.length} mapping(s)`);
167
+ }
168
+ else {
169
+ console.error(`Error: Unsupported format '${options.format}'. Use 'table', 'json', or 'yaml'.`);
170
+ process.exit(1);
171
+ }
172
+ });
173
+ program
174
+ .command('validate')
175
+ .description('Validate all mappings in the configuration file')
176
+ .option('-c, --config <config>', 'Config file path', 'url-references.json')
177
+ .action((options) => {
178
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({ configPath: options.config });
179
+ const result = mapper.validate();
180
+ if (result.warnings.length > 0) {
181
+ console.log('\nWarnings:');
182
+ result.warnings.forEach(w => console.log(` ⚠ [${w.type}] ${w.message}`));
183
+ }
184
+ if (result.errors.length > 0) {
185
+ console.log('\nErrors:');
186
+ result.errors.forEach(e => console.log(` ✗ [${e.type}] ${e.message}`));
187
+ process.exit(1);
188
+ }
189
+ console.log('\n✓ All mappings are valid');
190
+ });
191
+ program
192
+ .command('export')
193
+ .description('Export mappings to different formats')
194
+ .option('-c, --config <config>', 'Config file path', 'url-references.json')
195
+ .option('-f, --format <format>', 'Export format (json, yaml, csv)', 'json')
196
+ .option('-o, --output <output>', 'Output file path (optional)')
197
+ .action((options) => {
198
+ const mapper = new UrlReferenceMapper_1.UrlReferenceMapper({ configPath: options.config });
199
+ const format = options.format;
200
+ try {
201
+ const output = mapper.export(format);
202
+ if (options.output) {
203
+ fs.writeFileSync(options.output, output, 'utf-8');
204
+ console.log(`✓ Exported to ${options.output}`);
205
+ }
206
+ else {
207
+ console.log(output);
208
+ }
209
+ }
210
+ catch (error) {
211
+ console.error(`Error: ${error.message}`);
212
+ process.exit(1);
213
+ }
214
+ });
215
+ program.parse();
216
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { UrlReferenceMapper } from './UrlReferenceMapper';
2
+ export { UrlMapping, UrlReferenceMapperConfig, MapperConfig, ValidationResult, ValidationError, ValidationErrorType, ValidationWarning, ValidationWarningType, ExportFormat } from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,UAAU,EACV,wBAAwB,EACxB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACb,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UrlReferenceMapper = void 0;
4
+ var UrlReferenceMapper_1 = require("./UrlReferenceMapper");
5
+ Object.defineProperty(exports, "UrlReferenceMapper", { enumerable: true, get: function () { return UrlReferenceMapper_1.UrlReferenceMapper; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,34 @@
1
+ export interface UrlMapping {
2
+ title: string;
3
+ url: string;
4
+ localPath: string;
5
+ lastUpdated?: string;
6
+ metadata?: Record<string, any>;
7
+ }
8
+ export interface UrlReferenceMapperConfig {
9
+ configPath?: string;
10
+ mappings?: UrlMapping[];
11
+ autoSave?: boolean;
12
+ validateOnLoad?: boolean;
13
+ allowDuplicates?: boolean;
14
+ }
15
+ export type MapperConfig = UrlReferenceMapperConfig;
16
+ export type ValidationErrorType = 'duplicate_url' | 'duplicate_path' | 'invalid_url' | 'missing_file' | 'invalid_format';
17
+ export type ValidationWarningType = 'outdated_timestamp' | 'relative_path' | 'missing_metadata' | 'missing_file';
18
+ export interface ValidationError {
19
+ type: ValidationErrorType;
20
+ message: string;
21
+ mapping?: UrlMapping;
22
+ }
23
+ export interface ValidationWarning {
24
+ type: ValidationWarningType;
25
+ message: string;
26
+ mapping?: UrlMapping;
27
+ }
28
+ export interface ValidationResult {
29
+ valid: boolean;
30
+ errors: ValidationError[];
31
+ warnings: ValidationWarning[];
32
+ }
33
+ export type ExportFormat = 'json' | 'yaml' | 'csv';
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IAEzB,KAAK,EAAE,MAAM,CAAC;IAEd,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,MAAM,CAAC;IAElB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAKD,MAAM,WAAW,wBAAwB;IAEvC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IAExB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAKD,MAAM,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAKpD,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAKrB,MAAM,MAAM,qBAAqB,GAC7B,oBAAoB,GACpB,eAAe,GACf,kBAAkB,GAClB,cAAc,CAAC;AAKnB,MAAM,WAAW,eAAe;IAE9B,IAAI,EAAE,mBAAmB,CAAC;IAE1B,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAKD,MAAM,WAAW,iBAAiB;IAEhC,IAAI,EAAE,qBAAqB,CAAC;IAE5B,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAKD,MAAM,WAAW,gBAAgB;IAE/B,KAAK,EAAE,OAAO,CAAC;IAEf,MAAM,EAAE,eAAe,EAAE,CAAC;IAE1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAKD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@mytechtoday/url-reference-mapper",
3
+ "version": "1.0.0",
4
+ "description": "Bidirectional mapping between local filesystem paths and published internet URLs for Augment AI workflows",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "url-ref-mapper": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "README.md",
13
+ "LICENSE",
14
+ "CHANGELOG.md"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "test": "jest",
20
+ "test:watch": "jest --watch",
21
+ "test:coverage": "jest --coverage",
22
+ "lint": "eslint src/**/*.ts",
23
+ "lint:fix": "eslint src/**/*.ts --fix",
24
+ "format": "prettier --write \"src/**/*.ts\"",
25
+ "prepare": "npm run build",
26
+ "prepublishOnly": "npm run lint && npm run test && npm run build",
27
+ "validate": "node dist/cli.js validate"
28
+ },
29
+ "keywords": [
30
+ "url-mapping",
31
+ "path-mapping",
32
+ "augment-ai",
33
+ "openspec",
34
+ "beads",
35
+ "url-reference",
36
+ "filesystem",
37
+ "wordpress",
38
+ "static-site",
39
+ "developer-tools"
40
+ ],
41
+ "author": "MyTech.Today",
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/mytech-today-now/url-reference.git"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/mytech-today-now/url-reference/issues"
49
+ },
50
+ "homepage": "https://github.com/mytech-today-now/url-reference#readme",
51
+ "engines": {
52
+ "node": ">=16.0.0"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "dependencies": {
58
+ "commander": "^11.0.0",
59
+ "js-yaml": "^4.1.1"
60
+ },
61
+ "devDependencies": {
62
+ "@types/jest": "^29.5.0",
63
+ "@types/js-yaml": "^4.0.9",
64
+ "@types/node": "^20.0.0",
65
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
66
+ "@typescript-eslint/parser": "^6.0.0",
67
+ "eslint": "^8.50.0",
68
+ "jest": "^29.7.0",
69
+ "prettier": "^3.0.0",
70
+ "ts-jest": "^29.1.0",
71
+ "typescript": "^5.3.3"
72
+ }
73
+ }
74
+