@comapeo/core 5.4.1 → 6.0.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/blob-api.d.ts.map +1 -1
- package/dist/blob-store/downloader.d.ts.map +1 -1
- package/dist/blob-store/hyperdrive-index.d.ts.map +1 -1
- package/dist/blob-store/index.d.ts.map +1 -1
- package/dist/core-manager/bitfield-rle.d.ts.map +1 -1
- package/dist/core-manager/core-index.d.ts.map +1 -1
- package/dist/core-manager/index.d.ts +1 -2
- package/dist/core-manager/index.d.ts.map +1 -1
- package/dist/core-ownership.d.ts.map +1 -1
- package/dist/datastore/index.d.ts.map +1 -1
- package/dist/datatype/index.d.ts +7 -0
- package/dist/datatype/index.d.ts.map +1 -1
- package/dist/discovery/local-discovery.d.ts.map +1 -1
- package/dist/errors.d.ts +437 -35
- package/dist/errors.d.ts.map +1 -1
- package/dist/fastify-plugins/blobs.d.ts.map +1 -1
- package/dist/fastify-plugins/icons.d.ts.map +1 -1
- package/dist/fastify-plugins/maps.d.ts.map +1 -1
- package/dist/generated/extensions.d.ts +1 -1
- package/dist/generated/extensions.d.ts.map +1 -1
- package/dist/generated/rpc.d.ts +1 -0
- package/dist/generated/rpc.d.ts.map +1 -1
- package/dist/icon-api.d.ts +0 -1
- package/dist/icon-api.d.ts.map +1 -1
- package/dist/import-categories.d.ts.map +1 -1
- package/dist/index-writer/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/intl/parse-bcp-47.d.ts.map +1 -1
- package/dist/invite/invite-api.d.ts.map +1 -1
- package/dist/lib/drizzle-helpers.d.ts.map +1 -1
- package/dist/lib/hypercore-helpers.d.ts.map +1 -1
- package/dist/lib/key-by.d.ts.map +1 -1
- package/dist/local-peers.d.ts +0 -14
- package/dist/local-peers.d.ts.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/mapeo-manager.d.ts +2 -1
- package/dist/mapeo-manager.d.ts.map +1 -1
- package/dist/mapeo-project.d.ts +15 -8
- package/dist/mapeo-project.d.ts.map +1 -1
- package/dist/member-api.d.ts +42 -7
- package/dist/member-api.d.ts.map +1 -1
- package/dist/roles.d.ts.map +1 -1
- package/dist/schema/json-schema-to-drizzle.d.ts.map +1 -1
- package/dist/schema.d.ts +2 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/sync/core-sync-state.d.ts.map +1 -1
- package/dist/sync/peer-sync-controller.d.ts.map +1 -1
- package/dist/sync/sync-api.d.ts.map +1 -1
- package/dist/utils.d.ts +8 -10
- package/dist/utils.d.ts.map +1 -1
- package/package.json +18 -2
- package/src/blob-api.js +24 -4
- package/src/blob-store/downloader.js +7 -6
- package/src/blob-store/entries-stream.js +1 -1
- package/src/blob-store/hyperdrive-index.js +3 -5
- package/src/blob-store/index.js +15 -20
- package/src/core-manager/bitfield-rle.js +2 -1
- package/src/core-manager/core-index.js +2 -1
- package/src/core-manager/index.js +12 -13
- package/src/core-ownership.js +7 -3
- package/src/datastore/index.js +13 -9
- package/src/datatype/index.js +28 -5
- package/src/discovery/local-discovery.js +8 -7
- package/src/errors.js +530 -62
- package/src/fastify-controller.js +3 -3
- package/src/fastify-plugins/blobs.js +21 -14
- package/src/fastify-plugins/icons.js +18 -9
- package/src/fastify-plugins/maps.js +6 -5
- package/src/generated/extensions.d.ts +1 -1
- package/src/generated/extensions.js +5 -5
- package/src/generated/extensions.ts +6 -6
- package/src/generated/rpc.d.ts +1 -0
- package/src/generated/rpc.js +12 -1
- package/src/generated/rpc.ts +13 -0
- package/src/icon-api.js +15 -7
- package/src/import-categories.js +6 -7
- package/src/index-writer/index.js +3 -2
- package/src/index.js +1 -0
- package/src/intl/parse-bcp-47.js +2 -1
- package/src/invite/invite-api.js +26 -20
- package/src/lib/drizzle-helpers.js +54 -39
- package/src/lib/hypercore-helpers.js +4 -2
- package/src/lib/key-by.js +3 -1
- package/src/local-peers.js +39 -46
- package/src/logger.js +2 -1
- package/src/mapeo-manager.js +36 -23
- package/src/mapeo-project.js +96 -67
- package/src/member-api.js +177 -96
- package/src/roles.js +11 -10
- package/src/schema/json-schema-to-drizzle.js +13 -4
- package/src/schema.js +1 -0
- package/src/sync/core-sync-state.js +2 -1
- package/src/sync/peer-sync-controller.js +4 -3
- package/src/sync/sync-api.js +9 -9
- package/src/translation-api.js +2 -2
- package/src/utils.js +58 -43
- package/dist/lib/error.d.ts +0 -51
- package/dist/lib/error.d.ts.map +0 -1
- package/src/lib/error.js +0 -71
|
@@ -5,7 +5,13 @@ import { Type as T } from '@sinclair/typebox'
|
|
|
5
5
|
|
|
6
6
|
import { SUPPORTED_BLOB_VARIANTS } from '../blob-store/index.js'
|
|
7
7
|
import { HEX_REGEX_32_BYTES, Z_BASE_32_REGEX_32_BYTES } from './constants.js'
|
|
8
|
-
import {
|
|
8
|
+
import { ensureKnownError } from '../errors.js'
|
|
9
|
+
import {
|
|
10
|
+
BlobNotFoundError,
|
|
11
|
+
BlobStoreEntryNotFoundError,
|
|
12
|
+
UnsupportedVariantError,
|
|
13
|
+
} from '../errors.js'
|
|
14
|
+
import ensureError from 'ensure-error'
|
|
9
15
|
|
|
10
16
|
/** @import { BlobId } from '../types.js' */
|
|
11
17
|
|
|
@@ -45,7 +51,7 @@ const PARAMS_JSON_SCHEMA = T.Object({
|
|
|
45
51
|
|
|
46
52
|
/** @type {import('fastify').FastifyPluginAsync<import('fastify').RegisterOptions & BlobServerPluginOpts>} */
|
|
47
53
|
async function blobServerPlugin(fastify, options) {
|
|
48
|
-
if (!options.getBlobStore) throw new
|
|
54
|
+
if (!options.getBlobStore) throw new TypeError('Missing getBlobStore')
|
|
49
55
|
|
|
50
56
|
// We call register here so that the `prefix` option can work if desired
|
|
51
57
|
// https://fastify.dev/docs/latest/Reference/Routes#route-prefixing-and-fastify-plugin
|
|
@@ -64,9 +70,10 @@ async function routes(fastify, options) {
|
|
|
64
70
|
|
|
65
71
|
if (!isValidBlobId(blobId)) {
|
|
66
72
|
reply.code(400)
|
|
67
|
-
throw new
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
throw new UnsupportedVariantError({
|
|
74
|
+
variant: blobId.variant,
|
|
75
|
+
type: blobId.type,
|
|
76
|
+
})
|
|
70
77
|
}
|
|
71
78
|
const { driveId } = blobId
|
|
72
79
|
|
|
@@ -75,7 +82,7 @@ async function routes(fastify, options) {
|
|
|
75
82
|
blobStore = await getBlobStore(projectPublicId)
|
|
76
83
|
} catch (e) {
|
|
77
84
|
reply.code(404)
|
|
78
|
-
throw e
|
|
85
|
+
throw ensureKnownError(e)
|
|
79
86
|
}
|
|
80
87
|
|
|
81
88
|
let entry
|
|
@@ -83,12 +90,12 @@ async function routes(fastify, options) {
|
|
|
83
90
|
entry = await blobStore.entry(blobId, { wait: false })
|
|
84
91
|
} catch (e) {
|
|
85
92
|
reply.code(404)
|
|
86
|
-
throw e
|
|
93
|
+
throw ensureKnownError(e)
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
if (!entry) {
|
|
90
97
|
reply.code(404)
|
|
91
|
-
throw new
|
|
98
|
+
throw new BlobStoreEntryNotFoundError()
|
|
92
99
|
}
|
|
93
100
|
|
|
94
101
|
const { metadata } = entry.value
|
|
@@ -98,19 +105,19 @@ async function routes(fastify, options) {
|
|
|
98
105
|
blobStream = await blobStore.createReadStreamFromEntry(driveId, entry)
|
|
99
106
|
} catch (e) {
|
|
100
107
|
reply.code(404)
|
|
101
|
-
throw e
|
|
108
|
+
throw ensureKnownError(e)
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
try {
|
|
105
112
|
await pEvent(blobStream, 'readable', { rejectionEvents: ['error'] })
|
|
106
|
-
} catch (
|
|
113
|
+
} catch (e) {
|
|
107
114
|
// This matches [how Hyperblobs checks if a blob is unavailable][0].
|
|
108
115
|
// [0]: https://github.com/holepunchto/hyperblobs/blob/518088d2b828082fd70a276fa2c8848a2cf2a56b/index.js#L49
|
|
109
|
-
if (
|
|
116
|
+
if (ensureError(e).message === 'Block not available') {
|
|
110
117
|
reply.code(404)
|
|
111
|
-
throw new
|
|
118
|
+
throw new BlobNotFoundError()
|
|
112
119
|
} else {
|
|
113
|
-
throw
|
|
120
|
+
throw ensureKnownError(e)
|
|
114
121
|
}
|
|
115
122
|
}
|
|
116
123
|
|
|
@@ -130,7 +137,7 @@ async function routes(fastify, options) {
|
|
|
130
137
|
|
|
131
138
|
if (!blobSlice) {
|
|
132
139
|
reply.code(404)
|
|
133
|
-
throw new
|
|
140
|
+
throw new BlobNotFoundError()
|
|
134
141
|
}
|
|
135
142
|
|
|
136
143
|
const [guessedMime] = filetypemime(blobSlice)
|
|
@@ -4,7 +4,12 @@ import { docSchemas } from '@comapeo/schema'
|
|
|
4
4
|
|
|
5
5
|
import { kGetIconBlob } from '../icon-api.js'
|
|
6
6
|
import { HEX_REGEX_32_BYTES, Z_BASE_32_REGEX_32_BYTES } from './constants.js'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ensureKnownError,
|
|
9
|
+
InvalidIconPixelDensityError,
|
|
10
|
+
InvalidIconSizeError,
|
|
11
|
+
ExhaustivenessError,
|
|
12
|
+
} from '../errors.js'
|
|
8
13
|
|
|
9
14
|
export default fp(iconServerPlugin, {
|
|
10
15
|
fastify: '4.x',
|
|
@@ -42,7 +47,7 @@ const PARAMS_JSON_SCHEMA = T.Object({
|
|
|
42
47
|
case 'image/svg+xml':
|
|
43
48
|
return T.Literal('svg')
|
|
44
49
|
default:
|
|
45
|
-
throw new ExhaustivenessError(mimeType)
|
|
50
|
+
throw new ExhaustivenessError({ value: mimeType })
|
|
46
51
|
}
|
|
47
52
|
})
|
|
48
53
|
),
|
|
@@ -56,7 +61,7 @@ const PARAMS_JSON_SCHEMA = T.Object({
|
|
|
56
61
|
|
|
57
62
|
/** @type {import('fastify').FastifyPluginAsync<import('fastify').RegisterOptions & IconServerPluginOpts>} */
|
|
58
63
|
async function iconServerPlugin(fastify, options) {
|
|
59
|
-
if (!options.getProject) throw new
|
|
64
|
+
if (!options.getProject) throw new TypeError('Missing getProject')
|
|
60
65
|
fastify.register(routes, options)
|
|
61
66
|
}
|
|
62
67
|
|
|
@@ -95,9 +100,9 @@ async function routes(fastify, options) {
|
|
|
95
100
|
|
|
96
101
|
res.header('Content-Type', mimeType)
|
|
97
102
|
return res.send(icon)
|
|
98
|
-
} catch (
|
|
103
|
+
} catch (e) {
|
|
99
104
|
res.code(404)
|
|
100
|
-
throw
|
|
105
|
+
throw ensureKnownError(e)
|
|
101
106
|
}
|
|
102
107
|
}
|
|
103
108
|
)
|
|
@@ -143,16 +148,20 @@ function assertValidSize(value) {
|
|
|
143
148
|
value
|
|
144
149
|
)
|
|
145
150
|
) {
|
|
146
|
-
throw new
|
|
151
|
+
throw new InvalidIconSizeError({ value })
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
154
|
|
|
150
155
|
/**
|
|
151
|
-
* @param {
|
|
156
|
+
* @param {number} value
|
|
152
157
|
* @returns {asserts value is import('../icon-api.js').BitmapOpts['pixelDensity']}
|
|
153
158
|
*/
|
|
154
159
|
function assertValidPixelDensity(value) {
|
|
155
|
-
if (
|
|
156
|
-
|
|
160
|
+
if (
|
|
161
|
+
!VALID_PIXEL_DENSITIES.includes(
|
|
162
|
+
/** @type {import('../icon-api.js').BitmapOpts['pixelDensity']} */ (value)
|
|
163
|
+
)
|
|
164
|
+
) {
|
|
165
|
+
throw new InvalidIconPixelDensityError({ density: value })
|
|
157
166
|
}
|
|
158
167
|
}
|
|
@@ -5,7 +5,8 @@ import { ReaderWatch, createServer } from 'styled-map-package'
|
|
|
5
5
|
|
|
6
6
|
import { noop } from '../utils.js'
|
|
7
7
|
import { NotFoundError, ENOENTError } from './utils.js'
|
|
8
|
-
import { getErrorCode } from '../
|
|
8
|
+
import { ensureKnownError, getErrorCode } from '../errors.js'
|
|
9
|
+
import { FailedToGetStyleError } from '../errors.js'
|
|
9
10
|
|
|
10
11
|
/** @import { FastifyPluginAsync } from 'fastify' */
|
|
11
12
|
/** @import { Stats } from 'node:fs' */
|
|
@@ -48,7 +49,7 @@ export async function plugin(fastify, opts) {
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
if (!response.ok) {
|
|
51
|
-
throw new
|
|
52
|
+
throw new FailedToGetStyleError(customStyleJsonUrl)
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
/** @type {Stats | undefined} */
|
|
@@ -56,12 +57,12 @@ export async function plugin(fastify, opts) {
|
|
|
56
57
|
|
|
57
58
|
try {
|
|
58
59
|
stats = await fs.stat(customMapPath)
|
|
59
|
-
} catch (
|
|
60
|
-
if (getErrorCode(
|
|
60
|
+
} catch (e) {
|
|
61
|
+
if (getErrorCode(e) === 'ENOENT') {
|
|
61
62
|
throw new ENOENTError(customMapPath)
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
throw
|
|
65
|
+
throw ensureKnownError(e)
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
const style = await response.json()
|
|
@@ -43,7 +43,7 @@ export interface MapShareExtension {
|
|
|
43
43
|
/** URLs to map share */
|
|
44
44
|
mapShareUrls: string[];
|
|
45
45
|
/** ID of peer that can receive the map share (each map share is linked to a specific device ID) */
|
|
46
|
-
|
|
46
|
+
receiverDeviceKey: Buffer;
|
|
47
47
|
/** The ID of the map share */
|
|
48
48
|
shareId: string;
|
|
49
49
|
/** The name of the map being shared */
|
|
@@ -332,7 +332,7 @@ export var DownloadIntentExtension_DownloadIntentsEntry = {
|
|
|
332
332
|
function createBaseMapShareExtension() {
|
|
333
333
|
return {
|
|
334
334
|
mapShareUrls: [],
|
|
335
|
-
|
|
335
|
+
receiverDeviceKey: Buffer.alloc(0),
|
|
336
336
|
shareId: "",
|
|
337
337
|
mapName: "",
|
|
338
338
|
mapId: "",
|
|
@@ -351,8 +351,8 @@ export var MapShareExtension = {
|
|
|
351
351
|
var v = _a[_i];
|
|
352
352
|
writer.uint32(10).string(v);
|
|
353
353
|
}
|
|
354
|
-
if (message.
|
|
355
|
-
writer.uint32(18).
|
|
354
|
+
if (message.receiverDeviceKey.length !== 0) {
|
|
355
|
+
writer.uint32(18).bytes(message.receiverDeviceKey);
|
|
356
356
|
}
|
|
357
357
|
if (message.shareId !== "") {
|
|
358
358
|
writer.uint32(26).string(message.shareId);
|
|
@@ -403,7 +403,7 @@ export var MapShareExtension = {
|
|
|
403
403
|
if (tag !== 18) {
|
|
404
404
|
break;
|
|
405
405
|
}
|
|
406
|
-
message.
|
|
406
|
+
message.receiverDeviceKey = reader.bytes();
|
|
407
407
|
continue;
|
|
408
408
|
case 3:
|
|
409
409
|
if (tag !== 26) {
|
|
@@ -481,7 +481,7 @@ export var MapShareExtension = {
|
|
|
481
481
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
482
482
|
var message = createBaseMapShareExtension();
|
|
483
483
|
message.mapShareUrls = ((_a = object.mapShareUrls) === null || _a === void 0 ? void 0 : _a.map(function (e) { return e; })) || [];
|
|
484
|
-
message.
|
|
484
|
+
message.receiverDeviceKey = (_b = object.receiverDeviceKey) !== null && _b !== void 0 ? _b : Buffer.alloc(0);
|
|
485
485
|
message.shareId = (_c = object.shareId) !== null && _c !== void 0 ? _c : "";
|
|
486
486
|
message.mapName = (_d = object.mapName) !== null && _d !== void 0 ? _d : "";
|
|
487
487
|
message.mapId = (_e = object.mapId) !== null && _e !== void 0 ? _e : "";
|
|
@@ -91,7 +91,7 @@ export interface MapShareExtension {
|
|
|
91
91
|
/** URLs to map share */
|
|
92
92
|
mapShareUrls: string[];
|
|
93
93
|
/** ID of peer that can receive the map share (each map share is linked to a specific device ID) */
|
|
94
|
-
|
|
94
|
+
receiverDeviceKey: Buffer;
|
|
95
95
|
/** The ID of the map share */
|
|
96
96
|
shareId: string;
|
|
97
97
|
/** The name of the map being shared */
|
|
@@ -421,7 +421,7 @@ export const DownloadIntentExtension_DownloadIntentsEntry = {
|
|
|
421
421
|
function createBaseMapShareExtension(): MapShareExtension {
|
|
422
422
|
return {
|
|
423
423
|
mapShareUrls: [],
|
|
424
|
-
|
|
424
|
+
receiverDeviceKey: Buffer.alloc(0),
|
|
425
425
|
shareId: "",
|
|
426
426
|
mapName: "",
|
|
427
427
|
mapId: "",
|
|
@@ -439,8 +439,8 @@ export const MapShareExtension = {
|
|
|
439
439
|
for (const v of message.mapShareUrls) {
|
|
440
440
|
writer.uint32(10).string(v!);
|
|
441
441
|
}
|
|
442
|
-
if (message.
|
|
443
|
-
writer.uint32(18).
|
|
442
|
+
if (message.receiverDeviceKey.length !== 0) {
|
|
443
|
+
writer.uint32(18).bytes(message.receiverDeviceKey);
|
|
444
444
|
}
|
|
445
445
|
if (message.shareId !== "") {
|
|
446
446
|
writer.uint32(26).string(message.shareId);
|
|
@@ -493,7 +493,7 @@ export const MapShareExtension = {
|
|
|
493
493
|
break;
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
-
message.
|
|
496
|
+
message.receiverDeviceKey = reader.bytes() as Buffer;
|
|
497
497
|
continue;
|
|
498
498
|
case 3:
|
|
499
499
|
if (tag !== 26) {
|
|
@@ -583,7 +583,7 @@ export const MapShareExtension = {
|
|
|
583
583
|
fromPartial<I extends Exact<DeepPartial<MapShareExtension>, I>>(object: I): MapShareExtension {
|
|
584
584
|
const message = createBaseMapShareExtension();
|
|
585
585
|
message.mapShareUrls = object.mapShareUrls?.map((e) => e) || [];
|
|
586
|
-
message.
|
|
586
|
+
message.receiverDeviceKey = object.receiverDeviceKey ?? Buffer.alloc(0);
|
|
587
587
|
message.shareId = object.shareId ?? "";
|
|
588
588
|
message.mapName = object.mapName ?? "";
|
|
589
589
|
message.mapId = object.mapId ?? "";
|
package/src/generated/rpc.d.ts
CHANGED
package/src/generated/rpc.js
CHANGED
|
@@ -122,6 +122,7 @@ function createBaseInvite() {
|
|
|
122
122
|
projectName: "",
|
|
123
123
|
invitorName: "",
|
|
124
124
|
sendStats: false,
|
|
125
|
+
invitorWroteDeviceInfo: false,
|
|
125
126
|
};
|
|
126
127
|
}
|
|
127
128
|
export var Invite = {
|
|
@@ -154,6 +155,9 @@ export var Invite = {
|
|
|
154
155
|
if (message.sendStats === true) {
|
|
155
156
|
writer.uint32(72).bool(message.sendStats);
|
|
156
157
|
}
|
|
158
|
+
if (message.invitorWroteDeviceInfo === true) {
|
|
159
|
+
writer.uint32(80).bool(message.invitorWroteDeviceInfo);
|
|
160
|
+
}
|
|
157
161
|
return writer;
|
|
158
162
|
},
|
|
159
163
|
decode: function (input, length) {
|
|
@@ -217,6 +221,12 @@ export var Invite = {
|
|
|
217
221
|
}
|
|
218
222
|
message.sendStats = reader.bool();
|
|
219
223
|
continue;
|
|
224
|
+
case 10:
|
|
225
|
+
if (tag !== 80) {
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
message.invitorWroteDeviceInfo = reader.bool();
|
|
229
|
+
continue;
|
|
220
230
|
}
|
|
221
231
|
if ((tag & 7) === 4 || tag === 0) {
|
|
222
232
|
break;
|
|
@@ -229,7 +239,7 @@ export var Invite = {
|
|
|
229
239
|
return Invite.fromPartial(base !== null && base !== void 0 ? base : {});
|
|
230
240
|
},
|
|
231
241
|
fromPartial: function (object) {
|
|
232
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
242
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
233
243
|
var message = createBaseInvite();
|
|
234
244
|
message.inviteId = (_a = object.inviteId) !== null && _a !== void 0 ? _a : Buffer.alloc(0);
|
|
235
245
|
message.projectInviteId = (_b = object.projectInviteId) !== null && _b !== void 0 ? _b : Buffer.alloc(0);
|
|
@@ -240,6 +250,7 @@ export var Invite = {
|
|
|
240
250
|
message.projectColor = (_g = object.projectColor) !== null && _g !== void 0 ? _g : undefined;
|
|
241
251
|
message.projectDescription = (_h = object.projectDescription) !== null && _h !== void 0 ? _h : undefined;
|
|
242
252
|
message.sendStats = (_j = object.sendStats) !== null && _j !== void 0 ? _j : false;
|
|
253
|
+
message.invitorWroteDeviceInfo = (_k = object.invitorWroteDeviceInfo) !== null && _k !== void 0 ? _k : false;
|
|
243
254
|
return message;
|
|
244
255
|
},
|
|
245
256
|
};
|
package/src/generated/rpc.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface Invite {
|
|
|
12
12
|
projectColor?: string | undefined;
|
|
13
13
|
projectDescription?: string | undefined;
|
|
14
14
|
sendStats: boolean;
|
|
15
|
+
invitorWroteDeviceInfo: boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export interface InviteCancel {
|
|
@@ -187,6 +188,7 @@ function createBaseInvite(): Invite {
|
|
|
187
188
|
projectName: "",
|
|
188
189
|
invitorName: "",
|
|
189
190
|
sendStats: false,
|
|
191
|
+
invitorWroteDeviceInfo: false,
|
|
190
192
|
};
|
|
191
193
|
}
|
|
192
194
|
|
|
@@ -219,6 +221,9 @@ export const Invite = {
|
|
|
219
221
|
if (message.sendStats === true) {
|
|
220
222
|
writer.uint32(72).bool(message.sendStats);
|
|
221
223
|
}
|
|
224
|
+
if (message.invitorWroteDeviceInfo === true) {
|
|
225
|
+
writer.uint32(80).bool(message.invitorWroteDeviceInfo);
|
|
226
|
+
}
|
|
222
227
|
return writer;
|
|
223
228
|
},
|
|
224
229
|
|
|
@@ -292,6 +297,13 @@ export const Invite = {
|
|
|
292
297
|
|
|
293
298
|
message.sendStats = reader.bool();
|
|
294
299
|
continue;
|
|
300
|
+
case 10:
|
|
301
|
+
if (tag !== 80) {
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
message.invitorWroteDeviceInfo = reader.bool();
|
|
306
|
+
continue;
|
|
295
307
|
}
|
|
296
308
|
if ((tag & 7) === 4 || tag === 0) {
|
|
297
309
|
break;
|
|
@@ -315,6 +327,7 @@ export const Invite = {
|
|
|
315
327
|
message.projectColor = object.projectColor ?? undefined;
|
|
316
328
|
message.projectDescription = object.projectDescription ?? undefined;
|
|
317
329
|
message.sendStats = object.sendStats ?? false;
|
|
330
|
+
message.invitorWroteDeviceInfo = object.invitorWroteDeviceInfo ?? false;
|
|
318
331
|
return message;
|
|
319
332
|
},
|
|
320
333
|
};
|
package/src/icon-api.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/** @import { PresetValue, IconValue } from '@comapeo/schema' */
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
EmptyIconPathError,
|
|
5
|
+
EmptyVariantsArrayError,
|
|
6
|
+
InvalidPixelDensityError,
|
|
7
|
+
NoVariantsExistError,
|
|
8
|
+
NoVariantsForMimeTypeError,
|
|
9
|
+
} from './errors.js'
|
|
10
|
+
|
|
3
11
|
export const kGetIconBlob = Symbol('getIcon')
|
|
4
12
|
|
|
5
13
|
/** @typedef {PresetValue['iconRef']} IconRef */
|
|
@@ -59,7 +67,7 @@ export class IconApi {
|
|
|
59
67
|
*/
|
|
60
68
|
async create(icon) {
|
|
61
69
|
if (icon.variants.length < 1) {
|
|
62
|
-
throw new
|
|
70
|
+
throw new EmptyVariantsArrayError()
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
const savedVariants = await Promise.all(
|
|
@@ -158,15 +166,13 @@ export function getBestVariant(variants, opts) {
|
|
|
158
166
|
wantedPixelDensity = opts.pixelDensity
|
|
159
167
|
}
|
|
160
168
|
if (variants.length === 0) {
|
|
161
|
-
throw new
|
|
169
|
+
throw new NoVariantsExistError()
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
const matchingMime = variants.filter((v) => v.mimeType === wantedMimeType)
|
|
165
173
|
|
|
166
174
|
if (matchingMime.length === 0) {
|
|
167
|
-
throw new
|
|
168
|
-
`No variants with desired mime type ${wantedMimeType} exist`
|
|
169
|
-
)
|
|
175
|
+
throw new NoVariantsForMimeTypeError({ wantedMimeType })
|
|
170
176
|
}
|
|
171
177
|
const wantedSizeNum = SIZE_AS_NUMERIC[wantedSize]
|
|
172
178
|
|
|
@@ -264,14 +270,16 @@ function determineSortValue(target, a, b) {
|
|
|
264
270
|
*/
|
|
265
271
|
export function constructIconPath({ size, pixelDensity, iconId, extension }) {
|
|
266
272
|
if (iconId.length === 0 || size.length === 0 || extension.length === 0) {
|
|
267
|
-
throw new
|
|
273
|
+
throw new EmptyIconPathError()
|
|
268
274
|
}
|
|
269
275
|
|
|
270
276
|
let result = `${iconId}/${size}`
|
|
271
277
|
|
|
272
278
|
if (typeof pixelDensity === 'number') {
|
|
273
279
|
if (pixelDensity < 1) {
|
|
274
|
-
throw new
|
|
280
|
+
throw new InvalidPixelDensityError({
|
|
281
|
+
pixelDensity,
|
|
282
|
+
})
|
|
275
283
|
}
|
|
276
284
|
result += `@${pixelDensity}x`
|
|
277
285
|
}
|
package/src/import-categories.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Reader } from 'comapeocat/reader.js'
|
|
|
3
3
|
import { typedEntries } from './utils.js'
|
|
4
4
|
import { parseBcp47 } from './intl/parse-bcp-47.js'
|
|
5
5
|
import ensureError from 'ensure-error'
|
|
6
|
+
import { IconNotFoundError, KeyNotFoundError } from './errors.js'
|
|
6
7
|
|
|
7
8
|
// The main reason for the concurrency limit is to avoid run-away memory usage.
|
|
8
9
|
// The comapeocat Reader limits icon size to 2Mb (as-per the specification), and
|
|
@@ -75,7 +76,7 @@ export async function importCategories(project, { filePath, logger }) {
|
|
|
75
76
|
const iconXml = await reader.getIcon(iconName)
|
|
76
77
|
if (!iconXml) {
|
|
77
78
|
// This should never happen because of the validate() call above
|
|
78
|
-
throw new
|
|
79
|
+
throw new IconNotFoundError(iconName)
|
|
79
80
|
}
|
|
80
81
|
/** @type {Parameters<typeof project.$icons.create>[0]} */
|
|
81
82
|
const icon = {
|
|
@@ -308,7 +309,7 @@ export async function importCategories(project, { filePath, logger }) {
|
|
|
308
309
|
// flow statements (return, throw, break, continue) in the finally block
|
|
309
310
|
// will "mask" any completion value of the try block or catch block)
|
|
310
311
|
await reader.close().catch((e) => {
|
|
311
|
-
logger.log('
|
|
312
|
+
logger.log('ERROR: closing import file reader', e)
|
|
312
313
|
})
|
|
313
314
|
}
|
|
314
315
|
}
|
|
@@ -349,19 +350,17 @@ function appliesToToGeometry(appliesTo) {
|
|
|
349
350
|
/**
|
|
350
351
|
* Get a value from a Map, or throw an error if the key is not present
|
|
351
352
|
*
|
|
352
|
-
* @template K, V
|
|
353
|
+
* @template {string} K, V
|
|
353
354
|
* @param {Map<K, V>} map
|
|
354
355
|
* @param {K} key
|
|
355
|
-
* @param {string | Error} [msgOrError]
|
|
356
356
|
* @returns {V}
|
|
357
357
|
* @throws {TypeError} if `map` is not a Map
|
|
358
358
|
* @throws {Error} if `key` is not in `map` (with `msgOrError` as message or the default message)
|
|
359
359
|
*/
|
|
360
|
-
function getOrThrow(map, key
|
|
360
|
+
function getOrThrow(map, key) {
|
|
361
361
|
if (!(map instanceof Map)) throw new TypeError('map must be a Map')
|
|
362
362
|
if (!map.has(key)) {
|
|
363
|
-
|
|
364
|
-
throw new Error(msgOrError ?? `key ${key} not found in map`)
|
|
363
|
+
throw new KeyNotFoundError(key)
|
|
365
364
|
}
|
|
366
365
|
return /** @type {V} */ (map.get(key))
|
|
367
366
|
}
|
|
@@ -4,6 +4,7 @@ import { getTableConfig } from 'drizzle-orm/sqlite-core'
|
|
|
4
4
|
import { getBacklinkTableName } from '../schema/comapeo-to-drizzle.js'
|
|
5
5
|
import { discoveryKey } from 'hypercore-crypto'
|
|
6
6
|
import { Logger } from '../logger.js'
|
|
7
|
+
import { UnknownSchemaError } from '../errors.js'
|
|
7
8
|
/** @import { MapeoDoc, VersionIdObject } from '@comapeo/schema' */
|
|
8
9
|
/** @import { MapeoDocTables } from '../datatype/index.js' */
|
|
9
10
|
|
|
@@ -76,7 +77,7 @@ export class IndexWriter {
|
|
|
76
77
|
try {
|
|
77
78
|
const version = { coreDiscoveryKey: discoveryKey(key), index }
|
|
78
79
|
doc = this.#mapDoc(decode(block, version), version)
|
|
79
|
-
} catch
|
|
80
|
+
} catch {
|
|
80
81
|
this.#l.log('Could not decode entry %d of %h', index, key)
|
|
81
82
|
// Unknown or invalid entry - silently ignore
|
|
82
83
|
continue
|
|
@@ -119,7 +120,7 @@ export class IndexWriter {
|
|
|
119
120
|
deleteSchema(schemaName) {
|
|
120
121
|
const indexer = this.#indexers.get(schemaName)
|
|
121
122
|
if (!indexer) {
|
|
122
|
-
throw new
|
|
123
|
+
throw new UnknownSchemaError({ schemaName })
|
|
123
124
|
}
|
|
124
125
|
indexer.deleteAll()
|
|
125
126
|
}
|
package/src/index.js
CHANGED
|
@@ -34,6 +34,7 @@ export { MapeoManager } from './mapeo-manager.js'
|
|
|
34
34
|
/**
|
|
35
35
|
* @namespace MemberApi
|
|
36
36
|
* @typedef {import('./member-api.js').MemberInfo} MemberApi.MemberInfo
|
|
37
|
+
* @typedef {import('./member-api.js').ActiveMemberInfo} MemberApi.ActiveMemberInfo
|
|
37
38
|
* @typedef {import('./roles.js').RoleId} MemberApi.RoleId
|
|
38
39
|
* @typedef {import('./roles.js').RoleIdForNewInvite} MemberApi.RoleIdForNewInvite
|
|
39
40
|
* @typedef {import('./roles.js').RoleIdAssignableToOthers} MemberApi.RoleIdAssignableToOthers
|
package/src/intl/parse-bcp-47.js
CHANGED
|
@@ -4,6 +4,7 @@ import { iso6391To6393, iso6393 } from './iso639.js'
|
|
|
4
4
|
import { iso31661 } from 'iso-3166'
|
|
5
5
|
import { iso31661Alpha3ToAlpha2 } from 'iso-3166'
|
|
6
6
|
import { unM49 as unM49Array } from 'un-m49'
|
|
7
|
+
import { InvalidLanguageTagError } from '../errors.js'
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Map of UN M.49 country codes to their corresponding ISO 3166-1 alpha-2 country codes.
|
|
@@ -82,7 +83,7 @@ export function parseBcp47(languageTag) {
|
|
|
82
83
|
const normalized = bcp47Normalize(languageTag)
|
|
83
84
|
const { language, region } = simpleParseBcp47(normalized)
|
|
84
85
|
if (!language) {
|
|
85
|
-
throw new
|
|
86
|
+
throw new InvalidLanguageTagError({ languageTag })
|
|
86
87
|
}
|
|
87
88
|
return {
|
|
88
89
|
language: normalizePrimaryLanguageSubtag(language),
|