@sprigr/apps-app-sdk 0.2.0 → 0.3.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 CHANGED
@@ -11,6 +11,8 @@ npm install @sprigr/apps-app-sdk
11
11
  The runtime injects the `env.SPRIGR` host object **only on `/__sprigr/*` dispatch paths** (tool, schedule, event and platform-webhook handlers). Inline Next.js route handlers never get it, so an app that receives its provider webhook on an inline route has no working `env.SPRIGR` on the path that matters most.
12
12
 
13
13
  - `emitMarketplaceEvent(env, event, payload, opts?)` — emit from either context. Uses the injected binding when present, the install-token bridge (`POST ${SPRIGR_PLATFORM_BASE}/internal/wfp/emit`) otherwise. Never throws, so a webhook ack is never at risk; times out after 5s. Returns `{ emitted, via: 'binding' | 'http' | 'none', eventId?, error? }` — record `via` in your audit row.
14
+ - `createMarketplaceEmitter(integrationType, defaults?)` — pre-bind an app's integration type so call sites pass only what varies; `sourceIntegration` is built per call from `env.INSTALL_ID`.
15
+ - `canEmit(env)` — whether an emit could reach the platform by either transport. Gate work that only exists to feed an emit on this, not on `env.SPRIGR?.emit`.
14
16
  - `withSprigrEmitFallback(env)` — repair `env.SPRIGR.emit` once and leave existing call sites untouched. Matches the host object's contract (resolves `{ ok, eventId, queued }`, throws on non-2xx).
15
17
  - `resolveInstallBridge(env)` / `installTokenPost(bridge, path, body, opts?)` — build your own `/internal/wfp/*` fallback (collections, files, inbox) with the auth and error extraction handled.
16
18
  - `overlaySprigr(env, sprigr)` — overlay a patched `SPRIGR` via `Object.create`. Never rebuild a dispatch-path env by spread: the real bindings live on the prototype and `SPRIGR` is non-enumerable, so `{ ...env }` yields an env whose `DB` is `undefined`.
package/dist/index.d.ts CHANGED
@@ -364,6 +364,26 @@ declare function installTokenPost(bridge: InstallBridge, path: string, body: unk
364
364
  * await audit(env, 'emit', JSON.stringify(r)); // records `via`
365
365
  */
366
366
  declare function emitMarketplaceEvent(env: WfpBridgeEnv, event: string, payload: unknown, opts?: EmitMarketplaceEventOptions): Promise<EmitResult>;
367
+ /**
368
+ * Whether an emit could reach the platform at all, by either transport.
369
+ *
370
+ * Use it to skip work whose only purpose is to feed an emit. Gate on this
371
+ * rather than on `env.SPRIGR?.emit`: the binding is absent on every inline
372
+ * route, so the narrower check skips the work in exactly the context where the
373
+ * HTTP bridge would have carried it.
374
+ */
375
+ declare function canEmit(env: WfpBridgeEnv): boolean;
376
+ /**
377
+ * Pre-bind an app's `integrationType` so call sites pass only what varies.
378
+ * `sourceIntegration` is built per call from `env.INSTALL_ID`, and omitted
379
+ * entirely when that is unbound (the platform 400s on a partial one).
380
+ *
381
+ * const emit = createMarketplaceEmitter('procore');
382
+ * const r = await emit(env, 'procore.rfi.updated', payload);
383
+ */
384
+ declare function createMarketplaceEmitter<E extends WfpBridgeEnv = WfpBridgeEnv>(integrationType: string, defaults?: {
385
+ timeoutMs?: number;
386
+ }): (env: E, eventName: string, payload: unknown) => Promise<EmitResult>;
367
387
  /**
368
388
  * Return an env whose `SPRIGR.emit` works even on an inline route, leaving
369
389
  * existing `env.SPRIGR.emit(...)` call sites untouched. Use this when an app
@@ -853,4 +873,4 @@ interface ExecutionContextLike {
853
873
  }
854
874
  type HandlerFn<TArgs, TResult> = (args: TArgs, env: Record<string, unknown>, ctx?: ExecutionContextLike) => Promise<TResult>;
855
875
 
856
- export { type Actor, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type D1Like, type D1PreparedStatementLike, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EventArgs, type ExecutionContextLike, type FetchFileResult, type FetchWithRetryOptions, type GetAppFileResult, type HandlerFn, type InstallBridge, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, type OAuthState, type PlatformHostEnv, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type ScheduleArgs, type SprigrDataApi, type SprigrDataSearchOpts, type SprigrDataSearchResult, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, appFileUrl, base64ToBytes, buildMarketplaceWebhookUrl, bytesToBase64, constantTimeEqual, decodeState, deleteAppFile, describeMissingBridge, emitMarketplaceEvent, encodeState, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, getAppFile, hmacSha256Hex, installTokenPost, listAppFiles, overlaySprigr, parseActor, putAppFile, putAppFileStream, randomHex, resolveInstallBridge, resolvePlatformWebhookBase, withSprigrEmitFallback };
876
+ export { type Actor, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type D1Like, type D1PreparedStatementLike, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EventArgs, type ExecutionContextLike, type FetchFileResult, type FetchWithRetryOptions, type GetAppFileResult, type HandlerFn, type InstallBridge, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, type OAuthState, type PlatformHostEnv, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type ScheduleArgs, type SprigrDataApi, type SprigrDataSearchOpts, type SprigrDataSearchResult, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, appFileUrl, base64ToBytes, buildMarketplaceWebhookUrl, bytesToBase64, canEmit, constantTimeEqual, createMarketplaceEmitter, decodeState, deleteAppFile, describeMissingBridge, emitMarketplaceEvent, encodeState, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, getAppFile, hmacSha256Hex, installTokenPost, listAppFiles, overlaySprigr, parseActor, putAppFile, putAppFileStream, randomHex, resolveInstallBridge, resolvePlatformWebhookBase, withSprigrEmitFallback };
package/dist/index.js CHANGED
@@ -262,6 +262,18 @@ async function emitMarketplaceEvent(env, event, payload, opts) {
262
262
  return { emitted: false, via: "http", error: err instanceof Error ? err.message : String(err) };
263
263
  }
264
264
  }
265
+ function canEmit(env) {
266
+ return bindingEmit(env) !== null || resolveInstallBridge(env) !== null;
267
+ }
268
+ function createMarketplaceEmitter(integrationType, defaults = {}) {
269
+ return (env, eventName, payload) => {
270
+ const installId = typeof env.INSTALL_ID === "string" ? env.INSTALL_ID : "";
271
+ return emitMarketplaceEvent(env, eventName, payload, {
272
+ ...defaults,
273
+ ...installId ? { sourceIntegration: { integrationId: installId, integrationType } } : {}
274
+ });
275
+ };
276
+ }
265
277
  function withSprigrEmitFallback(env) {
266
278
  if (bindingEmit(env)) return env;
267
279
  const bridge = resolveInstallBridge(env);
@@ -391,7 +403,9 @@ export {
391
403
  base64ToBytes,
392
404
  buildMarketplaceWebhookUrl,
393
405
  bytesToBase64,
406
+ canEmit,
394
407
  constantTimeEqual,
408
+ createMarketplaceEmitter,
395
409
  decodeState,
396
410
  deleteAppFile,
397
411
  describeMissingBridge,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprigr/apps-app-sdk",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",