@docmana/sdk 0.28.1 → 0.32.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.
@@ -0,0 +1,317 @@
1
+ import type { HttpClient } from "./http/http-client.js";
2
+ /** Native editor data is lossless: unknown metadata is retained during edits. */
3
+ export type AuthoringData = Record<string, unknown>;
4
+ export interface AuthoringNode extends AuthoringData {
5
+ id: string;
6
+ type: string;
7
+ position: {
8
+ x: number;
9
+ y: number;
10
+ };
11
+ data: AuthoringData & {
12
+ label: string;
13
+ type: string;
14
+ enabled?: boolean;
15
+ };
16
+ parentId?: string;
17
+ }
18
+ export interface AuthoringEdge extends AuthoringData {
19
+ id: string;
20
+ source: string;
21
+ target: string;
22
+ }
23
+ export interface AuthoringRevisions {
24
+ flow: number;
25
+ nodes: Record<string, number>;
26
+ edges: Record<string, number>;
27
+ rules: Record<string, number>;
28
+ }
29
+ export type AuthoringSource = {
30
+ kind: "mongo";
31
+ } | {
32
+ kind: "git";
33
+ formulaId: string;
34
+ repository: string;
35
+ path: string;
36
+ ref: string;
37
+ };
38
+ export interface AuthoringGitPublication {
39
+ source: Extract<AuthoringSource, {
40
+ kind: "git";
41
+ }>;
42
+ commitSha: string;
43
+ publishedVersion: number;
44
+ mongoRevisions: AuthoringRevisions;
45
+ contentHash: string;
46
+ publishedAt: string;
47
+ artifactHash?: string | null;
48
+ toolingHash?: string | null;
49
+ }
50
+ export interface AuthoringGitProjection {
51
+ source: Extract<AuthoringSource, {
52
+ kind: "git";
53
+ }>;
54
+ commitSha: string;
55
+ artifactHash: string;
56
+ toolingHash: string;
57
+ operationId: string;
58
+ mongoRevisions: AuthoringRevisions;
59
+ contentHash: string;
60
+ projectedAt: string;
61
+ }
62
+ export interface AuthoringPublication {
63
+ operationId: string;
64
+ expectedRevisions: AuthoringRevisions;
65
+ gitCommitSha?: string;
66
+ gitArtifactHash?: string;
67
+ gitToolingHash?: string;
68
+ }
69
+ export interface AuthoringFlowSummary extends AuthoringData {
70
+ authoringSource?: AuthoringSource | null;
71
+ lastGitPublication?: AuthoringGitPublication | null;
72
+ lastGitProjection?: AuthoringGitProjection | null;
73
+ createdAt?: string;
74
+ updatedAt?: string;
75
+ executionStats?: {
76
+ totalExecutions: number;
77
+ totalDocuments: number;
78
+ };
79
+ id: string;
80
+ name: string;
81
+ type?: "manual" | "assisted";
82
+ state?: string;
83
+ isDirty?: boolean;
84
+ }
85
+ export interface AuthoringSnapshot {
86
+ gitPublicationState?: {
87
+ status: "not_published" | "unchanged" | "diverged" | "staged";
88
+ currentContentHash: string;
89
+ } | null;
90
+ flow: AuthoringFlowSummary & {
91
+ configs?: AuthoringData;
92
+ nodes: AuthoringNode[];
93
+ edges: AuthoringEdge[];
94
+ };
95
+ rules: AuthoringData[];
96
+ revisions: AuthoringRevisions;
97
+ historyCounts: {
98
+ snapshots: number;
99
+ published: number;
100
+ };
101
+ }
102
+ export interface AuthoringChanges {
103
+ create?: AuthoringData[];
104
+ update?: {
105
+ id: string;
106
+ patch: AuthoringData;
107
+ }[];
108
+ delete?: string[];
109
+ }
110
+ export interface AuthoringDraft {
111
+ gitProjection?: {
112
+ commitSha: string;
113
+ artifactHash: string;
114
+ toolingHash: string;
115
+ };
116
+ authoringSource?: AuthoringSource;
117
+ operationId: string;
118
+ expectedRevisions: AuthoringRevisions;
119
+ flowPatch?: AuthoringData;
120
+ nodes?: AuthoringChanges;
121
+ edges?: AuthoringChanges;
122
+ prompts?: {
123
+ create?: AuthoringData[];
124
+ updateForNode?: string[];
125
+ delete?: string[];
126
+ upsertForNode?: {
127
+ id: string;
128
+ prompt: AuthoringData;
129
+ }[];
130
+ };
131
+ rules?: AuthoringData[];
132
+ }
133
+ export interface AuthoringCreate {
134
+ authoringSource?: AuthoringSource;
135
+ operationId: string;
136
+ id: string;
137
+ name: string;
138
+ type: "manual" | "assisted";
139
+ configs?: AuthoringData;
140
+ nodes: AuthoringNode[];
141
+ edges: AuthoringEdge[];
142
+ }
143
+ export interface AuthoringReceipt {
144
+ success: boolean;
145
+ id?: string;
146
+ version?: number;
147
+ flowUpdatedAt: string;
148
+ revisions: AuthoringRevisions;
149
+ committedRuleIds?: Record<string, string>;
150
+ }
151
+ export interface AuthoringOptions {
152
+ organization: string;
153
+ signal?: AbortSignal;
154
+ }
155
+ export interface AuthoringDocumentTrialNode {
156
+ id: string;
157
+ name: string;
158
+ type: "classification" | "extraction" | "metadata-extraction";
159
+ prompt?: {
160
+ metadata: AuthoringData;
161
+ messages: AuthoringData[];
162
+ schemaDatas: AuthoringData;
163
+ };
164
+ /** Native assisted definition; mutually exclusive with a manual prompt. */
165
+ assisted?: {
166
+ metadata: AuthoringData;
167
+ rules: AuthoringData[];
168
+ configs: AuthoringData;
169
+ };
170
+ }
171
+ export type AuthoringDocumentTrialSpec = {
172
+ flowId: string;
173
+ expectedRevisions: AuthoringRevisions;
174
+ node?: string;
175
+ allNodes?: boolean;
176
+ } | {
177
+ nodes: AuthoringDocumentTrialNode[];
178
+ };
179
+ export interface AuthoringDocumentTrialReport {
180
+ executor?: "flows" | "docmana-api";
181
+ mode: "document-trial";
182
+ execution_scope: "isolated";
183
+ status: "completed" | "error";
184
+ rows: {
185
+ node: string;
186
+ name: string;
187
+ type: string;
188
+ status: "completed" | "error";
189
+ seconds: number;
190
+ output?: AuthoringData;
191
+ error?: string;
192
+ }[];
193
+ }
194
+ export interface AuthoringEditorCatalog {
195
+ capabilities?: {
196
+ canonicalProjection?: number;
197
+ runtimeEnvironment?: string;
198
+ };
199
+ models: {
200
+ default_model: string;
201
+ assisted_model?: string;
202
+ ai_provider: string;
203
+ models: {
204
+ model_name: string;
205
+ reasoning_effort_values?: string[] | null;
206
+ default_reasoning_effort?: string | null;
207
+ }[];
208
+ };
209
+ tools: (AuthoringData & {
210
+ tool_id: string;
211
+ tool_name?: string;
212
+ type?: string;
213
+ short_description_fr?: string;
214
+ short_description_en?: string;
215
+ })[];
216
+ systems: {
217
+ id: string;
218
+ name: string;
219
+ expectedFields?: AuthoringData[];
220
+ }[];
221
+ defaults: {
222
+ aggregator: string;
223
+ };
224
+ flags: {
225
+ flags: Record<string, boolean>;
226
+ };
227
+ }
228
+ export interface AuthoringConversationContext {
229
+ flow_id: string;
230
+ scope?: string | null;
231
+ node_id?: string | null;
232
+ node_label?: string | null;
233
+ }
234
+ export interface AuthoringConversation {
235
+ conversation_id: string;
236
+ expires_at: string;
237
+ context: AuthoringConversationContext;
238
+ }
239
+ export interface AuthoringConversationInput {
240
+ flow_id: string;
241
+ language: "fr" | "en";
242
+ scope?: string;
243
+ node_id?: string;
244
+ messages?: {
245
+ role: "user" | "assistant";
246
+ content: string;
247
+ }[];
248
+ }
249
+ export interface AuthoringConversationTurn {
250
+ assistant_message: string;
251
+ options?: unknown[] | null;
252
+ proposed_rule?: AuthoringData | null;
253
+ proposed_document_type_rename?: AuthoringData | null;
254
+ context: AuthoringConversationContext;
255
+ target_resolved: boolean;
256
+ expires_at: string;
257
+ }
258
+ export type AuthoringSort = "id" | "newest" | "oldest" | "recentlyModified" | "leastRecentlyModified" | "name";
259
+ export interface AuthoringPageOptions extends AuthoringOptions {
260
+ sort?: AuthoringSort;
261
+ offset?: number;
262
+ limit?: number;
263
+ }
264
+ /** Aggregate authoring only. Caller retains operation IDs when retrying mutations. */
265
+ export declare class FormulaAuthoring {
266
+ private readonly http;
267
+ constructor(http: HttpClient);
268
+ /** Read-only, revision-pinned definitions. Assisted execution belongs to the server-side Flows POC. */
269
+ documentTrialDefinitions(spec: {
270
+ flowId: string;
271
+ expectedRevisions: AuthoringRevisions;
272
+ node?: string;
273
+ allNodes?: boolean;
274
+ }, options: AuthoringOptions): Promise<{
275
+ nodes: AuthoringDocumentTrialNode[];
276
+ }>;
277
+ /** Native manual execution through Consumer Edge; assisted trials use definitions plus server-side Flows. */
278
+ trialDocument(file: Blob, filename: string, spec: AuthoringDocumentTrialSpec, options: AuthoringOptions): Promise<AuthoringDocumentTrialReport>;
279
+ editorCatalog(options: AuthoringOptions): Promise<AuthoringEditorCatalog>;
280
+ generateMapping(body: {
281
+ workflow_fields: AuthoringData[];
282
+ expected_fields: AuthoringData[];
283
+ current_mapping: string;
284
+ user_instructions: string;
285
+ }, options: AuthoringOptions): Promise<{
286
+ jsonataExpression: string;
287
+ }>;
288
+ openConversation(body: AuthoringConversationInput, options: AuthoringOptions): Promise<AuthoringConversation>;
289
+ sendConversationMessage(id: string, content: string, options: AuthoringOptions): Promise<AuthoringConversationTurn>;
290
+ confirmConversation(id: string, body: {
291
+ rule_id?: string;
292
+ document_type_rename?: boolean;
293
+ }, options: AuthoringOptions): Promise<{
294
+ expires_at: string;
295
+ }>;
296
+ private request;
297
+ list(options: AuthoringPageOptions): Promise<AuthoringFlowSummary[]>;
298
+ remove(id: string, options: AuthoringOptions): Promise<{
299
+ success: boolean;
300
+ }>;
301
+ exportArchive(id: string, options: AuthoringOptions): Promise<Uint8Array>;
302
+ importArchive(file: Blob, filename: string, options: AuthoringOptions & {
303
+ confirmOverwrite?: boolean;
304
+ }): Promise<{
305
+ status: "imported" | "confirmation_required";
306
+ flowName?: string;
307
+ }>;
308
+ get(id: string, options: AuthoringOptions): Promise<AuthoringSnapshot>;
309
+ create(body: AuthoringCreate, options: AuthoringOptions): Promise<AuthoringReceipt>;
310
+ save(id: string, body: AuthoringDraft, options: AuthoringOptions): Promise<AuthoringReceipt>;
311
+ validate(id: string, revisions: AuthoringRevisions, options: AuthoringOptions): Promise<AuthoringData>;
312
+ publish(id: string, body: AuthoringPublication, options: AuthoringOptions): Promise<AuthoringReceipt>;
313
+ history(id: string, kind: "snapshots" | "published", options: AuthoringPageOptions): Promise<AuthoringData[]>;
314
+ flags(options: AuthoringOptions): Promise<{
315
+ flags: Record<string, boolean>;
316
+ }>;
317
+ }
package/dist/cli.mjs CHANGED
@@ -36,11 +36,148 @@ function normalizeApiBaseUrl(value) {
36
36
  return /\/v\d+$/i.test(trimmed) ? trimmed : `${trimmed}/v1`;
37
37
  }
