@superdoc/sdk 2.18.0-next.2 → 2.18.0-next.4
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/dist/agent/doc-snapshot.cjs +38 -3
- package/dist/agent/doc-snapshot.d.ts +2 -0
- package/dist/agent/doc-snapshot.js +36 -3
- package/dist/agent/execution-context.cjs +12 -4
- package/dist/agent/execution-context.d.ts +1 -0
- package/dist/agent/execution-context.js +14 -6
- package/dist/generated/contract.cjs +1 -1
- package/dist/generated/contract.js +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -1
- package/dist/runtime/document-evidence.cjs +9 -2
- package/dist/runtime/document-evidence.d.ts +2 -1
- package/dist/runtime/document-evidence.js +8 -2
- package/dist/runtime/host.cjs +49 -7
- package/dist/runtime/host.d.ts +2 -0
- package/dist/runtime/host.js +50 -8
- package/dist/runtime/process.cjs +3 -0
- package/dist/runtime/process.d.ts +1 -0
- package/dist/runtime/process.js +3 -0
- package/dist/runtime/sdk-version.generated.cjs +1 -1
- package/dist/runtime/sdk-version.generated.d.ts +1 -1
- package/dist/runtime/sdk-version.generated.js +1 -1
- package/dist/runtime/transport-common.cjs +90 -0
- package/dist/runtime/transport-common.d.ts +1 -0
- package/dist/runtime/transport-common.js +89 -0
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -54,6 +54,9 @@ class BoundRuntime {
|
|
|
54
54
|
supportsDocumentFacts() {
|
|
55
55
|
return !this.closed && this.runtime.supportsDocumentFacts(this.sessionId);
|
|
56
56
|
}
|
|
57
|
+
usesCliDocumentFacts() {
|
|
58
|
+
return !this.closed && this.runtime.usesCliDocumentFacts(this.sessionId);
|
|
59
|
+
}
|
|
57
60
|
async readRevision() {
|
|
58
61
|
if (this.closed)
|
|
59
62
|
throw new errors.SuperDocCliError('Document handle is closed; cannot read its revision.', { code: 'DOCUMENT_CLOSED' });
|
|
@@ -84,7 +87,7 @@ class SuperDocDocumentCore {
|
|
|
84
87
|
this.client = client$1;
|
|
85
88
|
attachBoundDocApi(this, client.createBoundDocApi(this.boundRuntime));
|
|
86
89
|
documentEvidence.registerDocumentRevisionReader(this, () => this.boundRuntime.readRevision());
|
|
87
|
-
documentEvidence.registerDocumentFactCapability(this, () => this.boundRuntime.supportsDocumentFacts());
|
|
90
|
+
documentEvidence.registerDocumentFactCapability(this, () => this.boundRuntime.supportsDocumentFacts(), () => this.boundRuntime.usesCliDocumentFacts());
|
|
88
91
|
}
|
|
89
92
|
get sessionId() {
|
|
90
93
|
return this._sessionId;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ declare class BoundRuntime implements RuntimeInvoker {
|
|
|
14
14
|
invoke<TData = unknown>(operation: OperationSpec, params?: Record<string, unknown>, options?: InvokeOptions): Promise<TData>;
|
|
15
15
|
replaceFile(source: ReplaceFileSource, options?: ReplaceFileOptions): Promise<ReplaceFileResult>;
|
|
16
16
|
supportsDocumentFacts(): boolean;
|
|
17
|
+
usesCliDocumentFacts(): boolean;
|
|
17
18
|
readRevision(): Promise<string | undefined>;
|
|
18
19
|
markClosed(): void;
|
|
19
20
|
}
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,9 @@ class BoundRuntime {
|
|
|
42
42
|
supportsDocumentFacts() {
|
|
43
43
|
return !this.closed && this.runtime.supportsDocumentFacts(this.sessionId);
|
|
44
44
|
}
|
|
45
|
+
usesCliDocumentFacts() {
|
|
46
|
+
return !this.closed && this.runtime.usesCliDocumentFacts(this.sessionId);
|
|
47
|
+
}
|
|
45
48
|
async readRevision() {
|
|
46
49
|
if (this.closed)
|
|
47
50
|
throw new SuperDocCliError('Document handle is closed; cannot read its revision.', { code: 'DOCUMENT_CLOSED' });
|
|
@@ -72,7 +75,7 @@ class SuperDocDocumentCore {
|
|
|
72
75
|
this.client = client;
|
|
73
76
|
attachBoundDocApi(this, createBoundDocApi(this.boundRuntime));
|
|
74
77
|
registerDocumentRevisionReader(this, () => this.boundRuntime.readRevision());
|
|
75
|
-
registerDocumentFactCapability(this, () => this.boundRuntime.supportsDocumentFacts());
|
|
78
|
+
registerDocumentFactCapability(this, () => this.boundRuntime.supportsDocumentFacts(), () => this.boundRuntime.usesCliDocumentFacts());
|
|
76
79
|
}
|
|
77
80
|
get sessionId() {
|
|
78
81
|
return this._sessionId;
|
|
@@ -18,17 +18,23 @@ function getDocumentRevisionReader(document) {
|
|
|
18
18
|
return revisionReaders.get(document);
|
|
19
19
|
}
|
|
20
20
|
const factCapabilities = new WeakMap();
|
|
21
|
-
|
|
21
|
+
const summaryCapabilities = new WeakMap();
|
|
22
|
+
function registerDocumentFactCapability(document, supported, summaryCounts) {
|
|
22
23
|
factCapabilities.set(document, supported);
|
|
24
|
+
if (summaryCounts)
|
|
25
|
+
summaryCapabilities.set(document, summaryCounts);
|
|
23
26
|
}
|
|
24
27
|
function supportsDocumentFacts(document) {
|
|
25
28
|
return factCapabilities.get(document)?.() === true;
|
|
26
29
|
}
|
|
30
|
+
function requiresSummaryCounts(document) {
|
|
31
|
+
return summaryCapabilities.get(document)?.() === true;
|
|
32
|
+
}
|
|
27
33
|
function forwardDocumentEvidence(source, target) {
|
|
28
34
|
const reader = getDocumentRevisionReader(source);
|
|
29
35
|
if (reader)
|
|
30
36
|
registerDocumentRevisionReader(target, reader);
|
|
31
|
-
registerDocumentFactCapability(target, () => supportsDocumentFacts(source));
|
|
37
|
+
registerDocumentFactCapability(target, () => supportsDocumentFacts(source), () => requiresSummaryCounts(source));
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
exports.forwardDocumentEvidence = forwardDocumentEvidence;
|
|
@@ -37,4 +43,5 @@ exports.getMutationRevision = getMutationRevision;
|
|
|
37
43
|
exports.registerDocumentFactCapability = registerDocumentFactCapability;
|
|
38
44
|
exports.registerDocumentRevisionReader = registerDocumentRevisionReader;
|
|
39
45
|
exports.registerMutationRevision = registerMutationRevision;
|
|
46
|
+
exports.requiresSummaryCounts = requiresSummaryCounts;
|
|
40
47
|
exports.supportsDocumentFacts = supportsDocumentFacts;
|
|
@@ -7,7 +7,8 @@ export declare function registerMutationRevision(result: unknown, revision: Muta
|
|
|
7
7
|
export declare function getMutationRevision(result: unknown): MutationRevision | undefined;
|
|
8
8
|
export declare function registerDocumentRevisionReader(document: object, reader: RevisionReader): void;
|
|
9
9
|
export declare function getDocumentRevisionReader(document: object): RevisionReader | undefined;
|
|
10
|
-
export declare function registerDocumentFactCapability(document: object, supported: () => boolean): void;
|
|
10
|
+
export declare function registerDocumentFactCapability(document: object, supported: () => boolean, summaryCounts?: () => boolean): void;
|
|
11
11
|
export declare function supportsDocumentFacts(document: object): boolean;
|
|
12
|
+
export declare function requiresSummaryCounts(document: object): boolean;
|
|
12
13
|
export declare function forwardDocumentEvidence(source: object, target: object): void;
|
|
13
14
|
export {};
|
|
@@ -16,15 +16,21 @@ export function getDocumentRevisionReader(document) {
|
|
|
16
16
|
return revisionReaders.get(document);
|
|
17
17
|
}
|
|
18
18
|
const factCapabilities = new WeakMap();
|
|
19
|
-
|
|
19
|
+
const summaryCapabilities = new WeakMap();
|
|
20
|
+
export function registerDocumentFactCapability(document, supported, summaryCounts) {
|
|
20
21
|
factCapabilities.set(document, supported);
|
|
22
|
+
if (summaryCounts)
|
|
23
|
+
summaryCapabilities.set(document, summaryCounts);
|
|
21
24
|
}
|
|
22
25
|
export function supportsDocumentFacts(document) {
|
|
23
26
|
return factCapabilities.get(document)?.() === true;
|
|
24
27
|
}
|
|
28
|
+
export function requiresSummaryCounts(document) {
|
|
29
|
+
return summaryCapabilities.get(document)?.() === true;
|
|
30
|
+
}
|
|
25
31
|
export function forwardDocumentEvidence(source, target) {
|
|
26
32
|
const reader = getDocumentRevisionReader(source);
|
|
27
33
|
if (reader)
|
|
28
34
|
registerDocumentRevisionReader(target, reader);
|
|
29
|
-
registerDocumentFactCapability(target, () => supportsDocumentFacts(source));
|
|
35
|
+
registerDocumentFactCapability(target, () => supportsDocumentFacts(source), () => requiresSummaryCounts(source));
|
|
30
36
|
}
|
package/dist/runtime/host.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var node_child_process = require('node:child_process');
|
|
|
4
4
|
var transportCommon = require('./transport-common.cjs');
|
|
5
5
|
var errors = require('./errors.cjs');
|
|
6
6
|
var documentEvidence = require('./document-evidence.cjs');
|
|
7
|
+
var contract = require('../generated/contract.cjs');
|
|
7
8
|
var documentRpc = require('./document-rpc.cjs');
|
|
8
9
|
|
|
9
10
|
const HOST_PROTOCOL_VERSION = '1.0';
|
|
@@ -106,6 +107,7 @@ class HostTransport {
|
|
|
106
107
|
activeCalls = new Set();
|
|
107
108
|
hostFeatures = new Set();
|
|
108
109
|
documentRpcSessions = new Set();
|
|
110
|
+
cliLocalSessions = new Set();
|
|
109
111
|
dirtyDocumentRpcSessions = new Set();
|
|
110
112
|
documentRpcMutationStates = new Map();
|
|
111
113
|
indeterminateDiscardCloses = new Set();
|
|
@@ -132,13 +134,28 @@ class HostTransport {
|
|
|
132
134
|
await this.runWhileActive(() => this.ensureConnected());
|
|
133
135
|
}
|
|
134
136
|
supportsDocumentFacts(sessionId) {
|
|
135
|
-
return (this.
|
|
136
|
-
this.
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
return (this.usesCliDocumentFacts(sessionId) ||
|
|
138
|
+
(this.documentRpcSessions.has(sessionId) &&
|
|
139
|
+
this.hostFeatures.has('document.currentRevision') &&
|
|
140
|
+
this.hostFeatures.has('document.executionFacts') &&
|
|
141
|
+
this.hostFeatures.has('document.mutationRevision')));
|
|
142
|
+
}
|
|
143
|
+
usesCliDocumentFacts(sessionId) {
|
|
144
|
+
return this.cliLocalSessions.has(sessionId) && this.hostFeatures.has('cli.invoke.localExecutionFacts');
|
|
139
145
|
}
|
|
140
146
|
async readDocumentRevision(sessionId) {
|
|
141
147
|
return this.runWhileActive(async () => {
|
|
148
|
+
if (this.usesCliDocumentFacts(sessionId)) {
|
|
149
|
+
const revisionOperation = contract.CONTRACT.operations['doc.blocks.list'];
|
|
150
|
+
const page = await this.invoke(revisionOperation, {
|
|
151
|
+
sessionId,
|
|
152
|
+
offset: Number.MAX_SAFE_INTEGER,
|
|
153
|
+
limit: 1,
|
|
154
|
+
});
|
|
155
|
+
if (typeof page.revision !== 'string' || !page.revision || page.revision === 'unknown')
|
|
156
|
+
throw new errors.SuperDocCliError('CLI returned an invalid execution revision.', { code: 'HOST_PROTOCOL_ERROR' });
|
|
157
|
+
return page.revision;
|
|
158
|
+
}
|
|
142
159
|
if (!this.documentRpcSessions.has(sessionId) || !this.hostFeatures.has('document.currentRevision')) {
|
|
143
160
|
return undefined;
|
|
144
161
|
}
|
|
@@ -359,9 +376,23 @@ class HostTransport {
|
|
|
359
376
|
const argv = transportCommon.buildOperationArgv(operation, params, options, this.requestTimeoutMs, this.defaultChangeMode, this.user);
|
|
360
377
|
const stdinBase64 = options.stdinBytes ? Buffer.from(options.stdinBytes).toString('base64') : '';
|
|
361
378
|
const watchdogTimeout = this.resolveWatchdogTimeout(options.timeoutMs);
|
|
379
|
+
const structuredInput = this.hostFeatures.has('cli.invoke.structuredReads')
|
|
380
|
+
? transportCommon.buildStructuredReadInput(operation, params, options, argv)
|
|
381
|
+
: undefined;
|
|
382
|
+
const includeRevision = sessionId !== undefined &&
|
|
383
|
+
this.usesCliDocumentFacts(sessionId) &&
|
|
384
|
+
operation.mutates === true;
|
|
362
385
|
const response = await this.sendJsonRpcRequest('cli.invoke', {
|
|
363
|
-
|
|
364
|
-
|
|
386
|
+
...(structuredInput === undefined
|
|
387
|
+
? { argv, stdinBase64 }
|
|
388
|
+
: {
|
|
389
|
+
operationId: operation.operationId,
|
|
390
|
+
input: structuredInput,
|
|
391
|
+
...((options.timeoutMs ?? this.requestTimeoutMs) === undefined
|
|
392
|
+
? {}
|
|
393
|
+
: { timeoutMs: options.timeoutMs ?? this.requestTimeoutMs }),
|
|
394
|
+
}),
|
|
395
|
+
...(includeRevision ? { includeRevision: true } : {}),
|
|
365
396
|
...(collaborationAuth === undefined ? {} : { collaborationAuth }),
|
|
366
397
|
}, watchdogTimeout, {
|
|
367
398
|
requestTimeoutMs: supportsRequestTimeoutMetadata ? options.timeoutMs : undefined,
|
|
@@ -373,7 +404,18 @@ class HostTransport {
|
|
|
373
404
|
});
|
|
374
405
|
}
|
|
375
406
|
const resultRecord = response;
|
|
376
|
-
|
|
407
|
+
const result = mapCliInvocationResult(operation, resultRecord.data);
|
|
408
|
+
if (operation.operationId === 'doc.open' && typeof result === 'object' && result !== null) {
|
|
409
|
+
const opened = result;
|
|
410
|
+
if (typeof opened.contextId === 'string' && opened.sessionType === 'local')
|
|
411
|
+
this.cliLocalSessions.add(opened.contextId);
|
|
412
|
+
}
|
|
413
|
+
if (operation.operationId === 'doc.close' && sessionId)
|
|
414
|
+
this.cliLocalSessions.delete(sessionId);
|
|
415
|
+
const revision = resultRecord.meta?.revision;
|
|
416
|
+
if (includeRevision && revision)
|
|
417
|
+
documentEvidence.registerMutationRevision(result, revision);
|
|
418
|
+
return result;
|
|
377
419
|
}
|
|
378
420
|
runWhileActive(start) {
|
|
379
421
|
if (this.terminalDisposalError) {
|
package/dist/runtime/host.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ export declare class HostTransport {
|
|
|
54
54
|
private readonly activeCalls;
|
|
55
55
|
private readonly hostFeatures;
|
|
56
56
|
private readonly documentRpcSessions;
|
|
57
|
+
private readonly cliLocalSessions;
|
|
57
58
|
private readonly dirtyDocumentRpcSessions;
|
|
58
59
|
private readonly documentRpcMutationStates;
|
|
59
60
|
private readonly indeterminateDiscardCloses;
|
|
@@ -63,6 +64,7 @@ export declare class HostTransport {
|
|
|
63
64
|
} & SuperDocClientOptions);
|
|
64
65
|
connect(): Promise<void>;
|
|
65
66
|
supportsDocumentFacts(sessionId: string): boolean;
|
|
67
|
+
usesCliDocumentFacts(sessionId: string): boolean;
|
|
66
68
|
readDocumentRevision(sessionId: string): Promise<string | undefined>;
|
|
67
69
|
dispose(): Promise<void>;
|
|
68
70
|
private disposeAfterActiveCalls;
|
package/dist/runtime/host.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { buildOperationArgv, normalizeCollaborationAuth, resolveInvocation, } from './transport-common.js';
|
|
2
|
+
import { buildOperationArgv, buildStructuredReadInput, normalizeCollaborationAuth, resolveInvocation, } from './transport-common.js';
|
|
3
3
|
import { SuperDocCliError } from './errors.js';
|
|
4
4
|
import { registerMutationRevision } from './document-evidence.js';
|
|
5
|
+
import { CONTRACT } from '../generated/contract.js';
|
|
5
6
|
import { DOCUMENT_RPC_FEATURES, DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE, DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE, DOCUMENT_RPC_REPLACE_FILE_FEATURE, DOCUMENT_RPC_SOURCE_SAVE_FEATURE, buildDocumentInvokeParams, buildDocumentOpenParams, canOpenWithDocumentRpc, documentRpcRequestSupportsResponseTimeout, documentRpcEnabled, mapDocumentLifecycleResult, mapDocumentOpenResult, mapDocumentReplaceFileResult, supportsDocumentRpc, } from './document-rpc.js';
|
|
6
7
|
const HOST_PROTOCOL_VERSION = '1.0';
|
|
7
8
|
const CLI_HOST_REQUIRED_FEATURES = ['cli.invoke', 'host.shutdown'];
|
|
@@ -103,6 +104,7 @@ export class HostTransport {
|
|
|
103
104
|
activeCalls = new Set();
|
|
104
105
|
hostFeatures = new Set();
|
|
105
106
|
documentRpcSessions = new Set();
|
|
107
|
+
cliLocalSessions = new Set();
|
|
106
108
|
dirtyDocumentRpcSessions = new Set();
|
|
107
109
|
documentRpcMutationStates = new Map();
|
|
108
110
|
indeterminateDiscardCloses = new Set();
|
|
@@ -129,13 +131,28 @@ export class HostTransport {
|
|
|
129
131
|
await this.runWhileActive(() => this.ensureConnected());
|
|
130
132
|
}
|
|
131
133
|
supportsDocumentFacts(sessionId) {
|
|
132
|
-
return (this.
|
|
133
|
-
this.
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
return (this.usesCliDocumentFacts(sessionId) ||
|
|
135
|
+
(this.documentRpcSessions.has(sessionId) &&
|
|
136
|
+
this.hostFeatures.has('document.currentRevision') &&
|
|
137
|
+
this.hostFeatures.has('document.executionFacts') &&
|
|
138
|
+
this.hostFeatures.has('document.mutationRevision')));
|
|
139
|
+
}
|
|
140
|
+
usesCliDocumentFacts(sessionId) {
|
|
141
|
+
return this.cliLocalSessions.has(sessionId) && this.hostFeatures.has('cli.invoke.localExecutionFacts');
|
|
136
142
|
}
|
|
137
143
|
async readDocumentRevision(sessionId) {
|
|
138
144
|
return this.runWhileActive(async () => {
|
|
145
|
+
if (this.usesCliDocumentFacts(sessionId)) {
|
|
146
|
+
const revisionOperation = CONTRACT.operations['doc.blocks.list'];
|
|
147
|
+
const page = await this.invoke(revisionOperation, {
|
|
148
|
+
sessionId,
|
|
149
|
+
offset: Number.MAX_SAFE_INTEGER,
|
|
150
|
+
limit: 1,
|
|
151
|
+
});
|
|
152
|
+
if (typeof page.revision !== 'string' || !page.revision || page.revision === 'unknown')
|
|
153
|
+
throw new SuperDocCliError('CLI returned an invalid execution revision.', { code: 'HOST_PROTOCOL_ERROR' });
|
|
154
|
+
return page.revision;
|
|
155
|
+
}
|
|
139
156
|
if (!this.documentRpcSessions.has(sessionId) || !this.hostFeatures.has('document.currentRevision')) {
|
|
140
157
|
return undefined;
|
|
141
158
|
}
|
|
@@ -356,9 +373,23 @@ export class HostTransport {
|
|
|
356
373
|
const argv = buildOperationArgv(operation, params, options, this.requestTimeoutMs, this.defaultChangeMode, this.user);
|
|
357
374
|
const stdinBase64 = options.stdinBytes ? Buffer.from(options.stdinBytes).toString('base64') : '';
|
|
358
375
|
const watchdogTimeout = this.resolveWatchdogTimeout(options.timeoutMs);
|
|
376
|
+
const structuredInput = this.hostFeatures.has('cli.invoke.structuredReads')
|
|
377
|
+
? buildStructuredReadInput(operation, params, options, argv)
|
|
378
|
+
: undefined;
|
|
379
|
+
const includeRevision = sessionId !== undefined &&
|
|
380
|
+
this.usesCliDocumentFacts(sessionId) &&
|
|
381
|
+
operation.mutates === true;
|
|
359
382
|
const response = await this.sendJsonRpcRequest('cli.invoke', {
|
|
360
|
-
|
|
361
|
-
|
|
383
|
+
...(structuredInput === undefined
|
|
384
|
+
? { argv, stdinBase64 }
|
|
385
|
+
: {
|
|
386
|
+
operationId: operation.operationId,
|
|
387
|
+
input: structuredInput,
|
|
388
|
+
...((options.timeoutMs ?? this.requestTimeoutMs) === undefined
|
|
389
|
+
? {}
|
|
390
|
+
: { timeoutMs: options.timeoutMs ?? this.requestTimeoutMs }),
|
|
391
|
+
}),
|
|
392
|
+
...(includeRevision ? { includeRevision: true } : {}),
|
|
362
393
|
...(collaborationAuth === undefined ? {} : { collaborationAuth }),
|
|
363
394
|
}, watchdogTimeout, {
|
|
364
395
|
requestTimeoutMs: supportsRequestTimeoutMetadata ? options.timeoutMs : undefined,
|
|
@@ -370,7 +401,18 @@ export class HostTransport {
|
|
|
370
401
|
});
|
|
371
402
|
}
|
|
372
403
|
const resultRecord = response;
|
|
373
|
-
|
|
404
|
+
const result = mapCliInvocationResult(operation, resultRecord.data);
|
|
405
|
+
if (operation.operationId === 'doc.open' && typeof result === 'object' && result !== null) {
|
|
406
|
+
const opened = result;
|
|
407
|
+
if (typeof opened.contextId === 'string' && opened.sessionType === 'local')
|
|
408
|
+
this.cliLocalSessions.add(opened.contextId);
|
|
409
|
+
}
|
|
410
|
+
if (operation.operationId === 'doc.close' && sessionId)
|
|
411
|
+
this.cliLocalSessions.delete(sessionId);
|
|
412
|
+
const revision = resultRecord.meta?.revision;
|
|
413
|
+
if (includeRevision && revision)
|
|
414
|
+
registerMutationRevision(result, revision);
|
|
415
|
+
return result;
|
|
374
416
|
}
|
|
375
417
|
runWhileActive(start) {
|
|
376
418
|
if (this.terminalDisposalError) {
|
package/dist/runtime/process.cjs
CHANGED
|
@@ -60,6 +60,9 @@ class SuperDocRuntime {
|
|
|
60
60
|
supportsDocumentFacts(sessionId) {
|
|
61
61
|
return this.transport.supportsDocumentFacts(sessionId);
|
|
62
62
|
}
|
|
63
|
+
usesCliDocumentFacts(sessionId) {
|
|
64
|
+
return this.transport.usesCliDocumentFacts(sessionId);
|
|
65
|
+
}
|
|
63
66
|
async readDocumentRevision(sessionId) {
|
|
64
67
|
return this.transport.readDocumentRevision(sessionId);
|
|
65
68
|
}
|
|
@@ -33,6 +33,7 @@ export declare class SuperDocRuntime {
|
|
|
33
33
|
constructor(options?: SuperDocClientOptions);
|
|
34
34
|
connect(): Promise<void>;
|
|
35
35
|
supportsDocumentFacts(sessionId: string): boolean;
|
|
36
|
+
usesCliDocumentFacts(sessionId: string): boolean;
|
|
36
37
|
readDocumentRevision(sessionId: string): Promise<string | undefined>;
|
|
37
38
|
dispose(): Promise<void>;
|
|
38
39
|
invoke<TData = unknown>(operation: OperationSpec, params?: Record<string, unknown>, options?: TransportInvokeOptions): Promise<TData>;
|
package/dist/runtime/process.js
CHANGED
|
@@ -57,6 +57,9 @@ export class SuperDocRuntime {
|
|
|
57
57
|
supportsDocumentFacts(sessionId) {
|
|
58
58
|
return this.transport.supportsDocumentFacts(sessionId);
|
|
59
59
|
}
|
|
60
|
+
usesCliDocumentFacts(sessionId) {
|
|
61
|
+
return this.transport.usesCliDocumentFacts(sessionId);
|
|
62
|
+
}
|
|
60
63
|
async readDocumentRevision(sessionId) {
|
|
61
64
|
return this.transport.readDocumentRevision(sessionId);
|
|
62
65
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
// AUTO-GENERATED by scripts/embed-version.mjs — DO NOT EDIT.
|
|
4
4
|
// Source of truth: package.json. Regenerated on every SDK build so the
|
|
5
5
|
// SDK retains its own version identity when bundled into another package.
|
|
6
|
-
const SDK_VERSION = '2.18.0-next.
|
|
6
|
+
const SDK_VERSION = '2.18.0-next.4';
|
|
7
7
|
|
|
8
8
|
exports.SDK_VERSION = SDK_VERSION;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.18.0-next.
|
|
1
|
+
export declare const SDK_VERSION = "2.18.0-next.4";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// AUTO-GENERATED by scripts/embed-version.mjs — DO NOT EDIT.
|
|
2
2
|
// Source of truth: package.json. Regenerated on every SDK build so the
|
|
3
3
|
// SDK retains its own version identity when bundled into another package.
|
|
4
|
-
export const SDK_VERSION = '2.18.0-next.
|
|
4
|
+
export const SDK_VERSION = '2.18.0-next.4';
|
|
@@ -1,7 +1,96 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var node_util = require('node:util');
|
|
3
4
|
var errors = require('./errors.cjs');
|
|
4
5
|
|
|
6
|
+
function buildStructuredReadInput(operation, params, options, encodedArgv) {
|
|
7
|
+
if (!['doc.info', 'doc.blocks.list', 'doc.query.match'].includes(operation.operationId))
|
|
8
|
+
return undefined;
|
|
9
|
+
if (node_util.types.isProxy(params))
|
|
10
|
+
return undefined;
|
|
11
|
+
const prototype = Object.getPrototypeOf(params);
|
|
12
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
13
|
+
return undefined;
|
|
14
|
+
for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(params)))
|
|
15
|
+
if (descriptor.get || descriptor.set)
|
|
16
|
+
return undefined;
|
|
17
|
+
if (typeof params.sessionId !== 'string' ||
|
|
18
|
+
!params.sessionId ||
|
|
19
|
+
params.doc != null ||
|
|
20
|
+
options.stdinBytes !== undefined ||
|
|
21
|
+
options.collaborationAuth !== undefined)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (!encodedArgv)
|
|
24
|
+
return undefined;
|
|
25
|
+
const flags = new Map(operation.params.filter((spec) => spec.kind !== 'doc').map((spec) => [`--${spec.flag ?? spec.name}`, spec]));
|
|
26
|
+
const encoded = new Map();
|
|
27
|
+
// Read the completed encoding; later serializers may have mutated earlier params.
|
|
28
|
+
for (let index = operation.commandTokens.length; index < encodedArgv.length; index += 2) {
|
|
29
|
+
const flag = encodedArgv[index];
|
|
30
|
+
const value = encodedArgv[index + 1];
|
|
31
|
+
if (typeof value !== 'string')
|
|
32
|
+
return undefined;
|
|
33
|
+
if (flag === '--output' || flag === '--timeout-ms')
|
|
34
|
+
continue;
|
|
35
|
+
const spec = flags.get(flag);
|
|
36
|
+
if (!spec || (spec.kind !== 'jsonFlag' && value.startsWith('-')))
|
|
37
|
+
return undefined;
|
|
38
|
+
const values = encoded.get(spec.name) ?? [];
|
|
39
|
+
values.push(value);
|
|
40
|
+
encoded.set(spec.name, values);
|
|
41
|
+
}
|
|
42
|
+
const input = {};
|
|
43
|
+
for (const spec of operation.params) {
|
|
44
|
+
const value = params[spec.name];
|
|
45
|
+
const values = encoded.get(spec.name);
|
|
46
|
+
if (!values) {
|
|
47
|
+
if (spec.required)
|
|
48
|
+
return undefined;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (spec.type !== 'string[]' && values.length !== 1)
|
|
52
|
+
return undefined;
|
|
53
|
+
const token = values[0];
|
|
54
|
+
if (spec.kind === 'jsonFlag') {
|
|
55
|
+
// Reuse the existing encoding so custom serializers and getters run once.
|
|
56
|
+
if (value === null)
|
|
57
|
+
return undefined;
|
|
58
|
+
try {
|
|
59
|
+
input[spec.name] = JSON.parse(token);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Coercions and unusual scalar tokens retain the existing argv validator.
|
|
67
|
+
if (spec.type === 'number') {
|
|
68
|
+
if (typeof value !== 'number' ||
|
|
69
|
+
!Number.isFinite(value) ||
|
|
70
|
+
value < 0 ||
|
|
71
|
+
!Number.isFinite(Number(token)) ||
|
|
72
|
+
Number(token) < 0)
|
|
73
|
+
return undefined;
|
|
74
|
+
input[spec.name] = Number(token);
|
|
75
|
+
}
|
|
76
|
+
else if (spec.type === 'boolean') {
|
|
77
|
+
if (typeof value !== 'boolean' || !['true', 'false'].includes(token))
|
|
78
|
+
return undefined;
|
|
79
|
+
input[spec.name] = token === 'true';
|
|
80
|
+
}
|
|
81
|
+
else if (spec.type === 'string[]') {
|
|
82
|
+
if (values.some((item) => !item || item.trim() !== item))
|
|
83
|
+
return undefined;
|
|
84
|
+
input[spec.name] = values;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
if (typeof value !== 'string' || !token || token.trim() !== token)
|
|
88
|
+
return undefined;
|
|
89
|
+
input[spec.name] = token;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return input;
|
|
93
|
+
}
|
|
5
94
|
function normalizeCollaborationAuth(value) {
|
|
6
95
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
7
96
|
throw new errors.SuperDocCliError('collaborationAuth must be an object.', { code: 'INVALID_ARGUMENT' });
|
|
@@ -192,5 +281,6 @@ function buildOperationArgv(operation, params, options, runtimeTimeoutMs, defaul
|
|
|
192
281
|
|
|
193
282
|
exports.applyOperationParamAliases = applyOperationParamAliases;
|
|
194
283
|
exports.buildOperationArgv = buildOperationArgv;
|
|
284
|
+
exports.buildStructuredReadInput = buildStructuredReadInput;
|
|
195
285
|
exports.normalizeCollaborationAuth = normalizeCollaborationAuth;
|
|
196
286
|
exports.resolveInvocation = resolveInvocation;
|
|
@@ -12,6 +12,7 @@ export interface OperationSpec {
|
|
|
12
12
|
readonly commandTokens: readonly string[];
|
|
13
13
|
readonly params: readonly OperationParamSpec[];
|
|
14
14
|
}
|
|
15
|
+
export declare function buildStructuredReadInput(operation: OperationSpec, params: Record<string, unknown>, options: TransportInvokeOptions, encodedArgv?: readonly string[]): Record<string, unknown> | undefined;
|
|
15
16
|
export interface InvokeOptions {
|
|
16
17
|
timeoutMs?: number;
|
|
17
18
|
stdinBytes?: Uint8Array;
|
|
@@ -1,4 +1,93 @@
|
|
|
1
|
+
import { types as utilTypes } from 'node:util';
|
|
1
2
|
import { SuperDocCliError } from './errors.js';
|
|
3
|
+
export function buildStructuredReadInput(operation, params, options, encodedArgv) {
|
|
4
|
+
if (!['doc.info', 'doc.blocks.list', 'doc.query.match'].includes(operation.operationId))
|
|
5
|
+
return undefined;
|
|
6
|
+
if (utilTypes.isProxy(params))
|
|
7
|
+
return undefined;
|
|
8
|
+
const prototype = Object.getPrototypeOf(params);
|
|
9
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
10
|
+
return undefined;
|
|
11
|
+
for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(params)))
|
|
12
|
+
if (descriptor.get || descriptor.set)
|
|
13
|
+
return undefined;
|
|
14
|
+
if (typeof params.sessionId !== 'string' ||
|
|
15
|
+
!params.sessionId ||
|
|
16
|
+
params.doc != null ||
|
|
17
|
+
options.stdinBytes !== undefined ||
|
|
18
|
+
options.collaborationAuth !== undefined)
|
|
19
|
+
return undefined;
|
|
20
|
+
if (!encodedArgv)
|
|
21
|
+
return undefined;
|
|
22
|
+
const flags = new Map(operation.params.filter((spec) => spec.kind !== 'doc').map((spec) => [`--${spec.flag ?? spec.name}`, spec]));
|
|
23
|
+
const encoded = new Map();
|
|
24
|
+
// Read the completed encoding; later serializers may have mutated earlier params.
|
|
25
|
+
for (let index = operation.commandTokens.length; index < encodedArgv.length; index += 2) {
|
|
26
|
+
const flag = encodedArgv[index];
|
|
27
|
+
const value = encodedArgv[index + 1];
|
|
28
|
+
if (typeof value !== 'string')
|
|
29
|
+
return undefined;
|
|
30
|
+
if (flag === '--output' || flag === '--timeout-ms')
|
|
31
|
+
continue;
|
|
32
|
+
const spec = flags.get(flag);
|
|
33
|
+
if (!spec || (spec.kind !== 'jsonFlag' && value.startsWith('-')))
|
|
34
|
+
return undefined;
|
|
35
|
+
const values = encoded.get(spec.name) ?? [];
|
|
36
|
+
values.push(value);
|
|
37
|
+
encoded.set(spec.name, values);
|
|
38
|
+
}
|
|
39
|
+
const input = {};
|
|
40
|
+
for (const spec of operation.params) {
|
|
41
|
+
const value = params[spec.name];
|
|
42
|
+
const values = encoded.get(spec.name);
|
|
43
|
+
if (!values) {
|
|
44
|
+
if (spec.required)
|
|
45
|
+
return undefined;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (spec.type !== 'string[]' && values.length !== 1)
|
|
49
|
+
return undefined;
|
|
50
|
+
const token = values[0];
|
|
51
|
+
if (spec.kind === 'jsonFlag') {
|
|
52
|
+
// Reuse the existing encoding so custom serializers and getters run once.
|
|
53
|
+
if (value === null)
|
|
54
|
+
return undefined;
|
|
55
|
+
try {
|
|
56
|
+
input[spec.name] = JSON.parse(token);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
// Coercions and unusual scalar tokens retain the existing argv validator.
|
|
64
|
+
if (spec.type === 'number') {
|
|
65
|
+
if (typeof value !== 'number' ||
|
|
66
|
+
!Number.isFinite(value) ||
|
|
67
|
+
value < 0 ||
|
|
68
|
+
!Number.isFinite(Number(token)) ||
|
|
69
|
+
Number(token) < 0)
|
|
70
|
+
return undefined;
|
|
71
|
+
input[spec.name] = Number(token);
|
|
72
|
+
}
|
|
73
|
+
else if (spec.type === 'boolean') {
|
|
74
|
+
if (typeof value !== 'boolean' || !['true', 'false'].includes(token))
|
|
75
|
+
return undefined;
|
|
76
|
+
input[spec.name] = token === 'true';
|
|
77
|
+
}
|
|
78
|
+
else if (spec.type === 'string[]') {
|
|
79
|
+
if (values.some((item) => !item || item.trim() !== item))
|
|
80
|
+
return undefined;
|
|
81
|
+
input[spec.name] = values;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
if (typeof value !== 'string' || !token || token.trim() !== token)
|
|
85
|
+
return undefined;
|
|
86
|
+
input[spec.name] = token;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return input;
|
|
90
|
+
}
|
|
2
91
|
export function normalizeCollaborationAuth(value) {
|
|
3
92
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
4
93
|
throw new SuperDocCliError('collaborationAuth must be an object.', { code: 'INVALID_ARGUMENT' });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdoc/sdk",
|
|
3
|
-
"version": "2.18.0-next.
|
|
3
|
+
"version": "2.18.0-next.4",
|
|
4
4
|
"description": "Node SDK for SuperDoc, wrapping the SuperDoc CLI to read and edit .docx files from JavaScript and TypeScript.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"typescript": "^5.9.2"
|
|
39
39
|
},
|
|
40
40
|
"optionalDependencies": {
|
|
41
|
-
"@superdoc/sdk-darwin-arm64": "2.18.0-next.
|
|
42
|
-
"@superdoc/sdk-darwin-x64": "2.18.0-next.
|
|
43
|
-
"@superdoc/sdk-linux-x64": "2.18.0-next.
|
|
44
|
-
"@superdoc/sdk-linux-arm64": "2.18.0-next.
|
|
45
|
-
"@superdoc/sdk-windows-x64": "2.18.0-next.
|
|
41
|
+
"@superdoc/sdk-darwin-arm64": "2.18.0-next.4",
|
|
42
|
+
"@superdoc/sdk-darwin-x64": "2.18.0-next.4",
|
|
43
|
+
"@superdoc/sdk-linux-x64": "2.18.0-next.4",
|
|
44
|
+
"@superdoc/sdk-linux-arm64": "2.18.0-next.4",
|
|
45
|
+
"@superdoc/sdk-windows-x64": "2.18.0-next.4"
|
|
46
46
|
},
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"typecheck": "tsc --noEmit",
|
|
54
54
|
"typecheck:consumer": "tsc --noEmit --strict --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext ../../../../tests/consumer-typecheck/src/sdk-per-open-collaboration-auth.mts ../../../../tests/consumer-typecheck/src/sdk-replace-file.mts ../../../../tests/consumer-typecheck/src/sdk-agent-evidence.mts ../../../../tests/consumer-typecheck/src/sdk-custom-actions.mts ../../../../tests/consumer-typecheck/src/sd4807-sdk-inspect.mts ../../../../tests/consumer-typecheck/src/sdk-tracked-only-policy.mts ../../../../tests/consumer-typecheck/src/sdk-tracked-review-route.mts ../../../../tests/consumer-typecheck/src/sd5266-sdk-placeholder-null.mts",
|
|
55
55
|
"test:agent-actions": "bun test src/__tests__/actions.test.ts src/__tests__/agent-runtime.test.ts src/__tests__/custom-actions.test.ts src/__tests__/textbox-snapshot.test.ts",
|
|
56
|
-
"test:document-host": "bun test src/runtime/__tests__/host-spawn-args.test.ts src/runtime/__tests__/document-rpc.test.ts src/__tests__/tracked-review-route.test.ts src/__tests__/structured-document-rpc.e2e.test.ts src/__tests__/request-timeout-ms.e2e.test.ts src/__tests__/agent-evidence.e2e.test.ts src/__tests__/agent-apply.e2e.test.ts src/__tests__/find-text.e2e.test.ts src/__tests__/custom-actions.e2e.test.ts",
|
|
56
|
+
"test:document-host": "bun test src/__tests__/default-cli-optimization.e2e.test.ts src/runtime/__tests__/host-spawn-args.test.ts src/runtime/__tests__/document-rpc.test.ts src/__tests__/tracked-review-route.test.ts src/__tests__/structured-document-rpc.e2e.test.ts src/__tests__/request-timeout-ms.e2e.test.ts src/__tests__/agent-evidence.e2e.test.ts src/__tests__/agent-apply.e2e.test.ts src/__tests__/find-text.e2e.test.ts src/__tests__/custom-actions.e2e.test.ts",
|
|
57
57
|
"smoke:product-action": "node scripts/product-action-smoke.mjs"
|
|
58
58
|
}
|
|
59
59
|
}
|