stated-protocol 5.2.1 → 5.3.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.
Files changed (65) hide show
  1. package/dist/fixtures.test.d.ts +2 -0
  2. package/dist/fixtures.test.d.ts.map +1 -0
  3. package/dist/fixtures.test.js +207 -0
  4. package/dist/fixtures.test.js.map +1 -0
  5. package/dist/hash.js +2 -2
  6. package/dist/hash.js.map +1 -1
  7. package/dist/hash.test.d.ts +2 -0
  8. package/dist/hash.test.d.ts.map +1 -0
  9. package/dist/hash.test.js +183 -0
  10. package/dist/hash.test.js.map +1 -0
  11. package/dist/observation.test.d.ts +2 -0
  12. package/dist/observation.test.d.ts.map +1 -0
  13. package/dist/observation.test.js +101 -0
  14. package/dist/observation.test.js.map +1 -0
  15. package/dist/organisation-verification.test.d.ts +2 -0
  16. package/dist/organisation-verification.test.d.ts.map +1 -0
  17. package/dist/organisation-verification.test.js +44 -0
  18. package/dist/organisation-verification.test.js.map +1 -0
  19. package/dist/person-verification.test.d.ts +2 -0
  20. package/dist/person-verification.test.d.ts.map +1 -0
  21. package/dist/person-verification.test.js +41 -0
  22. package/dist/person-verification.test.js.map +1 -0
  23. package/dist/poll.test.d.ts +2 -0
  24. package/dist/poll.test.d.ts.map +1 -0
  25. package/dist/poll.test.js +26 -0
  26. package/dist/poll.test.js.map +1 -0
  27. package/dist/protocol.d.ts +3 -1
  28. package/dist/protocol.d.ts.map +1 -1
  29. package/dist/protocol.js +53 -8
  30. package/dist/protocol.js.map +1 -1
  31. package/dist/rating.test.d.ts +2 -0
  32. package/dist/rating.test.d.ts.map +1 -0
  33. package/dist/rating.test.js +24 -0
  34. package/dist/rating.test.js.map +1 -0
  35. package/dist/signature.js +2 -2
  36. package/dist/signature.js.map +1 -1
  37. package/dist/signature.test.d.ts +2 -0
  38. package/dist/signature.test.d.ts.map +1 -0
  39. package/dist/signature.test.js +165 -0
  40. package/dist/signature.test.js.map +1 -0
  41. package/dist/statement.test.d.ts +2 -0
  42. package/dist/statement.test.d.ts.map +1 -0
  43. package/dist/statement.test.js +90 -0
  44. package/dist/statement.test.js.map +1 -0
  45. package/dist/types.d.ts +7 -2
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/utils.d.ts +1 -1
  48. package/dist/utils.d.ts.map +1 -1
  49. package/dist/utils.js +2 -9
  50. package/dist/utils.js.map +1 -1
  51. package/dist/utils.test.d.ts +2 -0
  52. package/dist/utils.test.d.ts.map +1 -0
  53. package/dist/utils.test.js +106 -0
  54. package/dist/utils.test.js.map +1 -0
  55. package/package.json +1 -1
  56. package/src/fixtures.test.ts +8 -1
  57. package/src/hash.ts +2 -2
  58. package/src/observation.test.ts +128 -0
  59. package/src/poll.test.ts +1 -1
  60. package/src/protocol.ts +56 -8
  61. package/src/rating.test.ts +5 -1
  62. package/src/signature.ts +2 -2
  63. package/src/types.ts +9 -2
  64. package/src/utils.test.ts +5 -10
  65. package/src/utils.ts +2 -10
