@openmeter/sdk 1.0.0-beta.6 → 1.0.0-beta.62
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 +76 -1
- package/dist/cjs/clients/client.js +194 -0
- package/dist/cjs/clients/client.js.map +1 -0
- package/dist/cjs/clients/event.js +137 -0
- package/dist/cjs/clients/event.js.map +1 -0
- package/dist/cjs/clients/meter.js +139 -0
- package/dist/cjs/clients/meter.js.map +1 -0
- package/dist/cjs/clients/portal.js +109 -0
- package/dist/cjs/clients/portal.js.map +1 -0
- package/dist/cjs/clients/subject.js +141 -0
- package/dist/cjs/clients/subject.js.map +1 -0
- package/dist/cjs/index.js +21 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/schemas/openapi.js +7 -0
- package/dist/cjs/schemas/openapi.js.map +1 -0
- package/dist/cjs/test/agent.js +266 -0
- package/dist/cjs/test/agent.js.map +1 -0
- package/dist/cjs/test/mocks.js +44 -0
- package/dist/cjs/test/mocks.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/clients/client.js +191 -0
- package/dist/esm/clients/client.js.map +1 -0
- package/dist/esm/clients/event.js +131 -0
- package/dist/esm/clients/event.js.map +1 -0
- package/dist/esm/clients/meter.js +136 -0
- package/dist/esm/clients/meter.js.map +1 -0
- package/dist/esm/clients/portal.js +106 -0
- package/dist/esm/clients/portal.js.map +1 -0
- package/dist/esm/clients/subject.js +138 -0
- package/dist/esm/clients/subject.js.map +1 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/{schemas → esm/schemas}/openapi.js +1 -0
- package/dist/esm/schemas/openapi.js.map +1 -0
- package/dist/{test → esm/test}/agent.js +123 -31
- package/dist/esm/test/agent.js.map +1 -0
- package/dist/esm/test/mocks.js +41 -0
- package/dist/esm/test/mocks.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/{clients → types/clients}/client.d.ts +2 -3
- package/dist/{clients → types/clients}/event.d.ts +16 -2
- package/dist/{clients → types/clients}/meter.d.ts +12 -32
- package/dist/types/clients/portal.d.ts +22 -0
- package/dist/types/clients/subject.d.ts +27 -0
- package/dist/{index.d.ts → types/index.d.ts} +6 -2
- package/dist/types/schemas/openapi.d.ts +990 -0
- package/dist/{test → types/test}/mocks.d.ts +4 -1
- package/index.ts +8 -7
- package/package.json +37 -33
- package/tsconfig.base.json +24 -0
- package/tsconfig.cjs.json +8 -0
- package/tsconfig.esm.json +8 -0
- package/dist/clients/client.js +0 -104
- package/dist/clients/event.js +0 -39
- package/dist/clients/meter.js +0 -79
- package/dist/index.js +0 -11
- package/dist/schemas/openapi.d.ts +0 -505
- package/dist/test/mocks.js +0 -21
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/{test → types/test}/agent.d.ts +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Subject } from '../clients/subject.js';
|
|
2
|
+
import { Event, Meter } from '../index.js';
|
|
3
|
+
export declare const mockEvent: Event;
|
|
2
4
|
export declare const mockMeter: Meter;
|
|
3
5
|
export declare const mockMeterValue: {
|
|
4
6
|
subject: string;
|
|
@@ -9,3 +11,4 @@ export declare const mockMeterValue: {
|
|
|
9
11
|
method: string;
|
|
10
12
|
};
|
|
11
13
|
};
|
|
14
|
+
export declare const mockSubject: Subject;
|
package/index.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { OpenMeterConfig } from './clients/client.js'
|
|
2
2
|
import { EventsClient } from './clients/event.js'
|
|
3
3
|
import { MetersClient } from './clients/meter.js'
|
|
4
|
+
import { PortalClient } from './clients/portal.js'
|
|
5
|
+
import { SubjectClient } from './clients/subject.js'
|
|
4
6
|
|
|
5
7
|
export { OpenMeterConfig, RequestOptions } from './clients/client.js'
|
|
6
|
-
export { Event } from './clients/event.js'
|
|
7
|
-
export {
|
|
8
|
-
Meter,
|
|
9
|
-
MeterValue,
|
|
10
|
-
MeterAggregation,
|
|
11
|
-
WindowSize,
|
|
12
|
-
} from './clients/meter.js'
|
|
8
|
+
export { Event, IngestedEvent } from './clients/event.js'
|
|
9
|
+
export { Meter, MeterAggregation, WindowSize } from './clients/meter.js'
|
|
13
10
|
|
|
14
11
|
export class OpenMeter {
|
|
15
12
|
public events: EventsClient
|
|
16
13
|
public meters: MetersClient
|
|
14
|
+
public portal: PortalClient
|
|
15
|
+
public subjects: SubjectClient
|
|
17
16
|
|
|
18
17
|
constructor(config: OpenMeterConfig) {
|
|
19
18
|
this.events = new EventsClient(config)
|
|
20
19
|
this.meters = new MetersClient(config)
|
|
20
|
+
this.portal = new PortalClient(config)
|
|
21
|
+
this.subjects = new SubjectClient(config)
|
|
21
22
|
}
|
|
22
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmeter/sdk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.62",
|
|
4
4
|
"description": "Client for OpenMeter: Real-Time and Scalable Usage Metering",
|
|
5
5
|
"license": "Apache 2.0",
|
|
6
6
|
"homepage": "https://openmeter.io",
|
|
@@ -9,46 +9,50 @@
|
|
|
9
9
|
"url": "https://github.com/openmeterio/openmeter.git",
|
|
10
10
|
"directory": "api/client/node"
|
|
11
11
|
},
|
|
12
|
-
"main": "./dist/index.js",
|
|
13
|
-
"types": "./dist/index.d.ts",
|
|
12
|
+
"main": "./dist/esm/index.js",
|
|
13
|
+
"types": "./dist/types/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
"import": "./dist/esm/index.js",
|
|
16
|
+
"require": "./dist/cjs/index.js",
|
|
17
|
+
"default": "./dist/esm/index.js"
|
|
18
|
+
},
|
|
14
19
|
"type": "module",
|
|
15
20
|
"engines": {
|
|
16
21
|
"node": ">=18.16.1"
|
|
17
22
|
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"lint": "eslint . --ext .ts --format=pretty",
|
|
20
|
-
"format": "prettier --write .",
|
|
21
|
-
"build": "rimraf ./dist && tsc --build",
|
|
22
|
-
"generate": "rimraf ./schemas && openapi-typescript \"../../openapi.yaml\" --output schemas/",
|
|
23
|
-
"pretest": "npm run build",
|
|
24
|
-
"test": "vitest --run --threads=false",
|
|
25
|
-
"test:watch": "vitest --watch --threads=false",
|
|
26
|
-
"prepublishOnly": "npm run generate && npm run build && npm run test && npm run lint"
|
|
27
|
-
},
|
|
28
23
|
"devDependencies": {
|
|
29
|
-
"@types/node": "^20.
|
|
30
|
-
"@types/node-fetch": "
|
|
31
|
-
"@typescript-eslint/eslint-plugin": "
|
|
32
|
-
"@typescript-eslint/parser": "
|
|
33
|
-
"eslint": "
|
|
34
|
-
"eslint-config-prettier": "
|
|
35
|
-
"eslint-formatter-pretty": "
|
|
36
|
-
"eslint-import-resolver-typescript": "
|
|
37
|
-
"eslint-plugin-compat": "
|
|
38
|
-
"eslint-plugin-import": "
|
|
39
|
-
"eslint-plugin-require-extensions": "
|
|
40
|
-
"eslint-plugin-unused-imports": "
|
|
41
|
-
"eslint-plugin-vitest": "
|
|
42
|
-
"openapi-typescript": "
|
|
43
|
-
"prettier": "
|
|
44
|
-
"rimraf": "
|
|
45
|
-
"typescript": "
|
|
46
|
-
"vitest": "
|
|
24
|
+
"@types/node": "^20.12.7",
|
|
25
|
+
"@types/node-fetch": "2.6.11",
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "7.7.0",
|
|
27
|
+
"@typescript-eslint/parser": "7.7.0",
|
|
28
|
+
"eslint": "8.57.0",
|
|
29
|
+
"eslint-config-prettier": "9.1.0",
|
|
30
|
+
"eslint-formatter-pretty": "5.0.0",
|
|
31
|
+
"eslint-import-resolver-typescript": "3.6.1",
|
|
32
|
+
"eslint-plugin-compat": "4.2.0",
|
|
33
|
+
"eslint-plugin-import": "2.29.1",
|
|
34
|
+
"eslint-plugin-require-extensions": "0.1.3",
|
|
35
|
+
"eslint-plugin-unused-imports": "3.1.0",
|
|
36
|
+
"eslint-plugin-vitest": "0.4.1",
|
|
37
|
+
"openapi-typescript": "6.7.5",
|
|
38
|
+
"prettier": "3.2.5",
|
|
39
|
+
"rimraf": "5.0.5",
|
|
40
|
+
"typescript": "5.4.5",
|
|
41
|
+
"vitest": "1.5.0"
|
|
47
42
|
},
|
|
48
43
|
"browserslist": [
|
|
49
44
|
"current node"
|
|
50
45
|
],
|
|
51
46
|
"dependencies": {
|
|
52
|
-
"undici": "^
|
|
47
|
+
"undici": "^6.13.0"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"lint": "eslint . --ext .ts --format=pretty",
|
|
51
|
+
"format": "prettier --write .",
|
|
52
|
+
"build": "rimraf ./dist && tsc --project tsconfig.cjs.json && tsc --project tsconfig.esm.json",
|
|
53
|
+
"generate": "rimraf ./schemas && openapi-typescript '../../openapi.yaml' --output schemas/openapi.ts && prettier --write schemas/",
|
|
54
|
+
"pretest": "pnpm run build",
|
|
55
|
+
"test": "vitest --run",
|
|
56
|
+
"test:watch": "vitest --watch"
|
|
53
57
|
}
|
|
54
|
-
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"moduleResolution": "node",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"incremental": true,
|
|
11
|
+
"experimentalDecorators": true,
|
|
12
|
+
"emitDecoratorMetadata": true,
|
|
13
|
+
"allowSyntheticDefaultImports": true,
|
|
14
|
+
"sourceMap": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["**/*.ts"],
|
|
17
|
+
"exclude": [
|
|
18
|
+
"**/*.spec.ts",
|
|
19
|
+
"**/*.test.ts",
|
|
20
|
+
"scripts/**/*.ts",
|
|
21
|
+
"dist/**/*.ts",
|
|
22
|
+
"*.config.ts"
|
|
23
|
+
]
|
|
24
|
+
}
|
package/dist/clients/client.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { request } from 'undici';
|
|
2
|
-
export class BaseClient {
|
|
3
|
-
config;
|
|
4
|
-
constructor(config) {
|
|
5
|
-
this.config = config;
|
|
6
|
-
}
|
|
7
|
-
async request({ path, method, searchParams, headers, body, options, }) {
|
|
8
|
-
// Building URL
|
|
9
|
-
const url = this.getUrl(path, searchParams);
|
|
10
|
-
// Request options
|
|
11
|
-
const reqHeaders = {
|
|
12
|
-
Accept: 'application/json',
|
|
13
|
-
...headers,
|
|
14
|
-
...this.getAuthHeaders(),
|
|
15
|
-
...this.config.headers,
|
|
16
|
-
...options?.headers,
|
|
17
|
-
};
|
|
18
|
-
const reqOpts = {
|
|
19
|
-
method,
|
|
20
|
-
headers: reqHeaders,
|
|
21
|
-
};
|
|
22
|
-
// Optional body
|
|
23
|
-
if (body) {
|
|
24
|
-
if (!reqHeaders['Content-Type'] && !reqHeaders['content-type']) {
|
|
25
|
-
throw new Error('Content Type is required with body');
|
|
26
|
-
}
|
|
27
|
-
reqOpts.body = body;
|
|
28
|
-
}
|
|
29
|
-
const resp = await request(url, reqOpts);
|
|
30
|
-
// Error handling
|
|
31
|
-
if (resp.statusCode > 399) {
|
|
32
|
-
if (resp.headers['content-type'] === 'application/problem+json') {
|
|
33
|
-
const problem = (await resp.body.json());
|
|
34
|
-
throw new HttpError({
|
|
35
|
-
statusCode: resp.statusCode,
|
|
36
|
-
problem,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
// Requests can fail before API, in this case we only have a status code
|
|
40
|
-
throw new HttpError({
|
|
41
|
-
statusCode: resp.statusCode,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// Response parsing
|
|
45
|
-
if (resp.statusCode === 204 || resp.headers['content-length'] === '0') {
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
if (resp.headers['content-type'] === 'application/json') {
|
|
49
|
-
return (await resp.body.json());
|
|
50
|
-
}
|
|
51
|
-
if (!resp.headers['content-type']) {
|
|
52
|
-
throw new Error('Missing content type');
|
|
53
|
-
}
|
|
54
|
-
throw new Error(`Unknown content type: ${resp.headers['content-type']}`);
|
|
55
|
-
}
|
|
56
|
-
getUrl(path, searchParams) {
|
|
57
|
-
let qs = searchParams ? searchParams.toString() : '';
|
|
58
|
-
qs = qs.length > 0 ? `?${qs}` : '';
|
|
59
|
-
const url = new URL(`${path}${qs}`, this.config.baseUrl);
|
|
60
|
-
return url;
|
|
61
|
-
}
|
|
62
|
-
getAuthHeaders() {
|
|
63
|
-
if (this.config.token) {
|
|
64
|
-
return {
|
|
65
|
-
authorization: `Bearer ${this.config.token}`,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
if (this.config.username && this.config.password) {
|
|
69
|
-
const encoded = Buffer.from(`${this.config.username}:${this.config.password}`).toString('base64');
|
|
70
|
-
return {
|
|
71
|
-
authorization: `Basic ${encoded}`,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
return {};
|
|
75
|
-
}
|
|
76
|
-
static toURLSearchParams(params) {
|
|
77
|
-
const searchParams = new URLSearchParams();
|
|
78
|
-
for (const [key, value] of Object.entries(params)) {
|
|
79
|
-
if (value === undefined) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
if (Array.isArray(value)) {
|
|
83
|
-
searchParams.append(key, value.join(','));
|
|
84
|
-
}
|
|
85
|
-
else if (value instanceof Date) {
|
|
86
|
-
searchParams.append(key, value.toISOString());
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
searchParams.append(key, value.toString());
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return searchParams;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
export class HttpError extends Error {
|
|
96
|
-
statusCode;
|
|
97
|
-
problem;
|
|
98
|
-
constructor({ statusCode, problem, }) {
|
|
99
|
-
super(problem?.type || 'unexpected status code');
|
|
100
|
-
this.name = 'HttpError';
|
|
101
|
-
this.statusCode = statusCode;
|
|
102
|
-
this.problem = problem;
|
|
103
|
-
}
|
|
104
|
-
}
|
package/dist/clients/event.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import { BaseClient } from './client.js';
|
|
3
|
-
export class EventsClient extends BaseClient {
|
|
4
|
-
constructor(config) {
|
|
5
|
-
super(config);
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Ingest usage event in a CloudEvents format
|
|
9
|
-
* @see https://cloudevents.io
|
|
10
|
-
*/
|
|
11
|
-
async ingest(usageEvent, options) {
|
|
12
|
-
if (usageEvent.datacontenttype &&
|
|
13
|
-
usageEvent.datacontenttype !== 'application/json') {
|
|
14
|
-
throw new TypeError(`Unsupported datacontenttype: ${usageEvent.datacontenttype}`);
|
|
15
|
-
}
|
|
16
|
-
// We default where we can to lower the barrier to use CloudEvents
|
|
17
|
-
const body = {
|
|
18
|
-
specversion: usageEvent.specversion ?? '1.0',
|
|
19
|
-
id: usageEvent.id ?? crypto.randomUUID(),
|
|
20
|
-
source: usageEvent.source ?? '@openmeter/sdk',
|
|
21
|
-
type: usageEvent.type,
|
|
22
|
-
subject: usageEvent.subject,
|
|
23
|
-
time: usageEvent.time?.toISOString(),
|
|
24
|
-
datacontenttype: usageEvent.datacontenttype,
|
|
25
|
-
dataschema: usageEvent.dataschema,
|
|
26
|
-
data: usageEvent.data,
|
|
27
|
-
};
|
|
28
|
-
// Making Request
|
|
29
|
-
return await this.request({
|
|
30
|
-
path: '/api/v1/events',
|
|
31
|
-
method: 'POST',
|
|
32
|
-
body: JSON.stringify(body),
|
|
33
|
-
headers: {
|
|
34
|
-
'Content-Type': 'application/cloudevents+json',
|
|
35
|
-
},
|
|
36
|
-
options,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
}
|
package/dist/clients/meter.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { BaseClient } from './client.js';
|
|
2
|
-
export var WindowSize;
|
|
3
|
-
(function (WindowSize) {
|
|
4
|
-
WindowSize["MINUTE"] = "MINUTE";
|
|
5
|
-
WindowSize["HOUR"] = "HOUR";
|
|
6
|
-
WindowSize["DAY"] = "DAY";
|
|
7
|
-
})(WindowSize || (WindowSize = {}));
|
|
8
|
-
export var MeterAggregation;
|
|
9
|
-
(function (MeterAggregation) {
|
|
10
|
-
MeterAggregation["SUM"] = "SUM";
|
|
11
|
-
MeterAggregation["COUNT"] = "COUNT";
|
|
12
|
-
MeterAggregation["AVG"] = "AVG";
|
|
13
|
-
MeterAggregation["MIN"] = "MIN";
|
|
14
|
-
MeterAggregation["MAX"] = "MAX";
|
|
15
|
-
})(MeterAggregation || (MeterAggregation = {}));
|
|
16
|
-
export class MetersClient extends BaseClient {
|
|
17
|
-
constructor(config) {
|
|
18
|
-
super(config);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Get one meter by slug
|
|
22
|
-
*/
|
|
23
|
-
async get(slug, options) {
|
|
24
|
-
return this.request({
|
|
25
|
-
method: 'GET',
|
|
26
|
-
path: `/api/v1/meters/${slug}`,
|
|
27
|
-
options,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* List meters
|
|
32
|
-
*/
|
|
33
|
-
async list(options) {
|
|
34
|
-
return this.request({
|
|
35
|
-
method: 'GET',
|
|
36
|
-
path: `/api/v1/meters`,
|
|
37
|
-
options,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Get aggregated values of a meter
|
|
42
|
-
* @deprecated Use `meters.query` instead
|
|
43
|
-
*/
|
|
44
|
-
async values(slug, params, options) {
|
|
45
|
-
const searchParams = params
|
|
46
|
-
? BaseClient.toURLSearchParams(params)
|
|
47
|
-
: undefined;
|
|
48
|
-
return this.request({
|
|
49
|
-
method: 'GET',
|
|
50
|
-
path: `/api/v1/meters/${slug}/values`,
|
|
51
|
-
searchParams,
|
|
52
|
-
options,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Query a meter
|
|
57
|
-
*/
|
|
58
|
-
async query(slug, params, options) {
|
|
59
|
-
const searchParams = params
|
|
60
|
-
? BaseClient.toURLSearchParams(params)
|
|
61
|
-
: undefined;
|
|
62
|
-
return this.request({
|
|
63
|
-
method: 'GET',
|
|
64
|
-
path: `/api/v1/meters/${slug}/query`,
|
|
65
|
-
searchParams,
|
|
66
|
-
options,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* List subjects of a meter
|
|
71
|
-
*/
|
|
72
|
-
async subjects(slug, options) {
|
|
73
|
-
return this.request({
|
|
74
|
-
method: 'GET',
|
|
75
|
-
path: `/api/v1/meters/${slug}/subjects`,
|
|
76
|
-
options,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { EventsClient } from './clients/event.js';
|
|
2
|
-
import { MetersClient } from './clients/meter.js';
|
|
3
|
-
export { MeterAggregation, WindowSize, } from './clients/meter.js';
|
|
4
|
-
export class OpenMeter {
|
|
5
|
-
events;
|
|
6
|
-
meters;
|
|
7
|
-
constructor(config) {
|
|
8
|
-
this.events = new EventsClient(config);
|
|
9
|
-
this.meters = new MetersClient(config);
|
|
10
|
-
}
|
|
11
|
-
}
|