@iiasa/ixmp4-ts 0.8.0 → 0.9.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/dist/cjs/backend.js +12 -3
- package/dist/cjs/core/exceptions.js +5 -2
- package/dist/cjs/core/iamc/data.js +9 -9
- package/dist/cjs/core/meta.js +5 -5
- package/dist/cjs/core/run.js +6 -6
- package/dist/cjs/core/utils.js +10 -9
- package/dist/cjs/data/base.js +24 -15
- package/dist/cjs/data/fetch-client.js +182 -0
- package/dist/cjs/data/iamc/datapoint.js +14 -14
- package/dist/cjs/data/iamc/timeseries.js +12 -12
- package/dist/cjs/data/iamc/variable.js +6 -6
- package/dist/cjs/data/meta.js +6 -6
- package/dist/cjs/data/model.js +6 -6
- package/dist/cjs/data/region.js +6 -6
- package/dist/cjs/data/run.js +6 -6
- package/dist/cjs/data/scenario.js +6 -6
- package/dist/cjs/data/unit.js +6 -6
- package/dist/cjs/data/utils.js +5 -4
- package/dist/cjs/dataframe/utils.js +5 -4
- package/dist/cjs/index.js +2 -1
- package/dist/esm/backend.js +12 -3
- package/dist/esm/core/exceptions.js +3 -1
- package/dist/esm/data/base.js +17 -7
- package/dist/esm/data/fetch-client.js +161 -0
- package/dist/esm/index.js +1 -1
- package/dist/types/backend.d.ts +2 -0
- package/dist/types/core/exceptions.d.ts +3 -1
- package/dist/types/data/base.d.ts +2 -2
- package/dist/types/data/fetch-client.d.ts +54 -0
- package/dist/types/data/filters.d.ts +9 -9
- package/dist/types/data/iamc/variable.d.ts +2 -2
- package/dist/types/data/info.d.ts +2 -2
- package/dist/types/data/model.d.ts +2 -2
- package/dist/types/data/region.d.ts +2 -2
- package/dist/types/data/scenario.d.ts +2 -2
- package/dist/types/data/unit.d.ts +2 -2
- package/dist/types/index.d.ts +2 -1
- package/package.json +1 -2
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
- package/dist/esm/tsconfig.tsbuildinfo +0 -1
- package/dist/types/tsconfig.types.tsbuildinfo +0 -1
package/dist/cjs/data/model.js
CHANGED
|
@@ -17,18 +17,18 @@ class ModelRepository extends base_1.BaseRepository {
|
|
|
17
17
|
super(client);
|
|
18
18
|
this.docs = new docs_1.DocsRepository(client, 'docs/models/');
|
|
19
19
|
}
|
|
20
|
-
list() {
|
|
21
|
-
return __awaiter(this,
|
|
20
|
+
list(filter = {}) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
22
|
return yield this._list({ filter });
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
tabulate() {
|
|
26
|
-
return __awaiter(this,
|
|
25
|
+
tabulate(filter = {}) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
27
|
return yield this._tabulate({ filter });
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
|
-
count() {
|
|
31
|
-
return __awaiter(this,
|
|
30
|
+
count(filter = {}) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
32
|
return yield this._count({ filter });
|
|
33
33
|
});
|
|
34
34
|
}
|
package/dist/cjs/data/region.js
CHANGED
|
@@ -17,19 +17,19 @@ class RegionRepository extends base_1.BaseRepository {
|
|
|
17
17
|
super(client);
|
|
18
18
|
this.docs = new docs_1.DocsRepository(client, 'docs/regions/');
|
|
19
19
|
}
|
|
20
|
-
list() {
|
|
21
|
-
return __awaiter(this,
|
|
20
|
+
list(filter = {}) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
22
|
const Regions = yield this._list({ filter });
|
|
23
23
|
return Regions;
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
tabulate() {
|
|
27
|
-
return __awaiter(this,
|
|
26
|
+
tabulate(filter = {}) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
28
|
return yield this._tabulate({ filter });
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
-
count() {
|
|
32
|
-
return __awaiter(this,
|
|
31
|
+
count(filter = {}) {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
33
|
return yield this._count({ filter });
|
|
34
34
|
});
|
|
35
35
|
}
|
package/dist/cjs/data/run.js
CHANGED
|
@@ -13,18 +13,18 @@ exports.RunRepository = void 0;
|
|
|
13
13
|
const base_1 = require("./base");
|
|
14
14
|
const exceptions_1 = require("../core/exceptions");
|
|
15
15
|
class RunRepository extends base_1.BaseRepository {
|
|
16
|
-
list() {
|
|
17
|
-
return __awaiter(this,
|
|
16
|
+
list(filter = {}) {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
18
|
return yield this._list({ filter });
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
tabulate() {
|
|
22
|
-
return __awaiter(this,
|
|
21
|
+
tabulate(filter = {}) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
23
|
return yield this._tabulate({ filter });
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
count() {
|
|
27
|
-
return __awaiter(this,
|
|
26
|
+
count(filter = {}) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
28
|
return yield this._count({ filter });
|
|
29
29
|
});
|
|
30
30
|
}
|
|
@@ -17,18 +17,18 @@ class ScenarioRepository extends base_1.BaseRepository {
|
|
|
17
17
|
super(client);
|
|
18
18
|
this.docs = new docs_1.DocsRepository(client, 'docs/scenarios/');
|
|
19
19
|
}
|
|
20
|
-
list() {
|
|
21
|
-
return __awaiter(this,
|
|
20
|
+
list(filter = {}) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
22
|
return (yield this._list({ filter }));
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
tabulate() {
|
|
26
|
-
return __awaiter(this,
|
|
25
|
+
tabulate(filter = {}) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
27
|
return yield this._tabulate({ filter });
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
|
-
count() {
|
|
31
|
-
return __awaiter(this,
|
|
30
|
+
count(filter = {}) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
32
|
return yield this._count({ filter });
|
|
33
33
|
});
|
|
34
34
|
}
|
package/dist/cjs/data/unit.js
CHANGED
|
@@ -32,18 +32,18 @@ class UnitRepository extends base_1.BaseRepository {
|
|
|
32
32
|
return (yield this._get({ name }));
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
list() {
|
|
36
|
-
return __awaiter(this,
|
|
35
|
+
list(filter = {}) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
return (yield this._list({ filter }));
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
tabulate() {
|
|
41
|
-
return __awaiter(this,
|
|
40
|
+
tabulate(filter = {}) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
42
|
return yield this._tabulate({ filter });
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
-
count() {
|
|
46
|
-
return __awaiter(this,
|
|
45
|
+
count(filter = {}) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
47
|
return yield this._count({ filter });
|
|
48
48
|
});
|
|
49
49
|
}
|
package/dist/cjs/data/utils.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.convertToSnakeCase =
|
|
4
|
-
exports.convertStringToSnakeCase = convertStringToSnakeCase;
|
|
5
|
-
exports.dfToJson = dfToJson;
|
|
6
|
-
exports.jsonToDf = jsonToDf;
|
|
3
|
+
exports.jsonToDf = exports.dfToJson = exports.convertStringToSnakeCase = exports.convertToSnakeCase = void 0;
|
|
7
4
|
const dataframe_1 = require("../dataframe");
|
|
8
5
|
function convertStringToSnakeCase(name) {
|
|
9
6
|
return name.replaceAll(/([A-Z_])/g, '_$1').toLowerCase();
|
|
10
7
|
}
|
|
8
|
+
exports.convertStringToSnakeCase = convertStringToSnakeCase;
|
|
11
9
|
function convertToSnakeCase(obj) {
|
|
12
10
|
const snakeCaseObj = {};
|
|
13
11
|
for (const [key, value] of Object.entries(obj)) {
|
|
@@ -20,6 +18,7 @@ function convertToSnakeCase(obj) {
|
|
|
20
18
|
}
|
|
21
19
|
return snakeCaseObj;
|
|
22
20
|
}
|
|
21
|
+
exports.convertToSnakeCase = convertToSnakeCase;
|
|
23
22
|
function dfToJson(df) {
|
|
24
23
|
return {
|
|
25
24
|
index: df.index,
|
|
@@ -45,6 +44,7 @@ function dfToJson(df) {
|
|
|
45
44
|
data: df.values,
|
|
46
45
|
};
|
|
47
46
|
}
|
|
47
|
+
exports.dfToJson = dfToJson;
|
|
48
48
|
function jsonToDf(json) {
|
|
49
49
|
return new dataframe_1.DataFrame(json.data, {
|
|
50
50
|
index: json.index,
|
|
@@ -67,3 +67,4 @@ function jsonToDf(json) {
|
|
|
67
67
|
}),
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
+
exports.jsonToDf = jsonToDf;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.concat =
|
|
4
|
-
exports.toJson = toJson;
|
|
5
|
-
exports.toCsv = toCsv;
|
|
6
|
-
exports.merge = merge;
|
|
3
|
+
exports.merge = exports.toCsv = exports.toJson = exports.concat = void 0;
|
|
7
4
|
const dataframe_1 = require("./dataframe");
|
|
8
5
|
/**
|
|
9
6
|
* Concatenates multiple DataFrames along a specified axis.
|
|
@@ -21,6 +18,7 @@ function concat(options) {
|
|
|
21
18
|
else
|
|
22
19
|
throw new Error('Invalid value for axis parameter');
|
|
23
20
|
}
|
|
21
|
+
exports.concat = concat;
|
|
24
22
|
/**
|
|
25
23
|
* Converts a DataFrame to a JSON object.
|
|
26
24
|
*
|
|
@@ -35,6 +33,7 @@ function toJson(df) {
|
|
|
35
33
|
data: df.values,
|
|
36
34
|
};
|
|
37
35
|
}
|
|
36
|
+
exports.toJson = toJson;
|
|
38
37
|
/**
|
|
39
38
|
* Converts a DataFrame to a CSV string.
|
|
40
39
|
*
|
|
@@ -64,6 +63,7 @@ function toCsv(options) {
|
|
|
64
63
|
});
|
|
65
64
|
return header + rows.join('\n');
|
|
66
65
|
}
|
|
66
|
+
exports.toCsv = toCsv;
|
|
67
67
|
/**
|
|
68
68
|
* Merges two DataFrames based on specified columns.
|
|
69
69
|
*
|
|
@@ -190,6 +190,7 @@ function merge(options) {
|
|
|
190
190
|
dtypes,
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
|
+
exports.merge = merge;
|
|
193
194
|
/* PRIVATE */
|
|
194
195
|
function concatRows(dataFrames, addMissingColumns) {
|
|
195
196
|
if (!arraysEqual(...dataFrames.map((df) => df.columns))) {
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InvalidIndex = exports.InvalidColumn = exports.DataFrameError = exports.merge = exports.toCsv = exports.toJson = exports.concat = exports.DType = exports.DataFrame = exports.InvalidCredentials = exports.BadFilterArguments = exports.InvalidRunMeta = exports.NoDefaultRunVersion = exports.SchemaError = exports.OperationNotSupported = exports.DeletionPrevented = exports.NotUnique = exports.NotFound = exports.Forbidden = exports.InvalidToken = exports.MissingToken = exports.PlatformNotUnique = exports.PlatformNotFound = exports.UnknownApiError = exports.ManagerApiError = exports.ImproperlyConfigured = exports.BadRequest = exports.InconsistentIamcType = exports.ProgrammingError = exports.IxmpError = exports.DataPointType = exports.Platform = void 0;
|
|
3
|
+
exports.InvalidIndex = exports.InvalidColumn = exports.DataFrameError = exports.merge = exports.toCsv = exports.toJson = exports.concat = exports.DType = exports.DataFrame = exports.InvalidCredentials = exports.BadFilterArguments = exports.InvalidRunMeta = exports.NoDefaultRunVersion = exports.SchemaError = exports.OperationNotSupported = exports.DeletionPrevented = exports.NotUnique = exports.NotFound = exports.Forbidden = exports.InvalidToken = exports.MissingToken = exports.PlatformNotUnique = exports.PlatformNotFound = exports.UnknownApiError = exports.ManagerApiError = exports.ImproperlyConfigured = exports.BadRequest = exports.InconsistentIamcType = exports.NetworkError = exports.ProgrammingError = exports.IxmpError = exports.DataPointType = exports.Platform = void 0;
|
|
4
4
|
var platform_1 = require("./core/platform");
|
|
5
5
|
Object.defineProperty(exports, "Platform", { enumerable: true, get: function () { return platform_1.Platform; } });
|
|
6
6
|
var datapoint_1 = require("./data/iamc/datapoint");
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "DataPointType", { enumerable: true, get: functio
|
|
|
8
8
|
var exceptions_1 = require("./core/exceptions");
|
|
9
9
|
Object.defineProperty(exports, "IxmpError", { enumerable: true, get: function () { return exceptions_1.IxmpError; } });
|
|
10
10
|
Object.defineProperty(exports, "ProgrammingError", { enumerable: true, get: function () { return exceptions_1.ProgrammingError; } });
|
|
11
|
+
Object.defineProperty(exports, "NetworkError", { enumerable: true, get: function () { return exceptions_1.NetworkError; } });
|
|
11
12
|
Object.defineProperty(exports, "InconsistentIamcType", { enumerable: true, get: function () { return exceptions_1.InconsistentIamcType; } });
|
|
12
13
|
Object.defineProperty(exports, "BadRequest", { enumerable: true, get: function () { return exceptions_1.BadRequest; } });
|
|
13
14
|
Object.defineProperty(exports, "ImproperlyConfigured", { enumerable: true, get: function () { return exceptions_1.ImproperlyConfigured; } });
|
package/dist/esm/backend.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FetchClient } from './data/fetch-client';
|
|
2
2
|
import queryString from 'query-string';
|
|
3
3
|
import { RunRepository } from './data/run';
|
|
4
4
|
import { DataPointRepository } from './data/iamc/datapoint';
|
|
@@ -39,7 +39,7 @@ class Backend {
|
|
|
39
39
|
}
|
|
40
40
|
static async create(name, baseUrl, auth) {
|
|
41
41
|
const anonymous = !auth;
|
|
42
|
-
const client =
|
|
42
|
+
const client = FetchClient.create({
|
|
43
43
|
baseURL: new URL(`/v1/${name}`, baseUrl).href,
|
|
44
44
|
timeout: 0,
|
|
45
45
|
// we don't want to send (auth) cookies to ixmp4 but use JWT in Authorization header
|
|
@@ -60,10 +60,13 @@ class Backend {
|
|
|
60
60
|
: 'Bearer ' + auth.accessToken;
|
|
61
61
|
}
|
|
62
62
|
return config;
|
|
63
|
-
}
|
|
63
|
+
});
|
|
64
64
|
client.interceptors.response.use((value) => {
|
|
65
65
|
return value;
|
|
66
66
|
}, async (err) => {
|
|
67
|
+
if (!err.response) {
|
|
68
|
+
return Promise.reject(err);
|
|
69
|
+
}
|
|
67
70
|
const originalRequest = err.config;
|
|
68
71
|
if (!originalRequest._retry &&
|
|
69
72
|
err.response &&
|
|
@@ -89,5 +92,11 @@ class Backend {
|
|
|
89
92
|
}
|
|
90
93
|
return new Backend(client, auth);
|
|
91
94
|
}
|
|
95
|
+
addErrorHandler(handler) {
|
|
96
|
+
this.client.interceptors.response.use(undefined, handler);
|
|
97
|
+
}
|
|
98
|
+
removeErrorHandler(handler) {
|
|
99
|
+
this.client.interceptors.response.eject(undefined, handler);
|
|
100
|
+
}
|
|
92
101
|
}
|
|
93
102
|
export { Backend };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
class ProgrammingError extends Error {
|
|
2
2
|
}
|
|
3
|
+
class NetworkError extends Error {
|
|
4
|
+
}
|
|
3
5
|
class IxmpError extends Error {
|
|
4
6
|
_message = '';
|
|
5
7
|
http_status_code = 500;
|
|
@@ -162,4 +164,4 @@ registerError(NoDefaultRunVersion);
|
|
|
162
164
|
registerError(InvalidRunMeta);
|
|
163
165
|
registerError(BadFilterArguments);
|
|
164
166
|
registerError(InvalidCredentials);
|
|
165
|
-
export { createError, IxmpError, ProgrammingError, InconsistentIamcType, BadRequest, ImproperlyConfigured, ManagerApiError, UnknownApiError, PlatformNotFound, PlatformNotUnique, MissingToken, InvalidToken, Forbidden, NotFound, NotUnique, DeletionPrevented, OperationNotSupported, SchemaError, NoDefaultRunVersion, InvalidRunMeta, BadFilterArguments, InvalidCredentials, };
|
|
167
|
+
export { createError, IxmpError, ProgrammingError, NetworkError, InconsistentIamcType, BadRequest, ImproperlyConfigured, ManagerApiError, UnknownApiError, PlatformNotFound, PlatformNotUnique, MissingToken, InvalidToken, Forbidden, NotFound, NotUnique, DeletionPrevented, OperationNotSupported, SchemaError, NoDefaultRunVersion, InvalidRunMeta, BadFilterArguments, InvalidCredentials, };
|
package/dist/esm/data/base.js
CHANGED
|
@@ -29,7 +29,7 @@ class BaseRepository {
|
|
|
29
29
|
return res.data;
|
|
30
30
|
}
|
|
31
31
|
catch (err) {
|
|
32
|
-
BaseRepository.throwRemoteException(err.response, err.response?.status);
|
|
32
|
+
BaseRepository.throwRemoteException(err.response, err.response?.status || err.status);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
async _get(filter) {
|
|
@@ -149,21 +149,31 @@ class BaseRepository {
|
|
|
149
149
|
return await this._request(`${this.prefix}bulk/`, 'PATCH', params, dfToJson(df));
|
|
150
150
|
}
|
|
151
151
|
static throwRemoteException(res, statusCode) {
|
|
152
|
-
|
|
152
|
+
if (!res) {
|
|
153
|
+
throw new UnknownApiError({
|
|
154
|
+
message: 'No response received from server',
|
|
155
|
+
status_code: statusCode || 500,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const actualStatusCode = statusCode || res.status;
|
|
159
|
+
const json = res.data;
|
|
160
|
+
const contentType = res.headers.get('content-type');
|
|
153
161
|
if (typeof json !== 'object' ||
|
|
154
|
-
|
|
162
|
+
!contentType ||
|
|
163
|
+
!contentType.includes('application/json')) {
|
|
155
164
|
throw new UnknownApiError({
|
|
156
|
-
status_code:
|
|
157
|
-
|
|
165
|
+
status_code: actualStatusCode,
|
|
166
|
+
message: `HTTP ${actualStatusCode}: ${res.statusText}`,
|
|
167
|
+
...res.data,
|
|
158
168
|
});
|
|
159
169
|
}
|
|
160
170
|
if (!Object.hasOwn(json, 'error_name')) {
|
|
161
171
|
throw new UnknownApiError({
|
|
162
|
-
status_code:
|
|
172
|
+
status_code: actualStatusCode,
|
|
163
173
|
...json,
|
|
164
174
|
});
|
|
165
175
|
}
|
|
166
|
-
throw createError({ status_code:
|
|
176
|
+
throw createError({ status_code: actualStatusCode, ...json });
|
|
167
177
|
}
|
|
168
178
|
}
|
|
169
179
|
export { BaseRepository };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { NetworkError } from '../core/exceptions';
|
|
2
|
+
class FetchClient {
|
|
3
|
+
config;
|
|
4
|
+
requestInterceptors = [];
|
|
5
|
+
responseInterceptors = [];
|
|
6
|
+
errorInterceptors = [];
|
|
7
|
+
constructor(config = {}) {
|
|
8
|
+
this.config = { ...config };
|
|
9
|
+
}
|
|
10
|
+
static create(config = {}) {
|
|
11
|
+
return new FetchClient(config);
|
|
12
|
+
}
|
|
13
|
+
buildUrl(url, params, paramsSerializer) {
|
|
14
|
+
let fullUrl = url;
|
|
15
|
+
if (this.config.baseURL && !url.startsWith('http')) {
|
|
16
|
+
fullUrl =
|
|
17
|
+
this.config.baseURL.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
|
|
18
|
+
}
|
|
19
|
+
if (params && Object.keys(params).length > 0) {
|
|
20
|
+
const queryString = paramsSerializer
|
|
21
|
+
? paramsSerializer(params)
|
|
22
|
+
: new URLSearchParams(params).toString();
|
|
23
|
+
fullUrl += (fullUrl.includes('?') ? '&' : '?') + queryString;
|
|
24
|
+
}
|
|
25
|
+
return fullUrl;
|
|
26
|
+
}
|
|
27
|
+
async executeRequest(config) {
|
|
28
|
+
let finalConfig = { ...this.config, ...config };
|
|
29
|
+
// Ensure headers is always initialized
|
|
30
|
+
if (!finalConfig.headers) {
|
|
31
|
+
finalConfig.headers = {};
|
|
32
|
+
}
|
|
33
|
+
for (const interceptor of this.requestInterceptors) {
|
|
34
|
+
finalConfig = await interceptor(finalConfig);
|
|
35
|
+
}
|
|
36
|
+
const url = this.buildUrl(finalConfig.url || '', finalConfig.params, finalConfig.paramsSerializer || this.config.paramsSerializer);
|
|
37
|
+
const headers = {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
...this.config.headers,
|
|
40
|
+
...finalConfig.headers,
|
|
41
|
+
};
|
|
42
|
+
const fetchOptions = {
|
|
43
|
+
method: finalConfig.method || 'GET',
|
|
44
|
+
headers,
|
|
45
|
+
credentials: finalConfig.withCredentials ? 'include' : 'omit',
|
|
46
|
+
};
|
|
47
|
+
if (finalConfig.data !== undefined &&
|
|
48
|
+
finalConfig.method !== 'GET' &&
|
|
49
|
+
finalConfig.method !== 'HEAD') {
|
|
50
|
+
fetchOptions.body =
|
|
51
|
+
typeof finalConfig.data === 'string'
|
|
52
|
+
? finalConfig.data
|
|
53
|
+
: JSON.stringify(finalConfig.data);
|
|
54
|
+
}
|
|
55
|
+
let controller;
|
|
56
|
+
if (finalConfig.timeout && finalConfig.timeout > 0) {
|
|
57
|
+
controller = new AbortController();
|
|
58
|
+
fetchOptions.signal = controller.signal;
|
|
59
|
+
setTimeout(() => controller.abort(), finalConfig.timeout);
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const response = await fetch(url, fetchOptions);
|
|
63
|
+
let data;
|
|
64
|
+
const contentType = response.headers.get('content-type');
|
|
65
|
+
if (contentType && contentType.includes('application/json')) {
|
|
66
|
+
data = await response.json();
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
data = await response.text();
|
|
70
|
+
}
|
|
71
|
+
const fetchResponse = {
|
|
72
|
+
data,
|
|
73
|
+
status: response.status,
|
|
74
|
+
statusText: response.statusText,
|
|
75
|
+
headers: response.headers,
|
|
76
|
+
config: finalConfig,
|
|
77
|
+
};
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
80
|
+
error.config = finalConfig;
|
|
81
|
+
error.response = fetchResponse;
|
|
82
|
+
error.status = response.status;
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
let finalResponse = fetchResponse;
|
|
86
|
+
for (const interceptor of this.responseInterceptors) {
|
|
87
|
+
finalResponse = await interceptor(finalResponse);
|
|
88
|
+
}
|
|
89
|
+
return finalResponse;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
let fetchError = error;
|
|
93
|
+
// process through error interceptors
|
|
94
|
+
for (const interceptor of this.errorInterceptors) {
|
|
95
|
+
try {
|
|
96
|
+
return await interceptor(fetchError);
|
|
97
|
+
}
|
|
98
|
+
catch (interceptorError) {
|
|
99
|
+
fetchError = interceptorError;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (fetchError.name === 'AbortError') {
|
|
103
|
+
const timeoutError = new Error('Request timeout');
|
|
104
|
+
timeoutError.config = finalConfig;
|
|
105
|
+
throw timeoutError;
|
|
106
|
+
}
|
|
107
|
+
if (fetchError.name === 'TypeError') {
|
|
108
|
+
// This is likely a network error, CORS error, or DNS resolution failure
|
|
109
|
+
const networkError = new NetworkError(`Network error: ${fetchError.message}`);
|
|
110
|
+
throw networkError;
|
|
111
|
+
}
|
|
112
|
+
throw fetchError;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async request(config) {
|
|
116
|
+
return this.executeRequest(config);
|
|
117
|
+
}
|
|
118
|
+
async get(url, config = {}) {
|
|
119
|
+
return this.request({ ...config, method: 'GET', url });
|
|
120
|
+
}
|
|
121
|
+
async post(url, data, config = {}) {
|
|
122
|
+
return this.request({ ...config, method: 'POST', url, data });
|
|
123
|
+
}
|
|
124
|
+
async put(url, data, config = {}) {
|
|
125
|
+
return this.request({ ...config, method: 'PUT', url, data });
|
|
126
|
+
}
|
|
127
|
+
async patch(url, data, config = {}) {
|
|
128
|
+
return this.request({ ...config, method: 'PATCH', url, data });
|
|
129
|
+
}
|
|
130
|
+
async delete(url, config = {}) {
|
|
131
|
+
return this.request({ ...config, method: 'DELETE', url });
|
|
132
|
+
}
|
|
133
|
+
get interceptors() {
|
|
134
|
+
return {
|
|
135
|
+
request: {
|
|
136
|
+
use: (fulfilled) => {
|
|
137
|
+
this.requestInterceptors.push(fulfilled);
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
response: {
|
|
141
|
+
use: (fulfilled, rejected) => {
|
|
142
|
+
if (fulfilled) {
|
|
143
|
+
this.responseInterceptors.push(fulfilled);
|
|
144
|
+
}
|
|
145
|
+
if (rejected) {
|
|
146
|
+
this.errorInterceptors.push(rejected);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
eject: (fulfilled, rejected) => {
|
|
150
|
+
if (fulfilled) {
|
|
151
|
+
this.responseInterceptors = this.responseInterceptors.filter((interceptor) => interceptor !== fulfilled);
|
|
152
|
+
}
|
|
153
|
+
if (rejected) {
|
|
154
|
+
this.errorInterceptors = this.errorInterceptors.filter((interceptor) => interceptor !== rejected);
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export { FetchClient };
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { Platform } from './core/platform';
|
|
2
2
|
export { DataPointType } from './data/iamc/datapoint';
|
|
3
|
-
export { IxmpError, ProgrammingError, InconsistentIamcType, BadRequest, ImproperlyConfigured, ManagerApiError, UnknownApiError, PlatformNotFound, PlatformNotUnique, MissingToken, InvalidToken, Forbidden, NotFound, NotUnique, DeletionPrevented, OperationNotSupported, SchemaError, NoDefaultRunVersion, InvalidRunMeta, BadFilterArguments, InvalidCredentials, } from './core/exceptions';
|
|
3
|
+
export { IxmpError, ProgrammingError, NetworkError, InconsistentIamcType, BadRequest, ImproperlyConfigured, ManagerApiError, UnknownApiError, PlatformNotFound, PlatformNotUnique, MissingToken, InvalidToken, Forbidden, NotFound, NotUnique, DeletionPrevented, OperationNotSupported, SchemaError, NoDefaultRunVersion, InvalidRunMeta, BadFilterArguments, InvalidCredentials, } from './core/exceptions';
|
|
4
4
|
export { DataFrame, DType, concat, toJson, toCsv, merge, DataFrameError, InvalidColumn, InvalidIndex, } from './dataframe';
|
package/dist/types/backend.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ declare class Backend {
|
|
|
29
29
|
};
|
|
30
30
|
private constructor();
|
|
31
31
|
static create(name: string, baseUrl: string, auth?: IAuth): Promise<Backend>;
|
|
32
|
+
addErrorHandler(handler: (error: Error) => any): void;
|
|
33
|
+
removeErrorHandler(handler: (error: Error) => any): void;
|
|
32
34
|
}
|
|
33
35
|
export { Backend };
|
|
34
36
|
export type { IAuth };
|
|
@@ -6,6 +6,8 @@ type IxmpErrorOptions = {
|
|
|
6
6
|
};
|
|
7
7
|
declare class ProgrammingError extends Error {
|
|
8
8
|
}
|
|
9
|
+
declare class NetworkError extends Error {
|
|
10
|
+
}
|
|
9
11
|
declare class IxmpError extends Error {
|
|
10
12
|
private _message;
|
|
11
13
|
http_status_code: number;
|
|
@@ -91,4 +93,4 @@ declare class InvalidCredentials extends IxmpError {
|
|
|
91
93
|
static http_error_name: string;
|
|
92
94
|
}
|
|
93
95
|
declare function createError(options: IxmpErrorOptions): IxmpError;
|
|
94
|
-
export { createError, IxmpError, ProgrammingError, InconsistentIamcType, BadRequest, ImproperlyConfigured, ManagerApiError, UnknownApiError, PlatformNotFound, PlatformNotUnique, MissingToken, InvalidToken, Forbidden, NotFound, NotUnique, DeletionPrevented, OperationNotSupported, SchemaError, NoDefaultRunVersion, InvalidRunMeta, BadFilterArguments, InvalidCredentials, };
|
|
96
|
+
export { createError, IxmpError, ProgrammingError, NetworkError, InconsistentIamcType, BadRequest, ImproperlyConfigured, ManagerApiError, UnknownApiError, PlatformNotFound, PlatformNotUnique, MissingToken, InvalidToken, Forbidden, NotFound, NotUnique, DeletionPrevented, OperationNotSupported, SchemaError, NoDefaultRunVersion, InvalidRunMeta, BadFilterArguments, InvalidCredentials, };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DataFrame } from '../dataframe';
|
|
2
|
-
import {
|
|
2
|
+
import { FetchClient } from './fetch-client';
|
|
3
3
|
type BaseModel = {
|
|
4
4
|
id: number;
|
|
5
5
|
};
|
|
@@ -18,7 +18,7 @@ declare class BaseRepository {
|
|
|
18
18
|
private client;
|
|
19
19
|
prefix: string;
|
|
20
20
|
enumerationMethod: string;
|
|
21
|
-
constructor(client:
|
|
21
|
+
constructor(client: FetchClient, prefix?: string);
|
|
22
22
|
_request(url: string, method: string, params?: object, body?: any): Promise<any>;
|
|
23
23
|
_get(filter: object): Promise<any>;
|
|
24
24
|
_getById(id: number): Promise<any>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
interface FetchRequestConfig {
|
|
3
|
+
url?: string;
|
|
4
|
+
method?: string;
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
withCredentials?: boolean;
|
|
8
|
+
params?: Record<string, any>;
|
|
9
|
+
data?: any;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
paramsSerializer?: (params: Record<string, any>) => string;
|
|
12
|
+
}
|
|
13
|
+
interface FetchResponse<T = any> {
|
|
14
|
+
data: T;
|
|
15
|
+
status: number;
|
|
16
|
+
statusText: string;
|
|
17
|
+
headers: Headers;
|
|
18
|
+
config: FetchRequestConfig;
|
|
19
|
+
}
|
|
20
|
+
interface FetchError extends Error {
|
|
21
|
+
config: FetchRequestConfig;
|
|
22
|
+
response?: FetchResponse;
|
|
23
|
+
status?: number;
|
|
24
|
+
}
|
|
25
|
+
type RequestInterceptor = (config: FetchRequestConfig) => FetchRequestConfig | Promise<FetchRequestConfig>;
|
|
26
|
+
type ResponseInterceptor = (response: FetchResponse) => FetchResponse | Promise<FetchResponse>;
|
|
27
|
+
type ErrorInterceptor = (error: Error) => any | Promise<any>;
|
|
28
|
+
declare class FetchClient {
|
|
29
|
+
private config;
|
|
30
|
+
private requestInterceptors;
|
|
31
|
+
private responseInterceptors;
|
|
32
|
+
private errorInterceptors;
|
|
33
|
+
constructor(config?: FetchRequestConfig);
|
|
34
|
+
static create(config?: FetchRequestConfig): FetchClient;
|
|
35
|
+
private buildUrl;
|
|
36
|
+
private executeRequest;
|
|
37
|
+
request(config: FetchRequestConfig): Promise<FetchResponse>;
|
|
38
|
+
get(url: string, config?: FetchRequestConfig): Promise<FetchResponse>;
|
|
39
|
+
post(url: string, data?: any, config?: FetchRequestConfig): Promise<FetchResponse>;
|
|
40
|
+
put(url: string, data?: any, config?: FetchRequestConfig): Promise<FetchResponse>;
|
|
41
|
+
patch(url: string, data?: any, config?: FetchRequestConfig): Promise<FetchResponse>;
|
|
42
|
+
delete(url: string, config?: FetchRequestConfig): Promise<FetchResponse>;
|
|
43
|
+
get interceptors(): {
|
|
44
|
+
request: {
|
|
45
|
+
use: (fulfilled: RequestInterceptor) => void;
|
|
46
|
+
};
|
|
47
|
+
response: {
|
|
48
|
+
use: (fulfilled?: ResponseInterceptor, rejected?: ErrorInterceptor) => void;
|
|
49
|
+
eject: (fulfilled?: ResponseInterceptor, rejected?: ErrorInterceptor) => void;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export { FetchClient };
|
|
54
|
+
export type { FetchRequestConfig, FetchResponse, FetchError };
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
type Lookup<T> = T & {
|
|
2
|
-
[Key in keyof T as `${string & Key}_in`]
|
|
2
|
+
[Key in keyof T as `${string & Key}_in`]?: T[Key] extends string ? string[] : T[Key] extends number ? number[] : never;
|
|
3
3
|
} & {
|
|
4
|
-
[Key in keyof T as `${string & Key}_like`]
|
|
4
|
+
[Key in keyof T as `${string & Key}_like`]?: T[Key] extends string ? string : never;
|
|
5
5
|
} & {
|
|
6
|
-
[Key in keyof T as `${string & Key}_ilike`]
|
|
6
|
+
[Key in keyof T as `${string & Key}_ilike`]?: T[Key] extends string ? string : never;
|
|
7
7
|
} & {
|
|
8
|
-
[Key in keyof T as `${string & Key}_notlike`]
|
|
8
|
+
[Key in keyof T as `${string & Key}_notlike`]?: T[Key] extends string ? string : never;
|
|
9
9
|
} & {
|
|
10
|
-
[Key in keyof T as `${string & Key}_notilike`]
|
|
10
|
+
[Key in keyof T as `${string & Key}_notilike`]?: T[Key] extends string ? string : never;
|
|
11
11
|
} & {
|
|
12
|
-
[Key in keyof T as `${string & Key}_gt`]
|
|
12
|
+
[Key in keyof T as `${string & Key}_gt`]?: T[Key] extends number ? number : never;
|
|
13
13
|
} & {
|
|
14
|
-
[Key in keyof T as `${string & Key}_lt`]
|
|
14
|
+
[Key in keyof T as `${string & Key}_lt`]?: T[Key] extends number ? number : never;
|
|
15
15
|
} & {
|
|
16
|
-
[Key in keyof T as `${string & Key}_gte`]
|
|
16
|
+
[Key in keyof T as `${string & Key}_gte`]?: T[Key] extends number ? number : never;
|
|
17
17
|
} & {
|
|
18
|
-
[Key in keyof T as `${string & Key}_lte`]
|
|
18
|
+
[Key in keyof T as `${string & Key}_lte`]?: T[Key] extends number ? number : never;
|
|
19
19
|
};
|
|
20
20
|
export type { Lookup };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DataFrame } from '../../dataframe';
|
|
2
|
-
import {
|
|
2
|
+
import { type FetchClient } from '../fetch-client';
|
|
3
3
|
import { BaseModel, BaseRepository, PlainObject } from '../base';
|
|
4
4
|
import { Lookup } from '../filters';
|
|
5
5
|
import { DocsRepository } from '../docs';
|
|
@@ -15,7 +15,7 @@ type VariableFilter = Lookup<{
|
|
|
15
15
|
declare class VariableRepository extends BaseRepository {
|
|
16
16
|
static prefix: string;
|
|
17
17
|
docs: DocsRepository;
|
|
18
|
-
constructor(client:
|
|
18
|
+
constructor(client: FetchClient);
|
|
19
19
|
list(filter?: PlainObject): Promise<Variable[]>;
|
|
20
20
|
tabulate(filter?: PlainObject): Promise<DataFrame>;
|
|
21
21
|
count(filter?: PlainObject): Promise<number>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FetchClient } from './fetch-client';
|
|
2
2
|
import { BaseRepository } from './base';
|
|
3
3
|
type PlatformInfo = {
|
|
4
4
|
name: string;
|
|
@@ -9,7 +9,7 @@ type PlatformInfo = {
|
|
|
9
9
|
};
|
|
10
10
|
declare class PlatformInfoRepository extends BaseRepository {
|
|
11
11
|
static prefix: string;
|
|
12
|
-
constructor(client:
|
|
12
|
+
constructor(client: FetchClient);
|
|
13
13
|
get(): Promise<PlatformInfo>;
|
|
14
14
|
}
|
|
15
15
|
export { PlatformInfoRepository };
|