industrial-model 0.7.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.
@@ -50,7 +50,92 @@ var CogniteSdkAdapter = class {
50
50
  items: response.items
51
51
  };
52
52
  }
53
+ async retrieveDatapoints(options) {
54
+ const { items, ...rest } = options;
55
+ const sdkItems = items.map(({ space, externalId, ...itemRest }) => ({
56
+ ...itemRest,
57
+ instanceId: { space, externalId }
58
+ }));
59
+ const response = await this.client.datapoints.retrieve({
60
+ ...rest,
61
+ items: sdkItems
62
+ });
63
+ return { items: response.map(mapDatapointResult) };
64
+ }
65
+ async retrieveLatestDatapoints(items, options) {
66
+ const sdkItems = items.map(({ space, externalId, before }) => ({
67
+ instanceId: { space, externalId },
68
+ ...before !== void 0 ? { before } : {}
69
+ }));
70
+ const response = await this.client.datapoints.retrieveLatest(
71
+ sdkItems,
72
+ options
73
+ );
74
+ return { items: response.map(mapDatapointResult) };
75
+ }
76
+ async insertDatapoints(items) {
77
+ const sdkItems = items.map(({ space, externalId, datapoints }) => ({
78
+ instanceId: { space, externalId },
79
+ datapoints
80
+ }));
81
+ await this.client.datapoints.insert(
82
+ sdkItems
83
+ );
84
+ }
85
+ async deleteDatapoints(items) {
86
+ const sdkItems = items.map(({ space, externalId, inclusiveBegin, exclusiveEnd }) => ({
87
+ instanceId: { space, externalId },
88
+ inclusiveBegin,
89
+ ...exclusiveEnd !== void 0 ? { exclusiveEnd } : {}
90
+ }));
91
+ await this.client.datapoints.delete(
92
+ sdkItems
93
+ );
94
+ }
95
+ async uploadFile(fileInfo, content) {
96
+ const { instanceId, ...rest } = fileInfo;
97
+ const response = await this.client.files.upload(
98
+ { ...rest, instanceId },
99
+ content,
100
+ false,
101
+ content !== void 0
102
+ );
103
+ return mapFileResult(response);
104
+ }
105
+ async getFileDownloadUrls(ids) {
106
+ const response = await this.client.files.getDownloadUrls(
107
+ ids
108
+ );
109
+ return response.map((item) => ({
110
+ ...item.instanceId !== void 0 ? { instanceId: item.instanceId } : {},
111
+ downloadUrl: item.downloadUrl
112
+ }));
113
+ }
53
114
  };
115
+ function mapFileResult(item) {
116
+ return {
117
+ ...item.instanceId !== void 0 ? { instanceId: item.instanceId } : {},
118
+ name: item.name,
119
+ uploaded: item.uploaded,
120
+ createdTime: item.createdTime,
121
+ lastUpdatedTime: item.lastUpdatedTime,
122
+ ...item.uploadedTime !== void 0 ? { uploadedTime: item.uploadedTime } : {},
123
+ ...item.mimeType !== void 0 ? { mimeType: item.mimeType } : {},
124
+ ...item.directory !== void 0 ? { directory: item.directory } : {},
125
+ ...item.source !== void 0 ? { source: item.source } : {},
126
+ ...item.uploadUrl !== void 0 ? { uploadUrl: item.uploadUrl } : {}
127
+ };
128
+ }
129
+ function mapDatapointResult(item) {
130
+ return {
131
+ ...item.instanceId?.space !== void 0 ? { space: item.instanceId.space } : {},
132
+ ...item.instanceId?.externalId !== void 0 ? { externalId: item.instanceId.externalId } : {},
133
+ isString: item.isString ?? false,
134
+ ...item.unit !== void 0 ? { unit: item.unit } : {},
135
+ datapoints: item.datapoints ?? [],
136
+ ...item.nextCursor !== void 0 ? { nextCursor: item.nextCursor } : {}
137
+ };
138
+ }
54
139
 
55
140
  // src/constants.ts
56
141
  var NESTED_SEP = "|";
