@oddington/sdk 0.1.22 → 0.1.24

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.
@@ -14,10 +14,12 @@ export type { RecordReadInput } from '../../../shared/record-capture.js';
14
14
  export type { RecordDeleteRequest, RecordUpdateRequest, RecordWriteRequest } from '../../../shared/record-write.js';
15
15
  export { RoutineRecordWriteError } from '../../../shared/record-write.js';
16
16
  export { AirtableOperationError } from '../../../shared/airtable-contract.js';
17
- export type { AirtableField, AirtableTable, AirtableRecord, AirtableListInput, AirtableGetInput, AirtableCreateInput, AirtableUpdateInput, AirtableDeleteInput, AirtableReceipt, AirtableWriteResult, AirtableClient, Connections } from '../../../shared/airtable-contract.js';
17
+ export type { AirtableField, AirtableTable, AirtableRecord, AirtableListInput, AirtableGetInput, AirtableCreateInput, AirtableUpdateInput, AirtableDeleteInput, AirtableReceipt, AirtableWriteResult, AirtableClient } from '../../../shared/airtable-contract.js';
18
+ export type { GmailRuntimeConnection, AirtableRuntimeConnection, RuntimeConnection } from '../../../shared/connection-runtime.js';
19
+ export type { Connections } from '../../../shared/airtable-contract.js';
18
20
  export declare const connections: import('../../../shared/airtable-contract.js').Connections;
19
21
  export { DataOperationError } from '../../../shared/data-contract.js';
20
- export type { DataRepository, DataErrorCode, PublicValueDefinition, PublicField, CollectionSummary, CollectionSchema, QueryScalar, SelectionOptions, RecordSelection, RecordsQuery, DataValue, SelectedRecord, SelectionMetadata, RecordsResult, RecordsSearchOptions, RecordsSearchResult, HistoryListOptions, HistoryEntry, HistoryChangesOptions, HistoryChange, HistoryChangesResult, RecordIdentity, RecordCreation, RecordUpdateSet, DataPublication, DataChangeSet, DataEffect } from '../../../shared/data-contract.js';
22
+ export type { DataRepository, DataErrorCode, PublicValueDefinition, PublicField, CollectionSummary, CollectionSchema, QueryScalar, SelectionOptions, RecordSelection, RecordsQuery, DataValue, SelectedRecord, SelectionMetadata, RecordsResult, RecordsReadInput, RecordsReadResult, RecordsSearchOptions, RecordsSearchResult, HistoryListOptions, HistoryEntry, HistoryChangesOptions, HistoryChange, HistoryChangesResult, RecordIdentity, RecordCreation, RecordUpdateSet, DataPublication, DataChangeSet, DataEffect } from '../../../shared/data-contract.js';
21
23
  export declare const data: {
22
24
  repository(name: string): import('../../../shared/data-contract.js').DataRepository;
23
25
  };
@@ -183,6 +185,14 @@ export type AppRoutineBinding<Input, Result, Steps> = {
183
185
  };
184
186
  export declare const app: {
185
187
  listRoutines(): Promise<RoutineDescription[]>;
188
+ routine(id: string): {
189
+ describe(): Promise<RoutineDescription>;
190
+ run(input?: unknown): Promise<RunHandle>;
191
+ runs: {
192
+ list(): Promise<RunSummary[]>;
193
+ get(id: string): Promise<RunHandle>;
194
+ };
195
+ };
186
196
  routines: AppRoutineTypes;
187
197
  };
188
198
  /** A declared stage without a summary takes no second argument. */
@@ -1,6 +1,7 @@
1
1
  import type { AppValueSchema } from '../../../shared/app-routine-contract.js';
2
2
  import type { File } from '../../../shared/files-contract.js';
3
3
  import type { Connections } from '../../../shared/airtable-contract.js';
4
+ import type { RuntimeConnectionFor } from '../../../shared/connection-runtime.js';
4
5
  import type { DataRepository } from '../../../shared/data-contract.js';
5
6
  import type { Handler } from '../../../shared/inbox-contract.js';
6
7
  import type { files, RoutinePublicationClient } from './public.js';
@@ -59,11 +60,18 @@ export type RoutineCapabilities<Access extends RoutineAccess> = {
59
60
  readonly files: Access['files'] extends 'read-write' ? typeof files : Access['files'] extends 'read' ? Pick<typeof files, 'get' | 'read'> : {};
60
61
  readonly connections: {
61
62
  airtable(name: ConnectionName<Access>): ReturnType<Connections['airtable']>;
63
+ get<Name extends Extract<NonNullable<Access['connections']>[number], string>>(name: Name): Promise<RuntimeConnectionFor<Name>>;
62
64
  };
63
65
  readonly inbox: Pick<RoutinePublicationClient, (Access['publish'] extends readonly string[] ? 'asks' extends Access['publish'][number] ? 'publishAsk' : never : never) | (Access['publish'] extends readonly string[] ? 'digests' extends Access['publish'][number] ? 'publishDigest' : never : never)>;
64
66
  };
