@peac/disc 0.10.9 → 0.10.11
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/LICENSE +1 -1
- package/dist/index.cjs +198 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +185 -30
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/package.json +12 -8
- package/dist/parser.js +0 -135
- package/dist/parser.js.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -175,7 +175,7 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
|
175
175
|
|
|
176
176
|
END OF TERMS AND CONDITIONS
|
|
177
177
|
|
|
178
|
-
Copyright 2025 PEAC Protocol Contributors
|
|
178
|
+
Copyright 2025-2026 PEAC Protocol Contributors
|
|
179
179
|
|
|
180
180
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
181
|
you may not use this file except in compliance with the License.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __esm = (fn, res) => function __init() {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
};
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// src/parser.ts
|
|
14
|
+
var parser_exports = {};
|
|
15
|
+
__export(parser_exports, {
|
|
16
|
+
emit: () => emit,
|
|
17
|
+
parse: () => parse,
|
|
18
|
+
validate: () => validate
|
|
19
|
+
});
|
|
20
|
+
function parse(content, options = {}) {
|
|
21
|
+
const maxLines = options.maxLines ?? MAX_LINES;
|
|
22
|
+
const errors = [];
|
|
23
|
+
const data = {};
|
|
24
|
+
const lines = content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
25
|
+
if (lines.length > maxLines) {
|
|
26
|
+
return {
|
|
27
|
+
valid: false,
|
|
28
|
+
errors: [`Line limit exceeded: ${lines.length} > ${maxLines}`],
|
|
29
|
+
lineCount: lines.length
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
for (const [index, line] of lines.entries()) {
|
|
33
|
+
let matched = false;
|
|
34
|
+
for (const [field, pattern] of Object.entries(FIELD_PATTERNS)) {
|
|
35
|
+
const match = line.match(pattern);
|
|
36
|
+
if (match) {
|
|
37
|
+
matched = true;
|
|
38
|
+
try {
|
|
39
|
+
switch (field) {
|
|
40
|
+
case "preferences":
|
|
41
|
+
case "access_control":
|
|
42
|
+
case "provenance":
|
|
43
|
+
case "verify":
|
|
44
|
+
data[field] = match[1].trim();
|
|
45
|
+
break;
|
|
46
|
+
case "receipts":
|
|
47
|
+
data.receipts = match[1];
|
|
48
|
+
break;
|
|
49
|
+
case "payments":
|
|
50
|
+
data.payments = parseArray(match[1]);
|
|
51
|
+
break;
|
|
52
|
+
case "public_keys":
|
|
53
|
+
data.public_keys = parsePublicKeys(match[1]);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
errors.push(
|
|
58
|
+
`Line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!matched) {
|
|
65
|
+
errors.push(`Line ${index + 1}: Invalid format: ${line}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!data.verify) {
|
|
69
|
+
errors.push("Missing required field: verify");
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
valid: errors.length === 0,
|
|
73
|
+
data: errors.length === 0 ? data : void 0,
|
|
74
|
+
errors: errors.length > 0 ? errors : void 0,
|
|
75
|
+
lineCount: lines.length
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function parseArray(content) {
|
|
79
|
+
return content.split(",").map((item) => item.trim().replace(/^["']|["']$/g, "")).filter((item) => item.length > 0);
|
|
80
|
+
}
|
|
81
|
+
function parsePublicKeys(content) {
|
|
82
|
+
const keyStrings = parseArray(content);
|
|
83
|
+
const keys = [];
|
|
84
|
+
for (const keyString of keyStrings) {
|
|
85
|
+
const keyMatch = keyString.match(/^([^:]+):([^:]+):(.+)$/);
|
|
86
|
+
if (!keyMatch) {
|
|
87
|
+
throw new Error(`Invalid public key format: ${keyString}`);
|
|
88
|
+
}
|
|
89
|
+
keys.push({
|
|
90
|
+
kid: keyMatch[1],
|
|
91
|
+
alg: keyMatch[2],
|
|
92
|
+
key: keyMatch[3]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return keys;
|
|
96
|
+
}
|
|
97
|
+
function assertSafeFieldValue(value, fieldName) {
|
|
98
|
+
if (UNSAFE_FIELD_CHARS.test(value)) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Invalid ${fieldName}: must not contain quotes, colons, brackets, newlines, or control characters`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function emit(data) {
|
|
105
|
+
const lines = [];
|
|
106
|
+
if (data.preferences) {
|
|
107
|
+
lines.push(`preferences: ${data.preferences}`);
|
|
108
|
+
}
|
|
109
|
+
if (data.access_control) {
|
|
110
|
+
lines.push(`access_control: ${data.access_control}`);
|
|
111
|
+
}
|
|
112
|
+
if (data.payments && data.payments.length > 0) {
|
|
113
|
+
data.payments.forEach((p) => assertSafeFieldValue(p, "payment"));
|
|
114
|
+
const paymentsStr = data.payments.map((p) => `"${p}"`).join(", ");
|
|
115
|
+
lines.push(`payments: [${paymentsStr}]`);
|
|
116
|
+
}
|
|
117
|
+
if (data.provenance) {
|
|
118
|
+
lines.push(`provenance: ${data.provenance}`);
|
|
119
|
+
}
|
|
120
|
+
if (data.receipts) {
|
|
121
|
+
lines.push(`receipts: ${data.receipts}`);
|
|
122
|
+
}
|
|
123
|
+
if (data.verify) {
|
|
124
|
+
lines.push(`verify: ${data.verify}`);
|
|
125
|
+
}
|
|
126
|
+
if (data.public_keys && data.public_keys.length > 0) {
|
|
127
|
+
data.public_keys.forEach((k) => {
|
|
128
|
+
assertSafeFieldValue(k.kid, "kid");
|
|
129
|
+
assertSafeFieldValue(k.alg, "alg");
|
|
130
|
+
assertSafeFieldValue(k.key, "key");
|
|
131
|
+
});
|
|
132
|
+
const keysStr = data.public_keys.map((k) => `"${k.kid}:${k.alg}:${k.key}"`).join(", ");
|
|
133
|
+
lines.push(`public_keys: [${keysStr}]`);
|
|
134
|
+
}
|
|
135
|
+
if (lines.length > MAX_LINES) {
|
|
136
|
+
throw new Error(`Generated peac.txt exceeds ${MAX_LINES} lines: ${lines.length}`);
|
|
137
|
+
}
|
|
138
|
+
return lines.join("\n");
|
|
139
|
+
}
|
|
140
|
+
function validate(content) {
|
|
141
|
+
const result = parse(content);
|
|
142
|
+
return result.valid;
|
|
143
|
+
}
|
|
144
|
+
var MAX_LINES, FIELD_PATTERNS, UNSAFE_FIELD_CHARS;
|
|
145
|
+
var init_parser = __esm({
|
|
146
|
+
"src/parser.ts"() {
|
|
147
|
+
MAX_LINES = 20;
|
|
148
|
+
FIELD_PATTERNS = {
|
|
149
|
+
preferences: /^preferences:\s*(.+)$/,
|
|
150
|
+
access_control: /^access_control:\s*(.+)$/,
|
|
151
|
+
payments: /^payments:\s*\[([^\]]+)\]$/,
|
|
152
|
+
provenance: /^provenance:\s*(.+)$/,
|
|
153
|
+
receipts: /^receipts:\s*(required|optional)$/,
|
|
154
|
+
verify: /^verify:\s*(.+)$/,
|
|
155
|
+
public_keys: /^public_keys:\s*\[([^\]]+)\]$/
|
|
156
|
+
};
|
|
157
|
+
UNSAFE_FIELD_CHARS = /["\n\r\x00-\x1f:[\]]/;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// src/index.ts
|
|
162
|
+
init_parser();
|
|
163
|
+
var VERSION = "0.9.15";
|
|
164
|
+
var MAX_LINES2 = 20;
|
|
165
|
+
var WELL_KNOWN_PATH = "/.well-known/peac.txt";
|
|
166
|
+
var UA = `PEAC/${VERSION} (+https://www.peacprotocol.org)`;
|
|
167
|
+
async function discover(origin) {
|
|
168
|
+
try {
|
|
169
|
+
const url = new URL(WELL_KNOWN_PATH, origin);
|
|
170
|
+
const response = await fetch(url.toString(), {
|
|
171
|
+
headers: { "User-Agent": UA }
|
|
172
|
+
});
|
|
173
|
+
if (!response.ok) {
|
|
174
|
+
return {
|
|
175
|
+
valid: false,
|
|
176
|
+
errors: [`HTTP ${response.status}: ${response.statusText}`]
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const content = await response.text();
|
|
180
|
+
const { parse: parse2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
|
|
181
|
+
return parse2(content);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
return {
|
|
184
|
+
valid: false,
|
|
185
|
+
errors: [`Discovery failed: ${error instanceof Error ? error.message : String(error)}`]
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
exports.MAX_LINES = MAX_LINES2;
|
|
191
|
+
exports.VERSION = VERSION;
|
|
192
|
+
exports.WELL_KNOWN_PATH = WELL_KNOWN_PATH;
|
|
193
|
+
exports.discover = discover;
|
|
194
|
+
exports.emit = emit;
|
|
195
|
+
exports.parse = parse;
|
|
196
|
+
exports.validate = validate;
|
|
197
|
+
//# sourceMappingURL=index.cjs.map
|
|
198
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts","../src/index.ts"],"names":["MAX_LINES","parse"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @peac/disc/parser - peac.txt parser with ≤20 lines enforcement\n * ABNF-compliant discovery document parsing\n */\n\nimport type { PeacDiscovery, ParseResult, PublicKeyInfo, ValidationOptions } from './types.js';\n\nconst MAX_LINES = 20;\nconst FIELD_PATTERNS = {\n preferences: /^preferences:\\s*(.+)$/,\n access_control: /^access_control:\\s*(.+)$/,\n payments: /^payments:\\s*\\[([^\\]]+)\\]$/,\n provenance: /^provenance:\\s*(.+)$/,\n receipts: /^receipts:\\s*(required|optional)$/,\n verify: /^verify:\\s*(.+)$/,\n public_keys: /^public_keys:\\s*\\[([^\\]]+)\\]$/,\n};\n\nexport function parse(content: string, options: ValidationOptions = {}): ParseResult {\n const maxLines = options.maxLines ?? MAX_LINES;\n const errors: string[] = [];\n const data: PeacDiscovery = {};\n\n const lines = content\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l && !l.startsWith('#'));\n\n // Enforce line limit\n if (lines.length > maxLines) {\n return {\n valid: false,\n errors: [`Line limit exceeded: ${lines.length} > ${maxLines}`],\n lineCount: lines.length,\n };\n }\n\n // Parse each line\n for (const [index, line] of lines.entries()) {\n let matched = false;\n\n for (const [field, pattern] of Object.entries(FIELD_PATTERNS)) {\n const match = line.match(pattern);\n if (match) {\n matched = true;\n try {\n switch (field) {\n case 'preferences':\n case 'access_control':\n case 'provenance':\n case 'verify':\n data[field] = match[1].trim();\n break;\n case 'receipts':\n data.receipts = match[1] as 'required' | 'optional';\n break;\n case 'payments':\n data.payments = parseArray(match[1]);\n break;\n case 'public_keys':\n data.public_keys = parsePublicKeys(match[1]);\n break;\n }\n } catch (error) {\n errors.push(\n `Line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n break;\n }\n }\n\n if (!matched) {\n errors.push(`Line ${index + 1}: Invalid format: ${line}`);\n }\n }\n\n // Validate required fields\n if (!data.verify) {\n errors.push('Missing required field: verify');\n }\n\n return {\n valid: errors.length === 0,\n data: errors.length === 0 ? data : undefined,\n errors: errors.length > 0 ? errors : undefined,\n lineCount: lines.length,\n };\n}\n\nfunction parseArray(content: string): string[] {\n return content\n .split(',')\n .map((item) => item.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter((item) => item.length > 0);\n}\n\nfunction parsePublicKeys(content: string): PublicKeyInfo[] {\n const keyStrings = parseArray(content);\n const keys: PublicKeyInfo[] = [];\n\n for (const keyString of keyStrings) {\n const keyMatch = keyString.match(/^([^:]+):([^:]+):(.+)$/);\n if (!keyMatch) {\n throw new Error(`Invalid public key format: ${keyString}`);\n }\n\n keys.push({\n kid: keyMatch[1],\n alg: keyMatch[2],\n key: keyMatch[3],\n });\n }\n\n return keys;\n}\n\n/** Characters that break peac.txt wire format: quotes, colons, brackets, control chars */\nconst UNSAFE_FIELD_CHARS = /[\"\\n\\r\\x00-\\x1f:[\\]]/;\n\nfunction assertSafeFieldValue(value: string, fieldName: string): void {\n if (UNSAFE_FIELD_CHARS.test(value)) {\n throw new Error(\n `Invalid ${fieldName}: must not contain quotes, colons, brackets, newlines, or control characters`\n );\n }\n}\n\nexport function emit(data: PeacDiscovery): string {\n const lines: string[] = [];\n\n if (data.preferences) {\n lines.push(`preferences: ${data.preferences}`);\n }\n\n if (data.access_control) {\n lines.push(`access_control: ${data.access_control}`);\n }\n\n if (data.payments && data.payments.length > 0) {\n data.payments.forEach((p) => assertSafeFieldValue(p, 'payment'));\n const paymentsStr = data.payments.map((p) => `\"${p}\"`).join(', ');\n lines.push(`payments: [${paymentsStr}]`);\n }\n\n if (data.provenance) {\n lines.push(`provenance: ${data.provenance}`);\n }\n\n if (data.receipts) {\n lines.push(`receipts: ${data.receipts}`);\n }\n\n if (data.verify) {\n lines.push(`verify: ${data.verify}`);\n }\n\n if (data.public_keys && data.public_keys.length > 0) {\n data.public_keys.forEach((k) => {\n assertSafeFieldValue(k.kid, 'kid');\n assertSafeFieldValue(k.alg, 'alg');\n assertSafeFieldValue(k.key, 'key');\n });\n const keysStr = data.public_keys.map((k) => `\"${k.kid}:${k.alg}:${k.key}\"`).join(', ');\n lines.push(`public_keys: [${keysStr}]`);\n }\n\n // Enforce line limit during emission\n if (lines.length > MAX_LINES) {\n throw new Error(`Generated peac.txt exceeds ${MAX_LINES} lines: ${lines.length}`);\n }\n\n return lines.join('\\n');\n}\n\nexport function validate(content: string): boolean {\n const result = parse(content);\n return result.valid;\n}\n","/**\n * @peac/disc - PEAC discovery with ≤20 lines enforcement\n * ABNF-compliant .well-known/peac.txt parser and generator\n */\n\nexport { parse, emit, validate } from './parser.js';\nexport type { PeacDiscovery, PublicKeyInfo, ParseResult, ValidationOptions } from './types.js';\n\n// Constants\nexport const VERSION = '0.9.15';\nexport const MAX_LINES = 20;\nexport const WELL_KNOWN_PATH = '/.well-known/peac.txt';\n\nconst UA = `PEAC/${VERSION} (+https://www.peacprotocol.org)`;\n\n// Convenience function for fetching and parsing discovery documents\nexport async function discover(origin: string): Promise<import('./types.js').ParseResult> {\n try {\n const url = new URL(WELL_KNOWN_PATH, origin);\n const response = await fetch(url.toString(), {\n headers: { 'User-Agent': UA },\n });\n\n if (!response.ok) {\n return {\n valid: false,\n errors: [`HTTP ${response.status}: ${response.statusText}`],\n };\n }\n\n const content = await response.text();\n const { parse } = await import('./parser.js');\n return parse(content);\n } catch (error) {\n return {\n valid: false,\n errors: [`Discovery failed: ${error instanceof Error ? error.message : String(error)}`],\n };\n }\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,35 +1,190 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/parser.ts
|
|
12
|
+
var parser_exports = {};
|
|
13
|
+
__export(parser_exports, {
|
|
14
|
+
emit: () => emit,
|
|
15
|
+
parse: () => parse,
|
|
16
|
+
validate: () => validate
|
|
17
|
+
});
|
|
18
|
+
function parse(content, options = {}) {
|
|
19
|
+
const maxLines = options.maxLines ?? MAX_LINES;
|
|
20
|
+
const errors = [];
|
|
21
|
+
const data = {};
|
|
22
|
+
const lines = content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
23
|
+
if (lines.length > maxLines) {
|
|
24
|
+
return {
|
|
25
|
+
valid: false,
|
|
26
|
+
errors: [`Line limit exceeded: ${lines.length} > ${maxLines}`],
|
|
27
|
+
lineCount: lines.length
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
for (const [index, line] of lines.entries()) {
|
|
31
|
+
let matched = false;
|
|
32
|
+
for (const [field, pattern] of Object.entries(FIELD_PATTERNS)) {
|
|
33
|
+
const match = line.match(pattern);
|
|
34
|
+
if (match) {
|
|
35
|
+
matched = true;
|
|
36
|
+
try {
|
|
37
|
+
switch (field) {
|
|
38
|
+
case "preferences":
|
|
39
|
+
case "access_control":
|
|
40
|
+
case "provenance":
|
|
41
|
+
case "verify":
|
|
42
|
+
data[field] = match[1].trim();
|
|
43
|
+
break;
|
|
44
|
+
case "receipts":
|
|
45
|
+
data.receipts = match[1];
|
|
46
|
+
break;
|
|
47
|
+
case "payments":
|
|
48
|
+
data.payments = parseArray(match[1]);
|
|
49
|
+
break;
|
|
50
|
+
case "public_keys":
|
|
51
|
+
data.public_keys = parsePublicKeys(match[1]);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
errors.push(
|
|
56
|
+
`Line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`
|
|
57
|
+
);
|
|
23
58
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return parse(content);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
27
61
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
valid: false,
|
|
31
|
-
errors: [`Discovery failed: ${error instanceof Error ? error.message : String(error)}`],
|
|
32
|
-
};
|
|
62
|
+
if (!matched) {
|
|
63
|
+
errors.push(`Line ${index + 1}: Invalid format: ${line}`);
|
|
33
64
|
}
|
|
65
|
+
}
|
|
66
|
+
if (!data.verify) {
|
|
67
|
+
errors.push("Missing required field: verify");
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
valid: errors.length === 0,
|
|
71
|
+
data: errors.length === 0 ? data : void 0,
|
|
72
|
+
errors: errors.length > 0 ? errors : void 0,
|
|
73
|
+
lineCount: lines.length
|
|
74
|
+
};
|
|
34
75
|
}
|
|
76
|
+
function parseArray(content) {
|
|
77
|
+
return content.split(",").map((item) => item.trim().replace(/^["']|["']$/g, "")).filter((item) => item.length > 0);
|
|
78
|
+
}
|
|
79
|
+
function parsePublicKeys(content) {
|
|
80
|
+
const keyStrings = parseArray(content);
|
|
81
|
+
const keys = [];
|
|
82
|
+
for (const keyString of keyStrings) {
|
|
83
|
+
const keyMatch = keyString.match(/^([^:]+):([^:]+):(.+)$/);
|
|
84
|
+
if (!keyMatch) {
|
|
85
|
+
throw new Error(`Invalid public key format: ${keyString}`);
|
|
86
|
+
}
|
|
87
|
+
keys.push({
|
|
88
|
+
kid: keyMatch[1],
|
|
89
|
+
alg: keyMatch[2],
|
|
90
|
+
key: keyMatch[3]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return keys;
|
|
94
|
+
}
|
|
95
|
+
function assertSafeFieldValue(value, fieldName) {
|
|
96
|
+
if (UNSAFE_FIELD_CHARS.test(value)) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Invalid ${fieldName}: must not contain quotes, colons, brackets, newlines, or control characters`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function emit(data) {
|
|
103
|
+
const lines = [];
|
|
104
|
+
if (data.preferences) {
|
|
105
|
+
lines.push(`preferences: ${data.preferences}`);
|
|
106
|
+
}
|
|
107
|
+
if (data.access_control) {
|
|
108
|
+
lines.push(`access_control: ${data.access_control}`);
|
|
109
|
+
}
|
|
110
|
+
if (data.payments && data.payments.length > 0) {
|
|
111
|
+
data.payments.forEach((p) => assertSafeFieldValue(p, "payment"));
|
|
112
|
+
const paymentsStr = data.payments.map((p) => `"${p}"`).join(", ");
|
|
113
|
+
lines.push(`payments: [${paymentsStr}]`);
|
|
114
|
+
}
|
|
115
|
+
if (data.provenance) {
|
|
116
|
+
lines.push(`provenance: ${data.provenance}`);
|
|
117
|
+
}
|
|
118
|
+
if (data.receipts) {
|
|
119
|
+
lines.push(`receipts: ${data.receipts}`);
|
|
120
|
+
}
|
|
121
|
+
if (data.verify) {
|
|
122
|
+
lines.push(`verify: ${data.verify}`);
|
|
123
|
+
}
|
|
124
|
+
if (data.public_keys && data.public_keys.length > 0) {
|
|
125
|
+
data.public_keys.forEach((k) => {
|
|
126
|
+
assertSafeFieldValue(k.kid, "kid");
|
|
127
|
+
assertSafeFieldValue(k.alg, "alg");
|
|
128
|
+
assertSafeFieldValue(k.key, "key");
|
|
129
|
+
});
|
|
130
|
+
const keysStr = data.public_keys.map((k) => `"${k.kid}:${k.alg}:${k.key}"`).join(", ");
|
|
131
|
+
lines.push(`public_keys: [${keysStr}]`);
|
|
132
|
+
}
|
|
133
|
+
if (lines.length > MAX_LINES) {
|
|
134
|
+
throw new Error(`Generated peac.txt exceeds ${MAX_LINES} lines: ${lines.length}`);
|
|
135
|
+
}
|
|
136
|
+
return lines.join("\n");
|
|
137
|
+
}
|
|
138
|
+
function validate(content) {
|
|
139
|
+
const result = parse(content);
|
|
140
|
+
return result.valid;
|
|
141
|
+
}
|
|
142
|
+
var MAX_LINES, FIELD_PATTERNS, UNSAFE_FIELD_CHARS;
|
|
143
|
+
var init_parser = __esm({
|
|
144
|
+
"src/parser.ts"() {
|
|
145
|
+
MAX_LINES = 20;
|
|
146
|
+
FIELD_PATTERNS = {
|
|
147
|
+
preferences: /^preferences:\s*(.+)$/,
|
|
148
|
+
access_control: /^access_control:\s*(.+)$/,
|
|
149
|
+
payments: /^payments:\s*\[([^\]]+)\]$/,
|
|
150
|
+
provenance: /^provenance:\s*(.+)$/,
|
|
151
|
+
receipts: /^receipts:\s*(required|optional)$/,
|
|
152
|
+
verify: /^verify:\s*(.+)$/,
|
|
153
|
+
public_keys: /^public_keys:\s*\[([^\]]+)\]$/
|
|
154
|
+
};
|
|
155
|
+
UNSAFE_FIELD_CHARS = /["\n\r\x00-\x1f:[\]]/;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// src/index.ts
|
|
160
|
+
init_parser();
|
|
161
|
+
var VERSION = "0.9.15";
|
|
162
|
+
var MAX_LINES2 = 20;
|
|
163
|
+
var WELL_KNOWN_PATH = "/.well-known/peac.txt";
|
|
164
|
+
var UA = `PEAC/${VERSION} (+https://www.peacprotocol.org)`;
|
|
165
|
+
async function discover(origin) {
|
|
166
|
+
try {
|
|
167
|
+
const url = new URL(WELL_KNOWN_PATH, origin);
|
|
168
|
+
const response = await fetch(url.toString(), {
|
|
169
|
+
headers: { "User-Agent": UA }
|
|
170
|
+
});
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
return {
|
|
173
|
+
valid: false,
|
|
174
|
+
errors: [`HTTP ${response.status}: ${response.statusText}`]
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const content = await response.text();
|
|
178
|
+
const { parse: parse2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
|
|
179
|
+
return parse2(content);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
return {
|
|
182
|
+
valid: false,
|
|
183
|
+
errors: [`Discovery failed: ${error instanceof Error ? error.message : String(error)}`]
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export { MAX_LINES2 as MAX_LINES, VERSION, WELL_KNOWN_PATH, discover, emit, parse, validate };
|
|
189
|
+
//# sourceMappingURL=index.js.map
|
|
35
190
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGpD,YAAY;AACZ,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAChC,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAC5B,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAEvD,MAAM,EAAE,GAAG,QAAQ,OAAO,kCAAkC,CAAC;AAE7D,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAc;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;SAC9B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;aAC5D,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,CAAC,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;SACxF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts","../src/index.ts"],"names":["MAX_LINES","parse"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @peac/disc/parser - peac.txt parser with ≤20 lines enforcement\n * ABNF-compliant discovery document parsing\n */\n\nimport type { PeacDiscovery, ParseResult, PublicKeyInfo, ValidationOptions } from './types.js';\n\nconst MAX_LINES = 20;\nconst FIELD_PATTERNS = {\n preferences: /^preferences:\\s*(.+)$/,\n access_control: /^access_control:\\s*(.+)$/,\n payments: /^payments:\\s*\\[([^\\]]+)\\]$/,\n provenance: /^provenance:\\s*(.+)$/,\n receipts: /^receipts:\\s*(required|optional)$/,\n verify: /^verify:\\s*(.+)$/,\n public_keys: /^public_keys:\\s*\\[([^\\]]+)\\]$/,\n};\n\nexport function parse(content: string, options: ValidationOptions = {}): ParseResult {\n const maxLines = options.maxLines ?? MAX_LINES;\n const errors: string[] = [];\n const data: PeacDiscovery = {};\n\n const lines = content\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l && !l.startsWith('#'));\n\n // Enforce line limit\n if (lines.length > maxLines) {\n return {\n valid: false,\n errors: [`Line limit exceeded: ${lines.length} > ${maxLines}`],\n lineCount: lines.length,\n };\n }\n\n // Parse each line\n for (const [index, line] of lines.entries()) {\n let matched = false;\n\n for (const [field, pattern] of Object.entries(FIELD_PATTERNS)) {\n const match = line.match(pattern);\n if (match) {\n matched = true;\n try {\n switch (field) {\n case 'preferences':\n case 'access_control':\n case 'provenance':\n case 'verify':\n data[field] = match[1].trim();\n break;\n case 'receipts':\n data.receipts = match[1] as 'required' | 'optional';\n break;\n case 'payments':\n data.payments = parseArray(match[1]);\n break;\n case 'public_keys':\n data.public_keys = parsePublicKeys(match[1]);\n break;\n }\n } catch (error) {\n errors.push(\n `Line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n break;\n }\n }\n\n if (!matched) {\n errors.push(`Line ${index + 1}: Invalid format: ${line}`);\n }\n }\n\n // Validate required fields\n if (!data.verify) {\n errors.push('Missing required field: verify');\n }\n\n return {\n valid: errors.length === 0,\n data: errors.length === 0 ? data : undefined,\n errors: errors.length > 0 ? errors : undefined,\n lineCount: lines.length,\n };\n}\n\nfunction parseArray(content: string): string[] {\n return content\n .split(',')\n .map((item) => item.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter((item) => item.length > 0);\n}\n\nfunction parsePublicKeys(content: string): PublicKeyInfo[] {\n const keyStrings = parseArray(content);\n const keys: PublicKeyInfo[] = [];\n\n for (const keyString of keyStrings) {\n const keyMatch = keyString.match(/^([^:]+):([^:]+):(.+)$/);\n if (!keyMatch) {\n throw new Error(`Invalid public key format: ${keyString}`);\n }\n\n keys.push({\n kid: keyMatch[1],\n alg: keyMatch[2],\n key: keyMatch[3],\n });\n }\n\n return keys;\n}\n\n/** Characters that break peac.txt wire format: quotes, colons, brackets, control chars */\nconst UNSAFE_FIELD_CHARS = /[\"\\n\\r\\x00-\\x1f:[\\]]/;\n\nfunction assertSafeFieldValue(value: string, fieldName: string): void {\n if (UNSAFE_FIELD_CHARS.test(value)) {\n throw new Error(\n `Invalid ${fieldName}: must not contain quotes, colons, brackets, newlines, or control characters`\n );\n }\n}\n\nexport function emit(data: PeacDiscovery): string {\n const lines: string[] = [];\n\n if (data.preferences) {\n lines.push(`preferences: ${data.preferences}`);\n }\n\n if (data.access_control) {\n lines.push(`access_control: ${data.access_control}`);\n }\n\n if (data.payments && data.payments.length > 0) {\n data.payments.forEach((p) => assertSafeFieldValue(p, 'payment'));\n const paymentsStr = data.payments.map((p) => `\"${p}\"`).join(', ');\n lines.push(`payments: [${paymentsStr}]`);\n }\n\n if (data.provenance) {\n lines.push(`provenance: ${data.provenance}`);\n }\n\n if (data.receipts) {\n lines.push(`receipts: ${data.receipts}`);\n }\n\n if (data.verify) {\n lines.push(`verify: ${data.verify}`);\n }\n\n if (data.public_keys && data.public_keys.length > 0) {\n data.public_keys.forEach((k) => {\n assertSafeFieldValue(k.kid, 'kid');\n assertSafeFieldValue(k.alg, 'alg');\n assertSafeFieldValue(k.key, 'key');\n });\n const keysStr = data.public_keys.map((k) => `\"${k.kid}:${k.alg}:${k.key}\"`).join(', ');\n lines.push(`public_keys: [${keysStr}]`);\n }\n\n // Enforce line limit during emission\n if (lines.length > MAX_LINES) {\n throw new Error(`Generated peac.txt exceeds ${MAX_LINES} lines: ${lines.length}`);\n }\n\n return lines.join('\\n');\n}\n\nexport function validate(content: string): boolean {\n const result = parse(content);\n return result.valid;\n}\n","/**\n * @peac/disc - PEAC discovery with ≤20 lines enforcement\n * ABNF-compliant .well-known/peac.txt parser and generator\n */\n\nexport { parse, emit, validate } from './parser.js';\nexport type { PeacDiscovery, PublicKeyInfo, ParseResult, ValidationOptions } from './types.js';\n\n// Constants\nexport const VERSION = '0.9.15';\nexport const MAX_LINES = 20;\nexport const WELL_KNOWN_PATH = '/.well-known/peac.txt';\n\nconst UA = `PEAC/${VERSION} (+https://www.peacprotocol.org)`;\n\n// Convenience function for fetching and parsing discovery documents\nexport async function discover(origin: string): Promise<import('./types.js').ParseResult> {\n try {\n const url = new URL(WELL_KNOWN_PATH, origin);\n const response = await fetch(url.toString(), {\n headers: { 'User-Agent': UA },\n });\n\n if (!response.ok) {\n return {\n valid: false,\n errors: [`HTTP ${response.status}: ${response.statusText}`],\n };\n }\n\n const content = await response.text();\n const { parse } = await import('./parser.js');\n return parse(content);\n } catch (error) {\n return {\n valid: false,\n errors: [`Discovery failed: ${error instanceof Error ? error.message : String(error)}`],\n };\n }\n}\n"]}
|
package/dist/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAiB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAa/F,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,WAAW,CAsEnF;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAiB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAa/F,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,WAAW,CAsEnF;AAwCD,wBAAgB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA6ChD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGjD"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peac/disc",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.11",
|
|
4
4
|
"description": "PEAC discovery with ≤20 lines enforcement",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/index.
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
|
-
"require": "./dist/index.
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
13
|
"default": "./dist/index.js"
|
|
14
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"dist",
|
|
@@ -21,7 +22,8 @@
|
|
|
21
22
|
],
|
|
22
23
|
"dependencies": {},
|
|
23
24
|
"devDependencies": {
|
|
24
|
-
"typescript": "^5.0.0"
|
|
25
|
+
"typescript": "^5.0.0",
|
|
26
|
+
"tsup": "^8.0.0"
|
|
25
27
|
},
|
|
26
28
|
"keywords": [
|
|
27
29
|
"peac",
|
|
@@ -44,10 +46,12 @@
|
|
|
44
46
|
},
|
|
45
47
|
"sideEffects": false,
|
|
46
48
|
"scripts": {
|
|
47
|
-
"
|
|
48
|
-
"build
|
|
49
|
+
"prebuild": "rm -rf dist",
|
|
50
|
+
"build": "pnpm run build:js && pnpm run build:types",
|
|
51
|
+
"build:types": "rm -f dist/.tsbuildinfo && tsc && rm -f dist/.tsbuildinfo",
|
|
49
52
|
"test": "node --test src/*.test.js",
|
|
50
53
|
"lint": "echo 'Lint temporarily disabled due to workspace dependencies - run from root'",
|
|
51
|
-
"typecheck": "tsc --noEmit"
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"build:js": "tsup"
|
|
52
56
|
}
|
|
53
57
|
}
|
package/dist/parser.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @peac/disc/parser - peac.txt parser with ≤20 lines enforcement
|
|
3
|
-
* ABNF-compliant discovery document parsing
|
|
4
|
-
*/
|
|
5
|
-
const MAX_LINES = 20;
|
|
6
|
-
const FIELD_PATTERNS = {
|
|
7
|
-
preferences: /^preferences:\s*(.+)$/,
|
|
8
|
-
access_control: /^access_control:\s*(.+)$/,
|
|
9
|
-
payments: /^payments:\s*\[([^\]]+)\]$/,
|
|
10
|
-
provenance: /^provenance:\s*(.+)$/,
|
|
11
|
-
receipts: /^receipts:\s*(required|optional)$/,
|
|
12
|
-
verify: /^verify:\s*(.+)$/,
|
|
13
|
-
public_keys: /^public_keys:\s*\[([^\]]+)\]$/,
|
|
14
|
-
};
|
|
15
|
-
export function parse(content, options = {}) {
|
|
16
|
-
const maxLines = options.maxLines ?? MAX_LINES;
|
|
17
|
-
const errors = [];
|
|
18
|
-
const data = {};
|
|
19
|
-
const lines = content
|
|
20
|
-
.split('\n')
|
|
21
|
-
.map((l) => l.trim())
|
|
22
|
-
.filter((l) => l && !l.startsWith('#'));
|
|
23
|
-
// Enforce line limit
|
|
24
|
-
if (lines.length > maxLines) {
|
|
25
|
-
return {
|
|
26
|
-
valid: false,
|
|
27
|
-
errors: [`Line limit exceeded: ${lines.length} > ${maxLines}`],
|
|
28
|
-
lineCount: lines.length,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// Parse each line
|
|
32
|
-
for (const [index, line] of lines.entries()) {
|
|
33
|
-
let matched = false;
|
|
34
|
-
for (const [field, pattern] of Object.entries(FIELD_PATTERNS)) {
|
|
35
|
-
const match = line.match(pattern);
|
|
36
|
-
if (match) {
|
|
37
|
-
matched = true;
|
|
38
|
-
try {
|
|
39
|
-
switch (field) {
|
|
40
|
-
case 'preferences':
|
|
41
|
-
case 'access_control':
|
|
42
|
-
case 'provenance':
|
|
43
|
-
case 'verify':
|
|
44
|
-
data[field] = match[1].trim();
|
|
45
|
-
break;
|
|
46
|
-
case 'receipts':
|
|
47
|
-
data.receipts = match[1];
|
|
48
|
-
break;
|
|
49
|
-
case 'payments':
|
|
50
|
-
data.payments = parseArray(match[1]);
|
|
51
|
-
break;
|
|
52
|
-
case 'public_keys':
|
|
53
|
-
data.public_keys = parsePublicKeys(match[1]);
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
errors.push(`Line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`);
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (!matched) {
|
|
64
|
-
errors.push(`Line ${index + 1}: Invalid format: ${line}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// Validate required fields
|
|
68
|
-
if (!data.verify) {
|
|
69
|
-
errors.push('Missing required field: verify');
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
valid: errors.length === 0,
|
|
73
|
-
data: errors.length === 0 ? data : undefined,
|
|
74
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
75
|
-
lineCount: lines.length,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
function parseArray(content) {
|
|
79
|
-
return content
|
|
80
|
-
.split(',')
|
|
81
|
-
.map((item) => item.trim().replace(/^["']|["']$/g, ''))
|
|
82
|
-
.filter((item) => item.length > 0);
|
|
83
|
-
}
|
|
84
|
-
function parsePublicKeys(content) {
|
|
85
|
-
const keyStrings = parseArray(content);
|
|
86
|
-
const keys = [];
|
|
87
|
-
for (const keyString of keyStrings) {
|
|
88
|
-
const keyMatch = keyString.match(/^([^:]+):([^:]+):(.+)$/);
|
|
89
|
-
if (!keyMatch) {
|
|
90
|
-
throw new Error(`Invalid public key format: ${keyString}`);
|
|
91
|
-
}
|
|
92
|
-
keys.push({
|
|
93
|
-
kid: keyMatch[1],
|
|
94
|
-
alg: keyMatch[2],
|
|
95
|
-
key: keyMatch[3],
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
return keys;
|
|
99
|
-
}
|
|
100
|
-
export function emit(data) {
|
|
101
|
-
const lines = [];
|
|
102
|
-
if (data.preferences) {
|
|
103
|
-
lines.push(`preferences: ${data.preferences}`);
|
|
104
|
-
}
|
|
105
|
-
if (data.access_control) {
|
|
106
|
-
lines.push(`access_control: ${data.access_control}`);
|
|
107
|
-
}
|
|
108
|
-
if (data.payments && data.payments.length > 0) {
|
|
109
|
-
const paymentsStr = data.payments.map((p) => `"${p}"`).join(', ');
|
|
110
|
-
lines.push(`payments: [${paymentsStr}]`);
|
|
111
|
-
}
|
|
112
|
-
if (data.provenance) {
|
|
113
|
-
lines.push(`provenance: ${data.provenance}`);
|
|
114
|
-
}
|
|
115
|
-
if (data.receipts) {
|
|
116
|
-
lines.push(`receipts: ${data.receipts}`);
|
|
117
|
-
}
|
|
118
|
-
if (data.verify) {
|
|
119
|
-
lines.push(`verify: ${data.verify}`);
|
|
120
|
-
}
|
|
121
|
-
if (data.public_keys && data.public_keys.length > 0) {
|
|
122
|
-
const keysStr = data.public_keys.map((k) => `"${k.kid}:${k.alg}:${k.key}"`).join(', ');
|
|
123
|
-
lines.push(`public_keys: [${keysStr}]`);
|
|
124
|
-
}
|
|
125
|
-
// Enforce line limit during emission
|
|
126
|
-
if (lines.length > MAX_LINES) {
|
|
127
|
-
throw new Error(`Generated peac.txt exceeds ${MAX_LINES} lines: ${lines.length}`);
|
|
128
|
-
}
|
|
129
|
-
return lines.join('\n');
|
|
130
|
-
}
|
|
131
|
-
export function validate(content) {
|
|
132
|
-
const result = parse(content);
|
|
133
|
-
return result.valid;
|
|
134
|
-
}
|
|
135
|
-
//# sourceMappingURL=parser.js.map
|
package/dist/parser.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
DELETED
package/dist/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|