@serve.zone/interfaces 30.0.0 → 30.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +18 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/index.d.ts +2 -0
- package/dist_ts/data/index.js +3 -1
- package/dist_ts/data/runtimesession.d.ts +15 -0
- package/dist_ts/data/runtimesession.js +26 -13
- package/dist_ts/data/runtimeterminalreceipt.d.ts +97 -0
- package/dist_ts/data/runtimeterminalreceipt.js +281 -0
- package/dist_ts/data/servicecredential.d.ts +57 -0
- package/dist_ts/data/servicecredential.js +81 -0
- package/dist_ts/requests/admin.d.ts +25 -0
- package/dist_ts/requests/runtimesession.d.ts +7 -0
- package/package.json +1 -1
- package/readme.md +53 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/index.ts +2 -0
- package/ts/data/runtimesession.ts +38 -12
- package/ts/data/runtimeterminalreceipt.ts +338 -0
- package/ts/data/servicecredential.ts +130 -0
- package/ts/requests/admin.ts +25 -0
- package/ts/requests/runtimesession.ts +11 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { isSha256Digest } from './immutableimage.js';
|
|
2
|
+
import { evaluateRuntimeAssignmentV1, getRuntimeAssignmentV1Reference, snapshotRuntimeAssignmentV1 } from './runtimeassignment.js';
|
|
3
|
+
import { bindRuntimeReporterSessionV1, snapshotRuntimeSessionBindingV1 } from './runtimesession.js';
|
|
4
|
+
import { canonicalizeStrictJson, createCanonicalJsonSha256Hex } from '../private/canonicaljson.js';
|
|
5
|
+
export const runtimeAssignmentTerminalReceiptV1Contract = Object.freeze({
|
|
6
|
+
digestDomain: 'serve.zone/runtime-assignment-terminal-receipt-v1',
|
|
7
|
+
maximumReceiptCanonicalBytes: 16_384,
|
|
8
|
+
maximumHistoryCanonicalBytes: 98_304,
|
|
9
|
+
maximumReceipts: 2,
|
|
10
|
+
maximumAssignmentRevisions: 3,
|
|
11
|
+
error: 'Runtime terminal receipt contract rejected.',
|
|
12
|
+
});
|
|
13
|
+
const fail = () => { throw new Error(runtimeAssignmentTerminalReceiptV1Contract.error); };
|
|
14
|
+
function requireValue(conditionArg) { if (!conditionArg)
|
|
15
|
+
fail(); }
|
|
16
|
+
const safe = (operationArg) => { try {
|
|
17
|
+
return operationArg();
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return fail();
|
|
21
|
+
} };
|
|
22
|
+
const canonical = (valueArg) => canonicalizeStrictJson(valueArg, fail);
|
|
23
|
+
const encoder = new TextEncoder();
|
|
24
|
+
const identifier = (valueArg) => {
|
|
25
|
+
requireValue(typeof valueArg === 'string' && /^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$/.test(valueArg));
|
|
26
|
+
return valueArg;
|
|
27
|
+
};
|
|
28
|
+
const digest = (valueArg) => {
|
|
29
|
+
requireValue(typeof valueArg === 'string' && isSha256Digest(valueArg));
|
|
30
|
+
return valueArg;
|
|
31
|
+
};
|
|
32
|
+
/** Bounded inert copy before hashing or calling any nested validator. */
|
|
33
|
+
const capture = (valueArg, maximumBytesArg = runtimeAssignmentTerminalReceiptV1Contract.maximumHistoryCanonicalBytes) => safe(() => {
|
|
34
|
+
let nodes = 0;
|
|
35
|
+
let bytes = 0;
|
|
36
|
+
const ancestors = new Set();
|
|
37
|
+
const account = (value) => {
|
|
38
|
+
requireValue(value.length <= maximumBytesArg);
|
|
39
|
+
bytes += encoder.encode(value).byteLength;
|
|
40
|
+
requireValue(bytes <= maximumBytesArg);
|
|
41
|
+
};
|
|
42
|
+
const copy = (value, depth) => {
|
|
43
|
+
requireValue(++nodes <= 4096 && depth <= 12);
|
|
44
|
+
if (typeof value === 'string') {
|
|
45
|
+
account(value);
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'number')
|
|
49
|
+
return value;
|
|
50
|
+
requireValue(value !== null && typeof value === 'object' && !ancestors.has(value));
|
|
51
|
+
const array = Array.isArray(value);
|
|
52
|
+
const prototype = Object.getPrototypeOf(value);
|
|
53
|
+
requireValue(array ? prototype === Array.prototype : prototype === Object.prototype || prototype === null);
|
|
54
|
+
ancestors.add(value);
|
|
55
|
+
try {
|
|
56
|
+
const keys = Reflect.ownKeys(value);
|
|
57
|
+
requireValue(keys.length <= 65);
|
|
58
|
+
if (array) {
|
|
59
|
+
const length = Object.getOwnPropertyDescriptor(value, 'length')?.value;
|
|
60
|
+
requireValue(Number.isSafeInteger(length) && length >= 0 && length <= 64 && keys.length === length + 1);
|
|
61
|
+
const result = [];
|
|
62
|
+
for (let index = 0; index < length; index++) {
|
|
63
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
64
|
+
requireValue(descriptor?.enumerable && Object.hasOwn(descriptor, 'value'));
|
|
65
|
+
result.push(copy(descriptor.value, depth + 1));
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
const result = Object.create(null);
|
|
70
|
+
for (const key of keys) {
|
|
71
|
+
requireValue(typeof key === 'string');
|
|
72
|
+
account(key);
|
|
73
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
74
|
+
requireValue(descriptor?.enumerable && Object.hasOwn(descriptor, 'value'));
|
|
75
|
+
result[key] = copy(descriptor.value, depth + 1);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
ancestors.delete(value);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const serialized = canonical(copy(valueArg, 0));
|
|
84
|
+
requireValue(encoder.encode(serialized).byteLength <= maximumBytesArg);
|
|
85
|
+
return JSON.parse(serialized);
|
|
86
|
+
});
|
|
87
|
+
const record = (valueArg, keysArg) => {
|
|
88
|
+
requireValue(valueArg !== null && typeof valueArg === 'object' && !Array.isArray(valueArg));
|
|
89
|
+
const keys = Object.keys(valueArg);
|
|
90
|
+
requireValue(keys.length === keysArg.length && keys.every((key) => keysArg.includes(key)));
|
|
91
|
+
return valueArg;
|
|
92
|
+
};
|
|
93
|
+
const reference = (valueArg) => {
|
|
94
|
+
const value = record(valueArg, ['assignmentId', 'generation', 'digest']);
|
|
95
|
+
requireValue(typeof value.generation === 'number' && Number.isSafeInteger(value.generation)
|
|
96
|
+
&& value.generation >= 1 && value.generation <= 3);
|
|
97
|
+
return { assignmentId: identifier(value.assignmentId), generation: value.generation, digest: digest(value.digest) };
|
|
98
|
+
};
|
|
99
|
+
const evidence = (valueArg) => {
|
|
100
|
+
const value = record(valueArg, ['phase', 'sandboxId', 'containerId', 'imageConfigDigest', 'ipAddresses', 'exitCode']);
|
|
101
|
+
requireValue(value.phase === 'absent' || value.phase === 'stopped');
|
|
102
|
+
for (const field of ['sandboxId', 'containerId'])
|
|
103
|
+
requireValue(value[field] === null
|
|
104
|
+
|| (typeof value[field] === 'string' && /^[a-f0-9]{64}$/.test(value[field])));
|
|
105
|
+
requireValue(value.imageConfigDigest === null || (typeof value.imageConfigDigest === 'string'
|
|
106
|
+
&& isSha256Digest(value.imageConfigDigest)));
|
|
107
|
+
requireValue(Array.isArray(value.ipAddresses) && value.ipAddresses.length === 0);
|
|
108
|
+
requireValue(value.exitCode === null || (typeof value.exitCode === 'number' && Number.isSafeInteger(value.exitCode)
|
|
109
|
+
&& value.exitCode >= -2_147_483_648 && value.exitCode <= 2_147_483_647));
|
|
110
|
+
requireValue(value.phase === 'absent'
|
|
111
|
+
? value.sandboxId === null && value.containerId === null && value.imageConfigDigest === null && value.exitCode === null
|
|
112
|
+
: value.sandboxId !== null);
|
|
113
|
+
requireValue(value.containerId !== null || (value.imageConfigDigest === null && value.exitCode === null));
|
|
114
|
+
return value;
|
|
115
|
+
};
|
|
116
|
+
/** Detached exact-schema assertion only; digest, journal provenance and authority remain unverified. */
|
|
117
|
+
export const snapshotRuntimeAssignmentTerminalReceiptV1 = (valueArg) => safe(() => {
|
|
118
|
+
const value = record(capture(valueArg, runtimeAssignmentTerminalReceiptV1Contract.maximumReceiptCanonicalBytes), ['schemaVersion', 'assignment', 'runAssignment', 'reporterSessionId', 'sequence', 'operation', 'previousReceiptDigest', 'digest']);
|
|
119
|
+
const assignment = reference(value.assignment);
|
|
120
|
+
const runAssignment = reference(value.runAssignment);
|
|
121
|
+
const operation = record(value.operation, ['id', 'action', 'bootId', 'status', 'evidence']);
|
|
122
|
+
const terminalEvidence = evidence(operation.evidence);
|
|
123
|
+
requireValue(value.schemaVersion === 1 && (value.sequence === 1 || value.sequence === 2)
|
|
124
|
+
&& operation.status === 'completed' && assignment.generation === value.sequence + 1
|
|
125
|
+
&& runAssignment.generation === 1 && runAssignment.assignmentId === assignment.assignmentId);
|
|
126
|
+
requireValue(typeof operation.bootId === 'string'
|
|
127
|
+
&& /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(operation.bootId));
|
|
128
|
+
requireValue(value.sequence === 1 ? operation.action === 'stop' && value.previousReceiptDigest === null
|
|
129
|
+
: operation.action === 'remove' && terminalEvidence.phase === 'absent' && value.previousReceiptDigest !== null);
|
|
130
|
+
return { schemaVersion: 1, assignment, runAssignment, reporterSessionId: identifier(value.reporterSessionId),
|
|
131
|
+
sequence: value.sequence, operation: { id: identifier(operation.id), action: operation.action,
|
|
132
|
+
bootId: operation.bootId, status: 'completed', evidence: terminalEvidence },
|
|
133
|
+
previousReceiptDigest: value.previousReceiptDigest === null ? null : digest(value.previousReceiptDigest), digest: digest(value.digest) };
|
|
134
|
+
});
|
|
135
|
+
/** Bounded exact receipt history for synchronous persistence assertions; hashes remain unchecked. */
|
|
136
|
+
export const snapshotRuntimeAssignmentTerminalReceiptHistoryV1 = (valueArg) => safe(() => {
|
|
137
|
+
const values = capture(valueArg);
|
|
138
|
+
requireValue(Array.isArray(values) && values.length <= runtimeAssignmentTerminalReceiptV1Contract.maximumReceipts);
|
|
139
|
+
const receipts = values.map(snapshotRuntimeAssignmentTerminalReceiptV1);
|
|
140
|
+
for (const [index, receipt] of receipts.entries()) {
|
|
141
|
+
requireValue(receipt.sequence === index + 1);
|
|
142
|
+
if (index > 0)
|
|
143
|
+
requireValue(receipt.previousReceiptDigest === receipts[0].digest
|
|
144
|
+
&& canonical(receipt.runAssignment) === canonical(receipts[0].runAssignment)
|
|
145
|
+
&& receipt.operation.id !== receipts[0].operation.id);
|
|
146
|
+
}
|
|
147
|
+
return receipts;
|
|
148
|
+
});
|
|
149
|
+
const assignments = (valueArg) => {
|
|
150
|
+
const values = capture(valueArg);
|
|
151
|
+
requireValue(Array.isArray(values) && values.length >= 2
|
|
152
|
+
&& values.length <= runtimeAssignmentTerminalReceiptV1Contract.maximumAssignmentRevisions);
|
|
153
|
+
return values.map(snapshotRuntimeAssignmentV1);
|
|
154
|
+
};
|
|
155
|
+
const checkAssignmentHistory = async (historyArg) => {
|
|
156
|
+
const run = historyArg[0];
|
|
157
|
+
const scope = { controller: run.controller, organizationId: run.organizationId,
|
|
158
|
+
nodeId: run.nodeId, runtimeNamespace: run.runtimeNamespace };
|
|
159
|
+
for (const [index, assignment] of historyArg.entries()) {
|
|
160
|
+
requireValue(assignment.generation === index + 1
|
|
161
|
+
&& assignment.disposition === ['run', 'stop-preserve', 'remove-runtime-preserve-storage'][index]);
|
|
162
|
+
requireValue((await evaluateRuntimeAssignmentV1(assignment, index === 0 ? null : historyArg[index - 1], scope)).status === 'accept');
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const computeSnapshotDigest = async (receiptArg) => {
|
|
166
|
+
const { digest: _digest, ...payload } = receiptArg;
|
|
167
|
+
return `sha256:${await createCanonicalJsonSha256Hex(canonical({
|
|
168
|
+
domain: runtimeAssignmentTerminalReceiptV1Contract.digestDomain, payload,
|
|
169
|
+
}), fail)}`;
|
|
170
|
+
};
|
|
171
|
+
/** Domain-separated exact body digest; captures before asynchronous hashing. */
|
|
172
|
+
export const computeRuntimeAssignmentTerminalReceiptV1Digest = async (valueArg) => {
|
|
173
|
+
try {
|
|
174
|
+
return await computeSnapshotDigest(snapshotRuntimeAssignmentTerminalReceiptV1(valueArg));
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return fail();
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const checkReceipt = async (receiptArg, historyArg, previousArg) => {
|
|
181
|
+
requireValue(historyArg.length > receiptArg.sequence
|
|
182
|
+
&& canonical(receiptArg.runAssignment) === canonical(getRuntimeAssignmentV1Reference(historyArg[0]))
|
|
183
|
+
&& canonical(receiptArg.assignment) === canonical(getRuntimeAssignmentV1Reference(historyArg[receiptArg.sequence]))
|
|
184
|
+
&& receiptArg.digest === await computeSnapshotDigest(receiptArg));
|
|
185
|
+
if (receiptArg.sequence === 1)
|
|
186
|
+
requireValue(previousArg === null);
|
|
187
|
+
else {
|
|
188
|
+
requireValue(previousArg !== null && previousArg.sequence === 1);
|
|
189
|
+
await checkReceipt(previousArg, historyArg, null);
|
|
190
|
+
requireValue(receiptArg.previousReceiptDigest === previousArg.digest && receiptArg.operation.id !== previousArg.operation.id);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
/** Full immutable run/stop/remove chain and exact prior stop receipt are mandatory for removal. */
|
|
194
|
+
export const validateRuntimeAssignmentTerminalReceiptV1 = async (valueArg, assignmentHistoryArg, previousReceiptArg) => {
|
|
195
|
+
try {
|
|
196
|
+
const receipt = snapshotRuntimeAssignmentTerminalReceiptV1(valueArg);
|
|
197
|
+
const history = assignments(assignmentHistoryArg);
|
|
198
|
+
const previous = previousReceiptArg === null ? null : snapshotRuntimeAssignmentTerminalReceiptV1(previousReceiptArg);
|
|
199
|
+
await checkAssignmentHistory(history);
|
|
200
|
+
await checkReceipt(receipt, history, previous);
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return [runtimeAssignmentTerminalReceiptV1Contract.error];
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Pure bounded CAS decision. Persist under the owning transaction and current
|
|
209
|
+
* credential/peer fence. New acceptance also requires the exact global incumbent;
|
|
210
|
+
* only a previously persisted exact body can replay after the incumbent changes.
|
|
211
|
+
* The helper cannot prove either condition. Retain both bodies after removal.
|
|
212
|
+
*/
|
|
213
|
+
export const evaluateRuntimeAssignmentTerminalReceiptV1 = async (valueArg, acceptedHistoryArg, assignmentHistoryArg) => {
|
|
214
|
+
try {
|
|
215
|
+
const receipt = snapshotRuntimeAssignmentTerminalReceiptV1(valueArg);
|
|
216
|
+
const accepted = snapshotRuntimeAssignmentTerminalReceiptHistoryV1(acceptedHistoryArg);
|
|
217
|
+
const history = assignments(assignmentHistoryArg);
|
|
218
|
+
await checkAssignmentHistory(history);
|
|
219
|
+
for (const existing of accepted)
|
|
220
|
+
await checkReceipt(existing, history, existing.sequence === 1 ? null : accepted[0]);
|
|
221
|
+
if (receipt.digest !== await computeSnapshotDigest(receipt)
|
|
222
|
+
|| history.length <= receipt.sequence
|
|
223
|
+
|| canonical(receipt.runAssignment) !== canonical(getRuntimeAssignmentV1Reference(history[0]))
|
|
224
|
+
|| canonical(receipt.assignment) !== canonical(getRuntimeAssignmentV1Reference(history[receipt.sequence]))) {
|
|
225
|
+
return { status: 'reject', reason: 'invalid' };
|
|
226
|
+
}
|
|
227
|
+
const existing = accepted[receipt.sequence - 1];
|
|
228
|
+
if (existing)
|
|
229
|
+
return canonical(existing) === canonical(receipt)
|
|
230
|
+
? { status: 'replay', receipt: existing } : { status: 'reject', reason: 'conflict' };
|
|
231
|
+
if (receipt.sequence !== accepted.length + 1)
|
|
232
|
+
return { status: 'reject', reason: 'sequence-gap' };
|
|
233
|
+
if (receipt.sequence === 2 && (receipt.previousReceiptDigest !== accepted[0].digest
|
|
234
|
+
|| receipt.operation.id === accepted[0].operation.id))
|
|
235
|
+
return { status: 'reject', reason: 'predecessor-mismatch' };
|
|
236
|
+
return { status: 'accept', receipt };
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return { status: 'reject', reason: 'invalid' };
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
export const snapshotReportRuntimeAssignmentTerminalReceiptRequestV1 = (valueArg) => safe(() => {
|
|
243
|
+
const value = record(capture(valueArg), ['session', 'receipt']);
|
|
244
|
+
return { session: snapshotRuntimeSessionBindingV1(value.session), receipt: snapshotRuntimeAssignmentTerminalReceiptV1(value.receipt) };
|
|
245
|
+
});
|
|
246
|
+
export const snapshotReportRuntimeAssignmentTerminalReceiptResponseV1 = (valueArg) => safe(() => {
|
|
247
|
+
const value = record(capture(valueArg), ['receipt', 'authorityUse']);
|
|
248
|
+
requireValue(value.authorityUse === 'current-session' || value.authorityUse === 'historical-recovery');
|
|
249
|
+
return { receipt: snapshotRuntimeAssignmentTerminalReceiptV1(value.receipt), authorityUse: value.authorityUse };
|
|
250
|
+
});
|
|
251
|
+
/**
|
|
252
|
+
* CURRENT physical session and immutable server-indexed reporter history are
|
|
253
|
+
* trusted owner inputs, never wire claims. The previous stop receipt must also
|
|
254
|
+
* come from the durable owner. This binds content; it does not authenticate,
|
|
255
|
+
* prove the local operation join, advance CAS, or admit a replacement.
|
|
256
|
+
*/
|
|
257
|
+
export const bindReportRuntimeAssignmentTerminalReceiptRequestV1 = async (valueArg, assignmentHistoryArg, previousReceiptArg, trustedSessionArg, reporterHistoryArg) => {
|
|
258
|
+
try {
|
|
259
|
+
const request = snapshotReportRuntimeAssignmentTerminalReceiptRequestV1(valueArg);
|
|
260
|
+
const history = assignments(assignmentHistoryArg);
|
|
261
|
+
const previous = previousReceiptArg === null ? null : snapshotRuntimeAssignmentTerminalReceiptV1(previousReceiptArg);
|
|
262
|
+
requireValue(history.length > request.receipt.sequence);
|
|
263
|
+
const binding = bindRuntimeReporterSessionV1(request.session, request.receipt.reporterSessionId, history[request.receipt.sequence], trustedSessionArg, reporterHistoryArg);
|
|
264
|
+
await checkAssignmentHistory(history);
|
|
265
|
+
await checkReceipt(request.receipt, history, previous);
|
|
266
|
+
return { request, authorityUse: binding.authorityUse };
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return fail();
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
/** Exact ACK of the immutable outbox body; no rewritten session, operation or chain. */
|
|
273
|
+
export const bindReportRuntimeAssignmentTerminalReceiptResponseV1 = (valueArg, requestArg) => safe(() => {
|
|
274
|
+
const response = snapshotReportRuntimeAssignmentTerminalReceiptResponseV1(valueArg);
|
|
275
|
+
const request = snapshotReportRuntimeAssignmentTerminalReceiptRequestV1(requestArg);
|
|
276
|
+
requireValue(canonical(response.receipt) === canonical(request.receipt)
|
|
277
|
+
&& response.authorityUse === (request.receipt.reporterSessionId === request.session.reporterSessionId
|
|
278
|
+
? 'current-session' : 'historical-recovery'));
|
|
279
|
+
return response;
|
|
280
|
+
});
|
|
281
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZXRlcm1pbmFscmVjZWlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2RhdGEvcnVudGltZXRlcm1pbmFscmVjZWlwdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFckQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLCtCQUErQixFQUNuRSwyQkFBMkIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTlELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BHLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSw0QkFBNEIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBNERuRyxNQUFNLENBQUMsTUFBTSwwQ0FBMEMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3RFLFlBQVksRUFBRSxtREFBbUQ7SUFDakUsNEJBQTRCLEVBQUUsTUFBTTtJQUNwQyw0QkFBNEIsRUFBRSxNQUFNO0lBQ3BDLGVBQWUsRUFBRSxDQUFDO0lBQ2xCLDBCQUEwQixFQUFFLENBQUM7SUFDN0IsS0FBSyxFQUFFLDZDQUE2QztDQUM1QyxDQUFDLENBQUM7QUFFWixNQUFNLElBQUksR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pHLFNBQVMsWUFBWSxDQUFDLFlBQXFCLElBQTBCLElBQUksQ0FBQyxZQUFZO0lBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pHLE1BQU0sSUFBSSxHQUFHLENBQUksWUFBcUIsRUFBSyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQUMsT0FBTyxZQUFZLEVBQUUsQ0FBQztBQUFDLENBQUM7QUFBQyxNQUFNLENBQUM7SUFBQyxPQUFPLElBQUksRUFBRSxDQUFDO0FBQUMsQ0FBQyxDQUFDLENBQUMs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
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Workload permissions are independent of human membership and deployment grants. */
|
|
2
|
+
export type TServiceMachineCapabilityV1 = 'platform:session';
|
|
3
|
+
/** Exact existing-service authority. Never infer this grant from an API role. */
|
|
4
|
+
export interface IServiceMachineGrantV1 {
|
|
5
|
+
organizationId: string;
|
|
6
|
+
serviceId: string;
|
|
7
|
+
capabilities: TServiceMachineCapabilityV1[];
|
|
8
|
+
}
|
|
9
|
+
/** Public metadata only. The bearer is delivered through the owning service's SecretSet. */
|
|
10
|
+
export interface IServiceMachineCredentialMetadataV1 {
|
|
11
|
+
schemaVersion: 1;
|
|
12
|
+
credentialId: string;
|
|
13
|
+
userId: string;
|
|
14
|
+
grant: IServiceMachineGrantV1;
|
|
15
|
+
generation: number;
|
|
16
|
+
state: 'active' | 'revoked';
|
|
17
|
+
expiresAt: number;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
/** Exact immutable encrypted delivery version; null after revocation. */
|
|
21
|
+
delivery: {
|
|
22
|
+
secretId: string;
|
|
23
|
+
secretVersionId: string;
|
|
24
|
+
} | null;
|
|
25
|
+
}
|
|
26
|
+
interface IServiceMachineCredentialMutationBaseV1 {
|
|
27
|
+
schemaVersion: 1;
|
|
28
|
+
organizationId: string;
|
|
29
|
+
serviceId: string;
|
|
30
|
+
/** Retain the complete request and this ID across retries. */
|
|
31
|
+
mutationId: string;
|
|
32
|
+
}
|
|
33
|
+
/** Creation is absent-only; rotation and revocation require the exact current generation. */
|
|
34
|
+
export type TServiceMachineCredentialMutationV1 = IServiceMachineCredentialMutationBaseV1 & ({
|
|
35
|
+
operation: 'ensure';
|
|
36
|
+
expectedGeneration: null;
|
|
37
|
+
capabilities: TServiceMachineCapabilityV1[];
|
|
38
|
+
expiresAt: number;
|
|
39
|
+
} | {
|
|
40
|
+
operation: 'rotate';
|
|
41
|
+
expectedGeneration: number;
|
|
42
|
+
capabilities: TServiceMachineCapabilityV1[];
|
|
43
|
+
expiresAt: number;
|
|
44
|
+
} | {
|
|
45
|
+
operation: 'revoke';
|
|
46
|
+
expectedGeneration: number;
|
|
47
|
+
});
|
|
48
|
+
export interface IServiceMachineCredentialMutationResultV1 {
|
|
49
|
+
/** Historical on replay; replay never restores revoked or superseded authority. */
|
|
50
|
+
credential: IServiceMachineCredentialMetadataV1;
|
|
51
|
+
replayed: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Structural copy only; the backend must fence live service ownership and credential authority. */
|
|
54
|
+
export declare const snapshotServiceMachineGrantV1: (value: unknown) => IServiceMachineGrantV1;
|
|
55
|
+
export declare const snapshotServiceMachineCredentialMutationV1: (value: unknown) => TServiceMachineCredentialMutationV1;
|
|
56
|
+
export declare const snapshotServiceMachineCredentialMetadataV1: (value: unknown) => IServiceMachineCredentialMetadataV1;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const fail = () => { throw new Error('Service credential contract rejected.'); };
|
|
2
|
+
function requireValue(value) { if (!value)
|
|
3
|
+
fail(); }
|
|
4
|
+
const object = (value, keys) => {
|
|
5
|
+
requireValue(value !== null && typeof value === 'object' && !Array.isArray(value));
|
|
6
|
+
requireValue(Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
7
|
+
const actual = Reflect.ownKeys(value);
|
|
8
|
+
requireValue(actual.length === keys.length && keys.every((key) => actual.includes(key)));
|
|
9
|
+
const copy = Object.create(null);
|
|
10
|
+
for (const key of keys) {
|
|
11
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
12
|
+
requireValue(descriptor && Object.hasOwn(descriptor, 'value') && descriptor.enumerable);
|
|
13
|
+
copy[key] = descriptor.value;
|
|
14
|
+
}
|
|
15
|
+
return copy;
|
|
16
|
+
};
|
|
17
|
+
const identifier = (value) => {
|
|
18
|
+
requireValue(typeof value === 'string' && /^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$/.test(value));
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
21
|
+
const counter = (value) => {
|
|
22
|
+
requireValue(typeof value === 'number' && Number.isSafeInteger(value) && value > 0 && value < Number.MAX_SAFE_INTEGER);
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
const capabilities = (value) => {
|
|
26
|
+
requireValue(Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype);
|
|
27
|
+
const keys = Reflect.ownKeys(value);
|
|
28
|
+
requireValue(keys.length === 2 && keys.includes('length') && keys.includes('0'));
|
|
29
|
+
const entry = Object.getOwnPropertyDescriptor(value, '0');
|
|
30
|
+
requireValue(entry && Object.hasOwn(entry, 'value') && entry.enumerable && entry.value === 'platform:session');
|
|
31
|
+
return ['platform:session'];
|
|
32
|
+
};
|
|
33
|
+
const safe = (operation) => { try {
|
|
34
|
+
return operation();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return fail();
|
|
38
|
+
} };
|
|
39
|
+
/** Structural copy only; the backend must fence live service ownership and credential authority. */
|
|
40
|
+
export const snapshotServiceMachineGrantV1 = (value) => safe(() => {
|
|
41
|
+
const grant = object(value, ['organizationId', 'serviceId', 'capabilities']);
|
|
42
|
+
return { organizationId: identifier(grant.organizationId), serviceId: identifier(grant.serviceId),
|
|
43
|
+
capabilities: capabilities(grant.capabilities) };
|
|
44
|
+
});
|
|
45
|
+
export const snapshotServiceMachineCredentialMutationV1 = (value) => safe(() => {
|
|
46
|
+
requireValue(value !== null && typeof value === 'object');
|
|
47
|
+
const operation = Object.getOwnPropertyDescriptor(value, 'operation')?.value;
|
|
48
|
+
requireValue(operation === 'ensure' || operation === 'rotate' || operation === 'revoke');
|
|
49
|
+
const request = object(value, ['schemaVersion', 'organizationId', 'serviceId', 'mutationId', 'operation',
|
|
50
|
+
'expectedGeneration', ...(operation === 'revoke' ? [] : ['capabilities', 'expiresAt'])]);
|
|
51
|
+
requireValue(request.schemaVersion === 1);
|
|
52
|
+
const base = { schemaVersion: 1, organizationId: identifier(request.organizationId),
|
|
53
|
+
serviceId: identifier(request.serviceId), mutationId: identifier(request.mutationId) };
|
|
54
|
+
if (operation === 'revoke')
|
|
55
|
+
return { ...base, operation, expectedGeneration: counter(request.expectedGeneration) };
|
|
56
|
+
const material = { capabilities: capabilities(request.capabilities), expiresAt: counter(request.expiresAt) };
|
|
57
|
+
if (operation === 'ensure') {
|
|
58
|
+
requireValue(request.expectedGeneration === null);
|
|
59
|
+
return { ...base, ...material, operation, expectedGeneration: null };
|
|
60
|
+
}
|
|
61
|
+
return { ...base, ...material, operation, expectedGeneration: counter(request.expectedGeneration) };
|
|
62
|
+
});
|
|
63
|
+
export const snapshotServiceMachineCredentialMetadataV1 = (value) => safe(() => {
|
|
64
|
+
const metadata = object(value, ['schemaVersion', 'credentialId', 'userId', 'grant', 'generation', 'state',
|
|
65
|
+
'expiresAt', 'createdAt', 'updatedAt', 'delivery']);
|
|
66
|
+
requireValue(metadata.schemaVersion === 1 && (metadata.state === 'active' || metadata.state === 'revoked'));
|
|
67
|
+
const createdAt = counter(metadata.createdAt);
|
|
68
|
+
const updatedAt = counter(metadata.updatedAt);
|
|
69
|
+
requireValue(updatedAt >= createdAt);
|
|
70
|
+
let delivery = null;
|
|
71
|
+
if (metadata.state === 'active') {
|
|
72
|
+
const version = object(metadata.delivery, ['secretId', 'secretVersionId']);
|
|
73
|
+
delivery = { secretId: identifier(version.secretId), secretVersionId: identifier(version.secretVersionId) };
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
requireValue(metadata.delivery === null);
|
|
77
|
+
return { schemaVersion: 1, credentialId: identifier(metadata.credentialId), userId: identifier(metadata.userId),
|
|
78
|
+
grant: snapshotServiceMachineGrantV1(metadata.grant), generation: counter(metadata.generation),
|
|
79
|
+
state: metadata.state, expiresAt: counter(metadata.expiresAt), createdAt, updatedAt, delivery };
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZWNyZWRlbnRpYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL3NlcnZpY2VjcmVkZW50aWFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXdEQSxNQUFNLElBQUksR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEYsU0FBUyxZQUFZLENBQUMsS0FBYyxJQUFtQixJQUFJLENBQUMsS0FBSztJQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1RSxNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQWMsRUFBRSxJQUFjLEVBQTJCLEVBQUU7SUFDekUsWUFBWSxDQUFDLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ25GLFlBQVksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLLE1BQU0sQ0FBQyxTQUFTLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztJQUN6RyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RDLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekYsTUFBTSxJQUFJLEdBQTRCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUQsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixNQUFNLFVBQVUsR0FBRyxNQUFN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
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
2
|
import type { IIdentity, IIdentityCredential, IServiceDeploymentGrant } from '../data/user.js';
|
|
3
|
+
import type { IServiceMachineCredentialMetadataV1, IServiceMachineCredentialMutationResultV1, TServiceMachineCredentialMutationV1 } from '../data/servicecredential.js';
|
|
4
|
+
export interface IReq_Admin_GetServiceMachineCredentialV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Admin_GetServiceMachineCredentialV1> {
|
|
5
|
+
method: 'getServiceMachineCredentialV1';
|
|
6
|
+
request: {
|
|
7
|
+
identity: IIdentityCredential;
|
|
8
|
+
organizationId: string;
|
|
9
|
+
serviceId: string;
|
|
10
|
+
};
|
|
11
|
+
response: {
|
|
12
|
+
credential: IServiceMachineCredentialMetadataV1 | null;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The backend authorizes the exact service and mutates hashed credential authority,
|
|
17
|
+
* encrypted SecretSet delivery and the replay receipt in one fenced transaction.
|
|
18
|
+
* No bearer is returned. Existing legacy deployment/cluster credentials are separate.
|
|
19
|
+
*/
|
|
20
|
+
export interface IReq_Admin_MutateServiceMachineCredentialV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Admin_MutateServiceMachineCredentialV1> {
|
|
21
|
+
method: 'mutateServiceMachineCredentialV1';
|
|
22
|
+
request: {
|
|
23
|
+
identity: IIdentityCredential;
|
|
24
|
+
mutation: TServiceMachineCredentialMutationV1;
|
|
25
|
+
};
|
|
26
|
+
response: IServiceMachineCredentialMutationResultV1;
|
|
27
|
+
}
|
|
3
28
|
/** Backend-owned human credential metadata; never includes a password verifier. */
|
|
4
29
|
export interface IHumanCredentialMetadata {
|
|
5
30
|
userId: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
2
|
import type * as data from '../data/runtimesession.js';
|
|
3
|
+
import type * as terminal from '../data/runtimeterminalreceipt.js';
|
|
3
4
|
/** WSS-only Pallet bootstrap. Derive physical peer/process/idempotency server-side. */
|
|
4
5
|
export interface IReq_Pallet_Cloudly_RegisterPalletRuntimeSessionV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Pallet_Cloudly_RegisterPalletRuntimeSessionV1> {
|
|
5
6
|
method: 'registerPalletRuntimeSessionV1';
|
|
@@ -18,6 +19,12 @@ export interface IReq_Pallet_Controller_ReportRuntimeAssignmentObservationV1 ext
|
|
|
18
19
|
request: data.IReportRuntimeAssignmentObservationRequestV1;
|
|
19
20
|
response: data.IReportRuntimeAssignmentObservationResponseV1;
|
|
20
21
|
}
|
|
22
|
+
/** Exact joined terminal-operation receipt; observations and boot changes cannot substitute. */
|
|
23
|
+
export interface IReq_Pallet_Controller_ReportRuntimeAssignmentTerminalReceiptV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Pallet_Controller_ReportRuntimeAssignmentTerminalReceiptV1> {
|
|
24
|
+
method: 'reportRuntimeAssignmentTerminalReceiptV1';
|
|
25
|
+
request: terminal.IReportRuntimeAssignmentTerminalReceiptRequestV1;
|
|
26
|
+
response: terminal.IReportRuntimeAssignmentTerminalReceiptResponseV1;
|
|
27
|
+
}
|
|
21
28
|
/** Current-peer, exact current assignment authorization; response is secret material. */
|
|
22
29
|
export interface IReq_Pallet_Controller_GetRuntimeRegistryCredentialV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Pallet_Controller_GetRuntimeRegistryCredentialV1> {
|
|
23
30
|
method: 'getRuntimeRegistryCredentialV1';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -174,6 +174,24 @@ bounded time/concurrency, root-only directory/socket permissions and drained
|
|
|
174
174
|
cleanup. The package supplies no listener, permission checks or persistent state.
|
|
175
175
|
No bearer, generic rotation operation or database access is part of this IPC API.
|
|
176
176
|
|
|
177
|
+
### Service Machine Credentials
|
|
178
|
+
|
|
179
|
+
`requests.admin.getServiceMachineCredentialV1` inspects redacted metadata;
|
|
180
|
+
`mutateServiceMachineCredentialV1` creates, rotates or revokes authority for one
|
|
181
|
+
exact existing service and organization. `ensure` requires absent authority and
|
|
182
|
+
a null expected generation. Rotation and revocation require the exact current
|
|
183
|
+
generation. Retain the mutation ID and complete input for retry; a receipt replay
|
|
184
|
+
returns historical metadata without restoring authority.
|
|
185
|
+
|
|
186
|
+
`IServiceMachineGrantV1` currently grants only `platform:session`. This is separate
|
|
187
|
+
from deployment grants, human membership and infrastructure permissions. The
|
|
188
|
+
backend must authenticate each JWT against the current active credential
|
|
189
|
+
generation, expiry and exact service ownership. Structural snapshot helpers do
|
|
190
|
+
not perform these checks. Credential changes, encrypted service SecretSet
|
|
191
|
+
delivery and the replay receipt must commit in the same authorized transaction.
|
|
192
|
+
The response contains only the immutable secret/version reference; no bearer or
|
|
193
|
+
hash is returned. Revocation removes current delivery from the metadata.
|
|
194
|
+
|
|
177
195
|
### Node-Bound Runtime Assignments
|
|
178
196
|
|
|
179
197
|
The `data` namespace exports `IRuntimeAssignmentV1`, canonical digest helpers,
|
|
@@ -251,6 +269,41 @@ machine JWT on a physical TypedSocket so the server can own its identity tag.
|
|
|
251
269
|
Both registration methods reject HTTP transport. Sensitive requests and registry
|
|
252
270
|
responses must be excluded from hooks, logs, diagnostics and durable journals.
|
|
253
271
|
|
|
272
|
+
### Joined Runtime Terminal Receipts
|
|
273
|
+
|
|
274
|
+
`data.IRuntimeAssignmentTerminalReceiptV1` and
|
|
275
|
+
`requests.runtimesession.reportRuntimeAssignmentTerminalReceiptV1` carry a separate
|
|
276
|
+
receipt for the exact Pallet attempt's joined terminal execution. Sequence 1 binds
|
|
277
|
+
the generation 2 stop assignment; sequence 2 binds generation 3 removal and the
|
|
278
|
+
exact stop receipt digest. Both retain the original generation 1 run reference.
|
|
279
|
+
The full immutable assignment chain and both receipt bodies remain durable after
|
|
280
|
+
removal, permitting an exact earlier stop receipt to be acknowledged again.
|
|
281
|
+
|
|
282
|
+
Only a durably completed native operation can issue a terminal receipt. Native
|
|
283
|
+
stop joins container and sandbox stop; native remove requires an already stopped
|
|
284
|
+
sandbox and joins container and sandbox removal. The assignment owner separately
|
|
285
|
+
requires the exact completed stop before admitting removal. Terminal evidence
|
|
286
|
+
contains precise CRI identifiers, the kernel boot UUID, and stopped/absent state;
|
|
287
|
+
this native path does not collect IP addresses. Pending, unknown and host-fenced
|
|
288
|
+
journal entries never qualify. A proven boot change can permit a new joined
|
|
289
|
+
terminal operation but cannot skip the stop/remove chain.
|
|
290
|
+
|
|
291
|
+
The synchronous snapshot helpers validate bounded exact data only. Digest,
|
|
292
|
+
assignment-chain and receipt-chain helpers do not prove native execution or
|
|
293
|
+
authenticate a reporter. `bindRuntimeReporterSessionV1` and the terminal report
|
|
294
|
+
binder require the current physical session and immutable server-indexed reporter
|
|
295
|
+
history from their trusted owners. Reconnect recovery preserves every original
|
|
296
|
+
receipt field and returns `historical-recovery`; it never restores active
|
|
297
|
+
readiness, routes or liveness. The response binder rejects rewritten receipt bodies.
|
|
298
|
+
|
|
299
|
+
Cloudly must transact new acceptance against the exact global incumbent, stored
|
|
300
|
+
assignment chain and current peer, credential and node authority. A first receipt
|
|
301
|
+
after the incumbent changes is denied; only an already persisted exact receipt
|
|
302
|
+
can be acknowledged again under current authentication. These receipts settle
|
|
303
|
+
only the named Pallet attempt. They do not authorize storage relocation, prove
|
|
304
|
+
whole-host or Docker/Coreflow absence, grant another controller or organization
|
|
305
|
+
authority, or replace independently qualified readiness and routing evidence.
|
|
306
|
+
|
|
254
307
|
### Offline SmartDB Settlement And Packaging
|
|
255
308
|
|
|
256
309
|
The Node-only `@serve.zone/interfaces/runtime` export includes isolated V1
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/data/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ export * from './registry.js';
|
|
|
26
26
|
export * from './runtimeassignment.js';
|
|
27
27
|
export * from './runtimeconfig.js';
|
|
28
28
|
export * from './runtimesession.js';
|
|
29
|
+
export * from './runtimeterminalreceipt.js';
|
|
29
30
|
export * from './secret.js';
|
|
30
31
|
export * from './baremetal.js';
|
|
31
32
|
export * from './baseos.js';
|
|
@@ -33,6 +34,7 @@ export * from './backup.js';
|
|
|
33
34
|
export * from './clusternode.js';
|
|
34
35
|
export * from './settings.js';
|
|
35
36
|
export * from './service.js';
|
|
37
|
+
export * from './servicecredential.js';
|
|
36
38
|
export * from './serviceports.js';
|
|
37
39
|
export * from './status.js';
|
|
38
40
|
export * from './taskexecution.js';
|