67
+ type RoutineStepCalls<Steps extends RoutineSteps> = {
68
+ [Key in keyof Steps]: {
69
+ input: Parameters<Steps[Key]['run']> extends [] ? [] : [input: RoutineStepInput<Steps[Key]> | RoutineInput<RoutineStepInput<Steps[Key]>>];
70
+ result: RoutineStepResult<Steps[Key]>;
71
+ };
72
+ };
65
73
  export type RoutineRuntime<Steps extends RoutineSteps, Access extends RoutineAccess = RoutineAccess> = RoutineCapabilities<Access> & {
66
- step<Key extends Extract<keyof Steps, string>>(id: Key, ...input: Parameters<Steps[Key]['run']> extends [] ? [] : [input: RoutineInput<RoutineStepInput<Steps[Key]>>]): Promise<RoutineStepResult<Steps[Key]>>;
74
+ step<Key extends Extract<keyof Steps, string>>(id: Key, ...input: RoutineStepCalls<Steps>[Key]['input']): Promise<RoutineStepCalls<Steps>[Key]['result']>;
67
75
  };
68
76
  export type RoutineDefinition<Input extends RoutineSchema<unknown> | undefined = RoutineSchema<unknown> | undefined, Steps extends RoutineSteps = RoutineSteps, Result extends RoutineSchema<unknown> | undefined = RoutineSchema<unknown> | undefined, Access extends RoutineAccess = RoutineAccess, Responses extends readonly Handler<any>[] = readonly Handler<any>[], Id extends string = string> = {
69
77
  readonly id: Id;
@@ -98,4 +106,6 @@ export type RoutineSchemaBuilders = {
98
106
  }): RoutineSchema<number, false>;
99
107
  boolean(): RoutineSchema<boolean, false>;
100
108
  };
101
- export type RoutineFileSchema = () => RoutineSchema<File, false>;
109
+ export type RoutineFileSchema = (options?: {
110
+ storage?: 'local' | 'remote';
111
+ }) => RoutineSchema<File, false>;
@@ -73,6 +73,7 @@ export interface AirtableClient {
73
73
  }
74
74
  export interface Connections {
75
75
  airtable(name: string): AirtableClient;
76
+ get<Name extends string>(identity: Name): Promise<import('./connection-runtime.js').RuntimeConnectionFor<Name>>;
76
77
  }
77
78
  /** Safe provider failure. An uncertain or partial mutation must never be retried blindly. */