@@ -61,6 +146,15 @@ var MAX_DEPENDENCY_DEPTH = 3;
61
146
  var AGGREGATE_LIMIT = 1e3;
62
147
  var MAX_GROUP_BY = 5;
63
148
 
149
+ // src/utils/array.ts
150
+ function chunks(items, size) {
151
+ const result = [];
152
+ for (let index = 0; index < items.length; index += size) {
153
+ result.push(items.slice(index, index + size));
154
+ }
155
+ return result;
156
+ }
157
+
64
158
  // src/utils/query.ts
65
159
  function mapNodesAndEdges(queryResult, _query) {
66
160
  return queryResult.items;
@@ -717,6 +811,63 @@ ${errors.map((error) => `- ${error}`).join("\n")}`
717
811
  return [];
718
812
  }
719
813
  };
814
+ var dateSchema2 = zod.z.date();
815
+ var nodeIdSchema2 = zod.z.object({ space: zod.z.string(), externalId: zod.z.string() }).loose();
816
+ var retrieveOptionsSchema = zod.z.object({
817
+ timeSeries: zod.z.array(nodeIdSchema2),
818
+ start: dateSchema2.optional(),
819
+ end: dateSchema2.optional()
820
+ }).loose();
821
+ var deleteRangeSchema = zod.z.object({
822
+ timeSeries: zod.z.object({ space: zod.z.string(), externalId: zod.z.string() }).loose(),
823
+ start: dateSchema2,
824
+ end: dateSchema2.optional()
825
+ }).loose();
826
+ function formatIssues(error, prefix) {
827
+ return error.issues.map((issue) => {
828
+ const parts = prefix ? [prefix, ...issue.path] : [...issue.path];
829
+ return `${parts.map(String).join(".")}: ${issue.message}`;
830
+ });
831
+ }
832
+ var DatapointsValidator = class {
833
+ validateRetrieve(options) {
834
+ const result = retrieveOptionsSchema.safeParse(options);
835
+ if (!result.success) {
836
+ const messages = formatIssues(result.error);
837
+ throw new Error(`Invalid datapoints options:
838
+ - ${messages.join("\n- ")}`);
839
+ }
840
+ }
841
+ validateDelete(ranges) {
842
+ const result = zod.z.array(deleteRangeSchema).safeParse(ranges);
843
+ if (!result.success) {
844
+ const messages = formatIssues(result.error, "ranges");
845
+ throw new Error(`Invalid datapoints options:
846
+ - ${messages.join("\n- ")}`);
847
+ }
848
+ }
849
+ };
850
+ var nodeIdSchema3 = zod.z.object({
851
+ space: zod.z.string().min(1),
852
+ externalId: zod.z.string().min(1)
853
+ }).loose();
854
+ var deleteItemsSchema = zod.z.array(nodeIdSchema3);
855
+ function formatIssues2(error, prefix) {
856
+ return error.issues.map((issue) => {
857
+ const parts = [prefix, ...issue.path];
858
+ return `${parts.map(String).join(".")}: ${issue.message}`;
859
+ });
860
+ }
861
+ var DeleteValidator = class {
862
+ validateItems(items) {
863
+ const result = deleteItemsSchema.safeParse(items);
864
+ if (!result.success) {
865
+ const messages = formatIssues2(result.error, "items");
866
+ throw new Error(`Invalid delete options:
867
+ - ${messages.join("\n- ")}`);
868
+ }
869
+ }
870
+ };
720
871
  var nodeMetadataSchema = {
721
872
  instanceType: zod.z.literal("node").optional(),
722
873
  space: zod.z.string(),
@@ -1120,6 +1271,178 @@ var AggregateResultMapper = class {
1120
1271
  }
1121
1272
  };
1122
1273
 
1274
+ // src/mappers/datapoints-mapper.ts
1275
+ var CHUNK_SIZE = 100;
1276
+ var DatapointsMapper = class {
1277
+ constructor(cognite) {
1278
+ this.cognite = cognite;
1279
+ this.validator = new DatapointsValidator();
1280
+ }
1281
+ async retrieve(options) {
1282
+ this.validator.validateRetrieve(options);
1283
+ const cogniteOptions = this.toCogniteOptions(options);
1284
+ const allPages = options.limit === -1;
1285
+ if (!allPages) {
1286
+ const result = await this.cognite.retrieveDatapoints(cogniteOptions);
1287
+ return this.mapResult(result.items, cogniteOptions.items, options.aggregate);
1288
+ }
1289
+ const accumulated = /* @__PURE__ */ new Map();
1290
+ const itemByKey = new Map(cogniteOptions.items.map((item) => [this.toKey(item), item]));
1291
+ let currentItems = cogniteOptions.items;
1292
+ while (currentItems.length > 0) {
1293
+ const result = await this.cognite.retrieveDatapoints({
1294
+ ...cogniteOptions,
1295
+ items: currentItems
1296
+ });
1297
+ const nextItems = [];
1298
+ for (const resultItem of result.items) {
1299
+ const key = this.toKey(resultItem);
1300
+ let acc = accumulated.get(key);
1301
+ if (!acc) {
1302
+ acc = { ...resultItem, datapoints: [] };
1303
+ accumulated.set(key, acc);
1304
+ }
1305
+ acc.datapoints.push(...resultItem.datapoints);
1306
+ if (resultItem.nextCursor) {
1307
+ acc.nextCursor = resultItem.nextCursor;
1308
+ } else {
1309
+ delete acc.nextCursor;
1310
+ }
1311
+ if (resultItem.nextCursor) {
1312
+ const original = itemByKey.get(key);
1313
+ nextItems.push({
1314
+ ...original,
1315
+ space: resultItem.space ?? original?.space ?? "",
1316
+ externalId: resultItem.externalId ?? original?.externalId ?? "",
1317
+ cursor: resultItem.nextCursor
1318
+ });
1319
+ }
1320
+ }
1321
+ currentItems = nextItems;
1322
+ }
1323
+ return this.mapResult(
1324
+ Array.from(accumulated.values()),
1325
+ cogniteOptions.items,
1326
+ options.aggregate
1327
+ );
1328
+ }
1329
+ async retrieveLatest(options) {
1330
+ const items = options.timeSeries.map(
1331
+ ({ space, externalId, before }) => ({
1332
+ space,
1333
+ externalId,
1334
+ ...before !== void 0 ? { before } : {}
1335
+ })
1336
+ );
1337
+ const latestOptions = options.ignoreUnknownIds !== void 0 ? { ignoreUnknownIds: options.ignoreUnknownIds } : void 0;
1338
+ const result = await this.cognite.retrieveLatestDatapoints(items, latestOptions);
1339
+ return this.mapResult(result.items, items);
1340
+ }
1341
+ async insert(items) {
1342
+ const cogniteItems = items.map(({ timeSeries, datapoints }) => ({
1343
+ space: timeSeries.space,
1344
+ externalId: timeSeries.externalId,
1345
+ datapoints
1346
+ }));
1347
+ for (const chunk of chunks(cogniteItems, CHUNK_SIZE)) {
1348
+ await this.cognite.insertDatapoints(chunk);
1349
+ }
1350
+ }
1351
+ async delete(ranges) {
1352
+ this.validator.validateDelete(ranges);
1353
+ const cogniteItems = ranges.map(({ timeSeries, start, end }) => ({
1354
+ space: timeSeries.space,
1355
+ externalId: timeSeries.externalId,
1356
+ inclusiveBegin: start,
1357
+ ...end !== void 0 ? { exclusiveEnd: end } : {}
1358
+ }));
1359
+ for (const chunk of chunks(cogniteItems, CHUNK_SIZE)) {
1360
+ await this.cognite.deleteDatapoints(chunk);
1361
+ }
1362
+ }
1363
+ toKey(item) {
1364
+ return `${item.space ?? ""}:${item.externalId ?? ""}`;
1365
+ }
1366
+ toCogniteOptions(options) {
1367
+ const { timeSeries, aggregate, ...rest } = options;
1368
+ return {
1369
+ ...rest,
1370
+ ...aggregate !== void 0 ? { aggregates: [aggregate] } : {},
1371
+ items: timeSeries.map(({ space, externalId }) => ({ space, externalId }))
1372
+ };
1373
+ }
1374
+ mapResult(items, requestedItems, aggregate) {
1375
+ const requestedByKey = new Map(requestedItems.map((item) => [this.toKey(item), item]));
1376
+ const mappedItems = items.filter((item) => !item.isString).map((item) => {
1377
+ const requested = requestedByKey.get(this.toKey(item));
1378
+ const datapoints = aggregate !== void 0 ? item.datapoints.map((dp) => ({
1379
+ timestamp: dp.timestamp,
1380
+ value: dp[aggregate] ?? 0
1381
+ })) : item.datapoints;
1382
+ return {
1383
+ timeSeries: {
1384
+ space: item.space ?? requested?.space ?? "",
1385
+ externalId: item.externalId ?? requested?.externalId ?? ""
1386
+ },
1387
+ ...item.unit !== void 0 ? { unit: item.unit } : {},
1388
+ datapoints,
1389
+ cursor: item.nextCursor ?? null
1390
+ };
1391
+ });
1392
+ return { items: mappedItems };
1393
+ }
1394
+ };
1395
+
1396
+ // src/mappers/files-mapper.ts
1397
+ var FilesMapper = class {
1398
+ constructor(cognite) {
1399
+ this.cognite = cognite;
1400
+ }
1401
+ async upload(fileInfo, content) {
1402
+ const { space, externalId, ...rest } = fileInfo;
1403
+ const result = await this.cognite.uploadFile(
1404
+ { instanceId: { space, externalId }, ...rest },
1405
+ content
1406
+ );
1407
+ return this.mapUploadResult(result, { space, externalId });
1408
+ }
1409
+ async getDownloadUrls(nodeIds) {
1410
+ if (nodeIds.length === 0) return [];
1411
+ const ids = nodeIds.map(({ space, externalId }) => ({ instanceId: { space, externalId } }));
1412
+ const result = await this.cognite.getFileDownloadUrls(ids);
1413
+ return result.map(
1414
+ (item, i) => this.mapDownloadUrl(item, nodeIds[i] ?? { space: "", externalId: "" })
1415
+ );
1416
+ }
1417
+ toNodeId(item, fallback) {
1418
+ return {
1419
+ space: item.instanceId?.space ?? fallback.space,
1420
+ externalId: item.instanceId?.externalId ?? fallback.externalId
1421
+ };
1422
+ }
1423
+ mapUploadResult(item, fallback) {
1424
+ const nodeId = this.toNodeId(item, fallback);
1425
+ return {
1426
+ ...nodeId,
1427
+ name: item.name,
1428
+ uploaded: item.uploaded,
1429
+ createdTime: item.createdTime,
1430
+ lastUpdatedTime: item.lastUpdatedTime,
1431
+ ...item.uploadedTime !== void 0 ? { uploadedTime: item.uploadedTime } : {},
1432
+ ...item.mimeType !== void 0 ? { mimeType: item.mimeType } : {},
1433
+ ...item.directory !== void 0 ? { directory: item.directory } : {},
1434
+ ...item.source !== void 0 ? { source: item.source } : {},
1435
+ ...item.uploadUrl !== void 0 ? { uploadUrl: item.uploadUrl } : {}
1436
+ };
1437
+ }
1438
+ mapDownloadUrl(item, fallback) {
1439
+ return {
1440
+ ...this.toNodeId(item, fallback),
1441
+ downloadUrl: item.downloadUrl
1442
+ };
1443
+ }
1444
+ };
1445
+
1123
1446
  // src/mappers/sort-mapper.ts
1124
1447
  var SortMapper = class {
1125
1448
  map(sort, rootView) {
@@ -1676,6 +1999,10 @@ var ViewMapper = class {
1676
1999
  }
1677
2000
  return view;
1678
2001
  }
2002
+ async getViews() {
2003
+ const views = await this.loadViews();
2004
+ return Array.from(views.values());
2005
+ }
1679
2006
  loadViews() {
1680
2007
  if (this.cachePromise == null) {
1681
2008
  this.cachePromise = this.fetchViews();
@@ -1709,6 +2036,17 @@ var ViewMapper = class {
1709
2036
  var APPLY_ITEM_LIMIT = 1e3;
1710
2037
  var IndustrialModelClient = class {
1711
2038
  constructor(client, dataModelId, options = {}) {
2039
+ this.deleteValidator = new DeleteValidator();
2040
+ this.files = {
2041
+ upload: (fileInfo, content) => this.filesMapper.upload(fileInfo, content),
2042
+ getDownloadUrls: (nodeIds) => this.filesMapper.getDownloadUrls(nodeIds)
2043
+ };
2044
+ this.datapoints = {
2045
+ retrieve: (options) => this.datapointsMapper.retrieve(options),
2046
+ latest: (options) => this.datapointsMapper.retrieveLatest(options),
2047
+ insert: (items) => this.datapointsMapper.insert(items),
2048
+ delete: (ranges) => this.datapointsMapper.delete(ranges)
2049
+ };
1712
2050
  const cognite = createCogniteAdapter(client);
1713
2051
  this.cognite = cognite;
1714
2052
  const viewMapper = new ViewMapper(cognite, dataModelId);
@@ -1717,6 +2055,8 @@ var IndustrialModelClient = class {
1717
2055
  this.upsertMapper = new UpsertMapper(viewMapper, cognite);
1718
2056
  this.aggregateResultMapper = new AggregateResultMapper();
1719
2057
  this.resultMapper = new QueryResultMapper(viewMapper);
2058
+ this.datapointsMapper = new DatapointsMapper(cognite);
2059
+ this.filesMapper = new FilesMapper(cognite);
1720
2060
  this.resultValidator = new QueryResultValidator(viewMapper);
1721
2061
  this.validateResults = options.validateResults ?? false;
1722
2062
  }
@@ -1733,14 +2073,12 @@ var IndustrialModelClient = class {
1733
2073
  return execute;
1734
2074
  }
1735
2075
  async delete(items) {
1736
- const deleteItems = items.map((item) => {
1737
- assertNodeId2(item);
1738
- return {
1739
- instanceType: "node",
1740
- space: item.space,
1741
- externalId: item.externalId
1742
- };
1743
- });
2076
+ this.deleteValidator.validateItems(items);
2077
+ const deleteItems = items.map((item) => ({
2078
+ instanceType: "node",
2079
+ space: item.space,
2080
+ externalId: item.externalId
2081
+ }));
1744
2082
  const response = await this.applyInstancesInChunks({
1745
2083
  items: [],
1746
2084
  delete: deleteItems
@@ -1832,18 +2170,6 @@ var IndustrialModelClient = class {
1832
2170
  return appendNodesAndEdges(result, nestedResults);
1833
2171
  }
1834
2172
  };
1835
- function chunks(items, size) {
1836
- const result = [];
1837
- for (let index = 0; index < items.length; index += size) {
1838
- result.push(items.slice(index, index + size));
1839
- }
1840
- return result;
1841
- }
1842
- function assertNodeId2(value) {
1843
- if (value == null || typeof value !== "object" || Array.isArray(value) || typeof value.space !== "string" || value.space?.length === 0 || typeof value.externalId !== "string" || value.externalId?.length === 0) {
1844
- throw new Error("Invalid delete options:\n- items: expected NodeId values");
1845
- }
1846
- }
1847
2173
 
1848
2174
  // src/cognite-core/client.ts
1849
2175
  var COGNITE_CORE_DATA_MODEL = {
@@ -1874,6 +2200,9 @@ var CogniteCoreClient = class {
1874
2200
  delete(items) {
1875
2201
  return this.model.delete(items);
1876
2202
  }
2203
+ get datapoints() {
2204
+ return this.model.datapoints;
2205
+ }
1877
2206
  };
1878
2207
 
1879
2208
  exports.COGNITE_CORE_DATA_MODEL = COGNITE_CORE_DATA_MODEL;