notefeed 0.9.3 → 0.10.1

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/README.md CHANGED
@@ -31,6 +31,6 @@ A posted note can be changed or removed: `await client.edit(id, content)` replac
31
31
 
32
32
  A feed can have a title and a description, and can be deleted: `await client.feedInfo()` returns `{ name, title, description, protected, read_url }`, `await client.updateFeed({ title, description })` replaces both (an empty string clears one) and returns the feed, and `await client.deleteFeed()` removes the feed with all its notes for good. All three take the same `{ feed, feedPassword }` options as `post`, and a feed that doesn't exist is a `NotFoundError`. Anyone who can post to a feed can do this, and deleting is permanent; there are no `notefeed` commands for it.
33
33
 
34
- A picture is a note of its own: `await client.post(bytes, { type: "image/png", alt: "…" })` takes a `Uint8Array` or a `Blob` (PNG, JPEG, GIF or WebP; a Blob's own type is used if you leave `type` out) and returns what a markdown post returns, with the picture's `file` and `file_url` added. Write `![](file)` in a markdown note to show it; the feed is created by its first note, and a picture that is too large is a `NoteTooLargeError`. The server checks the bytes against the declared type. `await client.update(id, { title, alt })` changes a note's title or a picture's alt text, and `await client.edit(id, content)` replaces its content. `await client.updateFeed({ title, description, image: file })` makes a picture the feed's title image (`image: ""` removes it; leaving `image` out keeps it). `notefeed post --file photo.png` posts a file (the type comes from the extension, or `--type`). To post a note with its pictures in one call, `await client.post(text, { attachments: [{ name: "chart.png", content: bytes, type: "image/png" }] })` posts them with the text in one request, and the server swaps `![](chart.png)` for each file name (`null` content posts only the pictures) (`notefeed post "…" --attach chart.png` does the same); nothing is posted when one is refused. Pictures are public to anyone with the feed's read link, and metadata such as EXIF is not removed.
34
+ A picture is a note of its own: `await client.post(bytes, { type: "image/png", alt: "…" })` takes a `Uint8Array` or a `Blob` (PNG, JPEG, GIF or WebP; a Blob's own type is used if you leave `type` out) and returns what a markdown post returns, with the picture's `file` and `file_url` added. Write `![](file)` in a markdown note to show it; the feed is created by its first note, a picture that is too large is a `NoteTooLargeError`, and an instance that takes no pictures (`NOTEFEED_IMAGE_UPLOADS=0`) answers every picture with an `ImagesOffError`. The server checks the bytes against the declared type. `await client.update(id, { title, alt })` changes a note's title or a picture's alt text, and `await client.edit(id, content)` replaces its content. `await client.updateFeed({ title, description, image: file })` makes a picture the feed's title image (`image: ""` removes it; leaving `image` out keeps it). `notefeed post --file photo.png` posts a file (the type comes from the extension, or `--type`). To post a note with its pictures in one call, `await client.post(text, { attachments: [{ name: "chart.png", content: bytes, type: "image/png" }] })` posts them with the text in one request, and the server swaps `![](chart.png)` for each file name (`null` content posts only the pictures) (`notefeed post "…" --attach chart.png` does the same); nothing is posted when one is refused. Pictures are public to anyone with the feed's read link, and metadata such as EXIF is not removed.
35
35
 
36
36
  Full documentation: https://docs.notefeed.me/integrations/clients/
package/dist/client.d.ts CHANGED
@@ -34,7 +34,7 @@ export declare class RateLimitedError extends NotefeedError {
34
34
  readonly retryAfter: number | null;
35
35
  constructor(message: string, status: number | null, code: ErrorCode | null, retryAfter: number | null);
36
36
  }
37
- /** No such note, or a malformed read id. */
37
+ /** No such note, or a malformed read id; also a feed the operator removed for good (`removed`, 410). */
38
38
  export declare class NotFoundError extends NotefeedError {
39
39
  }
40
40
  /** The instance's feed or note limit, or the feed's image limit, is reached. */
@@ -43,7 +43,10 @@ export declare class LimitReachedError extends NotefeedError {
43
43
  /** The note or image is over the server's size limit. */
44
44
  export declare class NoteTooLargeError extends NotefeedError {
45
45
  }
46
- /** The server refused the request itself: invalid or reserved feed, empty note, bad body or parameter. */
46
+ /** The instance takes no pictures (`NOTEFEED_IMAGE_UPLOADS=0`): an image, a replaced picture or attachments were refused. */
47
+ export declare class ImagesOffError extends NotefeedError {
48
+ }
49
+ /** The server refused the request itself: invalid or reserved feed, empty note, bad body or parameter, or an image on the instance's blocklist (`blocked`, 451). */
47
50
  export declare class InvalidRequestError extends NotefeedError {
48
51
  }
49
52
  export declare class Client {
package/dist/client.js CHANGED
@@ -29,7 +29,7 @@ export class RateLimitedError extends NotefeedError {
29
29
  this.retryAfter = retryAfter;
30
30
  }
31
31
  }
32
- /** No such note, or a malformed read id. */
32
+ /** No such note, or a malformed read id; also a feed the operator removed for good (`removed`, 410). */
33
33
  export class NotFoundError extends NotefeedError {
34
34
  }
35
35
  /** The instance's feed or note limit, or the feed's image limit, is reached. */
@@ -38,7 +38,10 @@ export class LimitReachedError extends NotefeedError {
38
38
  /** The note or image is over the server's size limit. */
39
39
  export class NoteTooLargeError extends NotefeedError {
40
40
  }
41
- /** The server refused the request itself: invalid or reserved feed, empty note, bad body or parameter. */
41
+ /** The instance takes no pictures (`NOTEFEED_IMAGE_UPLOADS=0`): an image, a replaced picture or attachments were refused. */
42
+ export class ImagesOffError extends NotefeedError {
43
+ }
44
+ /** The server refused the request itself: invalid or reserved feed, empty note, bad body or parameter, or an image on the instance's blocklist (`blocked`, 451). */
42
45
  export class InvalidRequestError extends NotefeedError {
43
46
  }
44
47
  const BY_CODE = {
@@ -47,6 +50,7 @@ const BY_CODE = {
47
50
  feed_limit: LimitReachedError,
48
51
  note_limit: LimitReachedError,
49
52
  image_limit: LimitReachedError,
53
+ images_off: ImagesOffError,
50
54
  too_large: NoteTooLargeError,
51
55
  invalid_feed: InvalidRequestError,
52
56
  reserved_feed: InvalidRequestError,
@@ -55,6 +59,8 @@ const BY_CODE = {
55
59
  invalid_request: InvalidRequestError,
56
60
  feed_exists: InvalidRequestError,
57
61
  taken: InvalidRequestError,
62
+ removed: NotFoundError,
63
+ blocked: InvalidRequestError,
58
64
  unsupported_type: InvalidRequestError,
59
65
  };
60
66
  const IMAGE_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
@@ -80,19 +80,19 @@ export declare const changeFeedPassword: <ThrowOnError extends boolean = false>(
80
80
  /**
81
81
  * Get a feed's title and description by its read id
82
82
  *
83
- * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id has an empty title and description, so read ids can't be probed.
83
+ * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id has an empty title and description, so read ids can't be probed; one the operator removed is `410`.
84
84
  */
85
85
  export declare const getReadFeed: <ThrowOnError extends boolean = false>(options: Options<GetReadFeedData, ThrowOnError>) => RequestResult<GetReadFeedResponses, GetReadFeedErrors, ThrowOnError>;
86
86
  /**
87
87
  * List a feed's notes by its read id
88
88
  *
89
- * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id is an empty list, so read ids can't be probed. The same notes as the read link's RSS.
89
+ * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id is an empty list, so read ids can't be probed; one the operator removed is `410`. The same notes as the read link's RSS.
90
90
  */
91
91
  export declare const listReadNotes: <ThrowOnError extends boolean = false>(options: Options<ListReadNotesData, ThrowOnError>) => RequestResult<ListReadNotesResponses, ListReadNotesErrors, ThrowOnError>;
92
92
  /**
93
93
  * Get one note by its feed's read id
94
94
  *
95
- * Public, like the read link.
95
+ * Public, like the read link. A read id the operator removed is `410`.
96
96
  */
97
97
  export declare const getReadNote: <ThrowOnError extends boolean = false>(options: Options<GetReadNoteData, ThrowOnError>) => RequestResult<GetReadNoteResponses, GetReadNoteErrors, ThrowOnError>;
98
98
  /**
@@ -133,19 +133,19 @@ export const changeFeedPassword = (options) => (options.client ?? client).put({
133
133
  /**
134
134
  * Get a feed's title and description by its read id
135
135
  *
136
- * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id has an empty title and description, so read ids can't be probed.
136
+ * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id has an empty title and description, so read ids can't be probed; one the operator removed is `410`.
137
137
  */
138
138
  export const getReadFeed = (options) => (options.client ?? client).get({ url: '/api/v1/read/{readId}', ...options });
139
139
  /**
140
140
  * List a feed's notes by its read id
141
141
  *
142
- * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id is an empty list, so read ids can't be probed. The same notes as the read link's RSS.
142
+ * Public, even on an instance with a password, and never reveals the feed's name. An unknown read id is an empty list, so read ids can't be probed; one the operator removed is `410`. The same notes as the read link's RSS.
143
143
  */
144
144
  export const listReadNotes = (options) => (options.client ?? client).get({ url: '/api/v1/read/{readId}/notes', ...options });
145
145
  /**
146
146
  * Get one note by its feed's read id
147
147
  *
148
- * Public, like the read link.
148
+ * Public, like the read link. A read id the operator removed is `410`.
149
149
  */
150
150
  export const getReadNote = (options) => (options.client ?? client).get({ url: '/api/v1/read/{readId}/notes/{id}', ...options });
151
151
  /**
@@ -194,7 +194,7 @@ export type Error = {
194
194
  /**
195
195
  * Stable machine-readable code; absent only on a 500
196
196
  */
197
- code?: 'invalid_feed' | 'reserved_feed' | 'auth' | 'rate_limited' | 'too_many_attempts' | 'feed_limit' | 'note_limit' | 'image_limit' | 'empty_note' | 'too_large' | 'unsupported_type' | 'invalid_body' | 'invalid_request' | 'not_found' | 'feed_exists' | 'taken';
197
+ code?: 'invalid_feed' | 'reserved_feed' | 'auth' | 'rate_limited' | 'too_many_attempts' | 'feed_limit' | 'note_limit' | 'image_limit' | 'images_off' | 'empty_note' | 'too_large' | 'unsupported_type' | 'invalid_body' | 'invalid_request' | 'not_found' | 'feed_exists' | 'taken' | 'removed' | 'blocked';
198
198
  };
199
199
  export type NoteMeta = {
200
200
  /**
@@ -379,10 +379,18 @@ export type PostNoteErrors = {
379
379
  * The instance has a password, or the feed has its own, and it is missing or wrong
380
380
  */
381
381
  401: Error;
382
+ /**
383
+ * Image uploads are off on this instance (`NOTEFEED_IMAGE_UPLOADS=0`, code `images_off`): an image body, a picture replaced, or a multipart body with pictures. Stored pictures are still served
384
+ */
385
+ 403: Error;
382
386
  /**
383
387
  * A password was sent for a feed that already exists without one: it can't be claimed; or the chosen read id is taken
384
388
  */
385
389
  409: Error;
390
+ /**
391
+ * The operator removed this feed for good (`removed`): its name cannot be used again
392
+ */
393
+ 410: Error;
386
394
  /**
387
395
  * Markdown over 102400 bytes, or an image over NOTEFEED_MAX_IMAGE_BYTES (each picture of a multipart body too), or a multipart body over 102400 bytes plus 10 images plus 64 KiB
388
396
  */
@@ -395,6 +403,10 @@ export type PostNoteErrors = {
395
403
  * Too many posts, or wrong passwords, from this client
396
404
  */
397
405
  429: Error;
406
+ /**
407
+ * An image the operator removed, which may not be posted again in any feed (`blocked`)
408
+ */
409
+ 451: Error;
398
410
  /**
399
411
  * NOTEFEED_MAX_FEEDS, NOTEFEED_MAX_NOTES_PER_FEED or NOTEFEED_MAX_IMAGES_PER_FEED reached
400
412
  */
@@ -590,6 +602,10 @@ export type EditNoteErrors = {
590
602
  * The instance has a password, or the feed has its own, and it is missing or wrong
591
603
  */
592
604
  401: Error;
605
+ /**
606
+ * Image uploads are off on this instance (`NOTEFEED_IMAGE_UPLOADS=0`, code `images_off`): an image body, a picture replaced, or a multipart body with pictures. Stored pictures are still served
607
+ */
608
+ 403: Error;
593
609
  /**
594
610
  * No such note
595
611
  */
@@ -606,6 +622,10 @@ export type EditNoteErrors = {
606
622
  * Too many posts, edits and deletes, or wrong passwords, from this client
607
623
  */
608
624
  429: Error;
625
+ /**
626
+ * An image the operator removed, which may not be posted again in any feed (`blocked`)
627
+ */
628
+ 451: Error;
609
629
  /**
610
630
  * NOTEFEED_MAX_IMAGES_PER_FEED reached
611
631
  */
@@ -854,6 +874,10 @@ export type GetReadFeedErrors = {
854
874
  * Malformed read id
855
875
  */
856
876
  404: Error;
877
+ /**
878
+ * The operator removed the feed this read id belonged to (`removed`)
879
+ */
880
+ 410: Error;
857
881
  };
858
882
  export type GetReadFeedError = GetReadFeedErrors[keyof GetReadFeedErrors];
859
883
  export type GetReadFeedResponses = {
@@ -896,6 +920,10 @@ export type ListReadNotesErrors = {
896
920
  * Malformed read id
897
921
  */
898
922
  404: Error;
923
+ /**
924
+ * The operator removed the feed this read id belonged to (`removed`)
925
+ */
926
+ 410: Error;
899
927
  };
900
928
  export type ListReadNotesError = ListReadNotesErrors[keyof ListReadNotesErrors];
901
929
  export type ListReadNotesResponses = {
@@ -925,6 +953,10 @@ export type GetReadNoteErrors = {
925
953
  * No such note, or a malformed or unknown read id
926
954
  */
927
955
  404: Error;
956
+ /**
957
+ * The operator removed the feed this read id belonged to (`removed`)
958
+ */
959
+ 410: Error;
928
960
  };
929
961
  export type GetReadNoteError = GetReadNoteErrors[keyof GetReadNoteErrors];
930
962
  export type GetReadNoteResponses = {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { AuthError, Client, ConfigError, InvalidRequestError, LimitReachedError, NotefeedError, NotFoundError, NoteTooLargeError, RateLimitedError, } from "./client.js";
1
+ export { AuthError, Client, ConfigError, ImagesOffError, InvalidRequestError, LimitReachedError, NotefeedError, NotFoundError, NoteTooLargeError, RateLimitedError, } from "./client.js";
2
2
  export type { Attachment, ClientOptions, Created, ErrorCode, Feed, FeedSettings, Note } from "./client.js";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export { AuthError, Client, ConfigError, InvalidRequestError, LimitReachedError, NotefeedError, NotFoundError, NoteTooLargeError, RateLimitedError, } from "./client.js";
1
+ export { AuthError, Client, ConfigError, ImagesOffError, InvalidRequestError, LimitReachedError, NotefeedError, NotFoundError, NoteTooLargeError, RateLimitedError, } from "./client.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notefeed",
3
- "version": "0.9.3",
3
+ "version": "0.10.1",
4
4
  "description": "Client and CLI for notefeed, a self-hosted inbox for markdown notes that you read back as RSS.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Marcel Bruckner",