@sprigr/apps-app-sdk 0.24.0 → 0.26.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/README.md +1 -0
- package/dist/index.d.ts +135 -1
- package/dist/index.js +64 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ export default {
|
|
|
75
75
|
- `fetchWithRetry` — rate-limit-header-aware, jittered retry
|
|
76
76
|
- `constantTimeEqual(a, b)` — bearer-secret verification
|
|
77
77
|
- `encodeState` / `decodeState` — OAuth state base64url
|
|
78
|
+
- `encodeStateWithinEnvelope(state, { installId, appSlug, optional? })` — `encodeState` that leaves room for the platform's signed envelope (500 chars, decision 0190). An optional field (default `returnTo`) that does not fit is left out whole, never shortened, with a `console.warn` naming the lengths; without `returnTo` the bouncer lands the user on the install's dashboard. Use it for any state that carries a caller-supplied value. `oauthStateEnvelopeOverhead` and `OAUTH_STATE_ENVELOPE_MAX_CHARS` expose the arithmetic.
|
|
78
79
|
- `parseActor` / `actorKey` / `ownerFromActorKey` — per-actor token scoping
|
|
79
80
|
- `putAppFile` / `putAppFileStream` / `appFileUrl` / `getAppFile` / `listAppFiles` / `deleteAppFile` — durable app-scoped file storage from outside the injected bridge
|
|
80
81
|
- `fetchFileBytes` / `fetchFileAsBase64` / `bytesToBase64` / `base64ToBytes` — file byte helpers
|
package/dist/index.d.ts
CHANGED
|
@@ -74,6 +74,53 @@ interface OAuthState {
|
|
|
74
74
|
}
|
|
75
75
|
declare function encodeState(state: OAuthState): string;
|
|
76
76
|
declare function decodeState(encoded: string): OAuthState;
|
|
77
|
+
/**
|
|
78
|
+
* Longest platform-signed state the platform sends to a provider. Dropbox
|
|
79
|
+
* documents 500 bytes, the tightest cap among the marketplace's providers.
|
|
80
|
+
* Mirrors OAUTH_STATE_ENVELOPE_MAX_CHARS in sprigr-team
|
|
81
|
+
* packages/shared/src/utils/oauth-state-envelope.ts (decision 0190): a state
|
|
82
|
+
* whose envelope would pass it is sent UNSIGNED, and a slug on the bouncer's
|
|
83
|
+
* enforce list then refuses the connect.
|
|
84
|
+
*/
|
|
85
|
+
declare const OAUTH_STATE_ENVELOPE_MAX_CHARS = 500;
|
|
86
|
+
/**
|
|
87
|
+
* Characters the platform's signed envelope adds around an app's state.
|
|
88
|
+
* The wire shape is `sps1.<inner>.<payload>.<sig>`: payload is base64url JSON
|
|
89
|
+
* `{ i: installId, a: appSlug, t: <ms> }` and sig is 16 HMAC bytes, 22
|
|
90
|
+
* base64url characters (mintOAuthStateEnvelope in sprigr-team). `t` is the
|
|
91
|
+
* platform's signing time; any 13-digit ms timestamp gives the same length.
|
|
92
|
+
*/
|
|
93
|
+
declare function oauthStateEnvelopeOverhead(installId: string, appSlug: string, t?: number): number;
|
|
94
|
+
interface EncodeStateWithinEnvelopeOptions {
|
|
95
|
+
/** The install the platform signs into the envelope (env.INSTALL_ID). */
|
|
96
|
+
installId: string;
|
|
97
|
+
/** This app's marketplace slug, also signed into the envelope. */
|
|
98
|
+
appSlug: string;
|
|
99
|
+
/**
|
|
100
|
+
* Fields that may be left out, WHOLE, when the state would not fit, tried
|
|
101
|
+
* in this order. Default `['returnTo']`. List only fields the callback can
|
|
102
|
+
* do without: without returnTo the bouncer lands the user on the install's
|
|
103
|
+
* dashboard instead of the requested page.
|
|
104
|
+
*/
|
|
105
|
+
optional?: ReadonlyArray<keyof OAuthState>;
|
|
106
|
+
}
|
|
107
|
+
interface EncodedStateWithinEnvelope {
|
|
108
|
+
/** The encoded state to put on the authorize URL. */
|
|
109
|
+
state: string;
|
|
110
|
+
/** Optional fields left out to make it fit, in the order they were dropped. */
|
|
111
|
+
omitted: string[];
|
|
112
|
+
/** False when even the state without its optional fields is too long; it is then returned in full and the platform will send it unsigned. */
|
|
113
|
+
fits: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* encodeState, but leaving room for the platform's signed envelope
|
|
117
|
+
* (sprigr-apps#3190). An optional field that does not fit is left out whole,
|
|
118
|
+
* never shortened: a cut returnTo is a broken landing page, and an absent one
|
|
119
|
+
* falls back to the install's dashboard. Each omission is logged with the
|
|
120
|
+
* field's length and the state's length before and after, so the cause of a
|
|
121
|
+
* dashboard landing is findable.
|
|
122
|
+
*/
|
|
123
|
+
declare function encodeStateWithinEnvelope(state: OAuthState, opts: EncodeStateWithinEnvelopeOptions): EncodedStateWithinEnvelope;
|
|
77
124
|
|
|
78
125
|
/**
|
|
79
126
|
* fetchWithRetry — rate-limit-header-aware retry wrapper around fetch.
|
|
@@ -1653,6 +1700,46 @@ interface AppApprovalEnvelope {
|
|
|
1653
1700
|
* wrappers.
|
|
1654
1701
|
*/
|
|
1655
1702
|
unattended?: 'proceed';
|
|
1703
|
+
/**
|
|
1704
|
+
* Lay the card out as the thing being sent: an email with its header and
|
|
1705
|
+
* rendered body, an SMS, a document's rows (sprigr-team decision 0216).
|
|
1706
|
+
* You bind slots to YOUR TOOL'S ARGUMENT NAMES (or dotted paths such as
|
|
1707
|
+
* `input.body` for a dispatcher), and the platform fills them from the
|
|
1708
|
+
* exact arguments it replays on the tap, so the card cannot show one email
|
|
1709
|
+
* while another is sent. Build it with `emailPreview` / `smsPreview` /
|
|
1710
|
+
* `fieldsPreview`. Keep writing `question` and `summary`: a platform
|
|
1711
|
+
* without decision 0216, or a preview that resolves to nothing, falls
|
|
1712
|
+
* back to them.
|
|
1713
|
+
*/
|
|
1714
|
+
preview?: ApprovalPreviewSpec;
|
|
1715
|
+
}
|
|
1716
|
+
/** A slot bound to an argument name or dotted path, or a value you state. */
|
|
1717
|
+
type ApprovalPreviewSlot = string | {
|
|
1718
|
+
value: string;
|
|
1719
|
+
};
|
|
1720
|
+
/** Small facts shown as tags on the card. */
|
|
1721
|
+
type ApprovalPreviewFact = 'irreversible' | 'costs_credits' | 'no_signature';
|
|
1722
|
+
/** The `_approval.preview` an app declares (sprigr-team decision 0216). */
|
|
1723
|
+
interface ApprovalPreviewSpec {
|
|
1724
|
+
kind: 'email' | 'sms' | 'document' | 'calendar' | 'fields';
|
|
1725
|
+
from?: ApprovalPreviewSlot;
|
|
1726
|
+
to?: ApprovalPreviewSlot;
|
|
1727
|
+
cc?: ApprovalPreviewSlot;
|
|
1728
|
+
bcc?: ApprovalPreviewSlot;
|
|
1729
|
+
subject?: ApprovalPreviewSlot;
|
|
1730
|
+
/** Always an argument, never a stated value: the body must be what is sent. */
|
|
1731
|
+
body?: {
|
|
1732
|
+
arg: string;
|
|
1733
|
+
format: 'html' | 'text';
|
|
1734
|
+
};
|
|
1735
|
+
/** Argument holding an array of attachment names or `{ name, size }`. */
|
|
1736
|
+
attachments?: string;
|
|
1737
|
+
sendAt?: ApprovalPreviewSlot;
|
|
1738
|
+
fields?: Array<{
|
|
1739
|
+
label: string;
|
|
1740
|
+
from: ApprovalPreviewSlot;
|
|
1741
|
+
}>;
|
|
1742
|
+
facts?: ApprovalPreviewFact[];
|
|
1656
1743
|
}
|
|
1657
1744
|
/**
|
|
1658
1745
|
* Platform-stamped marker telling an app that a human approved this call. The
|
|
@@ -1742,6 +1829,53 @@ declare const APPROVAL_PREVIEW_MAX = 600;
|
|
|
1742
1829
|
*/
|
|
1743
1830
|
declare function approvalPreview(value: unknown, max?: number): string;
|
|
1744
1831
|
|
|
1832
|
+
/**
|
|
1833
|
+
* Builders for `_approval.preview` (sprigr-team decision 0216). They return
|
|
1834
|
+
* plain objects; the point is the types and the defaults, so a send tool
|
|
1835
|
+
* declares its card in one line:
|
|
1836
|
+
*
|
|
1837
|
+
* describe: (_t, a, mailbox) => ({
|
|
1838
|
+
* question: `Send an email to ${a.to}?`, header: 'Outlook',
|
|
1839
|
+
* preview: emailPreview({ from: { value: mailbox }, to: 'to', subject: 'subject', body: 'body' }),
|
|
1840
|
+
* })
|
|
1841
|
+
*
|
|
1842
|
+
* Every string slot is the NAME of one of your tool's arguments (or a dotted
|
|
1843
|
+
* path such as `input.body`). The platform reads the value from the exact
|
|
1844
|
+
* arguments it replays when the person taps, never from anything you send
|
|
1845
|
+
* here, so bind the argument you actually send.
|
|
1846
|
+
*/
|
|
1847
|
+
|
|
1848
|
+
interface EmailPreviewInput {
|
|
1849
|
+
from?: ApprovalPreviewSlot;
|
|
1850
|
+
to: ApprovalPreviewSlot;
|
|
1851
|
+
cc?: ApprovalPreviewSlot;
|
|
1852
|
+
bcc?: ApprovalPreviewSlot;
|
|
1853
|
+
subject?: ApprovalPreviewSlot;
|
|
1854
|
+
/** Argument name of the body. */
|
|
1855
|
+
body: string;
|
|
1856
|
+
/** Defaults to 'html'. */
|
|
1857
|
+
bodyFormat?: 'html' | 'text';
|
|
1858
|
+
attachments?: string;
|
|
1859
|
+
sendAt?: ApprovalPreviewSlot;
|
|
1860
|
+
/** Defaults to ['irreversible']: a sent email cannot be recalled. */
|
|
1861
|
+
facts?: ApprovalPreviewFact[];
|
|
1862
|
+
}
|
|
1863
|
+
declare function emailPreview(input: EmailPreviewInput): ApprovalPreviewSpec;
|
|
1864
|
+
interface SmsPreviewInput {
|
|
1865
|
+
from?: ApprovalPreviewSlot;
|
|
1866
|
+
to: ApprovalPreviewSlot;
|
|
1867
|
+
/** Argument name of the message text. */
|
|
1868
|
+
body: string;
|
|
1869
|
+
/** Defaults to ['irreversible']. Add 'costs_credits' when it does. */
|
|
1870
|
+
facts?: ApprovalPreviewFact[];
|
|
1871
|
+
}
|
|
1872
|
+
declare function smsPreview(input: SmsPreviewInput): ApprovalPreviewSpec;
|
|
1873
|
+
/** Label and value rows: an invoice's number and total, an event's time. */
|
|
1874
|
+
declare function fieldsPreview(kind: 'document' | 'calendar' | 'fields', rows: Array<{
|
|
1875
|
+
label: string;
|
|
1876
|
+
from: ApprovalPreviewSlot;
|
|
1877
|
+
}>, extra?: Pick<ApprovalPreviewSpec, 'to' | 'from' | 'subject' | 'facts'>): ApprovalPreviewSpec;
|
|
1878
|
+
|
|
1745
1879
|
/**
|
|
1746
1880
|
* Thrown by `undoEnvelope` for a field the platform would reject.
|
|
1747
1881
|
*
|
|
@@ -3523,4 +3657,4 @@ interface ExecutionContextLike {
|
|
|
3523
3657
|
}
|
|
3524
3658
|
type HandlerFn<TArgs, TResult> = (args: TArgs, env: Record<string, unknown>, ctx?: ExecutionContextLike) => Promise<TResult>;
|
|
3525
3659
|
|
|
3526
|
-
export { ACTOR_RETIRED_HOOK_TOOL, ACTOR_RETIRE_REASONS, APPROVAL_GRANTED_KEY, APPROVAL_PREVIEW_MAX, APP_FILES_ROOT, APP_OWNER_SEGMENT, type Actor, type ActorRetireReason, type ActorRetired, type ActorRetiredHookBody, type ActorRetiredResult, type AppApprovalEnvelope, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type AppToolEffectsDeclaration, type AppUndoEnvelope, type ApplyPoliciesOptions, type ApprovalCoverage, type ApprovalGateOptions, type ApprovalSpec, type ArchiveOfferOptions, type ArchiveOfferRefusal, type CallerKeyResolution, type CaptureJournal, type CompanyTimezoneEnv, type ConfirmCondition, type ConfirmRule, type ConfirmationPolicy, type ConnectCompleteRequest, type ConnectCompleteResult, type D1Like, type D1PreparedStatementLike, DATA_DELETE_MAX_IDS, DATA_PARTIAL_UPDATE_PATH, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_FILE_READ_TIMEOUT_MS, DEFAULT_LOG_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, DEFAULT_MONEY_FIELDS, DEFAULT_WRITE_PREFIXES, type DataClient, type DataIdsOpts, type DataListIdsResult, type DataTransport, type DerivePolicyOptions, type DerivedPolicy, type DispatcherApprovalGate, type DispatcherApprovalOptions, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EventArgs, type ExecutionContextLike, FILE_REF_SOURCES_HELP, type FetchFileResult, type FetchWithRetryOptions, type FileRef, type FileRefContent, type FileRefEnv, FileRefError, type FileRefErrorCode, type FileRefStream, type FileRefVia, type GetAppFileResult, type HandlerFn, INBOX_SEND_CONTRACT_V1, type IdPrefixSpec, type IdSnapshot, type InboxAddress, type InboxAppendRequest, type InboxAppendResult, type InboxChannelDeclaration, type InboxFoldersRequest, type InboxFoldersResult, type InboxOwner, type InboxSendConnection, type InboxSendHandlerImpl, InboxSendRefusal, type InboxSendSupports, type InboxSendV1Args, type InboxSendV1Result, type InstallBridge, InvalidUndoEnvelopeError, type JournalRowLike, type LogToPlatformOptions, type ManifestDispatchBlock, type ManifestLike, type ManifestToolLike, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, NotConnectedError, type OAuthBouncerSignals, type OAuthState, type OfferUndoArgs, type PartialUpdateDataOptions, type PlatformHostEnv, type PolicyCheckInput, type PolicySource, type PurgeResult, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type ReadFileRefOptions, type RequireApprovalOptions, type ResolveFileRefOptions, type ResolveViewerOptions, type ResolvedFileRef, type RestoreResult, type RestoreSpec, SPRIGR_DATA_MAX_OBJECTS_PER_CALL, SPRIGR_FILE_HOSTS, SPRIGR_LOG_LEVELS, SPRIGR_LOG_LIMITS, type ScheduleArgs, type SprigrDataAggregationCell, type SprigrDataAggregationResult, type SprigrDataAggregationSpec, type SprigrDataApi, type SprigrDataImportOpts, type SprigrDataIndexOpts, type SprigrDataPartialUpdateBody, type SprigrDataPartialUpdateOpts, type SprigrDataPartialUpdateResult, type SprigrDataPatch, type SprigrDataSearchOpts, type SprigrDataSearchResult, SprigrDataValidationError, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type SprigrFilesListItem, type SprigrFilesListResult, type SprigrInboxApi, type SprigrLogEntry, type SprigrLogFn, type SprigrLogLevel, type SprigrLogResult, SprigrLogValidationError, type SyncedAttachment, type SyncedMessage, type ToolArgs, type ToolHandler, type ToolResult, type ToolWrapperOptions, UNIT_SEP, type UndoApplyOptions, type UndoApplyResult, type UndoCaptureSpec, type UndoFidelity, VIEWER_ANONYMOUS, VIEWER_CONTEXT_HEADER, VIEWER_PLATFORM_USER_ID_HEADER, VIEWER_ROLE_HEADER, VIEWER_USER_ID_HEADER, type VerbRule, type ViewerContext, type ViewerContextFailure, type ViewerContextVerification, type ViewerEnv, WORKSPACE_FILE_HOW_TO, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, actorRetiredHook, actorTool, agentFileKeyFromUrl, appFileUrl, appKeyFromCallerKey, applyConfirmationPolicies, approvalHash, approvalPreview, approvalRecipients, archiveOfferRefusal, attendedFindings, base64ToBytes, buildConfirmationPolicy, buildMarketplaceWebhookUrl, buildPartialUpdateBody, bytesToBase64, callerKeyRefusal, canEmit, canLog, canPartialUpdate, checkConfirmationPolicy, commonDestructiveVerbs, connectComplete, connectDisconnect, constantTimeEqual, createMarketplaceEmitter, createToolWrappers, decodeState, defineInboxSendHandler, deleteAppFile, deleteSnapshotIds, deriveConfirmationPolicy, describeMissingBridge, dispatcherApproval, emitMarketplaceEvent, encodeState, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, fullWarning, getAppFile, getCompanyTimezone, hmacSha256Hex, installTokenPost, isNotConnectedError, isStagingHost, listAppFiles, logToPlatform, makeDataClient, manifestIsFresh, offerUndo, openFileRef, overlaySprigr, ownerFromActorKey, parseActor, parseActorRetiredArgs, partialUpdateData, purgeIndexByPrefix, putAppFile, putAppFileStream, randomHex, readFileRef, readableStoredKey, recreatedWarning, refuseWithoutForce, requireApproval, resolveFileRef, resolveInstallBridge, resolveOAuthBouncerBase, resolveOAuthBouncerCallbackUrl, resolvePlatformWebhookBase, resolveViewerContext, resolveViewerUserId, runUndoApply, safeCapture, seq, serializeManifest, set, snapshotIndexIds, tool, undoEnvelope, validateLogEntries, validateLogEntry, verifyViewerToken, withSprigrEmitFallback, withSprigrInboxFallback, withSprigrLogFallback };
|
|
3660
|
+
export { ACTOR_RETIRED_HOOK_TOOL, ACTOR_RETIRE_REASONS, APPROVAL_GRANTED_KEY, APPROVAL_PREVIEW_MAX, APP_FILES_ROOT, APP_OWNER_SEGMENT, type Actor, type ActorRetireReason, type ActorRetired, type ActorRetiredHookBody, type ActorRetiredResult, type AppApprovalEnvelope, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type AppToolEffectsDeclaration, type AppUndoEnvelope, type ApplyPoliciesOptions, type ApprovalCoverage, type ApprovalGateOptions, type ApprovalPreviewFact, type ApprovalPreviewSlot, type ApprovalPreviewSpec, type ApprovalSpec, type ArchiveOfferOptions, type ArchiveOfferRefusal, type CallerKeyResolution, type CaptureJournal, type CompanyTimezoneEnv, type ConfirmCondition, type ConfirmRule, type ConfirmationPolicy, type ConnectCompleteRequest, type ConnectCompleteResult, type D1Like, type D1PreparedStatementLike, DATA_DELETE_MAX_IDS, DATA_PARTIAL_UPDATE_PATH, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_FILE_READ_TIMEOUT_MS, DEFAULT_LOG_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, DEFAULT_MONEY_FIELDS, DEFAULT_WRITE_PREFIXES, type DataClient, type DataIdsOpts, type DataListIdsResult, type DataTransport, type DerivePolicyOptions, type DerivedPolicy, type DispatcherApprovalGate, type DispatcherApprovalOptions, type EmailPreviewInput, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EncodeStateWithinEnvelopeOptions, type EncodedStateWithinEnvelope, type EventArgs, type ExecutionContextLike, FILE_REF_SOURCES_HELP, type FetchFileResult, type FetchWithRetryOptions, type FileRef, type FileRefContent, type FileRefEnv, FileRefError, type FileRefErrorCode, type FileRefStream, type FileRefVia, type GetAppFileResult, type HandlerFn, INBOX_SEND_CONTRACT_V1, type IdPrefixSpec, type IdSnapshot, type InboxAddress, type InboxAppendRequest, type InboxAppendResult, type InboxChannelDeclaration, type InboxFoldersRequest, type InboxFoldersResult, type InboxOwner, type InboxSendConnection, type InboxSendHandlerImpl, InboxSendRefusal, type InboxSendSupports, type InboxSendV1Args, type InboxSendV1Result, type InstallBridge, InvalidUndoEnvelopeError, type JournalRowLike, type LogToPlatformOptions, type ManifestDispatchBlock, type ManifestLike, type ManifestToolLike, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, NotConnectedError, OAUTH_STATE_ENVELOPE_MAX_CHARS, type OAuthBouncerSignals, type OAuthState, type OfferUndoArgs, type PartialUpdateDataOptions, type PlatformHostEnv, type PolicyCheckInput, type PolicySource, type PurgeResult, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type ReadFileRefOptions, type RequireApprovalOptions, type ResolveFileRefOptions, type ResolveViewerOptions, type ResolvedFileRef, type RestoreResult, type RestoreSpec, SPRIGR_DATA_MAX_OBJECTS_PER_CALL, SPRIGR_FILE_HOSTS, SPRIGR_LOG_LEVELS, SPRIGR_LOG_LIMITS, type ScheduleArgs, type SmsPreviewInput, type SprigrDataAggregationCell, type SprigrDataAggregationResult, type SprigrDataAggregationSpec, type SprigrDataApi, type SprigrDataImportOpts, type SprigrDataIndexOpts, type SprigrDataPartialUpdateBody, type SprigrDataPartialUpdateOpts, type SprigrDataPartialUpdateResult, type SprigrDataPatch, type SprigrDataSearchOpts, type SprigrDataSearchResult, SprigrDataValidationError, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type SprigrFilesListItem, type SprigrFilesListResult, type SprigrInboxApi, type SprigrLogEntry, type SprigrLogFn, type SprigrLogLevel, type SprigrLogResult, SprigrLogValidationError, type SyncedAttachment, type SyncedMessage, type ToolArgs, type ToolHandler, type ToolResult, type ToolWrapperOptions, UNIT_SEP, type UndoApplyOptions, type UndoApplyResult, type UndoCaptureSpec, type UndoFidelity, VIEWER_ANONYMOUS, VIEWER_CONTEXT_HEADER, VIEWER_PLATFORM_USER_ID_HEADER, VIEWER_ROLE_HEADER, VIEWER_USER_ID_HEADER, type VerbRule, type ViewerContext, type ViewerContextFailure, type ViewerContextVerification, type ViewerEnv, WORKSPACE_FILE_HOW_TO, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, actorRetiredHook, actorTool, agentFileKeyFromUrl, appFileUrl, appKeyFromCallerKey, applyConfirmationPolicies, approvalHash, approvalPreview, approvalRecipients, archiveOfferRefusal, attendedFindings, base64ToBytes, buildConfirmationPolicy, buildMarketplaceWebhookUrl, buildPartialUpdateBody, bytesToBase64, callerKeyRefusal, canEmit, canLog, canPartialUpdate, checkConfirmationPolicy, commonDestructiveVerbs, connectComplete, connectDisconnect, constantTimeEqual, createMarketplaceEmitter, createToolWrappers, decodeState, defineInboxSendHandler, deleteAppFile, deleteSnapshotIds, deriveConfirmationPolicy, describeMissingBridge, dispatcherApproval, emailPreview, emitMarketplaceEvent, encodeState, encodeStateWithinEnvelope, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, fieldsPreview, fullWarning, getAppFile, getCompanyTimezone, hmacSha256Hex, installTokenPost, isNotConnectedError, isStagingHost, listAppFiles, logToPlatform, makeDataClient, manifestIsFresh, oauthStateEnvelopeOverhead, offerUndo, openFileRef, overlaySprigr, ownerFromActorKey, parseActor, parseActorRetiredArgs, partialUpdateData, purgeIndexByPrefix, putAppFile, putAppFileStream, randomHex, readFileRef, readableStoredKey, recreatedWarning, refuseWithoutForce, requireApproval, resolveFileRef, resolveInstallBridge, resolveOAuthBouncerBase, resolveOAuthBouncerCallbackUrl, resolvePlatformWebhookBase, resolveViewerContext, resolveViewerUserId, runUndoApply, safeCapture, seq, serializeManifest, set, smsPreview, snapshotIndexIds, tool, undoEnvelope, validateLogEntries, validateLogEntry, verifyViewerToken, withSprigrEmitFallback, withSprigrInboxFallback, withSprigrLogFallback };
|
package/dist/index.js
CHANGED
|
@@ -48,6 +48,36 @@ function decodeState(encoded) {
|
|
|
48
48
|
const json = new TextDecoder().decode(bytes);
|
|
49
49
|
return JSON.parse(json);
|
|
50
50
|
}
|
|
51
|
+
var OAUTH_STATE_ENVELOPE_MAX_CHARS = 500;
|
|
52
|
+
function oauthStateEnvelopeOverhead(installId, appSlug, t = Date.now()) {
|
|
53
|
+
const payloadBytes = new TextEncoder().encode(JSON.stringify({ i: installId, a: appSlug, t })).length;
|
|
54
|
+
const payloadChars = Math.ceil(payloadBytes * 4 / 3);
|
|
55
|
+
return "sps1.".length + 1 + payloadChars + 1 + 22;
|
|
56
|
+
}
|
|
57
|
+
function encodeStateWithinEnvelope(state, opts) {
|
|
58
|
+
const budget = OAUTH_STATE_ENVELOPE_MAX_CHARS - oauthStateEnvelopeOverhead(opts.installId, opts.appSlug);
|
|
59
|
+
const full = encodeState(state);
|
|
60
|
+
if (full.length <= budget) return { state: full, omitted: [], fits: true };
|
|
61
|
+
const trimmed = { ...state };
|
|
62
|
+
const omitted = [];
|
|
63
|
+
for (const key of opts.optional ?? ["returnTo"]) {
|
|
64
|
+
if (!(key in trimmed) || trimmed[key] === void 0) continue;
|
|
65
|
+
const value = trimmed[key];
|
|
66
|
+
delete trimmed[key];
|
|
67
|
+
omitted.push(key);
|
|
68
|
+
const candidate = encodeState(trimmed);
|
|
69
|
+
if (candidate.length <= budget) {
|
|
70
|
+
console.warn(
|
|
71
|
+
`[oauth-state] ${opts.appSlug}: left ${omitted.join(", ")} out of the OAuth state so it can be signed (${String(key)} was ${typeof value === "string" ? value.length : JSON.stringify(value).length} chars; state ${full.length} -> ${candidate.length} chars, room ${budget}). The connect lands on the install's dashboard.`
|
|
72
|
+
);
|
|
73
|
+
return { state: candidate, omitted, fits: true };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
console.warn(
|
|
77
|
+
`[oauth-state] ${opts.appSlug}: the OAuth state is ${full.length} chars and only ${budget} fit inside the signed envelope even without its optional fields, so the platform will send it unsigned.`
|
|
78
|
+
);
|
|
79
|
+
return { state: full, omitted: [], fits: false };
|
|
80
|
+
}
|
|
51
81
|
|
|
52
82
|
// src/fetch.ts
|
|
53
83
|
var DEFAULT_OPTS = {
|
|
@@ -1366,6 +1396,34 @@ function approvalPreview(value, max = APPROVAL_PREVIEW_MAX) {
|
|
|
1366
1396
|
return text.length > max ? `${text.slice(0, max)}\u2026` : text;
|
|
1367
1397
|
}
|
|
1368
1398
|
|
|
1399
|
+
// src/write-protection/approval-preview.ts
|
|
1400
|
+
function emailPreview(input) {
|
|
1401
|
+
return {
|
|
1402
|
+
kind: "email",
|
|
1403
|
+
...input.from !== void 0 ? { from: input.from } : {},
|
|
1404
|
+
to: input.to,
|
|
1405
|
+
...input.cc !== void 0 ? { cc: input.cc } : {},
|
|
1406
|
+
...input.bcc !== void 0 ? { bcc: input.bcc } : {},
|
|
1407
|
+
...input.subject !== void 0 ? { subject: input.subject } : {},
|
|
1408
|
+
body: { arg: input.body, format: input.bodyFormat ?? "html" },
|
|
1409
|
+
...input.attachments !== void 0 ? { attachments: input.attachments } : {},
|
|
1410
|
+
...input.sendAt !== void 0 ? { sendAt: input.sendAt } : {},
|
|
1411
|
+
facts: input.facts ?? ["irreversible"]
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
function smsPreview(input) {
|
|
1415
|
+
return {
|
|
1416
|
+
kind: "sms",
|
|
1417
|
+
...input.from !== void 0 ? { from: input.from } : {},
|
|
1418
|
+
to: input.to,
|
|
1419
|
+
body: { arg: input.body, format: "text" },
|
|
1420
|
+
facts: input.facts ?? ["irreversible"]
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1423
|
+
function fieldsPreview(kind, rows, extra = {}) {
|
|
1424
|
+
return { kind, ...extra, fields: rows };
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1369
1427
|
// src/write-protection/undo-envelope.ts
|
|
1370
1428
|
var InvalidUndoEnvelopeError = class extends Error {
|
|
1371
1429
|
constructor(message2) {
|
|
@@ -2229,6 +2287,7 @@ export {
|
|
|
2229
2287
|
InboxSendRefusal,
|
|
2230
2288
|
InvalidUndoEnvelopeError,
|
|
2231
2289
|
NotConnectedError,
|
|
2290
|
+
OAUTH_STATE_ENVELOPE_MAX_CHARS,
|
|
2232
2291
|
SPRIGR_DATA_MAX_OBJECTS_PER_CALL,
|
|
2233
2292
|
SPRIGR_FILE_HOSTS,
|
|
2234
2293
|
SPRIGR_LOG_LEVELS,
|
|
@@ -2277,11 +2336,14 @@ export {
|
|
|
2277
2336
|
deriveConfirmationPolicy,
|
|
2278
2337
|
describeMissingBridge,
|
|
2279
2338
|
dispatcherApproval,
|
|
2339
|
+
emailPreview,
|
|
2280
2340
|
emitMarketplaceEvent,
|
|
2281
2341
|
encodeState,
|
|
2342
|
+
encodeStateWithinEnvelope,
|
|
2282
2343
|
fetchFileAsBase64,
|
|
2283
2344
|
fetchFileBytes,
|
|
2284
2345
|
fetchWithRetry,
|
|
2346
|
+
fieldsPreview,
|
|
2285
2347
|
fullWarning,
|
|
2286
2348
|
getAppFile,
|
|
2287
2349
|
getCompanyTimezone,
|
|
@@ -2293,6 +2355,7 @@ export {
|
|
|
2293
2355
|
logToPlatform,
|
|
2294
2356
|
makeDataClient,
|
|
2295
2357
|
manifestIsFresh,
|
|
2358
|
+
oauthStateEnvelopeOverhead,
|
|
2296
2359
|
offerUndo,
|
|
2297
2360
|
openFileRef,
|
|
2298
2361
|
overlaySprigr,
|
|
@@ -2321,6 +2384,7 @@ export {
|
|
|
2321
2384
|
seq,
|
|
2322
2385
|
serializeManifest,
|
|
2323
2386
|
set,
|
|
2387
|
+
smsPreview,
|
|
2324
2388
|
snapshotIndexIds,
|
|
2325
2389
|
tool,
|
|
2326
2390
|
undoEnvelope,
|