industrial-model 0.7.0 → 0.8.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.
@@ -17,9 +17,9 @@ type DataModelId = NodeId & {
17
17
  version: string;
18
18
  };
19
19
  type SortDirection = "ascending" | "descending";
20
- interface IndustrialModelClientOptions {
20
+ type IndustrialModelClientOptions = {
21
21
  validateResults?: boolean;
22
- }
22
+ };
23
23
  type Simplify<T> = {
24
24
  [K in keyof T]: T[K];
25
25
  } & {};
@@ -55,14 +55,14 @@ type QuerySelect<TModel, TDepth extends QueryDepth = 3> = {
55
55
  type SortInput<TModel> = {
56
56
  [K in keyof ModelProps<TModel> as NonNull<ModelProps<TModel>[K]> extends string | number | boolean | Date | NodeId ? K : never]?: SortDirection;
57
57
  };
58
- interface QueryOptions<TModel, TSelect extends QuerySelect<TModel> | undefined = QuerySelect<TModel> | undefined> {
58
+ type QueryOptions<TModel, TSelect extends QuerySelect<TModel> | undefined = QuerySelect<TModel> | undefined> = {
59
59
  viewExternalId: string;
60
60
  select?: TSelect;
61
61
  filters?: WhereInput<TModel>;
62
62
  sort?: SortInput<TModel>;
63
63
  limit?: number;
64
64
  cursor?: string | null;
65
- }
65
+ };
66
66
  type QueryResultMetadata = Pick<NodeDefinition, "space" | "externalId" | "version" | "createdTime" | "deletedTime" | "lastUpdatedTime">;
67
67
  type ResultShapeForKey<TModel, K extends PropertyKey> = K extends keyof ModelProps<TModel> ? ModelProps<TModel>[K] : K extends RelationKeys<TModel> ? ModelRelations<TModel>[K] : never;
68
68
  type ResultEntityForKey<TModel, K extends PropertyKey> = K extends RelationKeys<TModel> ? ModelRelations<TModel>[K] : K extends keyof ModelProps<TModel> ? ModelProps<TModel>[K] : never;
@@ -77,10 +77,10 @@ type ExplicitSelectionResult<TModel, TSelect, TDepth extends QueryDepth> = Simpl
77
77
  type QueryResultItem<TModel, TSelect extends QuerySelect<TModel> | undefined = undefined, TDepth extends QueryDepth = 3> = [TSelect] extends [undefined] ? Merge<QueryResultMetadata, ModelProps<TModel>> : Merge<TSelect extends {
78
78
  _all: true;
79
79
  } ? Merge<QueryResultMetadata, ModelProps<TModel>> : QueryResultMetadata, ExplicitSelectionResult<TModel, TSelect, TDepth>>;
80
- interface QueryResult<TItem = Record<string, unknown>> {
80
+ type QueryResult<TItem = Record<string, unknown>> = {
81
81
  items: TItem[];
82
82
  cursor: string | null;
83
- }
83
+ };
84
84
  type QueryExecutor<TModel> = {
85
85
  <const TSelect extends QuerySelect<TModel>>(options: Omit<QueryOptions<TModel, TSelect>, "select"> & {
86
86
  select: TSelect & QuerySelect<TModel>;
@@ -143,19 +143,19 @@ type AggregateValue<TDef> = TDef extends {
143
143
  property: P;
144
144
  value: number;
145
145
  } : never;
146
- interface AggregateOptions<TModel> {
146
+ type AggregateOptions<TModel> = {
147
147
  viewExternalId: string;
148
148
  filters?: WhereInput<TModel>;
149
149
  groupBy?: AggregateGroupBy<TModel>;
150
150
  aggregate?: AggregateDefinition<TModel>;
151
- }
151
+ };
152
152
  type AggregateResultItem<TModel, TGroupBy extends AggregateGroupBy<TModel> | undefined = undefined, TAggregate extends AggregateDefinition<TModel> | undefined = undefined> = {
153
153
  group?: GroupValues<TModel, TGroupBy>;
154
154
  aggregate?: AggregateValue<TAggregate>;
155
155
  };
156
- interface AggregateResult<TItem = Record<string, unknown>> {
156
+ type AggregateResult<TItem = Record<string, unknown>> = {
157
157
  items: TItem[];
158
- }
158
+ };
159
159
  type AggregateExecutor<TModel> = <const TOptions extends AggregateOptions<TModel>>(options: TOptions) => Promise<AggregateResult<AggregateResultItem<TModel, TOptions["groupBy"], TOptions["aggregate"]>>>;
160
160
  type RelationReferenceValue<T> = [NonNull<T>] extends [readonly unknown[]] ? NodeId[] : NodeId;
161
161
  type NodeIdLike = {
@@ -172,22 +172,22 @@ type UpsertProperties<TModel> = Simplify<Partial<ModelProps<TModel>> & {
172
172
  [K in RelationKeys<TModel>]?: RelationReferenceValue<ModelRelations<TModel>[K]>;
173
173
  }>;
174
174
  type UpsertNode<TModel> = Simplify<NodeId & Partial<Omit<UpsertProperties<TModel>, keyof NodeId>>>;
175
- interface EdgeCreationContext {
175
+ type EdgeCreationContext = {
176
176
  startNode: NodeId;
177
177
  endNode: NodeId;
178
178
  edgeType: NodeId;
179
- }
179
+ };
180
180
  type EdgeCreationCallback = (context: EdgeCreationContext) => NodeId;
181
181
  type EdgeCreationCallbacks<TProperty extends string = string> = Partial<Record<TProperty, EdgeCreationCallback>>;
182
182
  type OnEdgeCreation<TModel> = EdgeCreationCallbacks<Extract<ArrayReferencePropertyKeys<TModel> | ArrayRelationKeys<TModel>, string>>;
183
183
  type EdgeMode = "append" | "replace";
184
- interface UpsertOptions<TModel> {
184
+ type UpsertOptions<TModel> = {
185
185
  viewExternalId: string;
186
186
  items: UpsertNode<TModel>[];
187
187
  onEdgeCreation?: OnEdgeCreation<TModel>;
188
188
  replace?: boolean;
189
189
  edgeMode?: EdgeMode;
190
- }
190
+ };
191
191
  type UpsertResultItem = {
192
192
  instanceType: "node" | "edge";
193
193
  version?: number;
@@ -197,17 +197,93 @@ type UpsertResultItem = {
197
197
  createdTime?: number;
198
198
  lastUpdatedTime?: number;
199
199
  };
200
- interface UpsertResult {
200
+ type UpsertResult = {
201
201
  items: UpsertResultItem[];
202
- }
202
+ };
203
203
  type UpsertExecutor<TModel> = (options: UpsertOptions<TModel>) => Promise<UpsertResult>;
204
204
  type DeleteResultItem = Omit<UpsertResultItem, "instanceType"> & {
205
205
  instanceType: "node";
206
206
  };
207
- interface DeleteResult {
207
+ type DeleteResult = {
208
208
  items: DeleteResultItem[];
209
- }
209
+ };
210
210
  type DeleteExecutor = <TItem extends NodeId>(items: TItem[]) => Promise<DeleteResult>;
211
+ type DatapointAggregate = "average" | "max" | "min" | "count" | "sum" | "interpolation" | "stepInterpolation" | "totalVariation" | "continuousVariance" | "discreteVariance";
212
+ type RawDatapoint = {
213
+ timestamp: Date;
214
+ value: number;
215
+ };
216
+ type DatapointSeriesResult = {
217
+ timeSeries: NodeId;
218
+ unit?: string;
219
+ datapoints: RawDatapoint[];
220
+ cursor: string | null;
221
+ };
222
+ type DatapointsResult = {
223
+ items: DatapointSeriesResult[];
224
+ };
225
+ type DatapointsRetrieveOptions = {
226
+ timeSeries: NodeId[];
227
+ start?: Date;
228
+ end?: Date;
229
+ /** Number of datapoints to return per time series, or -1 to auto-paginate all pages. */
230
+ limit?: number;
231
+ aggregate?: DatapointAggregate;
232
+ granularity?: string;
233
+ includeOutsidePoints?: boolean;
234
+ ignoreUnknownIds?: boolean;
235
+ timeZone?: string;
236
+ };
237
+ type DatapointsLatestSeries = NodeId & {
238
+ before?: Date;
239
+ };
240
+ type DatapointsLatestOptions = {
241
+ timeSeries: DatapointsLatestSeries[];
242
+ ignoreUnknownIds?: boolean;
243
+ };
244
+ type DatapointsInsertItem = {
245
+ timeSeries: NodeId;
246
+ datapoints: Array<{
247
+ timestamp: Date;
248
+ value: number;
249
+ }>;
250
+ };
251
+ type DatapointsDeleteRange = {
252
+ timeSeries: NodeId;
253
+ start: Date;
254
+ end?: Date;
255
+ };
256
+ type DatapointsExecutor = {
257
+ retrieve(options: DatapointsRetrieveOptions): Promise<DatapointsResult>;
258
+ latest(options: DatapointsLatestOptions): Promise<DatapointsResult>;
259
+ insert(items: DatapointsInsertItem[]): Promise<void>;
260
+ delete(ranges: DatapointsDeleteRange[]): Promise<void>;
261
+ };
262
+ type FileUploadInfo = NodeId & {
263
+ name: string;
264
+ mimeType?: string;
265
+ directory?: string;
266
+ source?: string;
267
+ metadata?: Record<string, string>;
268
+ };
269
+ type FileUploadResult = NodeId & {
270
+ name: string;
271
+ uploaded: boolean;
272
+ mimeType?: string;
273
+ directory?: string;
274
+ source?: string;
275
+ uploadedTime?: Date;
276
+ createdTime: Date;
277
+ lastUpdatedTime: Date;
278
+ uploadUrl?: string;
279
+ };
280
+ type FileDownloadUrl = NodeId & {
281
+ downloadUrl: string;
282
+ };
283
+ type FilesExecutor = {
284
+ upload(fileInfo: FileUploadInfo, content?: unknown): Promise<FileUploadResult>;
285
+ getDownloadUrls(nodeIds: NodeId[]): Promise<FileDownloadUrl[]>;
286
+ };
211
287
  type SearchFilter = {
212
288
  query: string;
213
289
  operator?: "OR" | "AND";
@@ -264,4 +340,4 @@ type WhereInput<TModel> = {
264
340
  [K in keyof ModelProps<TModel> | RelationKeys<TModel>]?: QueryFilterValue<TModel, K>;
265
341
  };
266
342
 
267
- export type { AggregateExecutor as A, DataModelId as D, EdgeCreationCallback as E, IndustrialModelClientOptions as I, ModelProps as M, NodeId as N, OnEdgeCreation as O, QueryExecutor as Q, UpsertExecutor as U, DeleteResult as a, AggregateResult as b, AggregateResultItem as c, DeleteExecutor as d, DeleteResultItem as e, EdgeCreationCallbacks as f, EdgeCreationContext as g, EdgeMode as h, IndustrialModel as i, ModelRelations as j, QueryResult as k, QueryResultItem as l, QuerySelect as m, UpsertNode as n, UpsertOptions as o, UpsertProperties as p, UpsertResult as q, UpsertResultItem as r, AggregateOptions as s, QueryOptions as t };
343
+ export type { AggregateExecutor as A, UpsertOptions as B, UpsertProperties as C, DataModelId as D, EdgeCreationCallback as E, FilesExecutor as F, UpsertResult as G, UpsertResultItem as H, IndustrialModelClientOptions as I, AggregateOptions as J, QueryOptions as K, ModelProps as M, NodeId as N, OnEdgeCreation as O, QueryExecutor as Q, RawDatapoint as R, UpsertExecutor as U, DatapointsExecutor as a, DeleteResult as b, AggregateResult as c, AggregateResultItem as d, DatapointAggregate as e, DatapointSeriesResult as f, DatapointsDeleteRange as g, DatapointsInsertItem as h, DatapointsLatestOptions as i, DatapointsLatestSeries as j, DatapointsResult as k, DatapointsRetrieveOptions as l, DeleteExecutor as m, DeleteResultItem as n, EdgeCreationCallbacks as o, EdgeCreationContext as p, EdgeMode as q, FileDownloadUrl as r, FileUploadInfo as s, FileUploadResult as t, IndustrialModel as u, ModelRelations as v, QueryResult as w, QueryResultItem as x, QuerySelect as y, UpsertNode as z };
@@ -17,9 +17,9 @@ type DataModelId = NodeId & {
17
17
  version: string;
18
18
  };
19
19
  type SortDirection = "ascending" | "descending";
20
- interface IndustrialModelClientOptions {
20
+ type IndustrialModelClientOptions = {
21
21
  validateResults?: boolean;
22
- }
22
+ };
23
23
  type Simplify<T> = {
24
24
  [K in keyof T]: T[K];
25
25
  } & {};
@@ -55,14 +55,14 @@ type QuerySelect<TModel, TDepth extends QueryDepth = 3> = {
55
55
  type SortInput<TModel> = {
56
56
  [K in keyof ModelProps<TModel> as NonNull<ModelProps<TModel>[K]> extends string | number | boolean | Date | NodeId ? K : never]?: SortDirection;
57
57
  };
58
- interface QueryOptions<TModel, TSelect extends QuerySelect<TModel> | undefined = QuerySelect<TModel> | undefined> {
58
+ type QueryOptions<TModel, TSelect extends QuerySelect<TModel> | undefined = QuerySelect<TModel> | undefined> = {
59
59
  viewExternalId: string;
60
60
  select?: TSelect;
61
61
  filters?: WhereInput<TModel>;
62
62
  sort?: SortInput<TModel>;
63
63
  limit?: number;
64
64
  cursor?: string | null;
65
- }
65
+ };
66
66
  type QueryResultMetadata = Pick<NodeDefinition, "space" | "externalId" | "version" | "createdTime" | "deletedTime" | "lastUpdatedTime">;
67
67
  type ResultShapeForKey<TModel, K extends PropertyKey> = K extends keyof ModelProps<TModel> ? ModelProps<TModel>[K] : K extends RelationKeys<TModel> ? ModelRelations<TModel>[K] : never;
68
68
  type ResultEntityForKey<TModel, K extends PropertyKey> = K extends RelationKeys<TModel> ? ModelRelations<TModel>[K] : K extends keyof ModelProps<TModel> ? ModelProps<TModel>[K] : never;
@@ -77,10 +77,10 @@ type ExplicitSelectionResult<TModel, TSelect, TDepth extends QueryDepth> = Simpl
77
77
  type QueryResultItem<TModel, TSelect extends QuerySelect<TModel> | undefined = undefined, TDepth extends QueryDepth = 3> = [TSelect] extends [undefined] ? Merge<QueryResultMetadata, ModelProps<TModel>> : Merge<TSelect extends {
78
78
  _all: true;
79
79
  } ? Merge<QueryResultMetadata, ModelProps<TModel>> : QueryResultMetadata, ExplicitSelectionResult<TModel, TSelect, TDepth>>;
80
- interface QueryResult<TItem = Record<string, unknown>> {
80
+ type QueryResult<TItem = Record<string, unknown>> = {
81
81
  items: TItem[];
82
82
  cursor: string | null;
83
- }
83
+ };
84
84
  type QueryExecutor<TModel> = {
85
85
  <const TSelect extends QuerySelect<TModel>>(options: Omit<QueryOptions<TModel, TSelect>, "select"> & {
86
86
  select: TSelect & QuerySelect<TModel>;
@@ -143,19 +143,19 @@ type AggregateValue<TDef> = TDef extends {
143
143
  property: P;
144
144
  value: number;
145
145
  } : never;
146
- interface AggregateOptions<TModel> {
146
+ type AggregateOptions<TModel> = {
147
147
  viewExternalId: string;
148
148
  filters?: WhereInput<TModel>;
149
149
  groupBy?: AggregateGroupBy<TModel>;
150
150
  aggregate?: AggregateDefinition<TModel>;
151
- }
151
+ };
152
152
  type AggregateResultItem<TModel, TGroupBy extends AggregateGroupBy<TModel> | undefined = undefined, TAggregate extends AggregateDefinition<TModel> | undefined = undefined> = {
153
153
  group?: GroupValues<TModel, TGroupBy>;
154
154
  aggregate?: AggregateValue<TAggregate>;
155
155
  };
156
- interface AggregateResult<TItem = Record<string, unknown>> {
156
+ type AggregateResult<TItem = Record<string, unknown>> = {
157
157
  items: TItem[];
158
- }
158
+ };
159
159
  type AggregateExecutor<TModel> = <const TOptions extends AggregateOptions<TModel>>(options: TOptions) => Promise<AggregateResult<AggregateResultItem<TModel, TOptions["groupBy"], TOptions["aggregate"]>>>;
160
160
  type RelationReferenceValue<T> = [NonNull<T>] extends [readonly unknown[]] ? NodeId[] : NodeId;
161
161
  type NodeIdLike = {
@@ -172,22 +172,22 @@ type UpsertProperties<TModel> = Simplify<Partial<ModelProps<TModel>> & {
172
172
  [K in RelationKeys<TModel>]?: RelationReferenceValue<ModelRelations<TModel>[K]>;
173
173
  }>;
174
174
  type UpsertNode<TModel> = Simplify<NodeId & Partial<Omit<UpsertProperties<TModel>, keyof NodeId>>>;
175
- interface EdgeCreationContext {
175
+ type EdgeCreationContext = {
176
176
  startNode: NodeId;
177
177
  endNode: NodeId;
178
178
  edgeType: NodeId;
179
- }
179
+ };
180
180
  type EdgeCreationCallback = (context: EdgeCreationContext) => NodeId;
181
181
  type EdgeCreationCallbacks<TProperty extends string = string> = Partial<Record<TProperty, EdgeCreationCallback>>;
182
182
  type OnEdgeCreation<TModel> = EdgeCreationCallbacks<Extract<ArrayReferencePropertyKeys<TModel> | ArrayRelationKeys<TModel>, string>>;
183
183
  type EdgeMode = "append" | "replace";
184
- interface UpsertOptions<TModel> {
184
+ type UpsertOptions<TModel> = {
185
185
  viewExternalId: string;
186
186
  items: UpsertNode<TModel>[];
187
187
  onEdgeCreation?: OnEdgeCreation<TModel>;
188
188
  replace?: boolean;
189
189
  edgeMode?: EdgeMode;
190
- }
190
+ };
191
191
  type UpsertResultItem = {
192
192
  instanceType: "node" | "edge";
193
193
  version?: number;
@@ -197,17 +197,93 @@ type UpsertResultItem = {
197
197
  createdTime?: number;
198
198
  lastUpdatedTime?: number;
199
199
  };
200
- interface UpsertResult {
200
+ type UpsertResult = {
201
201
  items: UpsertResultItem[];
202
- }
202
+ };
203
203
  type UpsertExecutor<TModel> = (options: UpsertOptions<TModel>) => Promise<UpsertResult>;
204
204
  type DeleteResultItem = Omit<UpsertResultItem, "instanceType"> & {
205
205
  instanceType: "node";
206
206
  };
207
- interface DeleteResult {
207
+ type DeleteResult = {
208
208
  items: DeleteResultItem[];
209
- }
209
+ };
210
210
  type DeleteExecutor = <TItem extends NodeId>(items: TItem[]) => Promise<DeleteResult>;
211
+ type DatapointAggregate = "average" | "max" | "min" | "count" | "sum" | "interpolation" | "stepInterpolation" | "totalVariation" | "continuousVariance" | "discreteVariance";
212
+ type RawDatapoint = {
213
+ timestamp: Date;
214
+ value: number;
215
+ };
216
+ type DatapointSeriesResult = {
217
+ timeSeries: NodeId;
218
+ unit?: string;
219
+ datapoints: RawDatapoint[];
220
+ cursor: string | null;
221
+ };
222
+ type DatapointsResult = {
223
+ items: DatapointSeriesResult[];
224
+ };
225
+ type DatapointsRetrieveOptions = {
226
+ timeSeries: NodeId[];
227
+ start?: Date;
228
+ end?: Date;
229
+ /** Number of datapoints to return per time series, or -1 to auto-paginate all pages. */
230
+ limit?: number;
231
+ aggregate?: DatapointAggregate;
232
+ granularity?: string;
233
+ includeOutsidePoints?: boolean;
234
+ ignoreUnknownIds?: boolean;
235
+ timeZone?: string;
236
+ };
237
+ type DatapointsLatestSeries = NodeId & {
238
+ before?: Date;
239
+ };
240
+ type DatapointsLatestOptions = {
241
+ timeSeries: DatapointsLatestSeries[];
242
+ ignoreUnknownIds?: boolean;
243
+ };
244
+ type DatapointsInsertItem = {
245
+ timeSeries: NodeId;
246
+ datapoints: Array<{
247
+ timestamp: Date;
248
+ value: number;
249
+ }>;
250
+ };
251
+ type DatapointsDeleteRange = {
252
+ timeSeries: NodeId;
253
+ start: Date;
254
+ end?: Date;
255
+ };
256
+ type DatapointsExecutor = {
257
+ retrieve(options: DatapointsRetrieveOptions): Promise<DatapointsResult>;
258
+ latest(options: DatapointsLatestOptions): Promise<DatapointsResult>;
259
+ insert(items: DatapointsInsertItem[]): Promise<void>;
260
+ delete(ranges: DatapointsDeleteRange[]): Promise<void>;
261
+ };
262
+ type FileUploadInfo = NodeId & {
263
+ name: string;
264
+ mimeType?: string;
265
+ directory?: string;
266
+ source?: string;
267
+ metadata?: Record<string, string>;
268
+ };
269
+ type FileUploadResult = NodeId & {
270
+ name: string;
271
+ uploaded: boolean;
272
+ mimeType?: string;
273
+ directory?: string;
274
+ source?: string;
275
+ uploadedTime?: Date;
276
+ createdTime: Date;
277
+ lastUpdatedTime: Date;
278
+ uploadUrl?: string;
279
+ };
280
+ type FileDownloadUrl = NodeId & {
281
+ downloadUrl: string;
282
+ };
283
+ type FilesExecutor = {
284
+ upload(fileInfo: FileUploadInfo, content?: unknown): Promise<FileUploadResult>;
285
+ getDownloadUrls(nodeIds: NodeId[]): Promise<FileDownloadUrl[]>;
286
+ };
211
287
  type SearchFilter = {
212
288
  query: string;
213
289
  operator?: "OR" | "AND";
@@ -264,4 +340,4 @@ type WhereInput<TModel> = {
264
340
  [K in keyof ModelProps<TModel> | RelationKeys<TModel>]?: QueryFilterValue<TModel, K>;
265
341
  };
266
342
 
267
- export type { AggregateExecutor as A, DataModelId as D, EdgeCreationCallback as E, IndustrialModelClientOptions as I, ModelProps as M, NodeId as N, OnEdgeCreation as O, QueryExecutor as Q, UpsertExecutor as U, DeleteResult as a, AggregateResult as b, AggregateResultItem as c, DeleteExecutor as d, DeleteResultItem as e, EdgeCreationCallbacks as f, EdgeCreationContext as g, EdgeMode as h, IndustrialModel as i, ModelRelations as j, QueryResult as k, QueryResultItem as l, QuerySelect as m, UpsertNode as n, UpsertOptions as o, UpsertProperties as p, UpsertResult as q, UpsertResultItem as r, AggregateOptions as s, QueryOptions as t };
343
+ export type { AggregateExecutor as A, UpsertOptions as B, UpsertProperties as C, DataModelId as D, EdgeCreationCallback as E, FilesExecutor as F, UpsertResult as G, UpsertResultItem as H, IndustrialModelClientOptions as I, AggregateOptions as J, QueryOptions as K, ModelProps as M, NodeId as N, OnEdgeCreation as O, QueryExecutor as Q, RawDatapoint as R, UpsertExecutor as U, DatapointsExecutor as a, DeleteResult as b, AggregateResult as c, AggregateResultItem as d, DatapointAggregate as e, DatapointSeriesResult as f, DatapointsDeleteRange as g, DatapointsInsertItem as h, DatapointsLatestOptions as i, DatapointsLatestSeries as j, DatapointsResult as k, DatapointsRetrieveOptions as l, DeleteExecutor as m, DeleteResultItem as n, EdgeCreationCallbacks as o, EdgeCreationContext as p, EdgeMode as q, FileDownloadUrl as r, FileUploadInfo as s, FileUploadResult as t, IndustrialModel as u, ModelRelations as v, QueryResult as w, QueryResultItem as x, QuerySelect as y, UpsertNode as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "industrial-model",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "TypeScript SDK for querying Cognite Industrial Data Models with a type-safe, graph-aware API",
5
5
  "license": "MIT",
6
6
  "keywords": [