Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './src/api/GraphEdge';
export * from './src/api/GraphNode';
export * from './src/api/GraphQuery';
export * from './src/api/GraphSchema';
export * from './src/api/import';
export * from './src/api/License';
export * from './src/api/Linkurious';
export * from './src/api/Plugin';
Expand Down
21 changes: 20 additions & 1 deletion src/api/GraphEdge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import {LkErrorKey} from '../../http/response';
import {LkEdge, LkSubGraph} from '../graphItemTypes';
import {IDataSourceParams} from '../commonTypes';

import {ICreateEdgeParams, IDeleteEdgeParams, IGetEdgeParams, IUpdateEdgeParams} from './types';
import {
BulkCreateEdgesParams,
ICreateEdgeParams,
IDeleteEdgeParams,
IGetEdgeParams,
IUpdateEdgeParams
} from './types';

export * from './types';

Expand Down Expand Up @@ -56,6 +62,19 @@ export class GraphEdgeAPI extends Request {
});
}

/**
* Add a chunk of edges to the graph. Optionally accepts an import ID parameter. If it is
* provided, the edges are linked to this import (via a hidden property). Otherwise, the
* edges are created without any link.
*/
public bulkCreateEdges(params: BulkCreateEdgesParams) {
return this.request({
errors: [UNAUTHORIZED, DATA_SOURCE_UNAVAILABLE, FORBIDDEN],
url: '/:sourceKey/graph/edges/bulk',
method: 'POST',
params: params
});
}
/**
* Delete an edge from the graph.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/api/GraphEdge/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ export interface IUpdateEdgeParams extends IDataSourceParams {
export interface IDeleteEdgeParams extends IDataSourceParams {
id: string;
}

export interface BulkCreateEdgesParams extends IDataSourceParams {
edges: Omit<ICreateEdgeParams, 'sourceKey'>;
importId?: number;
}
21 changes: 21 additions & 0 deletions src/api/GraphNode/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {LkNode, LkNodeStatistics, LkSubGraph} from '../graphItemTypes';
import {IDataSourceParams} from '../commonTypes';

import {
BulkCreateNodesParams,
ICreateNodeParams,
IDeleteNodeParams,
IGetAdjacentNodesParams,
Expand Down Expand Up @@ -98,6 +99,26 @@ export class GraphNodeAPI extends Request {
});
}

/**
* Add a chunk of nodes to the graph. Optionally accepts an import ID parameter. If it is
* provided, the nodes are linked to this import (via a hidden property). Otherwise, the
* nodes are created without any link.
*/
public bulkCreateNodes(params: BulkCreateNodesParams) {
return this.request({
errors: [
UNAUTHORIZED,
DATA_SOURCE_UNAVAILABLE,
FORBIDDEN,
INVALID_PARAMETER,
CONSTRAINT_VIOLATION
],
url: '/:sourceKey/graph/nodes/bulk',
method: 'POST',
params: params
});
}

/**
* Get the number of nodes in the graph.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/api/GraphNode/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export interface IDeleteNodeParams extends IDataSourceParams {
id: string;
}

export interface BulkCreateNodesParams extends IDataSourceParams {
nodes: Omit<ICreateNodeParams, 'sourceKey'>;
importId?: number;
}

export interface IGetStatisticsParams extends IDataSourceParams {
ids: string[];
withDigest?: boolean;
Expand Down
109 changes: 109 additions & 0 deletions src/api/import/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* LINKURIOUS CONFIDENTIAL
* Copyright Linkurious SAS 2012 - 2025
*
* - Created on 2025-11-18.
*/
import {Request} from '../../http/request';
import {LkErrorKey} from '../../http/response';

import {
CreateImportParams,
CreateImportTemplateParams,
DeleteImportDataParams,
DeleteImportTemplateParams,
GetImportTemplatesParams,
Import,
ImportTemplate,
UpdateImportTemplateParams
} from './types';

export * from './types';

const {UNAUTHORIZED, DATA_SOURCE_UNAVAILABLE, FORBIDDEN, NOT_FOUND} = LkErrorKey;

export class ImportAPI extends Request {
/**
* Create a new import template.
*/
createImportTemplate(this: Request<ImportTemplate>, params: CreateImportTemplateParams) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE],
url: '/:sourceKey/imports/templates',
method: 'POST',
params: params
});
}

/**
* Update an existing import template.
*/
updateImportTemplate(this: Request<ImportTemplate>, params: UpdateImportTemplateParams) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE, NOT_FOUND],
url: '/:sourceKey/imports/templates/:id',
method: 'PATCH',
params: params
});
}

/**
* Delete an existing import template.
*/
deleteImportTemplate(params: DeleteImportTemplateParams) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE, NOT_FOUND],
url: '/:sourceKey/imports/templates/:id',
method: 'DELETE',
params: params
});
}

