@valbuild/shared 0.145.1 → 0.146.2
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/CHANGELOG.md +46 -0
- package/dist/declarations/src/internal/ApiRoutes.d.ts +130 -273
- package/dist/declarations/src/internal/chainHead.d.ts +5 -7
- package/dist/declarations/src/internal/index.d.ts +4 -0
- package/dist/declarations/src/internal/patchSets/PatchSets.d.ts +75 -0
- package/dist/declarations/src/internal/patchSets/schemaTypesOfPath.d.ts +5 -0
- package/dist/declarations/src/internal/patchSets/selectionClosure.d.ts +23 -0
- package/dist/declarations/src/internal/proposalMerge/trees.d.ts +56 -0
- package/dist/declarations/src/internal/publish/contentApi.d.ts +10 -4
- package/dist/declarations/src/internal/resolveSchemaSourceFixes.d.ts +3 -2
- package/dist/declarations/src/internal/server/requestScopedMemo.d.ts +10 -8
- package/dist/declarations/src/internal/server/types.d.ts +3 -3
- package/dist/declarations/src/internal/zod/History.d.ts +5 -5
- package/dist/declarations/src/internal/zod/Patch.d.ts +0 -1
- package/dist/declarations/src/internal/zod/SerializedSchema.d.ts +1 -1
- package/internal/dist/valbuild-shared-internal.cjs.dev.js +770 -274
- package/internal/dist/valbuild-shared-internal.cjs.prod.js +770 -274
- package/internal/dist/valbuild-shared-internal.esm.js +763 -274
- package/package.json +2 -2
|
@@ -761,14 +761,16 @@ var VAL_ENABLE_COOKIE_NAME = Internal.VAL_ENABLE_COOKIE_NAME;
|
|
|
761
761
|
* byte-identical each time, because the query and the session are fixed for the
|
|
762
762
|
* length of a request. This is what makes the second and third call free.
|
|
763
763
|
*
|
|
764
|
-
* ## Why the scope is the REQUEST
|
|
764
|
+
* ## Why the scope is the REQUEST
|
|
765
765
|
*
|
|
766
|
-
* The memoised response is
|
|
767
|
-
*
|
|
768
|
-
*
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
766
|
+
* The memoised response is a DRAFT -- unpublished work, read with the caller's
|
|
767
|
+
* session cookie. Every caller allowed to read drafts gets the same draft (patch
|
|
768
|
+
* groups, which made it per author, are gone), but whether a caller is allowed
|
|
769
|
+
* at all is decided per session. A memo that outlived the request would hand
|
|
770
|
+
* the draft to the next visitor without asking, and it would be invisible: the
|
|
771
|
+
* page would simply render somebody's half-finished sentence. Sharing it across
|
|
772
|
+
* requests is possible now, keyed on the chain's head, and would be its own
|
|
773
|
+
* measured change.
|
|
772
774
|
*
|
|
773
775
|
* So this module holds NO state of its own. The caller supplies the box, and
|
|
774
776
|
* the box has to come from something the framework already scopes to the
|
|
@@ -1609,7 +1611,7 @@ var ValConfig = z.object({
|
|
|
1609
1611
|
gitCommit: z.string().optional(),
|
|
1610
1612
|
gitBranch: z.string().optional()
|
|
1611
1613
|
});
|
|
1612
|
-
var ValidationFixZ = z.union([z.literal("image:add-metadata"), z.literal("image:check-metadata"), z.literal("image:check-remote"), z.literal("image:upload-remote"), z.literal("image:download-remote"), z.literal("images:check-remote"), z.literal("images:upload-remote"), z.literal("file:add-metadata"), z.literal("video:add-metadata"), z.literal("video:upload-remote"), z.literal("video:download-remote"), z.literal("videos:add-metadata"), z.literal("videos:check-remote"), z.literal("videos:upload-remote"), z.literal("file:check-metadata"), z.literal("file:check-remote"), z.literal("file:upload-remote"), z.literal("file:download-remote"), z.literal("files:check-remote"), z.literal("files:upload-remote"), z.literal("keyof:check-keys"), z.literal("router:check-route"), z.literal("locale:check-locale"), z.literal("record:fill-keys"), z.literal("images:check-unique-folder"), z.literal("files:check-unique-folder"), z.literal("images:check-all-files"), z.literal("files:check-all-files"), z.literal("videos:check-unique-folder"), z.literal("videos:check-all-files"), z.literal("jsonValues:extract-entry"), z.literal("view:check-module")]);
|
|
1614
|
+
var ValidationFixZ = z.union([z.literal("image:add-metadata"), z.literal("image:check-metadata"), z.literal("image:check-remote"), z.literal("image:upload-remote"), z.literal("image:download-remote"), z.literal("images:check-remote"), z.literal("images:upload-remote"), z.literal("file:add-metadata"), z.literal("video:add-metadata"), z.literal("video:upload-remote"), z.literal("video:download-remote"), z.literal("videos:add-metadata"), z.literal("videos:check-remote"), z.literal("videos:upload-remote"), z.literal("file:check-metadata"), z.literal("file:check-remote"), z.literal("file:upload-remote"), z.literal("file:download-remote"), z.literal("files:check-remote"), z.literal("files:upload-remote"), z.literal("keyof:check-keys"), z.literal("image:check-gallery"), z.literal("file:check-gallery"), z.literal("video:check-gallery"), z.literal("router:check-route"), z.literal("locale:check-locale"), z.literal("record:fill-keys"), z.literal("images:check-unique-folder"), z.literal("files:check-unique-folder"), z.literal("images:check-all-files"), z.literal("files:check-all-files"), z.literal("videos:check-unique-folder"), z.literal("videos:check-all-files"), z.literal("jsonValues:extract-entry"), z.literal("view:check-module")]);
|
|
1613
1615
|
var ValidationError = z.object({
|
|
1614
1616
|
message: z.string(),
|
|
1615
1617
|
value: z.unknown().optional(),
|
|
@@ -1726,21 +1728,6 @@ var StatProposal = z.object({
|
|
|
1726
1728
|
/** `val/p/<name>`. */
|
|
1727
1729
|
branch: z.string()
|
|
1728
1730
|
});
|
|
1729
|
-
|
|
1730
|
-
/**
|
|
1731
|
-
* A patch group: the set of patches one user has chosen to publish.
|
|
1732
|
-
*
|
|
1733
|
-
* Not a patch *set* — a patch set is computed from the schema and says which
|
|
1734
|
-
* patches must move together; a patch group is curated and says which ones this
|
|
1735
|
-
* user wants live. See `docs/independent-publish/PLAN.md`.
|
|
1736
|
-
*/
|
|
1737
|
-
var PatchGroup = z.object({
|
|
1738
|
-
patchGroupId: z.string(),
|
|
1739
|
-
authorId: z.string().nullable(),
|
|
1740
|
-
createdAt: z.string(),
|
|
1741
|
-
publishedAt: z.string().nullable(),
|
|
1742
|
-
patchIds: z.array(PatchId)
|
|
1743
|
-
});
|
|
1744
1731
|
var GenericPatchError = z.union([z.object({
|
|
1745
1732
|
patchId: PatchId,
|
|
1746
1733
|
message: z.string(),
|
|
@@ -2249,14 +2236,6 @@ var Api = {
|
|
|
2249
2236
|
* highest version. Optional, for the same reason `headPatchId` is.
|
|
2250
2237
|
*/
|
|
2251
2238
|
headVersion: z.number().optional(),
|
|
2252
|
-
/**
|
|
2253
|
-
* Every group on the branch and which listed patches it holds,
|
|
2254
|
-
* read with the list and `headVersion`. What a Studio's view of
|
|
2255
|
-
* the groups is taken from, so a stage or an unstage made in
|
|
2256
|
-
* another browser reaches it with the next stat. Absent where
|
|
2257
|
-
* the content service has no groups.
|
|
2258
|
-
*/
|
|
2259
|
-
patchGroups: z.array(PatchGroup).optional(),
|
|
2260
2239
|
commits: z.array(ValCommit),
|
|
2261
2240
|
/**
|
|
2262
2241
|
* The publishes the content service knows about.
|
|
@@ -2553,24 +2532,6 @@ var Api = {
|
|
|
2553
2532
|
id: z.array(PatchId).min(1, "At least one patch id is required")
|
|
2554
2533
|
},
|
|
2555
2534
|
body: z.object({
|
|
2556
|
-
/*
|
|
2557
|
-
* Patches that are NOT being deleted but must lose their patch
|
|
2558
|
-
* group membership because these are.
|
|
2559
|
-
*
|
|
2560
|
-
* Deleting a patch out of the middle of a patch set leaves every
|
|
2561
|
-
* group holding the rest with a non-prefix intersection, and a
|
|
2562
|
-
* prefix is the one invariant a group has. Which patches those are
|
|
2563
|
-
* needs the content schema, so the client computes the forward
|
|
2564
|
-
* closure and sends it; the content API drops the memberships
|
|
2565
|
-
* without touching the patches.
|
|
2566
|
-
*
|
|
2567
|
-
* In the BODY while the ids to delete are in the query, because
|
|
2568
|
-
* this list is unbounded in the same way and the query string is
|
|
2569
|
-
* already chunked to fit. Optional throughout: `fs` mode has no
|
|
2570
|
-
* groups, and a client that predates this is deleting correctly,
|
|
2571
|
-
* just not repairing.
|
|
2572
|
-
*/
|
|
2573
|
-
unstagePatchIds: z.array(PatchId).optional(),
|
|
2574
2535
|
/*
|
|
2575
2536
|
* Answer with `{ deleted, headVersion }` rather than the bare id
|
|
2576
2537
|
* array. Asked for rather than always sent, because the array is
|
|
@@ -2612,16 +2573,7 @@ var Api = {
|
|
|
2612
2573
|
path: ModuleFilePath,
|
|
2613
2574
|
patchId: PatchId,
|
|
2614
2575
|
patch: z.any() // TODO: this should be Patch instead - we got a weird validation error: although input looks good, it still does not accept objects as values... Which it should do via the z.record(JSONValue) type
|
|
2615
|
-
}))
|
|
2616
|
-
// Patch group membership. Sent with the patch itself, in one request, so
|
|
2617
|
-
// there is no window in which a patch exists but belongs to no group.
|
|
2618
|
-
// Absent means "the caller does not know about groups" - the server then
|
|
2619
|
-
// behaves exactly as before.
|
|
2620
|
-
patchGroupId: z.string().nullish(),
|
|
2621
|
-
// What has to come with the patch: other patch ids that must join the
|
|
2622
|
-
// same group for it to stay applicable. Computed on the client, which
|
|
2623
|
-
// is the only side that has the schema needed to derive patch sets.
|
|
2624
|
-
withPatchIds: z.array(PatchId).optional()
|
|
2576
|
+
}))
|
|
2625
2577
|
}),
|
|
2626
2578
|
cookies: {
|
|
2627
2579
|
val_session: z.string().optional()
|
|
@@ -2663,7 +2615,6 @@ var Api = {
|
|
|
2663
2615
|
error: PlanRefusalError,
|
|
2664
2616
|
newPatchIds: z.array(PatchId),
|
|
2665
2617
|
parentRef: ParentRef,
|
|
2666
|
-
patchGroupId: z.string().optional(),
|
|
2667
2618
|
headVersion: z.number().optional()
|
|
2668
2619
|
})
|
|
2669
2620
|
}), z.object({
|
|
@@ -2671,7 +2622,6 @@ var Api = {
|
|
|
2671
2622
|
json: z.object({
|
|
2672
2623
|
newPatchIds: z.array(PatchId),
|
|
2673
2624
|
parentRef: ParentRef,
|
|
2674
|
-
patchGroupId: z.string().optional(),
|
|
2675
2625
|
/**
|
|
2676
2626
|
* The chain version the last of these patches made, comparable with
|
|
2677
2627
|
* `headVersion` on `/stat`. A client keeps the highest version, so a
|
|
@@ -2686,16 +2636,7 @@ var Api = {
|
|
|
2686
2636
|
req: {
|
|
2687
2637
|
query: {
|
|
2688
2638
|
patch_id: z.array(PatchId).optional(),
|
|
2689
|
-
exclude_patch_ops: onlyOneBooleanQueryParam.optional()
|
|
2690
|
-
/**
|
|
2691
|
-
* Include the patch group annotation in the answer.
|
|
2692
|
-
*
|
|
2693
|
-
* Off by default because the client CHUNKS this request — a long
|
|
2694
|
-
* chain is several round trips — and the groups are a property of the
|
|
2695
|
-
* branch, identical in every chunk. Asking on each one is N identical
|
|
2696
|
-
* lookups against the content API to learn the same thing.
|
|
2697
|
-
*/
|
|
2698
|
-
include_patch_groups: onlyOneBooleanQueryParam.optional()
|
|
2639
|
+
exclude_patch_ops: onlyOneBooleanQueryParam.optional()
|
|
2699
2640
|
},
|
|
2700
2641
|
cookies: {
|
|
2701
2642
|
val_session: z.string().optional()
|
|
@@ -2724,12 +2665,8 @@ var Api = {
|
|
|
2724
2665
|
authorId: z.string().nullable(),
|
|
2725
2666
|
appliedAt: z.object({
|
|
2726
2667
|
commitSha: z.string()
|
|
2727
|
-
}).nullable()
|
|
2728
|
-
// Which patch groups hold this patch. Optional so that FS mode, and
|
|
2729
|
-
// any server that predates patch groups, can leave it out.
|
|
2730
|
-
patchGroupIds: z.array(z.string()).optional()
|
|
2668
|
+
}).nullable()
|
|
2731
2669
|
})),
|
|
2732
|
-
patchGroups: z.array(PatchGroup).optional(),
|
|
2733
2670
|
baseSha: z.string(),
|
|
2734
2671
|
error: GenericError.optional(),
|
|
2735
2672
|
errors: z.record(PatchId, GenericError).optional()
|
|
@@ -2737,111 +2674,6 @@ var Api = {
|
|
|
2737
2674
|
})])
|
|
2738
2675
|
}
|
|
2739
2676
|
},
|
|
2740
|
-
// Patch group membership. Both are idempotent set operations, and both take an
|
|
2741
|
-
// already-closed set: the client computes the prefix closure (staging) or the
|
|
2742
|
-
// forward closure (unstaging) because only the client has the schema needed to
|
|
2743
|
-
// derive patch sets. See `docs/independent-publish/PLAN.md`.
|
|
2744
|
-
"/patch-groups/~/patches": {
|
|
2745
|
-
PUT: {
|
|
2746
|
-
req: {
|
|
2747
|
-
body: z.object({
|
|
2748
|
-
/**
|
|
2749
|
-
* The group to stage into. Absent means the caller's open group on
|
|
2750
|
-
* the branch, created if there is none — which is what the Studio
|
|
2751
|
-
* sends, so a stage never has to wait for a group to exist.
|
|
2752
|
-
*/
|
|
2753
|
-
patchGroupId: z.string().optional(),
|
|
2754
|
-
/** What the user asked to stage. */
|
|
2755
|
-
patchIds: z.array(PatchId),
|
|
2756
|
-
/*
|
|
2757
|
-
* What has to come with it, because the staged patches are written on
|
|
2758
|
-
* top of it.
|
|
2759
|
-
*
|
|
2760
|
-
* The content API records membership as `explicit` or `dependency`
|
|
2761
|
-
* and reads what it is not told about as a dependency — so folding
|
|
2762
|
-
* the two halves into `patchIds` files the patch someone clicked as
|
|
2763
|
-
* something the closure dragged in.
|
|
2764
|
-
*/
|
|
2765
|
-
withPatchIds: z.array(PatchId).optional()
|
|
2766
|
-
}).refine(function (body) {
|
|
2767
|
-
var _body$withPatchIds$le, _body$withPatchIds;
|
|
2768
|
-
return body.patchIds.length > 0 || ((_body$withPatchIds$le = (_body$withPatchIds = body.withPatchIds) === null || _body$withPatchIds === void 0 ? void 0 : _body$withPatchIds.length) !== null && _body$withPatchIds$le !== void 0 ? _body$withPatchIds$le : 0) > 0;
|
|
2769
|
-
},
|
|
2770
|
-
// Either half alone is a real request: a stage of only what came with
|
|
2771
|
-
// it happens when the deferred queue's scope filter drops everything
|
|
2772
|
-
// the user originally clicked.
|
|
2773
|
-
"At least one patch id is required"),
|
|
2774
|
-
cookies: {
|
|
2775
|
-
val_session: z.string().optional()
|
|
2776
|
-
}
|
|
2777
|
-
},
|
|
2778
|
-
res: z.union([unauthorizedResponse, z.object({
|
|
2779
|
-
status: z.literal(403),
|
|
2780
|
-
json: GenericError
|
|
2781
|
-
}), z.object({
|
|
2782
|
-
// The group has already been published, so its membership is frozen.
|
|
2783
|
-
status: z.literal(409),
|
|
2784
|
-
json: GenericError
|
|
2785
|
-
}), z.object({
|
|
2786
|
-
status: z.literal(500),
|
|
2787
|
-
json: GenericError
|
|
2788
|
-
}), z.object({
|
|
2789
|
-
status: z.literal(200),
|
|
2790
|
-
json: z.object({
|
|
2791
|
-
/** `null` for an unstage when the caller has no open group. */
|
|
2792
|
-
patchGroupId: z.string().nullable(),
|
|
2793
|
-
patchIds: z.array(PatchId),
|
|
2794
|
-
/**
|
|
2795
|
-
* The chain version the change committed at. The client keeps its
|
|
2796
|
-
* own view of the change until a stat at least this new shows it.
|
|
2797
|
-
* Absent from a content service that predates it.
|
|
2798
|
-
*/
|
|
2799
|
-
headVersion: z.number().optional()
|
|
2800
|
-
})
|
|
2801
|
-
})])
|
|
2802
|
-
},
|
|
2803
|
-
DELETE: {
|
|
2804
|
-
req: {
|
|
2805
|
-
body: z.object({
|
|
2806
|
-
/** See the PUT. Absent with no open group is a no-op. */
|
|
2807
|
-
patchGroupId: z.string().optional(),
|
|
2808
|
-
/** What the user asked to unstage. */
|
|
2809
|
-
patchIds: z.array(PatchId),
|
|
2810
|
-
/** What has to go with it: everything built on top of it. */
|
|
2811
|
-
withPatchIds: z.array(PatchId).optional()
|
|
2812
|
-
}).refine(function (body) {
|
|
2813
|
-
var _body$withPatchIds$le2, _body$withPatchIds2;
|
|
2814
|
-
return body.patchIds.length > 0 || ((_body$withPatchIds$le2 = (_body$withPatchIds2 = body.withPatchIds) === null || _body$withPatchIds2 === void 0 ? void 0 : _body$withPatchIds2.length) !== null && _body$withPatchIds$le2 !== void 0 ? _body$withPatchIds$le2 : 0) > 0;
|
|
2815
|
-
}, "At least one patch id is required"),
|
|
2816
|
-
cookies: {
|
|
2817
|
-
val_session: z.string().optional()
|
|
2818
|
-
}
|
|
2819
|
-
},
|
|
2820
|
-
res: z.union([unauthorizedResponse, z.object({
|
|
2821
|
-
status: z.literal(403),
|
|
2822
|
-
json: GenericError
|
|
2823
|
-
}), z.object({
|
|
2824
|
-
status: z.literal(409),
|
|
2825
|
-
json: GenericError
|
|
2826
|
-
}), z.object({
|
|
2827
|
-
status: z.literal(500),
|
|
2828
|
-
json: GenericError
|
|
2829
|
-
}), z.object({
|
|
2830
|
-
status: z.literal(200),
|
|
2831
|
-
json: z.object({
|
|
2832
|
-
/** `null` for an unstage when the caller has no open group. */
|
|
2833
|
-
patchGroupId: z.string().nullable(),
|
|
2834
|
-
patchIds: z.array(PatchId),
|
|
2835
|
-
/**
|
|
2836
|
-
* The chain version the change committed at. The client keeps its
|
|
2837
|
-
* own view of the change until a stat at least this new shows it.
|
|
2838
|
-
* Absent from a content service that predates it.
|
|
2839
|
-
*/
|
|
2840
|
-
headVersion: z.number().optional()
|
|
2841
|
-
})
|
|
2842
|
-
})])
|
|
2843
|
-
}
|
|
2844
|
-
},
|
|
2845
2677
|
"/schema": {
|
|
2846
2678
|
GET: {
|
|
2847
2679
|
req: {
|
|
@@ -2878,34 +2710,7 @@ var Api = {
|
|
|
2878
2710
|
validate_sources: onlyOneBooleanQueryParam.optional(),
|
|
2879
2711
|
validate_binary_files: onlyOneBooleanQueryParam.optional(),
|
|
2880
2712
|
exclude_patches: onlyOneBooleanQueryParam.optional(),
|
|
2881
|
-
apply_patches: onlyOneBooleanQueryParam.optional()
|
|
2882
|
-
/**
|
|
2883
|
-
* Apply ONLY these patches, rather than everything pending.
|
|
2884
|
-
*
|
|
2885
|
-
* This is what makes a draft-mode render match the caller's staged
|
|
2886
|
-
* view. Without it `/sources/~` replays every pending patch on the
|
|
2887
|
-
* branch, so a server-rendered preview shows other people's
|
|
2888
|
-
* unpublished work — the one thing independent publish is for.
|
|
2889
|
-
*
|
|
2890
|
-
* Omitted means everything pending, which is the behaviour every
|
|
2891
|
-
* existing caller has and must keep. An EMPTY array is a different
|
|
2892
|
-
* answer and is honoured as one: a group holding nothing renders
|
|
2893
|
-
* base.
|
|
2894
|
-
*/
|
|
2895
|
-
patch_id: z.array(PatchId).optional(),
|
|
2896
|
-
/**
|
|
2897
|
-
* Apply only the patches in the CALLER'S OWN patch groups.
|
|
2898
|
-
*
|
|
2899
|
-
* The server resolves them from the session, so a draft render does
|
|
2900
|
-
* not have to know its own group ids — which it cannot, since it has
|
|
2901
|
-
* no client state. This is what makes `fetchVal` in draft mode show
|
|
2902
|
-
* the person their own staged work rather than everybody's.
|
|
2903
|
-
*
|
|
2904
|
-
* Ignored when `patch_id` is given: an explicit list is a caller that
|
|
2905
|
-
* already knows what it wants, and silently intersecting the two
|
|
2906
|
-
* would make the narrower one invisible.
|
|
2907
|
-
*/
|
|
2908
|
-
own_patch_groups_only: onlyOneBooleanQueryParam.optional()
|
|
2713
|
+
apply_patches: onlyOneBooleanQueryParam.optional()
|
|
2909
2714
|
},
|
|
2910
2715
|
cookies: {
|
|
2911
2716
|
val_session: z.string().optional()
|
|
@@ -3059,24 +2864,72 @@ var Api = {
|
|
|
3059
2864
|
})])
|
|
3060
2865
|
}
|
|
3061
2866
|
},
|
|
2867
|
+
/**
|
|
2868
|
+
* Publish selected (`docs/plans/remove-patch-groups.md`, Phase 4), its first
|
|
2869
|
+
* half, on the site's own server: the changes picked in Review, already
|
|
2870
|
+
* closed into whole patch sets (`selectionClosure`), moved into a proposal
|
|
2871
|
+
* of kind `publish` and saved there -- prepared over the site's head, which
|
|
2872
|
+
* the proposal is based on, so a publish landing in between is refused
|
|
2873
|
+
* rather than reverted. The second half is that proposal's Publish, pressed
|
|
2874
|
+
* as any proposal's is (`publishProposal`); this server answers its checks
|
|
2875
|
+
* and press with what the merge moves, as the proposal's own address would.
|
|
2876
|
+
*/
|
|
2877
|
+
"/publish-selected": {
|
|
2878
|
+
POST: {
|
|
2879
|
+
req: {
|
|
2880
|
+
body: z.object({
|
|
2881
|
+
/** The changes to publish, whole patch sets, in any order: a move keeps the chain's. */
|
|
2882
|
+
patchIds: z.array(PatchId).min(1),
|
|
2883
|
+
/** What the merged proposal is listed as. */
|
|
2884
|
+
displayName: z.string().min(1).max(200),
|
|
2885
|
+
/** The press's own id: the same press sent again is the same proposal. */
|
|
2886
|
+
requestId: z.string().regex(/^[A-Za-z0-9_-]{1,100}$/)
|
|
2887
|
+
}),
|
|
2888
|
+
cookies: {
|
|
2889
|
+
val_session: z.string().optional()
|
|
2890
|
+
}
|
|
2891
|
+
},
|
|
2892
|
+
res: z.union([unauthorizedResponse, z.object({
|
|
2893
|
+
status: z.literal(400),
|
|
2894
|
+
json: GenericError
|
|
2895
|
+
}),
|
|
2896
|
+
/**
|
|
2897
|
+
* Refused: the site moved (`headMoved`: pressing again prepares over
|
|
2898
|
+
* the new head), a change went, or this deployment cannot.
|
|
2899
|
+
*/
|
|
2900
|
+
z.object({
|
|
2901
|
+
status: z.literal(409),
|
|
2902
|
+
json: GenericError.extend({
|
|
2903
|
+
headMoved: z.literal(true).optional()
|
|
2904
|
+
})
|
|
2905
|
+
}), z.object({
|
|
2906
|
+
status: z.literal(500),
|
|
2907
|
+
json: GenericError
|
|
2908
|
+
}),
|
|
2909
|
+
/**
|
|
2910
|
+
* The proposal was made and its changes moved into it, and the save
|
|
2911
|
+
* there failed: they are safe in it, which `proposal` names.
|
|
2912
|
+
*/
|
|
2913
|
+
z.object({
|
|
2914
|
+
status: z.literal(502),
|
|
2915
|
+
json: GenericError.extend({
|
|
2916
|
+
proposal: z.string()
|
|
2917
|
+
})
|
|
2918
|
+
}), z.object({
|
|
2919
|
+
status: z.literal(200),
|
|
2920
|
+
json: z.object({
|
|
2921
|
+
/** The proposal to publish next. */
|
|
2922
|
+
proposal: z.string()
|
|
2923
|
+
})
|
|
2924
|
+
})])
|
|
2925
|
+
}
|
|
2926
|
+
},
|
|
3062
2927
|
"/save": {
|
|
3063
2928
|
POST: {
|
|
3064
2929
|
req: {
|
|
3065
2930
|
body: z.object({
|
|
3066
2931
|
message: z.string().optional(),
|
|
3067
2932
|
patchIds: z.array(PatchId),
|
|
3068
|
-
/*
|
|
3069
|
-
* The patch group this commit EMPTIES, if it empties one.
|
|
3070
|
-
*
|
|
3071
|
-
* Forwarded to the content API, which closes the group it names —
|
|
3072
|
-
* and closes it unconditionally, without checking that the commit
|
|
3073
|
-
* shipped all of it. So the client sends it only when the publish
|
|
3074
|
-
* accounts for every patch the group still holds; a partial publish
|
|
3075
|
-
* omits it and the group stays open with the rest in it.
|
|
3076
|
-
*
|
|
3077
|
-
* Optional, and absent in `fs` mode, which has no groups.
|
|
3078
|
-
*/
|
|
3079
|
-
patchGroupId: z.string().optional(),
|
|
3080
2933
|
/*
|
|
3081
2934
|
* The newest commit this client knew about when it decided.
|
|
3082
2935
|
*
|
|
@@ -3185,19 +3038,6 @@ var Api = {
|
|
|
3185
3038
|
*/
|
|
3186
3039
|
headVersion: z.number().optional()
|
|
3187
3040
|
})
|
|
3188
|
-
}),
|
|
3189
|
-
/*
|
|
3190
|
-
* The named patch group is not this caller's, or the lookup that would
|
|
3191
|
-
* say so failed.
|
|
3192
|
-
*
|
|
3193
|
-
* Publishing may CLOSE a group, and closing somebody else's leaves
|
|
3194
|
-
* their pending work in a closed group and in no open one. So `/save`
|
|
3195
|
-
* runs the same ownership check stage and unstage do, and refuses the
|
|
3196
|
-
* same way — see `refuseUnlessOwn`.
|
|
3197
|
-
*/
|
|
3198
|
-
z.object({
|
|
3199
|
-
status: z.literal(403),
|
|
3200
|
-
json: GenericError
|
|
3201
3041
|
}), z.object({
|
|
3202
3042
|
status: z.literal(500),
|
|
3203
3043
|
json: GenericError
|
|
@@ -3215,8 +3055,7 @@ var Api = {
|
|
|
3215
3055
|
z.object({
|
|
3216
3056
|
message: z.string(),
|
|
3217
3057
|
publishRefusal: PublishRefusal
|
|
3218
|
-
}),
|
|
3219
|
-
z.object({
|
|
3058
|
+
}), z.object({
|
|
3220
3059
|
message: z.string()
|
|
3221
3060
|
}), z.object({
|
|
3222
3061
|
message: z.string(),
|
|
@@ -3235,22 +3074,6 @@ var Api = {
|
|
|
3235
3074
|
z.object({
|
|
3236
3075
|
message: z.string(),
|
|
3237
3076
|
headMoved: z.literal(true)
|
|
3238
|
-
}),
|
|
3239
|
-
/**
|
|
3240
|
-
* The group this commit named has already been published.
|
|
3241
|
-
*
|
|
3242
|
-
* A third thing sharing 409, and flagged for the same reason
|
|
3243
|
-
* `headMoved` is: read as a plain not-fast-forward it looks
|
|
3244
|
-
* retryable, and it is the opposite — the id will never be writable
|
|
3245
|
-
* again, so retrying reproduces it forever.
|
|
3246
|
-
*
|
|
3247
|
-
* It means this author published from somewhere else. The client
|
|
3248
|
-
* forgets the id and falls back to the annotation, which is the
|
|
3249
|
-
* same recovery a 409 on stage or unstage triggers.
|
|
3250
|
-
*/
|
|
3251
|
-
z.object({
|
|
3252
|
-
message: z.string(),
|
|
3253
|
-
patchGroupPublished: z.literal(true)
|
|
3254
3077
|
})])
|
|
3255
3078
|
}), z.object({
|
|
3256
3079
|
status: z.literal(400),
|
|
@@ -3545,16 +3368,7 @@ var Api = {
|
|
|
3545
3368
|
limit: onlyOneIntQueryParam.refine(function (arg) {
|
|
3546
3369
|
return arg > 0 && arg <= JSON_ENTRIES_BATCH_MAX;
|
|
3547
3370
|
}, "limit must be between 1 and ".concat(JSON_ENTRIES_BATCH_MAX)).optional(),
|
|
3548
|
-
apply_patches: onlyOneBooleanQueryParam.optional()
|
|
3549
|
-
/**
|
|
3550
|
-
* The caller's own staged work, and nobody else's.
|
|
3551
|
-
*
|
|
3552
|
-
* The same flag `/sources/~` takes, and for the same reason — a draft
|
|
3553
|
-
* page renders both, so a scoped module beside an unscoped
|
|
3554
|
-
* `jsonValues` entry showed one person's view and everybody's pending
|
|
3555
|
-
* work on the same screen.
|
|
3556
|
-
*/
|
|
3557
|
-
own_patch_groups_only: onlyOneBooleanQueryParam.optional()
|
|
3371
|
+
apply_patches: onlyOneBooleanQueryParam.optional()
|
|
3558
3372
|
},
|
|
3559
3373
|
cookies: _defineProperty({}, VAL_SESSION_COOKIE, z.string().optional())
|
|
3560
3374
|
},
|
|
@@ -4620,13 +4434,11 @@ function newestCommitSha(commits) {
|
|
|
4620
4434
|
*
|
|
4621
4435
|
* The head the server REPORTS (`headPatchId`) when it reports one, and not the
|
|
4622
4436
|
* last patch it listed. The list — `/applicable/patches`, and `/stat` on top of
|
|
4623
|
-
* it — leaves out patches the running deployment already contains, and
|
|
4624
|
-
*
|
|
4625
|
-
*
|
|
4626
|
-
*
|
|
4627
|
-
*
|
|
4628
|
-
* — and a re-sync returns the same list. What fixed it in the Studio before
|
|
4629
|
-
* this existed was discarding the other author's change.
|
|
4437
|
+
* it — leaves out patches the running deployment already contains, and a
|
|
4438
|
+
* publish can ship later patches while an earlier one stays pending (a failed
|
|
4439
|
+
* publish holds its changes back). The last listed id is then behind the head
|
|
4440
|
+
* for good, and the content service accepts a write only on the head, so every
|
|
4441
|
+
* save naming it is refused — and a re-sync returns the same list.
|
|
4630
4442
|
*
|
|
4631
4443
|
* `null` is a REPORTED empty chain, not "unknown". `undefined` is a server
|
|
4632
4444
|
* that reports no head (`fs` mode, which ignores the parent anyway, or a
|
|
@@ -5031,7 +4843,7 @@ function declaredLocales(snapshot) {
|
|
|
5031
4843
|
* these has to resolve all of them, and the two that leaked did so by adding a
|
|
5032
4844
|
* fix here and not to a condition somewhere else.
|
|
5033
4845
|
*/
|
|
5034
|
-
var SCHEMA_SOURCE_FIXES = ["keyof:check-keys", "router:check-route", "locale:check-locale", "record:fill-keys"];
|
|
4846
|
+
var SCHEMA_SOURCE_FIXES = ["keyof:check-keys", "image:check-gallery", "file:check-gallery", "video:check-gallery", "router:check-route", "locale:check-locale", "record:fill-keys"];
|
|
5035
4847
|
|
|
5036
4848
|
/** Whether an error is a marker only the whole project can answer. */
|
|
5037
4849
|
function isSchemaSourceFixError(error) {
|
|
@@ -5042,8 +4854,9 @@ function isSchemaSourceFixError(error) {
|
|
|
5042
4854
|
}
|
|
5043
4855
|
|
|
5044
4856
|
/**
|
|
5045
|
-
* The record a `keyof:check-keys` error resolves against
|
|
5046
|
-
*
|
|
4857
|
+
* The record a `keyof:check-keys` error resolves against -- or a gallery
|
|
4858
|
+
* marker's (`image:check-gallery` and the rest): its gallery module -- or null
|
|
4859
|
+
* for any other error, including a malformed marker, which
|
|
5047
4860
|
* {@link resolveSchemaSourceFixForError} reports and this has nothing to say
|
|
5048
4861
|
* about.
|
|
5049
4862
|
*
|
|
@@ -5053,6 +4866,12 @@ function isSchemaSourceFixError(error) {
|
|
|
5053
4866
|
*/
|
|
5054
4867
|
function keyOfRecordPath(error) {
|
|
5055
4868
|
var _error$fixes2;
|
|
4869
|
+
// A gallery-backed field's marker reads its gallery the same way: the
|
|
4870
|
+
// record whose keys say whether the field's path is there.
|
|
4871
|
+
var gallery = Internal.media.galleryMarkerOf(error);
|
|
4872
|
+
if (gallery !== null) {
|
|
4873
|
+
return gallery.gallery;
|
|
4874
|
+
}
|
|
5056
4875
|
if (!((_error$fixes2 = error.fixes) !== null && _error$fixes2 !== void 0 ? _error$fixes2 : []).includes("keyof:check-keys")) {
|
|
5057
4876
|
return null;
|
|
5058
4877
|
}
|
|
@@ -5074,6 +4893,37 @@ function keyOfRecordPath(error) {
|
|
|
5074
4893
|
function resolveSchemaSourceFixForError(error, snapshot) {
|
|
5075
4894
|
var _error$fixes3;
|
|
5076
4895
|
var fixes = (_error$fixes3 = error.fixes) !== null && _error$fixes3 !== void 0 ? _error$fixes3 : [];
|
|
4896
|
+
var gallery = Internal.media.galleryMarkerOf(error);
|
|
4897
|
+
if (gallery !== null) {
|
|
4898
|
+
// The gallery as it is now -- with what a pending change, a save in a
|
|
4899
|
+
// proposal or a content-only publish added -- not as the schema was built.
|
|
4900
|
+
var entries = getKeyOfRecordAt(gallery.gallery, snapshot).source;
|
|
4901
|
+
var has = _typeof(entries) === "object" && entries !== null && !Array.isArray(entries) && Internal.media.galleryKeyOf(gallery.path, function (key) {
|
|
4902
|
+
return key in entries;
|
|
4903
|
+
}) !== null;
|
|
4904
|
+
if (has) {
|
|
4905
|
+
return {
|
|
4906
|
+
status: "resolved"
|
|
4907
|
+
};
|
|
4908
|
+
}
|
|
4909
|
+
return {
|
|
4910
|
+
status: "remaining",
|
|
4911
|
+
error: _objectSpread2(_objectSpread2({}, error), {}, {
|
|
4912
|
+
value: gallery.source,
|
|
4913
|
+
fixes: undefined
|
|
4914
|
+
})
|
|
4915
|
+
};
|
|
4916
|
+
}
|
|
4917
|
+
if (fixes.includes("image:check-gallery") || fixes.includes("file:check-gallery") || fixes.includes("video:check-gallery")) {
|
|
4918
|
+
return {
|
|
4919
|
+
status: "remaining",
|
|
4920
|
+
error: _objectSpread2(_objectSpread2({}, error), {}, {
|
|
4921
|
+
message: "".concat(error.message, " The gallery could not be read from this error. ").concat(TYPE_ERROR_MESSAGE),
|
|
4922
|
+
typeError: true,
|
|
4923
|
+
fixes: undefined
|
|
4924
|
+
})
|
|
4925
|
+
};
|
|
4926
|
+
}
|
|
5077
4927
|
if (fixes.includes("keyof:check-keys")) {
|
|
5078
4928
|
if (!error.value) {
|
|
5079
4929
|
return {
|
|
@@ -6365,6 +6215,9 @@ function isSkippableFixCode(fix) {
|
|
|
6365
6215
|
// also took them off the publish gate, so a broken key published unseen.
|
|
6366
6216
|
return false;
|
|
6367
6217
|
case "keyof:check-keys":
|
|
6218
|
+
case "image:check-gallery":
|
|
6219
|
+
case "file:check-gallery":
|
|
6220
|
+
case "video:check-gallery":
|
|
6368
6221
|
case "router:check-route":
|
|
6369
6222
|
case "locale:check-locale":
|
|
6370
6223
|
case "record:fill-keys":
|
|
@@ -7998,7 +7851,12 @@ var requestStatus = z.union([z.object({
|
|
|
7998
7851
|
kind: z.literal("failed"),
|
|
7999
7852
|
message: z.string(),
|
|
8000
7853
|
actions: z.array(z["enum"](["try-again", "discard", "re-run-build"])),
|
|
8001
|
-
job: z.string()
|
|
7854
|
+
job: z.string(),
|
|
7855
|
+
movedTo: z.object({
|
|
7856
|
+
proposal: z.string(),
|
|
7857
|
+
displayName: z.string(),
|
|
7858
|
+
changes: z.number()
|
|
7859
|
+
}).optional()
|
|
8002
7860
|
}), z.object({
|
|
8003
7861
|
kind: z.literal("cancelled")
|
|
8004
7862
|
}), z.object({
|
|
@@ -8081,4 +7939,635 @@ function parse(schema, body, call) {
|
|
|
8081
7939
|
return parsed.data;
|
|
8082
7940
|
}
|
|
8083
7941
|
|
|
8084
|
-
|
|
7942
|
+
/**
|
|
7943
|
+
* This functions returns all the possible schema types of a given module path.
|
|
7944
|
+
*/
|
|
7945
|
+
function schemaTypesOfPath(schema, patchPath) {
|
|
7946
|
+
if (!patchPath || patchPath.length === 0) {
|
|
7947
|
+
return new Set([schema.type]);
|
|
7948
|
+
}
|
|
7949
|
+
var branches = new Set();
|
|
7950
|
+
var current = schema;
|
|
7951
|
+
var i = -1;
|
|
7952
|
+
var _iterator = _createForOfIteratorHelper(patchPath),
|
|
7953
|
+
_step;
|
|
7954
|
+
try {
|
|
7955
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
7956
|
+
var pathPart = _step.value;
|
|
7957
|
+
i++;
|
|
7958
|
+
if (!current) {
|
|
7959
|
+
break;
|
|
7960
|
+
}
|
|
7961
|
+
if (current.type === "array") {
|
|
7962
|
+
current = current.item;
|
|
7963
|
+
} else if (current.type === "record") {
|
|
7964
|
+
current = current.item;
|
|
7965
|
+
} else if (current.type === "object" || current.type === "settings") {
|
|
7966
|
+
current = current.items[pathPart];
|
|
7967
|
+
} else if (current.type === "richtext") {
|
|
7968
|
+
// richtext has internal structure (nodes with indices and tags), allow traversal
|
|
7969
|
+
break;
|
|
7970
|
+
} else if (current.type === "discriminated-union") {
|
|
7971
|
+
var types = current.items;
|
|
7972
|
+
var _iterator2 = _createForOfIteratorHelper(types),
|
|
7973
|
+
_step2;
|
|
7974
|
+
try {
|
|
7975
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
7976
|
+
var type = _step2.value;
|
|
7977
|
+
var subTypes = schemaTypesOfPath(type, patchPath.slice(i));
|
|
7978
|
+
for (var _i = 0, _Array$from = Array.from(subTypes.values()); _i < _Array$from.length; _i++) {
|
|
7979
|
+
var subType = _Array$from[_i];
|
|
7980
|
+
branches.add(subType);
|
|
7981
|
+
}
|
|
7982
|
+
}
|
|
7983
|
+
} catch (err) {
|
|
7984
|
+
_iterator2.e(err);
|
|
7985
|
+
} finally {
|
|
7986
|
+
_iterator2.f();
|
|
7987
|
+
}
|
|
7988
|
+
return branches;
|
|
7989
|
+
} else if (current.type === "enum" || current.type === "boolean" || current.type === "number" || current.type === "string" || current.type === "date" || current.type === "dateTime" || current.type === "color" || current.type === "code" || current.type === "file" || current.type === "image" || current.type === "video" || current.type === "keyOf" || current.type === "route" || current.type === "locale" || current.type === "literal" ||
|
|
7990
|
+
// Nothing is patchable at a view path: the target module owns its source.
|
|
7991
|
+
current.type === "view") {
|
|
7992
|
+
if (current.type === "image" || current.type === "file") {
|
|
7993
|
+
// allow changes to metadata
|
|
7994
|
+
if (patchPath[i] === "metadata") {
|
|
7995
|
+
break;
|
|
7996
|
+
}
|
|
7997
|
+
}
|
|
7998
|
+
if (current.type === "video") {
|
|
7999
|
+
// A video is edited a property at a time — its poster time, a caption
|
|
8000
|
+
// track's label — so that two editors changing different parts of one
|
|
8001
|
+
// video do not overwrite each other. Everything below it is the video.
|
|
8002
|
+
break;
|
|
8003
|
+
}
|
|
8004
|
+
if (i !== patchPath.length - 1) {
|
|
8005
|
+
throw new Error("Found " + current.type + " (primitive), but path has more parts: " + patchPath.join("/") + " at " + pathPart);
|
|
8006
|
+
}
|
|
8007
|
+
break;
|
|
8008
|
+
} else {
|
|
8009
|
+
var _unreachable = current;
|
|
8010
|
+
var unknownType = _unreachable.type;
|
|
8011
|
+
console.error("Unexecpted resolved schema type: ".concat(unknownType, " in ").concat(patchPath.join("/"), " at ").concat(pathPart));
|
|
8012
|
+
return new Set([unknownType]);
|
|
8013
|
+
}
|
|
8014
|
+
}
|
|
8015
|
+
} catch (err) {
|
|
8016
|
+
_iterator.e(err);
|
|
8017
|
+
} finally {
|
|
8018
|
+
_iterator.f();
|
|
8019
|
+
}
|
|
8020
|
+
if (current) {
|
|
8021
|
+
branches.add(current.type);
|
|
8022
|
+
// A discriminated union's value IS an object, and an enum's IS a string:
|
|
8023
|
+
// a patch op typed for either has to be accepted here too.
|
|
8024
|
+
if (current.type === "discriminated-union") {
|
|
8025
|
+
branches.add("object");
|
|
8026
|
+
} else if (current.type === "enum") {
|
|
8027
|
+
branches.add("string");
|
|
8028
|
+
}
|
|
8029
|
+
}
|
|
8030
|
+
return branches;
|
|
8031
|
+
}
|
|
8032
|
+
|
|
8033
|
+
// Examples: /file/name.val.ts?/path/to/patch
|
|
8034
|
+
|
|
8035
|
+
/**
|
|
8036
|
+
* A patch set is a set of patches that are non-independent of each other. This is useful for example when we want to apply a set of patches atomically.
|
|
8037
|
+
* A patch set is identified by a module file path and a json patch path delimited by a '?' character. We call this the patch set path. Example: /file/name.val.ts?/path/to/patch
|
|
8038
|
+
*
|
|
8039
|
+
*
|
|
8040
|
+
* NOTE: the order of patch sets is always newest first. This is because the UX always shows the newest patches first.
|
|
8041
|
+
*/
|
|
8042
|
+
|
|
8043
|
+
/**
|
|
8044
|
+
* Is `inner` strictly nested inside the patch set `outer`?
|
|
8045
|
+
*
|
|
8046
|
+
* A plain `inner.startsWith(outer)` is not enough, and the difference is not
|
|
8047
|
+
* cosmetic. The file part of a key is terminated by the '?' delimiter, but the
|
|
8048
|
+
* segments of the patch path are not terminated by anything, so a raw prefix
|
|
8049
|
+
* test also matches siblings whose *name* merely starts with the same
|
|
8050
|
+
* characters: '/p.val.ts?foobar/title' starts with '/p.val.ts?foo', so removing
|
|
8051
|
+
* record key "foo" and retitling record key "foobar" would be merged into one
|
|
8052
|
+
* patch set.
|
|
8053
|
+
*
|
|
8054
|
+
* That used to only over-group two unrelated changes in the compare view. Now
|
|
8055
|
+
* that patch sets decide what moves between branches as one (whole patch sets,
|
|
8056
|
+
* as `changesToMove` moves them), it means moving one key silently moves its
|
|
8057
|
+
* similarly-named sibling — so the boundary has to be
|
|
8058
|
+
* checked explicitly: '?' when `outer` is a bare module file path, '/' when it
|
|
8059
|
+
* already has a patch path.
|
|
8060
|
+
*/
|
|
8061
|
+
function isInsidePatchSetPath(inner, outer) {
|
|
8062
|
+
if (!inner.startsWith(outer)) {
|
|
8063
|
+
return false;
|
|
8064
|
+
}
|
|
8065
|
+
var boundary = inner[outer.length];
|
|
8066
|
+
return outer.includes("?") ? boundary === "/" : boundary === "?";
|
|
8067
|
+
}
|
|
8068
|
+
var PatchSets = /*#__PURE__*/function () {
|
|
8069
|
+
function PatchSets() {
|
|
8070
|
+
_classCallCheck(this, PatchSets);
|
|
8071
|
+
_defineProperty(this, "insertedPatches", void 0);
|
|
8072
|
+
_defineProperty(this, "patchSetMetadata", void 0);
|
|
8073
|
+
_defineProperty(this, "orderedInsertKeys", void 0);
|
|
8074
|
+
this.patchSetMetadata = {};
|
|
8075
|
+
this.orderedInsertKeys = [];
|
|
8076
|
+
this.insertedPatches = new Set();
|
|
8077
|
+
}
|
|
8078
|
+
return _createClass(PatchSets, [{
|
|
8079
|
+
key: "reset",
|
|
8080
|
+
value: function reset() {
|
|
8081
|
+
this.patchSetMetadata = {};
|
|
8082
|
+
this.orderedInsertKeys = [];
|
|
8083
|
+
this.insertedPatches = new Set();
|
|
8084
|
+
}
|
|
8085
|
+
}, {
|
|
8086
|
+
key: "getInsertedPatches",
|
|
8087
|
+
value: function getInsertedPatches() {
|
|
8088
|
+
return this.insertedPatches;
|
|
8089
|
+
}
|
|
8090
|
+
}, {
|
|
8091
|
+
key: "insertPath",
|
|
8092
|
+
value: function insertPath(moduleFilePath, affectsPatchPath, patchId, createdAt, author, opType, schemaTypes, opPath) {
|
|
8093
|
+
var newPatchSetPath = affectsPatchPath.length > 0 ? "".concat(moduleFilePath, "?").concat(affectsPatchPath.join("/")) : moduleFilePath;
|
|
8094
|
+
var pathIndexesThatMustBeMerged = [];
|
|
8095
|
+
// TODO: current implementation is O(n), with isInside it is: O(n x m) - there's room for optimization (Trie?). Just make sure order is maintained and that insert AND then serialize is what we optimize for because the UX will do an insert, then serialize immediately after
|
|
8096
|
+
for (var i = this.orderedInsertKeys.length - 1; i >= 0; i--) {
|
|
8097
|
+
var currentInsertKey = this.orderedInsertKeys[i];
|
|
8098
|
+
if (newPatchSetPath !== currentInsertKey) {
|
|
8099
|
+
if (isInsidePatchSetPath(newPatchSetPath, currentInsertKey)) {
|
|
8100
|
+
// This new patch set is inside an existing patch set...
|
|
8101
|
+
// Use the existing patch set as the new name
|
|
8102
|
+
newPatchSetPath = currentInsertKey;
|
|
8103
|
+
// Move to new patch set to head
|
|
8104
|
+
this.orderedInsertKeys.splice(i, 1);
|
|
8105
|
+
this.orderedInsertKeys.unshift(newPatchSetPath);
|
|
8106
|
+
} else if (isInsidePatchSetPath(currentInsertKey, newPatchSetPath)) {
|
|
8107
|
+
// We found a patch set (with a shorter path) that needs to be merged into this new patch set
|
|
8108
|
+
pathIndexesThatMustBeMerged.push(i);
|
|
8109
|
+
}
|
|
8110
|
+
} else {
|
|
8111
|
+
// This patch set already exists
|
|
8112
|
+
// Move to new patch set to head
|
|
8113
|
+
this.orderedInsertKeys.splice(i, 1);
|
|
8114
|
+
this.orderedInsertKeys.unshift(newPatchSetPath);
|
|
8115
|
+
}
|
|
8116
|
+
}
|
|
8117
|
+
|
|
8118
|
+
// Merge existing patch sets into this new one:
|
|
8119
|
+
for (var _i = 0, _pathIndexesThatMustB = pathIndexesThatMustBeMerged; _i < _pathIndexesThatMustB.length; _i++) {
|
|
8120
|
+
var pathIndexThatMustBeMerged = _pathIndexesThatMustB[_i];
|
|
8121
|
+
var moduleFileOrPatchSetPath = this.orderedInsertKeys[pathIndexThatMustBeMerged];
|
|
8122
|
+
|
|
8123
|
+
// 1) remove the old patch set path from ordered insert key
|
|
8124
|
+
this.orderedInsertKeys.splice(pathIndexThatMustBeMerged, 1);
|
|
8125
|
+
|
|
8126
|
+
// 2) merge metadata into new
|
|
8127
|
+
var existingPatchSetMetadata = this.patchSetMetadata[moduleFileOrPatchSetPath];
|
|
8128
|
+
if (!this.patchSetMetadata[newPatchSetPath]) {
|
|
8129
|
+
this.patchSetMetadata[newPatchSetPath] = {
|
|
8130
|
+
moduleFilePath: moduleFilePath,
|
|
8131
|
+
patchPath: affectsPatchPath,
|
|
8132
|
+
patches: [],
|
|
8133
|
+
authors: [],
|
|
8134
|
+
opTypes: [],
|
|
8135
|
+
schemaTypes: Array.from(schemaTypes),
|
|
8136
|
+
lastUpdated: createdAt,
|
|
8137
|
+
lastUpdatedBy: author
|
|
8138
|
+
};
|
|
8139
|
+
}
|
|
8140
|
+
if (existingPatchSetMetadata) {
|
|
8141
|
+
var _iterator = _createForOfIteratorHelper(existingPatchSetMetadata.patches.slice()),
|
|
8142
|
+
_step;
|
|
8143
|
+
try {
|
|
8144
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
8145
|
+
var patchMetadata = _step.value;
|
|
8146
|
+
this.patchSetMetadata[newPatchSetPath].patches.unshift(patchMetadata);
|
|
8147
|
+
if (patchMetadata.author !== null) {
|
|
8148
|
+
this.patchSetMetadata[newPatchSetPath].authors.unshift(patchMetadata.author);
|
|
8149
|
+
}
|
|
8150
|
+
this.patchSetMetadata[newPatchSetPath].opTypes.unshift(patchMetadata.opType);
|
|
8151
|
+
}
|
|
8152
|
+
} catch (err) {
|
|
8153
|
+
_iterator.e(err);
|
|
8154
|
+
} finally {
|
|
8155
|
+
_iterator.f();
|
|
8156
|
+
}
|
|
8157
|
+
} else {
|
|
8158
|
+
throw new Error("Could not find patch set metadata or patch metadata for (inserted) patch set path: ".concat(moduleFileOrPatchSetPath));
|
|
8159
|
+
}
|
|
8160
|
+
|
|
8161
|
+
// 3) delete old metadata
|
|
8162
|
+
if (moduleFileOrPatchSetPath !== newPatchSetPath) {
|
|
8163
|
+
delete this.patchSetMetadata[moduleFileOrPatchSetPath];
|
|
8164
|
+
}
|
|
8165
|
+
}
|
|
8166
|
+
|
|
8167
|
+
// Insert new metadata
|
|
8168
|
+
if (!this.patchSetMetadata[newPatchSetPath]) {
|
|
8169
|
+
this.patchSetMetadata[newPatchSetPath] = {
|
|
8170
|
+
moduleFilePath: moduleFilePath,
|
|
8171
|
+
patchPath: affectsPatchPath,
|
|
8172
|
+
patches: [],
|
|
8173
|
+
authors: [],
|
|
8174
|
+
opTypes: [],
|
|
8175
|
+
schemaTypes: schemaTypes,
|
|
8176
|
+
lastUpdated: createdAt,
|
|
8177
|
+
lastUpdatedBy: author
|
|
8178
|
+
};
|
|
8179
|
+
}
|
|
8180
|
+
if (author !== null && !this.patchSetMetadata[newPatchSetPath].authors.includes(author)) {
|
|
8181
|
+
this.patchSetMetadata[newPatchSetPath].authors.unshift(author);
|
|
8182
|
+
}
|
|
8183
|
+
this.patchSetMetadata[newPatchSetPath].lastUpdatedBy = author;
|
|
8184
|
+
this.patchSetMetadata[newPatchSetPath].lastUpdated = createdAt;
|
|
8185
|
+
if (!this.patchSetMetadata[newPatchSetPath].opTypes.includes(opType)) {
|
|
8186
|
+
this.patchSetMetadata[newPatchSetPath].opTypes.unshift(opType);
|
|
8187
|
+
}
|
|
8188
|
+
this.patchSetMetadata[newPatchSetPath].patches.unshift({
|
|
8189
|
+
patchPath: opPath,
|
|
8190
|
+
patchId: patchId,
|
|
8191
|
+
author: author,
|
|
8192
|
+
createdAt: createdAt,
|
|
8193
|
+
opType: opType,
|
|
8194
|
+
schemaTypes: schemaTypes
|
|
8195
|
+
});
|
|
8196
|
+
if (!this.orderedInsertKeys.includes(newPatchSetPath)) {
|
|
8197
|
+
this.orderedInsertKeys.unshift(newPatchSetPath);
|
|
8198
|
+
}
|
|
8199
|
+
}
|
|
8200
|
+
|
|
8201
|
+
/**
|
|
8202
|
+
* Insert a whole patch.
|
|
8203
|
+
*
|
|
8204
|
+
* Takes the patch rather than one op because the de-duplication below is
|
|
8205
|
+
* per-*patch*: a patch is either known to this instance or it is not. When this
|
|
8206
|
+
* took a single op, callers looped and every call after the first hit the
|
|
8207
|
+
* `insertedPatches` guard and returned — so only a patch's first op ever reached
|
|
8208
|
+
* a patch set. A patch that touched two places (a `move`, or a `file` op sitting
|
|
8209
|
+
* before its source op) was therefore mis-grouped, which is invisible in the
|
|
8210
|
+
* compare view but decides what moves as one.
|
|
8211
|
+
*/
|
|
8212
|
+
}, {
|
|
8213
|
+
key: "insert",
|
|
8214
|
+
value: function insert(moduleFilePath, schema, patch, patchId, createdAt, author) {
|
|
8215
|
+
if (this.insertedPatches.has(patchId)) {
|
|
8216
|
+
return;
|
|
8217
|
+
}
|
|
8218
|
+
// Marked inserted unconditionally, schema or not. An earlier revision of this
|
|
8219
|
+
// fix only marked it once a schema was available, so that a patch grouped
|
|
8220
|
+
// under the whole-module fallback could be re-inserted later with the real
|
|
8221
|
+
// schema. That is no longer this class's problem: `PatchSetChain` invalidates
|
|
8222
|
+
// on `schema:init` and a rebuild calls `reset()`, which clears this set — so
|
|
8223
|
+
// the fallback is already re-derived from scratch when the schema lands, and a
|
|
8224
|
+
// conditional here would only leave the per-patch de-duplication half-applied.
|
|
8225
|
+
this.insertedPatches.add(patchId);
|
|
8226
|
+
var _iterator2 = _createForOfIteratorHelper(patch),
|
|
8227
|
+
_step2;
|
|
8228
|
+
try {
|
|
8229
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
8230
|
+
var op = _step2.value;
|
|
8231
|
+
this.insertOp(moduleFilePath, schema, op, patchId, createdAt, author);
|
|
8232
|
+
}
|
|
8233
|
+
} catch (err) {
|
|
8234
|
+
_iterator2.e(err);
|
|
8235
|
+
} finally {
|
|
8236
|
+
_iterator2.f();
|
|
8237
|
+
}
|
|
8238
|
+
}
|
|
8239
|
+
}, {
|
|
8240
|
+
key: "insertOp",
|
|
8241
|
+
value: function insertOp(moduleFilePath, schema, op, patchId, createdAt, author) {
|
|
8242
|
+
if (!schema) {
|
|
8243
|
+
this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [], op.path);
|
|
8244
|
+
return;
|
|
8245
|
+
}
|
|
8246
|
+
if (op.op === "file" || op.op === "test") {
|
|
8247
|
+
return;
|
|
8248
|
+
}
|
|
8249
|
+
try {
|
|
8250
|
+
if (op.op === "replace") {
|
|
8251
|
+
var schemaTypesAtPath = schemaTypesOfPath(schema, op.path);
|
|
8252
|
+
this.insertPath(moduleFilePath, op.path, patchId, createdAt, author, op.op, Array.from(schemaTypesAtPath), op.path);
|
|
8253
|
+
} else if (op.op === "add" || op.op === "remove" || op.op === "move" || op.op === "copy") {
|
|
8254
|
+
// This is the default case, were we, to be sure, take the parent of the path and as the patch set
|
|
8255
|
+
var path = op.path.slice(0, -1);
|
|
8256
|
+
var _schemaTypesAtPath = schemaTypesOfPath(schema, path);
|
|
8257
|
+
if (_schemaTypesAtPath.size === 1 && _schemaTypesAtPath.has("array")) {
|
|
8258
|
+
// for arrays we would need a lot of logic to create a patch set that is not on the entire parent so for now we do just that
|
|
8259
|
+
this.insertPath(moduleFilePath, path, patchId, createdAt, author, op.op, Array.from(_schemaTypesAtPath), op.path);
|
|
8260
|
+
if (op.op === "move" || op.op === "copy") {
|
|
8261
|
+
// `copy` as well as `move`: it does not write the source, but it
|
|
8262
|
+
// READS it, so the value it produces depends on every pending edit
|
|
8263
|
+
// to that source and on the indices around it.
|
|
8264
|
+
var _path = op.from.slice(0, -1);
|
|
8265
|
+
var _schemaTypesAtPath2 = schemaTypesOfPath(schema, _path);
|
|
8266
|
+
this.insertPath(moduleFilePath, _path, patchId, createdAt, author, op.op, Array.from(_schemaTypesAtPath2), op.path);
|
|
8267
|
+
}
|
|
8268
|
+
} else if (_schemaTypesAtPath.size === 1 && (_schemaTypesAtPath.has("record") ||
|
|
8269
|
+
// An OBJECT is keyed too: its keys are named rather than
|
|
8270
|
+
// positional, so neither `add` (create-or-set, `addToNode` in
|
|
8271
|
+
// `@valbuild/core/patch`) nor `remove` (delete the property)
|
|
8272
|
+
// disturbs any sibling. Either way the op affects exactly the key
|
|
8273
|
+
// it names and nothing else, which is the property this branch
|
|
8274
|
+
// needs — unlike an array, where both shift every later index.
|
|
8275
|
+
//
|
|
8276
|
+
// The studio emits `add` rather than `replace` here on purpose, so
|
|
8277
|
+
// that the write survives the key having gone away in the meantime:
|
|
8278
|
+
// see `ImageField`'s alt write and
|
|
8279
|
+
// `ModuleGallery.handleAltTextChange`, which both say so.
|
|
8280
|
+
//
|
|
8281
|
+
// That last one is why this branch exists. `s.imagedir()`
|
|
8282
|
+
// serializes as a record whose ITEM is an object, so editing the
|
|
8283
|
+
// alt text of a gallery entry resolves `object` here, hit the throw
|
|
8284
|
+
// below, and terminated the whole media module into one patch set —
|
|
8285
|
+
// once per keystroke. Moving any one change in that module then
|
|
8286
|
+
// dragged every other change in it along, because changes move a
|
|
8287
|
+
// whole patch set at a time.
|
|
8288
|
+
_schemaTypesAtPath.has("object") ||
|
|
8289
|
+
// A settings SECTION is addressed like a record: its keys are
|
|
8290
|
+
// named, and an `add` at ["theme", "accent"] modifies exactly that
|
|
8291
|
+
// one. Without this it fell to the throw below — every settings
|
|
8292
|
+
// edit terminated the whole module into one patch set, which is why
|
|
8293
|
+
// the publish diff said "Settings" where `settingsChangeLabels` has
|
|
8294
|
+
// a name for the field. Both sections write `add` this way; see
|
|
8295
|
+
// `useWriteAssistantSetting`, which has to create an absent section
|
|
8296
|
+
// in a single op.
|
|
8297
|
+
_schemaTypesAtPath.has("settings"))) {
|
|
8298
|
+
// If we know this is a record, we can be more specific and only insert the path that is being modified
|
|
8299
|
+
var _path2 = op.path;
|
|
8300
|
+
var _schemaTypesAtPath3 = schemaTypesOfPath(schema, _path2);
|
|
8301
|
+
this.insertPath(moduleFilePath, _path2, patchId, createdAt, author, op.op, Array.from(_schemaTypesAtPath3), op.path);
|
|
8302
|
+
if (op.op === "move" || op.op === "copy") {
|
|
8303
|
+
// The SOURCE is classified on its own terms, not the
|
|
8304
|
+
// destination's. A move out of an array item shifts every later
|
|
8305
|
+
// index, so that side has to be the array — exactly as the branch
|
|
8306
|
+
// above does for a move whose destination is an array. Only when
|
|
8307
|
+
// the source parent is keyed too does `op.from` name the whole of
|
|
8308
|
+
// what the op affects.
|
|
8309
|
+
//
|
|
8310
|
+
// `copy` reaches here as well as `move`. It does not write the
|
|
8311
|
+
// source, but the value it produces is read from it, so it depends
|
|
8312
|
+
// on every pending edit to that source just as a move does.
|
|
8313
|
+
// Duplicating a record entry (`useDuplicateRecordEntry`) is
|
|
8314
|
+
// the copy that actually ships, and its source went ungrouped.
|
|
8315
|
+
var fromParent = op.from.slice(0, -1);
|
|
8316
|
+
var fromParentTypes = schemaTypesOfPath(schema, fromParent);
|
|
8317
|
+
// ANY possible array parent widens, rather than only an
|
|
8318
|
+
// unambiguous one: a discriminated union resolves to every
|
|
8319
|
+
// variant's type at once, so a source inside one can be an array
|
|
8320
|
+
// here and an object there. Requiring a single type grouped it at
|
|
8321
|
+
// the item, which is wrong the moment the array variant is the
|
|
8322
|
+
// live one — and the whole array is the safe direction.
|
|
8323
|
+
var isPositionalSource = fromParentTypes.has("array");
|
|
8324
|
+
var _path3 = isPositionalSource ? fromParent : op.from;
|
|
8325
|
+
var _schemaTypesAtPath4 = schemaTypesOfPath(schema, _path3);
|
|
8326
|
+
this.insertPath(moduleFilePath, _path3, patchId, createdAt, author, op.op, Array.from(_schemaTypesAtPath4), op.path);
|
|
8327
|
+
}
|
|
8328
|
+
} else if (_schemaTypesAtPath.size === 1 && !(_schemaTypesAtPath.has("image") || _schemaTypesAtPath.has("file"))) {
|
|
8329
|
+
// What is left is a parent this function cannot isolate a key
|
|
8330
|
+
// inside. Two different reasons end up here, and the message covers
|
|
8331
|
+
// both: a PRIMITIVE cannot hold the key at all, which means the path
|
|
8332
|
+
// no longer fits the schema — a genuinely stale patch; and `richtext`
|
|
8333
|
+
// can, but its children are positional, so isolating one would let a
|
|
8334
|
+
// node insert be moved without the edits whose indices it shifted.
|
|
8335
|
+
// Both keep reporting, and the catch below terminates the module,
|
|
8336
|
+
// which is the conservative thing to do when we cannot say what a
|
|
8337
|
+
// change affects.
|
|
8338
|
+
throw new Error("Cannot isolate a patch set for op: '".concat(op.op, "' \u2014 no addressable key inside schema type: ").concat(_schemaTypesAtPath.values().next().value));
|
|
8339
|
+
} else {
|
|
8340
|
+
// we cannot really know if this is a record or array so the entire module is the patch set
|
|
8341
|
+
this.insertPath(moduleFilePath, path, patchId, createdAt, author, op.op, [schema.type], op.path);
|
|
8342
|
+
}
|
|
8343
|
+
} else {
|
|
8344
|
+
var _unreachable = op;
|
|
8345
|
+
throw new Error("Unreachable op: " + _unreachable);
|
|
8346
|
+
}
|
|
8347
|
+
} catch (e) {
|
|
8348
|
+
// We might be in this situation if the schema changes, etc etc:
|
|
8349
|
+
if (e instanceof Error) {
|
|
8350
|
+
console.error("Could not resolve path while creating patch set", e.message);
|
|
8351
|
+
} else {
|
|
8352
|
+
console.error("Could not resolve path while creating patch set", e);
|
|
8353
|
+
}
|
|
8354
|
+
// "terminate" the entire module file path (i.e. all patches are their own patch set)
|
|
8355
|
+
this.insertPath(moduleFilePath, [], patchId, createdAt, author, op.op, [schema.type], op.path);
|
|
8356
|
+
}
|
|
8357
|
+
}
|
|
8358
|
+
}, {
|
|
8359
|
+
key: "isInserted",
|
|
8360
|
+
value: function isInserted(patchId) {
|
|
8361
|
+
return this.insertedPatches.has(patchId);
|
|
8362
|
+
}
|
|
8363
|
+
}, {
|
|
8364
|
+
key: "serialize",
|
|
8365
|
+
value: function serialize() {
|
|
8366
|
+
var _this = this;
|
|
8367
|
+
return this.orderedInsertKeys.map(function (key) {
|
|
8368
|
+
if (key in _this.patchSetMetadata) {
|
|
8369
|
+
return _this.patchSetMetadata[key];
|
|
8370
|
+
} else {
|
|
8371
|
+
throw new Error("Could not find patch set metadata or patch metadata for (inserted) patch set path: ".concat(key));
|
|
8372
|
+
}
|
|
8373
|
+
});
|
|
8374
|
+
}
|
|
8375
|
+
}]);
|
|
8376
|
+
}();
|
|
8377
|
+
|
|
8378
|
+
/**
|
|
8379
|
+
* Patch sets that share a change become one: a change is never split.
|
|
8380
|
+
*
|
|
8381
|
+
* Shared by the two places that move changes between branches a whole set at
|
|
8382
|
+
* a time -- the merge moving the site's conflicting pending changes
|
|
8383
|
+
* (`changesToMove` in `@valbuild/server`) and Publish selected
|
|
8384
|
+
* ({@link selectionClosure}) -- so that they agree on what "a whole set" is.
|
|
8385
|
+
*/
|
|
8386
|
+
function joinSharedChanges(sets) {
|
|
8387
|
+
var groups = [];
|
|
8388
|
+
var _iterator = _createForOfIteratorHelper(sets),
|
|
8389
|
+
_step;
|
|
8390
|
+
try {
|
|
8391
|
+
var _loop = function _loop() {
|
|
8392
|
+
var set = _step.value;
|
|
8393
|
+
var joined = new Set(set);
|
|
8394
|
+
var _iterator2 = _createForOfIteratorHelper(groups.filter(function (g) {
|
|
8395
|
+
return set.some(function (id) {
|
|
8396
|
+
return g.has(id);
|
|
8397
|
+
});
|
|
8398
|
+
})),
|
|
8399
|
+
_step2;
|
|
8400
|
+
try {
|
|
8401
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
8402
|
+
var group = _step2.value;
|
|
8403
|
+
var _iterator3 = _createForOfIteratorHelper(group),
|
|
8404
|
+
_step3;
|
|
8405
|
+
try {
|
|
8406
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
8407
|
+
var id = _step3.value;
|
|
8408
|
+
joined.add(id);
|
|
8409
|
+
}
|
|
8410
|
+
} catch (err) {
|
|
8411
|
+
_iterator3.e(err);
|
|
8412
|
+
} finally {
|
|
8413
|
+
_iterator3.f();
|
|
8414
|
+
}
|
|
8415
|
+
groups.splice(groups.indexOf(group), 1);
|
|
8416
|
+
}
|
|
8417
|
+
} catch (err) {
|
|
8418
|
+
_iterator2.e(err);
|
|
8419
|
+
} finally {
|
|
8420
|
+
_iterator2.f();
|
|
8421
|
+
}
|
|
8422
|
+
groups.push(joined);
|
|
8423
|
+
};
|
|
8424
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
8425
|
+
_loop();
|
|
8426
|
+
}
|
|
8427
|
+
} catch (err) {
|
|
8428
|
+
_iterator.e(err);
|
|
8429
|
+
} finally {
|
|
8430
|
+
_iterator.f();
|
|
8431
|
+
}
|
|
8432
|
+
return groups;
|
|
8433
|
+
}
|
|
8434
|
+
|
|
8435
|
+
/**
|
|
8436
|
+
* What publishing `selected` publishes: every change in every patch set a
|
|
8437
|
+
* selected change is in, sets that share a change joined
|
|
8438
|
+
* (valbuild/val `docs/plans/remove-patch-groups.md`, Phase 4, rule 2).
|
|
8439
|
+
*
|
|
8440
|
+
* A patch set is changes that do not apply without each other, so a selection
|
|
8441
|
+
* of part of one cannot be published on its own. What it pulls in is someone
|
|
8442
|
+
* else's as often as not; the caller says whose, before anything moves.
|
|
8443
|
+
*
|
|
8444
|
+
* In the order of `patchIds` -- the chain's -- with nothing that is not in it.
|
|
8445
|
+
*/
|
|
8446
|
+
function selectionClosure(patchSets, selected, patchIds) {
|
|
8447
|
+
var wanted = new Set(selected);
|
|
8448
|
+
var closed = new Set();
|
|
8449
|
+
var _iterator4 = _createForOfIteratorHelper(joinSharedChanges(patchSets.map(function (set) {
|
|
8450
|
+
return set.patches.map(function (patch) {
|
|
8451
|
+
return patch.patchId;
|
|
8452
|
+
});
|
|
8453
|
+
}))),
|
|
8454
|
+
_step4;
|
|
8455
|
+
try {
|
|
8456
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
8457
|
+
var group = _step4.value;
|
|
8458
|
+
if (_toConsumableArray(group).some(function (id) {
|
|
8459
|
+
return wanted.has(id);
|
|
8460
|
+
})) {
|
|
8461
|
+
var _iterator6 = _createForOfIteratorHelper(group),
|
|
8462
|
+
_step6;
|
|
8463
|
+
try {
|
|
8464
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
8465
|
+
var id = _step6.value;
|
|
8466
|
+
closed.add(id);
|
|
8467
|
+
}
|
|
8468
|
+
} catch (err) {
|
|
8469
|
+
_iterator6.e(err);
|
|
8470
|
+
} finally {
|
|
8471
|
+
_iterator6.f();
|
|
8472
|
+
}
|
|
8473
|
+
}
|
|
8474
|
+
}
|
|
8475
|
+
// A selected change no patch set knows of is its own set.
|
|
8476
|
+
} catch (err) {
|
|
8477
|
+
_iterator4.e(err);
|
|
8478
|
+
} finally {
|
|
8479
|
+
_iterator4.f();
|
|
8480
|
+
}
|
|
8481
|
+
var _iterator5 = _createForOfIteratorHelper(wanted),
|
|
8482
|
+
_step5;
|
|
8483
|
+
try {
|
|
8484
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
8485
|
+
var _id = _step5.value;
|
|
8486
|
+
closed.add(_id);
|
|
8487
|
+
}
|
|
8488
|
+
} catch (err) {
|
|
8489
|
+
_iterator5.e(err);
|
|
8490
|
+
} finally {
|
|
8491
|
+
_iterator5.f();
|
|
8492
|
+
}
|
|
8493
|
+
return patchIds.filter(function (id) {
|
|
8494
|
+
return closed.has(id);
|
|
8495
|
+
});
|
|
8496
|
+
}
|
|
8497
|
+
|
|
8498
|
+
/**
|
|
8499
|
+
* Update from the site, for a proposal with code (valbuild/home
|
|
8500
|
+
* `docs/hosted-publishing.md` step 8.2, slice 1b): what content hands over,
|
|
8501
|
+
* what the builder tab makes of it, and what Val's server reads -- one
|
|
8502
|
+
* definition of each for the three.
|
|
8503
|
+
*/
|
|
8504
|
+
|
|
8505
|
+
/** Content a schema does not allow, by path in the module. */
|
|
8506
|
+
|
|
8507
|
+
/** Content's `merge-trees` answer. */
|
|
8508
|
+
|
|
8509
|
+
/** Which tree: where the proposal started, the site, or the proposal. */
|
|
8510
|
+
|
|
8511
|
+
/** A module, as evaluating its tree in the tab gave it. */
|
|
8512
|
+
|
|
8513
|
+
/** A side's files: the site's tree, the base's changes over it, the proposal's over that. */
|
|
8514
|
+
function sideFiles(trees, side) {
|
|
8515
|
+
var layers = side === "site" ? [] : side === "base" ? [trees.trees.base] : [trees.trees.base, trees.trees.proposal];
|
|
8516
|
+
var files = _objectSpread2({}, trees.trees.site);
|
|
8517
|
+
for (var _i = 0, _layers = layers; _i < _layers.length; _i++) {
|
|
8518
|
+
var layer = _layers[_i];
|
|
8519
|
+
for (var _i2 = 0, _Object$entries = Object.entries(layer); _i2 < _Object$entries.length; _i2++) {
|
|
8520
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2),
|
|
8521
|
+
path = _Object$entries$_i[0],
|
|
8522
|
+
text = _Object$entries$_i[1];
|
|
8523
|
+
if (text === null) delete files[path];else files[path] = text;
|
|
8524
|
+
}
|
|
8525
|
+
}
|
|
8526
|
+
return files;
|
|
8527
|
+
}
|
|
8528
|
+
|
|
8529
|
+
/** A side's Source of a module, from content's index; `null` when it has none. */
|
|
8530
|
+
function sideSource(trees, side, moduleFilePath) {
|
|
8531
|
+
var _trees$modules$module, _trees$modules$module2, _trees$sources$sha;
|
|
8532
|
+
var sha = (_trees$modules$module = (_trees$modules$module2 = trees.modules[moduleFilePath]) === null || _trees$modules$module2 === void 0 ? void 0 : _trees$modules$module2[side]) !== null && _trees$modules$module !== void 0 ? _trees$modules$module : null;
|
|
8533
|
+
return sha === null ? null : (_trees$sources$sha = trees.sources[sha]) !== null && _trees$sources$sha !== void 0 ? _trees$sources$sha : null;
|
|
8534
|
+
}
|
|
8535
|
+
|
|
8536
|
+
/**
|
|
8537
|
+
* What a schema reports about this content, without the errors the server
|
|
8538
|
+
* fixes on its own (those with `fixes`): run on the schema instance that
|
|
8539
|
+
* evaluating the module made, so custom rules take part.
|
|
8540
|
+
*/
|
|
8541
|
+
function schemaErrorsOf(schema, moduleFilePath, source) {
|
|
8542
|
+
var res = schema["executeValidate"](moduleFilePath, source);
|
|
8543
|
+
if (res === false) return [];
|
|
8544
|
+
var errors = [];
|
|
8545
|
+
for (var _i3 = 0, _Object$entries2 = Object.entries(res); _i3 < _Object$entries2.length; _i3++) {
|
|
8546
|
+
var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
|
|
8547
|
+
sourcePath = _Object$entries2$_i[0],
|
|
8548
|
+
list = _Object$entries2$_i[1];
|
|
8549
|
+
var _Internal$splitModule = Internal.splitModuleFilePathAndModulePath(sourcePath),
|
|
8550
|
+
_Internal$splitModule2 = _slicedToArray(_Internal$splitModule, 2),
|
|
8551
|
+
modulePath = _Internal$splitModule2[1];
|
|
8552
|
+
var path = modulePath ? Internal.createPatchPath(modulePath) : [];
|
|
8553
|
+
var _iterator = _createForOfIteratorHelper(list),
|
|
8554
|
+
_step;
|
|
8555
|
+
try {
|
|
8556
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
8557
|
+
var error = _step.value;
|
|
8558
|
+
if (error.fixes && error.fixes.length > 0) continue;
|
|
8559
|
+
errors.push({
|
|
8560
|
+
path: path,
|
|
8561
|
+
message: error.message
|
|
8562
|
+
});
|
|
8563
|
+
}
|
|
8564
|
+
} catch (err) {
|
|
8565
|
+
_iterator.e(err);
|
|
8566
|
+
} finally {
|
|
8567
|
+
_iterator.f();
|
|
8568
|
+
}
|
|
8569
|
+
}
|
|
8570
|
+
return errors;
|
|
8571
|
+
}
|
|
8572
|
+
|
|
8573
|
+
export { AA_LARGE, AA_TEXT, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, ModuleComparison, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchId, PatchJSON, PatchSets, PlanRefusalError, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SerializedVideoSchema, SharedValConfig, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, VAL_STUDIO_HEADER, ValCommit, ValDeployment, VideoOptions, VideoStreamOption, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, explainIncompatible, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, forEachRichTextImage, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, indexModule, isInsidePatchSetPath, isMimeTypeAccepted, isRemoteSchema, isSchemaSourceFixError, isSkippedSource, joinSharedChanges, keyOfRecordPath, levenshtein, localeAt, memoizePerRequest, newestCommitSha, parseArtifacts, parseBuildTarget, parseCancel, parseDeclare, parseDiscard, parseJob, parseNewestCiRun, parsePress, parseProblems, parseProjectSource, parsePromote, parsePublishToken, parseRenew, parseRequestStatus, parseStatus, parseUpdateTarget, parseVerify, partitionValidationErrors, performSearch, relativeLuminance, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextImageSchema, richTextToRemirror, safeParsePatch, schemaErrorsOf, schemaTypesOfPath, selectionClosure, sideFiles, sideSource, sourcePathOfChild, themeCustomProperties, toolNames, traverseSchemaSource, urlOf, validateRoutePatterns, withExtension };
|