@iiasa/ixmp4-ts 0.5.0 → 0.6.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.
@@ -70,23 +70,26 @@ class Backend {
70
70
  client.interceptors.response.use((value) => {
71
71
  return value;
72
72
  }, (err) => __awaiter(this, void 0, void 0, function* () {
73
- if (err.response &&
73
+ const originalRequest = err.config;
74
+ if (!originalRequest._retry &&
75
+ err.response &&
74
76
  ((err.response.status === 401 &&
75
77
  err.response.data.error_name === 'invalid_token') ||
76
78
  (err.response.status === 403 &&
77
79
  err.response.data.error_name === 'forbidden' &&
78
80
  auth.accessToken === null))) {
81
+ originalRequest._retry = true;
79
82
  return yield auth
80
83
  .refreshOrObtainAccessToken()
81
84
  .then(() => {
82
85
  return client.request(err.config);
83
86
  })
84
- .catch(() => {
85
- throw new Error('Failed to retrieve or refresh token');
87
+ .catch((error) => {
88
+ return Promise.reject(error);
86
89
  });
87
90
  }
88
91
  else {
89
- throw err;
92
+ return Promise.reject(err);
90
93
  }
91
94
  }));
92
95
  }
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ModelRepository = exports.Model = void 0;
13
13
  const base_1 = require("./base");
14
+ const utils_1 = require("./utils");
14
15
  /**
15
16
  * Represents a model in the assessment modeling system.
16
17
  */
@@ -120,7 +121,7 @@ class ModelRepository extends base_1.BaseFacade {
120
121
  */
121
122
  list(filter) {
122
123
  return __awaiter(this, void 0, void 0, function* () {
123
- const models = yield this.backend.models.list(filter);
124
+ const models = yield this.backend.models.list((0, utils_1.withIamcDefault)(filter));
124
125
  return models.map((model) => {
125
126
  return new Model(this.backend, model);
126
127
  });
@@ -133,7 +134,7 @@ class ModelRepository extends base_1.BaseFacade {
133
134
  */
134
135
  tabulate(filter) {
135
136
  return __awaiter(this, void 0, void 0, function* () {
136
- return this.backend.models.tabulate(filter);
137
+ return this.backend.models.tabulate((0, utils_1.withIamcDefault)(filter));
137
138
  });
138
139
  }
139
140
  }
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.RegionRepository = exports.Region = void 0;
13
13
  const base_1 = require("./base");
14
+ const utils_1 = require("./utils");
14
15
  /**
15
16
  * Represents a unit in the system.
16
17
  */
@@ -152,7 +153,7 @@ class RegionRepository extends base_1.BaseFacade {
152
153
  */
153
154
  list(filter) {
154
155
  return __awaiter(this, void 0, void 0, function* () {
155
- return this.backend.regions.list(filter).then((models) => {
156
+ return this.backend.regions.list((0, utils_1.withIamcDefault)(filter)).then((models) => {
156
157
  return models.map((model) => new Region(this.backend, model));
157
158
  });
158
159
  });
@@ -164,7 +165,7 @@ class RegionRepository extends base_1.BaseFacade {
164
165
  */
165
166
  tabulate(filter) {
166
167
  return __awaiter(this, void 0, void 0, function* () {
167
- return this.backend.regions.tabulate(filter);
168
+ return this.backend.regions.tabulate((0, utils_1.withIamcDefault)(filter));
168
169
  });
169
170
  }
170
171
  }
@@ -13,6 +13,7 @@ exports.RunRepository = exports.Run = void 0;
13
13
  const base_1 = require("./base");
14
14
  const data_1 = require("./iamc/data");
15
15
  const meta_1 = require("./meta");
16
+ const utils_1 = require("./utils");
16
17
  /**
17
18
  * Represents a Modeling Run.
18
19
  */
@@ -155,7 +156,7 @@ class RunRepository extends base_1.BaseFacade {
155
156
  if (filter.defaultOnly === undefined) {
156
157
  filter.defaultOnly = true;
157
158
  }
158
- const runs = yield this.backend.runs.list(filter);
159
+ const runs = yield this.backend.runs.list((0, utils_1.withIamcDefault)(filter));
159
160
  const runPromises = runs.map((run) => __awaiter(this, void 0, void 0, function* () {
160
161
  return new Run(this.backend, run);
161
162
  }));
@@ -172,7 +173,7 @@ class RunRepository extends base_1.BaseFacade {
172
173
  if (filter.defaultOnly === undefined) {
173
174
  filter.defaultOnly = true;
174
175
  }
175
- const df = yield this.backend.runs.tabulate(filter);
176
+ const df = yield this.backend.runs.tabulate((0, utils_1.withIamcDefault)(filter));
176
177
  const models = yield this.backend.models.list();
177
178
  const scenarios = yield this.backend.scenarios.list();
178
179
  const modelNames = df.columnValues('model__id').map((id) => {
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ScenarioRepository = exports.Scenario = void 0;
13
13
  const base_1 = require("./base");
14
+ const utils_1 = require("./utils");
14
15
  /**
15
16
  * Represents a Modeling Scenario.
16
17
  */
@@ -127,7 +128,9 @@ class ScenarioRepository extends base_1.BaseFacade {
127
128
  */
128
129
  list(filter) {
129
130
  return __awaiter(this, void 0, void 0, function* () {
130
- return this.backend.scenarios.list(filter).then((models) => {
131
+ return this.backend.scenarios
132
+ .list((0, utils_1.withIamcDefault)(filter))
133
+ .then((models) => {
131
134
  return models.map((model) => new Scenario(this.backend, model));
132
135
  });
133
136
  });
@@ -139,7 +142,7 @@ class ScenarioRepository extends base_1.BaseFacade {
139
142
  */
140
143
  tabulate(filter) {
141
144
  return __awaiter(this, void 0, void 0, function* () {
142
- return this.backend.scenarios.tabulate(filter);
145
+ return this.backend.scenarios.tabulate((0, utils_1.withIamcDefault)(filter));
143
146
  });
144
147
  }
145
148
  }
@@ -167,7 +167,7 @@ class UnitRepository extends base_1.BaseFacade {
167
167
  */
168
168
  list(filter) {
169
169
  return __awaiter(this, void 0, void 0, function* () {
170
- return this.backend.units.list(filter).then((models) => {
170
+ return this.backend.units.list((0, utils_1.withIamcDefault)(filter)).then((models) => {
171
171
  return models.map((model) => new Unit(this.backend, model));
172
172
  });
173
173
  });
@@ -179,7 +179,7 @@ class UnitRepository extends base_1.BaseFacade {
179
179
  */
180
180
  tabulate(filter) {
181
181
  return __awaiter(this, void 0, void 0, function* () {
182
- return this.backend.units.tabulate(filter);
182
+ return this.backend.units.tabulate((0, utils_1.withIamcDefault)(filter));
183
183
  });
184
184
  }
185
185
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toIamcWide = exports.dfToDimensionless = exports.unitToDimensionless = exports.substitudeType = void 0;
3
+ exports.withIamcDefault = exports.toIamcWide = exports.dfToDimensionless = exports.unitToDimensionless = exports.substitudeType = void 0;
4
4
  const dataframe_1 = require("../dataframe");
5
5
  const datapoint_1 = require("../data/iamc/datapoint");
6
6
  function substitudeType(df, type) {
@@ -111,3 +111,24 @@ exports.toIamcWide = toIamcWide;
111
111
  function getIamcRowIndex(row, rowIdentifiers) {
112
112
  return rowIdentifiers.map((i) => row[i]).join('_');
113
113
  }
114
+ /**
115
+ * Processes the filter to ensure that IAMC filter is enabled by default unless explicitly disabled.
116
+ * When enabled, only entities with associated datapoints are returned.
117
+ * @param filter The filter to process
118
+ * @returns The processed filter with IAMC default settings
119
+ */
120
+ function withIamcDefault(filter) {
121
+ if (!filter) {
122
+ return { iamc: true };
123
+ }
124
+ else if (filter.iamc === undefined) {
125
+ // If the IAMC filter is not explicitly set, default to true
126
+ filter.iamc = true;
127
+ }
128
+ else if (filter.iamc === null) {
129
+ // If the IAMC filter is explicitly set to null, leave it as is
130
+ return filter;
131
+ }
132
+ return filter;
133
+ }
134
+ exports.withIamcDefault = withIamcDefault;
@@ -118,6 +118,10 @@ class BaseRepository {
118
118
  }
119
119
  _list({ filter, params, }) {
120
120
  return __awaiter(this, void 0, void 0, function* () {
121
+ if (this.enumerationMethod === 'GET') {
122
+ params = Object.assign(Object.assign({}, params), filter);
123
+ filter = undefined;
124
+ }
121
125
  const data = yield this._requestEnumeration(params, filter, false);
122
126
  const pagination = data.pagination;
123
127
  if (pagination !== undefined) {
@@ -14,7 +14,7 @@ const base_1 = require("./base");
14
14
  class DocsRepository extends base_1.BaseRepository {
15
15
  get(dimensionId) {
16
16
  return __awaiter(this, void 0, void 0, function* () {
17
- return yield this._get({ dimension_id: dimensionId });
17
+ return yield this._get({ dimensionId });
18
18
  });
19
19
  }
20
20
  set(dimensionId, description) {
@@ -27,7 +27,7 @@ class DocsRepository extends base_1.BaseRepository {
27
27
  }
28
28
  list(dimensionId) {
29
29
  return __awaiter(this, void 0, void 0, function* () {
30
- return yield this._list({ filter: { dimension_id: dimensionId } });
30
+ return yield this._list({ filter: { dimensionId } });
31
31
  });
32
32
  }
33
33
  delete(dimensionId) {
@@ -64,23 +64,26 @@ class Backend {
64
64
  client.interceptors.response.use((value) => {
65
65
  return value;
66
66
  }, async (err) => {
67
- if (err.response &&
67
+ const originalRequest = err.config;
68
+ if (!originalRequest._retry &&
69
+ err.response &&
68
70
  ((err.response.status === 401 &&
69
71
  err.response.data.error_name === 'invalid_token') ||
70
72
  (err.response.status === 403 &&
71
73
  err.response.data.error_name === 'forbidden' &&
72
74
  auth.accessToken === null))) {
75
+ originalRequest._retry = true;
73
76
  return await auth
74
77
  .refreshOrObtainAccessToken()
75
78
  .then(() => {
76
79
  return client.request(err.config);
77
80
  })
78
- .catch(() => {
79
- throw new Error('Failed to retrieve or refresh token');
81
+ .catch((error) => {
82
+ return Promise.reject(error);
80
83
  });
81
84
  }
82
85
  else {
83
- throw err;
86
+ return Promise.reject(err);
84
87
  }
85
88
  });
86
89
  }
@@ -1,4 +1,5 @@
1
1
  import { BaseFacade, BaseModelFacade } from './base';
2
+ import { withIamcDefault } from './utils';
2
3
  /**
3
4
  * Represents a model in the assessment modeling system.
4
5
  */
@@ -96,7 +97,7 @@ class ModelRepository extends BaseFacade {
96
97
  * @returns A promise that resolves to an array of models.
97
98
  */
98
99
  async list(filter) {
99
- const models = await this.backend.models.list(filter);
100
+ const models = await this.backend.models.list(withIamcDefault(filter));
100
101
  return models.map((model) => {
101
102
  return new Model(this.backend, model);
102
103
  });
@@ -107,7 +108,7 @@ class ModelRepository extends BaseFacade {
107
108
  * @returns A promise that resolves to the tabulated result.
108
109
  */
109
110
  async tabulate(filter) {
110
- return this.backend.models.tabulate(filter);
111
+ return this.backend.models.tabulate(withIamcDefault(filter));
111
112
  }
112
113
  }
113
114
  export { Model, ModelRepository };
@@ -1,4 +1,5 @@
1
1
  import { BaseFacade, BaseModelFacade } from './base';
2
+ import { withIamcDefault } from './utils';
2
3
  /**
3
4
  * Represents a unit in the system.
4
5
  */
@@ -126,7 +127,7 @@ class RegionRepository extends BaseFacade {
126
127
  * @returns A promise that resolves to an array of regions.
127
128
  */
128
129
  async list(filter) {
129
- return this.backend.regions.list(filter).then((models) => {
130
+ return this.backend.regions.list(withIamcDefault(filter)).then((models) => {
130
131
  return models.map((model) => new Region(this.backend, model));
131
132
  });
132
133
  }
@@ -136,7 +137,7 @@ class RegionRepository extends BaseFacade {
136
137
  * @returns A promise that resolves to a DataFrame containing the tabulated regions.
137
138
  */
138
139
  async tabulate(filter) {
139
- return this.backend.regions.tabulate(filter);
140
+ return this.backend.regions.tabulate(withIamcDefault(filter));
140
141
  }
141
142
  }
142
143
  export { Region as Region, RegionRepository };
@@ -1,6 +1,7 @@
1
1
  import { BaseFacade, BaseModelFacade } from './base';
2
2
  import { RunIamcData } from './iamc/data';
3
3
  import { RunMetaIndicatorRepository } from './meta';
4
+ import { withIamcDefault } from './utils';
4
5
  /**
5
6
  * Represents a Modeling Run.
6
7
  */
@@ -135,7 +136,7 @@ class RunRepository extends BaseFacade {
135
136
  if (filter.defaultOnly === undefined) {
136
137
  filter.defaultOnly = true;
137
138
  }
138
- const runs = await this.backend.runs.list(filter);
139
+ const runs = await this.backend.runs.list(withIamcDefault(filter));
139
140
  const runPromises = runs.map(async (run) => {
140
141
  return new Run(this.backend, run);
141
142
  });
@@ -150,7 +151,7 @@ class RunRepository extends BaseFacade {
150
151
  if (filter.defaultOnly === undefined) {
151
152
  filter.defaultOnly = true;
152
153
  }
153
- const df = await this.backend.runs.tabulate(filter);
154
+ const df = await this.backend.runs.tabulate(withIamcDefault(filter));
154
155
  const models = await this.backend.models.list();
155
156
  const scenarios = await this.backend.scenarios.list();
156
157
  const modelNames = df.columnValues('model__id').map((id) => {
@@ -1,4 +1,5 @@
1
1
  import { BaseFacade, BaseModelFacade } from './base';
2
+ import { withIamcDefault } from './utils';
2
3
  /**
3
4
  * Represents a Modeling Scenario.
4
5
  */
@@ -103,7 +104,9 @@ class ScenarioRepository extends BaseFacade {
103
104
  * @returns A Promise that resolves to an array of Scenarios.
104
105
  */
105
106
  async list(filter) {
106
- return this.backend.scenarios.list(filter).then((models) => {
107
+ return this.backend.scenarios
108
+ .list(withIamcDefault(filter))
109
+ .then((models) => {
107
110
  return models.map((model) => new Scenario(this.backend, model));
108
111
  });
109
112
  }
@@ -113,7 +116,7 @@ class ScenarioRepository extends BaseFacade {
113
116
  * @returns A Promise that resolves to a DataFrame containing the tabulated data.
114
117
  */
115
118
  async tabulate(filter) {
116
- return this.backend.scenarios.tabulate(filter);
119
+ return this.backend.scenarios.tabulate(withIamcDefault(filter));
117
120
  }
118
121
  }
119
122
  export { Scenario, ScenarioRepository };
@@ -1,5 +1,5 @@
1
1
  import { BaseFacade, BaseModelFacade } from './base';
2
- import { unitToDimensionless } from './utils';
2
+ import { withIamcDefault, unitToDimensionless } from './utils';
3
3
  /**
4
4
  * Represents a unit in the system.
5
5
  */
@@ -139,7 +139,7 @@ class UnitRepository extends BaseFacade {
139
139
  * @returns A promise that resolves with an array of Unit objects.
140
140
  */
141
141
  async list(filter) {
142
- return this.backend.units.list(filter).then((models) => {
142
+ return this.backend.units.list(withIamcDefault(filter)).then((models) => {
143
143
  return models.map((model) => new Unit(this.backend, model));
144
144
  });
145
145
  }
@@ -149,7 +149,7 @@ class UnitRepository extends BaseFacade {
149
149
  * @returns A promise that resolves with a DataFrame object.
150
150
  */
151
151
  async tabulate(filter) {
152
- return this.backend.units.tabulate(filter);
152
+ return this.backend.units.tabulate(withIamcDefault(filter));
153
153
  }
154
154
  }
155
155
  export { Unit, UnitRepository };
@@ -104,4 +104,24 @@ function toIamcWide(df) {
104
104
  function getIamcRowIndex(row, rowIdentifiers) {
105
105
  return rowIdentifiers.map((i) => row[i]).join('_');
106
106
  }
107
- export { substitudeType, unitToDimensionless, dfToDimensionless, toIamcWide };
107
+ /**
108
+ * Processes the filter to ensure that IAMC filter is enabled by default unless explicitly disabled.
109
+ * When enabled, only entities with associated datapoints are returned.
110
+ * @param filter The filter to process
111
+ * @returns The processed filter with IAMC default settings
112
+ */
113
+ function withIamcDefault(filter) {
114
+ if (!filter) {
115
+ return { iamc: true };
116
+ }
117
+ else if (filter.iamc === undefined) {
118
+ // If the IAMC filter is not explicitly set, default to true
119
+ filter.iamc = true;
120
+ }
121
+ else if (filter.iamc === null) {
122
+ // If the IAMC filter is explicitly set to null, leave it as is
123
+ return filter;
124
+ }
125
+ return filter;
126
+ }
127
+ export { substitudeType, unitToDimensionless, dfToDimensionless, toIamcWide, withIamcDefault, };
@@ -91,6 +91,10 @@ class BaseRepository {
91
91
  }
92
92
  }
93
93
  async _list({ filter, params, }) {
94
+ if (this.enumerationMethod === 'GET') {
95
+ params = { ...params, ...filter };
96
+ filter = undefined;
97
+ }
94
98
  const data = await this._requestEnumeration(params, filter, false);
95
99
  const pagination = data.pagination;
96
100
  if (pagination !== undefined) {
@@ -2,7 +2,7 @@ import { BaseRepository } from './base';
2
2
  class DocsRepository extends BaseRepository {
3
3
  static enumerationMethod = 'GET';
4
4
  async get(dimensionId) {
5
- return await this._get({ dimension_id: dimensionId });
5
+ return await this._get({ dimensionId });
6
6
  }
7
7
  async set(dimensionId, description) {
8
8
  return (await this._post({
@@ -11,7 +11,7 @@ class DocsRepository extends BaseRepository {
11
11
  }));
12
12
  }
13
13
  async list(dimensionId) {
14
- return await this._list({ filter: { dimension_id: dimensionId } });
14
+ return await this._list({ filter: { dimensionId } });
15
15
  }
16
16
  async delete(dimensionId) {
17
17
  await this._delete(dimensionId);
@@ -7,6 +7,7 @@ import { VariableFilter as BaseVariableFilter } from '../data/iamc/variable';
7
7
  import { UnitFilter as BaseUnitFilter } from '../data/unit';
8
8
  import { RunFilter as BaseRunFilter } from '../data/run';
9
9
  import { ScenarioFilter as BaseScenarioFilter } from '../data/scenario';
10
+ import { DataFrame } from '../dataframe';
10
11
  /**
11
12
  * Represents a filter for listing and tabulating models.
12
13
  */
@@ -18,7 +19,7 @@ type ModelFilter = BaseModelFilter & {
18
19
  run?: BaseRunFilter & {
19
20
  scenario?: BaseScenarioFilter;
20
21
  };
21
- };
22
+ } | boolean;
22
23
  };
23
24
  /**
24
25
  * Represents a model in the assessment modeling system.
@@ -94,7 +95,7 @@ declare class ModelRepository extends BaseFacade {
94
95
  * @param filter Optional. Filter for tabulating models.
95
96
  * @returns A promise that resolves to the tabulated result.
96
97
  */
97
- tabulate(filter?: ModelFilter): Promise<any>;
98
+ tabulate(filter?: ModelFilter): Promise<DataFrame>;
98
99
  }
99
100
  export { Model, ModelRepository };
100
101
  export type { ModelFilter };
@@ -19,7 +19,7 @@ type RegionFilter = BaseRegionFilter & {
19
19
  scenario?: BaseScenarioFilter;
20
20
  model?: BaseModelFilter;
21
21
  };
22
- };
22
+ } | boolean;
23
23
  };
24
24
  /**
25
25
  * Represents a unit in the system.
@@ -22,7 +22,7 @@ type RunFilter = BaseRunFilter & {
22
22
  variable?: BaseVariableFilter;
23
23
  region?: BaseRegionFilter;
24
24
  unit?: BaseUnitFilter;
25
- };
25
+ } | boolean;
26
26
  };
27
27
  /**
28
28
  * Represents a Modeling Run.
@@ -19,7 +19,7 @@ type ScenarioFilter = BaseScenarioFilter & {
19
19
  run?: BaseRunFilter & {
20
20
  model?: BaseModelFilter;
21
21
  };
22
- };
22
+ } | boolean;
23
23
  };
24
24
  /**
25
25
  * Represents a Modeling Scenario.
@@ -19,7 +19,7 @@ type UnitFilter = BaseUnitFilter & {
19
19
  scenario?: BaseScenarioFilter;
20
20
  model?: BaseModelFilter;
21
21
  };
22
- };
22
+ } | boolean;
23
23
  };
24
24
  /**
25
25
  * Represents a unit in the system.
@@ -1,7 +1,20 @@
1
1
  import { DataFrame } from '../dataframe';
2
2
  import { DataPointType } from '../data/iamc/datapoint';
3
+ import { PlainObject } from '../data/base';
4
+ import { RunFilter } from './run';
5
+ import { ScenarioFilter } from './scenario';
6
+ import { RegionFilter } from './region';
7
+ import { UnitFilter } from './unit';
8
+ import { ModelFilter } from './model';
3
9
  declare function substitudeType(df: DataFrame, type?: DataPointType): DataFrame;
4
10
  declare function unitToDimensionless(name: string): string;
5
11
  declare function dfToDimensionless(df: DataFrame): DataFrame;
6
12
  declare function toIamcWide(df: DataFrame): DataFrame;
7
- export { substitudeType, unitToDimensionless, dfToDimensionless, toIamcWide };
13
+ /**
14
+ * Processes the filter to ensure that IAMC filter is enabled by default unless explicitly disabled.
15
+ * When enabled, only entities with associated datapoints are returned.
16
+ * @param filter The filter to process
17
+ * @returns The processed filter with IAMC default settings
18
+ */
19
+ declare function withIamcDefault(filter?: RunFilter | ScenarioFilter | ModelFilter | RegionFilter | UnitFilter): PlainObject;
20
+ export { substitudeType, unitToDimensionless, dfToDimensionless, toIamcWide, withIamcDefault, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iiasa/ixmp4-ts",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "license": "MIT",
5
5
  "description": "typescript client for ixmp4, a data warehouse for scenario analysis",
6
6
  "repository": {
@@ -91,7 +91,7 @@
91
91
  "testcontainers": "^10.3.2",
92
92
  "typedoc": "^0.25.7",
93
93
  "typescript": "^5.3.2",
94
- "vitest": "^1.4.0"
94
+ "vitest": "^3.1.2"
95
95
  },
96
96
  "dependencies": {
97
97
  "axios": "^1.6.2",