@artinet/sdk 0.6.10 → 0.6.12
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/browser/config/index.d.ts +3 -2
- package/dist/browser/config/index.js +4 -4
- package/dist/browser/messenger/messenger.js +1 -1
- package/dist/browser/utils/utils.d.ts +4 -2
- package/dist/browser/utils/utils.js +10 -0
- package/dist/config/index.d.ts +3 -2
- package/dist/config/index.js +4 -4
- package/dist/create/create.d.ts +10 -440
- package/dist/create/create.js +5 -393
- package/dist/create/factory.d.ts +395 -0
- package/dist/create/factory.js +352 -0
- package/dist/index.d.ts +10 -10
- package/dist/index.js +11 -10
- package/dist/messenger/messenger.js +1 -1
- package/dist/server/express/create.d.ts +113 -0
- package/dist/server/express/create.js +113 -0
- package/dist/server/express/module.d.ts +2 -0
- package/dist/server/express/module.js +2 -0
- package/dist/server/express/utils.d.ts +2 -2
- package/dist/server/express/utils.js +10 -14
- package/dist/services/a2a/factory/state-machine.d.ts +1 -1
- package/dist/services/a2a/factory/state-machine.js +10 -10
- package/dist/services/a2a/managers.d.ts +1 -1
- package/dist/services/a2a/managers.js +19 -12
- package/dist/services/core/manager.js +3 -6
- package/dist/storage/file.js +9 -9
- package/dist/storage/sqlite.d.ts +2 -2
- package/dist/storage/sqlite.js +7 -5
- package/dist/utils/utils.d.ts +4 -2
- package/dist/utils/utils.js +10 -0
- package/package.json +7 -4
|
@@ -7,20 +7,16 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { SystemError } from "../../utils/index.js";
|
|
9
9
|
import { logger } from "../../config/index.js";
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import express from "express";
|
|
10
|
+
import { A2AError } from '@a2a-js/sdk/server';
|
|
11
|
+
import { formatJson, sanitizeString } from "../../utils/index.js";
|
|
12
|
+
import express from 'express';
|
|
14
13
|
export function rpcParser(req, res, next) {
|
|
15
14
|
express.json()(req, res, (err) => {
|
|
16
|
-
if (!req.body || typeof req.body !==
|
|
15
|
+
if (!req.body || typeof req.body !== 'object') {
|
|
17
16
|
return next(A2AError.parseError(`Invalid request body: ${formatJson(req.body)}`));
|
|
18
17
|
}
|
|
19
18
|
if (err) {
|
|
20
|
-
if (err instanceof SyntaxError &&
|
|
21
|
-
"status" in err &&
|
|
22
|
-
err.status === 400 &&
|
|
23
|
-
"body" in err) {
|
|
19
|
+
if (err instanceof SyntaxError && 'status' in err && err.status === 400 && 'body' in err) {
|
|
24
20
|
return next(A2AError.parseError(`Invalid request body: ${formatJson(req.body)}`));
|
|
25
21
|
}
|
|
26
22
|
return next(err);
|
|
@@ -36,15 +32,15 @@ export const errorHandler = (err, req, res, _) => {
|
|
|
36
32
|
if (res.headersSent) {
|
|
37
33
|
headersSent = true;
|
|
38
34
|
}
|
|
39
|
-
logger.error(
|
|
35
|
+
logger.error('errorHandler', err);
|
|
40
36
|
let reqId = null;
|
|
41
37
|
try {
|
|
42
|
-
if (req.body && typeof req.body ===
|
|
38
|
+
if (req.body && typeof req.body === 'object' && 'id' in req.body) {
|
|
43
39
|
reqId = req.body.id;
|
|
44
40
|
}
|
|
45
41
|
}
|
|
46
42
|
catch (e) {
|
|
47
|
-
logger.error(
|
|
43
|
+
logger.error('errorHandler: Error extracting request ID', e);
|
|
48
44
|
}
|
|
49
45
|
let jsonRpcError;
|
|
50
46
|
if (err instanceof A2AError || err instanceof SystemError) {
|
|
@@ -54,8 +50,8 @@ export const errorHandler = (err, req, res, _) => {
|
|
|
54
50
|
jsonRpcError = A2AError.internalError(err.message, err.data).toJSONRPCError();
|
|
55
51
|
}
|
|
56
52
|
const errorResponse = {
|
|
57
|
-
jsonrpc:
|
|
58
|
-
id:
|
|
53
|
+
jsonrpc: '2.0',
|
|
54
|
+
id: sanitizeString(reqId),
|
|
59
55
|
error: jsonRpcError,
|
|
60
56
|
};
|
|
61
57
|
if (!headersSent) {
|
|
@@ -7,5 +7,5 @@ export declare function createStateMachine({ contextId, service, task: currentTa
|
|
|
7
7
|
contextId: string;
|
|
8
8
|
service: A2A.Service;
|
|
9
9
|
task: A2A.Task;
|
|
10
|
-
overrides?: Partial<Omit<A2A.EventConsumer,
|
|
10
|
+
overrides?: Partial<Omit<A2A.EventConsumer, 'contextId'>>;
|
|
11
11
|
}): A2A.EventPublisher;
|
|
@@ -7,12 +7,12 @@ import { logger } from "../../../config/index.js";
|
|
|
7
7
|
import * as describe from "../../../create/describe.js";
|
|
8
8
|
import { TASK_NOT_FOUND } from "../../../utils/errors.js";
|
|
9
9
|
import { formatJson } from "../../../utils/utils.js";
|
|
10
|
-
import assert from "assert";
|
|
10
|
+
// import assert from "assert";
|
|
11
11
|
export function createStateMachine({ contextId, service, task: currentTask, overrides, }) {
|
|
12
12
|
const handler = {
|
|
13
13
|
contextId: contextId,
|
|
14
14
|
onStart: async (context) => {
|
|
15
|
-
assert(context.contextId === contextId,
|
|
15
|
+
// assert(context.contextId === contextId, 'context mismatch');
|
|
16
16
|
logger.info(`onStart[ctx:${contextId}]:`, { taskId: context.taskId });
|
|
17
17
|
await service.connections.set(context.contextId);
|
|
18
18
|
const task = await service.tasks.get(context.taskId);
|
|
@@ -24,8 +24,8 @@ export function createStateMachine({ contextId, service, task: currentTask, over
|
|
|
24
24
|
return task;
|
|
25
25
|
},
|
|
26
26
|
onCancel: async (update, task) => {
|
|
27
|
-
logger.info(`onCancel[ctx:${contextId}]:`,
|
|
28
|
-
logger.debug(`onCancel[ctx:${contextId}]:`,
|
|
27
|
+
logger.info(`onCancel[ctx:${contextId}]:`, 'cancellation triggered');
|
|
28
|
+
logger.debug(`onCancel[ctx:${contextId}]:`, 'arguments', update, task);
|
|
29
29
|
await service.cancellations.set(task.id);
|
|
30
30
|
const cancellation = describe.update.canceled({
|
|
31
31
|
taskId: task.id,
|
|
@@ -34,13 +34,13 @@ export function createStateMachine({ contextId, service, task: currentTask, over
|
|
|
34
34
|
});
|
|
35
35
|
/**We've intentionally blocked further updates, so the first cancellation update is responsible for updating stored task state and notifying listeners*/
|
|
36
36
|
const updatedTask = await service.tasks.update((await service.contexts.get(contextId)), cancellation);
|
|
37
|
-
(await service.contexts.get(contextId))?.publisher.emit(
|
|
37
|
+
(await service.contexts.get(contextId))?.publisher.emit('update', updatedTask, cancellation);
|
|
38
38
|
},
|
|
39
39
|
onUpdate: async (update, task) => {
|
|
40
40
|
logger.info(`onUpdate[ctx:${contextId}]:`);
|
|
41
41
|
logger.debug(`onUpdate[ctx:${contextId}]:`, { taskId: task.id });
|
|
42
42
|
if (await service.cancellations.has(task.id)) {
|
|
43
|
-
logger.warn(`onUpdate[ctx:${contextId}]:`, { taskId: task.id },
|
|
43
|
+
logger.warn(`onUpdate[ctx:${contextId}]:`, { taskId: task.id }, 'task is cancelled, no longer processing updates');
|
|
44
44
|
return task;
|
|
45
45
|
}
|
|
46
46
|
return await service.tasks.update((await service.contexts.get(contextId)), update);
|
|
@@ -48,7 +48,7 @@ export function createStateMachine({ contextId, service, task: currentTask, over
|
|
|
48
48
|
onError: async (error, task) => {
|
|
49
49
|
logger.error(`onError[ctx:${contextId}]:`, error);
|
|
50
50
|
if (!task) {
|
|
51
|
-
logger.error(`onError[ctx:${contextId}]:`, new Error(
|
|
51
|
+
logger.error(`onError[ctx:${contextId}]:`, new Error('task not found'));
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
const errorUpdate = describe.update.failed({
|
|
@@ -58,7 +58,7 @@ export function createStateMachine({ contextId, service, task: currentTask, over
|
|
|
58
58
|
messageId: `failed:${task.id}`,
|
|
59
59
|
parts: [
|
|
60
60
|
{
|
|
61
|
-
kind:
|
|
61
|
+
kind: 'text',
|
|
62
62
|
text: error instanceof Error ? error.message : formatJson(error),
|
|
63
63
|
},
|
|
64
64
|
],
|
|
@@ -66,7 +66,7 @@ export function createStateMachine({ contextId, service, task: currentTask, over
|
|
|
66
66
|
});
|
|
67
67
|
const context = await service.contexts.get(contextId);
|
|
68
68
|
if (!context) {
|
|
69
|
-
logger.error(`onError[ctx:${contextId}]:`, new Error(
|
|
69
|
+
logger.error(`onError[ctx:${contextId}]:`, new Error('context not found'));
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
/**triggering onUpdate here with a catch instead of a raw tasks.update call*/
|
|
@@ -77,7 +77,7 @@ export function createStateMachine({ contextId, service, task: currentTask, over
|
|
|
77
77
|
await context.publisher.onComplete();
|
|
78
78
|
},
|
|
79
79
|
onComplete: async (task) => {
|
|
80
|
-
assert(task.contextId === contextId,
|
|
80
|
+
// assert(task.contextId === contextId, 'context mismatch');
|
|
81
81
|
logger.info(`onComplete[ctx:${contextId}]: `, { taskId: task.id });
|
|
82
82
|
await service.cancellations.delete(task.id);
|
|
83
83
|
await service.connections.delete(task.contextId);
|
|
@@ -17,7 +17,7 @@ export declare class Streams extends Manager<A2A.Stream> implements A2A.Streams
|
|
|
17
17
|
}): Promise<A2A.Stream>;
|
|
18
18
|
}
|
|
19
19
|
export declare class Tasks extends Manager<A2A.Task> implements A2A.Tasks {
|
|
20
|
-
constructor(tasks?: Map<string, A2A.Task>);
|
|
20
|
+
constructor(tasks?: Map<string, A2A.Task>, storage?: core.Manager<A2A.Task>);
|
|
21
21
|
update(context: A2A.Context, update: A2A.Update): Promise<A2A.Task>;
|
|
22
22
|
create(params: Partial<A2A.Task>): Promise<A2A.Task>;
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A2A } from "../../types/index.js";
|
|
2
|
-
import { Stream } from
|
|
3
|
-
import { createBaseContext, createContext
|
|
4
|
-
import { v4 } from
|
|
2
|
+
import { Stream } from './streams.js';
|
|
3
|
+
import { createBaseContext, createContext } from "./factory/context.js";
|
|
4
|
+
import { v4 } from 'uuid';
|
|
5
5
|
import { getCurrentTimestamp } from "../../utils/index.js";
|
|
6
6
|
import { handleUpdate } from "./handlers/update.js";
|
|
7
7
|
import { Manager } from "../core/manager.js";
|
|
@@ -22,7 +22,7 @@ export class Contexts extends Manager {
|
|
|
22
22
|
}
|
|
23
23
|
async create(params) {
|
|
24
24
|
if (await this.has(params.contextId)) {
|
|
25
|
-
logger.warn(
|
|
25
|
+
logger.warn('Contexts[create]: context already exists', {
|
|
26
26
|
contextId: params.contextId,
|
|
27
27
|
});
|
|
28
28
|
return (await this.get(params.contextId));
|
|
@@ -54,26 +54,30 @@ export class Streams extends Manager {
|
|
|
54
54
|
}
|
|
55
55
|
async create({ contextId, context, updates, }) {
|
|
56
56
|
if (await this.has(contextId)) {
|
|
57
|
-
throw new Error(
|
|
57
|
+
throw new Error('Stream already exists');
|
|
58
58
|
}
|
|
59
59
|
await this.set(contextId, new Stream(contextId, context, updates));
|
|
60
60
|
return (await this.get(contextId));
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
export class Tasks extends Manager {
|
|
64
|
-
constructor(tasks = new Map()) {
|
|
65
|
-
super(tasks, true);
|
|
64
|
+
constructor(tasks = new Map(), storage) {
|
|
65
|
+
super(tasks, true, storage);
|
|
66
66
|
}
|
|
67
67
|
async update(context, update) {
|
|
68
68
|
logger.info(`Tasks[update]: updating task`, { taskId: context.taskId });
|
|
69
69
|
logger.debug(`Tasks[update]: update`, { update });
|
|
70
70
|
logger.debug(`Tasks[update]: context`, { context });
|
|
71
|
+
const currentTask = await context.getTask();
|
|
72
|
+
if (!currentTask) {
|
|
73
|
+
throw new Error(`Task not found: ${context.taskId}`);
|
|
74
|
+
}
|
|
71
75
|
logger.debug(`Tasks[update]: context task`, {
|
|
72
|
-
task:
|
|
76
|
+
task: currentTask,
|
|
73
77
|
});
|
|
74
78
|
const task = await handleUpdate({
|
|
75
79
|
context,
|
|
76
|
-
task:
|
|
80
|
+
task: currentTask,
|
|
77
81
|
update,
|
|
78
82
|
});
|
|
79
83
|
logger.debug(`Tasks[update]: task`, task);
|
|
@@ -81,15 +85,18 @@ export class Tasks extends Manager {
|
|
|
81
85
|
return task;
|
|
82
86
|
}
|
|
83
87
|
async create(params) {
|
|
84
|
-
if (params.id
|
|
85
|
-
|
|
88
|
+
if (params.id) {
|
|
89
|
+
const task = await this.get(params.id);
|
|
90
|
+
if (task) {
|
|
91
|
+
return task;
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
logger.info(`Tasks[create]: creating task`, { id: params.id });
|
|
88
95
|
const task = {
|
|
89
96
|
...params,
|
|
90
97
|
id: params.id ?? v4(),
|
|
91
98
|
contextId: params.contextId ?? v4(),
|
|
92
|
-
kind:
|
|
99
|
+
kind: 'task',
|
|
93
100
|
status: {
|
|
94
101
|
state: A2A.TaskState.submitted,
|
|
95
102
|
timestamp: getCurrentTimestamp(),
|
|
@@ -88,14 +88,11 @@ export class Manager {
|
|
|
88
88
|
}
|
|
89
89
|
const results = [];
|
|
90
90
|
if (filter) {
|
|
91
|
-
const
|
|
92
|
-
const filterResults = await Promise.all(items.map(async (item) => {
|
|
91
|
+
for (const item of this.cache.values()) {
|
|
93
92
|
if (await filter(item)) {
|
|
94
|
-
|
|
93
|
+
results.push(item);
|
|
95
94
|
}
|
|
96
|
-
|
|
97
|
-
}));
|
|
98
|
-
results.push(...filterResults.filter((item) => item !== undefined));
|
|
95
|
+
}
|
|
99
96
|
}
|
|
100
97
|
if (this.storage) {
|
|
101
98
|
const storageFilter = async (item) => {
|
package/dist/storage/file.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { A2A } from "../types/index.js";
|
|
6
|
-
import fs from
|
|
7
|
-
import path from
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
8
|
import { logger } from "../config/index.js";
|
|
9
9
|
import { Tasks } from "../services/a2a/managers.js";
|
|
10
10
|
import { formatJson, safeParseSchema } from "../utils/index.js";
|
|
@@ -19,6 +19,7 @@ export class Files extends Tasks {
|
|
|
19
19
|
* @param baseDir The base directory to store task files in.
|
|
20
20
|
*/
|
|
21
21
|
constructor(baseDir) {
|
|
22
|
+
//TODO: we're inverting the dependency injection pattern here. Tasks should take the storage instance
|
|
22
23
|
super(new Map());
|
|
23
24
|
this.baseDir = baseDir;
|
|
24
25
|
logger.info(`FileStore[init]: baseDir`, { baseDir });
|
|
@@ -54,7 +55,7 @@ export class Files extends Tasks {
|
|
|
54
55
|
try {
|
|
55
56
|
await this.ensureBaseDir();
|
|
56
57
|
await fs.writeFile(filePath, formatJson(task), {
|
|
57
|
-
encoding:
|
|
58
|
+
encoding: 'utf8',
|
|
58
59
|
});
|
|
59
60
|
}
|
|
60
61
|
catch (error) {
|
|
@@ -69,11 +70,11 @@ export class Files extends Tasks {
|
|
|
69
70
|
*/
|
|
70
71
|
async readJsonFile(filePath) {
|
|
71
72
|
try {
|
|
72
|
-
const content = await fs.readFile(filePath, { encoding:
|
|
73
|
+
const content = await fs.readFile(filePath, { encoding: 'utf8' });
|
|
73
74
|
return await safeParseSchema(content, A2A.TaskSchema);
|
|
74
75
|
}
|
|
75
76
|
catch (error) {
|
|
76
|
-
if (error.code ===
|
|
77
|
+
if (error.code === 'ENOENT') {
|
|
77
78
|
logger.warn(`FileStore[readJsonFile]: ${filePath} not found`);
|
|
78
79
|
return null;
|
|
79
80
|
}
|
|
@@ -86,8 +87,7 @@ export class Files extends Tasks {
|
|
|
86
87
|
* @returns A promise resolving to the task and history, or null if not found.
|
|
87
88
|
*/
|
|
88
89
|
async get(taskId) {
|
|
89
|
-
const task = (await super.get(taskId)) ??
|
|
90
|
-
(await this.readJsonFile(this.getTaskFilePath(taskId)).catch(() => undefined));
|
|
90
|
+
const task = (await super.get(taskId)) ?? (await this.readJsonFile(this.getTaskFilePath(taskId)).catch(() => undefined));
|
|
91
91
|
return task ?? undefined;
|
|
92
92
|
}
|
|
93
93
|
/**
|
|
@@ -101,8 +101,8 @@ export class Files extends Tasks {
|
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
if (task && taskId !== task.id) {
|
|
104
|
-
logger.warn(
|
|
105
|
-
throw new Error(
|
|
104
|
+
logger.warn('FileStore', `Task ID mismatch: ${taskId} !== ${task.id}`);
|
|
105
|
+
throw new Error('Task ID mismatch');
|
|
106
106
|
}
|
|
107
107
|
const taskFilePath = this.getTaskFilePath(taskId);
|
|
108
108
|
await this.writeJsonFile(taskFilePath, task);
|
package/dist/storage/sqlite.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { A2A } from "../types/index.js";
|
|
|
6
6
|
import { Tasks } from "../services/a2a/managers.js";
|
|
7
7
|
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
8
8
|
export declare const TABLE_NAME = "artinet_tasks";
|
|
9
|
-
export declare const createTaskTable: (db: BaseSQLiteDatabase<`sync` | `async`, any, TaskTable
|
|
9
|
+
export declare const createTaskTable: (db: BaseSQLiteDatabase<`sync` | `async`, any, TaskTable>, tableName?: string) => Promise<void>;
|
|
10
10
|
export declare const TaskTable: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
11
11
|
name: "artinet_tasks";
|
|
12
12
|
schema: undefined;
|
|
@@ -345,7 +345,7 @@ export declare const TaskTable: import("drizzle-orm/sqlite-core").SQLiteTableWit
|
|
|
345
345
|
export type TaskTable = typeof TaskTable.$inferSelect;
|
|
346
346
|
export declare class SQLiteStore extends Tasks {
|
|
347
347
|
private db;
|
|
348
|
-
constructor(db: BaseSQLiteDatabase<`sync` | `async`, any, TaskTable>, tasks?: Map<string, A2A.Task
|
|
348
|
+
constructor(db: BaseSQLiteDatabase<`sync` | `async`, any, TaskTable>, tasks?: Map<string, A2A.Task>, tableName?: string);
|
|
349
349
|
has(id: string): Promise<boolean>;
|
|
350
350
|
list(): Promise<A2A.Task[]>;
|
|
351
351
|
get(id: string): Promise<A2A.Task | undefined>;
|
package/dist/storage/sqlite.js
CHANGED
|
@@ -7,14 +7,14 @@ import { eq, like, or /*Table, TableConfig*/ } from 'drizzle-orm';
|
|
|
7
7
|
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
|
|
8
8
|
import { logger } from "../config/index.js";
|
|
9
9
|
export const TABLE_NAME = 'artinet_tasks';
|
|
10
|
-
const CREATE_TASKS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS ${
|
|
10
|
+
const CREATE_TASKS_TABLE_SQL = (tableName = TABLE_NAME) => `CREATE TABLE IF NOT EXISTS ${tableName}\
|
|
11
11
|
(id TEXT PRIMARY KEY, contextId TEXT NOT NULL,\
|
|
12
12
|
kind TEXT NOT NULL, status TEXT NOT NULL,\
|
|
13
13
|
history TEXT NOT NULL,\
|
|
14
14
|
artifacts TEXT NOT NULL,\
|
|
15
15
|
metadata TEXT NOT NULL)`;
|
|
16
|
-
export const createTaskTable = async (db) => {
|
|
17
|
-
await db.run(CREATE_TASKS_TABLE_SQL);
|
|
16
|
+
export const createTaskTable = async (db, tableName = TABLE_NAME) => {
|
|
17
|
+
await db.run(CREATE_TASKS_TABLE_SQL(tableName));
|
|
18
18
|
};
|
|
19
19
|
/*export type TTable = Table<TableConfig>; //TODO: Unwind Config/Column types */
|
|
20
20
|
export const TaskTable = sqliteTable(TABLE_NAME, {
|
|
@@ -28,10 +28,12 @@ export const TaskTable = sqliteTable(TABLE_NAME, {
|
|
|
28
28
|
});
|
|
29
29
|
export class SQLiteStore extends Tasks {
|
|
30
30
|
db;
|
|
31
|
-
|
|
31
|
+
//TODO: better for this to be a factory function? We're forcing the table/table name onto the user.
|
|
32
|
+
constructor(db, tasks = new Map(), tableName = TABLE_NAME) {
|
|
33
|
+
//TODO: we're inverting the dependency injection pattern here. Tasks should take the storage instance
|
|
32
34
|
super(tasks);
|
|
33
35
|
this.db = db;
|
|
34
|
-
createTaskTable(db);
|
|
36
|
+
createTaskTable(db, tableName);
|
|
35
37
|
}
|
|
36
38
|
async has(id) {
|
|
37
39
|
return ((await super.has(id)) ||
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Sanitizes a string by escaping HTML characters to prevent XSS attacks.
|
|
3
|
+
* @param str - The string to sanitize.
|
|
4
|
+
* @returns The sanitized string.
|
|
4
5
|
*/
|
|
6
|
+
export declare function sanitizeString(str: string): string;
|
|
5
7
|
/**
|
|
6
8
|
* Generates a timestamp in ISO 8601 format.
|
|
7
9
|
* @returns The current timestamp as a string.
|
package/dist/utils/utils.js
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
* Copyright 2025 The Artinet Project
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
+
import escapeHtml from 'escape-html';
|
|
6
|
+
import { Buffer } from 'node:buffer';
|
|
7
|
+
/**
|
|
8
|
+
* Sanitizes a string by escaping HTML characters to prevent XSS attacks.
|
|
9
|
+
* @param str - The string to sanitize.
|
|
10
|
+
* @returns The sanitized string.
|
|
11
|
+
*/
|
|
12
|
+
export function sanitizeString(str) {
|
|
13
|
+
return escapeHtml(str).trim();
|
|
14
|
+
}
|
|
5
15
|
/**
|
|
6
16
|
* Generates a timestamp in ISO 8601 format.
|
|
7
17
|
* @returns The current timestamp as a string.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artinet/sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.12",
|
|
4
4
|
"description": "A TypeScript SDK for building collaborative AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"default": "./dist/storage/sqlite.js"
|
|
39
39
|
},
|
|
40
40
|
"./express": {
|
|
41
|
-
"types": "./dist/server/express/
|
|
42
|
-
"import": "./dist/server/express/
|
|
43
|
-
"default": "./dist/server/express/
|
|
41
|
+
"types": "./dist/server/express/module.d.ts",
|
|
42
|
+
"import": "./dist/server/express/module.js",
|
|
43
|
+
"default": "./dist/server/express/module.js"
|
|
44
44
|
},
|
|
45
45
|
"./trpc": {
|
|
46
46
|
"types": "./dist/transport/trpc/index.d.ts",
|
|
@@ -152,6 +152,9 @@
|
|
|
152
152
|
},
|
|
153
153
|
"drizzle-orm": {
|
|
154
154
|
"optional": true
|
|
155
|
+
},
|
|
156
|
+
"serverless-http": {
|
|
157
|
+
"optional": true
|
|
155
158
|
}
|
|
156
159
|
},
|
|
157
160
|
"devDependencies": {
|