rmapi-js 10.0.0 → 10.1.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/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type BackgroundFilter, type CollectionContent, type Content, type DocumentContent, type Metadata, type Orientation, type RawRemarkableApi, type SimpleEntry, type Tag, type TemplateContent, type TextAlignment, type ZoomMode } from "./raw";
2
2
  export { HashNotFoundError, ValidationError } from "./error";
3
- export type { BackgroundFilter, CollectionContent, Content, CPageNumberValue, CPagePage, CPageStringValue, CPages, CPageUUID, DocumentContent, DocumentMetadata, Entries, FileType, KeyboardMetadata, Metadata, Orientation, PageTag, RawEntry, RawRemarkableApi, SchemaVersion, SimpleEntry, Tag, TemplateContent, TextAlignment, UploadMimeType, ZoomMode, } from "./raw";
3
+ export type { BackgroundFilter, CollectionContent, Content, CPageNumberValue, CPagePage, CPageStringValue, CPages, CPageUUID, DocumentContent, DocumentMetadata, Entries, FileType, KeyboardMetadata, LegacyCollectionContent, LegacyDocumentContent, Metadata, Orientation, PageTag, RawEntry, RawRemarkableApi, SchemaVersion, SimpleEntry, Tag, TemplateContent, TextAlignment, UploadMimeType, ZoomMode, } from "./raw";
4
4
  /** common properties shared by collections and documents */