38
38
 
39
+ // src/sdk/authoring.ts
40
+ function identity(id) {
41
+ if (!/^[A-Za-z0-9_-]{1,200}$/.test(id)) throw new Error("Invalid formula identifier");
42
+ return encodeURIComponent(id);
43
+ }
44
+ var FormulaAuthoring = class {
45
+ constructor(http) {
46
+ this.http = http;
47
+ }
48
+ http;
49
+ /** Read-only, revision-pinned definitions. Assisted execution belongs to the server-side Flows POC. */
50
+ documentTrialDefinitions(spec, options) {
51
+ identity(spec.flowId);
52
+ if (Boolean(spec.node) === (spec.allNodes === true))
53
+ throw new Error("Select one node or all nodes");
54
+ if (spec.node) identity(spec.node);
55
+ return this.request("POST", "document-trial/definitions", options, spec);
56
+ }
57
+ /** Native manual execution through Consumer Edge; assisted trials use definitions plus server-side Flows. */
58
+ async trialDocument(file, filename, spec, options) {
59
+ if (!options.organization.trim()) throw new Error("Organization is required");
60
+ if (!file.size || file.size > 20 * 1024 * 1024 || !/\.(pdf|jpeg|jpg|png|bmp|tiff|tif|heic)$/i.test(filename))
61
+ throw new Error("Invalid trial document");
62
+ if ("flowId" in spec) {
63
+ identity(spec.flowId);
64
+ if (Boolean(spec.node) === (spec.allNodes === true))
65
+ throw new Error("Select one node or all nodes");
66
+ if (spec.node) identity(spec.node);
67
+ } else if (!Array.isArray(spec.nodes) || !spec.nodes.length || spec.nodes.length > 100)
68
+ throw new Error("Invalid trial nodes");
69
+ const body = new FormData();
70
+ body.set("file", file, filename);
71
+ body.set("spec", JSON.stringify(spec));
72
+ return this.http.requestJson("POST", "/authoring/document-trial", {
73
+ query: { organization: options.organization },
74
+ signal: options.signal,
75
+ body
76
+ });
77
+ }
78
+ editorCatalog(options) {
79
+ return this.request("GET", "editor-catalog", options);
80
+ }
81
+ generateMapping(body, options) {
82
+ return this.request("POST", "generate-mapping", options, body);
83
+ }
84
+ openConversation(body, options) {
85
+ identity(body.flow_id);
86
+ if (body.node_id) identity(body.node_id);
87
+ return this.request("POST", "conversations", options, body);
88
+ }
89
+ sendConversationMessage(id, content, options) {
90
+ return this.request("POST", `conversations/${identity(id)}/messages`, options, { content });
91
+ }
92
+ confirmConversation(id, body, options) {
93
+ return this.request("POST", `conversations/${identity(id)}/confirm`, options, body);
94
+ }
95
+ request(method, path, options, body) {
96
+ if (!options.organization.trim()) throw new Error("Organization is required");
97
+ return this.http.requestJson(method, `/authoring/${path}`, {
98
+ query: { organization: options.organization },
99
+ signal: options.signal,
100
+ ...body === void 0 ? {} : {
101
+ body: JSON.stringify(body),
102
+ headers: { "content-type": "application/json" }
103
+ }
104
+ });
105
+ }
106
+ list(options) {
107
+ const offset = options.offset ?? 0, limit = options.limit ?? 50;
108
+ if (!Number.isInteger(offset) || offset < 0 || !Number.isInteger(limit) || limit < 1 || limit > 200)
109
+ throw new Error("Invalid authoring pagination");
110
+ return this.request(
111
+ "GET",
112
+ `flows?offset=${offset}&limit=${limit}&sort=${encodeURIComponent(options.sort ?? "id")}`,
113
+ options
114
+ );
115
+ }
116
+ remove(id, options) {
117
+ return this.request("DELETE", `flows/${identity(id)}`, options);
118
+ }
119
+ async exportArchive(id, options) {
120
+ if (!options.organization.trim()) throw new Error("Organization is required");
121
+ return (await this.http.requestBytes("GET", `/authoring/flows/${identity(id)}/export`, {
122
+ query: { organization: options.organization },
123
+ signal: options.signal
124
+ })).bytes;
125
+ }
126
+ importArchive(file, filename, options) {
127
+ if (!options.organization.trim()) throw new Error("Organization is required");
128
+ if (!/\.(zip|docmana)$/i.test(filename) || file.size > 10 * 1024 * 1024)
129
+ throw new Error("Invalid formula archive");
130
+ const body = new FormData();
131
+ body.append("file", file, filename);
132
+ return this.http.requestJson("POST", "/authoring/flows/import", {
133
+ query: {
134
+ organization: options.organization,
135
+ confirmOverwrite: String(options.confirmOverwrite === true)
136
+ },
137
+ body,
138
+ signal: options.signal
139
+ });
140
+ }
141
+ get(id, options) {
142
+ return this.request("GET", `flows/${identity(id)}`, options);
143
+ }
144
+ create(body, options) {
145
+ return this.request("POST", "flows", options, body);
146
+ }
147
+ save(id, body, options) {
148
+ return this.request("PATCH", `flows/${identity(id)}/draft`, options, body);
149
+ }
150
+ validate(id, revisions, options) {
151
+ return this.request("POST", `flows/${identity(id)}/validate`, options, {
152
+ expectedRevisions: revisions
153
+ });
154
+ }
155
+ publish(id, body, options) {
156
+ return this.request("POST", `flows/${identity(id)}/publish`, options, body);
157
+ }
158
+ history(id, kind, options) {
159
+ if (kind !== "snapshots" && kind !== "published") throw new Error("Invalid history kind");
160
+ const offset = options.offset ?? 0, limit = options.limit ?? 20;
161
+ if (!Number.isInteger(offset) || offset < 0 || !Number.isInteger(limit) || limit < 1 || limit > 100)
162
+ throw new Error("Invalid history pagination");
163
+ return this.request(
164
+ "GET",
165
+ `flows/${identity(id)}/history/${kind}?offset=${offset}&limit=${limit}`,
166
+ options
167
+ );
168
+ }
169
+ flags(options) {
170
+ return this.request("GET", "feature-flags", options);
171
+ }
172
+ };
173
+
39
174
  // src/sdk/errors.ts