@@ -0,0 +1,90 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import { parseStatement, buildStatement } from './protocol';
4
+ const randomUnicodeString = () => Array.from({ length: 20 }, () => String.fromCharCode(Math.floor(Math.random() * 65536)))
5
+ .join('')
6
+ .replace(/[\n;>=<"''\\]/g, '');
7
+ describe('Statement building', () => {
8
+ it('build & parse function compatibility: input=parse(build(input))', () => {
9
+ const [domain, author, representative, content, supersededStatement] = Array.from({ length: 5 }, randomUnicodeString);
10
+ const tags = Array.from({ length: 4 }, randomUnicodeString);
11
+ const contentWithTrailingNewline = content + (content.match(/\n$/) ? '' : '\n');
12
+ const time = new Date('Sun, 04 Sep 2022 14:48:50 GMT');
13
+ const statementContent = buildStatement({
14
+ domain,
15
+ author,
16
+ time,
17
+ content: contentWithTrailingNewline,
18
+ representative,
19
+ supersededStatement,
20
+ tags,
21
+ });
22
+ const parsedStatement = parseStatement({ statement: statementContent });
23
+ assert.strictEqual(parsedStatement.domain, domain);
24
+ assert.strictEqual(parsedStatement.author, author);
25
+ assert.strictEqual(parsedStatement.time?.toUTCString(), time.toUTCString());
26
+ assert.strictEqual(parsedStatement.content, content);
27
+ assert.strictEqual(parsedStatement.representative, representative);
28
+ assert.strictEqual(parsedStatement.supersededStatement, supersededStatement);
29
+ assert.deepStrictEqual(parsedStatement.tags?.sort(), tags.sort());
30
+ });
31
+ it('build & parse statement with attachments', () => {
32
+ const domain = 'example.com';
33
+ const author = 'Test Author';
34
+ const time = new Date('Thu, 15 Jun 2023 20:01:26 GMT');
35
+ const content = 'Statement with attachments';
36
+ const attachments = ['abc123_-XYZ.pdf', 'def456-_ABC.jpg', 'xyz789_hash.docx'];
37
+ const statementContent = buildStatement({
38
+ domain,
39
+ author,
40
+ time,
41
+ content,
42
+ attachments,
43
+ });
44
+ const parsedStatement = parseStatement({ statement: statementContent });
45
+ assert.strictEqual(parsedStatement.domain, domain);
46
+ assert.strictEqual(parsedStatement.author, author);
47
+ assert.strictEqual(parsedStatement.content, content);
48
+ assert.deepStrictEqual(parsedStatement.attachments, attachments);
49
+ });
50
+ it('reject statement with more than 5 attachments', () => {
51
+ const domain = 'example.com';
52
+ const author = 'Test Author';
53
+ const time = new Date();
54
+ const content = 'Too many attachments\n';
55
+ const attachments = [
56
+ 'hash1.pdf',
57
+ 'hash2.pdf',
58
+ 'hash3.pdf',
59
+ 'hash4.pdf',
60
+ 'hash5.pdf',
61
+ 'hash6.pdf',
62
+ ];
63
+ assert.throws(() => {
64
+ buildStatement({
65
+ domain,
66
+ author,
67
+ time,
68
+ content,
69
+ attachments,
70
+ });
71
+ }, /Maximum 5 attachments allowed/);
72
+ });
73
+ it('reject attachment with invalid format', () => {
74
+ const domain = 'example.com';
75
+ const author = 'Test Author';
76
+ const time = new Date();
77
+ const content = 'Invalid attachment\n';
78
+ const attachments = ['invalid file name.pdf'];
79
+ assert.throws(() => {
80
+ buildStatement({
81
+ domain,
82
+ author,
83
+ time,
84
+ content,
85
+ attachments,
86
+ });
87
+ }, /Attachment 1 must be in format 'base64hash.extension' \(URL-safe base64\)/);
88
+ });
89
+ });
90
+ //# sourceMappingURL=statement.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statement.test.js","sourceRoot":"","sources":["../src/statement.test.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -4,7 +4,7 @@ export type PeopleCountBucket = '0-10' | '10-100' | '100-1000' | '1000-10,000' |
4
4
  export declare function isLegalForm(value: string): value is LegalForm;
5
5
  export declare function isPeopleCountBucket(value: string): value is PeopleCountBucket;
6
6
  export declare function isRatingValue(value: number): value is RatingValue;
7
- export type StatementTypeValue = 'statement' | 'organisation_verification' | 'person_verification' | 'poll' | 'vote' | 'response' | 'dispute_statement_content' | 'dispute_statement_authenticity' | 'rating' | 'sign_pdf';
7
+ export type StatementTypeValue = 'statement' | 'organisation_verification' | 'person_verification' | 'poll' | 'vote' | 'response' | 'dispute_statement_content' | 'dispute_statement_authenticity' | 'rating' | 'sign_pdf' | 'observation';
8
8
  export type Statement = {
9
9
  domain: string;
10
10
  author: string;
@@ -89,7 +89,7 @@ export type ResponseContent = {
89
89
  hash: string;
90
90
  response: string;
91
91
  };
92
- export type PDFSigning = {};
92
+ export type PDFSigning = Record<string, never>;
93
93
  export type RatingSubjectTypeValue = 'Organisation' | 'Policy proposal' | 'Treaty draft' | 'Research publication' | 'Regulation' | 'Product';
94
94
  export type RatingValue = 1 | 2 | 3 | 4 | 5;
95
95
  export type Rating = {
@@ -108,4 +108,9 @@ export type Bounty = {
108
108
  judge: string;
109
109
  judgePay?: string;
110
110
  };
111
+ export type Observation = {
112
+ subject: string;
113
+ property: string;
114
+ value: string;
115
+ };
111
116
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/utils.d.ts CHANGED
@@ -5,7 +5,7 @@ export declare const validateStatementContentHash: (statementContent: string, ex
5
5
  export declare const generateStatementHash: (statement: string) => string;
6
6
  export declare const validateStatementHash: (statement: string, expectedHash: string) => boolean;
7
7
  export declare const generateStatementsFile: (statements: string[]) => string;
8
- export declare const parseStatementsFile: (statementsFileContent: string) => string[];
8
+ export declare const splitStatements: (statementsFileContent: string) => string[];
9
9
  export declare const generateStatementFilename: (statement: string) => string;
10
10
  export declare const generateAttachmentFilename: (fileContent: Buffer | string, extension: string) => string;
11
11
  export declare const minPeopleCountToRange: (n: number) => string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,GAAG,MAAM,KAAG,MAE/D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,GAAG,MAAM,EAAE,cAAc,MAAM,KAAG,OAErF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,kBAAkB,MAAM,KAAG,MAEvE,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,kBAAkB,MAAM,EACxB,cAAc,MAAM,KACnB,OAEF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,KAAG,MASzD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,EAAE,cAAc,MAAM,KAAG,OAG/E,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,YAAY,MAAM,EAAE,KAAG,MAE7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,uBAAuB,MAAM,KAAG,MAAM,EA0BzE,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,WAAW,MAAM,KAAG,MAG7D,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,aAAa,MAAM,GAAG,MAAM,EAC5B,WAAW,MAAM,KAChB,MAIF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,GAAG,MAAM,KAAG,MAAM,GAAG,SAS1D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAGxC,CAAC;AAEJ,eAAO,MAAM,eAAe,EAAE,MAC2D,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,GAAG,MAAM,KAAG,MAE/D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,GAAG,MAAM,EAAE,cAAc,MAAM,KAAG,OAErF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,kBAAkB,MAAM,KAAG,MAEvE,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,kBAAkB,MAAM,EACxB,cAAc,MAAM,KACnB,OAEF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,KAAG,MASzD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,EAAE,cAAc,MAAM,KAAG,OAG/E,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,YAAY,MAAM,EAAE,KAAG,MAE7D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,uBAAuB,MAAM,KAAG,MAAM,EAmBrE,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,WAAW,MAAM,KAAG,MAG7D,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,aAAa,MAAM,GAAG,MAAM,EAC5B,WAAW,MAAM,KAChB,MAIF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,GAAG,MAAM,KAAG,MAAM,GAAG,SAS1D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAGxC,CAAC;AAEJ,eAAO,MAAM,eAAe,EAAE,MAC2D,CAAC"}
package/dist/utils.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { peopleCountBuckets } from './constants';
2
2
  import { sha256, verify } from './hash';
3
- import { parseStatement } from './protocol';
4
3
  export const generateFileHash = (fileContent) => {
5
4
  return sha256(fileContent);
6
5
  };
@@ -28,7 +27,7 @@ export const validateStatementHash = (statement, expectedHash) => {
28
27
  export const generateStatementsFile = (statements) => {
29
28
  return statements.join('\n\n');
30
29
  };
31
- export const parseStatementsFile = (statementsFileContent) => {
30
+ export const splitStatements = (statementsFileContent) => {
32
31
  const statementParts = statementsFileContent.split(/\n\nStated protocol version: /);
33
32
  const statements = [];
34
33
  for (let i = 0; i < statementParts.length; i++) {
@@ -39,13 +38,7 @@ export const parseStatementsFile = (statementsFileContent) => {
39
38
  statement = 'Stated protocol version: ' + statement;
40
39
  }
41
40
  statement = statement.replace(/\n+$/, '\n');
42
- try {
43
- parseStatement({ statement });
44
- statements.push(statement);
45
- }
46
- catch (error) {
47
- throw new Error(`Invalid statement at index ${i}: ${error instanceof Error ? error.message : String(error)}`);
48
- }
41
+ statements.push(statement);
49
42
  }
50
43
  return statements;
51
44
  };
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import { buildStatement } from './protocol';
4
+ import { generateFileHash, validateFileHash, generateStatementContentHash, validateStatementContentHash, generateStatementHash, validateStatementHash, generateStatementsFile, splitStatements, generateStatementFilename, generateAttachmentFilename, } from './utils';
5
+ describe('Statement Utils', () => {
6
+ const testContent = 'test content';
7
+ const testFileContent = Buffer.from('test file content');
8
+ describe('File Hash Functions', () => {
9
+ it('should generate file hash', () => {
10
+ const hash = generateFileHash(testFileContent);
11
+ assert.ok(hash);
12
+ assert.strictEqual(typeof hash, 'string');
13
+ });
14
+ it('should validate file hash', () => {
15
+ const hash = generateFileHash(testFileContent);
16
+ assert.strictEqual(validateFileHash(testFileContent, hash), true);
17
+ assert.strictEqual(validateFileHash(testFileContent, 'invalid-hash'), false);
18
+ });
19
+ it('should generate attachment filename', () => {
20
+ const filename = generateAttachmentFilename(testFileContent, 'pdf');
21
+ assert.ok(/^[A-Za-z0-9_-]+\.pdf$/.test(filename));
22
+ });
23
+ it('should handle extension with dot', () => {
24
+ const filename = generateAttachmentFilename(testFileContent, '.jpg');
25
+ assert.ok(/^[A-Za-z0-9_-]+\.jpg$/.test(filename));
26
+ });
27
+ });
28
+ describe('Statement Content Hash Functions', () => {
29
+ it('should generate statement content hash', () => {
30
+ const hash = generateStatementContentHash(testContent);
31
+ assert.ok(hash);
32
+ assert.strictEqual(typeof hash, 'string');
33
+ });
34
+ it('should validate statement content hash', () => {
35
+ const hash = generateStatementContentHash(testContent);
36
+ assert.strictEqual(validateStatementContentHash(testContent, hash), true);
37
+ assert.strictEqual(validateStatementContentHash(testContent, 'invalid-hash'), false);
38
+ });
39
+ });
40
+ describe('Statement Hash Functions', () => {
41
+ const statement = buildStatement({
42
+ domain: 'example.com',
43
+ author: 'Test Author',
44
+ time: new Date('2023-06-15T20:01:26.000Z'),
45
+ content: 'Test statement content',
46
+ });
47
+ it('should generate statement hash', () => {
48
+ const hash = generateStatementHash(statement);
49
+ assert.ok(hash);
50
+ assert.strictEqual(typeof hash, 'string');
51
+ });
52
+ it('should validate statement hash', () => {
53
+ const hash = generateStatementHash(statement);
54
+ assert.strictEqual(validateStatementHash(statement, hash), true);
55
+ assert.strictEqual(validateStatementHash(statement, 'invalid-hash'), false);
56
+ });
57
+ it('should generate statement filename', () => {
58
+ const filename = generateStatementFilename(statement);
59
+ assert.ok(/^[A-Za-z0-9_-]+\.txt$/.test(filename));
60
+ });
61
+ it('should exclude signature fields from hash', () => {
62
+ const signedStatement = statement +
63
+ '---\n' +
64
+ 'Statement hash: test-hash\n' +
65
+ 'Public key: test-key\n' +
66
+ 'Signature: test-signature\n' +
67
+ 'Algorithm: Ed25519\n';
68
+ const hash = generateStatementHash(signedStatement);
69
+ const hashWithoutSignature = generateStatementHash(statement);
70
+ assert.strictEqual(hash, hashWithoutSignature);
71
+ });
72
+ });
73
+ describe('Statements File Functions', () => {
74
+ const statement1 = buildStatement({
75
+ domain: 'example.com',
76
+ author: 'Test Author',
77
+ time: new Date('2023-06-15T20:01:26.000Z'),
78
+ content: 'First statement',
79
+ });
80
+ const statement2 = buildStatement({
81
+ domain: 'example.com',
82
+ author: 'Test Author',
83
+ time: new Date('2023-06-16T10:30:00.000Z'),
84
+ content: 'Second statement',
85
+ });
86
+ it('should generate statements file', () => {
87
+ const statementsFile = generateStatementsFile([statement1, statement2]);
88
+ assert.ok(statementsFile.includes(statement1));
89
+ assert.ok(statementsFile.includes(statement2));
90
+ assert.ok(statementsFile.includes('\n\n'));
91
+ });
92
+ it('should split statements file', () => {
93
+ const statementsFile = generateStatementsFile([statement1, statement2]);
94
+ const parsed = splitStatements(statementsFile);
95
+ assert.strictEqual(parsed.length, 2);
96
+ assert.strictEqual(parsed[0], statement1);
97
+ assert.strictEqual(parsed[1], statement2);
98
+ });
99
+ it('should filter empty statements when splitting', () => {
100
+ const fileWithEmpty = statement1 + '\n\n\n\n' + statement2;
101
+ const parsed = splitStatements(fileWithEmpty);
102
+ assert.strictEqual(parsed.length, 2);
103
+ });
104
+ });
105
+ });
106
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../src/utils.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stated-protocol",
3
- "version": "5.2.1",
3
+ "version": "5.3.1",
4
4
  "description": "Protocol for Decentralised Interorganisational Coordination",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,6 +15,7 @@ import {
15
15
  buildResponseContent,
16
16
  buildPDFSigningContent,
17
17
  buildRating,
18
+ buildObservationContent,
18
19
  } from './protocol';
19
20
  import { verifySignedStatement } from './signature';
20
21
 
@@ -119,6 +120,12 @@ function buildContentFromInput(contentObj: any): string {
119
120
  quality: contentObj.quality,
120
121
  comment: contentObj.comment,
121
122
  });
123
+ case 'observation':
124
+ return buildObservationContent({
125
+ subject: contentObj.subject,
126
+ property: contentObj.property,
127
+ value: contentObj.value,
128
+ });
122
129
  default:
123
130
  throw new Error(`Unknown content type: ${contentObj.type}`);
124
131
  }
@@ -199,7 +206,7 @@ describe('Fixture Validation', () => {
199
206
  assert.ok(parsed.domain);
200
207
  assert.ok(parsed.author);
201
208
  assert.ok(parsed.content);
202
- assert.strictEqual(parsed.formatVersion, '5');
209
+ assert.strictEqual(parsed.formatVersion, '5.3');
203
210
  });
204
211
 
205
212
  it('round-trip: parse(output.txt) should match input.json structure', () => {
package/src/hash.ts CHANGED
@@ -71,9 +71,9 @@ export const toUrlSafeBase64 = (base64: string): string => {
71
71
  * @returns Base64 string
72
72
  */
73
73
  function bytesToBase64(bytes: Uint8Array): string {
74
- // Use btoa if available (browser), otherwise use Buffer (Node.js)
75
74
  if (typeof btoa !== 'undefined') {
76
- return btoa(String.fromCharCode(...Array.from(bytes)));
75
+ const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join('');
76
+ return btoa(binaryString);
77
77
  } else {
78
78
  return Buffer.from(bytes).toString('base64');
79
79
  }
@@ -0,0 +1,128 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import {
4
+ buildObservationContent,
5
+ parseObservation,
6
+ buildStatement,
7
+ parseStatement,
8
+ } from './protocol';
9
+
10
+ describe('Observation', () => {
11
+ it('should build observation content', () => {
12
+ const observation = {
13
+ subject: 'John_Doe@globalcoordination.johndoe.com',
14
+ property: 'Among the members of this network they are the most appropriate to represent',
15
+ value: 'Germany',
16
+ };
17
+
18
+ const content = buildObservationContent(observation);
19
+
20
+ assert.ok(content.includes('Type: Observation'));
21
+ assert.ok(content.includes('Subject: John_Doe@globalcoordination.johndoe.com'));
22
+ assert.ok(
23
+ content.includes(
24
+ 'Property: Among the members of this network they are the most appropriate to represent'
25
+ )
26
+ );
27
+ assert.ok(content.includes('Value: Germany'));
28
+ });
29
+
30
+ it('should parse observation content', () => {
31
+ const content =
32
+ ' Type: Observation\n' +
33
+ ' Subject: John_Doe@globalcoordination.johndoe.com\n' +
34
+ ' Property: Among the members of this network they are the most appropriate to represent\n' +
35
+ ' Value: Germany\n';
36
+
37
+ const parsed = parseObservation(content);
38
+
39
+ assert.strictEqual(parsed.subject, 'John_Doe@globalcoordination.johndoe.com');
40
+ assert.strictEqual(
41
+ parsed.property,
42
+ 'Among the members of this network they are the most appropriate to represent'
43
+ );
44
+ assert.strictEqual(parsed.value, 'Germany');
45
+ });
46
+
47
+ it('should build and parse observation in a statement', () => {
48
+ const observation = {
49
+ subject: 'John_Doe@globalcoordination.johndoe.com',
50
+ property: 'Among the members of this network they are the most appropriate to represent',
51
+ value: 'Germany',
52
+ };
53
+
54
+ const content = buildObservationContent(observation);
55
+ const statement = buildStatement({
56
+ domain: 'example.com',
57
+ author: 'Test Author',
58
+ time: new Date('2023-06-15T10:00:00Z'),
59
+ content,
60
+ });
61
+
62
+ const parsed = parseStatement({ statement });
63
+ assert.strictEqual(parsed.type, 'observation');
64
+
65
+ const parsedObservation = parseObservation(parsed.content);
66
+ assert.strictEqual(parsedObservation.subject, observation.subject);
67
+ assert.strictEqual(parsedObservation.property, observation.property);
68
+ assert.strictEqual(parsedObservation.value, observation.value);
69
+ });
70
+
71
+ it('should throw error when subject is missing', () => {
72
+ assert.throws(() => {
73
+ buildObservationContent({
74
+ subject: '',
75
+ property: 'Some property',
76
+ value: 'Some value',
77
+ });
78
+ }, /Subject is required/);
79
+ });
80
+
81
+ it('should throw error when property is missing', () => {
82
+ assert.throws(() => {
83
+ buildObservationContent({
84
+ subject: 'test@example.com',
85
+ property: '',
86
+ value: 'Some value',
87
+ });
88
+ }, /Property is required/);
89
+ });
90
+
91
+ it('should throw error when value is missing', () => {
92
+ assert.throws(() => {
93
+ buildObservationContent({
94
+ subject: 'test@example.com',
95
+ property: 'Some property',
96
+ value: '',
97
+ });
98
+ }, /Value is required/);
99
+ });
100
+
101
+ it('should handle various subject formats', () => {
102
+ const observations = [
103
+ {
104
+ subject: 'user@domain.com',
105
+ property: 'role',
106
+ value: 'administrator',
107
+ },
108
+ {
109
+ subject: 'https://example.com/resource/123',
110
+ property: 'status',
111
+ value: 'active',
112
+ },
113
+ {
114
+ subject: 'Organization Name',
115
+ property: 'headquarters',
116
+ value: 'Berlin, Germany',
117
+ },
118
+ ];
119
+
120
+ observations.forEach((obs) => {
121
+ const content = buildObservationContent(obs);
122
+ const parsed = parseObservation(content);
123
+ assert.strictEqual(parsed.subject, obs.subject);
124
+ assert.strictEqual(parsed.property, obs.property);
125
+ assert.strictEqual(parsed.value, obs.value);
126
+ });
127
+ });
128
+ });
package/src/poll.test.ts CHANGED
@@ -18,7 +18,7 @@ describe('Poll building', () => {
18
18
  options,
19
19
  scopeDescription,
20
20
  });
21
- const parsedPoll = parsePoll(pollContent, '5');
21
+ const parsedPoll = parsePoll(pollContent, '5.3');
22
22
  assert.strictEqual(parsedPoll.poll, poll);
23
23
  assert.strictEqual(parsedPoll.scopeDescription, scopeDescription);
24
24
  assert.strictEqual(parsedPoll.deadline?.toUTCString(), deadline.toUTCString());
package/src/protocol.ts CHANGED
@@ -14,10 +14,11 @@ import type {
14
14
  PDFSigning,
15
15
  Rating,
16
16
  RatingSubjectTypeValue,
17
+ Observation,
17
18
  } from './types';
18
19
  import { isLegalForm, isPeopleCountBucket, isRatingValue } from './types';
19
20
 
20
- const version = 5.2;
21
+ const VERSION = '5.3';
21
22
 
22
23
  export * from './types';
23
24
  export * from './constants';
@@ -100,7 +101,7 @@ export const buildStatement = ({
100
101
 
101
102
  const statement =
102
103
  'Stated protocol version: ' +
103
- version +
104
+ VERSION +
104
105
  '\n' +
105
106
  'Publishing domain: ' +
106
107
  domain +
@@ -236,9 +237,9 @@ export const parseStatement = ({
236
237
  if (!parsed.content) throw new Error('Invalid statement format: statement content is required');
237
238
  if (!parsed.formatVersion)
238
239
  throw new Error('Invalid statement format: format version is required');
239
- if (parsed.formatVersion !== '5.2')
240
+ if (parsed.formatVersion !== VERSION)
240
241
  throw new Error(
241
- `Invalid statement format: only version 5.2 is supported, got version ${parsed.formatVersion}`
242
+ `Invalid statement format: only version ${VERSION} is supported, got version ${parsed.formatVersion}`
242
243
  );
243
244
 
244
245
  const tags = parsed.tagsStr?.split(', ');
@@ -322,7 +323,7 @@ export const buildPollContent = ({
322
323
  };
323
324
 
324
325
  export const parsePoll = (content: string, version?: string): Poll => {
325
- if (version !== '5') throw new Error('Invalid version ' + version);
326
+ if (version !== VERSION) throw new Error('Invalid version ' + version);
326
327
  const pollRegex = new RegExp(
327
328
  '' +
328
329
  /^ Type: Poll\n/.source +
@@ -435,7 +436,8 @@ export const parseOrganisationVerification = (content: string): OrganisationVeri
435
436
  const organisationVerificationRegex = new RegExp(
436
437
  '' +
437
438
  /^ Type: Organisation verification\n/.source +
438
- / Description: We verified the following information about an organisation\.(?:\sTheir logo may be attached to this statement\.)?\n/.source +
439
+ / Description: We verified the following information about an organisation\.(?:\sTheir logo may be attached to this statement\.)?\n/
440
+ .source +
439
441
  / Name: (?<name>[^\n]+?)\n/.source +
440
442
  /(?: English name: (?<englishName>[^\n]+?)\n)?/.source +
441
443
  / Country: (?<country>[^\n]+?)\n/.source +
@@ -561,7 +563,8 @@ export const parsePersonVerification = (content: string): PersonVerification =>
561
563
  const domainVerificationRegex = new RegExp(
562
564
  '' +
563
565
  /^ Type: Person verification\n/.source +
564
- / Description: We verified the following information about a person\.(?:\sTheir profile picture may be attached to this statement\.)?\n/.source +
566
+ / Description: We verified the following information about a person\.(?:\sTheir profile picture may be attached to this statement\.)?\n/
567
+ .source +
565
568
  / Name: (?<name>[^\n]+?)\n/.source +
566
569
  / Date of birth: (?<dateOfBirth>[^\n]+?)\n/.source +
567
570
  / City of birth: (?<cityOfBirth>[^\n]+?)\n/.source +
@@ -759,7 +762,8 @@ export const parsePDFSigning = (content: string): PDFSigning => {
759
762
  const signingRegex = new RegExp(
760
763
  '' +
761
764
  /^ Type: Sign PDF\n/.source +
762
- / Description: We hereby digitally sign the attached PDF file\. The filename contains a hash of the file contents\.\n/.source +
765
+ / Description: We hereby digitally sign the attached PDF file\. The filename contains a hash of the file contents\.\n/
766
+ .source +
763
767
  /$/.source
764
768
  );
765
769
  const match = content.match(signingRegex);
@@ -850,3 +854,47 @@ export const parseRating = (content: string): Rating => {
850
854
  comment,
851
855
  };
852
856
  };
857
+
858
+ export const buildObservationContent = ({ subject, property, value }: Observation) => {
859
+ if (!subject) throw new Error('Subject is required');
860
+ if (!property) throw new Error('Property is required');
861
+ if (!value) throw new Error('Value is required');
862
+
863
+ const content =
864
+ ' Type: Observation\n' +
865
+ ' Subject: ' +
866
+ subject +
867
+ '\n' +
868
+ ' Property: ' +
869
+ property +
870
+ '\n' +
871
+ ' Value: ' +
872
+ value +
873
+ '\n';
874
+ return content;
875
+ };
876
+
877
+ export const parseObservation = (content: string): Observation => {
878
+ const observationRegex = new RegExp(
879
+ '' +
880
+ /^ Type: Observation\n/.source +
881
+ / Subject: (?<subject>[^\n]+?)\n/.source +
882
+ / Property: (?<property>[^\n]+?)\n/.source +
883
+ / Value: (?<value>[^\n]+?)\n/.source +
884
+ /$/.source
885
+ );
886
+ const match = content.match(observationRegex);
887
+ if (!match || !match.groups) throw new Error('Invalid observation format: ' + content);
888
+
889
+ const { subject, property, value } = match.groups;
890
+
891
+ if (!subject) throw new Error('Missing subject');
892
+ if (!property) throw new Error('Missing property');
893
+ if (!value) throw new Error('Missing value');
894
+
895
+ return {
896
+ subject,
897
+ property,
898
+ value,
899
+ };
900
+ };