@miakapp/cli 4.0.0-alpha.3 → 4.0.0-alpha.5
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/assets/agent-guide.md +5 -5
- package/dist/agent-pack.d.ts +86 -0
- package/dist/agent-pack.d.ts.map +1 -0
- package/dist/agent-pack.js +202 -0
- package/dist/agent-pack.js.map +1 -0
- package/dist/artifact.d.ts +32 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +328 -0
- package/dist/artifact.js.map +1 -0
- package/dist/control-plane.d.ts +37 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +127 -0
- package/dist/control-plane.js.map +1 -0
- package/dist/discovery.d.ts +95 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +389 -0
- package/dist/discovery.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +56 -0
- package/dist/errors.js.map +1 -0
- package/dist/internal/http.d.ts +35 -0
- package/dist/internal/http.d.ts.map +1 -0
- package/dist/internal/http.js +125 -0
- package/dist/internal/http.js.map +1 -0
- package/dist/internal/json.d.ts +15 -0
- package/dist/internal/json.d.ts.map +1 -0
- package/dist/internal/json.js +227 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/names.d.ts +45 -0
- package/dist/internal/names.d.ts.map +1 -0
- package/dist/internal/names.js +98 -0
- package/dist/internal/names.js.map +1 -0
- package/dist/internal/requirements.d.ts +10 -0
- package/dist/internal/requirements.d.ts.map +1 -0
- package/dist/internal/requirements.js +50 -0
- package/dist/internal/requirements.js.map +1 -0
- package/dist/internal/yaml.d.ts +26 -0
- package/dist/internal/yaml.d.ts.map +1 -0
- package/dist/internal/yaml.js +184 -0
- package/dist/internal/yaml.js.map +1 -0
- package/dist/main.d.ts +88 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +698 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp.d.ts +93 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +539 -0
- package/dist/mcp.js.map +1 -0
- package/dist/project.d.ts +25 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +90 -0
- package/dist/project.js.map +1 -0
- package/dist/publication.d.ts +95 -0
- package/dist/publication.d.ts.map +1 -0
- package/dist/publication.js +408 -0
- package/dist/publication.js.map +1 -0
- package/dist/version.d.ts +15 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -1
package/dist/artifact.js
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { artifactError } from './errors.js';
|
|
3
|
+
import { MAXIMUM_ARTIFACT_BYTES, MAXIMUM_PROGRAM_TOKENS, } from './internal/names.js';
|
|
4
|
+
const IDENTIFIER_START = /[$_\p{ID_Start}]/u;
|
|
5
|
+
const IDENTIFIER_PART = /[$_\u200c\u200d\p{ID_Continue}]/u;
|
|
6
|
+
/**
|
|
7
|
+
* Tokens after which a `/` starts a regular expression rather than a division.
|
|
8
|
+
* The list is deliberately conservative: a wrong guess only changes how the
|
|
9
|
+
* scanner counts, never whether the broker's pinned parser accepts the program.
|
|
10
|
+
*/
|
|
11
|
+
const REGEX_ALLOWED_AFTER = new Set([
|
|
12
|
+
'case', 'delete', 'do', 'else', 'in', 'instanceof', 'new', 'of', 'return',
|
|
13
|
+
'throw', 'typeof', 'void', 'yield',
|
|
14
|
+
]);
|
|
15
|
+
function isRegexPosition(previous) {
|
|
16
|
+
if (previous === undefined)
|
|
17
|
+
return true;
|
|
18
|
+
if (REGEX_ALLOWED_AFTER.has(previous))
|
|
19
|
+
return true;
|
|
20
|
+
if (/^[A-Za-z_$]/.test(previous))
|
|
21
|
+
return false;
|
|
22
|
+
if (/^[0-9]/.test(previous))
|
|
23
|
+
return false;
|
|
24
|
+
return previous !== ')' && previous !== ']' && previous !== '}' && previous !== '++'
|
|
25
|
+
&& previous !== '--' && previous[0] !== '"' && previous[0] !== "'" && previous[0] !== '`';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Publisher pre-check for the RFC 0002 §7.2 artifact rules.
|
|
29
|
+
*
|
|
30
|
+
* RFC 0002 makes the broker's pinned platform parser authoritative; this scan
|
|
31
|
+
* exists so an agent learns about module syntax, a dynamic import, a source-map
|
|
32
|
+
* directive or an oversized program before spending an upload capability. It
|
|
33
|
+
* reports findings rather than throwing, so one run can show every problem.
|
|
34
|
+
*/
|
|
35
|
+
export function scanArtifactSource(source) {
|
|
36
|
+
const findings = [];
|
|
37
|
+
let index = 0;
|
|
38
|
+
let line = 1;
|
|
39
|
+
let tokens = 0;
|
|
40
|
+
let previous;
|
|
41
|
+
let lineStartOnlyWhitespace = true;
|
|
42
|
+
const record = (kind, detail) => {
|
|
43
|
+
if (findings.some((finding) => finding.kind === kind && finding.line === line))
|
|
44
|
+
return;
|
|
45
|
+
findings.push({ kind, line, detail });
|
|
46
|
+
};
|
|
47
|
+
const advanceLines = (text) => {
|
|
48
|
+
for (const character of text)
|
|
49
|
+
if (character === '\n')
|
|
50
|
+
line += 1;
|
|
51
|
+
};
|
|
52
|
+
while (index < source.length) {
|
|
53
|
+
const character = source[index];
|
|
54
|
+
if (character === '\n') {
|
|
55
|
+
line += 1;
|
|
56
|
+
lineStartOnlyWhitespace = true;
|
|
57
|
+
index += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (character === ' ' || character === '\t' || character === '\r' || character === '\f'
|
|
61
|
+
|| character === '\v' || character === '\u00a0' || character === '\ufeff') {
|
|
62
|
+
index += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (character === '/' && source[index + 1] === '/') {
|
|
66
|
+
const end = source.indexOf('\n', index);
|
|
67
|
+
const comment = source.slice(index, end === -1 ? source.length : end);
|
|
68
|
+
if (/^\/\/[#@]\s*sourceMappingURL=/.test(comment)) {
|
|
69
|
+
record('source_map_directive', comment.trim());
|
|
70
|
+
}
|
|
71
|
+
index = end === -1 ? source.length : end;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (character === '/' && source[index + 1] === '*') {
|
|
75
|
+
const end = source.indexOf('*/', index + 2);
|
|
76
|
+
if (end === -1) {
|
|
77
|
+
record('unterminated', 'Unterminated block comment');
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
const comment = source.slice(index, end + 2);
|
|
81
|
+
if (/^\/\*[#@]\s*sourceMappingURL=/.test(comment)) {
|
|
82
|
+
record('source_map_directive', comment.slice(0, 64));
|
|
83
|
+
}
|
|
84
|
+
advanceLines(comment);
|
|
85
|
+
index = end + 2;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (character === '"' || character === "'") {
|
|
89
|
+
const end = scanQuoted(source, index, character);
|
|
90
|
+
if (end === -1) {
|
|
91
|
+
record('unterminated', 'Unterminated string literal');
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
advanceLines(source.slice(index, end));
|
|
95
|
+
previous = `${character}string`;
|
|
96
|
+
tokens += 1;
|
|
97
|
+
index = end;
|
|
98
|
+
lineStartOnlyWhitespace = false;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (character === '`') {
|
|
102
|
+
const end = scanTemplate(source, index);
|
|
103
|
+
if (end === -1) {
|
|
104
|
+
record('unterminated', 'Unterminated template literal');
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
advanceLines(source.slice(index, end));
|
|
108
|
+
previous = '`template';
|
|
109
|
+
tokens += 1;
|
|
110
|
+
index = end;
|
|
111
|
+
lineStartOnlyWhitespace = false;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (character === '/' && isRegexPosition(previous)) {
|
|
115
|
+
const end = scanRegex(source, index);
|
|
116
|
+
if (end === -1) {
|
|
117
|
+
record('unterminated', 'Unterminated regular expression literal');
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
previous = '/regex';
|
|
121
|
+
tokens += 1;
|
|
122
|
+
index = end;
|
|
123
|
+
lineStartOnlyWhitespace = false;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (IDENTIFIER_START.test(character)) {
|
|
127
|
+
let end = index + 1;
|
|
128
|
+
while (end < source.length && IDENTIFIER_PART.test(source[end]))
|
|
129
|
+
end += 1;
|
|
130
|
+
const word = source.slice(index, end);
|
|
131
|
+
if (word === 'import') {
|
|
132
|
+
const next = nextSignificant(source, end);
|
|
133
|
+
if (next === '(')
|
|
134
|
+
record('dynamic_import', 'import( expression');
|
|
135
|
+
else if (next === '.')
|
|
136
|
+
record('dynamic_import', 'import.meta reference');
|
|
137
|
+
else
|
|
138
|
+
record('module_syntax', 'import declaration');
|
|
139
|
+
}
|
|
140
|
+
else if (word === 'export' && lineStartOnlyWhitespace) {
|
|
141
|
+
record('module_syntax', 'export declaration');
|
|
142
|
+
}
|
|
143
|
+
previous = word;
|
|
144
|
+
tokens += 1;
|
|
145
|
+
index = end;
|
|
146
|
+
lineStartOnlyWhitespace = false;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (character >= '0' && character <= '9') {
|
|
150
|
+
let end = index + 1;
|
|
151
|
+
while (end < source.length && /[0-9a-fA-FxXoObBn._]/.test(source[end]))
|
|
152
|
+
end += 1;
|
|
153
|
+
previous = source.slice(index, end);
|
|
154
|
+
tokens += 1;
|
|
155
|
+
index = end;
|
|
156
|
+
lineStartOnlyWhitespace = false;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const punctuator = scanPunctuator(source, index);
|
|
160
|
+
previous = punctuator;
|
|
161
|
+
tokens += 1;
|
|
162
|
+
index += punctuator.length;
|
|
163
|
+
lineStartOnlyWhitespace = false;
|
|
164
|
+
if (tokens > MAXIMUM_PROGRAM_TOKENS)
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
if (tokens > MAXIMUM_PROGRAM_TOKENS) {
|
|
168
|
+
findings.push({
|
|
169
|
+
kind: 'token_ceiling',
|
|
170
|
+
line,
|
|
171
|
+
detail: `Program exceeds the ABI 1 ceiling of ${MAXIMUM_PROGRAM_TOKENS} lexical tokens`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return { tokens, findings };
|
|
175
|
+
}
|
|
176
|
+
function scanQuoted(source, start, quote) {
|
|
177
|
+
let index = start + 1;
|
|
178
|
+
while (index < source.length) {
|
|
179
|
+
const character = source[index];
|
|
180
|
+
if (character === '\\') {
|
|
181
|
+
index += 2;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (character === quote)
|
|
185
|
+
return index + 1;
|
|
186
|
+
if (character === '\n')
|
|
187
|
+
return -1;
|
|
188
|
+
index += 1;
|
|
189
|
+
}
|
|
190
|
+
return -1;
|
|
191
|
+
}
|
|
192
|
+
function scanTemplate(source, start) {
|
|
193
|
+
let index = start + 1;
|
|
194
|
+
while (index < source.length) {
|
|
195
|
+
const character = source[index];
|
|
196
|
+
if (character === '\\') {
|
|
197
|
+
index += 2;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (character === '`')
|
|
201
|
+
return index + 1;
|
|
202
|
+
if (character === '$' && source[index + 1] === '{') {
|
|
203
|
+
let depth = 1;
|
|
204
|
+
index += 2;
|
|
205
|
+
while (index < source.length && depth > 0) {
|
|
206
|
+
const inner = source[index];
|
|
207
|
+
if (inner === '{')
|
|
208
|
+
depth += 1;
|
|
209
|
+
else if (inner === '}')
|
|
210
|
+
depth -= 1;
|
|
211
|
+
else if (inner === '`') {
|
|
212
|
+
const nested = scanTemplate(source, index);
|
|
213
|
+
if (nested === -1)
|
|
214
|
+
return -1;
|
|
215
|
+
index = nested;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
else if (inner === '"' || inner === "'") {
|
|
219
|
+
const nested = scanQuoted(source, index, inner);
|
|
220
|
+
if (nested === -1)
|
|
221
|
+
return -1;
|
|
222
|
+
index = nested;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
index += 1;
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
index += 1;
|
|
230
|
+
}
|
|
231
|
+
return -1;
|
|
232
|
+
}
|
|
233
|
+
function scanRegex(source, start) {
|
|
234
|
+
let index = start + 1;
|
|
235
|
+
let inClass = false;
|
|
236
|
+
while (index < source.length) {
|
|
237
|
+
const character = source[index];
|
|
238
|
+
if (character === '\\') {
|
|
239
|
+
index += 2;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (character === '\n')
|
|
243
|
+
return -1;
|
|
244
|
+
if (character === '[')
|
|
245
|
+
inClass = true;
|
|
246
|
+
else if (character === ']')
|
|
247
|
+
inClass = false;
|
|
248
|
+
else if (character === '/' && !inClass) {
|
|
249
|
+
index += 1;
|
|
250
|
+
while (index < source.length && IDENTIFIER_PART.test(source[index]))
|
|
251
|
+
index += 1;
|
|
252
|
+
return index;
|
|
253
|
+
}
|
|
254
|
+
index += 1;
|
|
255
|
+
}
|
|
256
|
+
return -1;
|
|
257
|
+
}
|
|
258
|
+
const PUNCTUATORS = [
|
|
259
|
+
'>>>=', '...', '===', '!==', '**=', '<<=', '>>=', '>>>', '&&=', '||=', '??=',
|
|
260
|
+
'=>', '==', '!=', '<=', '>=', '&&', '||', '??', '?.', '++', '--', '+=', '-=',
|
|
261
|
+
'*=', '/=', '%=', '&=', '|=', '^=', '<<', '>>', '**',
|
|
262
|
+
];
|
|
263
|
+
function scanPunctuator(source, index) {
|
|
264
|
+
for (const punctuator of PUNCTUATORS) {
|
|
265
|
+
if (source.startsWith(punctuator, index))
|
|
266
|
+
return punctuator;
|
|
267
|
+
}
|
|
268
|
+
return source[index];
|
|
269
|
+
}
|
|
270
|
+
function nextSignificant(source, from) {
|
|
271
|
+
let index = from;
|
|
272
|
+
while (index < source.length) {
|
|
273
|
+
const character = source[index];
|
|
274
|
+
if (/\s/.test(character)) {
|
|
275
|
+
index += 1;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (character === '/' && source[index + 1] === '/') {
|
|
279
|
+
const end = source.indexOf('\n', index);
|
|
280
|
+
if (end === -1)
|
|
281
|
+
return undefined;
|
|
282
|
+
index = end + 1;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (character === '/' && source[index + 1] === '*') {
|
|
286
|
+
const end = source.indexOf('*/', index + 2);
|
|
287
|
+
if (end === -1)
|
|
288
|
+
return undefined;
|
|
289
|
+
index = end + 2;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
return character;
|
|
293
|
+
}
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Verifies the exact bytes an upload would deliver and derives the digest and
|
|
298
|
+
* size that bind the upload capability.
|
|
299
|
+
*/
|
|
300
|
+
export function prepareArtifact(bytes) {
|
|
301
|
+
if (bytes.byteLength === 0)
|
|
302
|
+
throw artifactError('Artifact is empty');
|
|
303
|
+
if (bytes.byteLength > MAXIMUM_ARTIFACT_BYTES) {
|
|
304
|
+
throw artifactError(`Artifact is ${bytes.byteLength} bytes, above the ABI 1 ceiling of ${MAXIMUM_ARTIFACT_BYTES}`);
|
|
305
|
+
}
|
|
306
|
+
let source;
|
|
307
|
+
try {
|
|
308
|
+
source = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
throw artifactError('Artifact is not valid UTF-8');
|
|
312
|
+
}
|
|
313
|
+
const { tokens, findings } = scanArtifactSource(source);
|
|
314
|
+
if (findings.length > 0) {
|
|
315
|
+
const detail = findings
|
|
316
|
+
.map((finding) => ` line ${finding.line}: ${finding.kind} — ${finding.detail}`)
|
|
317
|
+
.join('\n');
|
|
318
|
+
throw artifactError(`Artifact violates the RFC 0002 §7.2 artifact rules:\n${detail}`, 'Bundle to one self-contained classic Worker program with no module syntax, '
|
|
319
|
+
+ 'no dynamic import and no source map.');
|
|
320
|
+
}
|
|
321
|
+
return Object.freeze({
|
|
322
|
+
bytes,
|
|
323
|
+
sha256: createHash('sha256').update(bytes).digest('base64url'),
|
|
324
|
+
size: bytes.byteLength,
|
|
325
|
+
tokens,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.js","sourceRoot":"","sources":["../src/artifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type FetchLike } from './internal/http.js';
|
|
2
|
+
export interface Discovery {
|
|
3
|
+
readonly issuer: string;
|
|
4
|
+
readonly jwksUri: string;
|
|
5
|
+
readonly exchangeEndpoint: string;
|
|
6
|
+
readonly userRelayExchangeEndpoint: string;
|
|
7
|
+
readonly pushAudience: string;
|
|
8
|
+
readonly componentsAudience: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PublisherToken {
|
|
11
|
+
readonly accessToken: string;
|
|
12
|
+
readonly expiresAtMs: number;
|
|
13
|
+
readonly keyId: string;
|
|
14
|
+
readonly keyLabel: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ControlPlaneOptions {
|
|
17
|
+
readonly issuer: string;
|
|
18
|
+
readonly fetch?: FetchLike;
|
|
19
|
+
}
|
|
20
|
+
export declare function homeKeyId(homeKey: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Reads the pinned deployment profile. The CLI never follows an issuer, JWKS URL
|
|
23
|
+
* or audience supplied by a token: only this document, fetched from the issuer
|
|
24
|
+
* the operator configured, selects endpoints.
|
|
25
|
+
*/
|
|
26
|
+
export declare function fetchDiscovery(options: ControlPlaneOptions): Promise<Discovery>;
|
|
27
|
+
/**
|
|
28
|
+
* Exchanges a Home Key for the five-minute `components:publish` profile.
|
|
29
|
+
*
|
|
30
|
+
* RFC 0004 §7.2 attenuates the issued token to exactly that one scope, and
|
|
31
|
+
* §7.3 omits `relay_url` for this purpose: a component token is useless at a
|
|
32
|
+
* relay. Publication APIs never accept the Home Key itself.
|
|
33
|
+
*/
|
|
34
|
+
export declare function exchangePublisherToken(discovery: Discovery, homeKey: string, options?: {
|
|
35
|
+
readonly fetch?: FetchLike;
|
|
36
|
+
}): Promise<PublisherToken>;
|
|
37
|
+
//# sourceMappingURL=control-plane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAY5B,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUjD;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC,CAwCrF;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAO,GAC3C,OAAO,CAAC,cAAc,CAAC,CA4DzB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { authorizationError, contractError } from './errors.js';
|
|
2
|
+
import { canonicalHttpsUrl, cancelBody, readBoundedBody, requestBody, } from './internal/http.js';
|
|
3
|
+
import { boundedString, exactRecord, parseJson } from './internal/json.js';
|
|
4
|
+
/** RFC 0004 §3 caps the discovery document at 4 KiB. */
|
|
5
|
+
const MAXIMUM_DISCOVERY_BYTES = 4_096;
|
|
6
|
+
/** RFC 0004 §7 leases every access token for at most five minutes. */
|
|
7
|
+
const MAXIMUM_TOKEN_LIFETIME_MS = 330_000;
|
|
8
|
+
const HOME_KEY = /^mhk1_([A-Za-z0-9_-]{22})_([A-Za-z0-9_-]{43})$/;
|
|
9
|
+
const DISCOVERY_PATH = '/.well-known/miakapp-control-plane';
|
|
10
|
+
export function homeKeyId(homeKey) {
|
|
11
|
+
const match = HOME_KEY.exec(homeKey);
|
|
12
|
+
const keyId = match?.[1];
|
|
13
|
+
if (keyId === undefined) {
|
|
14
|
+
throw authorizationError('The Home Key is not a valid mhk1 credential', 'Create a new Home Key with the components:publish scope and store it outside Git.');
|
|
15
|
+
}
|
|
16
|
+
return keyId;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reads the pinned deployment profile. The CLI never follows an issuer, JWKS URL
|
|
20
|
+
* or audience supplied by a token: only this document, fetched from the issuer
|
|
21
|
+
* the operator configured, selects endpoints.
|
|
22
|
+
*/
|
|
23
|
+
export async function fetchDiscovery(options) {
|
|
24
|
+
const issuer = canonicalHttpsUrl(options.issuer, 'issuer');
|
|
25
|
+
if (issuer.endsWith('/'))
|
|
26
|
+
throw contractError('issuer must not have a trailing slash');
|
|
27
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
28
|
+
const response = await fetcher(`${issuer}${DISCOVERY_PATH}`, {
|
|
29
|
+
method: 'GET',
|
|
30
|
+
headers: { accept: 'application/json' },
|
|
31
|
+
redirect: 'error',
|
|
32
|
+
});
|
|
33
|
+
if (response.status !== 200) {
|
|
34
|
+
cancelBody(response);
|
|
35
|
+
throw contractError(`Discovery document returned HTTP ${response.status}`);
|
|
36
|
+
}
|
|
37
|
+
const body = await readBoundedBody(response, MAXIMUM_DISCOVERY_BYTES);
|
|
38
|
+
const document = exactRecord(parseJson(body), [
|
|
39
|
+
'schema',
|
|
40
|
+
'issuer',
|
|
41
|
+
'jwks_uri',
|
|
42
|
+
'exchange_endpoint',
|
|
43
|
+
'user_relay_exchange_endpoint',
|
|
44
|
+
'push_audience',
|
|
45
|
+
'components_audience',
|
|
46
|
+
]);
|
|
47
|
+
if (document.schema !== 'miakapp.control-plane-discovery/1') {
|
|
48
|
+
throw contractError('Discovery document has an unsupported schema');
|
|
49
|
+
}
|
|
50
|
+
if (document.issuer !== issuer) {
|
|
51
|
+
throw contractError('Discovery document advertises a different issuer');
|
|
52
|
+
}
|
|
53
|
+
return Object.freeze({
|
|
54
|
+
issuer,
|
|
55
|
+
jwksUri: canonicalHttpsUrl(document.jwks_uri, 'jwks_uri'),
|
|
56
|
+
exchangeEndpoint: canonicalHttpsUrl(document.exchange_endpoint, 'exchange_endpoint'),
|
|
57
|
+
userRelayExchangeEndpoint: canonicalHttpsUrl(document.user_relay_exchange_endpoint, 'user_relay_exchange_endpoint'),
|
|
58
|
+
pushAudience: canonicalHttpsUrl(document.push_audience, 'push_audience'),
|
|
59
|
+
componentsAudience: canonicalHttpsUrl(document.components_audience, 'components_audience'),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Exchanges a Home Key for the five-minute `components:publish` profile.
|
|
64
|
+
*
|
|
65
|
+
* RFC 0004 §7.2 attenuates the issued token to exactly that one scope, and
|
|
66
|
+
* §7.3 omits `relay_url` for this purpose: a component token is useless at a
|
|
67
|
+
* relay. Publication APIs never accept the Home Key itself.
|
|
68
|
+
*/
|
|
69
|
+
export async function exchangePublisherToken(discovery, homeKey, options = {}) {
|
|
70
|
+
const keyId = homeKeyId(homeKey);
|
|
71
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
72
|
+
const response = await fetcher(discovery.exchangeEndpoint, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
accept: 'application/json',
|
|
76
|
+
authorization: `Bearer ${homeKey}`,
|
|
77
|
+
'content-type': 'application/json',
|
|
78
|
+
},
|
|
79
|
+
body: requestBody({ purpose: 'components' }),
|
|
80
|
+
// No request-side `cache` hint: Node and Bun have no HTTP cache to opt out
|
|
81
|
+
// of, and the response-side no-store headers checked below are the actual
|
|
82
|
+
// guarantee that this token is never stored by an intermediary.
|
|
83
|
+
credentials: 'omit',
|
|
84
|
+
redirect: 'error',
|
|
85
|
+
referrerPolicy: 'no-referrer',
|
|
86
|
+
});
|
|
87
|
+
if (response.status !== 200) {
|
|
88
|
+
cancelBody(response);
|
|
89
|
+
throw authorizationError(`Component token exchange returned HTTP ${response.status}`, 'Confirm the Home Key exists, is not revoked and holds the components:publish scope.');
|
|
90
|
+
}
|
|
91
|
+
if (response.headers.get('cache-control') !== 'no-store'
|
|
92
|
+
|| response.headers.get('pragma') !== 'no-cache'
|
|
93
|
+
|| response.headers.get('referrer-policy') !== 'no-referrer') {
|
|
94
|
+
cancelBody(response);
|
|
95
|
+
throw contractError('Component token response is missing its required no-store headers');
|
|
96
|
+
}
|
|
97
|
+
const body = await readBoundedBody(response, 65_536);
|
|
98
|
+
const document = exactRecord(parseJson(body), [
|
|
99
|
+
'schema',
|
|
100
|
+
'access_token',
|
|
101
|
+
'token_type',
|
|
102
|
+
'expires_at_ms',
|
|
103
|
+
'key',
|
|
104
|
+
]);
|
|
105
|
+
const key = exactRecord(document.key, ['id', 'label']);
|
|
106
|
+
const accessToken = boundedString(document.access_token, 1, 8_192);
|
|
107
|
+
const expiresAtMs = document.expires_at_ms;
|
|
108
|
+
if (document.schema !== 'miakapp.access-token/1'
|
|
109
|
+
|| document.token_type !== 'Bearer'
|
|
110
|
+
|| accessToken.split('.').length !== 3
|
|
111
|
+
|| typeof expiresAtMs !== 'number'
|
|
112
|
+
|| !Number.isSafeInteger(expiresAtMs)
|
|
113
|
+
|| key.id !== keyId) {
|
|
114
|
+
throw contractError('Component token response does not match the closed exchange schema');
|
|
115
|
+
}
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
if (expiresAtMs <= now || expiresAtMs - now > MAXIMUM_TOKEN_LIFETIME_MS) {
|
|
118
|
+
throw contractError('Component token lease is expired or longer than the five-minute ceiling');
|
|
119
|
+
}
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
accessToken,
|
|
122
|
+
expiresAtMs,
|
|
123
|
+
keyId,
|
|
124
|
+
keyLabel: boundedString(key.label, 1, 64),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=control-plane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generous ceiling for a local export. The strict parser in `internal/json.ts`
|
|
3
|
+
* is bounded for untrusted control-plane responses at 2,048 values, which a real
|
|
4
|
+
* house blows through in the first tab; a flows export is an operator-supplied
|
|
5
|
+
* local file, so the bound here is on bytes rather than on structure.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MAXIMUM_FLOWS_BYTES = 33554432;
|
|
8
|
+
export type FindingKind =
|
|
9
|
+
/** A coordinator secret sits in cleartext in the export. */
|
|
10
|
+
'secret_in_export'
|
|
11
|
+
/** An action any signed-in user may invoke, because no group was listed. */
|
|
12
|
+
| 'unrestricted_action'
|
|
13
|
+
/** A V3 name that is not a legal V4 dotted name and has to be renamed. */
|
|
14
|
+
| 'name_needs_rename'
|
|
15
|
+
/** A subscription pattern rather than one device's topic. */
|
|
16
|
+
| 'wildcard_subscription'
|
|
17
|
+
/** A broker reached without TLS. */
|
|
18
|
+
| 'broker_without_tls'
|
|
19
|
+
/** A node type this inventory does not model. */
|
|
20
|
+
| 'unmodelled_node';
|
|
21
|
+
export type FindingSeverity = 'critical' | 'attention' | 'note';
|
|
22
|
+
export interface Finding {
|
|
23
|
+
readonly kind: FindingKind;
|
|
24
|
+
readonly severity: FindingSeverity;
|
|
25
|
+
readonly detail: string;
|
|
26
|
+
readonly nodeId: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
export interface Broker {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly host: string;
|
|
32
|
+
readonly port: number | undefined;
|
|
33
|
+
readonly tls: boolean;
|
|
34
|
+
readonly subscribes: readonly string[];
|
|
35
|
+
readonly publishes: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
export interface FlowTab {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly label: string;
|
|
40
|
+
readonly disabled: boolean;
|
|
41
|
+
readonly nodeCount: number;
|
|
42
|
+
}
|
|
43
|
+
export interface HomeBinding {
|
|
44
|
+
readonly nodeId: string;
|
|
45
|
+
readonly homeId: string;
|
|
46
|
+
readonly coordinatorId: string;
|
|
47
|
+
readonly secretInExport: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** One `commitVariables` entry: a V3 variable path and where its value came from. */
|
|
50
|
+
export interface StateCandidate {
|
|
51
|
+
readonly path: string;
|
|
52
|
+
readonly source: 'jsonata' | 'env' | 'literal';
|
|
53
|
+
readonly nodeId: string;
|
|
54
|
+
readonly legalV4Name: boolean;
|
|
55
|
+
}
|
|
56
|
+
/** One `onUserAction` handler: the V3 shape of what becomes a V4 function. */
|
|
57
|
+
export interface ActionCandidate {
|
|
58
|
+
readonly inputId: string;
|
|
59
|
+
readonly allowedGroups: readonly string[];
|
|
60
|
+
readonly nodeId: string;
|
|
61
|
+
readonly legalV4Name: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** One `sendPushNotif` node: the V3 shape of what becomes a V4 published event. */
|
|
64
|
+
export interface NotificationCandidate {
|
|
65
|
+
readonly nodeId: string;
|
|
66
|
+
readonly name: string;
|
|
67
|
+
readonly adminOnly: boolean;
|
|
68
|
+
readonly group: string;
|
|
69
|
+
}
|
|
70
|
+
export interface Inventory {
|
|
71
|
+
readonly nodeCount: number;
|
|
72
|
+
readonly flows: readonly FlowTab[];
|
|
73
|
+
readonly brokers: readonly Broker[];
|
|
74
|
+
readonly homes: readonly HomeBinding[];
|
|
75
|
+
readonly state: readonly StateCandidate[];
|
|
76
|
+
readonly actions: readonly ActionCandidate[];
|
|
77
|
+
readonly notifications: readonly NotificationCandidate[];
|
|
78
|
+
/** Every type this module does not model, with how many nodes carry it. */
|
|
79
|
+
readonly unmodelled: readonly {
|
|
80
|
+
readonly type: string;
|
|
81
|
+
readonly count: number;
|
|
82
|
+
}[];
|
|
83
|
+
readonly findings: readonly Finding[];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Builds the inventory for one Node-RED export.
|
|
87
|
+
*
|
|
88
|
+
* The result is a pure function of the bytes: the same export always produces
|
|
89
|
+
* the same report, which is what makes it usable as a migration baseline that
|
|
90
|
+
* can be diffed between two runs.
|
|
91
|
+
*/
|
|
92
|
+
export declare function discoverFlows(source: Uint8Array): Inventory;
|
|
93
|
+
/** The JSON body of `miakapp discover --json`, with no secret value in it. */
|
|
94
|
+
export declare function inventoryJson(inventory: Inventory): Record<string, unknown>;
|
|
95
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|