@superdoc/sdk 2.6.0 → 2.7.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/dist/agent/actions.cjs +1869 -160
- package/dist/agent/actions.d.ts +77 -10
- package/dist/agent/actions.js +1870 -161
- package/dist/agent/catalog.cjs +102 -9
- package/dist/agent/catalog.d.ts +243 -0
- package/dist/agent/catalog.js +99 -9
- package/dist/agent/doc-snapshot.cjs +200 -2
- package/dist/agent/doc-snapshot.d.ts +91 -0
- package/dist/agent/doc-snapshot.js +199 -2
- package/dist/agent/runtime.cjs +9 -1
- package/dist/agent/runtime.d.ts +8 -0
- package/dist/agent/runtime.js +9 -1
- package/dist/generated/client.cjs +754 -770
- package/dist/generated/client.d.ts +9 -9
- package/dist/generated/client.js +754 -770
- package/dist/generated/contract.cjs +16170 -272
- package/dist/generated/contract.d.ts +38 -0
- package/dist/generated/contract.js +17411 -1510
- package/dist/index.cjs +5 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -4
- package/dist/introspection.cjs +59 -0
- package/dist/introspection.d.ts +3 -0
- package/dist/introspection.js +53 -0
- package/dist/runtime/document-rpc.cjs +179 -40
- package/dist/runtime/document-rpc.d.ts +13 -4
- package/dist/runtime/document-rpc.js +175 -40
- package/dist/runtime/embedded-cli.cjs +5 -68
- package/dist/runtime/embedded-cli.js +5 -67
- package/dist/runtime/embedded-document-host.cjs +28 -0
- package/dist/runtime/embedded-document-host.d.ts +1 -0
- package/dist/runtime/embedded-document-host.js +23 -0
- package/dist/runtime/embedded-platform.cjs +102 -0
- package/dist/runtime/embedded-platform.d.ts +5 -0
- package/dist/runtime/embedded-platform.js +93 -0
- package/dist/runtime/host.cjs +70 -19
- package/dist/runtime/host.d.ts +2 -0
- package/dist/runtime/host.js +70 -20
- package/dist/runtime/process.cjs +30 -9
- package/dist/runtime/process.d.ts +9 -0
- package/dist/runtime/process.js +29 -9
- package/dist/runtime/transport-common.cjs +1 -0
- package/dist/runtime/transport-common.d.ts +28 -10
- package/dist/runtime/transport-common.js +1 -1
- package/package.json +6 -6
- package/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- package/tools/__pycache__/intent_dispatch_generated.cpython-311.pyc +0 -0
- package/tools/tools-policy.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var client = require('./generated/client.cjs');
|
|
|
4
4
|
var contract = require('./generated/contract.cjs');
|
|
5
5
|
var process = require('./runtime/process.cjs');
|
|
6
6
|
var errors = require('./runtime/errors.cjs');
|
|
7
|
+
var introspection = require('./introspection.cjs');
|
|
7
8
|
var skills = require('./skills.cjs');
|
|
8
9
|
var tools = require('./tools.cjs');
|
|
9
10
|
var intentDispatch_generated = require('./generated/intent-dispatch.generated.cjs');
|
|
@@ -145,11 +146,11 @@ class SuperDocClient {
|
|
|
145
146
|
this.handles.set(contextId, handle);
|
|
146
147
|
return handle;
|
|
147
148
|
}
|
|
148
|
-
async describe(
|
|
149
|
-
return
|
|
149
|
+
async describe(_params = {}, _options) {
|
|
150
|
+
return introspection.describeContract();
|
|
150
151
|
}
|
|
151
|
-
async describeCommand(params,
|
|
152
|
-
return
|
|
152
|
+
async describeCommand(params, _options) {
|
|
153
|
+
return introspection.describeContractOperation(params);
|
|
153
154
|
}
|
|
154
155
|
async dispose() {
|
|
155
156
|
for (const handle of this.handles.values()) {
|
package/dist/index.d.ts
CHANGED
|
@@ -74,8 +74,8 @@ export declare class SuperDocClient {
|
|
|
74
74
|
* different session ids (useful for diff workflows).
|
|
75
75
|
*/
|
|
76
76
|
open(params: DocOpenParams, options?: InvokeOptions): Promise<SuperDocDocument>;
|
|
77
|
-
describe(
|
|
78
|
-
describeCommand(params: DocDescribeCommandParams,
|
|
77
|
+
describe(_params?: Record<string, unknown>, _options?: InvokeOptions): Promise<unknown>;
|
|
78
|
+
describeCommand(params: DocDescribeCommandParams, _options?: InvokeOptions): Promise<unknown>;
|
|
79
79
|
dispose(): Promise<void>;
|
|
80
80
|
/** @internal */
|
|
81
81
|
removeHandle(sessionId: string): void;
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createDocApi, createBoundDocApi, } from './generated/client.js';
|
|
|
2
2
|
import { CONTRACT } from './generated/contract.js';
|
|
3
3
|
import { SuperDocRuntime, } from './runtime/process.js';
|
|
4
4
|
import { SuperDocCliError } from './runtime/errors.js';
|
|
5
|
+
import { describeContract, describeContractOperation } from './introspection.js';
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// Session-bound runtime wrapper
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
@@ -137,11 +138,11 @@ export class SuperDocClient {
|
|
|
137
138
|
this.handles.set(contextId, handle);
|
|
138
139
|
return handle;
|
|
139
140
|
}
|
|
140
|
-
async describe(
|
|
141
|
-
return
|
|
141
|
+
async describe(_params = {}, _options) {
|
|
142
|
+
return describeContract();
|
|
142
143
|
}
|
|
143
|
-
async describeCommand(params,
|
|
144
|
-
return
|
|
144
|
+
async describeCommand(params, _options) {
|
|
145
|
+
return describeContractOperation(params);
|
|
145
146
|
}
|
|
146
147
|
async dispose() {
|
|
147
148
|
for (const handle of this.handles.values()) {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var contract = require('./generated/contract.cjs');
|
|
4
|
+
var errors = require('./runtime/errors.cjs');
|
|
5
|
+
|
|
6
|
+
function cloneJson(value) {
|
|
7
|
+
return JSON.parse(JSON.stringify(value));
|
|
8
|
+
}
|
|
9
|
+
function detailParam(param) {
|
|
10
|
+
return {
|
|
11
|
+
name: param.name,
|
|
12
|
+
kind: param.kind,
|
|
13
|
+
...(Object.prototype.hasOwnProperty.call(param, 'flag') ? { flag: param.flag } : {}),
|
|
14
|
+
type: param.type,
|
|
15
|
+
...(Object.prototype.hasOwnProperty.call(param, 'required') ? { required: param.required } : {}),
|
|
16
|
+
...(Object.prototype.hasOwnProperty.call(param, 'schema') ? { schema: param.schema } : {}),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function describeContract() {
|
|
20
|
+
return cloneJson(contract.CONTRACT.introspection.overview);
|
|
21
|
+
}
|
|
22
|
+
function describeContractOperation(params) {
|
|
23
|
+
const rawQuery = params?.operationId;
|
|
24
|
+
if (rawQuery == null || String(rawQuery).length === 0) {
|
|
25
|
+
throw new errors.SuperDocCliError('describe command: missing required input.operationId.', {
|
|
26
|
+
code: 'MISSING_REQUIRED',
|
|
27
|
+
exitCode: 1,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const query = String(rawQuery);
|
|
31
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
32
|
+
const index = Object.prototype.hasOwnProperty.call(contract.CONTRACT.introspection.lookup, normalizedQuery)
|
|
33
|
+
? contract.CONTRACT.introspection.lookup[normalizedQuery]
|
|
34
|
+
: undefined;
|
|
35
|
+
if (typeof index !== 'number' ||
|
|
36
|
+
!Number.isInteger(index) ||
|
|
37
|
+
index < 0 ||
|
|
38
|
+
index >= contract.CONTRACT.introspection.overview.operations.length) {
|
|
39
|
+
throw new errors.SuperDocCliError(`Unknown operation: ${query}`, {
|
|
40
|
+
code: 'TARGET_NOT_FOUND',
|
|
41
|
+
details: { query },
|
|
42
|
+
exitCode: 1,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const summary = contract.CONTRACT.introspection.overview.operations[index];
|
|
46
|
+
const operation = contract.CONTRACT.operations[summary.id];
|
|
47
|
+
return cloneJson({
|
|
48
|
+
contractVersion: contract.CONTRACT.contractVersion,
|
|
49
|
+
query,
|
|
50
|
+
operation: {
|
|
51
|
+
...summary,
|
|
52
|
+
params: operation.params.map(detailParam),
|
|
53
|
+
constraints: operation.constraints ?? null,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
exports.describeContract = describeContract;
|
|
59
|
+
exports.describeContractOperation = describeContractOperation;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CONTRACT } from './generated/contract.js';
|
|
2
|
+
import { SuperDocCliError } from './runtime/errors.js';
|
|
3
|
+
function cloneJson(value) {
|
|
4
|
+
return JSON.parse(JSON.stringify(value));
|
|
5
|
+
}
|
|
6
|
+
function detailParam(param) {
|
|
7
|
+
return {
|
|
8
|
+
name: param.name,
|
|
9
|
+
kind: param.kind,
|
|
10
|
+
...(Object.prototype.hasOwnProperty.call(param, 'flag') ? { flag: param.flag } : {}),
|
|
11
|
+
type: param.type,
|
|
12
|
+
...(Object.prototype.hasOwnProperty.call(param, 'required') ? { required: param.required } : {}),
|
|
13
|
+
...(Object.prototype.hasOwnProperty.call(param, 'schema') ? { schema: param.schema } : {}),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function describeContract() {
|
|
17
|
+
return cloneJson(CONTRACT.introspection.overview);
|
|
18
|
+
}
|
|
19
|
+
export function describeContractOperation(params) {
|
|
20
|
+
const rawQuery = params?.operationId;
|
|
21
|
+
if (rawQuery == null || String(rawQuery).length === 0) {
|
|
22
|
+
throw new SuperDocCliError('describe command: missing required input.operationId.', {
|
|
23
|
+
code: 'MISSING_REQUIRED',
|
|
24
|
+
exitCode: 1,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const query = String(rawQuery);
|
|
28
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
29
|
+
const index = Object.prototype.hasOwnProperty.call(CONTRACT.introspection.lookup, normalizedQuery)
|
|
30
|
+
? CONTRACT.introspection.lookup[normalizedQuery]
|
|
31
|
+
: undefined;
|
|
32
|
+
if (typeof index !== 'number' ||
|
|
33
|
+
!Number.isInteger(index) ||
|
|
34
|
+
index < 0 ||
|
|
35
|
+
index >= CONTRACT.introspection.overview.operations.length) {
|
|
36
|
+
throw new SuperDocCliError(`Unknown operation: ${query}`, {
|
|
37
|
+
code: 'TARGET_NOT_FOUND',
|
|
38
|
+
details: { query },
|
|
39
|
+
exitCode: 1,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const summary = CONTRACT.introspection.overview.operations[index];
|
|
43
|
+
const operation = CONTRACT.operations[summary.id];
|
|
44
|
+
return cloneJson({
|
|
45
|
+
contractVersion: CONTRACT.contractVersion,
|
|
46
|
+
query,
|
|
47
|
+
operation: {
|
|
48
|
+
...summary,
|
|
49
|
+
params: operation.params.map(detailParam),
|
|
50
|
+
constraints: operation.constraints ?? null,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
var node_crypto = require('node:crypto');
|
|
4
4
|
var errors = require('./errors.cjs');
|
|
5
|
+
var transportCommon = require('./transport-common.cjs');
|
|
5
6
|
|
|
6
7
|
const DOCUMENT_RPC_FEATURES = ['document.open', 'document.invoke', 'document.save', 'document.close'];
|
|
7
|
-
const
|
|
8
|
+
const DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = 'document.open.defaultChangeMode';
|
|
9
|
+
const DOCUMENT_RPC_SOURCE_SAVE_FEATURE = 'document.save.source';
|
|
10
|
+
const DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = 'host.request.timeoutMs';
|
|
8
11
|
const DOCUMENT_RPC_OPEN_FIELDS = new Set(['doc', 'sessionId', 'runtime']);
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'placement',
|
|
16
|
-
'content',
|
|
17
|
-
'nestingPolicy',
|
|
12
|
+
const DOCUMENT_RPC_SAVE_FIELDS = new Set(['sessionId', 'out', 'force', 'mode', 'inPlace']);
|
|
13
|
+
const DOCUMENT_API_OPTION_FIELDS = new Set(['expectedRevision', 'changeMode', 'dryRun', 'supportCheck']);
|
|
14
|
+
const DOCUMENT_API_REVISION_PREFLIGHT_OPERATIONS = new Set([
|
|
15
|
+
'doc.history.redo',
|
|
16
|
+
'doc.history.undo',
|
|
17
|
+
'doc.plan.execute',
|
|
18
18
|
]);
|
|
19
19
|
function unsupported(message, operationId) {
|
|
20
20
|
return new errors.SuperDocCliError(message, {
|
|
@@ -22,21 +22,42 @@ function unsupported(message, operationId) {
|
|
|
22
22
|
...(operationId === undefined ? {} : { details: { operationId } }),
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
+
function buildDocumentAuthor(user) {
|
|
26
|
+
if (user === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
if (typeof user !== 'object' || user === null || Array.isArray(user)) {
|
|
29
|
+
throw new errors.SuperDocCliError('user must be an object with a non-empty name.', {
|
|
30
|
+
code: 'INVALID_ARGUMENT',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const record = user;
|
|
34
|
+
if (typeof record.name !== 'string' || record.name.trim().length === 0) {
|
|
35
|
+
throw new errors.SuperDocCliError('user.name must be a non-empty string.', {
|
|
36
|
+
code: 'INVALID_ARGUMENT',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (record.email !== undefined && typeof record.email !== 'string') {
|
|
40
|
+
throw new errors.SuperDocCliError('user.email must be a string.', {
|
|
41
|
+
code: 'INVALID_ARGUMENT',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
name: record.name,
|
|
46
|
+
...(record.email === undefined ? {} : { email: record.email }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
25
49
|
function documentRpcEnabled(env) {
|
|
26
50
|
return (env?.SUPERDOC_SDK_DOCUMENT_RPC ?? process.env.SUPERDOC_SDK_DOCUMENT_RPC) === '1';
|
|
27
51
|
}
|
|
28
52
|
function supportsDocumentRpc(features) {
|
|
29
53
|
return DOCUMENT_RPC_FEATURES.every((feature) => features.has(feature));
|
|
30
54
|
}
|
|
31
|
-
function hasUnsupportedInvokeOptions(options) {
|
|
32
|
-
return (options.stdinBytes !== undefined ||
|
|
33
|
-
options.dryRun !== undefined ||
|
|
34
|
-
options.expectedRevision !== undefined ||
|
|
35
|
-
options.changeMode !== undefined);
|
|
36
|
-
}
|
|
37
55
|
function canOpenWithDocumentRpc(params, options) {
|
|
38
|
-
if (
|
|
56
|
+
if (options.stdinBytes !== undefined)
|
|
57
|
+
return false;
|
|
58
|
+
if (options.dryRun !== undefined || options.expectedRevision !== undefined || options.changeMode !== undefined) {
|
|
39
59
|
return false;
|
|
60
|
+
}
|
|
40
61
|
if (typeof params.doc !== 'string' || params.doc.trim().length === 0 || params.doc === '-')
|
|
41
62
|
return false;
|
|
42
63
|
if (params.runtime !== undefined && params.runtime !== 'v2')
|
|
@@ -46,11 +67,17 @@ function canOpenWithDocumentRpc(params, options) {
|
|
|
46
67
|
}
|
|
47
68
|
return Object.entries(params).every(([key, value]) => value === undefined || DOCUMENT_RPC_OPEN_FIELDS.has(key));
|
|
48
69
|
}
|
|
49
|
-
function buildDocumentOpenParams(params) {
|
|
70
|
+
function buildDocumentOpenParams(params, user, defaultChangeMode) {
|
|
50
71
|
const sessionId = typeof params.sessionId === 'string' && params.sessionId.length > 0 ? params.sessionId : node_crypto.randomUUID();
|
|
72
|
+
const author = buildDocumentAuthor(user);
|
|
51
73
|
return {
|
|
52
74
|
sessionId,
|
|
53
|
-
params: {
|
|
75
|
+
params: {
|
|
76
|
+
sessionId,
|
|
77
|
+
path: params.doc,
|
|
78
|
+
...(author === undefined ? {} : { author }),
|
|
79
|
+
...(defaultChangeMode == null ? {} : { defaultChangeMode }),
|
|
80
|
+
},
|
|
54
81
|
};
|
|
55
82
|
}
|
|
56
83
|
function mapDocumentOpenResult(response, sessionId, path) {
|
|
@@ -76,37 +103,120 @@ function mapDocumentOpenResult(response, sessionId, path) {
|
|
|
76
103
|
dirty: false,
|
|
77
104
|
};
|
|
78
105
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
const input = Object.fromEntries(Object.entries(params).filter(([key, value]) => value !== undefined && key !== 'doc' && key !== 'sessionId'));
|
|
82
|
-
const unsupportedField = Object.keys(input).find((key) => !allowedFields.has(key));
|
|
83
|
-
if (unsupportedField) {
|
|
84
|
-
throw unsupported(`Structured document RPC v0 does not support ${operationId} field ${unsupportedField}.`, operationId);
|
|
85
|
-
}
|
|
86
|
-
return input;
|
|
106
|
+
function supportsTrackedMode(operation) {
|
|
107
|
+
return operation.supportsTrackedMode === true || operation.supportsConditionalTrackedMode === true;
|
|
87
108
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
function documentInvokePayload(operation, params, invokeOptions) {
|
|
110
|
+
const normalizedParams = transportCommon.applyOperationParamAliases(operation, params);
|
|
111
|
+
if (invokeOptions.stdinBytes !== undefined) {
|
|
112
|
+
throw unsupported('Structured document RPC does not support stdinBytes.', operation.operationId);
|
|
113
|
+
}
|
|
114
|
+
if (typeof normalizedParams.out === 'string' && normalizedParams.out.length > 0) {
|
|
115
|
+
throw unsupported('Structured document RPC does not support per-operation output paths.', operation.operationId);
|
|
116
|
+
}
|
|
117
|
+
if (normalizedParams.force === true) {
|
|
118
|
+
throw unsupported('Structured document RPC does not support per-operation force.', operation.operationId);
|
|
119
|
+
}
|
|
120
|
+
const input = {};
|
|
121
|
+
const options = {};
|
|
122
|
+
const paramsByName = new Map(operation.params.map((param) => [param.name, param]));
|
|
123
|
+
for (const [name, value] of Object.entries(normalizedParams)) {
|
|
124
|
+
if (value === undefined || name === 'doc' || name === 'sessionId' || name === 'out' || name === 'force')
|
|
125
|
+
continue;
|
|
126
|
+
const param = paramsByName.get(name);
|
|
127
|
+
if (!param) {
|
|
128
|
+
throw unsupported(`Structured document RPC does not support ${operation.operationId} field ${name}.`, operation.operationId);
|
|
129
|
+
}
|
|
130
|
+
if (typeof param.documentApiInputName === 'string' && param.documentApiInputName.length > 0) {
|
|
131
|
+
input[param.documentApiInputName] = value;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (DOCUMENT_API_OPTION_FIELDS.has(name)) {
|
|
135
|
+
options[name] = value;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
throw unsupported(`Structured document RPC does not support ${operation.operationId} field ${name}.`, operation.operationId);
|
|
91
139
|
}
|
|
92
|
-
|
|
93
|
-
|
|
140
|
+
for (const name of ['expectedRevision', 'changeMode', 'dryRun']) {
|
|
141
|
+
const value = invokeOptions[name];
|
|
142
|
+
if (value === undefined || normalizedParams[name] !== undefined)
|
|
143
|
+
continue;
|
|
144
|
+
const projectedValue = name === 'expectedRevision' ? String(value) : value;
|
|
145
|
+
const param = paramsByName.get(name);
|
|
146
|
+
if (typeof param?.documentApiInputName === 'string' && param.documentApiInputName.length > 0) {
|
|
147
|
+
input[param.documentApiInputName] = projectedValue;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
options[name] = projectedValue;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (options.changeMode !== undefined && !supportsTrackedMode(operation)) {
|
|
154
|
+
if (options.changeMode === 'tracked') {
|
|
155
|
+
throw unsupported(`Structured document RPC does not support tracked mode for ${operation.operationId}.`, operation.operationId);
|
|
156
|
+
}
|
|
157
|
+
if (options.changeMode !== 'direct') {
|
|
158
|
+
throw unsupported(`Structured document RPC received an invalid change mode for ${operation.operationId}.`, operation.operationId);
|
|
159
|
+
}
|
|
160
|
+
delete options.changeMode;
|
|
94
161
|
}
|
|
162
|
+
if (options.dryRun !== undefined && operation.supportsDryRun !== true) {
|
|
163
|
+
if (options.dryRun === true) {
|
|
164
|
+
throw unsupported(`Structured document RPC does not support dry run for ${operation.operationId}.`, operation.operationId);
|
|
165
|
+
}
|
|
166
|
+
delete options.dryRun;
|
|
167
|
+
}
|
|
168
|
+
if (options.expectedRevision !== undefined && DOCUMENT_API_REVISION_PREFLIGHT_OPERATIONS.has(operation.operationId)) {
|
|
169
|
+
throw unsupported(`Structured document RPC does not yet support expectedRevision for ${operation.operationId}.`, operation.operationId);
|
|
170
|
+
}
|
|
171
|
+
if (options.expectedRevision !== undefined && operation.mutates !== true) {
|
|
172
|
+
throw unsupported(`Structured document RPC does not support expectedRevision for ${operation.operationId}.`, operation.operationId);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
input,
|
|
176
|
+
...(Object.keys(options).length === 0 ? {} : { options }),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function buildDocumentInvokeParams(sessionId, operation, params, options, hostFeatures) {
|
|
95
180
|
if (operation.operationId === 'doc.save') {
|
|
96
|
-
if (
|
|
97
|
-
|
|
181
|
+
if (options.stdinBytes !== undefined ||
|
|
182
|
+
options.dryRun !== undefined ||
|
|
183
|
+
options.expectedRevision !== undefined ||
|
|
184
|
+
options.changeMode !== undefined) {
|
|
185
|
+
throw unsupported('Structured document RPC does not support document.save invoke options.', operation.operationId);
|
|
186
|
+
}
|
|
187
|
+
const unknownField = Object.entries(params).find(([name, value]) => value !== undefined && !DOCUMENT_RPC_SAVE_FIELDS.has(name))?.[0];
|
|
188
|
+
if (unknownField !== undefined) {
|
|
189
|
+
throw unsupported(`Structured document RPC does not support doc.save field ${unknownField}.`, operation.operationId);
|
|
190
|
+
}
|
|
191
|
+
if (params.inPlace !== undefined && typeof params.inPlace !== 'boolean') {
|
|
192
|
+
throw unsupported('Structured document RPC requires inPlace to be a boolean.', operation.operationId);
|
|
193
|
+
}
|
|
194
|
+
if (params.inPlace === true && params.out !== undefined) {
|
|
195
|
+
throw unsupported('Structured document RPC requires either inPlace or out, not both.', operation.operationId);
|
|
196
|
+
}
|
|
197
|
+
if (params.out !== undefined && (typeof params.out !== 'string' || params.out.length === 0)) {
|
|
198
|
+
throw unsupported('Structured document RPC requires out to be a non-empty path.', operation.operationId);
|
|
199
|
+
}
|
|
200
|
+
if (params.out === undefined && hostFeatures?.has(DOCUMENT_RPC_SOURCE_SAVE_FEATURE) !== true) {
|
|
201
|
+
throw unsupported('Structured document RPC host does not support source saves.', operation.operationId);
|
|
98
202
|
}
|
|
99
203
|
return {
|
|
100
204
|
method: 'document.save',
|
|
101
205
|
params: {
|
|
102
206
|
sessionId,
|
|
103
|
-
path: params.out,
|
|
104
|
-
|
|
207
|
+
...(params.out === undefined ? {} : { path: params.out }),
|
|
208
|
+
...(params.force === true ? { overwrite: true } : {}),
|
|
105
209
|
...(params.mode === undefined ? {} : { mode: params.mode }),
|
|
106
210
|
},
|
|
107
211
|
};
|
|
108
212
|
}
|
|
109
213
|
if (operation.operationId === 'doc.close') {
|
|
214
|
+
if (options.stdinBytes !== undefined ||
|
|
215
|
+
options.dryRun !== undefined ||
|
|
216
|
+
options.expectedRevision !== undefined ||
|
|
217
|
+
options.changeMode !== undefined) {
|
|
218
|
+
throw unsupported('Structured document RPC does not support document.close invoke options.', operation.operationId);
|
|
219
|
+
}
|
|
110
220
|
return {
|
|
111
221
|
method: 'document.close',
|
|
112
222
|
params: {
|
|
@@ -115,16 +225,40 @@ function buildDocumentInvokeParams(sessionId, operation, params, options) {
|
|
|
115
225
|
},
|
|
116
226
|
};
|
|
117
227
|
}
|
|
228
|
+
const documentOperation = operation;
|
|
229
|
+
if (typeof documentOperation.documentApiOperationId !== 'string' ||
|
|
230
|
+
documentOperation.documentApiOperationId.length === 0) {
|
|
231
|
+
throw unsupported(`Structured document RPC does not support ${operation.operationId}.`, operation.operationId);
|
|
232
|
+
}
|
|
233
|
+
const payload = documentInvokePayload(documentOperation, params, options);
|
|
118
234
|
return {
|
|
119
235
|
method: 'document.invoke',
|
|
120
236
|
params: {
|
|
121
237
|
sessionId,
|
|
122
|
-
operationId:
|
|
123
|
-
input:
|
|
238
|
+
operationId: documentOperation.documentApiOperationId,
|
|
239
|
+
input: payload.input,
|
|
240
|
+
...(payload.options === undefined ? {} : { options: payload.options }),
|
|
124
241
|
},
|
|
125
242
|
};
|
|
126
243
|
}
|
|
127
|
-
function
|
|
244
|
+
function documentRpcRequestSupportsResponseTimeout(operation, request) {
|
|
245
|
+
if (request.method === 'document.save')
|
|
246
|
+
return false;
|
|
247
|
+
if (request.method !== 'document.invoke')
|
|
248
|
+
return true;
|
|
249
|
+
const documentOperation = operation;
|
|
250
|
+
const requestOptions = typeof request.params.options === 'object' &&
|
|
251
|
+
request.params.options !== null &&
|
|
252
|
+
!Array.isArray(request.params.options)
|
|
253
|
+
? request.params.options
|
|
254
|
+
: undefined;
|
|
255
|
+
if (requestOptions?.dryRun === true)
|
|
256
|
+
return true;
|
|
257
|
+
if (documentOperation.mutates === false)
|
|
258
|
+
return true;
|
|
259
|
+
return documentOperation.idempotency === 'idempotent';
|
|
260
|
+
}
|
|
261
|
+
function mapDocumentLifecycleResult(operationId, response, sessionId, expectedInPlace) {
|
|
128
262
|
if (operationId !== 'doc.save' && operationId !== 'doc.close')
|
|
129
263
|
return response;
|
|
130
264
|
if (typeof response !== 'object' || response == null || Array.isArray(response)) {
|
|
@@ -158,6 +292,7 @@ function mapDocumentLifecycleResult(operationId, response, sessionId) {
|
|
|
158
292
|
}
|
|
159
293
|
const output = record.output;
|
|
160
294
|
if (record.saved !== true ||
|
|
295
|
+
(typeof record.inPlace !== 'boolean' && !(record.inPlace === undefined && expectedInPlace === false)) ||
|
|
161
296
|
typeof output !== 'object' ||
|
|
162
297
|
output == null ||
|
|
163
298
|
Array.isArray(output) ||
|
|
@@ -172,18 +307,22 @@ function mapDocumentLifecycleResult(operationId, response, sessionId) {
|
|
|
172
307
|
contextId: sessionId,
|
|
173
308
|
runtime: 'v2',
|
|
174
309
|
saved: true,
|
|
175
|
-
inPlace: false,
|
|
310
|
+
inPlace: record.inPlace ?? false,
|
|
176
311
|
mode: record.mode,
|
|
177
312
|
output,
|
|
178
313
|
report: record.report,
|
|
179
314
|
};
|
|
180
315
|
}
|
|
181
316
|
|
|
317
|
+
exports.DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE;
|
|
182
318
|
exports.DOCUMENT_RPC_FEATURES = DOCUMENT_RPC_FEATURES;
|
|
319
|
+
exports.DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE;
|
|
320
|
+
exports.DOCUMENT_RPC_SOURCE_SAVE_FEATURE = DOCUMENT_RPC_SOURCE_SAVE_FEATURE;
|
|
183
321
|
exports.buildDocumentInvokeParams = buildDocumentInvokeParams;
|
|
184
322
|
exports.buildDocumentOpenParams = buildDocumentOpenParams;
|
|
185
323
|
exports.canOpenWithDocumentRpc = canOpenWithDocumentRpc;
|
|
186
324
|
exports.documentRpcEnabled = documentRpcEnabled;
|
|
325
|
+
exports.documentRpcRequestSupportsResponseTimeout = documentRpcRequestSupportsResponseTimeout;
|
|
187
326
|
exports.mapDocumentLifecycleResult = mapDocumentLifecycleResult;
|
|
188
327
|
exports.mapDocumentOpenResult = mapDocumentOpenResult;
|
|
189
328
|
exports.supportsDocumentRpc = supportsDocumentRpc;
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ChangeMode, type InvokeOptions, type OperationSpec, type UserIdentity } from './transport-common.js';
|
|
2
2
|
export declare const DOCUMENT_RPC_FEATURES: readonly ["document.open", "document.invoke", "document.save", "document.close"];
|
|
3
|
+
export declare const DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = "document.open.defaultChangeMode";
|
|
4
|
+
export declare const DOCUMENT_RPC_SOURCE_SAVE_FEATURE = "document.save.source";
|
|
5
|
+
export declare const DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = "host.request.timeoutMs";
|
|
6
|
+
type DocumentRpcRequest = {
|
|
7
|
+
readonly method: string;
|
|
8
|
+
readonly params: Record<string, unknown>;
|
|
9
|
+
};
|
|
3
10
|
export declare function documentRpcEnabled(env: Record<string, string | undefined> | undefined): boolean;
|
|
4
11
|
export declare function supportsDocumentRpc(features: ReadonlySet<string>): boolean;
|
|
5
12
|
export declare function canOpenWithDocumentRpc(params: Record<string, unknown>, options: InvokeOptions): boolean;
|
|
6
|
-
export declare function buildDocumentOpenParams(params: Record<string, unknown
|
|
13
|
+
export declare function buildDocumentOpenParams(params: Record<string, unknown>, user?: UserIdentity, defaultChangeMode?: ChangeMode): {
|
|
7
14
|
readonly sessionId: string;
|
|
8
15
|
readonly params: Record<string, unknown>;
|
|
9
16
|
};
|
|
10
17
|
export declare function mapDocumentOpenResult(response: unknown, sessionId: string, path: string): Record<string, unknown>;
|
|
11
|
-
export declare function buildDocumentInvokeParams(sessionId: string, operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions): {
|
|
18
|
+
export declare function buildDocumentInvokeParams(sessionId: string, operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions, hostFeatures?: ReadonlySet<string>): {
|
|
12
19
|
readonly method: string;
|
|
13
20
|
readonly params: Record<string, unknown>;
|
|
14
21
|
};
|
|
15
|
-
export declare function
|
|
22
|
+
export declare function documentRpcRequestSupportsResponseTimeout(operation: OperationSpec, request: DocumentRpcRequest): boolean;
|
|
23
|
+
export declare function mapDocumentLifecycleResult(operationId: string, response: unknown, sessionId: string, expectedInPlace?: boolean): unknown;
|
|
24
|
+
export {};
|