stellarium-ts 0.13.0 → 0.14.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.
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +6 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/resource/repository.d.ts +9 -1
- package/dist/resource/repository.d.ts.map +1 -1
- package/dist/resource/repository.js +21 -4
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +8 -1
- package/dist/tests/db/db.test.js +1 -1
- package/dist/tests/resource/repository.test.js +31 -0
- package/package.json +1 -1
package/dist/db/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAU1D,wGAAwG;AACxG,wBAAsB,YAAY,CAAC,QAAQ,GAAE,MAA8B,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9F;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,QAAQ,iBA0I9C"}
|
package/dist/db/db.js
CHANGED
|
@@ -5,8 +5,9 @@ export const DEFAULT_DATABASE_PATH = './requestscript.db';
|
|
|
5
5
|
* Bumped whenever the schema changes in a way `CREATE TABLE IF NOT EXISTS` can't apply.
|
|
6
6
|
* Version 1 dropped `UNIQUE (base_url)` from `resource` and added uniqueness to the function tables.
|
|
7
7
|
* Version 2 added `resource_function.restricted`.
|
|
8
|
+
* Version 3 added `resource.website` and the `description` columns of the resource tables.
|
|
8
9
|
*/
|
|
9
|
-
const SCHEMA_VERSION =
|
|
10
|
+
const SCHEMA_VERSION = 3;
|
|
10
11
|
/** Opens (or creates) the node database and brings its schema up to date. Pass ':memory:' for tests. */
|
|
11
12
|
export async function openDatabase(filename = DEFAULT_DATABASE_PATH) {
|
|
12
13
|
const db = await open({ filename, driver: sqlite3.Database });
|
|
@@ -45,6 +46,8 @@ export async function createTables(db) {
|
|
|
45
46
|
path TEXT NOT NULL,
|
|
46
47
|
name TEXT NOT NULL,
|
|
47
48
|
base_url TEXT NOT NULL,
|
|
49
|
+
website TEXT,
|
|
50
|
+
description TEXT,
|
|
48
51
|
created_at TEXT NOT NULL,
|
|
49
52
|
updated_at TEXT NOT NULL,
|
|
50
53
|
|
|
@@ -58,6 +61,7 @@ export async function createTables(db) {
|
|
|
58
61
|
resource_id INTEGER NOT NULL,
|
|
59
62
|
name TEXT NOT NULL,
|
|
60
63
|
return_type TEXT NOT NULL,
|
|
64
|
+
description TEXT,
|
|
61
65
|
restricted INTEGER NOT NULL DEFAULT 0,
|
|
62
66
|
created_at TEXT NOT NULL,
|
|
63
67
|
updated_at TEXT NOT NULL,
|
|
@@ -72,6 +76,7 @@ export async function createTables(db) {
|
|
|
72
76
|
resource_function_id INTEGER NOT NULL,
|
|
73
77
|
name TEXT NOT NULL,
|
|
74
78
|
parameter_type TEXT NOT NULL,
|
|
79
|
+
description TEXT,
|
|
75
80
|
created_at TEXT NOT NULL,
|
|
76
81
|
updated_at TEXT NOT NULL,
|
|
77
82
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { StellariumNode, resolveConfig, type StellariumNodeOptions } from './server.js';
|
|
2
2
|
export type { NodeConfig } from './service.js';
|
|
3
|
-
export type { StellariumResource, StellariumResourceFunction, StellariumResourceFunctionPaymentManifest } from './resource/repository.js';
|
|
3
|
+
export type { StellariumResource, StellariumResourceFunction, StellariumResourceFunctionParameter, StellariumResourceFunctionPaymentManifest } from './resource/repository.js';
|
|
4
4
|
export { CombinationResourceInvoker, invocationHash, paymentVoucherPayload, type PaymentVoucher } from './resource/invoker.js';
|
|
5
5
|
export { grantHash, grantPayload, grantRenewalPayload, grantRequestPayload, grantsHash, CLOCK_SKEW_TOLERANCE_MS, invocationAuthorizationPayload, MAX_AUTHORIZATION_LIFETIME_MS, MAX_GRANT_CHAIN_LENGTH, MAX_GRANT_LIFETIME_MS, type Capability, type Grant, type GrantRenewalRequest, type GrantRequest, type InvocationAuthorization, } from './grant/grant.js';
|
|
6
6
|
export type { ApproveGrant, GrantApproval, GrantOptions } from './grant/service.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxF,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,yCAAyC,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxF,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,mCAAmC,EAAE,yCAAyC,EAAE,MAAM,0BAA0B,CAAC;AAE/K,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE/H,OAAO,EACH,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,6BAA6B,EAC7B,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,UAAU,EACf,KAAK,KAAK,EACV,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,uBAAuB,GAC/B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACpF,YAAY,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -6,8 +6,13 @@ export interface StellariumResourceFunctionPaymentManifest {
|
|
|
6
6
|
costLamports: number;
|
|
7
7
|
recipientAddress: string;
|
|
8
8
|
}
|
|
9
|
+
export interface StellariumResourceFunctionParameter extends ResourceFunctionParameter {
|
|
10
|
+
description?: string;
|
|
11
|
+
}
|
|
9
12
|
export interface StellariumResourceFunction extends ResourceFunction {
|
|
10
13
|
id?: number;
|
|
14
|
+
description?: string;
|
|
15
|
+
parameters: StellariumResourceFunctionParameter[];
|
|
11
16
|
paymentManifest?: StellariumResourceFunctionPaymentManifest;
|
|
12
17
|
/** Callers need a grant from the hosting node. Announced to peers so callers can tell. */
|
|
13
18
|
restricted?: boolean;
|
|
@@ -15,6 +20,9 @@ export interface StellariumResourceFunction extends ResourceFunction {
|
|
|
15
20
|
export interface StellariumResource extends Resource {
|
|
16
21
|
id: number;
|
|
17
22
|
baseUrl: string;
|
|
23
|
+
/** A URL where callers can learn more about the resource. */
|
|
24
|
+
website?: string;
|
|
25
|
+
description?: string;
|
|
18
26
|
functions: StellariumResourceFunction[];
|
|
19
27
|
}
|
|
20
28
|
/**
|
|
@@ -63,7 +71,7 @@ export declare class ResourceRepository {
|
|
|
63
71
|
getExternalResources(offset?: number, limit?: number): Promise<StellariumResource[]>;
|
|
64
72
|
getResourceFunction(resourcePath: string, resourceName: string, functionName: string): Promise<StellariumResourceFunction | undefined>;
|
|
65
73
|
getResourceFunctions(resourceId: number): Promise<StellariumResourceFunction[]>;
|
|
66
|
-
getResourceParameters(resourceFunctionId: number): Promise<
|
|
74
|
+
getResourceParameters(resourceFunctionId: number): Promise<StellariumResourceFunctionParameter[]>;
|
|
67
75
|
getResourceFunctionPaymentManifest(resourceFunctionId: number): Promise<StellariumResourceFunctionPaymentManifest | undefined>;
|
|
68
76
|
/**
|
|
69
77
|
* One page of every resource this node knows: the ones it hosts first, then learned ones.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/resource/repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,WAAW,yCAAyC;IACtD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAChE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,yCAAyC,CAAC;IAC5D,0FAA0F;IAC1F,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAmB,SAAQ,QAAQ;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,0BAA0B,EAAE,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,MAAM;;;EAE1F;AAED,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/resource/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,18 @@ import { isFreshExpiry, safeVerifyData } from "../crypto/utils.js";
|
|
|
6
6
|
export function resourceAnnouncementPayload(resources, expiry) {
|
|
7
7
|
return { resources, expiry };
|
|
8
8
|
}
|
|
9
|
+
/** Peers' resources aren't validated on receipt, so a description that isn't a string is stored as absent. */
|
|
10
|
+
function optionalText(value) {
|
|
11
|
+
return typeof value === 'string' ? value : null;
|
|
12
|
+
}
|
|
13
|
+
/** Only http(s) URLs are kept, since clients may render a resource's website as a link. */
|
|
14
|
+
function optionalWebsite(value) {
|
|
15
|
+
if (typeof value !== 'string' || !URL.canParse(value)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const { protocol } = new URL(value);
|
|
19
|
+
return protocol === 'http:' || protocol === 'https:' ? value : null;
|
|
20
|
+
}
|
|
9
21
|
const resourceKey = (resource) => `${resource.path}.${resource.name}`;
|
|
10
22
|
export class ResourceRepository {
|
|
11
23
|
db;
|
|
@@ -85,7 +97,7 @@ export class ResourceRepository {
|
|
|
85
97
|
continue;
|
|
86
98
|
}
|
|
87
99
|
await this.deleteFunctions(existing.id);
|
|
88
|
-
await this.db.run('UPDATE resource SET base_url = ?, peer_id = ?, updated_at = ? WHERE id = ?', [resource.baseUrl, peer.id, new Date().toISOString(), existing.id]);
|
|
100
|
+
await this.db.run('UPDATE resource SET base_url = ?, website = ?, description = ?, peer_id = ?, updated_at = ? WHERE id = ?', [resource.baseUrl, optionalWebsite(resource.website), optionalText(resource.description), peer.id, new Date().toISOString(), existing.id]);
|
|
89
101
|
await this.insertFunctions(existing.id, resource.functions);
|
|
90
102
|
}
|
|
91
103
|
});
|
|
@@ -93,7 +105,7 @@ export class ResourceRepository {
|
|
|
93
105
|
}
|
|
94
106
|
async insert(resource, peerId) {
|
|
95
107
|
const createdAt = new Date().toISOString();
|
|
96
|
-
const result = await this.db.run('INSERT INTO resource (path, name, base_url, peer_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)', [resource.path, resource.name, resource.baseUrl, peerId, createdAt, createdAt]);
|
|
108
|
+
const result = await this.db.run('INSERT INTO resource (path, name, base_url, website, description, peer_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', [resource.path, resource.name, resource.baseUrl, optionalWebsite(resource.website), optionalText(resource.description), peerId, createdAt, createdAt]);
|
|
97
109
|
if (!result.changes || result.lastID === undefined) {
|
|
98
110
|
throw new Error('Failed to create resource');
|
|
99
111
|
}
|
|
@@ -102,10 +114,10 @@ export class ResourceRepository {
|
|
|
102
114
|
async insertFunctions(resourceId, functions) {
|
|
103
115
|
const createdAt = new Date().toISOString();
|
|
104
116
|
for (const fn of functions) {
|
|
105
|
-
const functionResult = await this.db.run('INSERT INTO resource_function (resource_id, name, return_type, restricted, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)', [resourceId, fn.name, fn.returnType, fn.restricted === true ? 1 : 0, createdAt, createdAt]);
|
|
117
|
+
const functionResult = await this.db.run('INSERT INTO resource_function (resource_id, name, return_type, description, restricted, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)', [resourceId, fn.name, fn.returnType, optionalText(fn.description), fn.restricted === true ? 1 : 0, createdAt, createdAt]);
|
|
106
118
|
const functionId = functionResult.lastID;
|
|
107
119
|
for (const parameter of fn.parameters) {
|
|
108
|
-
await this.db.run('INSERT INTO resource_function_parameter (resource_function_id, name, parameter_type, created_at, updated_at) VALUES (?, ?, ?, ?, ?)', [functionId, parameter.name, parameter.type, createdAt, createdAt]);
|
|
120
|
+
await this.db.run('INSERT INTO resource_function_parameter (resource_function_id, name, parameter_type, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)', [functionId, parameter.name, parameter.type, optionalText(parameter.description), createdAt, createdAt]);
|
|
109
121
|
}
|
|
110
122
|
if (fn.paymentManifest) {
|
|
111
123
|
await this.db.run('INSERT INTO resource_function_payment_manifest (resource_function_id, cost_lamports, recipient_address, created_at, updated_at) VALUES (?, ?, ?, ?, ?)', [functionId, fn.paymentManifest.costLamports, fn.paymentManifest.recipientAddress, createdAt, createdAt]);
|
|
@@ -155,6 +167,8 @@ export class ResourceRepository {
|
|
|
155
167
|
path: r.path,
|
|
156
168
|
name: r.name,
|
|
157
169
|
baseUrl: r.base_url,
|
|
170
|
+
website: r.website ?? undefined,
|
|
171
|
+
description: r.description ?? undefined,
|
|
158
172
|
metadata: { baseUrl: r.base_url },
|
|
159
173
|
functions: await this.getResourceFunctions(r.id),
|
|
160
174
|
})));
|
|
@@ -172,6 +186,7 @@ export class ResourceRepository {
|
|
|
172
186
|
id: fn.id,
|
|
173
187
|
name: fn.name,
|
|
174
188
|
returnType: fn.return_type,
|
|
189
|
+
description: fn.description ?? undefined,
|
|
175
190
|
parameters: await this.getResourceParameters(fn.id),
|
|
176
191
|
exec: async () => undefined,
|
|
177
192
|
paymentManifest: await this.getResourceFunctionPaymentManifest(fn.id),
|
|
@@ -184,6 +199,7 @@ export class ResourceRepository {
|
|
|
184
199
|
id: f.id,
|
|
185
200
|
name: f.name,
|
|
186
201
|
returnType: f.return_type,
|
|
202
|
+
description: f.description ?? undefined,
|
|
187
203
|
parameters: await this.getResourceParameters(f.id),
|
|
188
204
|
exec: async () => undefined,
|
|
189
205
|
paymentManifest: await this.getResourceFunctionPaymentManifest(f.id),
|
|
@@ -194,6 +210,7 @@ export class ResourceRepository {
|
|
|
194
210
|
return (await this.db.all('SELECT * FROM resource_function_parameter WHERE resource_function_id = ? ORDER BY id', [resourceFunctionId])).map(p => ({
|
|
195
211
|
name: p.name,
|
|
196
212
|
type: p.parameter_type,
|
|
213
|
+
description: p.description ?? undefined,
|
|
197
214
|
}));
|
|
198
215
|
}
|
|
199
216
|
async getResourceFunctionPaymentManifest(resourceFunctionId) {
|
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,SAAS,CAAC;AAKhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAK5C,MAAM,WAAW,eAAe;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,UAAU,YAAY;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC/B;AAiDD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,aAAa,MAAM,CAAC;AAsHjC;;;;GAIG;AACH,QAAA,MAAM,MAAM,EAAE,kBAAkB,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAgC,MAAM,SAAS,CAAC;AAKhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAK5C,MAAM,WAAW,eAAe;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,UAAU,YAAY;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC/B;AAiDD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,aAAa,MAAM,CAAC;AAsHjC;;;;GAIG;AACH,QAAA,MAAM,MAAM,EAAE,kBAAkB,CAAC,YAAY,CAqS5C,CAAC;eAGa,MAAM"}
|
package/dist/routes.js
CHANGED
|
@@ -176,10 +176,17 @@ const routes = async (fastify, options) => {
|
|
|
176
176
|
resources: resources.map((resource) => ({
|
|
177
177
|
path: resource.path,
|
|
178
178
|
name: resource.name,
|
|
179
|
+
website: resource.website,
|
|
180
|
+
description: resource.description,
|
|
179
181
|
functions: resource.functions.map((fn) => ({
|
|
180
182
|
name: fn.name,
|
|
181
183
|
returnType: fn.returnType,
|
|
182
|
-
|
|
184
|
+
description: fn.description,
|
|
185
|
+
parameters: fn.parameters.map(parameter => ({
|
|
186
|
+
name: parameter.name,
|
|
187
|
+
type: parameter.type,
|
|
188
|
+
description: parameter.description,
|
|
189
|
+
})),
|
|
183
190
|
paymentManifest: fn.paymentManifest ? ({
|
|
184
191
|
costLamports: fn.paymentManifest.costLamports,
|
|
185
192
|
recipientAddress: fn.paymentManifest.recipientAddress,
|
package/dist/tests/db/db.test.js
CHANGED
|
@@ -17,7 +17,7 @@ describe("openDatabase", () => {
|
|
|
17
17
|
const filename = path.join(dir, "node.db");
|
|
18
18
|
await (await openDatabase(filename)).close();
|
|
19
19
|
const db = await openDatabase(filename);
|
|
20
|
-
expect(await db.get("PRAGMA user_version")).toEqual({ user_version:
|
|
20
|
+
expect(await db.get("PRAGMA user_version")).toEqual({ user_version: 3 });
|
|
21
21
|
await db.close();
|
|
22
22
|
});
|
|
23
23
|
test("rebuilds resource tables from the old schema and keeps peers", async () => {
|
|
@@ -33,6 +33,24 @@ describe("ResourceRepository", () => {
|
|
|
33
33
|
expect(functions.map(fn => [fn.name, fn.restricted])).toEqual([["open", true], ["peek", undefined]]);
|
|
34
34
|
expect((await repository.getResourceFunction("com.provider", "Vault", "open"))?.restricted).toBe(true);
|
|
35
35
|
});
|
|
36
|
+
test("keeps the descriptions of resources, functions and parameters", async () => {
|
|
37
|
+
await repository.learn({
|
|
38
|
+
...resource("Forecast", [
|
|
39
|
+
{ name: "tomorrow", description: "Tomorrow's forecast", parameters: [{ name: "city", type: "string", description: "City name" }] },
|
|
40
|
+
{ name: "today", parameters: [{ name: "city", type: "string" }] },
|
|
41
|
+
]),
|
|
42
|
+
website: "https://forecast.example",
|
|
43
|
+
description: "Weather forecasts",
|
|
44
|
+
});
|
|
45
|
+
const [learned] = await repository.getExternalResources();
|
|
46
|
+
expect(learned.website).toBe("https://forecast.example");
|
|
47
|
+
expect(learned.description).toBe("Weather forecasts");
|
|
48
|
+
expect(learned.functions.map(fn => [fn.name, fn.description, fn.parameters[0].description])).toEqual([
|
|
49
|
+
["today", undefined, undefined],
|
|
50
|
+
["tomorrow", "Tomorrow's forecast", "City name"],
|
|
51
|
+
]);
|
|
52
|
+
expect((await repository.getResourceFunction("com.provider", "Forecast", "tomorrow"))?.description).toBe("Tomorrow's forecast");
|
|
53
|
+
});
|
|
36
54
|
test("is idempotent, so startup can run on every boot", async () => {
|
|
37
55
|
const learned = resource("Forecast", [{ name: "tomorrow" }]);
|
|
38
56
|
await repository.learn(learned);
|
|
@@ -110,6 +128,19 @@ describe("ResourceRepository", () => {
|
|
|
110
128
|
expect(today?.paymentManifest).toMatchObject({ costLamports: 100 });
|
|
111
129
|
expect(await repository.getResourceFunction("com.provider", "Forecast", "tomorrow")).toBeDefined();
|
|
112
130
|
});
|
|
131
|
+
test("drops descriptions that aren't strings and websites that aren't http(s) URLs", async () => {
|
|
132
|
+
const sent = {
|
|
133
|
+
...resource("Forecast", [{ name: "today", description: 42, parameters: [{ name: "city", type: "string", description: { text: "City" } }] }]),
|
|
134
|
+
website: "javascript:alert(1)",
|
|
135
|
+
description: ["Weather forecasts"],
|
|
136
|
+
};
|
|
137
|
+
await save([sent, { ...resource("Radar", []), website: "https://radar.example", description: "Rain radar" }]);
|
|
138
|
+
const [forecast, radar] = await repository.getExternalResources();
|
|
139
|
+
expect([forecast.website, forecast.description]).toEqual([undefined, undefined]);
|
|
140
|
+
expect(forecast.functions[0].description).toBeUndefined();
|
|
141
|
+
expect(forecast.functions[0].parameters[0].description).toBeUndefined();
|
|
142
|
+
expect([radar.website, radar.description]).toEqual(["https://radar.example", "Rain radar"]);
|
|
143
|
+
});
|
|
113
144
|
test("removes functions and payment manifests the peer no longer advertises", async () => {
|
|
114
145
|
await save([resource("Forecast", [{ name: "today", paymentManifest: { costLamports: 100, recipientAddress: RECIPIENT } }, { name: "old" }])]);
|
|
115
146
|
await save([resource("Forecast", [{ name: "today" }])]);
|