@sprigr/apps-app-sdk 0.18.0 → 0.19.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
@@ -15,7 +15,7 @@ The runtime injects the `env.SPRIGR` host object **only on `/__sprigr/*` dispatc
15
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`.
16
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).
17
17
  - `logToPlatform(env, entry | entry[], opts?)`: durable app logging from either context (`env.SPRIGR.log` on dispatch, `POST ${SPRIGR_PLATFORM_BASE}/internal/wfp/log` from an inline route). Rows land in the platform's `system_logs` Analytics Engine dataset (90-day retention, scoped to the install's company, category prefixed with the app slug), so use it instead of a per-webhook or per-tick audit row in your D1: D1 bills every row written, AE does not. Validation throws synchronously on a cap violation (summary 256, detail 4096, metadata JSON 3840, category 64 matching `[A-Za-z0-9._:-]`, 50 entries per call; nothing is ever truncated); after that the promise never rejects and resolves `{ ok: true, written }` or `{ ok: false, error, status?, detail? }`. Pass `{ waitUntil: ctx.waitUntil.bind(ctx) }` on an inline route so the send outlives the response. `withSprigrLogFallback(env, opts?)` installs `env.SPRIGR.log` once for many call sites; `canLog(env)` gates work whose only purpose is a log row; the `SprigrLogEntry` / `SprigrLogFn` types let your env interface declare the host member.
18
- - `partialUpdateData(env, objects, opts?)`: merge fields into objects already in the app's data index without reading them first (`env.SPRIGR.data.partialUpdate` on dispatch, `POST ${SPRIGR_PLATFORM_BASE}/internal/wfp/data/partial-update` from an inline route). Deep merge: nested objects recurse, arrays and scalars replace wholesale, absent keys survive, `null` overwrites. `createIfNotExists` defaults to `false`; on a sharded logical index every patch must carry the `shard_field` value or the batch fails with `shard_field_invalid`; 1000 objects per call like `import`. Throws on a bad batch before sending (`SprigrDataValidationError`) and on a platform rejection (`.status`, `.error`, `.detail` on the `Error`), the same contract as `import`. `canPartialUpdate(env)` gates a patch step on either transport; the `SprigrDataPartialUpdateOpts` / `SprigrDataPartialUpdateResult` types let your env interface declare the host member.
18
+ - `partialUpdateData(env, objects, opts?)`: merge fields into objects already in the app's data index without reading them first (`env.SPRIGR.data.partialUpdate` on dispatch, `POST ${SPRIGR_PLATFORM_BASE}/internal/wfp/data/partial-update` from an inline route). Deep merge: nested objects recurse, arrays and scalars replace wholesale, absent keys survive, `null` overwrites. `createIfNotExists` defaults to `false`; on a sharded logical index every patch must carry the `shard_field` value or the batch fails with `shard_field_invalid`; 1000 objects per call like `import`. Throws on a bad batch before sending (`SprigrDataValidationError`) and on a platform rejection (`.status`, `.error`, `.detail` on the `Error`), the same contract as `import`. With `{ withAcl: true }` it patches existing rows of the app's `-acl-files` index: each object carries `objectID` plus `acl_principals` and/or label fields the manifest declares in `data_index.acl_patchable_fields` (never `content`), and an object that omits `acl_principals` keeps its stored ones. `canPartialUpdate(env)` gates a patch step on either transport; the `SprigrDataPartialUpdateOpts` / `SprigrDataPartialUpdateResult` types let your env interface declare the host member.
19
19
  - `resolveInstallBridge(env)` / `installTokenPost(bridge, path, body, opts?)`: build your own `/internal/wfp/*` fallback (collections, files, inbox) with the auth and error extraction handled. A non-2xx throws an `Error` whose `.status`, `.error` (the platform's code) and `.detail` are set alongside the message.
20
20
  - `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`.
21
21
 
package/dist/index.d.ts CHANGED
@@ -2763,14 +2763,20 @@ interface SprigrDataPartialUpdateOpts extends SprigrDataIndexOpts {
2763
2763
  */