/**
* List all the import templates (the publicly shared ones and the private ones owned by the user).
*/
getImportTemplates(this: Request<{items: ImportTemplate[]}>, params: GetImportTemplatesParams) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE],
url: '/:sourceKey/imports/templates',
method: 'GET',
params: params
});
}

/**
* Create a new import.
*/
createImport(this: Request<Import>, params: CreateImportParams) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE],
url: '/:sourceKey/imports',
method: 'POST',
params: params
});
}

/**
* List all the existing imports (for the current user if they are not admin, or for all users
* if the current user is an admin).
*/
getImports(this: Request<{items: Import[]}>) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE],
url: '/:sourceKey/imports',
method: 'GET'
});
}

/**
* Delete all the nodes/edges uploaded as part of an existing import.
*/
deleteImportData(params: DeleteImportDataParams) {
return this.request({
errors: [UNAUTHORIZED, FORBIDDEN, DATA_SOURCE_UNAVAILABLE],
url: '/:sourceKey/imports/:id/data',
method: 'DELETE',
params: params
});
}
}
106 changes: 106 additions & 0 deletions src/api/import/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/**
* LINKURIOUS CONFIDENTIAL
* Copyright Linkurious SAS 2012 - 2025
*
* - Created on 2025-11-18.
*/
import {DeletableUser, IDataSourceParams, SharingMode} from '../commonTypes';
import {EntityType} from '../GraphSchema';

export type CreateImportTemplateParams =
| CreateNodeImportTemplateParams
| CreateEdgeImportTemplateParams;

export interface CreateNodeImportTemplateParams extends CreateBaseImportTemplateParams {
entityType: EntityType.NODE;
}

export interface CreateEdgeImportTemplateParams extends CreateBaseImportTemplateParams {
entityType: EntityType.EDGE;
sourceNode: NodeReference;
targetNode: NodeReference;
}

interface CreateBaseImportTemplateParams extends IDataSourceParams {
name: string;
description?: string;
sharing?: SharingMode.PRIVATE | SharingMode.SOURCE;
/**
* The target node category / edge type.
*/
itemType: string;
/**
* How to map imported fields to node/edge properties.
*/
properties: PropertyMapping[];
}

interface PropertyMapping {
/**
* The field in the imported file.
*/
sourceField: string;
/**
* The destination property key on the node/edge.
*/
targetProperty: string;
}

interface NodeReference {
/**
* The field in the imported file.
*/
sourceField: string;
/**
* The destination node category.
*/
targetCategory: string;
/**
* The destination property key on the node. If it is undefined, the destination is the native
* ID of the node.
*/
targetProperty?: string;
}

export type UpdateImportTemplateParams = CreateImportTemplateParams & {
id: number;
};

export interface DeleteImportTemplateParams extends IDataSourceParams {
id: number;
}

export interface GetImportTemplatesParams extends IDataSourceParams {
entityType?: EntityType;
}

export type ImportTemplate = CreateImportTemplateParams & {
id: number;
sourceKey: string;
};

export interface CreateImportParams extends IDataSourceParams {
/**
* Filename of the uploaded file (including its extension).
*/
filename: string;
}

export interface Import extends CreateImportParams {
id: number;
sourceKey: string;
/**
* Who created this import.
*/
createdBy: DeletableUser;
/**
* When was this import handle created (so before actually uploading nodes/edges).
*
* It's a date-time formatted as a ISO 8601 string, for instance "2025-01-31T09:32:07.508Z".
*/
createdAt: string;
}

export interface DeleteImportDataParams extends IDataSourceParams {
id: number;
}
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {GraphEdgeAPI} from './api/GraphEdge';
import {GraphNodeAPI} from './api/GraphNode';
import {GraphQueryAPI} from './api/GraphQuery';
import {GraphSchemaAPI} from './api/GraphSchema';
import {ImportAPI} from './api/import';
import {LicenseAPI} from './api/License';
import {LinkuriousAPI} from './api/Linkurious';
import {PluginAPI} from './api/Plugin';
Expand Down Expand Up @@ -50,6 +51,7 @@ export class RestClient extends ErrorListener {
public readonly graphNode: GraphNodeAPI;
public readonly graphQuery: GraphQueryAPI;
public readonly graphSchema: GraphSchemaAPI;
public readonly import: ImportAPI;
public readonly license: LicenseAPI;
public readonly linkurious: LinkuriousAPI;
public readonly plugin: PluginAPI;
Expand Down Expand Up @@ -97,6 +99,7 @@ export class RestClient extends ErrorListener {
this.graphNode = new GraphNodeAPI(moduleProps);
this.graphQuery = new GraphQueryAPI(moduleProps);
this.graphSchema = new GraphSchemaAPI(moduleProps);
this.import = new ImportAPI(moduleProps);
this.license = new LicenseAPI(moduleProps);
this.linkurious = new LinkuriousAPI(moduleProps);
this.plugin = new PluginAPI(moduleProps);
Expand Down