78
79
  export declare class AirtableOperationError extends Error {
@@ -1,4 +1,5 @@
1
1
  import type { AppValueSchema } from './app-routine-contract.js';
2
+ import type { RoutineContract } from './routine-definition-contract.js';
2
3
  /** Build-time structure only. Runtime readiness and availability belong to hosts. */
3
4
  export type AppRoutineDescriptor = {
4
5
  id: string;
@@ -19,3 +20,5 @@ export type AppRoutineDescriptor = {
19
20
  export type AppDescriptor = {
20
21
  routines: AppRoutineDescriptor[];
21
22
  };
23
+ /** The shared safe projection for generated apps and deployed preparation. */
24
+ export declare function routineDefinitionDescriptor(contract: RoutineContract): AppRoutineDescriptor;
@@ -29,6 +29,7 @@ export type AppValueSchema = {
29
29
  maximum?: number;
30
30
  } | {
31
31
  type: 'file';
32
+ storage?: 'local' | 'remote';
32
33
  };
33
34
  export type AppRoutineContract = {
34
35
  routine: string;
@@ -0,0 +1,20 @@
1
+ /** Public values delivered only inside trusted routine or handler execution. */
2
+ export type GmailRuntimeConnection = {
3
+ id: `gmail/${string}`;
4
+ provider: 'gmail';
5
+ name: string;
6
+ accountEmail: string;
7
+ scopes: string[];
8
+ accessToken: string;
9
+ expiresAt: string;
10
+ };
11
+ export type AirtableRuntimeConnection = {
12
+ id: `airtable/${string}`;
13
+ provider: 'airtable';
14
+ name: string;
15
+ baseId: string;
16
+ accessToken: string;
17
+ runExpiresAt: string;
18
+ };
19
+ export type RuntimeConnection = GmailRuntimeConnection | AirtableRuntimeConnection;
20
+ export type RuntimeConnectionFor<Name extends string> = string extends Name ? RuntimeConnection : Name extends `gmail/${string}` ? GmailRuntimeConnection : Name extends `airtable/${string}` ? AirtableRuntimeConnection : never;
@@ -102,11 +102,26 @@ export type SelectionMetadata = {
102
102
  next?: string;
103
103
  }>;
104
104
  };
105
- export type RecordsResult = {
105
+ type SelectedRecordFor<Selection extends RecordSelection> = string extends keyof Selection ? SelectedRecord : SelectedRecord & {
106
+ [Link in Exclude<keyof Selection, '$'>]?: SelectedLinkFor<Selection[Link]>;
107
+ };
108
+ type SelectedLinkFor<Selection> = Selection extends RecordSelection ? SelectedRecordFor<Selection> | SelectedRecordFor<Selection>[] | null : never;
109
+ export type RecordsResult<Query extends RecordsQuery = RecordsQuery> = string extends keyof Query ? {
106
110
  $meta: SelectionMetadata;
107
111
  [collection: string]: SelectedRecord[] | SelectionMetadata;
112
+ } : {
113
+ $meta: SelectionMetadata;
114
+ } & {
115
+ [Collection in keyof Query]: SelectedRecordFor<Query[Collection]>[];
108
116
  };
109
117
  export type RecordIdentity = Pick<SelectedRecord, '$ref' | '$version'>;
118
+ export type RecordsReadInput = string | readonly string[];
119
+ export type RecordsReadResult = {
120
+ $meta: {
121
+ version: string;
122
+ };
123
+ records: Array<SelectedRecord | null>;
124
+ };
110
125
  export type RecordsSearchOptions = {
111
126
  collections?: string[];
112
127
  limit?: number;
@@ -190,7 +205,14 @@ export interface DataRepository {
190
205
  schema(name: string): Promise<CollectionSchema>;
191
206
  };
192
207
  records: {
193
- select(query: RecordsQuery): Promise<RecordsResult>;
208
+ select<Query extends RecordsQuery>(query: Query): Promise<RecordsResult<Query>>;
209
+ pages<Query extends RecordsQuery>(query: Query): AsyncIterable<RecordsResult<Query>>;
210
+ all<Query extends RecordsQuery>(query: Query, options: {
211
+ maxRecords: number;
212
+ }): Promise<RecordsResult<Query>>;
213
+ read(ref: string): Promise<SelectedRecord | null>;
214
+ read(refs: readonly string[]): Promise<RecordsReadResult>;
215
+ read(input: RecordsReadInput): Promise<SelectedRecord | null | RecordsReadResult>;
194
216
  search(query: string, options?: RecordsSearchOptions): Promise<RecordsSearchResult>;
195
217
  };
196
218
  history: {
@@ -138,9 +138,15 @@ type Presentation = {
138
138
  body?: InboxBlock[];
139
139
  notifyImmediately?: boolean;
140
140
  };
141
+ export type AskRecordRef = {
142
+ repository: string;
143
+ id: string;
144
+ };
141
145
  export type AskInput = Presentation & {
142
146
  recipients?: string[];
143
147
  questions?: QuestionInput[];
148
+ tags?: string[];
149
+ recordRefs?: AskRecordRef[];
144
150
  };
145
151
  export type DigestInput = Presentation & {
146
152
  recipients: string[];
@@ -149,6 +155,8 @@ export type AskPublication = Presentation & {
149
155
  kind: 'ask';
150
156
  recipients: string[];
151
157
  questions: Question[];
158
+ tags: string[];
159
+ recordRefs: AskRecordRef[];
152
160
  };
153
161
  export type DigestPublication = DigestInput & {
154
162
  kind: 'digest';
@@ -333,7 +341,7 @@ export declare function validateHandlerTransition(value: unknown, state: {
333
341
  export declare function validateResolution(value: unknown): ResolutionInput;
334
342
  export type PublicationRequest = {
335
343
  requestKey: string;
336
- item: Publication;
344
+ item: DigestPublication | (Omit<AskPublication, 'tags' | 'recordRefs'> & Pick<AskInput, 'tags' | 'recordRefs'>);
337
345
  };
338
346
  export type PublishedAsk = {
339
347
  id: string;
@@ -63,12 +63,11 @@ export type LinkedAskSnapshot = {
63
63
  state: 'unavailable';
64
64
  done: boolean;
65
65
  };
66
- export interface InboxItem {
66
+ interface InboxItemSnapshot {
67
67
  canonicalRoutineId?: string | null;
68
68
  id: string;
69
69
  workspaceId: string;
70
70
  number: number;
71
- kind: 'ask' | 'digest';
72
71
  title: string;
73
72
  description: string;
74
73
  author: string;
@@ -105,6 +104,18 @@ export interface InboxItem {
105
104
  settledAt: string | null;
106
105
  }[];
107
106
  }
107
+ export type InboxItem = InboxItemSnapshot & ({
108
+ kind: 'ask';
109
+ tags: string[];
110
+ recordRefs: Array<{
111
+ repository: string;
112
+ id: string;
113
+ }>;
114
+ } | {
115
+ kind: 'digest';
116
+ tags?: never;
117
+ recordRefs?: never;
118
+ });
108
119
  export interface DigestReadConfirmation {
109
120
  readAt: string;
110
121
  activityId: number;
@@ -127,6 +138,7 @@ export interface AnswerableQuestion {
127
138
  instructions?: string;
128
139
  response: ResponseDefinition;
129
140
  answerable: boolean;
141
+ tags: string[];
130
142
  recordRefs: Array<{
131
143
  repository: string;
132
144
  id: string;
@@ -194,3 +206,4 @@ export interface InboxMember {
194
206
  }): Promise<Response>;
195
207
  };
196
208
  }
209
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oddington/sdk",
3
- "version": "0.1.22",
4
- "description": "Oddington routine and response-handler SDK",
3
+ "version": "0.1.24",
4
+ "description": "OS routine and response-handler SDK",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
7
7
  "files": ["dist", "LICENSE", "README.md"],