5
5
  export interface EntryCommon {
6
6
  /** the document id, a uuid4 */
@@ -21,7 +21,7 @@ export interface EntryCommon {
21
21
  */
22
22
  parent?: string;
23
23
  /** any tags the entry might have */
24
- tags?: Tag[];
24
+ tags?: Tag[] | string[];
25
25
  }
26
26
  /** a folder, referred to in the api as a collection */
27
27
  export interface CollectionEntry extends EntryCommon {
package/dist/index.js CHANGED
@@ -348,7 +348,7 @@ class Remarkable {
348
348
  ]);
349
349
  // now upload a new root entry
350
350
  rootEntries.push(collectionEntry);
351
- const [rootEntry, uploadRoot] = await this.raw.putEntries("root", rootEntries, schemaVersion);
351
+ const [rootEntry, uploadRoot] = await this.raw.putEntries("root", rootEntries, 4);
352
352
  // before updating the root hash, first upload everything
353
353
  await Promise.all([
354
354
  uploadContent,
@@ -402,7 +402,7 @@ class Remarkable {
402
402
  ]);
403
403
  // now upload a new root entry
404
404
  rootEntries.push(collectionEntry);
405
- const [rootEntry, uploadRoot] = await this.raw.putEntries("root", rootEntries, schemaVersion);
405
+ const [rootEntry, uploadRoot] = await this.raw.putEntries("root", rootEntries, 4);
406
406
  // before updating the root hash, first upload everything
407
407
  await Promise.all([
408
408
  uploadContent,
@@ -459,7 +459,7 @@ class Remarkable {
459
459
  throw new Error(`expected type ${expectedType} but got ${meta.type} for hash ${hash}`);
460
460
  }
461
461
  entries[hashInd] = newEnt;
462
- const [rootEntry, uploadRoot] = await this.raw.putEntries("root", entries, schemaVersion);
462
+ const [rootEntry, uploadRoot] = await this.raw.putEntries("root", entries, 4);
463
463
  await Promise.all([uploadEnt, uploadRoot]);
464
464
  await this.#putRootHash(rootEntry.hash, generation);
465
465
  return { hash: newEnt.hash };
@@ -501,7 +501,7 @@ class Remarkable {
501
501
  }
502
502
  const [newEnt, uploadEnt] = await this.#editMetaRaw(hashEnt.id, hash, update, schemaVersion);
503
503
  entries[hashInd] = newEnt;
504
- const [rootEntry, uploadRoot] = await this.raw.putEntries("root", entries, schemaVersion);
504
+ const [rootEntry, uploadRoot] = await this.raw.putEntries("root", entries, 4);
505
505
  await Promise.all([uploadEnt, uploadRoot]);
506
506
  await this.#putRootHash(rootEntry.hash, generation);
507
507
  return { hash: newEnt.hash };
@@ -547,7 +547,7 @@ class Remarkable {
547
547
  uploads.push(upload);
548
548
  result[toUpdate[i].hash] = newEnt.hash;
549
549
  }
550
- const [rootEntry, uploadRoot] = await this.raw.putEntries("root", newEntries, schemaVersion);
550
+ const [rootEntry, uploadRoot] = await this.raw.putEntries("root", newEntries, 4);
551
551
  await Promise.all([Promise.all(uploads), uploadRoot]);
552
552
  await this.#putRootHash(rootEntry.hash, generation);
553
553
  return { hashes: result };
package/dist/raw.d.ts CHANGED
@@ -147,13 +147,21 @@ export interface CollectionContent {
147
147
  /** collections don't have a file type */
148
148
  fileType?: undefined;
149
149
  }
150
+ /** legacy collection content can store tags as raw strings */
151
+ export interface LegacyCollectionContent {
152
+ /** the legacy tag names for the collection */
153
+ tags?: string[];
154
+ /** collections don't have a file type */
155
+ fileType?: undefined;
156
+ }
150
157
  /**
151
158
  * content metadata, stored with the "content" extension
152
159
  *
153
160
  * This largely contains description of how to render the document, rather than
154
161
  * metadata about it.
155
162
  */
156
- export interface DocumentContent {
163
+ /** fields shared by current and legacy document content payloads */
164
+ export interface CommonDocumentContent {
157
165
  /**
158
166
  * which page to use for the thumbnail
159
167
  *
@@ -209,8 +217,6 @@ export interface DocumentContent {
209
217
  redirectionPageMap?: number[];
210
218
  /** ostensibly the size in bytes of the file, but this differs from other measurements */
211
219
  sizeInBytes: string;
212
- /** document tags for this document */
213
- tags?: Tag[];
214
220
  /** text alignment for this document */
215
221
  textAlignment: TextAlignment;
216
222
  /**
@@ -269,6 +275,16 @@ export interface DocumentContent {
269
275
  */
270
276
  viewBackgroundFilter?: BackgroundFilter;
271
277
  }
278
+ /** document content with modern structured tag payloads */
279
+ export interface DocumentContent extends CommonDocumentContent {
280
+ /** document tags for this document */
281
+ tags?: Tag[];
282
+ }
283
+ /** legacy document content can store tags as raw strings */
284
+ export interface LegacyDocumentContent extends CommonDocumentContent {
285
+ /** the legacy tag names for this document */
286
+ tags?: string[];
287
+ }
272
288
  /**
273
289
  * content metadata, stored with the "content" extension
274
290
  *
@@ -307,7 +323,7 @@ export interface TemplateContent {
307
323
  items: object[];
308
324
  }
309
325
  /** content metadata for any item */
310
- export type Content = CollectionContent | DocumentContent | TemplateContent;
326
+ export type Content = CollectionContent | LegacyCollectionContent | DocumentContent | LegacyDocumentContent | TemplateContent;
311
327
  /**
312
328
  * item level metadata
313
329
  *
@@ -533,6 +549,11 @@ export interface RawRemarkableApi {
533
549
  * 3. append this entry to the root entry and call this again to update this root list
534
550
  * 4. put the new root hash
535
551
  *
552
+ * NOTE: reMarkable currently rejects newly written schema 3 root indexes
553
+ * with a 400 "Software must be updated" error, even for accounts that still
554
+ * report schema 3, so the root list should always be written as schema 4. A
555
+ * warning is logged if a schema 3 root index is written.
556
+ *
536
557
  * @param id - the id of the list to upload - this should be the item id if
537
558
  * uploading an item list, or "root" if uploading a new root list.
538
559
  * @param entries - the entries to upload
package/dist/raw.js CHANGED
@@ -65,7 +65,10 @@ const cPages = properties({
65
65
  const collectionContent = properties(undefined, {
66
66
  tags: elements(tag),
67
67
  });
68
- const documentContent = properties({
68
+ const legacyCollectionContent = properties(undefined, {
69
+ tags: elements(string()),
70
+ });
71
+ const documentContentRequired = {
69
72
  coverPageNumber: int32(),
70
73
  documentMetadata,
71
74
  extraMetadata: values(string()),
@@ -77,7 +80,8 @@ const documentContent = properties({
77
80
  sizeInBytes: string(),
78
81
  textAlignment: enumeration("", "justify", "left"),
79
82
  textScale: float64(),
80
- }, {
83
+ };
84
+ const documentContentOptional = {
81
85
  cPages,
82
86
  customZoomCenterX: float64(),
83
87
  customZoomCenterY: float64(),
@@ -97,7 +101,6 @@ const documentContent = properties({
97
101
  pages: nullable(elements(string())),
98
102
  pageTags: elements(pageTag),
99
103
  redirectionPageMap: elements(int32()),
100
- tags: elements(tag),
101
104
  transform: properties(undefined, {
102
105
  m11: float64(),
103
106
  m12: float64(),
@@ -112,6 +115,14 @@ const documentContent = properties({
112
115
  // eslint-disable-next-line spellcheck/spell-checker
113
116
  viewBackgroundFilter: enumeration("off", "fullpage"),
114
117
  zoomMode: enumeration("bestFit", "customFit", "fitToHeight", "fitToWidth"),
118
+ };
119
+ const documentContent = properties(documentContentRequired, {
120
+ ...documentContentOptional,
121
+ tags: elements(tag),
122
+ }, true);
123
+ const legacyDocumentContent = properties(documentContentRequired, {
124
+ ...documentContentOptional,
125
+ tags: elements(string()),
115
126
  }, true);
116
127
  const templateContent = properties({
117
128
  name: string(),
@@ -298,8 +309,10 @@ export class RawRemarkable {
298
309
  const errors = [];
299
310
  for (const [name, valid] of [
300
311
  ["collection", collectionContent],
312
+ ["legacy collection", legacyCollectionContent],
301
313
  ["template", templateContent],
302
314
  ["document", documentContent],
315
+ ["legacy document", legacyDocumentContent],
303
316
  ]) {
304
317
  try {
305
318
  if (valid.guardAssert(loaded))
@@ -407,6 +420,9 @@ export class RawRemarkable {
407
420
  }
408
421
  }
409
422
  async putEntries(id, entries, schemaVersion) {
423
+ if (id === "root" && schemaVersion === 3) {
424
+ console.warn('writing a schema 3 root index, which reMarkable rejects with a 400 "Software must be updated" error; write the root index with schema version 4 instead');
425
+ }
410
426
  // NOTE v3 collections have a special hash function, the hash of their
411
427
  // contents, so this needs to be different
412
428
  entries.sort((a, b) => a.id.localeCompare(b.id));
@@ -417,7 +433,8 @@ export class RawRemarkable {
417
433
  records.push(`0:${name}:${entries.length}:${size}\n`);
418
434
  }
419
435
  for (const { hash, type, id, subfiles, size } of entries) {
420
- records.push(`${hash}:${type}:${id}:${subfiles}:${size}\n`);
436
+ const lineType = schemaVersion === 4 ? 0 : type;
437
+ records.push(`${hash}:${lineType}:${id}:${subfiles}:${size}\n`);
421
438
  }
422
439
  const enc = new TextEncoder();
423
440
  const entryBuff = enc.encode(records.join(""));