maven-api-client 0.0.1 → 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/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # maven-api-client
2
+
3
+ <p align="center">
4
+ <img src="https://maven.apache.org/images/maven-logo-black-on-white.png" alt="Maven logo" width="200" />
5
+ </p>
6
+
7
+ [![npm version](https://img.shields.io/npm/v/maven-api-client)](https://www.npmjs.com/package/maven-api-client)
8
+ [![npm downloads](https://img.shields.io/npm/dm/maven-api-client)](https://www.npmjs.com/package/maven-api-client)
9
+ [![Bundle size](https://img.shields.io/bundlephobia/minzip/maven-api-client)](https://bundlephobia.com/package/maven-api-client)
10
+ [![CI](https://github.com/ElJijuna/maven-api-client/actions/workflows/ci.yml/badge.svg)](https://github.com/ElJijuna/maven-api-client/actions/workflows/ci.yml)
11
+ [![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-6.x-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
14
+ [![Node.js](https://img.shields.io/node/v/maven-api-client)](https://nodejs.org/)
15
+
16
+ TypeScript client for the [Maven Central Search API](https://central.sonatype.com/). Covers artifact metadata, version listings, search, and suggestions. Works in **Node.js** and the **browser** (isomorphic). Fully typed, zero runtime dependencies.
17
+
18
+ **Data source:**
19
+
20
+ | Source | What it provides |
21
+ | --- | --- |
22
+ | [search.maven.org](https://search.maven.org) | Full-text search, artifact versions, and metadata via the Solr search API |
23
+
24
+ ---
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install maven-api-client
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Quick start
35
+
36
+ ```typescript
37
+ import { MavenClient } from 'maven-api-client';
38
+
39
+ // Public API — no auth required
40
+ const maven = new MavenClient();
41
+
42
+ // Custom registry (e.g. a private Nexus/Artifactory instance)
43
+ const privateFeed = new MavenClient({
44
+ baseUrl: 'https://my-nexus.example.com',
45
+ });
46
+ ```
47
+
48
+ ---
49
+
50
+ ## API reference
51
+
52
+ ### Artifact versions
53
+
54
+ ```typescript
55
+ // All published versions
56
+ const versions = await maven.artifact('com.fasterxml.jackson.core', 'jackson-databind').versions();
57
+ console.log(versions); // ['2.0.0', '2.1.0', ..., '2.17.0']
58
+
59
+ // Latest version (highest timestamp)
60
+ const latest = await maven.artifact('com.fasterxml.jackson.core', 'jackson-databind').latest();
61
+ console.log(latest.v); // '2.17.0'
62
+ console.log(latest.g); // 'com.fasterxml.jackson.core'
63
+ console.log(latest.a); // 'jackson-databind'
64
+ console.log(latest.timestamp); // 1712000000000
65
+
66
+ // Specific version metadata
67
+ const v2 = await maven.artifact('com.fasterxml.jackson.core', 'jackson-databind').version('2.15.0');
68
+ console.log(v2.v); // '2.15.0'
69
+ console.log(v2.p); // 'jar'
70
+ console.log(v2.ec); // ['-sources.jar', '-javadoc.jar', '.jar', '.pom']
71
+ ```
72
+
73
+ ### Search
74
+
75
+ ```typescript
76
+ const results = await maven.search({ query: 'jackson databind', rows: 10 });
77
+
78
+ console.log(results.response.numFound); // total matching artifacts
79
+
80
+ results.response.docs.forEach(doc => {
81
+ console.log(doc.id); // 'com.fasterxml.jackson.core:jackson-databind'
82
+ console.log(doc.g); // 'com.fasterxml.jackson.core'
83
+ console.log(doc.a); // 'jackson-databind'
84
+ console.log(doc.latestVersion); // '2.17.0'
85
+ console.log(doc.versionCount); // 120
86
+ });
87
+
88
+ // Paginate
89
+ const page2 = await maven.search({ query: 'logging', rows: 20, start: 20 });
90
+ ```
91
+
92
+ | Parameter | Type | Description |
93
+ | --- | --- | --- |
94
+ | `query` | `string` | Search text (optional — omit for all artifacts) |
95
+ | `rows` | `number` | Results per page (default: 20) |
96
+ | `start` | `number` | Offset for pagination (default: 0) |
97
+
98
+ ### Suggest
99
+
100
+ ```typescript
101
+ const suggestions = await maven.suggest({ query: 'jackson', rows: 5 });
102
+
103
+ suggestions.response.docs.forEach(doc => {
104
+ console.log(doc.id); // 'com.fasterxml.jackson.core:jackson-databind'
105
+ });
106
+ ```
107
+
108
+ | Parameter | Type | Description |
109
+ | --- | --- | --- |
110
+ | `query` | `string` | Prefix or keyword to match |
111
+ | `rows` | `number` | Results to return |
112
+
113
+ ---
114
+
115
+ ## Cancelling requests
116
+
117
+ Pass an `AbortSignal` to any method to cancel the in-flight request:
118
+
119
+ ```typescript
120
+ const controller = new AbortController();
121
+ setTimeout(() => controller.abort(), 5000);
122
+
123
+ await maven.artifact('com.example', 'my-lib').versions(controller.signal);
124
+ await maven.artifact('com.example', 'my-lib').latest(controller.signal);
125
+ await maven.artifact('com.example', 'my-lib').version('1.0.0', controller.signal);
126
+ await maven.search({ query: 'jackson' }, controller.signal);
127
+ await maven.suggest({ query: 'jackson' }, controller.signal);
128
+ ```
129
+
130
+ When aborted, `fetch` throws a `DOMException` with `name === 'AbortError'`. The `request` event is still emitted with the error attached.
131
+
132
+ ---
133
+
134
+ ## Request events
135
+
136
+ Subscribe to every HTTP request for logging, monitoring, or debugging:
137
+
138
+ ```typescript
139
+ maven.on('request', (event) => {
140
+ console.log(`[${event.statusCode}] ${event.method} ${event.url} (${event.durationMs}ms)`);
141
+ if (event.error) {
142
+ console.error('Request failed:', event.error.message);
143
+ }
144
+ });
145
+ ```
146
+
147
+ | Field | Type | Description |
148
+ | --- | --- | --- |
149
+ | `url` | `string` | Full URL requested |
150
+ | `method` | `'GET'` | HTTP method |
151
+ | `startedAt` | `Date` | When the request started |
152
+ | `finishedAt` | `Date` | When the request finished |
153
+ | `durationMs` | `number` | Duration in milliseconds |
154
+ | `statusCode` | `number \| undefined` | HTTP status code, if a response was received |
155
+ | `error` | `Error \| undefined` | Present only if the request failed |
156
+
157
+ `on()` is chainable and supports multiple listeners:
158
+
159
+ ```typescript
160
+ maven
161
+ .on('request', logToConsole)
162
+ .on('request', sendToDatadog);
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Error handling
168
+
169
+ Non-2xx responses throw a `MavenApiError`:
170
+
171
+ ```typescript
172
+ import { MavenApiError } from 'maven-api-client';
173
+
174
+ try {
175
+ await maven.artifact('com.example', 'non-existent').versions();
176
+ } catch (err) {
177
+ if (err instanceof MavenApiError) {
178
+ console.log(err.status); // 404
179
+ console.log(err.statusText); // 'Not Found'
180
+ console.log(err.message); // 'Maven API error: 404 Not Found'
181
+ }
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ ## TypeScript types
188
+
189
+ All domain types are exported:
190
+
191
+ ```typescript
192
+ import type {
193
+ // Client
194
+ MavenClientOptions,
195
+ RequestEvent,
196
+ MavenClientEvents,
197
+
198
+ // Search & suggest
199
+ MavenSearchParams,
200
+ MavenSuggestParams,
201
+ MavenSearchResult,
202
+ MavenSearchDoc,
203
+
204
+ // Versions
205
+ MavenVersionsResult,
206
+ MavenVersionDoc,
207
+ } from 'maven-api-client';
208
+ ```
209
+
210
+ ---
211
+
212
+ ## License
213
+
214
+ [MIT](LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ArtifactResource: () => ArtifactResource,
24
+ MavenApiError: () => MavenApiError,
25
+ MavenClient: () => MavenClient
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/errors/MavenApiError.ts
30
+ var MavenApiError = class _MavenApiError extends Error {
31
+ status;
32
+ statusText;
33
+ constructor(status, statusText) {
34
+ super(`Maven API error: ${status} ${statusText}`);
35
+ this.name = "MavenApiError";
36
+ this.status = status;
37
+ this.statusText = statusText;
38
+ Object.setPrototypeOf(this, _MavenApiError.prototype);
39
+ }
40
+ };
41
+
42
+ // src/resources/ArtifactResource.ts
43
+ var ArtifactResource = class {
44
+ groupId;
45
+ artifactId;
46
+ request;
47
+ /** @internal */
48
+ constructor(request, groupId, artifactId) {
49
+ this.request = request;
50
+ this.groupId = groupId;
51
+ this.artifactId = artifactId;
52
+ }
53
+ async versions(signal) {
54
+ const data = await this.request(
55
+ "/solrsearch/select",
56
+ {
57
+ q: `g:${this.groupId} AND a:${this.artifactId}`,
58
+ core: "gav",
59
+ rows: 200,
60
+ wt: "json"
61
+ },
62
+ void 0,
63
+ signal
64
+ );
65
+ return data.response.docs.map((d) => d.v);
66
+ }
67
+ async version(v, signal) {
68
+ const data = await this.request(
69
+ "/solrsearch/select",
70
+ {
71
+ q: `g:${this.groupId} AND a:${this.artifactId}`,
72
+ core: "gav",
73
+ rows: 200,
74
+ wt: "json"
75
+ },
76
+ void 0,
77
+ signal
78
+ );
79
+ const doc = data.response.docs.find((d) => d.v === v);
80
+ if (!doc) {
81
+ throw new Error(`Version ${v} not found for ${this.groupId}:${this.artifactId}`);
82
+ }
83
+ return doc;
84
+ }
85
+ async latest(signal) {
86
+ const data = await this.request(
87
+ "/solrsearch/select",
88
+ {
89
+ q: `g:${this.groupId} AND a:${this.artifactId}`,
90
+ core: "gav",
91
+ rows: 200,
92
+ wt: "json"
93
+ },
94
+ void 0,
95
+ signal
96
+ );
97
+ const docs = data.response.docs;
98
+ if (docs.length === 0) {
99
+ throw new Error(`No versions found for ${this.groupId}:${this.artifactId}`);
100
+ }
101
+ return docs.slice().sort((a, b) => b.timestamp - a.timestamp)[0];
102
+ }
103
+ };
104
+
105
+ // src/MavenClient.ts
106
+ var DEFAULT_BASE_URL = "https://search.maven.org";
107
+ var MavenClient = class {
108
+ baseUrl;
109
+ listeners = /* @__PURE__ */ new Map();
110
+ constructor(options = {}) {
111
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
112
+ }
113
+ on(event, callback) {
114
+ const cbs = this.listeners.get(event) ?? [];
115
+ cbs.push(callback);
116
+ this.listeners.set(event, cbs);
117
+ return this;
118
+ }
119
+ emit(event, payload) {
120
+ const cbs = this.listeners.get(event) ?? [];
121
+ for (const cb of cbs) {
122
+ cb(payload);
123
+ }
124
+ }
125
+ /** @internal */
126
+ async request(path, params, _baseUrl, signal) {
127
+ const url = buildUrl(`${this.baseUrl}${path}`, params);
128
+ const startedAt = /* @__PURE__ */ new Date();
129
+ let statusCode;
130
+ try {
131
+ const response = await fetch(url, {
132
+ headers: { Accept: "application/json" },
133
+ signal
134
+ });
135
+ statusCode = response.status;
136
+ if (!response.ok) {
137
+ throw new MavenApiError(response.status, response.statusText);
138
+ }
139
+ const data = await response.json();
140
+ this.emit("request", {
141
+ url,
142
+ method: "GET",
143
+ startedAt,
144
+ finishedAt: /* @__PURE__ */ new Date(),
145
+ durationMs: Date.now() - startedAt.getTime(),
146
+ statusCode
147
+ });
148
+ return data;
149
+ } catch (err) {
150
+ const finishedAt = /* @__PURE__ */ new Date();
151
+ this.emit("request", {
152
+ url,
153
+ method: "GET",
154
+ startedAt,
155
+ finishedAt,
156
+ durationMs: finishedAt.getTime() - startedAt.getTime(),
157
+ statusCode,
158
+ error: err instanceof Error ? err : new Error(String(err))
159
+ });
160
+ throw err;
161
+ }
162
+ }
163
+ artifact(groupId, artifactId) {
164
+ return new ArtifactResource(
165
+ (path, params, baseUrl, signal) => this.request(path, params, baseUrl, signal),
166
+ groupId,
167
+ artifactId
168
+ );
169
+ }
170
+ async search(params, signal) {
171
+ return this.request(
172
+ "/solrsearch/select",
173
+ {
174
+ q: params.query ?? "",
175
+ rows: params.rows ?? 20,
176
+ start: params.start ?? 0,
177
+ wt: "json"
178
+ },
179
+ void 0,
180
+ signal
181
+ );
182
+ }
183
+ async suggest(params, signal) {
184
+ return this.request(
185
+ "/solrsearch/select",
186
+ {
187
+ q: params.query,
188
+ ...params.rows !== void 0 && { rows: params.rows },
189
+ wt: "json"
190
+ },
191
+ void 0,
192
+ signal
193
+ );
194
+ }
195
+ };
196
+ function buildUrl(base, params) {
197
+ if (!params) {
198
+ return base;
199
+ }
200
+ const entries = Object.entries(params).filter(([, v]) => v !== void 0);
201
+ if (entries.length === 0) {
202
+ return base;
203
+ }
204
+ const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));
205
+ return `${base}?${search.toString()}`;
206
+ }
207
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors/MavenApiError.ts","../src/resources/ArtifactResource.ts","../src/MavenClient.ts"],"sourcesContent":["export type {\n MavenSearchDoc,\n MavenSearchParams,\n MavenSearchResult,\n MavenSuggestParams,\n} from './domain/Search';\nexport type { MavenVersionDoc, MavenVersionsResult } from './domain/Versions';\nexport { MavenApiError } from './errors/MavenApiError';\nexport type { MavenClientEvents, MavenClientOptions, RequestEvent } from './MavenClient';\nexport { MavenClient } from './MavenClient';\nexport { ArtifactResource } from './resources/ArtifactResource';\n","export class MavenApiError extends Error {\n readonly status: number;\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`Maven API error: ${status} ${statusText}`);\n this.name = 'MavenApiError';\n this.status = status;\n this.statusText = statusText;\n Object.setPrototypeOf(this, MavenApiError.prototype);\n }\n}\n","import type { MavenVersionDoc, MavenVersionsResult } from '../domain/Versions';\nimport type { RequestFn } from './types';\n\nexport class ArtifactResource {\n private readonly groupId: string;\n private readonly artifactId: string;\n private readonly request: RequestFn;\n\n /** @internal */\n constructor(request: RequestFn, groupId: string, artifactId: string) {\n this.request = request;\n this.groupId = groupId;\n this.artifactId = artifactId;\n }\n\n async versions(signal?: AbortSignal): Promise<string[]> {\n const data = await this.request<MavenVersionsResult>(\n '/solrsearch/select',\n {\n q: `g:${this.groupId} AND a:${this.artifactId}`,\n core: 'gav',\n rows: 200,\n wt: 'json',\n },\n undefined,\n signal,\n );\n return data.response.docs.map((d) => d.v);\n }\n\n async version(v: string, signal?: AbortSignal): Promise<MavenVersionDoc> {\n const data = await this.request<MavenVersionsResult>(\n '/solrsearch/select',\n {\n q: `g:${this.groupId} AND a:${this.artifactId}`,\n core: 'gav',\n rows: 200,\n wt: 'json',\n },\n undefined,\n signal,\n );\n const doc = data.response.docs.find((d) => d.v === v);\n if (!doc) {\n throw new Error(`Version ${v} not found for ${this.groupId}:${this.artifactId}`);\n }\n return doc;\n }\n\n async latest(signal?: AbortSignal): Promise<MavenVersionDoc> {\n const data = await this.request<MavenVersionsResult>(\n '/solrsearch/select',\n {\n q: `g:${this.groupId} AND a:${this.artifactId}`,\n core: 'gav',\n rows: 200,\n wt: 'json',\n },\n undefined,\n signal,\n );\n const docs = data.response.docs;\n if (docs.length === 0) {\n throw new Error(`No versions found for ${this.groupId}:${this.artifactId}`);\n }\n return docs.slice().sort((a, b) => b.timestamp - a.timestamp)[0];\n }\n}\n","import type { MavenSearchParams, MavenSearchResult, MavenSuggestParams } from './domain/Search';\nimport { MavenApiError } from './errors/MavenApiError';\nimport { ArtifactResource } from './resources/ArtifactResource';\n\nconst DEFAULT_BASE_URL = 'https://search.maven.org';\n\nexport interface RequestEvent {\n url: string;\n method: 'GET';\n startedAt: Date;\n finishedAt: Date;\n durationMs: number;\n statusCode?: number;\n error?: Error;\n}\n\nexport interface MavenClientEvents {\n request: (event: RequestEvent) => void;\n}\n\nexport interface MavenClientOptions {\n baseUrl?: string;\n}\n\nexport class MavenClient {\n private readonly baseUrl: string;\n private readonly listeners: Map<\n keyof MavenClientEvents,\n MavenClientEvents[keyof MavenClientEvents][]\n > = new Map();\n\n constructor(options: MavenClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n }\n\n on<K extends keyof MavenClientEvents>(event: K, callback: MavenClientEvents[K]): this {\n const cbs = this.listeners.get(event) ?? [];\n cbs.push(callback);\n this.listeners.set(event, cbs);\n return this;\n }\n\n private emit<K extends keyof MavenClientEvents>(\n event: K,\n payload: Parameters<MavenClientEvents[K]>[0],\n ): void {\n const cbs = this.listeners.get(event) ?? [];\n for (const cb of cbs) {\n (cb as (p: typeof payload) => void)(payload);\n }\n }\n\n /** @internal */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n _baseUrl?: string,\n signal?: AbortSignal,\n ): Promise<T> {\n const url = buildUrl(`${this.baseUrl}${path}`, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, {\n headers: { Accept: 'application/json' },\n signal,\n });\n statusCode = response.status;\n if (!response.ok) {\n throw new MavenApiError(response.status, response.statusText);\n }\n const data = (await response.json()) as T;\n this.emit('request', {\n url,\n method: 'GET',\n startedAt,\n finishedAt: new Date(),\n durationMs: Date.now() - startedAt.getTime(),\n statusCode,\n });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', {\n url,\n method: 'GET',\n startedAt,\n finishedAt,\n durationMs: finishedAt.getTime() - startedAt.getTime(),\n statusCode,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n throw err;\n }\n }\n\n artifact(groupId: string, artifactId: string): ArtifactResource {\n return new ArtifactResource(\n <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n baseUrl?: string,\n signal?: AbortSignal,\n ) => this.request<T>(path, params, baseUrl, signal),\n groupId,\n artifactId,\n );\n }\n\n async search(params: MavenSearchParams, signal?: AbortSignal): Promise<MavenSearchResult> {\n return this.request<MavenSearchResult>(\n '/solrsearch/select',\n {\n q: params.query ?? '',\n rows: params.rows ?? 20,\n start: params.start ?? 0,\n wt: 'json',\n },\n undefined,\n signal,\n );\n }\n\n async suggest(params: MavenSuggestParams, signal?: AbortSignal): Promise<MavenSearchResult> {\n return this.request<MavenSearchResult>(\n '/solrsearch/select',\n {\n q: params.query,\n ...(params.rows !== undefined && { rows: params.rows }),\n wt: 'json',\n },\n undefined,\n signal,\n );\n }\n}\n\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) {\n return base;\n }\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) {\n return base;\n }\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,96 @@
1
+ interface MavenSearchParams {
2
+ query?: string;
3
+ rows?: number;
4
+ start?: number;
5
+ }
6
+ interface MavenSuggestParams {
7
+ query: string;
8
+ rows?: number;
9
+ }
10
+ interface MavenSearchDoc {
11
+ id: string;
12
+ g: string;
13
+ a: string;
14
+ latestVersion: string;
15
+ repositoryId: string;
16
+ p: string;
17
+ timestamp: number;
18
+ versionCount: number;
19
+ ec: string[];
20
+ }
21
+ interface MavenSearchResult {
22
+ responseHeader: {
23
+ status: number;
24
+ QTime: number;
25
+ };
26
+ response: {
27
+ numFound: number;
28
+ start: number;
29
+ docs: MavenSearchDoc[];
30
+ };
31
+ }
32
+
33
+ interface MavenVersionDoc {
34
+ id: string;
35
+ g: string;
36
+ a: string;
37
+ v: string;
38
+ p: string;
39
+ timestamp: number;
40
+ ec: string[];
41
+ }
42
+ interface MavenVersionsResult {
43
+ response: {
44
+ numFound: number;
45
+ docs: MavenVersionDoc[];
46
+ };
47
+ }
48
+
49
+ declare class MavenApiError extends Error {
50
+ readonly status: number;
51
+ readonly statusText: string;
52
+ constructor(status: number, statusText: string);
53
+ }
54
+
55
+ type RequestFn = <T>(path: string, params?: Record<string, string | number | boolean>, baseUrl?: string, signal?: AbortSignal) => Promise<T>;
56
+
57
+ declare class ArtifactResource {
58
+ private readonly groupId;
59
+ private readonly artifactId;
60
+ private readonly request;
61
+ /** @internal */
62
+ constructor(request: RequestFn, groupId: string, artifactId: string);
63
+ versions(signal?: AbortSignal): Promise<string[]>;
64
+ version(v: string, signal?: AbortSignal): Promise<MavenVersionDoc>;
65
+ latest(signal?: AbortSignal): Promise<MavenVersionDoc>;
66
+ }
67
+
68
+ interface RequestEvent {
69
+ url: string;
70
+ method: 'GET';
71
+ startedAt: Date;
72
+ finishedAt: Date;
73
+ durationMs: number;
74
+ statusCode?: number;
75
+ error?: Error;
76
+ }
77
+ interface MavenClientEvents {
78
+ request: (event: RequestEvent) => void;
79
+ }
80
+ interface MavenClientOptions {
81
+ baseUrl?: string;
82
+ }
83
+ declare class MavenClient {
84
+ private readonly baseUrl;
85
+ private readonly listeners;
86
+ constructor(options?: MavenClientOptions);
87
+ on<K extends keyof MavenClientEvents>(event: K, callback: MavenClientEvents[K]): this;
88
+ private emit;
89
+ /** @internal */
90
+ private request;
91
+ artifact(groupId: string, artifactId: string): ArtifactResource;
92
+ search(params: MavenSearchParams, signal?: AbortSignal): Promise<MavenSearchResult>;
93
+ suggest(params: MavenSuggestParams, signal?: AbortSignal): Promise<MavenSearchResult>;
94
+ }
95
+
96
+ export { ArtifactResource, MavenApiError, MavenClient, type MavenClientEvents, type MavenClientOptions, type MavenSearchDoc, type MavenSearchParams, type MavenSearchResult, type MavenSuggestParams, type MavenVersionDoc, type MavenVersionsResult, type RequestEvent };
@@ -0,0 +1,96 @@
1
+ interface MavenSearchParams {
2
+ query?: string;
3
+ rows?: number;
4
+ start?: number;
5
+ }
6
+ interface MavenSuggestParams {
7
+ query: string;
8
+ rows?: number;
9
+ }
10
+ interface MavenSearchDoc {
11
+ id: string;
12
+ g: string;
13
+ a: string;
14
+ latestVersion: string;
15
+ repositoryId: string;
16
+ p: string;
17
+ timestamp: number;
18
+ versionCount: number;
19
+ ec: string[];
20
+ }
21
+ interface MavenSearchResult {
22
+ responseHeader: {
23
+ status: number;
24
+ QTime: number;
25
+ };
26
+ response: {
27
+ numFound: number;
28
+ start: number;
29
+ docs: MavenSearchDoc[];
30
+ };
31
+ }
32
+
33
+ interface MavenVersionDoc {
34
+ id: string;
35
+ g: string;
36
+ a: string;
37
+ v: string;
38
+ p: string;
39
+ timestamp: number;
40
+ ec: string[];
41
+ }
42
+ interface MavenVersionsResult {
43
+ response: {
44
+ numFound: number;
45
+ docs: MavenVersionDoc[];
46
+ };
47
+ }
48
+
49
+ declare class MavenApiError extends Error {
50
+ readonly status: number;
51
+ readonly statusText: string;
52
+ constructor(status: number, statusText: string);
53
+ }
54
+
55
+ type RequestFn = <T>(path: string, params?: Record<string, string | number | boolean>, baseUrl?: string, signal?: AbortSignal) => Promise<T>;
56
+
57
+ declare class ArtifactResource {
58
+ private readonly groupId;
59
+ private readonly artifactId;
60
+ private readonly request;
61
+ /** @internal */
62
+ constructor(request: RequestFn, groupId: string, artifactId: string);
63
+ versions(signal?: AbortSignal): Promise<string[]>;
64
+ version(v: string, signal?: AbortSignal): Promise<MavenVersionDoc>;
65
+ latest(signal?: AbortSignal): Promise<MavenVersionDoc>;
66
+ }
67
+
68
+ interface RequestEvent {
69
+ url: string;
70
+ method: 'GET';
71
+ startedAt: Date;
72
+ finishedAt: Date;
73
+ durationMs: number;
74
+ statusCode?: number;
75
+ error?: Error;
76
+ }
77
+ interface MavenClientEvents {
78
+ request: (event: RequestEvent) => void;
79
+ }
80
+ interface MavenClientOptions {
81
+ baseUrl?: string;
82
+ }
83
+ declare class MavenClient {
84
+ private readonly baseUrl;
85
+ private readonly listeners;
86
+ constructor(options?: MavenClientOptions);
87
+ on<K extends keyof MavenClientEvents>(event: K, callback: MavenClientEvents[K]): this;
88
+ private emit;
89
+ /** @internal */
90
+ private request;
91
+ artifact(groupId: string, artifactId: string): ArtifactResource;
92
+ search(params: MavenSearchParams, signal?: AbortSignal): Promise<MavenSearchResult>;
93
+ suggest(params: MavenSuggestParams, signal?: AbortSignal): Promise<MavenSearchResult>;
94
+ }
95
+
96
+ export { ArtifactResource, MavenApiError, MavenClient, type MavenClientEvents, type MavenClientOptions, type MavenSearchDoc, type MavenSearchParams, type MavenSearchResult, type MavenSuggestParams, type MavenVersionDoc, type MavenVersionsResult, type RequestEvent };
package/dist/index.js ADDED
@@ -0,0 +1,184 @@
1
+ // src/errors/MavenApiError.ts
2
+ var MavenApiError = class _MavenApiError extends Error {
3
+ status;
4
+ statusText;
5
+ constructor(status, statusText) {
6
+ super(`Maven API error: ${status} ${statusText}`);
7
+ this.name = "MavenApiError";
8
+ this.status = status;
9
+ this.statusText = statusText;
10
+ Object.setPrototypeOf(this, _MavenApiError.prototype);
11
+ }
12
+ };
13
+
14
+ // src/resources/ArtifactResource.ts
15
+ var ArtifactResource = class {
16
+ groupId;
17
+ artifactId;
18
+ request;
19
+ /** @internal */
20
+ constructor(request, groupId, artifactId) {
21
+ this.request = request;
22
+ this.groupId = groupId;
23
+ this.artifactId = artifactId;
24
+ }
25
+ async versions(signal) {
26
+ const data = await this.request(
27
+ "/solrsearch/select",
28
+ {
29
+ q: `g:${this.groupId} AND a:${this.artifactId}`,
30
+ core: "gav",
31
+ rows: 200,
32
+ wt: "json"
33
+ },
34
+ void 0,
35
+ signal
36
+ );
37
+ return data.response.docs.map((d) => d.v);
38
+ }
39
+ async version(v, signal) {
40
+ const data = await this.request(
41
+ "/solrsearch/select",
42
+ {
43
+ q: `g:${this.groupId} AND a:${this.artifactId}`,
44
+ core: "gav",
45
+ rows: 200,
46
+ wt: "json"
47
+ },
48
+ void 0,
49
+ signal
50
+ );
51
+ const doc = data.response.docs.find((d) => d.v === v);
52
+ if (!doc) {
53
+ throw new Error(`Version ${v} not found for ${this.groupId}:${this.artifactId}`);
54
+ }
55
+ return doc;
56
+ }
57
+ async latest(signal) {
58
+ const data = await this.request(
59
+ "/solrsearch/select",
60
+ {
61
+ q: `g:${this.groupId} AND a:${this.artifactId}`,
62
+ core: "gav",
63
+ rows: 200,
64
+ wt: "json"
65
+ },
66
+ void 0,
67
+ signal
68
+ );
69
+ const docs = data.response.docs;
70
+ if (docs.length === 0) {
71
+ throw new Error(`No versions found for ${this.groupId}:${this.artifactId}`);
72
+ }
73
+ return docs.slice().sort((a, b) => b.timestamp - a.timestamp)[0];
74
+ }
75
+ };
76
+
77
+ // src/MavenClient.ts
78
+ var DEFAULT_BASE_URL = "https://search.maven.org";
79
+ var MavenClient = class {
80
+ baseUrl;
81
+ listeners = /* @__PURE__ */ new Map();
82
+ constructor(options = {}) {
83
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
84
+ }
85
+ on(event, callback) {
86
+ const cbs = this.listeners.get(event) ?? [];
87
+ cbs.push(callback);
88
+ this.listeners.set(event, cbs);
89
+ return this;
90
+ }
91
+ emit(event, payload) {
92
+ const cbs = this.listeners.get(event) ?? [];
93
+ for (const cb of cbs) {
94
+ cb(payload);
95
+ }
96
+ }
97
+ /** @internal */
98
+ async request(path, params, _baseUrl, signal) {
99
+ const url = buildUrl(`${this.baseUrl}${path}`, params);
100
+ const startedAt = /* @__PURE__ */ new Date();
101
+ let statusCode;
102
+ try {
103
+ const response = await fetch(url, {
104
+ headers: { Accept: "application/json" },
105
+ signal
106
+ });
107
+ statusCode = response.status;
108
+ if (!response.ok) {
109
+ throw new MavenApiError(response.status, response.statusText);
110
+ }
111
+ const data = await response.json();
112
+ this.emit("request", {
113
+ url,
114
+ method: "GET",
115
+ startedAt,
116
+ finishedAt: /* @__PURE__ */ new Date(),
117
+ durationMs: Date.now() - startedAt.getTime(),
118
+ statusCode
119
+ });
120
+ return data;
121
+ } catch (err) {
122
+ const finishedAt = /* @__PURE__ */ new Date();
123
+ this.emit("request", {
124
+ url,
125
+ method: "GET",
126
+ startedAt,
127
+ finishedAt,
128
+ durationMs: finishedAt.getTime() - startedAt.getTime(),
129
+ statusCode,
130
+ error: err instanceof Error ? err : new Error(String(err))
131
+ });
132
+ throw err;
133
+ }
134
+ }
135
+ artifact(groupId, artifactId) {
136
+ return new ArtifactResource(
137
+ (path, params, baseUrl, signal) => this.request(path, params, baseUrl, signal),
138
+ groupId,
139
+ artifactId
140
+ );
141
+ }
142
+ async search(params, signal) {
143
+ return this.request(
144
+ "/solrsearch/select",
145
+ {
146
+ q: params.query ?? "",
147
+ rows: params.rows ?? 20,
148
+ start: params.start ?? 0,
149
+ wt: "json"
150
+ },
151
+ void 0,
152
+ signal
153
+ );
154
+ }
155
+ async suggest(params, signal) {
156
+ return this.request(
157
+ "/solrsearch/select",
158
+ {
159
+ q: params.query,
160
+ ...params.rows !== void 0 && { rows: params.rows },
161
+ wt: "json"
162
+ },
163
+ void 0,
164
+ signal
165
+ );
166
+ }
167
+ };
168
+ function buildUrl(base, params) {
169
+ if (!params) {
170
+ return base;
171
+ }
172
+ const entries = Object.entries(params).filter(([, v]) => v !== void 0);
173
+ if (entries.length === 0) {
174
+ return base;
175
+ }
176
+ const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));
177
+ return `${base}?${search.toString()}`;
178
+ }
179
+ export {
180
+ ArtifactResource,
181
+ MavenApiError,
182
+ MavenClient
183
+ };
184
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/MavenApiError.ts","../src/resources/ArtifactResource.ts","../src/MavenClient.ts"],"sourcesContent":["export class MavenApiError extends Error {\n readonly status: number;\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`Maven API error: ${status} ${statusText}`);\n this.name = 'MavenApiError';\n this.status = status;\n this.statusText = statusText;\n Object.setPrototypeOf(this, MavenApiError.prototype);\n }\n}\n","import type { MavenVersionDoc, MavenVersionsResult } from '../domain/Versions';\nimport type { RequestFn } from './types';\n\nexport class ArtifactResource {\n private readonly groupId: string;\n private readonly artifactId: string;\n private readonly request: RequestFn;\n\n /** @internal */\n constructor(request: RequestFn, groupId: string, artifactId: string) {\n this.request = request;\n this.groupId = groupId;\n this.artifactId = artifactId;\n }\n\n async versions(signal?: AbortSignal): Promise<string[]> {\n const data = await this.request<MavenVersionsResult>(\n '/solrsearch/select',\n {\n q: `g:${this.groupId} AND a:${this.artifactId}`,\n core: 'gav',\n rows: 200,\n wt: 'json',\n },\n undefined,\n signal,\n );\n return data.response.docs.map((d) => d.v);\n }\n\n async version(v: string, signal?: AbortSignal): Promise<MavenVersionDoc> {\n const data = await this.request<MavenVersionsResult>(\n '/solrsearch/select',\n {\n q: `g:${this.groupId} AND a:${this.artifactId}`,\n core: 'gav',\n rows: 200,\n wt: 'json',\n },\n undefined,\n signal,\n );\n const doc = data.response.docs.find((d) => d.v === v);\n if (!doc) {\n throw new Error(`Version ${v} not found for ${this.groupId}:${this.artifactId}`);\n }\n return doc;\n }\n\n async latest(signal?: AbortSignal): Promise<MavenVersionDoc> {\n const data = await this.request<MavenVersionsResult>(\n '/solrsearch/select',\n {\n q: `g:${this.groupId} AND a:${this.artifactId}`,\n core: 'gav',\n rows: 200,\n wt: 'json',\n },\n undefined,\n signal,\n );\n const docs = data.response.docs;\n if (docs.length === 0) {\n throw new Error(`No versions found for ${this.groupId}:${this.artifactId}`);\n }\n return docs.slice().sort((a, b) => b.timestamp - a.timestamp)[0];\n }\n}\n","import type { MavenSearchParams, MavenSearchResult, MavenSuggestParams } from './domain/Search';\nimport { MavenApiError } from './errors/MavenApiError';\nimport { ArtifactResource } from './resources/ArtifactResource';\n\nconst DEFAULT_BASE_URL = 'https://search.maven.org';\n\nexport interface RequestEvent {\n url: string;\n method: 'GET';\n startedAt: Date;\n finishedAt: Date;\n durationMs: number;\n statusCode?: number;\n error?: Error;\n}\n\nexport interface MavenClientEvents {\n request: (event: RequestEvent) => void;\n}\n\nexport interface MavenClientOptions {\n baseUrl?: string;\n}\n\nexport class MavenClient {\n private readonly baseUrl: string;\n private readonly listeners: Map<\n keyof MavenClientEvents,\n MavenClientEvents[keyof MavenClientEvents][]\n > = new Map();\n\n constructor(options: MavenClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n }\n\n on<K extends keyof MavenClientEvents>(event: K, callback: MavenClientEvents[K]): this {\n const cbs = this.listeners.get(event) ?? [];\n cbs.push(callback);\n this.listeners.set(event, cbs);\n return this;\n }\n\n private emit<K extends keyof MavenClientEvents>(\n event: K,\n payload: Parameters<MavenClientEvents[K]>[0],\n ): void {\n const cbs = this.listeners.get(event) ?? [];\n for (const cb of cbs) {\n (cb as (p: typeof payload) => void)(payload);\n }\n }\n\n /** @internal */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n _baseUrl?: string,\n signal?: AbortSignal,\n ): Promise<T> {\n const url = buildUrl(`${this.baseUrl}${path}`, params);\n const startedAt = new Date();\n let statusCode: number | undefined;\n try {\n const response = await fetch(url, {\n headers: { Accept: 'application/json' },\n signal,\n });\n statusCode = response.status;\n if (!response.ok) {\n throw new MavenApiError(response.status, response.statusText);\n }\n const data = (await response.json()) as T;\n this.emit('request', {\n url,\n method: 'GET',\n startedAt,\n finishedAt: new Date(),\n durationMs: Date.now() - startedAt.getTime(),\n statusCode,\n });\n return data;\n } catch (err) {\n const finishedAt = new Date();\n this.emit('request', {\n url,\n method: 'GET',\n startedAt,\n finishedAt,\n durationMs: finishedAt.getTime() - startedAt.getTime(),\n statusCode,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n throw err;\n }\n }\n\n artifact(groupId: string, artifactId: string): ArtifactResource {\n return new ArtifactResource(\n <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n baseUrl?: string,\n signal?: AbortSignal,\n ) => this.request<T>(path, params, baseUrl, signal),\n groupId,\n artifactId,\n );\n }\n\n async search(params: MavenSearchParams, signal?: AbortSignal): Promise<MavenSearchResult> {\n return this.request<MavenSearchResult>(\n '/solrsearch/select',\n {\n q: params.query ?? '',\n rows: params.rows ?? 20,\n start: params.start ?? 0,\n wt: 'json',\n },\n undefined,\n signal,\n );\n }\n\n async suggest(params: MavenSuggestParams, signal?: AbortSignal): Promise<MavenSearchResult> {\n return this.request<MavenSearchResult>(\n '/solrsearch/select',\n {\n q: params.query,\n ...(params.rows !== undefined && { rows: params.rows }),\n wt: 'json',\n },\n undefined,\n signal,\n );\n }\n}\n\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) {\n return base;\n }\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) {\n return base;\n }\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":";AAAO,IAAM,gBAAN,MAAM,uBAAsB,MAAM;AAAA,EAC9B;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,YAAoB;AAC9C,UAAM,oBAAoB,MAAM,IAAI,UAAU,EAAE;AAChD,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,WAAO,eAAe,MAAM,eAAc,SAAS;AAAA,EACrD;AACF;;;ACRO,IAAM,mBAAN,MAAuB;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGjB,YAAY,SAAoB,SAAiB,YAAoB;AACnE,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,SAAS,QAAyC;AACtD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,QACE,GAAG,KAAK,KAAK,OAAO,UAAU,KAAK,UAAU;AAAA,QAC7C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK,SAAS,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,QAAQ,GAAW,QAAgD;AACvE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,QACE,GAAG,KAAK,KAAK,OAAO,UAAU,KAAK,UAAU;AAAA,QAC7C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,MAAM,KAAK,SAAS,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;AACpD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,WAAW,CAAC,kBAAkB,KAAK,OAAO,IAAI,KAAK,UAAU,EAAE;AAAA,IACjF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,QAAgD;AAC3D,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,QACE,GAAG,KAAK,KAAK,OAAO,UAAU,KAAK,UAAU;AAAA,QAC7C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,IAAI,MAAM,yBAAyB,KAAK,OAAO,IAAI,KAAK,UAAU,EAAE;AAAA,IAC5E;AACA,WAAO,KAAK,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAAA,EACjE;AACF;;;AC/DA,IAAM,mBAAmB;AAoBlB,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EACA,YAGb,oBAAI,IAAI;AAAA,EAEZ,YAAY,UAA8B,CAAC,GAAG;AAC5C,SAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,OAAO,EAAE;AAAA,EACxE;AAAA,EAEA,GAAsC,OAAU,UAAsC;AACpF,UAAM,MAAM,KAAK,UAAU,IAAI,KAAK,KAAK,CAAC;AAC1C,QAAI,KAAK,QAAQ;AACjB,SAAK,UAAU,IAAI,OAAO,GAAG;AAC7B,WAAO;AAAA,EACT;AAAA,EAEQ,KACN,OACA,SACM;AACN,UAAM,MAAM,KAAK,UAAU,IAAI,KAAK,KAAK,CAAC;AAC1C,eAAW,MAAM,KAAK;AACpB,MAAC,GAAmC,OAAO;AAAA,IAC7C;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,QACZ,MACA,QACA,UACA,QACY;AACZ,UAAM,MAAM,SAAS,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI,MAAM;AACrD,UAAM,YAAY,oBAAI,KAAK;AAC3B,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,SAAS,EAAE,QAAQ,mBAAmB;AAAA,QACtC;AAAA,MACF,CAAC;AACD,mBAAa,SAAS;AACtB,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,cAAc,SAAS,QAAQ,SAAS,UAAU;AAAA,MAC9D;AACA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAK,KAAK,WAAW;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA,YAAY,oBAAI,KAAK;AAAA,QACrB,YAAY,KAAK,IAAI,IAAI,UAAU,QAAQ;AAAA,QAC3C;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,aAAa,oBAAI,KAAK;AAC5B,WAAK,KAAK,WAAW;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,YAAY,WAAW,QAAQ,IAAI,UAAU,QAAQ;AAAA,QACrD;AAAA,QACA,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,MAC3D,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,SAAS,SAAiB,YAAsC;AAC9D,WAAO,IAAI;AAAA,MACT,CACE,MACA,QACA,SACA,WACG,KAAK,QAAW,MAAM,QAAQ,SAAS,MAAM;AAAA,MAClD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAA2B,QAAkD;AACxF,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,QACE,GAAG,OAAO,SAAS;AAAA,QACnB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO,SAAS;AAAA,QACvB,IAAI;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,QAA4B,QAAkD;AAC1F,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,QACE,GAAG,OAAO;AAAA,QACV,GAAI,OAAO,SAAS,UAAa,EAAE,MAAM,OAAO,KAAK;AAAA,QACrD,IAAI;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,SAAS,MAAc,QAA4D;AAC1F,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AACxE,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AACA,QAAM,SAAS,IAAI,gBAAgB,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1E,SAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AACrC;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "maven-api-client",
3
- "version": "0.0.1",
4
- "description": "",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript client for the Maven Central REST API",
5
5
  "homepage": "https://github.com/ElJijuna/maven-api-client#readme",
6
6
  "bugs": {
7
7
  "url": "https://github.com/ElJijuna/maven-api-client/issues"
@@ -11,10 +11,60 @@
11
11
  "url": "git+https://github.com/ElJijuna/maven-api-client.git"
12
12
  },
13
13
  "license": "MIT",
14
- "author": "pilmee <pilmee@gmail.com>",
14
+ "author": "pilmee <pilmee@gmail.com> (https://github.com/ElJijuna)",
15
15
  "type": "module",
16
- "main": "index.js",
16
+ "main": "dist/index.cjs",
17
+ "module": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js",
23
+ "require": "./dist/index.cjs"
24
+ }
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "keywords": [
33
+ "maven",
34
+ "maven-central",
35
+ "registry",
36
+ "api-client",
37
+ "rest",
38
+ "typescript"
39
+ ],
17
40
  "scripts": {
18
- "test": "jest"
41
+ "build": "tsup",
42
+ "check": "npm run lint && npm run format:check",
43
+ "format": "biome check --write .",
44
+ "format:check": "biome check .",
45
+ "lint": "eslint .",
46
+ "lint:fix": "eslint . --fix",
47
+ "test": "jest",
48
+ "test:coverage": "jest --coverage",
49
+ "test:client": "npm run build && node test-client/test.js",
50
+ "docs": "typedoc"
51
+ },
52
+ "devDependencies": {
53
+ "@biomejs/biome": "^2.4.16",
54
+ "@semantic-release/changelog": "^6.0.3",
55
+ "@semantic-release/github": "^12.0.8",
56
+ "@types/jest": "^30.0.0",
57
+ "eslint": "^9.39.4",
58
+ "jest": "^30.4.2",
59
+ "semantic-release": "^25.0.3",
60
+ "super-configs": "^1.12.0",
61
+ "ts-jest": "^29.4.11",
62
+ "ts-node": "^10.9.2",
63
+ "tsup": "^8.5.1",
64
+ "typedoc": "^0.28.19",
65
+ "typescript": "^6.0.3"
66
+ },
67
+ "publishConfig": {
68
+ "access": "public"
19
69
  }
20
70
  }