@graffiti-garden/api 1.0.1 → 1.0.3
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/index.cjs +1 -1
- package/dist/index.cjs.map +3 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +3 -3
- package/dist/src/1-api.d.ts +23 -42
- package/dist/src/1-api.d.ts.map +1 -1
- package/dist/src/2-types.d.ts +37 -2
- package/dist/src/2-types.d.ts.map +1 -1
- package/dist/src/3-errors.d.ts +0 -3
- package/dist/src/3-errors.d.ts.map +1 -1
- package/dist/tests/crud.d.ts.map +1 -1
- package/dist/tests/discover.d.ts.map +1 -1
- package/dist/tests.mjs +57 -6
- package/dist/tests.mjs.map +3 -3
- package/package.json +1 -1
- package/src/1-api.ts +24 -43
- package/src/2-types.ts +39 -2
- package/src/3-errors.ts +0 -8
- package/tests/crud.ts +6 -0
- package/tests/discover.ts +54 -2
package/src/2-types.ts
CHANGED
|
@@ -102,7 +102,7 @@ export interface GraffitiObjectBase {
|
|
|
102
102
|
* Schema-aware objects are returned by {@link Graffiti.get} and {@link Graffiti.discover}.
|
|
103
103
|
*/
|
|
104
104
|
export type GraffitiObject<Schema extends JSONSchema> = GraffitiObjectBase &
|
|
105
|
-
FromSchema<Schema & typeof
|
|
105
|
+
FromSchema<Schema & typeof GraffitiPostObjectJSONSchema>;
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
108
|
* A JSON Schema equivalent to the {@link GraffitiObjectBase} type.
|
|
@@ -145,7 +145,6 @@ export type GraffitiPostObject<Schema extends JSONSchema> = Pick<
|
|
|
145
145
|
GraffitiObjectBase,
|
|
146
146
|
"value" | "channels" | "allowed"
|
|
147
147
|
> &
|
|
148
|
-
Partial<GraffitiObjectBase> &
|
|
149
148
|
FromSchema<Schema & typeof GraffitiPostObjectJSONSchema>;
|
|
150
149
|
|
|
151
150
|
/**
|
|
@@ -397,3 +396,41 @@ export type GraffitiSessionInitializedEvent = CustomEvent<
|
|
|
397
396
|
| null
|
|
398
397
|
| undefined
|
|
399
398
|
>;
|
|
399
|
+
|
|
400
|
+
export type GraffitiMedia = {
|
|
401
|
+
/**
|
|
402
|
+
* The binary data of the media to be uploaded,
|
|
403
|
+
* along with its [media type](https://www.iana.org/assignments/media-types/media-types.xhtml),
|
|
404
|
+
* formatted as a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
|
|
405
|
+
*/
|
|
406
|
+
data: Blob;
|
|
407
|
+
/**
|
|
408
|
+
* The {@link GraffitiObjectBase.actor | `actor`} that
|
|
409
|
+
* {@link Graffiti.postMedia | `post`ed} the media.
|
|
410
|
+
*/
|
|
411
|
+
actor: string;
|
|
412
|
+
/**
|
|
413
|
+
* An optional list, identical in function to an object's
|
|
414
|
+
* {@link GraffitiObjectBase.allowed | `allowed`} property,
|
|
415
|
+
* that specifies the {@link GraffitiObjectBase.actor | `actor`}s
|
|
416
|
+
* who are allowed to access the media. If the list is `undefined`
|
|
417
|
+
* or `null`, anyone with the URL can access the media. If the list
|
|
418
|
+
* is empty, only the {@link GraffitiObjectBase.actor | `actor`}
|
|
419
|
+
* who {@link Graffiti.postMedia | `post`ed} the media can access it.
|
|
420
|
+
*/
|
|
421
|
+
allowed?: string[] | null;
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
export type GraffitiPostMedia = Pick<GraffitiMedia, "data" | "allowed">;
|
|
425
|
+
|
|
426
|
+
export type GraffitiMediaRequirements = {
|
|
427
|
+
/**
|
|
428
|
+
* A list of acceptable media types for the retrieved media,
|
|
429
|
+
* formatted as like an [HTTP Accept header](https://httpwg.org/specs/rfc9110.html#field.accept)
|
|
430
|
+
*/
|
|
431
|
+
accept?: string;
|
|
432
|
+
/**
|
|
433
|
+
* The maximum acceptable size, in bytes, of the media.
|
|
434
|
+
*/
|
|
435
|
+
maxBytes?: number;
|
|
436
|
+
};
|
package/src/3-errors.ts
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
export class GraffitiErrorUnauthorized extends Error {
|
|
2
|
-
constructor(message?: string) {
|
|
3
|
-
super(message);
|
|
4
|
-
this.name = "GraffitiErrorUnauthorized";
|
|
5
|
-
Object.setPrototypeOf(this, GraffitiErrorUnauthorized.prototype);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
1
|
export class GraffitiErrorForbidden extends Error {
|
|
10
2
|
constructor(message?: string) {
|
|
11
3
|
super(message);
|
package/tests/crud.ts
CHANGED
|
@@ -34,6 +34,12 @@ export const graffitiCRUDTests = (
|
|
|
34
34
|
session2 = await useSession2();
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
it("get nonexistant object", async () => {
|
|
38
|
+
await expect(graffiti.get(randomString(), {})).rejects.toThrow(
|
|
39
|
+
GraffitiErrorNotFound,
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
37
43
|
it("post, get, delete", async () => {
|
|
38
44
|
const value = {
|
|
39
45
|
something: "hello, world~ c:",
|
package/tests/discover.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { it, expect, describe, assert, beforeAll } from "vitest";
|
|
2
2
|
import type {
|
|
3
3
|
Graffiti,
|
|
4
|
-
GraffitiObjectBase,
|
|
5
4
|
GraffitiSession,
|
|
6
5
|
JSONSchema,
|
|
7
6
|
} from "@graffiti-garden/api";
|
|
7
|
+
import {
|
|
8
|
+
GraffitiErrorForbidden,
|
|
9
|
+
GraffitiErrorInvalidSchema,
|
|
10
|
+
GraffitiErrorNotFound,
|
|
11
|
+
} from "@graffiti-garden/api";
|
|
8
12
|
import {
|
|
9
13
|
randomString,
|
|
10
14
|
nextStreamValue,
|
|
@@ -103,6 +107,19 @@ export const graffitiDiscoverTests = (
|
|
|
103
107
|
expect(value.actor).toEqual(session1.actor);
|
|
104
108
|
});
|
|
105
109
|
|
|
110
|
+
it("discover bad schema", async () => {
|
|
111
|
+
const iterator = graffiti.discover([], {
|
|
112
|
+
properties: {
|
|
113
|
+
value: {
|
|
114
|
+
//@ts-ignore
|
|
115
|
+
type: "asdf",
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await expect(iterator.next()).rejects.toThrow(GraffitiErrorInvalidSchema);
|
|
121
|
+
});
|
|
122
|
+
|
|
106
123
|
it("discover for actor", async () => {
|
|
107
124
|
const object1 = randomPostObject();
|
|
108
125
|
const posted1 = await graffiti.post<{}>(object1, session1);
|
|
@@ -396,12 +413,47 @@ export const graffitiDiscoverTests = (
|
|
|
396
413
|
assert(!value.done && !value.value.error, "value is done");
|
|
397
414
|
assert(value.value.tombstone, "value is not tombstone");
|
|
398
415
|
expect(value.value.object.url).toEqual(posted.url);
|
|
399
|
-
await
|
|
416
|
+
const returnValue2 = await tombIterator.next();
|
|
417
|
+
assert(returnValue2.done, "value2 is not done");
|
|
418
|
+
|
|
419
|
+
// Post another object
|
|
420
|
+
const posted2 = await graffiti.post<{}>(object, session);
|
|
421
|
+
const doubleContinueIterator = continueStream<{}>(
|
|
422
|
+
graffiti,
|
|
423
|
+
returnValue2.value,
|
|
424
|
+
continueType,
|
|
425
|
+
);
|
|
426
|
+
const value2 = await doubleContinueIterator.next();
|
|
427
|
+
assert(!value2.done && !value2.value.error, "value2 is done");
|
|
428
|
+
assert(!value2.value.tombstone, "value2 is tombstone");
|
|
429
|
+
expect(value2.value.object.url).toEqual(posted2.url);
|
|
430
|
+
await expect(doubleContinueIterator.next()).resolves.toHaveProperty(
|
|
400
431
|
"done",
|
|
401
432
|
true,
|
|
402
433
|
);
|
|
403
434
|
});
|
|
435
|
+
|
|
436
|
+
it("continue with wrong actor", async () => {
|
|
437
|
+
const iterator = graffiti.discover<{}>([], {}, session1);
|
|
438
|
+
const result = await iterator.next();
|
|
439
|
+
assert(result.done, "iterator is not done");
|
|
440
|
+
|
|
441
|
+
const continuation = continueStream<{}>(
|
|
442
|
+
graffiti,
|
|
443
|
+
result.value,
|
|
444
|
+
continueType,
|
|
445
|
+
session2,
|
|
446
|
+
);
|
|
447
|
+
await expect(continuation.next()).rejects.toThrow(
|
|
448
|
+
GraffitiErrorForbidden,
|
|
449
|
+
);
|
|
450
|
+
});
|
|
404
451
|
});
|
|
405
452
|
}
|
|
453
|
+
|
|
454
|
+
it("lookup non-existant cursor", async () => {
|
|
455
|
+
const iterator = graffiti.continueDiscover(randomString());
|
|
456
|
+
await expect(iterator.next()).rejects.toThrow(GraffitiErrorNotFound);
|
|
457
|
+
});
|
|
406
458
|
});
|
|
407
459
|
};
|