@dxos/keys 0.7.5-labs.5f04cf6 → 0.7.5-labs.8a82073

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.
@@ -1 +1 @@
1
- {"version":"5.7.2"}
1
+ {"version":"5.7.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/keys",
3
- "version": "0.7.5-labs.5f04cf6",
3
+ "version": "0.7.5-labs.8a82073",
4
4
  "description": "Key utils and definitions.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -26,9 +26,9 @@
26
26
  "src"
27
27
  ],
28
28
  "dependencies": {
29
- "@dxos/debug": "0.7.5-labs.5f04cf6",
30
- "@dxos/invariant": "0.7.5-labs.5f04cf6",
31
- "@dxos/node-std": "0.7.5-labs.5f04cf6"
29
+ "@dxos/debug": "0.7.5-labs.8a82073",
30
+ "@dxos/node-std": "0.7.5-labs.8a82073",
31
+ "@dxos/invariant": "0.7.5-labs.8a82073"
32
32
  },
33
33
  "devDependencies": {
34
34
  "base32-decode": "^1.0.0",
package/src/dxn.ts CHANGED
@@ -11,7 +11,7 @@ import type { SpaceId } from './space-id';
11
11
 
12
12
  /**
13
13
  * DXN unambiguously names a resource like an ECHO object, schema definition, plugin, etc.
14
- * Each DXN starts with a dx prefix, followed by a resource kind.
14
+ * Each DXN starts with a dxn prefix, followed by a resource kind.
15
15
  * Colon Symbol : is used a delimiter between parts.
16
16
  * DXNs may contain slashes.
17
17
  * '@' in the place of the space id is used to denote that the DXN should be resolved in the local space.
@@ -19,11 +19,11 @@ import type { SpaceId } from './space-id';
19
19
  * @example
20
20
  *
21
21
  * ```
22
- * dx:echo:<space key>:<echo id>
23
- * dx:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
24
- * dx:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6
25
- * dx:type:dxos.org/type/Calendar
26
- * dx:plugin:dxos.org/agent/plugin/functions
22
+ * dxn:echo:<space key>:<echo id>
23
+ * dxn:echo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
24
+ * dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6
25
+ * dxn:type:dxos.org/type/Calendar
26
+ * dxn:plugin:dxos.org/agent/plugin/functions
27
27
  * ```
28
28
  */
29
29
  export class DXN {
@@ -41,7 +41,8 @@ export class DXN {
41
41
  */
42
42
  ECHO: 'echo',
43
43
  /**
44
- * dxn:queue:<subspace tag>:<space id>:<queue id>[:object id]
44
+ * The subspace tag enables us to partition queues by usage within the context of a space.
45
+ * dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
45
46
  * dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
46
47
  * dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
47
48
  */
@@ -56,38 +57,32 @@ export class DXN {
56
57
  return dxn.startsWith('dxn:');
57
58
  }
58
59
 
59
- static parse(dxn: string): DXN;
60
- static parse(dxn: string, noThrow: boolean): DXN | undefined;
61
- static parse(dxn: string, noThrow?: boolean): DXN | undefined {
60
+ static parse(dxn: string): DXN {
62
61
  if (typeof dxn !== 'string') {
63
- if (noThrow) {
64
- return undefined;
65
- }
66
62
  throw new Error(`Invalid DXN: ${dxn}`);
67
63
  }
68
64
  const [prefix, kind, ...parts] = dxn.split(':');
69
65
  if (!(prefix === 'dxn')) {
70
- if (noThrow) {
71
- return undefined;
72
- }
73
66
  throw new Error(`Invalid DXN: ${dxn}`);
74
67
  }
75
68
  if (!(typeof kind === 'string' && kind.length > 0)) {
76
- if (noThrow) {
77
- return undefined;
78
- }
79
69
  throw new Error(`Invalid DXN: ${dxn}`);
80
70
  }
81
71
  if (!(parts.length > 0)) {
82
- if (noThrow) {
83
- return undefined;
84
- }
85
72
  throw new Error(`Invalid DXN: ${dxn}`);
86
73
  }
87
74
 
88
75
  return new DXN(kind, parts);
89
76
  }
90
77
 
78
+ static tryParse(dxn: string) {
79
+ try {
80
+ return DXN.parse(dxn);
81
+ } catch (error) {
82
+ return undefined;
83
+ }
84
+ }
85
+
91
86
  /**
92
87
  * @example `dxn:type:example.com/type/Contact`
93
88
  */
@@ -185,6 +180,7 @@ export class DXN {
185
180
  if (typeof queueId !== 'string') {
186
181
  return undefined;
187
182
  }
183
+
188
184
  return {
189
185
  subspaceTag,
190
186
  spaceId: spaceId as SpaceId,
@@ -0,0 +1,17 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { expect, test } from 'vitest';
6
+
7
+ import { IdentityDid } from './identity-did';
8
+
9
+ test('identity-did', () => {
10
+ const id = IdentityDid.random();
11
+
12
+ expect(id.length).toBe(42);
13
+ expect(IdentityDid.isValid(id)).toBe(true);
14
+ const decoded = IdentityDid.decode(id);
15
+ expect(decoded.length).toBe(IdentityDid.byteLength);
16
+ expect(IdentityDid.encode(decoded)).toBe(id);
17
+ });
@@ -0,0 +1,49 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import base32Decode from 'base32-decode';
6
+ import base32Encode from 'base32-encode';
7
+
8
+ import { invariant } from '@dxos/invariant';
9
+
10
+ import { randomBytes } from './random-bytes';
11
+
12
+ /**
13
+ * A unique identifier for a space.
14
+ * Space keys are generated by creating a keypair, and then taking the first 20 bytes of the SHA-256 hash of the public key and encoding them to multibase RFC4648 base-32 format (prefixed with B, see Multibase Table).
15
+ * @example did:halo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE
16
+ */
17
+ export type IdentityDid = string & { __IdentityDid: true };
18
+
19
+ export const IdentityDid = Object.freeze({
20
+ byteLength: 20,
21
+ encode: (value: Uint8Array): IdentityDid => {
22
+ invariant(value instanceof Uint8Array, 'Invalid type');
23
+ invariant(value.length === IdentityDid.byteLength, 'Invalid length');
24
+
25
+ return (DID_PREFIX + MULTIBASE_PREFIX + base32Encode(value, 'RFC4648')) as IdentityDid;
26
+ },
27
+ decode: (value: IdentityDid): Uint8Array => {
28
+ invariant(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), 'Invalid multibase32 encoding');
29
+
30
+ return new Uint8Array(base32Decode(value.slice(10), 'RFC4648'));
31
+ },
32
+ isValid: (value: string): value is IdentityDid => {
33
+ return (
34
+ typeof value === 'string' && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH
35
+ );
36
+ },
37
+ random: (): IdentityDid => {
38
+ return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
39
+ },
40
+ });
41
+
42
+ /**
43
+ * Denotes RFC4648 base-32 format.
44
+ */
45
+ const MULTIBASE_PREFIX = 'B';
46
+
47
+ const DID_PREFIX = 'did:halo:';
48
+
49
+ const ENCODED_LENGTH = 42;
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
+ export * from './identity-did';
5
6
  export * from './public-key';
6
7
  export * from './types';
7
8
  export * from './space-id';