2764
2764
  createIfNotExists?: boolean;
2765
2765
  /**
2766
- * Re-stamp `acl_principals` on rows already in the app's `-acl-files`
2767
- * index without rewriting the rest of each row. Every object must be
2768
- * exactly `{ objectID, acl_principals }` with a non-empty, valid principal
2769
- * list; `createIfNotExists` and `index` are refused alongside it. Use it
2770
- * when the source changes who may see an item without reporting the item
2771
- * as changed (OneDrive's delta omits sharing-only changes). Needs a
2772
- * platform with sprigr/sprigr-team#9843; older wrappers drop the flag,
2773
- * which `partialUpdateData` detects and throws on.
2766
+ * Patch rows already in the app's `-acl-files` index without rewriting
2767
+ * the rest of each row. Each object carries `objectID` plus
2768
+ * `acl_principals` (a non-empty, valid list: re-stamps who may see it)
2769
+ * and/or label fields the manifest declares in
2770
+ * `data_index.acl_patchable_fields` (for example `tags`, `properties`).
2771
+ * An object that omits `acl_principals` keeps its stored ones. `content`
2772
+ * is never patchable, and `createIfNotExists` and `index` are refused. Use
2773
+ * it when the source changes who may see an item, or only its labels,
2774
+ * without changing its content (OneDrive's delta omits sharing-only
2775
+ * changes; a Dropbox tag edit leaves the file's text as it was). The
2776
+ * re-stamp needs a platform with sprigr/sprigr-team#9843, label fields one
2777
+ * with #10371 (an older one answers `acl_partial_update_fields`: fall back
2778
+ * to a whole-row import). Older wrappers drop the flag, which
2779
+ * `partialUpdateData` detects and throws on.
2774
2780
  */
2775
2781
  withAcl?: boolean;
2776
2782
  }
package/dist/index.js CHANGED
@@ -580,19 +580,26 @@ function checkAclRestamp(objects, opts, at) {
580
580
  }
581
581
  for (let i = 0; i < objects.length; i++) {
582
582
  const o = objects[i];
583
- const extra = Object.keys(o).find((k) => k !== "objectID" && k !== "acl_principals");
584
- if (extra !== void 0) {
583
+ if ("content" in o) {
585
584
  throw new SprigrDataValidationError(
586
- `${at}: objects[${i}] carries "${extra}"; a withAcl partial update sets only objectID and acl_principals (write content with data.import withAcl)`,
585
+ `${at}: objects[${i}] carries "content"; a withAcl partial update never writes extracted text (write content with data.import withAcl)`,
587
586
  { error: "acl_partial_update_fields", index: i }
588
587
  );
589
588
  }
590
- const principals = o.acl_principals;
591
- if (!Array.isArray(principals) || principals.length === 0) {
592
- throw new SprigrDataValidationError(`${at}: objects[${i}] needs a non-empty acl_principals: string[]`, {
593
- error: "missing_acl_principals",
594
- index: i
595
- });
589
+ if (!Object.keys(o).some((k) => k !== "objectID")) {
590
+ throw new SprigrDataValidationError(
591
+ `${at}: objects[${i}] sets nothing; send acl_principals or a field your manifest declares in data_index.acl_patchable_fields`,
592
+ { error: "acl_partial_update_empty", index: i }
593
+ );
594
+ }
595
+ if ("acl_principals" in o) {
596
+ const principals = o.acl_principals;
597
+ if (!Array.isArray(principals) || principals.length === 0) {
598
+ throw new SprigrDataValidationError(`${at}: objects[${i}] needs a non-empty acl_principals: string[]`, {
599
+ error: "missing_acl_principals",
600
+ index: i
601
+ });
602
+ }
596
603
  }
597
604
  }
598
605
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprigr/apps-app-sdk",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",