@oddington/sdk 0.0.0-stage → 0.1.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/LICENSE +17 -0
- package/README.md +68 -2
- package/dist/index.js +22410 -0
- package/dist/types/packages/sdk/src/public.d.ts +47 -0
- package/dist/types/shared/delimited-text.d.ts +2 -0
- package/dist/types/shared/inbox-contract.d.ts +366 -0
- package/dist/types/shared/inbox-files.d.ts +17 -0
- package/dist/types/shared/inbox-views.d.ts +97 -0
- package/dist/types/shared/record-capture.d.ts +7 -0
- package/dist/types/shared/record-write.d.ts +29 -0
- package/dist/types/shared/repository-targets.d.ts +22 -0
- package/package.json +25 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AskInput, CapturedRecords, DigestInput, InboxFile, PublicationRequest, PublishedAsk, PublishedDigest, RepositoryReceipt, ResolutionInput } from '../../../shared/inbox-contract.js';
|
|
2
|
+
import type { FileAddOptions } from '../../../shared/inbox-files.js';
|
|
3
|
+
import type { RecordReadInput } from '../../../shared/record-capture.js';
|
|
4
|
+
import type { RecordDeleteRequest, RecordUpdateRequest, RecordWriteRequest } from '../../../shared/record-write.js';
|
|
5
|
+
export * from '../../../shared/inbox-contract.js';
|
|
6
|
+
export * from '../../../shared/inbox-views.js';
|
|
7
|
+
export { RoutineRecordWriteError } from '../../../shared/record-write.js';
|
|
8
|
+
export type InboxRequester = (path: string, init?: RequestInit) => Promise<Response>;
|
|
9
|
+
export type RoutinePublicationClientOptions = {
|
|
10
|
+
workspace?: string;
|
|
11
|
+
capability?: string;
|
|
12
|
+
request?: InboxRequester;
|
|
13
|
+
workingRoot?: string;
|
|
14
|
+
};
|
|
15
|
+
export type RoutinePublicationClient = {
|
|
16
|
+
publishAsk(value: AskInput, options: {
|
|
17
|
+
requestKey: string;
|
|
18
|
+
}): Promise<PublishedAsk>;
|
|
19
|
+
publishDigest(value: DigestInput, options: {
|
|
20
|
+
requestKey: string;
|
|
21
|
+
}): Promise<PublishedDigest>;
|
|
22
|
+
publishResolution(askId: string, value: ResolutionInput): Promise<void>;
|
|
23
|
+
readRecords(input: RecordReadInput): Promise<CapturedRecords>;
|
|
24
|
+
repository: {
|
|
25
|
+
readRecords(input: RecordReadInput): Promise<CapturedRecords>;
|
|
26
|
+
updateRecords(input: RecordUpdateRequest, options: {
|
|
27
|
+
requestKey: string;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
receipt: RepositoryReceipt;
|
|
30
|
+
}>;
|
|
31
|
+
writeRecords(input: RecordWriteRequest, options: {
|
|
32
|
+
requestKey: string;
|
|
33
|
+
}): Promise<{
|
|
34
|
+
receipt: RepositoryReceipt;
|
|
35
|
+
}>;
|
|
36
|
+
deleteRecords(input: RecordDeleteRequest, options: {
|
|
37
|
+
requestKey: string;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
receipt: RepositoryReceipt;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
42
|
+
files: {
|
|
43
|
+
add(value: FileAddOptions): Promise<InboxFile>;
|
|
44
|
+
};
|
|
45
|
+
check(body: PublicationRequest): Promise<void>;
|
|
46
|
+
};
|
|
47
|
+
export declare function routinePublicationClient(options?: RoutinePublicationClientOptions): RoutinePublicationClient;
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/** The bounded ask/digest contract. Authorization and durable effects belong to
|
|
2
|
+
* the server; constructing a value here grants no publication authority. */
|
|
3
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject;
|
|
4
|
+
export type JsonObject = {
|
|
5
|
+
[key: string]: JsonValue;
|
|
6
|
+
};
|
|
7
|
+
export type AuthoredSource = {
|
|
8
|
+
type: 'authored';
|
|
9
|
+
options: Array<{
|
|
10
|
+
value: string;
|
|
11
|
+
label: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
note?: {
|
|
14
|
+
placeholder: string;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
suggestions?: string[];
|
|
18
|
+
search?: {
|
|
19
|
+
triggerLabel: string;
|
|
20
|
+
placeholder: string;
|
|
21
|
+
emptyLabel: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export type RecordReference = {
|
|
25
|
+
repository: string;
|
|
26
|
+
ref: string;
|
|
27
|
+
};
|
|
28
|
+
export type RecordSource = {
|
|
29
|
+
type: 'records';
|
|
30
|
+
collection: {
|
|
31
|
+
repository: string;
|
|
32
|
+
name: string;
|
|
33
|
+
};
|
|
34
|
+
refPrefix?: string;
|
|
35
|
+
where?: Record<string, string | number | boolean | null>;
|
|
36
|
+
display: {
|
|
37
|
+
labelFields: string[];
|
|
38
|
+
};
|
|
39
|
+
suggestions?: Array<{
|
|
40
|
+
record: RecordReference;
|
|
41
|
+
reason?: string;
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
44
|
+
export type ResponseDefinition = {
|
|
45
|
+
type: 'selection';
|
|
46
|
+
source: AuthoredSource | RecordSource;
|
|
47
|
+
};
|
|
48
|
+
export type QuestionResponse = {
|
|
49
|
+
selection: string | RecordReference;
|
|
50
|
+
note?: string;
|
|
51
|
+
};
|
|
52
|
+
export type HandlerReference = {
|
|
53
|
+
id: string;
|
|
54
|
+
input: JsonValue;
|
|
55
|
+
};
|
|
56
|
+
export type Question = {
|
|
57
|
+
id: string;
|
|
58
|
+
to: string;
|
|
59
|
+
allowedResponders: string[];
|
|
60
|
+
prompt: string;
|
|
61
|
+
instructions?: string;
|
|
62
|
+
response: ResponseDefinition;
|
|
63
|
+
handler?: HandlerReference;
|
|
64
|
+
};
|
|
65
|
+
export type QuestionInput = Omit<Question, 'allowedResponders'> & {
|
|
66
|
+
allowedResponders?: string[];
|
|
67
|
+
};
|
|
68
|
+
export type PublishedView = {
|
|
69
|
+
id: string;
|
|
70
|
+
view: string;
|
|
71
|
+
input: JsonValue;
|
|
72
|
+
};
|
|
73
|
+
export type PresentedField = {
|
|
74
|
+
label: string;
|
|
75
|
+
value: string;
|
|
76
|
+
};
|
|
77
|
+
export type PresentedRecord = {
|
|
78
|
+
ref: string;
|
|
79
|
+
title: string;
|
|
80
|
+
fields: PresentedField[];
|
|
81
|
+
};
|
|
82
|
+
export type PresentedRecordSummary = {
|
|
83
|
+
ref: string;
|
|
84
|
+
title: string;
|
|
85
|
+
description?: string;
|
|
86
|
+
facts?: PresentedField[];
|
|
87
|
+
view?: string;
|
|
88
|
+
};
|
|
89
|
+
export type CsvDetails = {
|
|
90
|
+
kind: 'csv';
|
|
91
|
+
encoding: 'utf-8' | 'windows-1252';
|
|
92
|
+
delimiter: ',' | ';' | '\t';
|
|
93
|
+
headerRow: number;
|
|
94
|
+
dataRows: number;
|
|
95
|
+
};
|
|
96
|
+
export type InboxFile = {
|
|
97
|
+
id: string;
|
|
98
|
+
name: string;
|
|
99
|
+
mediaType: string;
|
|
100
|
+
size: number;
|
|
101
|
+
sha256: string;
|
|
102
|
+
details: CsvDetails | {
|
|
103
|
+
kind: 'pdf';
|
|
104
|
+
pages?: number;
|
|
105
|
+
} | {
|
|
106
|
+
kind: 'other';
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
export type InboxBlock = {
|
|
110
|
+
kind: 'rich-text';
|
|
111
|
+
markdown: string;
|
|
112
|
+
} | {
|
|
113
|
+
kind: 'record';
|
|
114
|
+
label: string;
|
|
115
|
+
record: PresentedRecord;
|
|
116
|
+
view?: string;
|
|
117
|
+
initiallyExpanded?: boolean;
|
|
118
|
+
} | {
|
|
119
|
+
kind: 'records';
|
|
120
|
+
label: string;
|
|
121
|
+
records: PresentedRecordSummary[];
|
|
122
|
+
view?: string;
|
|
123
|
+
initiallyExpanded?: boolean;
|
|
124
|
+
} | {
|
|
125
|
+
kind: 'files';
|
|
126
|
+
label: string;
|
|
127
|
+
files: InboxFile[];
|
|
128
|
+
initiallyExpanded?: boolean;
|
|
129
|
+
} | {
|
|
130
|
+
kind: 'asks';
|
|
131
|
+
problem: string;
|
|
132
|
+
asks: string[];
|
|
133
|
+
};
|
|
134
|
+
type Presentation = {
|
|
135
|
+
title: string;
|
|
136
|
+
description: string;
|
|
137
|
+
views?: PublishedView[];
|
|
138
|
+
body?: InboxBlock[];
|
|
139
|
+
notifyImmediately?: boolean;
|
|
140
|
+
};
|
|
141
|
+
export type AskInput = Presentation & {
|
|
142
|
+
recipients?: string[];
|
|
143
|
+
questions?: QuestionInput[];
|
|
144
|
+
};
|
|
145
|
+
export type DigestInput = Presentation & {
|
|
146
|
+
recipients: string[];
|
|
147
|
+
};
|
|
148
|
+
export type AskPublication = Presentation & {
|
|
149
|
+
kind: 'ask';
|
|
150
|
+
recipients: string[];
|
|
151
|
+
questions: Question[];
|
|
152
|
+
};
|
|
153
|
+
export type DigestPublication = DigestInput & {
|
|
154
|
+
kind: 'digest';
|
|
155
|
+
};
|
|
156
|
+
export type Publication = AskPublication | DigestPublication;
|
|
157
|
+
export type RecipientPublication = DigestPublication | (Omit<AskPublication, 'questions'> & {
|
|
158
|
+
questions: Array<Omit<Question, 'handler'>>;
|
|
159
|
+
});
|
|
160
|
+
/** These values are supplied by the verified launch/storage path, never by an
|
|
161
|
+
* authored item. They are separate from recipient-facing presentation. */
|
|
162
|
+
export type PublisherProvenance = {
|
|
163
|
+
workspaceId: string;
|
|
164
|
+
} & ({
|
|
165
|
+
personId: string;
|
|
166
|
+
} | {
|
|
167
|
+
routineId: string;
|
|
168
|
+
runId: string;
|
|
169
|
+
routineVersion: string;
|
|
170
|
+
});
|
|
171
|
+
export type RetainedPublication = {
|
|
172
|
+
id: string;
|
|
173
|
+
revision: 1;
|
|
174
|
+
publisher: PublisherProvenance;
|
|
175
|
+
/** Internal retained definition, including private handler input. Never send
|
|
176
|
+
* this object directly to a recipient; use recipientPresentation. */
|
|
177
|
+
presentation: Publication;
|
|
178
|
+
resolvedViews: Array<{
|
|
179
|
+
id: string;
|
|
180
|
+
implementation: string;
|
|
181
|
+
}>;
|
|
182
|
+
};
|
|
183
|
+
export type QuestionInstance = {
|
|
184
|
+
askId: string;
|
|
185
|
+
revision: number;
|
|
186
|
+
questionId: string;
|
|
187
|
+
};
|
|
188
|
+
export type ResponseSubmission = QuestionInstance & {
|
|
189
|
+
response: QuestionResponse;
|
|
190
|
+
};
|
|
191
|
+
export type OddingtonAssignment = {
|
|
192
|
+
type: 'oddington';
|
|
193
|
+
reason: string;
|
|
194
|
+
};
|
|
195
|
+
export type Resolution = {
|
|
196
|
+
outcome: string;
|
|
197
|
+
evidence?: JsonValue[];
|
|
198
|
+
};
|
|
199
|
+
export type HandlerTransition = {
|
|
200
|
+
type: 'continue';
|
|
201
|
+
assignTo?: OddingtonAssignment;
|
|
202
|
+
} | ({
|
|
203
|
+
type: 'resolve';
|
|
204
|
+
} & Resolution);
|
|
205
|
+
export type ResolutionInput = Resolution & {
|
|
206
|
+
expectedRevision: number;
|
|
207
|
+
};
|
|
208
|
+
export type CapturedRecords = {
|
|
209
|
+
commit: string;
|
|
210
|
+
records: Array<{
|
|
211
|
+
ref: string;
|
|
212
|
+
version: string;
|
|
213
|
+
fields: JsonObject;
|
|
214
|
+
}>;
|
|
215
|
+
};
|
|
216
|
+
export type RecordUpdate = {
|
|
217
|
+
ref: string;
|
|
218
|
+
expectedVersion: string;
|
|
219
|
+
set: JsonObject;
|
|
220
|
+
};
|
|
221
|
+
export type RecordCreate = {
|
|
222
|
+
ref: string;
|
|
223
|
+
path: string;
|
|
224
|
+
fields: JsonObject;
|
|
225
|
+
};
|
|
226
|
+
export type RecordDelete = {
|
|
227
|
+
ref: string;
|
|
228
|
+
expectedVersion: string;
|
|
229
|
+
};
|
|
230
|
+
export type RepositoryReceipt = {
|
|
231
|
+
repository: string;
|
|
232
|
+
commit: string;
|
|
233
|
+
diff: string;
|
|
234
|
+
};
|
|
235
|
+
export interface RepositoryCapabilities {
|
|
236
|
+
readRecords(input: {
|
|
237
|
+
repository: string;
|
|
238
|
+
refs: string[];
|
|
239
|
+
atCommit?: string;
|
|
240
|
+
}): Promise<CapturedRecords>;
|
|
241
|
+
writeRecords(input: {
|
|
242
|
+
repository: string;
|
|
243
|
+
records: Array<RecordCreate | RecordUpdate>;
|
|
244
|
+
}): Promise<{
|
|
245
|
+
receipt: RepositoryReceipt;
|
|
246
|
+
}>;
|
|
247
|
+
updateRecords(input: {
|
|
248
|
+
repository: string;
|
|
249
|
+
records: RecordUpdate[];
|
|
250
|
+
}): Promise<{
|
|
251
|
+
receipt: RepositoryReceipt;
|
|
252
|
+
}>;
|
|
253
|
+
deleteRecords(input: {
|
|
254
|
+
repository: string;
|
|
255
|
+
records: RecordDelete[];
|
|
256
|
+
}): Promise<{
|
|
257
|
+
receipt: RepositoryReceipt;
|
|
258
|
+
}>;
|
|
259
|
+
}
|
|
260
|
+
export type HandlerRuntime<Input extends JsonValue = JsonValue> = {
|
|
261
|
+
input: Input;
|
|
262
|
+
response: QuestionResponse;
|
|
263
|
+
ask: {
|
|
264
|
+
readonly id: string;
|
|
265
|
+
readonly revision: number;
|
|
266
|
+
viewInput(id: string): JsonValue;
|
|
267
|
+
};
|
|
268
|
+
responseDefinition: ResponseDefinition;
|
|
269
|
+
questionId: string;
|
|
270
|
+
repository: RepositoryCapabilities;
|
|
271
|
+
};
|
|
272
|
+
export type Handler<Input extends JsonValue = JsonValue> = {
|
|
273
|
+
id: string;
|
|
274
|
+
run(runtime: HandlerRuntime<Input>): Promise<HandlerTransition>;
|
|
275
|
+
};
|
|
276
|
+
export declare class InboxContractError extends Error {
|
|
277
|
+
constructor(message: string);
|
|
278
|
+
}
|
|
279
|
+
/** Copy only lossless JSON. In particular, JSON.stringify must not silently
|
|
280
|
+
* erase undefined/functions or convert dates, sparse arrays, or nonfinite numbers. */
|
|
281
|
+
export declare function serializable(value: unknown, ancestors?: Set<object>): JsonValue;
|
|
282
|
+
export declare function validateInboxFile(value: unknown): InboxFile;
|
|
283
|
+
export declare function validateBlock(value: unknown): InboxBlock;
|
|
284
|
+
export declare function richTextBlock(value: Omit<Extract<InboxBlock, {
|
|
285
|
+
kind: 'rich-text';
|
|
286
|
+
}>, 'kind'>): Extract<InboxBlock, {
|
|
287
|
+
kind: 'rich-text';
|
|
288
|
+
}>;
|
|
289
|
+
export declare function recordBlock(value: Omit<Extract<InboxBlock, {
|
|
290
|
+
kind: 'record';
|
|
291
|
+
}>, 'kind'>): Extract<InboxBlock, {
|
|
292
|
+
kind: 'record';
|
|
293
|
+
}>;
|
|
294
|
+
export declare function recordsBlock(value: Omit<Extract<InboxBlock, {
|
|
295
|
+
kind: 'records';
|
|
296
|
+
}>, 'kind'>): Extract<InboxBlock, {
|
|
297
|
+
kind: 'records';
|
|
298
|
+
}>;
|
|
299
|
+
export declare function fileBlock(value: Omit<Extract<InboxBlock, {
|
|
300
|
+
kind: 'files';
|
|
301
|
+
}>, 'kind'>): Extract<InboxBlock, {
|
|
302
|
+
kind: 'files';
|
|
303
|
+
}>;
|
|
304
|
+
export declare function asksBlock(value: Omit<Extract<InboxBlock, {
|
|
305
|
+
kind: 'asks';
|
|
306
|
+
}>, 'kind'>): Extract<InboxBlock, {
|
|
307
|
+
kind: 'asks';
|
|
308
|
+
}>;
|
|
309
|
+
export declare function selection(value: {
|
|
310
|
+
source: AuthoredSource | RecordSource;
|
|
311
|
+
}): ResponseDefinition;
|
|
312
|
+
export declare function validateRecordReference(value: unknown): RecordReference;
|
|
313
|
+
export declare function validateRecordSource(value: unknown): RecordSource;
|
|
314
|
+
export declare function validateResponseDefinition(value: unknown): ResponseDefinition;
|
|
315
|
+
export declare function validateResponse(definition: unknown, value: unknown): QuestionResponse;
|
|
316
|
+
export declare function defineHandler<Input extends JsonValue>(value: Handler<Input>): Handler<Input>;
|
|
317
|
+
export declare function respond<Input extends JsonValue>(handler: Handler<Input>, input: Input): HandlerReference;
|
|
318
|
+
export declare function question(value: QuestionInput): Question;
|
|
319
|
+
/** Structural validation is shared. Registered view/handler availability,
|
|
320
|
+
* people, repository/file access, and provenance MUST be checked by publication too. */
|
|
321
|
+
export declare function validatePublication(value: unknown): Publication;
|
|
322
|
+
/** Structural projection only. The read boundary must check current recipient,
|
|
323
|
+
* workspace and repository/file access before returning this content. */
|
|
324
|
+
export declare function recipientPresentation(value: unknown): RecipientPublication;
|
|
325
|
+
export declare function oddington(value: {
|
|
326
|
+
reason: string;
|
|
327
|
+
}): OddingtonAssignment;
|
|
328
|
+
export declare function continueAsk(value: {
|
|
329
|
+
assignTo?: OddingtonAssignment;
|
|
330
|
+
}): HandlerTransition;
|
|
331
|
+
export declare function resolveAsk(value: Resolution): HandlerTransition;
|
|
332
|
+
/** Call at the durable transition boundary with server-derived remaining work,
|
|
333
|
+
* excluding the execution being completed. Lifecycle/effect guards also apply. */
|
|
334
|
+
export declare function validateHandlerTransition(value: unknown, state: {
|
|
335
|
+
hasOtherViableWork: boolean;
|
|
336
|
+
}): HandlerTransition;
|
|
337
|
+
export declare function validateResolution(value: unknown): ResolutionInput;
|
|
338
|
+
export type PublicationRequest = {
|
|
339
|
+
requestKey: string;
|
|
340
|
+
item: Publication;
|
|
341
|
+
};
|
|
342
|
+
export type PublishedAsk = {
|
|
343
|
+
id: string;
|
|
344
|
+
revision: number;
|
|
345
|
+
};
|
|
346
|
+
export type PublishedDigest = {
|
|
347
|
+
id: string;
|
|
348
|
+
};
|
|
349
|
+
/** The server verifies workspace membership and optional trusted run provenance. */
|
|
350
|
+
export interface InboxPublicationTransport {
|
|
351
|
+
publish(request: PublicationRequest): Promise<PublishedAsk | PublishedDigest>;
|
|
352
|
+
resolve(request: {
|
|
353
|
+
askId: string;
|
|
354
|
+
resolution: ResolutionInput;
|
|
355
|
+
}): Promise<void>;
|
|
356
|
+
}
|
|
357
|
+
export declare function createInboxPublisher(transport: InboxPublicationTransport): {
|
|
358
|
+
publishAsk(value: AskInput, options: {
|
|
359
|
+
requestKey: string;
|
|
360
|
+
}): Promise<PublishedAsk>;
|
|
361
|
+
publishDigest(value: DigestInput, options: {
|
|
362
|
+
requestKey: string;
|
|
363
|
+
}): Promise<PublishedDigest>;
|
|
364
|
+
publishResolution(askId: string, value: ResolutionInput): Promise<void>;
|
|
365
|
+
};
|
|
366
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type InboxFile, type CsvDetails } from './inbox-contract.js';
|
|
2
|
+
export type FileAddOptions = {
|
|
3
|
+
path: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
csv?: {
|
|
6
|
+
encoding?: CsvDetails['encoding'];
|
|
7
|
+
delimiter?: CsvDetails['delimiter'];
|
|
8
|
+
headerRow?: number;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare function validateFileAddOptions(value: unknown): FileAddOptions;
|
|
12
|
+
export declare function validateCsvHints(value: unknown): NonNullable<FileAddOptions['csv']>;
|
|
13
|
+
export declare function csvRows(bytes: Uint8Array, details: CsvDetails): string[][];
|
|
14
|
+
export declare function deriveInboxFile(bytes: Uint8Array, name: string, csv?: FileAddOptions['csv']): Promise<Omit<InboxFile, 'id'>>;
|
|
15
|
+
/** Integrity/type checks apply to publication and every fresh download. */
|
|
16
|
+
export declare function verifyInboxFile(bytes: Uint8Array, value: unknown): Promise<InboxFile>;
|
|
17
|
+
export declare function publicationFiles(body?: import('./inbox-contract.js').InboxBlock[]): InboxFile[];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type JsonObject, type PublishedView } from './inbox-contract.js';
|
|
2
|
+
export type TableColumn = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
type: 'string' | 'date' | 'integer' | 'number' | 'boolean' | 'enum' | 'nullable-enum' | 'link';
|
|
6
|
+
unit?: string;
|
|
7
|
+
values?: string[];
|
|
8
|
+
missing: 'reject';
|
|
9
|
+
missingLabel?: string;
|
|
10
|
+
};
|
|
11
|
+
export type RecordTableInput = {
|
|
12
|
+
repository?: string;
|
|
13
|
+
commit?: string;
|
|
14
|
+
columns: TableColumn[];
|
|
15
|
+
rows: Array<{
|
|
16
|
+
ref: string;
|
|
17
|
+
version?: string;
|
|
18
|
+
values: JsonObject;
|
|
19
|
+
}>;
|
|
20
|
+
/** Routine-owned evidence (such as batch relationships), never interpreted by the host. */
|
|
21
|
+
metadata?: JsonObject;
|
|
22
|
+
};
|
|
23
|
+
export type CapturedRecordTableInput = Omit<RecordTableInput, 'repository' | 'commit' | 'rows'> & {
|
|
24
|
+
repository: string;
|
|
25
|
+
commit: string;
|
|
26
|
+
rows: Array<{
|
|
27
|
+
ref: string;
|
|
28
|
+
version: string;
|
|
29
|
+
values: JsonObject;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
export declare function validateCapturedRecordTableInput(value: unknown): CapturedRecordTableInput;
|
|
33
|
+
export type ResolvedView = PublishedView & {
|
|
34
|
+
implementation: string;
|
|
35
|
+
};
|
|
36
|
+
export type RecordValue = {
|
|
37
|
+
kind: 'text';
|
|
38
|
+
text: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'missing';
|
|
41
|
+
label: string;
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'record';
|
|
44
|
+
ref: string;
|
|
45
|
+
label: string;
|
|
46
|
+
recordType?: string;
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'list';
|
|
49
|
+
items: RecordValue[];
|
|
50
|
+
remaining?: number;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'object';
|
|
53
|
+
fields: RecordField[];
|
|
54
|
+
};
|
|
55
|
+
export type RecordField = {
|
|
56
|
+
label: string;
|
|
57
|
+
value: RecordValue;
|
|
58
|
+
};
|
|
59
|
+
export type ViewRecord = {
|
|
60
|
+
ref: string;
|
|
61
|
+
title: string;
|
|
62
|
+
recordType?: string;
|
|
63
|
+
fields: RecordField[];
|
|
64
|
+
body?: {
|
|
65
|
+
label: string;
|
|
66
|
+
markdown: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export type RecordViewInput = {
|
|
70
|
+
record: ViewRecord;
|
|
71
|
+
related?: ViewRecord[];
|
|
72
|
+
};
|
|
73
|
+
export declare const commonViews: ({
|
|
74
|
+
name: string;
|
|
75
|
+
implementation: string;
|
|
76
|
+
workspaces: '*';
|
|
77
|
+
validate: typeof validateRecordViewInput;
|
|
78
|
+
} | {
|
|
79
|
+
name: string;
|
|
80
|
+
implementation: string;
|
|
81
|
+
workspaces: '*';
|
|
82
|
+
validate: typeof validateRecordTableInput;
|
|
83
|
+
})[];
|
|
84
|
+
export declare function validateRecordViewInput(value: unknown): RecordViewInput;
|
|
85
|
+
export declare function validateRecordTableInput(value: unknown): RecordTableInput;
|
|
86
|
+
export declare const registeredViews: ({
|
|
87
|
+
name: string;
|
|
88
|
+
implementation: string;
|
|
89
|
+
workspaces: '*';
|
|
90
|
+
validate: typeof validateRecordViewInput;
|
|
91
|
+
} | {
|
|
92
|
+
name: string;
|
|
93
|
+
implementation: string;
|
|
94
|
+
workspaces: '*';
|
|
95
|
+
validate: typeof validateRecordTableInput;
|
|
96
|
+
})[];
|
|
97
|
+
export declare function resolveInboxView(view: PublishedView, workspace: string): ResolvedView;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RepositoryCapabilities } from './inbox-contract.js';
|
|
2
|
+
export type RecordReadInput = Parameters<RepositoryCapabilities['readRecords']>[0];
|
|
3
|
+
export declare const RECORD_READ_INPUT_LIMIT: number;
|
|
4
|
+
export declare const RECORD_CAPTURE_OUTPUT_LIMIT: number;
|
|
5
|
+
export declare function validRecordRef(value: unknown): value is string;
|
|
6
|
+
/** Only record selectors cross the customer boundary; destinations are trusted configuration. */
|
|
7
|
+
export declare function validateRecordRead(value: unknown): RecordReadInput;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type RecordCreate, type RecordDelete, type RecordUpdate } from './inbox-contract.js';
|
|
2
|
+
export type RecordWrite = RecordCreate | RecordUpdate;
|
|
3
|
+
export type RecordUpdateRequest = {
|
|
4
|
+
repository: string;
|
|
5
|
+
records: RecordUpdate[];
|
|
6
|
+
};
|
|
7
|
+
export type RecordWriteRequest = {
|
|
8
|
+
repository: string;
|
|
9
|
+
records: RecordWrite[];
|
|
10
|
+
};
|
|
11
|
+
export type RecordDeleteRequest = {
|
|
12
|
+
repository: string;
|
|
13
|
+
records: RecordDelete[];
|
|
14
|
+
};
|
|
15
|
+
export type RecordChangeRequest = RecordWriteRequest | RecordDeleteRequest;
|
|
16
|
+
export type RoutineRecordWriteRequest = {
|
|
17
|
+
input: RecordChangeRequest;
|
|
18
|
+
requestKey: string;
|
|
19
|
+
};
|
|
20
|
+
export declare const RECORD_WRITE_INPUT_LIMIT: number;
|
|
21
|
+
export declare class RoutineRecordWriteError extends Error {
|
|
22
|
+
readonly effect: 'unapplied' | 'uncertain' | 'pending';
|
|
23
|
+
constructor(message: string, effect: 'unapplied' | 'uncertain' | 'pending');
|
|
24
|
+
}
|
|
25
|
+
export declare function validateRecordWrite(value: unknown): RecordWriteRequest;
|
|
26
|
+
export declare function validateRecordUpdate(value: unknown): RecordUpdateRequest;
|
|
27
|
+
export declare function validateRecordDelete(value: unknown): RecordDeleteRequest;
|
|
28
|
+
export declare function validateRecordChange(value: unknown): RecordChangeRequest;
|
|
29
|
+
export declare function validateRoutineRecordWrite(value: unknown): RoutineRecordWriteRequest;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Secret-free, workspace-member-visible GitHub repository destination. */
|
|
2
|
+
export interface RepositoryTarget {
|
|
3
|
+
id: string;
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
connectionId: string;
|
|
6
|
+
repository: string;
|
|
7
|
+
remote: string;
|
|
8
|
+
githubRepositoryId: number;
|
|
9
|
+
targetRef: string;
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
}
|
|
14
|
+
/** Managed Git-tree data boundaries. */
|
|
15
|
+
export interface RepositoryDataTarget extends RepositoryTarget {
|
|
16
|
+
dataRoots: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function validDataRoots(value: unknown): value is string[];
|
|
19
|
+
export declare function parseRepositoryDataTarget(value: unknown): RepositoryDataTarget;
|
|
20
|
+
export declare function validRepositoryAlias(value: unknown): value is string;
|
|
21
|
+
export declare function validTargetRef(value: unknown): value is string;
|
|
22
|
+
export declare function parseRepositoryTarget(value: unknown): RepositoryTarget;
|
package/package.json
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oddington/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Oddington routine and response-handler SDK",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": ["dist", "LICENSE", "README.md"],
|
|
8
|
+
"engines": { "node": ">=22.12.0" },
|
|
9
|
+
"publishConfig": { "access": "public" },
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/types/packages/sdk/src/public.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "bun run scripts/build.ts",
|
|
19
|
+
"check": "tsc --noEmit",
|
|
20
|
+
"prepack": "bun run scripts/prepack.ts",
|
|
21
|
+
"verify:package": "bun run scripts/verify-package.ts"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "26.6.1",
|
|
25
|
+
"typescript": "7.0.2"
|
|
26
|
+
}
|
|
27
|
+
}
|