@sprigr/apps-app-sdk 0.13.0 → 0.14.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/dist/index.d.ts +24 -2
- package/dist/index.js +45 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -669,6 +669,12 @@ declare function withSprigrLogFallback<E extends WfpBridgeEnv & object>(env: E,
|
|
|
669
669
|
* fails with `shard_field_invalid`: a patch cannot be routed to its shard
|
|
670
670
|
* otherwise. The per-call cap is the same 1000 objects as `import`.
|
|
671
671
|
*
|
|
672
|
+
* `withAcl: true` is a narrower mode: it re-stamps `acl_principals` on rows
|
|
673
|
+
* already in the app's `-acl-files` index and nothing else. Every patch must
|
|
674
|
+
* be exactly `{ objectID, acl_principals }`, and `createIfNotExists` and
|
|
675
|
+
* `index` cannot be combined with it. Content is written only by an ACL
|
|
676
|
+
* `import`, whole.
|
|
677
|
+
*
|
|
672
678
|
* This module carries two things:
|
|
673
679
|
*
|
|
674
680
|
* 1. `buildPartialUpdateBody`, the wire body both transports send, with
|
|
@@ -687,10 +693,13 @@ declare function withSprigrLogFallback<E extends WfpBridgeEnv & object>(env: E,
|
|
|
687
693
|
* swallow.
|
|
688
694
|
*
|
|
689
695
|
* Wire contract (workers/provisioning/src/wfp-data.ts in sprigr-team):
|
|
690
|
-
* POST { index?, objects, createIfNotExists? }
|
|
696
|
+
* POST { index?, objects, createIfNotExists?, withAcl? }
|
|
691
697
|
* 200 { ok: true, updated, skippedMissing, index, physical_indexes? }
|
|
692
698
|
* 400 { error, detail, index? } with error one of too_many_objects,
|
|
693
|
-
* invalid_object, unknown_data_index, shard_field_invalid,
|
|
699
|
+
* invalid_object, unknown_data_index, shard_field_invalid,
|
|
700
|
+
* acl_partial_update_fields, acl_partial_update_create_unsupported,
|
|
701
|
+
* acl_index_combination_unsupported, missing_acl_principals,
|
|
702
|
+
* invalid_acl_principal, ...
|
|
694
703
|
* 401 / 404 bad token / inactive install
|
|
695
704
|
*/
|
|
696
705
|
|
|
@@ -708,6 +717,8 @@ interface SprigrDataPartialUpdateBody {
|
|
|
708
717
|
index?: string;
|
|
709
718
|
objects: SprigrDataPatch[];
|
|
710
719
|
createIfNotExists: boolean;
|
|
720
|
+
/** Present (and true) only for an ACL re-stamp. */
|
|
721
|
+
withAcl?: true;
|
|
711
722
|
}
|
|
712
723
|
interface PartialUpdateDataOptions extends SprigrDataPartialUpdateOpts {
|
|
713
724
|
/** Ceiling on the HTTP fallback. No default: a data write is awaited for its result. */
|
|
@@ -2244,6 +2255,17 @@ interface SprigrDataPartialUpdateOpts extends SprigrDataIndexOpts {
|
|
|
2244
2255
|
* missing target is counted in `skippedMissing` instead of being written.
|
|
2245
2256
|
*/
|
|
2246
2257
|
createIfNotExists?: boolean;
|
|
2258
|
+
/**
|
|
2259
|
+
* Re-stamp `acl_principals` on rows already in the app's `-acl-files`
|
|
2260
|
+
* index without rewriting the rest of each row. Every object must be
|
|
2261
|
+
* exactly `{ objectID, acl_principals }` with a non-empty, valid principal
|
|
2262
|
+
* list; `createIfNotExists` and `index` are refused alongside it. Use it
|
|
2263
|
+
* when the source changes who may see an item without reporting the item
|
|
2264
|
+
* as changed (OneDrive's delta omits sharing-only changes). Needs a
|
|
2265
|
+
* platform with sprigr/sprigr-team#9843; older wrappers drop the flag,
|
|
2266
|
+
* which `partialUpdateData` detects and throws on.
|
|
2267
|
+
*/
|
|
2268
|
+
withAcl?: boolean;
|
|
2247
2269
|
}
|
|
2248
2270
|
/** Reply of `env.SPRIGR.data.partialUpdate` (`POST /internal/wfp/data/partial-update`). */
|
|
2249
2271
|
interface SprigrDataPartialUpdateResult {
|
package/dist/index.js
CHANGED
|
@@ -512,6 +512,7 @@ function withSprigrLogFallback(env, opts) {
|
|
|
512
512
|
// src/platform-data.ts
|
|
513
513
|
var DATA_PARTIAL_UPDATE_PATH = "/internal/wfp/data/partial-update";
|
|
514
514
|
var SPRIGR_DATA_MAX_OBJECTS_PER_CALL = 1e3;
|
|
515
|
+
var ACL_INDEX_SUFFIX = "-acl-files";
|
|
515
516
|
var SprigrDataValidationError = class extends Error {
|
|
516
517
|
error;
|
|
517
518
|
index;
|
|
@@ -556,12 +557,51 @@ function buildPartialUpdateBody(objects, opts) {
|
|
|
556
557
|
error: "unknown_data_index"
|
|
557
558
|
});
|
|
558
559
|
}
|
|
560
|
+
const withAcl = opts?.withAcl === true;
|
|
561
|
+
if (withAcl) checkAclRestamp(objects, opts, at);
|
|
559
562
|
return {
|
|
560
563
|
...opts?.index !== void 0 ? { index: opts.index } : {},
|
|
561
564
|
objects,
|
|
562
|
-
createIfNotExists: opts?.createIfNotExists === true
|
|
565
|
+
createIfNotExists: opts?.createIfNotExists === true,
|
|
566
|
+
...withAcl ? { withAcl: true } : {}
|
|
563
567
|
};
|
|
564
568
|
}
|
|
569
|
+
function checkAclRestamp(objects, opts, at) {
|
|
570
|
+
if (opts?.createIfNotExists === true) {
|
|
571
|
+
throw new SprigrDataValidationError(
|
|
572
|
+
`${at}: withAcl only re-stamps existing rows; createIfNotExists would create a row with principals and no content`,
|
|
573
|
+
{ error: "acl_partial_update_create_unsupported" }
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
if (opts?.index !== void 0) {
|
|
577
|
+
throw new SprigrDataValidationError(`${at}: withAcl targets the reserved -acl-files index and cannot be combined with index`, {
|
|
578
|
+
error: "acl_index_combination_unsupported"
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
for (let i = 0; i < objects.length; i++) {
|
|
582
|
+
const o = objects[i];
|
|
583
|
+
const extra = Object.keys(o).find((k) => k !== "objectID" && k !== "acl_principals");
|
|
584
|
+
if (extra !== void 0) {
|
|
585
|
+
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)`,
|
|
587
|
+
{ error: "acl_partial_update_fields", index: i }
|
|
588
|
+
);
|
|
589
|
+
}
|
|
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
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function assertAclIndex(result) {
|
|
600
|
+
if (typeof result?.index === "string" && result.index.endsWith(ACL_INDEX_SUFFIX)) return result;
|
|
601
|
+
throw new Error(
|
|
602
|
+
`data.partialUpdate withAcl landed on ${String(result?.index)}, not the ${ACL_INDEX_SUFFIX} index: this app was built by a platform wrapper that drops withAcl. Republish the app to pick up the current wrapper.`
|
|
603
|
+
);
|
|
604
|
+
}
|
|
565
605
|
function bindingPartialUpdate(env) {
|
|
566
606
|
const data = env.SPRIGR?.data;
|
|
567
607
|
return typeof data?.partialUpdate === "function" ? data.partialUpdate.bind(data) : null;
|
|
@@ -579,10 +619,12 @@ async function partialUpdateData(env, objects, opts) {
|
|
|
579
619
|
const body = buildPartialUpdateBody(objects, dataOpts);
|
|
580
620
|
const injected = bindingPartialUpdate(env);
|
|
581
621
|
if (injected) {
|
|
582
|
-
|
|
622
|
+
const result = await injected(body.objects, {
|
|
583
623
|
...body.index !== void 0 ? { index: body.index } : {},
|
|
584
|
-
createIfNotExists: body.createIfNotExists
|
|
624
|
+
createIfNotExists: body.createIfNotExists,
|
|
625
|
+
...body.withAcl ? { withAcl: true } : {}
|
|
585
626
|
});
|
|
627
|
+
return body.withAcl ? assertAclIndex(result) : result;
|
|
586
628
|
}
|
|
587
629
|
const bridge = resolveInstallBridge(env);
|
|
588
630
|
if (!bridge) {
|