40
175
  var DocmanaError = class extends Error {
41
176
  status;
42
177
  requestId;
43
178
  code;
179
+ /** Public API business code; `code` retains the SDK's existing error category. */
180
+ apiCode;
44
181
  constructor(message, opts = {}) {
45
182
  super(message);
46
183
  this.name = new.target.name;
@@ -169,12 +306,16 @@ var HttpClient = class {
169
306
  if (!res.ok) {
170
307
  const requestId = res.headers.get("x-request-id") ?? void 0;
171
308
  const message = await this.extractMessage(res);
172
- throw errorFromResponse(
309
+ const error = errorFromResponse(
173
310
  res.status,
174
311
  message,
175
312
  requestId,
176
313
  parseRetryAfterMs(res.headers.get("retry-after"))
177
314
  );
315
+ const data = await res.clone().json().catch(() => null);
316
+ if (typeof data?.code === "string" && /^[A-Za-z][A-Za-z0-9_]{0,99}$/.test(data.code))
317
+ Object.defineProperty(error, "apiCode", { value: data.code, enumerable: true });
318
+ throw error;
178
319
  }
179
320
  return res;
180
321
  }
@@ -674,6 +815,7 @@ function fullJitterDelay(intervalMs, maxIntervalMs, attempt, random) {
674
815
 
675
816
  // src/sdk/client.ts
676
817
  var Docmana = class {
818
+ authoring;
677
819
  config;
678
820
  http;
679
821
  constructor(config) {
@@ -685,6 +827,7 @@ var Docmana = class {
685
827
  getAccessToken: this.config.getAccessToken,
686
828
  headers: this.config.headers
687
829
  });
830
+ this.authoring = new FormulaAuthoring(this.http);
688
831
  }
689
832
  async runFlowAsync(flowId, params, options = {}) {
690
833
  const parts = await resolveInputs(params);