tinacms 0.66.6 → 0.66.9
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 +35 -0
- package/dist/admin/api.d.ts +2 -0
- package/dist/edit-state.es.js +5 -1
- package/dist/edit-state.js +5 -1
- package/dist/hooks/formify/formify.d.ts +23 -0
- package/dist/hooks/formify/index.d.ts +11 -43
- package/dist/hooks/formify/reducer.d.ts +26 -0
- package/dist/hooks/formify/test/{to-be-similar-to.d.ts → runner.d.ts} +1 -1
- package/dist/hooks/formify/test/util.d.ts +25 -0
- package/dist/hooks/formify/types.d.ts +176 -0
- package/dist/hooks/formify/util.d.ts +103 -2
- package/dist/hooks/use-graphql-forms.d.ts +21 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +2378 -1137
- package/dist/index.js +2518 -1276
- package/dist/rich-text.es.js +4 -11
- package/dist/rich-text.js +4 -11
- package/package.json +4 -2
package/dist/index.es.js
CHANGED
|
@@ -29,17 +29,17 @@ var __objRest = (source, exclude) => {
|
|
|
29
29
|
}
|
|
30
30
|
return target;
|
|
31
31
|
};
|
|
32
|
-
import { EventBus, Modal, ModalPopup, ModalHeader, ModalBody, ModalActions, Button, LoadingDots, useLocalStorage, TinaCMS, BranchSwitcherPlugin, BranchDataProvider, TinaProvider,
|
|
32
|
+
import { useCMS, useBranchData, FormMetaPlugin, Form, GlobalFormPlugin, EventBus, Modal, ModalPopup, ModalHeader, ModalBody, ModalActions, Button, LoadingDots, useLocalStorage, TinaCMS, BranchSwitcherPlugin, BranchDataProvider, TinaProvider, Nav, LocalWarning, FormStatus, FormBuilder } from "@tinacms/toolkit";
|
|
33
33
|
export * from "@tinacms/toolkit";
|
|
34
34
|
import * as G from "graphql";
|
|
35
35
|
import { TypeInfo, visit, visitWithTypeInfo, getNamedType, GraphQLObjectType, isLeafType, GraphQLUnionType, isScalarType, getIntrospectionQuery, buildClientSchema, print, parse } from "graphql";
|
|
36
36
|
import set from "lodash.set";
|
|
37
37
|
import React, { useState, useCallback, useEffect, Fragment, useMemo } from "react";
|
|
38
|
+
import { getIn, setIn } from "final-form";
|
|
39
|
+
import * as yup from "yup";
|
|
38
40
|
import gql$1 from "graphql-tag";
|
|
39
41
|
import styled from "styled-components";
|
|
40
|
-
import * as yup from "yup";
|
|
41
42
|
import { setEditing, TinaDataContext, useEditState } from "@tinacms/sharedctx";
|
|
42
|
-
import { getIn, setIn } from "final-form";
|
|
43
43
|
import UrlPattern from "url-pattern";
|
|
44
44
|
import { NavLink, useNavigate, useParams, Link, HashRouter, Routes, Route } from "react-router-dom";
|
|
45
45
|
import { Menu, Transition } from "@headlessui/react";
|
|
@@ -376,210 +376,980 @@ function assertIsUnionType(type) {
|
|
|
376
376
|
throw new Error(`Expected an instance of GraphQLUnionType for type ${type.name}`);
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
throw new Error(`Expected GraphQLObjectType or GraphQLUnionType for isNodeField check`);
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
const isConnectionField = (type) => {
|
|
395
|
-
if (G.isObjectType(type)) {
|
|
396
|
-
return !!type.getInterfaces().find((intfc) => intfc.name === "Connection");
|
|
397
|
-
} else {
|
|
398
|
-
throw new Error(`Expected GraphQLObjectType for isCollectionField check`);
|
|
399
|
-
}
|
|
400
|
-
};
|
|
401
|
-
const getObjectField = (object, selectionNode) => {
|
|
402
|
-
return object.getFields()[selectionNode.name.value];
|
|
403
|
-
};
|
|
404
|
-
const getSelectedUnionType = (unionType, selectionNode) => {
|
|
405
|
-
return unionType.getTypes().find((type) => type.name === selectionNode.typeCondition.name.value);
|
|
379
|
+
const createClient = ({
|
|
380
|
+
clientId,
|
|
381
|
+
isLocalClient = true,
|
|
382
|
+
branch,
|
|
383
|
+
tinaioConfig
|
|
384
|
+
}) => {
|
|
385
|
+
return isLocalClient ? new LocalClient() : new Client({
|
|
386
|
+
clientId: clientId || "",
|
|
387
|
+
branch: branch || "main",
|
|
388
|
+
tokenStorage: "LOCAL_STORAGE",
|
|
389
|
+
tinaioConfig
|
|
390
|
+
});
|
|
406
391
|
};
|
|
407
|
-
function
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
throw new Error(`Expected type to be GraphQLUnionType`);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
function ensureObjectType(type) {
|
|
418
|
-
if (!G.isObjectType(type)) {
|
|
419
|
-
console.log(type);
|
|
420
|
-
throw new Error(`Expected type to be GraphQLObjectType`);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
function ensureOperationDefinition(type) {
|
|
424
|
-
if (type.kind !== "OperationDefinition") {
|
|
425
|
-
throw new Error(`Expected top-level definition to be an OperationDefinition node, ensure your query has been optimized before calling formify`);
|
|
392
|
+
function assertShape(value, yupSchema, errorMessage) {
|
|
393
|
+
const shape = yupSchema(yup);
|
|
394
|
+
try {
|
|
395
|
+
shape.validateSync(value);
|
|
396
|
+
} catch (e) {
|
|
397
|
+
const message = errorMessage || `Failed to assertShape - ${e.message}`;
|
|
398
|
+
throw new Error(message);
|
|
426
399
|
}
|
|
427
400
|
}
|
|
428
|
-
function
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
const node = G.parse(`
|
|
436
|
-
query Sample {
|
|
437
|
-
_internalSys: sys {
|
|
438
|
-
path
|
|
439
|
-
collection {
|
|
440
|
-
name
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
form
|
|
444
|
-
values
|
|
445
|
-
}`);
|
|
446
|
-
const metaFields = node.definitions[0].selectionSet.selections;
|
|
447
|
-
const NOOP = "This is either an error or is not yet supported";
|
|
448
|
-
const UNEXPECTED = "Formify encountered an unexpected error, please contact support";
|
|
449
|
-
const DATA_NODE_NAME = "data";
|
|
450
|
-
const EDGES_NODE_NAME = "edges";
|
|
451
|
-
const NODE_NAME = "node";
|
|
452
|
-
const COLLECTION_FIELD_NAME = "getCollection";
|
|
453
|
-
const COLLECTIONS_FIELD_NAME = "getCollections";
|
|
454
|
-
const COLLECTIONS_DOCUMENTS_NAME = "documents";
|
|
455
|
-
class FormifyError extends Error {
|
|
456
|
-
constructor(code, details) {
|
|
457
|
-
let message;
|
|
458
|
-
switch (code) {
|
|
459
|
-
case "NOOP":
|
|
460
|
-
message = NOOP;
|
|
461
|
-
break;
|
|
462
|
-
case "UNEXPECTED":
|
|
463
|
-
message = UNEXPECTED;
|
|
464
|
-
break;
|
|
465
|
-
default:
|
|
466
|
-
message = "";
|
|
467
|
-
break;
|
|
468
|
-
}
|
|
469
|
-
super(`${message} ${details || ""}`);
|
|
470
|
-
this.name = "FormifyError";
|
|
401
|
+
function safeAssertShape(value, yupSchema) {
|
|
402
|
+
try {
|
|
403
|
+
assertShape(value, yupSchema);
|
|
404
|
+
return true;
|
|
405
|
+
} catch (e) {
|
|
406
|
+
return false;
|
|
471
407
|
}
|
|
472
408
|
}
|
|
473
|
-
|
|
474
|
-
|
|
409
|
+
function useGraphqlFormsUnstable({
|
|
410
|
+
variables,
|
|
411
|
+
onSubmit,
|
|
475
412
|
query,
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
413
|
+
formify: formify2,
|
|
414
|
+
eventList
|
|
415
|
+
}) {
|
|
416
|
+
const cms = useCMS();
|
|
417
|
+
React.useEffect(() => {
|
|
418
|
+
console.log("NOTE: using unstable formify");
|
|
419
|
+
}, []);
|
|
420
|
+
const state = useFormify({
|
|
421
|
+
query,
|
|
422
|
+
cms,
|
|
423
|
+
variables,
|
|
424
|
+
formify: formify2,
|
|
425
|
+
eventList,
|
|
426
|
+
onSubmit
|
|
427
|
+
});
|
|
428
|
+
return [state.data, state.status !== "done"];
|
|
429
|
+
}
|
|
430
|
+
function useGraphqlForms({
|
|
431
|
+
variables,
|
|
432
|
+
onSubmit,
|
|
433
|
+
formify: formify2 = null,
|
|
434
|
+
query
|
|
435
|
+
}) {
|
|
436
|
+
const cms = useCMS();
|
|
437
|
+
const [formValues, setFormValues] = React.useState({});
|
|
438
|
+
const [data, setData] = React.useState(null);
|
|
439
|
+
const [initialData, setInitialData] = React.useState({});
|
|
440
|
+
const [pendingReset, setPendingReset] = React.useState(null);
|
|
441
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
442
|
+
const [newUpdate, setNewUpdate] = React.useState(null);
|
|
443
|
+
const { currentBranch } = useBranchData();
|
|
444
|
+
const updateData = async () => {
|
|
445
|
+
var _a;
|
|
446
|
+
if (newUpdate) {
|
|
447
|
+
const newValue = getIn(formValues, newUpdate.get);
|
|
448
|
+
const activeForm = getIn(data, [newUpdate.queryName, "form"].join("."));
|
|
449
|
+
if (!activeForm) {
|
|
450
|
+
throw new Error(`Unable to find form for query ${newUpdate.queryName}`);
|
|
489
451
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
return __spreadProps(__spreadValues({}, selectionNode), {
|
|
503
|
-
selectionSet: {
|
|
504
|
-
kind: "SelectionSet",
|
|
505
|
-
selections: selectionNode.selectionSet.selections.map((selectionNode2) => {
|
|
506
|
-
switch (selectionNode2.kind) {
|
|
507
|
-
case "Field":
|
|
508
|
-
if (selectionNode2.name.value === EDGES_NODE_NAME) {
|
|
509
|
-
const edgeField = namedFieldType.getFields()[EDGES_NODE_NAME];
|
|
510
|
-
const edgeType = G.getNamedType(edgeField.type);
|
|
511
|
-
ensureObjectType(edgeType);
|
|
512
|
-
return __spreadProps(__spreadValues({}, selectionNode2), {
|
|
513
|
-
selectionSet: {
|
|
514
|
-
kind: "SelectionSet",
|
|
515
|
-
selections: selectionNode2.selectionSet.selections.map((subSelectionNode) => {
|
|
516
|
-
switch (subSelectionNode.kind) {
|
|
517
|
-
case "Field":
|
|
518
|
-
if (subSelectionNode.name.value === NODE_NAME) {
|
|
519
|
-
const nodeField = edgeType.getFields()[NODE_NAME];
|
|
520
|
-
return formifyNode({
|
|
521
|
-
fieldOrInlineFragmentNode: subSelectionNode,
|
|
522
|
-
parentType: nodeField.type,
|
|
523
|
-
path: [
|
|
524
|
-
...path,
|
|
525
|
-
getNameAndAlias(selectionNode2),
|
|
526
|
-
getNameAndAlias(subSelectionNode, true)
|
|
527
|
-
]
|
|
528
|
-
});
|
|
529
|
-
} else {
|
|
530
|
-
return subSelectionNode;
|
|
531
|
-
}
|
|
532
|
-
default:
|
|
533
|
-
throw new FormifyError("NOOP");
|
|
534
|
-
}
|
|
535
|
-
})
|
|
536
|
-
}
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
return selectionNode2;
|
|
540
|
-
default:
|
|
541
|
-
throw new FormifyError("UNEXPECTED");
|
|
542
|
-
}
|
|
543
|
-
})
|
|
452
|
+
if (activeForm == null ? void 0 : activeForm.paths) {
|
|
453
|
+
const asyncUpdate = (_a = activeForm.paths) == null ? void 0 : _a.find((p) => p.dataPath.join(".") === newUpdate.setReference);
|
|
454
|
+
if (asyncUpdate) {
|
|
455
|
+
const res = await cms.api.tina.request(asyncUpdate.queryString, {
|
|
456
|
+
variables: { id: newValue }
|
|
457
|
+
});
|
|
458
|
+
const newData2 = setIn(data, newUpdate.set, res.node);
|
|
459
|
+
const newDataAndNewJSONData2 = setIn(newData2, newUpdate.set.replace("data", "dataJSON"), newValue);
|
|
460
|
+
setData(newDataAndNewJSONData2);
|
|
461
|
+
setNewUpdate(null);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
544
464
|
}
|
|
545
|
-
|
|
465
|
+
if (newUpdate.lookup) {
|
|
466
|
+
const field = getFieldUpdate(newUpdate, activeForm, formValues);
|
|
467
|
+
if (field && field.typeMap) {
|
|
468
|
+
newValue.forEach((item) => {
|
|
469
|
+
if (!item.__typename) {
|
|
470
|
+
item["__typename"] = field.typeMap[item._template];
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const newData = setIn(data, newUpdate.set, newValue);
|
|
476
|
+
const newDataAndNewJSONData = setIn(newData, newUpdate.set.replace("data", "dataJSON"), newValue);
|
|
477
|
+
setData(newDataAndNewJSONData);
|
|
478
|
+
setNewUpdate(null);
|
|
479
|
+
}
|
|
546
480
|
};
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
481
|
+
React.useEffect(() => {
|
|
482
|
+
updateData();
|
|
483
|
+
}, [JSON.stringify(formValues)]);
|
|
484
|
+
React.useEffect(() => {
|
|
485
|
+
if (pendingReset) {
|
|
486
|
+
setData(__spreadProps(__spreadValues({}, data), { [pendingReset]: initialData[pendingReset] }));
|
|
487
|
+
setPendingReset(null);
|
|
488
|
+
}
|
|
489
|
+
}, [pendingReset]);
|
|
490
|
+
React.useEffect(() => {
|
|
491
|
+
if (!query) {
|
|
492
|
+
setIsLoading(false);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const formIds = [];
|
|
496
|
+
setIsLoading(true);
|
|
497
|
+
cms.api.tina.requestWithForm((gql2) => gql2(query), {
|
|
498
|
+
variables,
|
|
499
|
+
useUnstableFormify: cms.flags.get("use-unstable-formify")
|
|
500
|
+
}).then((payload) => {
|
|
501
|
+
cms.plugins.remove(new FormMetaPlugin({ name: "tina-admin-link" }));
|
|
502
|
+
setData(payload);
|
|
503
|
+
setInitialData(payload);
|
|
504
|
+
setIsLoading(false);
|
|
505
|
+
Object.entries(payload).map(([queryName, result]) => {
|
|
506
|
+
formIds.push(queryName);
|
|
507
|
+
const canBeFormified = safeAssertShape(result, (yup2) => yup2.object({
|
|
508
|
+
values: yup2.object().required(),
|
|
509
|
+
form: yup2.object().required()
|
|
510
|
+
}));
|
|
511
|
+
if (!canBeFormified) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
assertShape(result, (yup2) => yup2.object({
|
|
515
|
+
values: yup2.object().required(),
|
|
516
|
+
form: yup2.object().required()
|
|
517
|
+
}), `Unable to build form shape for fields at ${queryName}`);
|
|
518
|
+
const formConfig = {
|
|
519
|
+
id: queryName,
|
|
520
|
+
label: result.form.label,
|
|
521
|
+
initialValues: result.values,
|
|
522
|
+
fields: result.form.fields,
|
|
523
|
+
reset: () => {
|
|
524
|
+
setPendingReset(queryName);
|
|
525
|
+
},
|
|
526
|
+
onSubmit: async (payload2) => {
|
|
527
|
+
try {
|
|
528
|
+
const params = transformDocumentIntoMutationRequestPayload(payload2, result.form.mutationInfo);
|
|
529
|
+
const variables2 = { params };
|
|
530
|
+
const mutationString = result.form.mutationInfo.string;
|
|
531
|
+
if (onSubmit) {
|
|
532
|
+
onSubmit({
|
|
533
|
+
queryString: mutationString,
|
|
534
|
+
mutationString,
|
|
535
|
+
variables: variables2
|
|
536
|
+
});
|
|
537
|
+
} else {
|
|
538
|
+
try {
|
|
539
|
+
await cms.api.tina.request(mutationString, {
|
|
540
|
+
variables: variables2
|
|
541
|
+
});
|
|
542
|
+
cms.alerts.success("Document saved!");
|
|
543
|
+
} catch (e) {
|
|
544
|
+
cms.alerts.error("There was a problem saving your document");
|
|
545
|
+
console.error(e);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
} catch (e) {
|
|
549
|
+
console.error(e);
|
|
550
|
+
cms.alerts.error("There was a problem saving your document");
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
const { createForm, createGlobalForm } = generateFormCreators(cms);
|
|
555
|
+
const SKIPPED = "SKIPPED";
|
|
556
|
+
let form;
|
|
557
|
+
let skipped;
|
|
558
|
+
const skip = () => {
|
|
559
|
+
skipped = SKIPPED;
|
|
560
|
+
};
|
|
561
|
+
if (skipped)
|
|
562
|
+
return;
|
|
563
|
+
if (formify2) {
|
|
564
|
+
form = formify2({ formConfig, createForm, createGlobalForm, skip }, cms);
|
|
565
|
+
} else {
|
|
566
|
+
form = createForm(formConfig);
|
|
567
|
+
}
|
|
568
|
+
if (!(form instanceof Form)) {
|
|
569
|
+
if (skipped === SKIPPED) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
throw new Error("formify must return a form or skip()");
|
|
573
|
+
}
|
|
574
|
+
const { change } = form.finalForm;
|
|
575
|
+
form.finalForm.change = (name, value) => {
|
|
576
|
+
let referenceName = "";
|
|
577
|
+
if (typeof name === "string") {
|
|
578
|
+
referenceName = name.split(".").filter((item) => isNaN(Number(item))).join(".");
|
|
579
|
+
} else {
|
|
580
|
+
throw new Error(`Expected name to be of type string for FinalForm change callback`);
|
|
581
|
+
}
|
|
582
|
+
setNewUpdate({
|
|
583
|
+
queryName,
|
|
584
|
+
get: [queryName, "values", name].join("."),
|
|
585
|
+
set: [queryName, "data", name].join("."),
|
|
586
|
+
setReference: [queryName, "data", referenceName].join(".")
|
|
587
|
+
});
|
|
588
|
+
return change(name, value);
|
|
589
|
+
};
|
|
590
|
+
const _a = form.finalForm.mutators, { insert, move, remove } = _a, rest = __objRest(_a, ["insert", "move", "remove"]);
|
|
591
|
+
const prepareNewUpdate = (name, lookup) => {
|
|
592
|
+
const extra = {};
|
|
593
|
+
if (lookup) {
|
|
594
|
+
extra["lookup"] = lookup;
|
|
595
|
+
}
|
|
596
|
+
const referenceName = name.split(".").filter((item) => isNaN(Number(item))).join(".");
|
|
597
|
+
setNewUpdate(__spreadValues({
|
|
598
|
+
queryName,
|
|
599
|
+
get: [queryName, "values", name].join("."),
|
|
600
|
+
set: [queryName, "data", name].join("."),
|
|
601
|
+
setReference: [queryName, "data", referenceName].join(".")
|
|
602
|
+
}, extra));
|
|
603
|
+
};
|
|
604
|
+
form.finalForm.mutators = __spreadValues({
|
|
605
|
+
insert: (...args) => {
|
|
606
|
+
const fieldName = args[0];
|
|
607
|
+
prepareNewUpdate(fieldName, fieldName);
|
|
608
|
+
insert(...args);
|
|
609
|
+
},
|
|
610
|
+
move: (...args) => {
|
|
611
|
+
const fieldName = args[0];
|
|
612
|
+
prepareNewUpdate(fieldName, fieldName);
|
|
613
|
+
move(...args);
|
|
614
|
+
},
|
|
615
|
+
remove: (...args) => {
|
|
616
|
+
const fieldName = args[0];
|
|
617
|
+
prepareNewUpdate(fieldName, fieldName);
|
|
618
|
+
remove(...args);
|
|
619
|
+
}
|
|
620
|
+
}, rest);
|
|
621
|
+
form.subscribe(({ values }) => {
|
|
622
|
+
setFormValues(__spreadProps(__spreadValues({}, formValues), { [queryName]: { values } }));
|
|
623
|
+
}, { values: true });
|
|
624
|
+
});
|
|
625
|
+
}).catch((e) => {
|
|
626
|
+
cms.alerts.error("There was a problem setting up forms for your query");
|
|
627
|
+
console.error("There was a problem setting up forms for your query");
|
|
628
|
+
console.error(e);
|
|
629
|
+
setIsLoading(false);
|
|
630
|
+
});
|
|
631
|
+
return () => {
|
|
632
|
+
formIds.forEach((name) => {
|
|
633
|
+
const formPlugin = cms.forms.find(name);
|
|
634
|
+
if (formPlugin) {
|
|
635
|
+
cms.forms.remove(formPlugin);
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
};
|
|
639
|
+
}, [query, JSON.stringify(variables), currentBranch]);
|
|
640
|
+
return [data, isLoading];
|
|
641
|
+
}
|
|
642
|
+
const transformDocumentIntoMutationRequestPayload = (document, instructions) => {
|
|
643
|
+
const _a = document, { _collection, __typename, _template } = _a, rest = __objRest(_a, ["_collection", "__typename", "_template"]);
|
|
644
|
+
const params = transformParams(rest);
|
|
645
|
+
const paramsWithTemplate = instructions.includeTemplate ? { [_template]: params } : params;
|
|
646
|
+
return instructions.includeCollection ? { [_collection]: paramsWithTemplate } : paramsWithTemplate;
|
|
647
|
+
};
|
|
648
|
+
const transformParams = (data) => {
|
|
649
|
+
if (["string", "number", "boolean"].includes(typeof data)) {
|
|
650
|
+
return data;
|
|
651
|
+
}
|
|
652
|
+
if (Array.isArray(data)) {
|
|
653
|
+
return data.map((item) => transformParams(item));
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
assertShape(data, (yup2) => yup2.object({ _template: yup2.string().required() }));
|
|
657
|
+
const _a = data, { _template, __typename } = _a, rest = __objRest(_a, ["_template", "__typename"]);
|
|
658
|
+
const nested = transformParams(rest);
|
|
659
|
+
return { [_template]: nested };
|
|
660
|
+
} catch (e) {
|
|
661
|
+
if (e.message === "Failed to assertShape - _template is a required field") {
|
|
662
|
+
if (!data) {
|
|
663
|
+
return [];
|
|
664
|
+
}
|
|
665
|
+
const accum = {};
|
|
666
|
+
Object.entries(data).map(([keyName, value]) => {
|
|
667
|
+
accum[keyName] = transformParams(value);
|
|
668
|
+
});
|
|
669
|
+
return accum;
|
|
670
|
+
} else {
|
|
671
|
+
if (!data) {
|
|
672
|
+
return [];
|
|
673
|
+
}
|
|
674
|
+
throw e;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
const getFieldUpdate = (newUpdate, activeForm, formValues) => {
|
|
679
|
+
const items = newUpdate.lookup.split(".");
|
|
680
|
+
let currentFields = activeForm.fields;
|
|
681
|
+
items.map((item, index) => {
|
|
682
|
+
const lookupName = items.slice(0, index + 1).join(".");
|
|
683
|
+
const value = getIn(formValues, [newUpdate.queryName, "values", lookupName].join("."));
|
|
684
|
+
if (isNaN(Number(item))) {
|
|
685
|
+
if (Array.isArray(currentFields)) {
|
|
686
|
+
currentFields = currentFields.find((field) => field.name === item);
|
|
687
|
+
}
|
|
688
|
+
} else {
|
|
689
|
+
const template = currentFields.templates ? currentFields.templates[value._template] : currentFields;
|
|
690
|
+
currentFields = template.fields;
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
return currentFields;
|
|
694
|
+
};
|
|
695
|
+
const generateFormCreators = (cms) => {
|
|
696
|
+
const createForm = (formConfig) => {
|
|
697
|
+
const form = new Form(formConfig);
|
|
698
|
+
cms.forms.add(form);
|
|
699
|
+
return form;
|
|
700
|
+
};
|
|
701
|
+
const createGlobalForm = (formConfig, options) => {
|
|
702
|
+
const form = new Form(formConfig);
|
|
703
|
+
cms.plugins.add(new GlobalFormPlugin(form, options == null ? void 0 : options.icon, options == null ? void 0 : options.layout));
|
|
704
|
+
return form;
|
|
705
|
+
};
|
|
706
|
+
return { createForm, createGlobalForm };
|
|
707
|
+
};
|
|
708
|
+
const generateFormCreatorsUnstable = (cms, showInSidebar) => {
|
|
709
|
+
const createForm = (formConfig) => {
|
|
710
|
+
const form = new Form(formConfig);
|
|
711
|
+
if (showInSidebar) {
|
|
712
|
+
cms.forms.add(form);
|
|
713
|
+
}
|
|
714
|
+
return form;
|
|
715
|
+
};
|
|
716
|
+
const createGlobalForm = (formConfig, options) => {
|
|
717
|
+
const form = new Form(formConfig);
|
|
718
|
+
if (showInSidebar) {
|
|
719
|
+
cms.plugins.add(new GlobalFormPlugin(form, options == null ? void 0 : options.icon, options == null ? void 0 : options.layout));
|
|
720
|
+
}
|
|
721
|
+
return form;
|
|
722
|
+
};
|
|
723
|
+
return { createForm, createGlobalForm };
|
|
724
|
+
};
|
|
725
|
+
const isNodeField = (type) => {
|
|
726
|
+
if (G.isUnionType(type)) {
|
|
727
|
+
return type.getTypes().every((type2) => {
|
|
728
|
+
return type2.getInterfaces().find((intfc) => intfc.name === "Node");
|
|
729
|
+
});
|
|
730
|
+
} else if (G.isObjectType(type)) {
|
|
731
|
+
return !!type.getInterfaces().find((intfc) => intfc.name === "Node");
|
|
732
|
+
} else if (G.isInterfaceType(type)) {
|
|
733
|
+
if (type.name === "Node") {
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
} else {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
const isConnectionField = (type) => {
|
|
741
|
+
if (G.isObjectType(type)) {
|
|
742
|
+
return !!type.getInterfaces().find((intfc) => intfc.name === "Connection");
|
|
743
|
+
} else {
|
|
744
|
+
throw new Error(`Expected GraphQLObjectType for isConnectionField check`);
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
const getObjectField = (object, selectionNode) => {
|
|
748
|
+
return object.getFields()[selectionNode.name.value];
|
|
749
|
+
};
|
|
750
|
+
const getSelectedUnionType = (unionType, selectionNode) => {
|
|
751
|
+
return unionType.getTypes().find((type) => type.name === selectionNode.typeCondition.name.value);
|
|
752
|
+
};
|
|
753
|
+
function isListType(type) {
|
|
754
|
+
if (G.isListType(type)) {
|
|
755
|
+
return true;
|
|
756
|
+
} else if (G.isNonNullType(type)) {
|
|
757
|
+
if (G.isListType(type.ofType)) {
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
function ensureNodeField(field) {
|
|
764
|
+
if (!isNodeField(field)) {
|
|
765
|
+
throw new Error(`Expected field to implement Node interface`);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function ensureUnionType(type) {
|
|
769
|
+
if (!G.isUnionType(type)) {
|
|
770
|
+
throw new Error(`Expected type to be GraphQLUnionType`);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
function ensureObjectType(type) {
|
|
774
|
+
if (!G.isObjectType(type)) {
|
|
775
|
+
console.log(type);
|
|
776
|
+
throw new Error(`Expected type to be GraphQLObjectType`);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
function ensureOperationDefinition(type) {
|
|
780
|
+
if (type.kind !== "OperationDefinition") {
|
|
781
|
+
throw new Error(`Expected top-level definition to be an OperationDefinition node, ensure your query has been optimized before calling formify`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
function getNameAndAlias(fieldNode, list, isNode) {
|
|
785
|
+
return {
|
|
786
|
+
name: fieldNode.name.value,
|
|
787
|
+
alias: fieldNode.alias ? fieldNode.alias.value : fieldNode.name.value,
|
|
788
|
+
list: !!list,
|
|
789
|
+
isNode: !!isNode
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
const node = G.parse(`
|
|
793
|
+
query Sample {
|
|
794
|
+
_internalSys: sys {
|
|
795
|
+
path
|
|
796
|
+
collection {
|
|
797
|
+
name
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
form
|
|
801
|
+
values
|
|
802
|
+
}`);
|
|
803
|
+
const metaFields = node.definitions[0].selectionSet.selections;
|
|
804
|
+
const getRelativeBlueprint = (path) => {
|
|
805
|
+
let indexOfLastNode = 0;
|
|
806
|
+
path.forEach((item, i) => {
|
|
807
|
+
if (item.isNode) {
|
|
808
|
+
if (i === path.length - 1)
|
|
809
|
+
;
|
|
810
|
+
else {
|
|
811
|
+
indexOfLastNode = i;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
const documentBlueprintPath = path.slice(0, indexOfLastNode + 1);
|
|
816
|
+
return getBlueprintNamePath({ path: documentBlueprintPath });
|
|
817
|
+
};
|
|
818
|
+
const getIn2 = (state, path) => {
|
|
819
|
+
const pathArray = path.split(".");
|
|
820
|
+
let latest = state;
|
|
821
|
+
pathArray.every((item, index) => {
|
|
822
|
+
if (item === "[]") {
|
|
823
|
+
const restOfItems = pathArray.slice(index + 1);
|
|
824
|
+
if (latest) {
|
|
825
|
+
const next = [];
|
|
826
|
+
if (Array.isArray(latest)) {
|
|
827
|
+
latest.forEach((latest2, index2) => {
|
|
828
|
+
const res = getIn2(latest2, restOfItems.join("."));
|
|
829
|
+
next.push(res);
|
|
830
|
+
});
|
|
831
|
+
} else {
|
|
832
|
+
throw new Error(`Expected value to be an array for "[]" item`);
|
|
833
|
+
}
|
|
834
|
+
if (next.length > 0) {
|
|
835
|
+
latest = next;
|
|
836
|
+
} else {
|
|
837
|
+
latest = void 0;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return false;
|
|
841
|
+
} else {
|
|
842
|
+
if (latest) {
|
|
843
|
+
latest = latest[item];
|
|
844
|
+
} else {
|
|
845
|
+
latest = void 0;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return true;
|
|
849
|
+
});
|
|
850
|
+
return latest;
|
|
851
|
+
};
|
|
852
|
+
const getFieldNameOrAlias = (fieldBlueprint) => {
|
|
853
|
+
return fieldBlueprint.path[fieldBlueprint.path.length - 1].alias;
|
|
854
|
+
};
|
|
855
|
+
const spliceLocation = (string, location) => {
|
|
856
|
+
const accum = [];
|
|
857
|
+
let counter = 0;
|
|
858
|
+
string.split(".").forEach((item) => {
|
|
859
|
+
if (item === "[]") {
|
|
860
|
+
accum.push(location[counter]);
|
|
861
|
+
counter++;
|
|
862
|
+
} else {
|
|
863
|
+
accum.push(item);
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
return accum.join(".");
|
|
867
|
+
};
|
|
868
|
+
const getPathToChange = (documentBlueprint, formNode, event) => {
|
|
869
|
+
const fieldName = event.field.name;
|
|
870
|
+
const location = [...formNode.location, ...stripIndices(fieldName)];
|
|
871
|
+
const accum = [];
|
|
872
|
+
let counter = 0;
|
|
873
|
+
documentBlueprint.path.forEach((item) => {
|
|
874
|
+
accum.push(item.alias);
|
|
875
|
+
if (item.list) {
|
|
876
|
+
if (location[counter] !== void 0) {
|
|
877
|
+
accum.push(location[counter]);
|
|
878
|
+
counter++;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
return accum.join(".");
|
|
883
|
+
};
|
|
884
|
+
const buildForm = (doc, cms, formify2, showInSidebar = false, onSubmit) => {
|
|
885
|
+
const { createForm, createGlobalForm } = generateFormCreatorsUnstable(cms, showInSidebar);
|
|
886
|
+
const SKIPPED = "SKIPPED";
|
|
887
|
+
let form;
|
|
888
|
+
let skipped;
|
|
889
|
+
const skip = () => {
|
|
890
|
+
skipped = SKIPPED;
|
|
891
|
+
};
|
|
892
|
+
if (skipped)
|
|
893
|
+
return;
|
|
894
|
+
const id = doc._internalSys.path;
|
|
895
|
+
const formConfig = __spreadProps(__spreadValues({
|
|
896
|
+
id
|
|
897
|
+
}, doc.form), {
|
|
898
|
+
label: doc.form.label,
|
|
899
|
+
initialValues: doc.values,
|
|
900
|
+
onSubmit: async (payload) => {
|
|
901
|
+
try {
|
|
902
|
+
const params = transformDocumentIntoMutationRequestPayload(payload, doc.form.mutationInfo);
|
|
903
|
+
const variables = { params };
|
|
904
|
+
const mutationString = doc.form.mutationInfo.string;
|
|
905
|
+
if (onSubmit) {
|
|
906
|
+
onSubmit({
|
|
907
|
+
queryString: mutationString,
|
|
908
|
+
mutationString,
|
|
909
|
+
variables
|
|
910
|
+
});
|
|
911
|
+
} else {
|
|
912
|
+
try {
|
|
913
|
+
await cms.api.tina.request(mutationString, {
|
|
914
|
+
variables
|
|
915
|
+
});
|
|
916
|
+
cms.alerts.success("Document saved!");
|
|
917
|
+
} catch (e) {
|
|
918
|
+
cms.alerts.error("There was a problem saving your document");
|
|
919
|
+
console.error(e);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
} catch (e) {
|
|
923
|
+
console.error(e);
|
|
924
|
+
cms.alerts.error("There was a problem saving your document");
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
if (formify2) {
|
|
929
|
+
form = formify2({
|
|
930
|
+
formConfig,
|
|
931
|
+
createForm,
|
|
932
|
+
createGlobalForm,
|
|
933
|
+
skip
|
|
934
|
+
}, cms);
|
|
935
|
+
} else {
|
|
936
|
+
form = createForm(formConfig);
|
|
937
|
+
}
|
|
938
|
+
if (!(form instanceof Form)) {
|
|
939
|
+
if (skipped === SKIPPED) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
throw new Error("formify must return a form or skip()");
|
|
943
|
+
}
|
|
944
|
+
return form;
|
|
945
|
+
};
|
|
946
|
+
const formNodeId = (formNode) => {
|
|
947
|
+
return spliceLocation(formNode.documentBlueprintId, formNode.location) + formNode.documentFormId;
|
|
948
|
+
};
|
|
949
|
+
const formNodePath = (formNode) => {
|
|
950
|
+
return spliceLocation(formNode.documentBlueprintId, formNode.location);
|
|
951
|
+
};
|
|
952
|
+
const formNodeNotIn = (formNode, formNodes) => {
|
|
953
|
+
return !formNodes.find((fn) => formNodeId(fn) === formNodeId(formNode));
|
|
954
|
+
};
|
|
955
|
+
const sequential = async (items, callback) => {
|
|
956
|
+
const accum = [];
|
|
957
|
+
if (!items) {
|
|
958
|
+
return [];
|
|
959
|
+
}
|
|
960
|
+
const reducePromises = async (previous, endpoint) => {
|
|
961
|
+
const prev = await previous;
|
|
962
|
+
if (prev) {
|
|
963
|
+
accum.push(prev);
|
|
964
|
+
}
|
|
965
|
+
return callback(endpoint, accum.length);
|
|
966
|
+
};
|
|
967
|
+
const result = await items.reduce(reducePromises, Promise.resolve());
|
|
968
|
+
if (result) {
|
|
969
|
+
accum.push(result);
|
|
970
|
+
}
|
|
971
|
+
return accum;
|
|
972
|
+
};
|
|
973
|
+
const getBlueprintId = (path) => {
|
|
974
|
+
const namePath = [];
|
|
975
|
+
const aliasPath = [];
|
|
976
|
+
path.forEach((p) => {
|
|
977
|
+
namePath.push(p.name);
|
|
978
|
+
aliasPath.push(p.alias);
|
|
979
|
+
if (p.list) {
|
|
980
|
+
namePath.push("[]");
|
|
981
|
+
aliasPath.push("[]");
|
|
982
|
+
}
|
|
983
|
+
});
|
|
984
|
+
return namePath.join(".");
|
|
985
|
+
};
|
|
986
|
+
const getFormNodesStartingWith = (string, state) => {
|
|
987
|
+
return state.formNodes.filter((subFormNode) => {
|
|
988
|
+
return subFormNode.documentBlueprintId.startsWith(string);
|
|
989
|
+
});
|
|
990
|
+
};
|
|
991
|
+
const getFormNodesForField = (fieldBlueprint, formNode, event, state) => {
|
|
992
|
+
const pathToChange = getPathToChange(fieldBlueprint, formNode, event);
|
|
993
|
+
const formNodes = getFormNodesStartingWith(fieldBlueprint.id, state);
|
|
994
|
+
const eventLocation = [
|
|
995
|
+
...formNode.location,
|
|
996
|
+
...stripIndices(event.field.name)
|
|
997
|
+
];
|
|
998
|
+
const existing = getIn(state.data, pathToChange);
|
|
999
|
+
return { pathToChange, formNodes, eventLocation, existing };
|
|
1000
|
+
};
|
|
1001
|
+
const matchLocation = (eventLocation, formNode) => {
|
|
1002
|
+
return eventLocation.every((item, index) => item === formNode.location[index]);
|
|
1003
|
+
};
|
|
1004
|
+
const bumpLocation = (location) => {
|
|
1005
|
+
return location.map((item, index) => {
|
|
1006
|
+
if (index === location.length - 1) {
|
|
1007
|
+
return item + 1;
|
|
1008
|
+
}
|
|
1009
|
+
return item;
|
|
1010
|
+
});
|
|
1011
|
+
};
|
|
1012
|
+
const maybeLowerLocation = (location, at) => {
|
|
1013
|
+
return location.map((item, index) => {
|
|
1014
|
+
if (index === location.length - 1) {
|
|
1015
|
+
return item < at ? item : item - 1;
|
|
1016
|
+
}
|
|
1017
|
+
return item;
|
|
1018
|
+
});
|
|
1019
|
+
};
|
|
1020
|
+
const matchesAt = (location, at) => {
|
|
1021
|
+
let matches = false;
|
|
1022
|
+
location.map((item, index) => {
|
|
1023
|
+
if (index === location.length - 1) {
|
|
1024
|
+
if (item === at) {
|
|
1025
|
+
matches = true;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
return matches;
|
|
1030
|
+
};
|
|
1031
|
+
const swapLocation = (location, mapping) => {
|
|
1032
|
+
return location.map((item, index) => {
|
|
1033
|
+
if (index === location.length - 1) {
|
|
1034
|
+
return mapping[item];
|
|
1035
|
+
}
|
|
1036
|
+
return item;
|
|
1037
|
+
});
|
|
1038
|
+
};
|
|
1039
|
+
const getBlueprintAliasPath = (blueprint) => {
|
|
1040
|
+
const namePath = [];
|
|
1041
|
+
const aliasPath = [];
|
|
1042
|
+
blueprint.path.forEach((p) => {
|
|
1043
|
+
namePath.push(p.name);
|
|
1044
|
+
aliasPath.push(p.alias);
|
|
1045
|
+
if (p.list) {
|
|
1046
|
+
namePath.push("[]");
|
|
1047
|
+
aliasPath.push("[]");
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
return aliasPath.join(".");
|
|
1051
|
+
};
|
|
1052
|
+
const getBlueprintFieldsForEvent = (blueprint, event) => {
|
|
1053
|
+
return blueprint.fields.filter((fbp) => {
|
|
1054
|
+
return getBlueprintNamePath(fbp) === getEventPath(event, blueprint);
|
|
1055
|
+
});
|
|
1056
|
+
};
|
|
1057
|
+
const getBlueprintNamePath = (blueprint) => {
|
|
1058
|
+
const namePath = [];
|
|
1059
|
+
const aliasPath = [];
|
|
1060
|
+
blueprint.path.forEach((p) => {
|
|
1061
|
+
namePath.push(p.name);
|
|
1062
|
+
aliasPath.push(p.alias);
|
|
1063
|
+
if (p.list) {
|
|
1064
|
+
namePath.push("[]");
|
|
1065
|
+
aliasPath.push("[]");
|
|
1066
|
+
}
|
|
1067
|
+
});
|
|
1068
|
+
return namePath.join(".");
|
|
1069
|
+
};
|
|
1070
|
+
const stripIndices = (string) => {
|
|
1071
|
+
const accum = [];
|
|
1072
|
+
const stringArray = string.split(".");
|
|
1073
|
+
stringArray.forEach((item) => {
|
|
1074
|
+
if (isNaN(item))
|
|
1075
|
+
;
|
|
1076
|
+
else {
|
|
1077
|
+
accum.push(Number(item));
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
return accum;
|
|
1081
|
+
};
|
|
1082
|
+
const replaceRealNum = (string) => {
|
|
1083
|
+
const stringArray = string.split(".");
|
|
1084
|
+
return stringArray.map((item) => {
|
|
1085
|
+
if (isNaN(item)) {
|
|
1086
|
+
return item;
|
|
1087
|
+
}
|
|
1088
|
+
return "[]";
|
|
1089
|
+
}).join(".");
|
|
1090
|
+
};
|
|
1091
|
+
const getFormNodesFromEvent = (state, event) => {
|
|
1092
|
+
const formNodes = state.formNodes.filter((formNode) => formNode.documentFormId === event.formId);
|
|
1093
|
+
return formNodes;
|
|
1094
|
+
};
|
|
1095
|
+
const DATA_NODE_NAME$1 = "data";
|
|
1096
|
+
const getEventPath = (event, blueprint) => {
|
|
1097
|
+
const eventPath = replaceRealNum(event.field.name);
|
|
1098
|
+
const items = [blueprint.id, DATA_NODE_NAME$1, eventPath];
|
|
1099
|
+
const isList = event.field.data.tinaField.list;
|
|
1100
|
+
if (isList && !eventPath.endsWith("[]")) {
|
|
1101
|
+
items.push("[]");
|
|
1102
|
+
}
|
|
1103
|
+
return items.join(".");
|
|
1104
|
+
};
|
|
1105
|
+
const printEvent = (event) => {
|
|
1106
|
+
var _a, _b;
|
|
1107
|
+
return {
|
|
1108
|
+
type: event.type,
|
|
1109
|
+
value: event.value,
|
|
1110
|
+
previousValue: event.previousValue,
|
|
1111
|
+
mutationType: event.mutationType,
|
|
1112
|
+
formId: event.formId,
|
|
1113
|
+
field: {
|
|
1114
|
+
data: (_a = event.field) == null ? void 0 : _a.data,
|
|
1115
|
+
name: (_b = event.field) == null ? void 0 : _b.name
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
};
|
|
1119
|
+
const getFormNodeBlueprint = (formNode, state) => {
|
|
1120
|
+
return state.blueprints.find((d) => d.id === formNode.documentBlueprintId);
|
|
1121
|
+
};
|
|
1122
|
+
const getMoveMapping = (existing, from, to) => {
|
|
1123
|
+
const newOrderObject = {};
|
|
1124
|
+
if (from < to) {
|
|
1125
|
+
existing.map((_, i) => {
|
|
1126
|
+
if (i === from) {
|
|
1127
|
+
newOrderObject[i] = to;
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
if (i > from) {
|
|
1131
|
+
if (i < to) {
|
|
1132
|
+
newOrderObject[i] = i - 1;
|
|
1133
|
+
return;
|
|
1134
|
+
} else {
|
|
1135
|
+
if (i === to) {
|
|
1136
|
+
newOrderObject[i] = i - 1;
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
newOrderObject[i] = i;
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
} else {
|
|
1143
|
+
newOrderObject[i] = i;
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
1147
|
+
} else {
|
|
1148
|
+
existing.map((_, i) => {
|
|
1149
|
+
if (i === from) {
|
|
1150
|
+
newOrderObject[i] = to;
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
if (i > to) {
|
|
1154
|
+
if (i < from) {
|
|
1155
|
+
newOrderObject[i] = i + 1;
|
|
1156
|
+
return;
|
|
1157
|
+
} else {
|
|
1158
|
+
newOrderObject[i] = i;
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
} else {
|
|
1162
|
+
if (i === to) {
|
|
1163
|
+
newOrderObject[i] = i + 1;
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
newOrderObject[i] = i;
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
return newOrderObject;
|
|
1172
|
+
};
|
|
1173
|
+
const getPathsToChange = (event, state) => {
|
|
1174
|
+
const pathsToChange = [];
|
|
1175
|
+
const formNodes = getFormNodesFromEvent(state, event);
|
|
1176
|
+
formNodes.forEach((formNode) => {
|
|
1177
|
+
const blueprint = getFormNodeBlueprint(formNode, state);
|
|
1178
|
+
getBlueprintFieldsForEvent(blueprint, event).forEach((fieldBlueprint) => {
|
|
1179
|
+
const pathToChange = getPathToChange(fieldBlueprint, formNode, event);
|
|
1180
|
+
pathsToChange.push({ pathToChange, formNode });
|
|
1181
|
+
});
|
|
1182
|
+
});
|
|
1183
|
+
return pathsToChange;
|
|
1184
|
+
};
|
|
1185
|
+
const getSubFields = (changeSet) => {
|
|
1186
|
+
var _a;
|
|
1187
|
+
const fields = changeSet.fieldDefinition.fields ? changeSet.fieldDefinition.fields : changeSet.fieldDefinition.templates[changeSet.value[0]._template].fields;
|
|
1188
|
+
let __typename;
|
|
1189
|
+
if ((_a = changeSet.fieldDefinition) == null ? void 0 : _a.templates) {
|
|
1190
|
+
__typename = changeSet.fieldDefinition.typeMap[changeSet.value[0]._template];
|
|
1191
|
+
}
|
|
1192
|
+
return { fields, __typename };
|
|
1193
|
+
};
|
|
1194
|
+
const NOOP = "This is either an error or is not yet supported";
|
|
1195
|
+
const UNEXPECTED = "Formify encountered an unexpected error, please contact support";
|
|
1196
|
+
const EDGES_NODE_NAME = "edges";
|
|
1197
|
+
const NODE_NAME = "node";
|
|
1198
|
+
const COLLECTION_FIELD_NAME = "getCollection";
|
|
1199
|
+
const COLLECTIONS_FIELD_NAME = "getCollections";
|
|
1200
|
+
const COLLECTIONS_DOCUMENTS_NAME = "documents";
|
|
1201
|
+
const DATA_NODE_NAME = "data";
|
|
1202
|
+
const formify = async ({
|
|
1203
|
+
schema,
|
|
1204
|
+
query,
|
|
1205
|
+
getOptimizedQuery
|
|
1206
|
+
}) => {
|
|
1207
|
+
const blueprints = [];
|
|
1208
|
+
const documentNode = G.parse(query);
|
|
1209
|
+
const visitor = {
|
|
1210
|
+
OperationDefinition: (node2) => {
|
|
1211
|
+
if (!node2.name) {
|
|
1212
|
+
return __spreadProps(__spreadValues({}, node2), {
|
|
1213
|
+
name: {
|
|
1214
|
+
kind: "Name",
|
|
1215
|
+
value: `QueryOperation`
|
|
1216
|
+
}
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
return node2;
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
const documentNodeWithName = G.visit(documentNode, visitor);
|
|
1223
|
+
const optimizedQuery = await getOptimizedQuery(documentNodeWithName);
|
|
1224
|
+
const typeInfo = new G.TypeInfo(schema);
|
|
1225
|
+
const formifyConnection = ({
|
|
1226
|
+
namedFieldType,
|
|
1227
|
+
selectionNode,
|
|
1228
|
+
path
|
|
1229
|
+
}) => {
|
|
1230
|
+
ensureObjectType(namedFieldType);
|
|
1231
|
+
return __spreadProps(__spreadValues({}, selectionNode), {
|
|
1232
|
+
selectionSet: {
|
|
1233
|
+
kind: "SelectionSet",
|
|
1234
|
+
selections: selectionNode.selectionSet.selections.map((selectionNode2) => {
|
|
1235
|
+
switch (selectionNode2.kind) {
|
|
1236
|
+
case "Field":
|
|
1237
|
+
if (selectionNode2.name.value === EDGES_NODE_NAME) {
|
|
1238
|
+
const edgeField = namedFieldType.getFields()[EDGES_NODE_NAME];
|
|
1239
|
+
const edgeType = G.getNamedType(edgeField.type);
|
|
1240
|
+
ensureObjectType(edgeType);
|
|
1241
|
+
const path2 = [
|
|
1242
|
+
...path,
|
|
1243
|
+
getNameAndAlias(selectionNode2, true, false)
|
|
1244
|
+
];
|
|
1245
|
+
return __spreadProps(__spreadValues({}, selectionNode2), {
|
|
1246
|
+
selectionSet: {
|
|
1247
|
+
kind: "SelectionSet",
|
|
1248
|
+
selections: selectionNode2.selectionSet.selections.map((subSelectionNode) => {
|
|
1249
|
+
switch (subSelectionNode.kind) {
|
|
1250
|
+
case "Field":
|
|
1251
|
+
if (subSelectionNode.name.value === NODE_NAME) {
|
|
1252
|
+
const nodeField = edgeType.getFields()[NODE_NAME];
|
|
1253
|
+
const path3 = [
|
|
1254
|
+
...path2,
|
|
1255
|
+
getNameAndAlias(subSelectionNode, false, true)
|
|
1256
|
+
];
|
|
1257
|
+
return formifyNode({
|
|
1258
|
+
fieldOrInlineFragmentNode: subSelectionNode,
|
|
1259
|
+
type: nodeField.type,
|
|
1260
|
+
path: path3,
|
|
1261
|
+
showInSidebar: false
|
|
1262
|
+
});
|
|
1263
|
+
} else {
|
|
1264
|
+
return subSelectionNode;
|
|
1265
|
+
}
|
|
1266
|
+
default:
|
|
1267
|
+
throw new FormifyError("NOOP");
|
|
1268
|
+
}
|
|
1269
|
+
})
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
return selectionNode2;
|
|
1274
|
+
default:
|
|
1275
|
+
throw new FormifyError("UNEXPECTED");
|
|
1276
|
+
}
|
|
1277
|
+
})
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
};
|
|
1281
|
+
function formifyNode({
|
|
1282
|
+
fieldOrInlineFragmentNode,
|
|
1283
|
+
type,
|
|
1284
|
+
path,
|
|
1285
|
+
showInSidebar = false
|
|
1286
|
+
}) {
|
|
1287
|
+
let extraFields = [];
|
|
1288
|
+
const namedType = G.getNamedType(type);
|
|
1289
|
+
let hasDataJSONField = false;
|
|
1290
|
+
let hasValuesField = false;
|
|
1291
|
+
let shouldFormify = false;
|
|
1292
|
+
fieldOrInlineFragmentNode.selectionSet.selections.forEach((selection) => {
|
|
1293
|
+
if (selection.kind === "Field") {
|
|
1294
|
+
if (selection.name.value === "dataJSON") {
|
|
1295
|
+
shouldFormify = true;
|
|
1296
|
+
hasDataJSONField = true;
|
|
1297
|
+
}
|
|
1298
|
+
if (selection.name.value === "values") {
|
|
1299
|
+
shouldFormify = true;
|
|
1300
|
+
hasValuesField = true;
|
|
1301
|
+
}
|
|
1302
|
+
if (selection.name.value === "data") {
|
|
1303
|
+
shouldFormify = true;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
});
|
|
1307
|
+
if (shouldFormify) {
|
|
1308
|
+
blueprints.push({
|
|
1309
|
+
id: getBlueprintId(path),
|
|
1310
|
+
path,
|
|
1311
|
+
selection: fieldOrInlineFragmentNode,
|
|
1312
|
+
fields: [],
|
|
1313
|
+
showInSidebar,
|
|
1314
|
+
hasDataJSONField,
|
|
1315
|
+
hasValuesField
|
|
1316
|
+
});
|
|
1317
|
+
extraFields = metaFields;
|
|
1318
|
+
}
|
|
1319
|
+
const formifiedNode = __spreadProps(__spreadValues({}, fieldOrInlineFragmentNode), {
|
|
1320
|
+
selectionSet: {
|
|
1321
|
+
kind: "SelectionSet",
|
|
1322
|
+
selections: [
|
|
1323
|
+
...fieldOrInlineFragmentNode.selectionSet.selections.map((selectionNode) => {
|
|
1324
|
+
switch (selectionNode.kind) {
|
|
1325
|
+
case "InlineFragment":
|
|
1326
|
+
if (G.isInterfaceType(namedType)) {
|
|
1327
|
+
const subType2 = schema.getImplementations(namedType).objects.find((item) => item.name === selectionNode.typeCondition.name.value);
|
|
1328
|
+
return formifyNode({
|
|
1329
|
+
fieldOrInlineFragmentNode: selectionNode,
|
|
1330
|
+
type: subType2,
|
|
1331
|
+
path,
|
|
1332
|
+
showInSidebar: false
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
ensureUnionType(namedType);
|
|
1336
|
+
const subType = getSelectedUnionType(namedType, selectionNode);
|
|
1337
|
+
return formifyNode({
|
|
1338
|
+
fieldOrInlineFragmentNode: selectionNode,
|
|
1339
|
+
type: subType,
|
|
1340
|
+
path,
|
|
1341
|
+
showInSidebar
|
|
1342
|
+
});
|
|
576
1343
|
case "Field":
|
|
577
1344
|
if (selectionNode.name.value === DATA_NODE_NAME) {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
1345
|
+
const path2 = [
|
|
1346
|
+
...path,
|
|
1347
|
+
getNameAndAlias(selectionNode, false, false)
|
|
1348
|
+
];
|
|
1349
|
+
if (G.isObjectType(namedType)) {
|
|
1350
|
+
const field = getObjectField(namedType, selectionNode);
|
|
1351
|
+
const namedSubType = G.getNamedType(field.type);
|
|
1352
|
+
ensureObjectType(namedSubType);
|
|
583
1353
|
return __spreadProps(__spreadValues({}, selectionNode), {
|
|
584
1354
|
selectionSet: {
|
|
585
1355
|
kind: "SelectionSet",
|
|
@@ -587,16 +1357,17 @@ const formify = async ({
|
|
|
587
1357
|
...selectionNode.selectionSet.selections.map((subSelectionNode) => {
|
|
588
1358
|
switch (subSelectionNode.kind) {
|
|
589
1359
|
case "Field":
|
|
590
|
-
const subSelectionField = getObjectField(
|
|
1360
|
+
const subSelectionField = getObjectField(namedSubType, subSelectionNode);
|
|
591
1361
|
if (!subSelectionField) {
|
|
592
1362
|
return subSelectionNode;
|
|
593
1363
|
}
|
|
1364
|
+
const subSelectionType = G.getNamedType(subSelectionField.type);
|
|
594
1365
|
return formifyField({
|
|
595
1366
|
fieldNode: subSelectionNode,
|
|
596
1367
|
parentType: field.type,
|
|
597
1368
|
path: [
|
|
598
|
-
...
|
|
599
|
-
getNameAndAlias(subSelectionNode,
|
|
1369
|
+
...path2,
|
|
1370
|
+
getNameAndAlias(subSelectionNode, isListType(subSelectionField.type), isNodeField(subSelectionType))
|
|
600
1371
|
]
|
|
601
1372
|
});
|
|
602
1373
|
default:
|
|
@@ -607,7 +1378,7 @@ const formify = async ({
|
|
|
607
1378
|
}
|
|
608
1379
|
});
|
|
609
1380
|
}
|
|
610
|
-
|
|
1381
|
+
throw new FormifyError("UNEXPECTED");
|
|
611
1382
|
}
|
|
612
1383
|
return selectionNode;
|
|
613
1384
|
default:
|
|
@@ -636,6 +1407,13 @@ const formify = async ({
|
|
|
636
1407
|
}
|
|
637
1408
|
}
|
|
638
1409
|
const namedType = G.getNamedType(field.type);
|
|
1410
|
+
const fieldBlueprint = {
|
|
1411
|
+
id: getBlueprintId([...path]),
|
|
1412
|
+
documentBlueprintId: getRelativeBlueprint(path),
|
|
1413
|
+
path: [...path]
|
|
1414
|
+
};
|
|
1415
|
+
const blueprint = blueprints.find((blueprint2) => blueprint2.id === getRelativeBlueprint(path));
|
|
1416
|
+
blueprint.fields.push(fieldBlueprint);
|
|
639
1417
|
if (G.isScalarType(namedType)) {
|
|
640
1418
|
return fieldNode;
|
|
641
1419
|
}
|
|
@@ -650,37 +1428,75 @@ const formify = async ({
|
|
|
650
1428
|
return selectionNode;
|
|
651
1429
|
}
|
|
652
1430
|
ensureObjectType(namedType);
|
|
653
|
-
const
|
|
654
|
-
if (!
|
|
1431
|
+
const subField = getObjectField(namedType, selectionNode);
|
|
1432
|
+
if (!subField) {
|
|
655
1433
|
return fieldNode;
|
|
656
1434
|
}
|
|
657
|
-
if (G.isScalarType(G.getNamedType(
|
|
1435
|
+
if (G.isScalarType(G.getNamedType(subField.type))) {
|
|
1436
|
+
const newPath2 = [
|
|
1437
|
+
...path,
|
|
1438
|
+
getNameAndAlias(selectionNode, isListType(subField.type), false)
|
|
1439
|
+
];
|
|
1440
|
+
const fieldBlueprint3 = {
|
|
1441
|
+
id: getBlueprintId(newPath2),
|
|
1442
|
+
documentBlueprintId: getRelativeBlueprint(newPath2),
|
|
1443
|
+
path: newPath2
|
|
1444
|
+
};
|
|
1445
|
+
const blueprint3 = blueprints.find((blueprint4) => blueprint4.id === getRelativeBlueprint(path));
|
|
1446
|
+
blueprint3.fields.push(fieldBlueprint3);
|
|
658
1447
|
return selectionNode;
|
|
659
1448
|
}
|
|
1449
|
+
const subFieldType = subField.type;
|
|
1450
|
+
const namedSubFieldType = G.getNamedType(subFieldType);
|
|
1451
|
+
const newPath = [
|
|
1452
|
+
...path,
|
|
1453
|
+
getNameAndAlias(selectionNode, isListType(subFieldType), isNodeField(namedSubFieldType))
|
|
1454
|
+
];
|
|
1455
|
+
const fieldBlueprint2 = {
|
|
1456
|
+
id: getBlueprintId(newPath),
|
|
1457
|
+
documentBlueprintId: getRelativeBlueprint(newPath),
|
|
1458
|
+
path: newPath
|
|
1459
|
+
};
|
|
1460
|
+
const blueprint2 = blueprints.find((blueprint3) => blueprint3.id === getRelativeBlueprint(path));
|
|
1461
|
+
blueprint2.fields.push(fieldBlueprint2);
|
|
660
1462
|
return __spreadProps(__spreadValues({}, selectionNode), {
|
|
661
1463
|
selectionSet: {
|
|
662
1464
|
kind: "SelectionSet",
|
|
663
|
-
selections: selectionNode.selectionSet.selections.map((
|
|
664
|
-
switch (
|
|
1465
|
+
selections: selectionNode.selectionSet.selections.map((subSelectionNode) => {
|
|
1466
|
+
switch (subSelectionNode.kind) {
|
|
665
1467
|
case "Field":
|
|
666
|
-
if (
|
|
667
|
-
return
|
|
1468
|
+
if (subSelectionNode.name.value === "__typename") {
|
|
1469
|
+
return subSelectionNode;
|
|
668
1470
|
}
|
|
1471
|
+
ensureObjectType(namedSubFieldType);
|
|
1472
|
+
const subField1 = getObjectField(namedSubFieldType, subSelectionNode);
|
|
1473
|
+
const subType1 = subField1.type;
|
|
1474
|
+
const namedSubType2 = G.getNamedType(subType1);
|
|
669
1475
|
return formifyField({
|
|
670
|
-
fieldNode:
|
|
671
|
-
parentType:
|
|
672
|
-
path
|
|
1476
|
+
fieldNode: subSelectionNode,
|
|
1477
|
+
parentType: subFieldType,
|
|
1478
|
+
path: [
|
|
1479
|
+
...path,
|
|
1480
|
+
getNameAndAlias(subSelectionNode, isListType(subType1), isNodeField(namedSubType2))
|
|
1481
|
+
]
|
|
673
1482
|
});
|
|
674
1483
|
case "InlineFragment":
|
|
675
|
-
const
|
|
676
|
-
ensureNodeField(
|
|
1484
|
+
const subNamedType = G.getNamedType(subField.type);
|
|
1485
|
+
ensureNodeField(subNamedType);
|
|
1486
|
+
ensureUnionType(subNamedType);
|
|
1487
|
+
const subType2 = getSelectedUnionType(subNamedType, subSelectionNode);
|
|
1488
|
+
const newPath2 = [
|
|
1489
|
+
...path,
|
|
1490
|
+
getNameAndAlias(selectionNode, isListType(subField.type), true)
|
|
1491
|
+
];
|
|
677
1492
|
return formifyNode({
|
|
678
|
-
fieldOrInlineFragmentNode:
|
|
679
|
-
|
|
680
|
-
path
|
|
1493
|
+
fieldOrInlineFragmentNode: subSelectionNode,
|
|
1494
|
+
type: subType2,
|
|
1495
|
+
path: newPath2,
|
|
1496
|
+
showInSidebar: false
|
|
681
1497
|
});
|
|
682
1498
|
default:
|
|
683
|
-
throw new FormifyError("UNEXPECTED", `selection ${
|
|
1499
|
+
throw new FormifyError("UNEXPECTED", `selection ${subSelectionNode.kind}`);
|
|
684
1500
|
}
|
|
685
1501
|
})
|
|
686
1502
|
}
|
|
@@ -691,21 +1507,30 @@ const formify = async ({
|
|
|
691
1507
|
const parentType2 = getSelectedUnionType(namedType, selectionNode);
|
|
692
1508
|
return formifyNode({
|
|
693
1509
|
fieldOrInlineFragmentNode: selectionNode,
|
|
694
|
-
|
|
695
|
-
path
|
|
1510
|
+
type: parentType2,
|
|
1511
|
+
path,
|
|
1512
|
+
showInSidebar: false
|
|
696
1513
|
});
|
|
697
1514
|
}
|
|
1515
|
+
const subType = getSelectedUnionType(namedType, selectionNode);
|
|
1516
|
+
const namedSubType = G.getNamedType(subType);
|
|
698
1517
|
return __spreadProps(__spreadValues({}, selectionNode), {
|
|
699
1518
|
selectionSet: {
|
|
700
1519
|
kind: "SelectionSet",
|
|
701
1520
|
selections: selectionNode.selectionSet.selections.map((subSelectionNode) => {
|
|
702
1521
|
switch (subSelectionNode.kind) {
|
|
703
1522
|
case "Field":
|
|
704
|
-
|
|
1523
|
+
ensureObjectType(namedSubType);
|
|
1524
|
+
const subField2 = getObjectField(namedSubType, subSelectionNode);
|
|
1525
|
+
const subType2 = subField2.type;
|
|
1526
|
+
const namedSubType2 = G.getNamedType(subType2);
|
|
705
1527
|
return formifyField({
|
|
706
1528
|
fieldNode: subSelectionNode,
|
|
707
|
-
parentType:
|
|
708
|
-
path
|
|
1529
|
+
parentType: subType,
|
|
1530
|
+
path: [
|
|
1531
|
+
...path,
|
|
1532
|
+
getNameAndAlias(subSelectionNode, isListType(subType2), isNodeField(namedSubType2))
|
|
1533
|
+
]
|
|
709
1534
|
});
|
|
710
1535
|
default:
|
|
711
1536
|
throw new FormifyError("UNEXPECTED", `selection ${subSelectionNode.kind}`);
|
|
@@ -743,34 +1568,41 @@ const formify = async ({
|
|
|
743
1568
|
if (isNodeField(namedFieldType)) {
|
|
744
1569
|
return formifyNode({
|
|
745
1570
|
fieldOrInlineFragmentNode: selectionNode,
|
|
746
|
-
|
|
747
|
-
path: [getNameAndAlias(selectionNode)]
|
|
1571
|
+
type: field.type,
|
|
1572
|
+
path: [getNameAndAlias(selectionNode, false, true)],
|
|
1573
|
+
showInSidebar: true
|
|
748
1574
|
});
|
|
749
1575
|
} else if (isConnectionField(namedFieldType)) {
|
|
750
1576
|
return formifyConnection({
|
|
751
1577
|
namedFieldType,
|
|
752
1578
|
selectionNode,
|
|
753
|
-
path: [getNameAndAlias(selectionNode)]
|
|
1579
|
+
path: [getNameAndAlias(selectionNode, false, false)]
|
|
754
1580
|
});
|
|
755
1581
|
}
|
|
756
1582
|
if (selectionNode.name.value === COLLECTION_FIELD_NAME || selectionNode.name.value === COLLECTIONS_FIELD_NAME) {
|
|
1583
|
+
const path = [
|
|
1584
|
+
getNameAndAlias(selectionNode, false, false)
|
|
1585
|
+
];
|
|
757
1586
|
return __spreadProps(__spreadValues({}, selectionNode), {
|
|
758
1587
|
selectionSet: {
|
|
759
1588
|
kind: "SelectionSet",
|
|
760
|
-
selections: selectionNode.selectionSet.selections.map((
|
|
761
|
-
switch (
|
|
1589
|
+
selections: selectionNode.selectionSet.selections.map((subSelectionNode) => {
|
|
1590
|
+
switch (subSelectionNode.kind) {
|
|
762
1591
|
case "Field":
|
|
763
|
-
if (
|
|
1592
|
+
if (subSelectionNode.name.value === COLLECTIONS_DOCUMENTS_NAME) {
|
|
764
1593
|
ensureObjectType(namedFieldType);
|
|
765
1594
|
const n = namedFieldType.getFields()[COLLECTIONS_DOCUMENTS_NAME];
|
|
766
1595
|
const docType = G.getNamedType(n.type);
|
|
767
1596
|
return formifyConnection({
|
|
768
1597
|
namedFieldType: docType,
|
|
769
|
-
selectionNode:
|
|
770
|
-
path: [
|
|
1598
|
+
selectionNode: subSelectionNode,
|
|
1599
|
+
path: [
|
|
1600
|
+
...path,
|
|
1601
|
+
getNameAndAlias(subSelectionNode, isListType(docType), isNodeField(docType))
|
|
1602
|
+
]
|
|
771
1603
|
});
|
|
772
1604
|
}
|
|
773
|
-
return
|
|
1605
|
+
return subSelectionNode;
|
|
774
1606
|
default:
|
|
775
1607
|
throw new FormifyError("NOOP");
|
|
776
1608
|
}
|
|
@@ -781,898 +1613,1249 @@ const formify = async ({
|
|
|
781
1613
|
throw new FormifyError("NOOP");
|
|
782
1614
|
default:
|
|
783
1615
|
throw new FormifyError("UNEXPECTED");
|
|
784
|
-
}
|
|
785
|
-
})
|
|
786
|
-
}
|
|
787
|
-
});
|
|
788
|
-
})
|
|
789
|
-
};
|
|
790
|
-
nodes.map((node2) => {
|
|
791
|
-
const namePath = [];
|
|
792
|
-
const aliasPath = [];
|
|
793
|
-
node2.path.forEach((p) => {
|
|
794
|
-
namePath.push(p.name);
|
|
795
|
-
aliasPath.push(p.alias);
|
|
796
|
-
if (p.list) {
|
|
797
|
-
namePath.push("NUM");
|
|
798
|
-
aliasPath.push("NUM");
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
JSON.stringify({
|
|
802
|
-
namePath: namePath.join("."),
|
|
803
|
-
aliasPath: aliasPath.join(".")
|
|
804
|
-
}, null, 2);
|
|
805
|
-
});
|
|
806
|
-
return { formifiedQuery, nodes };
|
|
807
|
-
};
|
|
808
|
-
const captureBranchName = /^refs\/heads\/(.*)/;
|
|
809
|
-
const parseRefForBranchName = (ref) => {
|
|
810
|
-
const matches = ref.match(captureBranchName);
|
|
811
|
-
return matches[1];
|
|
812
|
-
};
|
|
813
|
-
class Client {
|
|
814
|
-
constructor(_a) {
|
|
815
|
-
var _b = _a, { tokenStorage = "MEMORY" } = _b, options = __objRest(_b, ["tokenStorage"]);
|
|
816
|
-
this.events = new EventBus();
|
|
817
|
-
this.addPendingContent = async (props) => {
|
|
818
|
-
const mutation = `#graphql
|
|
819
|
-
mutation addPendingDocumentMutation(
|
|
820
|
-
$relativePath: String!
|
|
821
|
-
$collection: String!
|
|
822
|
-
$template: String
|
|
823
|
-
) {
|
|
824
|
-
addPendingDocument(
|
|
825
|
-
relativePath: $relativePath
|
|
826
|
-
template: $template
|
|
827
|
-
collection: $collection
|
|
828
|
-
) {
|
|
829
|
-
... on Document {
|
|
830
|
-
sys {
|
|
831
|
-
relativePath
|
|
832
|
-
path
|
|
833
|
-
breadcrumbs
|
|
834
|
-
collection {
|
|
835
|
-
slug
|
|
1616
|
+
}
|
|
1617
|
+
})
|
|
836
1618
|
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}`;
|
|
841
|
-
const result = await this.request(mutation, {
|
|
842
|
-
variables: props
|
|
843
|
-
});
|
|
844
|
-
return result;
|
|
845
|
-
};
|
|
846
|
-
this.getSchema = async () => {
|
|
847
|
-
if (!this.schema) {
|
|
848
|
-
const data = await this.request(getIntrospectionQuery(), {
|
|
849
|
-
variables: {}
|
|
850
|
-
});
|
|
851
|
-
this.schema = buildClientSchema(data);
|
|
852
|
-
}
|
|
853
|
-
return this.schema;
|
|
854
|
-
};
|
|
855
|
-
this.getOptimizedQuery = async (documentNode) => {
|
|
856
|
-
const data = await this.request(`query GetOptimizedQuery($queryString: String!) {
|
|
857
|
-
getOptimizedQuery(queryString: $queryString)
|
|
858
|
-
}`, {
|
|
859
|
-
variables: { queryString: print(documentNode) }
|
|
860
1619
|
});
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
this.getToken = async function() {
|
|
872
|
-
const tokens = localStorage.getItem(AUTH_TOKEN_KEY) || null;
|
|
873
|
-
if (tokens) {
|
|
874
|
-
return await this.getRefreshedToken(tokens);
|
|
875
|
-
} else {
|
|
876
|
-
return {
|
|
877
|
-
access_token: null,
|
|
878
|
-
id_token: null,
|
|
879
|
-
refresh_token: null
|
|
880
|
-
};
|
|
881
|
-
}
|
|
882
|
-
};
|
|
883
|
-
this.setToken = function(token) {
|
|
884
|
-
localStorage.setItem(AUTH_TOKEN_KEY, JSON.stringify(token, null, 2));
|
|
885
|
-
};
|
|
1620
|
+
})
|
|
1621
|
+
};
|
|
1622
|
+
return { formifiedQuery, blueprints };
|
|
1623
|
+
};
|
|
1624
|
+
class FormifyError extends Error {
|
|
1625
|
+
constructor(code, details) {
|
|
1626
|
+
let message;
|
|
1627
|
+
switch (code) {
|
|
1628
|
+
case "NOOP":
|
|
1629
|
+
message = NOOP;
|
|
886
1630
|
break;
|
|
887
|
-
case "
|
|
888
|
-
|
|
889
|
-
if (this.token) {
|
|
890
|
-
return await this.getRefreshedToken(this.token);
|
|
891
|
-
} else {
|
|
892
|
-
return {
|
|
893
|
-
access_token: null,
|
|
894
|
-
id_token: null,
|
|
895
|
-
refresh_token: null
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
};
|
|
899
|
-
this.setToken = (token) => {
|
|
900
|
-
this.token = JSON.stringify(token, null, 2);
|
|
901
|
-
};
|
|
1631
|
+
case "UNEXPECTED":
|
|
1632
|
+
message = UNEXPECTED;
|
|
902
1633
|
break;
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
throw new Error("When CUSTOM token storage is selected, a getTokenFn must be provided");
|
|
906
|
-
}
|
|
907
|
-
this.getToken = options.getTokenFn;
|
|
1634
|
+
default:
|
|
1635
|
+
message = "";
|
|
908
1636
|
break;
|
|
909
1637
|
}
|
|
1638
|
+
super(`${message} ${details || ""}`);
|
|
1639
|
+
this.name = "FormifyError";
|
|
910
1640
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
this.contentApiUrl = this.options.customContentApiUrl || `${this.contentApiBase}/content/${this.options.clientId}/github/${encodedBranch}`;
|
|
921
|
-
}
|
|
922
|
-
async requestWithForm(query, {
|
|
923
|
-
variables,
|
|
924
|
-
useUnstableFormify
|
|
925
|
-
}) {
|
|
926
|
-
const schema = await this.getSchema();
|
|
927
|
-
let formifiedQuery;
|
|
928
|
-
if (useUnstableFormify) {
|
|
929
|
-
const res = await formify({
|
|
930
|
-
schema,
|
|
931
|
-
query: print(query(gql$1)),
|
|
932
|
-
getOptimizedQuery: this.getOptimizedQuery
|
|
1641
|
+
}
|
|
1642
|
+
function reducer(state, action) {
|
|
1643
|
+
var _a, _b, _c, _d;
|
|
1644
|
+
switch (action.type) {
|
|
1645
|
+
case "addDocumentBlueprints":
|
|
1646
|
+
return __spreadProps(__spreadValues({}, state), {
|
|
1647
|
+
status: "formified",
|
|
1648
|
+
blueprints: action.value.blueprints,
|
|
1649
|
+
query: action.value.formifiedQuery
|
|
933
1650
|
});
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
return this.request(print(formifiedQuery), { variables });
|
|
939
|
-
}
|
|
940
|
-
async request(query, { variables }) {
|
|
941
|
-
const res = await fetch(this.contentApiUrl, {
|
|
942
|
-
method: "POST",
|
|
943
|
-
headers: {
|
|
944
|
-
"Content-Type": "application/json",
|
|
945
|
-
Authorization: "Bearer " + (await this.getToken()).id_token
|
|
946
|
-
},
|
|
947
|
-
body: JSON.stringify({
|
|
948
|
-
query: typeof query === "function" ? print(query(gql$1)) : query,
|
|
949
|
-
variables
|
|
950
|
-
})
|
|
951
|
-
});
|
|
952
|
-
if (res.status !== 200) {
|
|
953
|
-
throw new Error(`Unable to complete request, ${res.statusText}`);
|
|
954
|
-
}
|
|
955
|
-
const json = await res.json();
|
|
956
|
-
if (json.errors) {
|
|
957
|
-
throw new Error(`Unable to fetch, errors:
|
|
958
|
-
${json.errors.map((error) => error.message).join("\n")}`);
|
|
959
|
-
}
|
|
960
|
-
return json.data;
|
|
961
|
-
}
|
|
962
|
-
parseJwt(token) {
|
|
963
|
-
const base64Url = token.split(".")[1];
|
|
964
|
-
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
965
|
-
const jsonPayload = decodeURIComponent(atob(base64).split("").map(function(c) {
|
|
966
|
-
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
967
|
-
}).join(""));
|
|
968
|
-
return JSON.parse(jsonPayload);
|
|
969
|
-
}
|
|
970
|
-
async getRefreshedToken(tokens) {
|
|
971
|
-
const { access_token, id_token, refresh_token } = JSON.parse(tokens);
|
|
972
|
-
const { exp, iss, client_id } = this.parseJwt(access_token);
|
|
973
|
-
if (Date.now() / 1e3 >= exp - 120) {
|
|
974
|
-
const refreshResponse = await fetch(iss, {
|
|
975
|
-
method: "POST",
|
|
976
|
-
headers: {
|
|
977
|
-
"Content-Type": "application/x-amz-json-1.1",
|
|
978
|
-
"x-amz-target": "AWSCognitoIdentityProviderService.InitiateAuth"
|
|
979
|
-
},
|
|
980
|
-
body: JSON.stringify({
|
|
981
|
-
ClientId: client_id,
|
|
982
|
-
AuthFlow: "REFRESH_TOKEN_AUTH",
|
|
983
|
-
AuthParameters: {
|
|
984
|
-
REFRESH_TOKEN: refresh_token,
|
|
985
|
-
DEVICE_KEY: null
|
|
986
|
-
}
|
|
987
|
-
})
|
|
1651
|
+
case "addOrReplaceDocumentFormNode": {
|
|
1652
|
+
const existingDocumentForms = state.documentForms.filter((documentForm) => {
|
|
1653
|
+
var _a2, _b2;
|
|
1654
|
+
return documentForm.id !== ((_b2 = (_a2 = action.value) == null ? void 0 : _a2.documentForm) == null ? void 0 : _b2.id);
|
|
988
1655
|
});
|
|
989
|
-
|
|
990
|
-
|
|
1656
|
+
const existingDocumentFormNodes = state.formNodes.filter((formNode) => {
|
|
1657
|
+
return formNodeId(formNode) !== formNodeId(action.value.formNode);
|
|
1658
|
+
});
|
|
1659
|
+
const newDocumentForms = [];
|
|
1660
|
+
if ((_a = action.value) == null ? void 0 : _a.documentForm) {
|
|
1661
|
+
newDocumentForms.push((_b = action.value) == null ? void 0 : _b.documentForm);
|
|
991
1662
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
refresh_token
|
|
997
|
-
};
|
|
998
|
-
this.setToken(newToken);
|
|
999
|
-
return Promise.resolve(newToken);
|
|
1000
|
-
}
|
|
1001
|
-
return Promise.resolve({ access_token, id_token, refresh_token });
|
|
1002
|
-
}
|
|
1003
|
-
async isAuthorized() {
|
|
1004
|
-
return this.isAuthenticated();
|
|
1005
|
-
}
|
|
1006
|
-
async isAuthenticated() {
|
|
1007
|
-
return !!await this.getUser();
|
|
1008
|
-
}
|
|
1009
|
-
async authenticate() {
|
|
1010
|
-
const token = await authenticate(this.clientId, this.frontendUrl);
|
|
1011
|
-
this.setToken(token);
|
|
1012
|
-
return token;
|
|
1013
|
-
}
|
|
1014
|
-
async fetchWithToken(input, init) {
|
|
1015
|
-
const headers = (init == null ? void 0 : init.headers) || {};
|
|
1016
|
-
return await fetch(input, __spreadProps(__spreadValues({}, init), {
|
|
1017
|
-
headers: new Headers(__spreadValues({
|
|
1018
|
-
Authorization: "Bearer " + (await this.getToken()).id_token
|
|
1019
|
-
}, headers))
|
|
1020
|
-
}));
|
|
1021
|
-
}
|
|
1022
|
-
async getUser() {
|
|
1023
|
-
if (!this.clientId) {
|
|
1024
|
-
return null;
|
|
1663
|
+
return __spreadProps(__spreadValues({}, state), {
|
|
1664
|
+
formNodes: [...existingDocumentFormNodes, action.value.formNode],
|
|
1665
|
+
documentForms: [...existingDocumentForms, ...newDocumentForms]
|
|
1666
|
+
});
|
|
1025
1667
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1668
|
+
case "onFieldChange": {
|
|
1669
|
+
const event = action.value.event;
|
|
1670
|
+
const changeSets = [];
|
|
1671
|
+
const formNodesToReplace = [];
|
|
1672
|
+
const formNodesToRemove = [];
|
|
1673
|
+
const newFormNodes = [];
|
|
1674
|
+
const form = state.documentForms.find((documentForm) => documentForm.id === event.formId);
|
|
1675
|
+
getFormNodesFromEvent(state, event).forEach((formNode) => {
|
|
1676
|
+
const blueprint = getFormNodeBlueprint(formNode, state);
|
|
1677
|
+
if (blueprint.hasValuesField) {
|
|
1678
|
+
changeSets.push(__spreadProps(__spreadValues({
|
|
1679
|
+
path: [formNodePath(formNode), "values"].join(".")
|
|
1680
|
+
}, buildChangeSet(event, formNode)), {
|
|
1681
|
+
value: form.values,
|
|
1682
|
+
mutationType: {
|
|
1683
|
+
type: "global"
|
|
1684
|
+
}
|
|
1685
|
+
}));
|
|
1686
|
+
}
|
|
1687
|
+
if (blueprint.hasDataJSONField) {
|
|
1688
|
+
changeSets.push(__spreadProps(__spreadValues({
|
|
1689
|
+
path: [formNodePath(formNode), "dataJSON"].join(".")
|
|
1690
|
+
}, buildChangeSet(event, formNode)), {
|
|
1691
|
+
value: form.values,
|
|
1692
|
+
mutationType: {
|
|
1693
|
+
type: "global"
|
|
1694
|
+
}
|
|
1695
|
+
}));
|
|
1696
|
+
}
|
|
1697
|
+
if (event.mutationType.type === "change") {
|
|
1698
|
+
if (!action.value.form) {
|
|
1699
|
+
getPathsToChange(event, state).forEach(({ formNode: formNode2, pathToChange }) => {
|
|
1700
|
+
changeSets.push(__spreadValues({
|
|
1701
|
+
path: pathToChange
|
|
1702
|
+
}, buildChangeSet(event, formNode2)));
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
} else if (event.mutationType.type === "referenceChange") {
|
|
1706
|
+
getBlueprintFieldsForEvent(blueprint, event).forEach((fieldBlueprint) => {
|
|
1707
|
+
const { pathToChange, formNodes, eventLocation } = getFormNodesForField(fieldBlueprint, formNode, event, state);
|
|
1708
|
+
if (action.value.form) {
|
|
1709
|
+
const newFormNode = {
|
|
1710
|
+
documentBlueprintId: fieldBlueprint.id,
|
|
1711
|
+
documentFormId: action.value.form.id,
|
|
1712
|
+
location: eventLocation
|
|
1713
|
+
};
|
|
1714
|
+
newFormNodes.push(newFormNode);
|
|
1715
|
+
changeSets.push(__spreadValues({
|
|
1716
|
+
path: pathToChange
|
|
1717
|
+
}, buildChangeSet(event, newFormNode)));
|
|
1718
|
+
}
|
|
1719
|
+
formNodes.forEach((subFormNode) => {
|
|
1720
|
+
if (matchLocation(eventLocation, subFormNode)) {
|
|
1721
|
+
formNodesToReplace.push(subFormNode);
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
});
|
|
1725
|
+
} else {
|
|
1726
|
+
getBlueprintFieldsForEvent(blueprint, event).forEach((fieldBlueprint) => {
|
|
1727
|
+
const { pathToChange, formNodes, existing, eventLocation } = getFormNodesForField(fieldBlueprint, formNode, event, state);
|
|
1728
|
+
if (event.mutationType.type === "insert") {
|
|
1729
|
+
formNodes.forEach((subFormNode) => {
|
|
1730
|
+
if (matchLocation(eventLocation, subFormNode)) {
|
|
1731
|
+
newFormNodes.push(__spreadProps(__spreadValues({}, subFormNode), {
|
|
1732
|
+
location: bumpLocation(subFormNode.location)
|
|
1733
|
+
}));
|
|
1734
|
+
formNodesToReplace.push(subFormNode);
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1737
|
+
changeSets.push(__spreadValues({
|
|
1738
|
+
path: pathToChange
|
|
1739
|
+
}, buildChangeSet(event, formNode)));
|
|
1740
|
+
}
|
|
1741
|
+
if (event.mutationType.type === "remove") {
|
|
1742
|
+
const { at } = event.mutationType;
|
|
1743
|
+
formNodes.forEach((subFormNode) => {
|
|
1744
|
+
if (matchLocation(eventLocation, subFormNode)) {
|
|
1745
|
+
if (matchesAt(subFormNode.location, at)) {
|
|
1746
|
+
formNodesToRemove.push(subFormNode);
|
|
1747
|
+
} else {
|
|
1748
|
+
newFormNodes.push(__spreadProps(__spreadValues({}, subFormNode), {
|
|
1749
|
+
location: maybeLowerLocation(subFormNode.location, at)
|
|
1750
|
+
}));
|
|
1751
|
+
formNodesToReplace.push(subFormNode);
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
});
|
|
1755
|
+
const next = existing.filter((_, index) => index !== at);
|
|
1756
|
+
changeSets.push(__spreadProps(__spreadValues({
|
|
1757
|
+
path: pathToChange
|
|
1758
|
+
}, buildChangeSet(event, formNode)), {
|
|
1759
|
+
value: next
|
|
1760
|
+
}));
|
|
1761
|
+
}
|
|
1762
|
+
if (event.mutationType.type === "move") {
|
|
1763
|
+
const next = [];
|
|
1764
|
+
const { from, to } = event.mutationType;
|
|
1765
|
+
const newOrderObject = getMoveMapping(existing, from, to);
|
|
1766
|
+
formNodes.forEach((subFormNode) => {
|
|
1767
|
+
if (matchLocation(eventLocation, subFormNode)) {
|
|
1768
|
+
newFormNodes.push(__spreadProps(__spreadValues({}, subFormNode), {
|
|
1769
|
+
location: swapLocation(subFormNode.location, newOrderObject)
|
|
1770
|
+
}));
|
|
1771
|
+
formNodesToReplace.push(subFormNode);
|
|
1772
|
+
}
|
|
1773
|
+
});
|
|
1774
|
+
Object.values(newOrderObject).forEach((orderIndex, index) => {
|
|
1775
|
+
next[orderIndex] = existing[index];
|
|
1776
|
+
});
|
|
1777
|
+
changeSets.push(__spreadProps(__spreadValues({
|
|
1778
|
+
path: pathToChange
|
|
1779
|
+
}, buildChangeSet(event, formNode)), {
|
|
1780
|
+
value: next
|
|
1781
|
+
}));
|
|
1782
|
+
}
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1030
1785
|
});
|
|
1031
|
-
const
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1786
|
+
const existingDocumentForms = state.documentForms.filter((documentForm) => {
|
|
1787
|
+
var _a2;
|
|
1788
|
+
return documentForm.id !== ((_a2 = action.value.form) == null ? void 0 : _a2.id);
|
|
1789
|
+
});
|
|
1790
|
+
const newDocumentForms = [];
|
|
1791
|
+
if ((_c = action.value) == null ? void 0 : _c.form) {
|
|
1792
|
+
newDocumentForms.push((_d = action.value) == null ? void 0 : _d.form);
|
|
1035
1793
|
}
|
|
1036
|
-
return
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1794
|
+
return __spreadProps(__spreadValues({}, state), {
|
|
1795
|
+
changeSets,
|
|
1796
|
+
formNodes: [
|
|
1797
|
+
...state.formNodes.filter((formNode) => formNodeNotIn(formNode, formNodesToReplace)).filter((formNode) => formNodeNotIn(formNode, formNodesToRemove)),
|
|
1798
|
+
...newFormNodes
|
|
1799
|
+
],
|
|
1800
|
+
documentForms: [...existingDocumentForms, ...newDocumentForms]
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
case "formOnReset": {
|
|
1804
|
+
const { event } = action.value;
|
|
1805
|
+
const changeSets = [];
|
|
1806
|
+
const form = state.documentForms.find((documentForm) => documentForm.id === event.formId);
|
|
1807
|
+
state.formNodes.filter((fn) => fn.documentFormId === (form == null ? void 0 : form.id)).forEach((formNode) => {
|
|
1808
|
+
const blueprint = getFormNodeBlueprint(formNode, state);
|
|
1809
|
+
if (blueprint.hasValuesField) {
|
|
1810
|
+
changeSets.push(__spreadValues({
|
|
1811
|
+
path: [formNodePath(formNode), "values"].join(".")
|
|
1812
|
+
}, buildChangeSet(event, formNode)));
|
|
1813
|
+
}
|
|
1814
|
+
if (blueprint.hasDataJSONField) {
|
|
1815
|
+
changeSets.push(__spreadValues({
|
|
1816
|
+
path: [formNodePath(formNode), "dataJSON"].join(".")
|
|
1817
|
+
}, buildChangeSet(event, formNode)));
|
|
1060
1818
|
}
|
|
1819
|
+
changeSets.push(__spreadValues({
|
|
1820
|
+
path: [formNodePath(formNode), "data"].join(".")
|
|
1821
|
+
}, buildChangeSet(event, formNode)));
|
|
1061
1822
|
});
|
|
1062
|
-
return
|
|
1063
|
-
} catch (error) {
|
|
1064
|
-
console.error("There was an error creating a new branch.", error);
|
|
1065
|
-
return null;
|
|
1823
|
+
return __spreadProps(__spreadValues({}, state), { changeSets });
|
|
1066
1824
|
}
|
|
1825
|
+
case "ready":
|
|
1826
|
+
return __spreadProps(__spreadValues({}, state), { status: "ready" });
|
|
1827
|
+
case "done":
|
|
1828
|
+
return __spreadProps(__spreadValues({}, state), { status: "done" });
|
|
1829
|
+
case "setData":
|
|
1830
|
+
return __spreadProps(__spreadValues({}, state), { data: action.value });
|
|
1831
|
+
case "setIn": {
|
|
1832
|
+
let newData;
|
|
1833
|
+
if (action.value.displaceIndex) {
|
|
1834
|
+
const existing = getIn(state.data, action.value.path) || [];
|
|
1835
|
+
newData = setIn(state.data, action.value.path, [
|
|
1836
|
+
action.value.value,
|
|
1837
|
+
...existing
|
|
1838
|
+
]);
|
|
1839
|
+
} else {
|
|
1840
|
+
newData = setIn(state.data, action.value.path, action.value.value);
|
|
1841
|
+
}
|
|
1842
|
+
const changeSets = state.changeSets.filter((cs) => cs.path !== action.value.path);
|
|
1843
|
+
return __spreadProps(__spreadValues({}, state), {
|
|
1844
|
+
data: newData,
|
|
1845
|
+
changeSets
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
default:
|
|
1849
|
+
return state;
|
|
1067
1850
|
}
|
|
1068
1851
|
}
|
|
1069
|
-
const
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
}
|
|
1079
|
-
async isAuthorized() {
|
|
1080
|
-
return true;
|
|
1081
|
-
}
|
|
1082
|
-
async isAuthenticated() {
|
|
1083
|
-
return true;
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
function ModalBuilder(modalProps) {
|
|
1087
|
-
return /* @__PURE__ */ React.createElement(Modal, null, /* @__PURE__ */ React.createElement(ModalPopup, null, /* @__PURE__ */ React.createElement(ModalHeader, null, modalProps.title), /* @__PURE__ */ React.createElement(ModalBody, {
|
|
1088
|
-
padded: true
|
|
1089
|
-
}, /* @__PURE__ */ React.createElement("p", null, modalProps.message), modalProps.error && /* @__PURE__ */ React.createElement(ErrorLabel, null, modalProps.error)), /* @__PURE__ */ React.createElement(ModalActions, null, modalProps.actions.map((action) => /* @__PURE__ */ React.createElement(AsyncButton, __spreadValues({
|
|
1090
|
-
key: action.name
|
|
1091
|
-
}, action))))));
|
|
1092
|
-
}
|
|
1093
|
-
const ErrorLabel = styled.p`
|
|
1094
|
-
color: var(--tina-color-error) !important;
|
|
1095
|
-
`;
|
|
1096
|
-
const AsyncButton = ({ name, primary, action }) => {
|
|
1097
|
-
const [submitting, setSubmitting] = useState(false);
|
|
1098
|
-
const onClick = useCallback(async () => {
|
|
1099
|
-
setSubmitting(true);
|
|
1100
|
-
try {
|
|
1101
|
-
await action();
|
|
1102
|
-
setSubmitting(false);
|
|
1103
|
-
} catch (e) {
|
|
1104
|
-
setSubmitting(false);
|
|
1105
|
-
throw e;
|
|
1106
|
-
}
|
|
1107
|
-
}, [action, setSubmitting]);
|
|
1108
|
-
return /* @__PURE__ */ React.createElement(Button, {
|
|
1109
|
-
variant: primary ? "primary" : "secondary",
|
|
1110
|
-
onClick,
|
|
1111
|
-
busy: submitting,
|
|
1112
|
-
disabled: submitting
|
|
1113
|
-
}, submitting && /* @__PURE__ */ React.createElement(LoadingDots, null), !submitting && name);
|
|
1114
|
-
};
|
|
1115
|
-
const TINA_AUTH_CONFIG = "tina_auth_config";
|
|
1116
|
-
const useTinaAuthRedirect = () => {
|
|
1117
|
-
useEffect(() => {
|
|
1118
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
1119
|
-
const config = {
|
|
1120
|
-
code: urlParams.get("code") || "",
|
|
1121
|
-
scope: urlParams.get("scope") || "email",
|
|
1122
|
-
state: urlParams.get("state")
|
|
1123
|
-
};
|
|
1124
|
-
if (!config.code) {
|
|
1125
|
-
return;
|
|
1126
|
-
}
|
|
1127
|
-
localStorage[TINA_AUTH_CONFIG] = JSON.stringify(config);
|
|
1128
|
-
}, []);
|
|
1852
|
+
const buildChangeSet = (event, formNode) => {
|
|
1853
|
+
var _a, _b, _c;
|
|
1854
|
+
return {
|
|
1855
|
+
fieldDefinition: (_b = (_a = event.field) == null ? void 0 : _a.data) == null ? void 0 : _b.tinaField,
|
|
1856
|
+
name: (_c = event.field) == null ? void 0 : _c.name,
|
|
1857
|
+
formId: event.formId,
|
|
1858
|
+
mutationType: event.mutationType,
|
|
1859
|
+
value: event.value,
|
|
1860
|
+
formNode
|
|
1861
|
+
};
|
|
1129
1862
|
};
|
|
1130
|
-
const
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1863
|
+
const useFormify = ({
|
|
1864
|
+
query,
|
|
1865
|
+
cms,
|
|
1866
|
+
variables,
|
|
1867
|
+
onSubmit,
|
|
1868
|
+
formify: formifyFunc,
|
|
1869
|
+
eventList
|
|
1135
1870
|
}) => {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1871
|
+
const formIds = React.useRef([]);
|
|
1872
|
+
const [state, dispatch] = React.useReducer(reducer, {
|
|
1873
|
+
status: "initialized",
|
|
1874
|
+
schema: void 0,
|
|
1875
|
+
query: query ? G.parse(query) : null,
|
|
1876
|
+
queryString: query,
|
|
1877
|
+
data: {},
|
|
1878
|
+
changeSets: [],
|
|
1879
|
+
count: 0,
|
|
1880
|
+
blueprints: [],
|
|
1881
|
+
formNodes: [],
|
|
1882
|
+
documentForms: []
|
|
1141
1883
|
});
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
extension
|
|
1195
|
-
}
|
|
1884
|
+
React.useEffect(() => {
|
|
1885
|
+
if (state.status === "initialized") {
|
|
1886
|
+
cms.api.tina.request(query, { variables }).then((res) => {
|
|
1887
|
+
delete res.paths;
|
|
1888
|
+
dispatch({ type: "setData", value: res });
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
}, [state.status]);
|
|
1892
|
+
React.useEffect(() => {
|
|
1893
|
+
const run = async () => {
|
|
1894
|
+
const schema = await cms.api.tina.getSchema();
|
|
1895
|
+
const result = await formify({
|
|
1896
|
+
schema,
|
|
1897
|
+
query,
|
|
1898
|
+
getOptimizedQuery: cms.api.tina.getOptimizedQuery
|
|
1899
|
+
});
|
|
1900
|
+
dispatch({
|
|
1901
|
+
type: "addDocumentBlueprints",
|
|
1902
|
+
value: result
|
|
1903
|
+
});
|
|
1904
|
+
};
|
|
1905
|
+
if (state.status === "initialized") {
|
|
1906
|
+
run();
|
|
1907
|
+
}
|
|
1908
|
+
}, [state.status]);
|
|
1909
|
+
React.useEffect(() => {
|
|
1910
|
+
const run = async () => {
|
|
1911
|
+
const result = await cms.api.tina.request(G.print(state.query), {
|
|
1912
|
+
variables
|
|
1913
|
+
});
|
|
1914
|
+
state.blueprints.map((blueprint) => {
|
|
1915
|
+
const responseAtBlueprint = getIn2(result, getBlueprintAliasPath(blueprint));
|
|
1916
|
+
const location = [];
|
|
1917
|
+
const findFormNodes = (res, location2) => {
|
|
1918
|
+
if (Array.isArray(res)) {
|
|
1919
|
+
res.forEach((item, index) => {
|
|
1920
|
+
if (Array.isArray(item)) {
|
|
1921
|
+
findFormNodes(item, [...location2, index]);
|
|
1922
|
+
} else {
|
|
1923
|
+
if (item) {
|
|
1924
|
+
const form = buildForm(item, cms, formifyFunc, blueprint.showInSidebar, onSubmit);
|
|
1925
|
+
const formNode = buildFormNode(blueprint, form, [
|
|
1926
|
+
...location2,
|
|
1927
|
+
index
|
|
1928
|
+
]);
|
|
1929
|
+
dispatch({
|
|
1930
|
+
type: "addOrReplaceDocumentFormNode",
|
|
1931
|
+
value: {
|
|
1932
|
+
formNode,
|
|
1933
|
+
documentForm: form
|
|
1934
|
+
}
|
|
1935
|
+
});
|
|
1196
1936
|
}
|
|
1197
1937
|
}
|
|
1938
|
+
});
|
|
1939
|
+
} else {
|
|
1940
|
+
if (res) {
|
|
1941
|
+
const form = buildForm(res, cms, formifyFunc, blueprint.showInSidebar, onSubmit);
|
|
1942
|
+
const formNode = buildFormNode(blueprint, form, location2);
|
|
1943
|
+
dispatch({
|
|
1944
|
+
type: "addOrReplaceDocumentFormNode",
|
|
1945
|
+
value: {
|
|
1946
|
+
formNode,
|
|
1947
|
+
documentForm: form
|
|
1948
|
+
}
|
|
1949
|
+
});
|
|
1198
1950
|
}
|
|
1199
1951
|
}
|
|
1952
|
+
};
|
|
1953
|
+
findFormNodes(responseAtBlueprint, location);
|
|
1954
|
+
});
|
|
1955
|
+
dispatch({ type: "ready" });
|
|
1956
|
+
};
|
|
1957
|
+
if (state.status === "formified") {
|
|
1958
|
+
run();
|
|
1959
|
+
}
|
|
1960
|
+
}, [state.status]);
|
|
1961
|
+
React.useEffect(() => {
|
|
1962
|
+
if (state.status === "ready") {
|
|
1963
|
+
cms.events.subscribe(`forms:reset`, (event) => {
|
|
1964
|
+
dispatch({ type: "formOnReset", value: { event } });
|
|
1965
|
+
});
|
|
1966
|
+
cms.events.subscribe(`forms:fields:onChange`, async (event) => {
|
|
1967
|
+
if (eventList) {
|
|
1968
|
+
eventList.push(printEvent(event));
|
|
1200
1969
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1970
|
+
if (event.field.data.tinaField.type === "reference") {
|
|
1971
|
+
let form;
|
|
1972
|
+
if (event.value && typeof event.value === "string") {
|
|
1973
|
+
const existingForm = cms.forms.find(event.value);
|
|
1974
|
+
if (existingForm) {
|
|
1975
|
+
form = existingForm;
|
|
1976
|
+
} else {
|
|
1977
|
+
const formInfo = await cms.api.tina.request(`#graphql
|
|
1978
|
+
query Node($id: String!) {
|
|
1979
|
+
node(id: $id) {
|
|
1980
|
+
...on Document {
|
|
1981
|
+
form
|
|
1982
|
+
values
|
|
1983
|
+
_internalSys: sys {
|
|
1984
|
+
path
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
`, { variables: { id: event.value } });
|
|
1990
|
+
form = buildForm(formInfo.node, cms, formifyFunc, false, onSubmit);
|
|
1991
|
+
}
|
|
1211
1992
|
}
|
|
1993
|
+
dispatch({
|
|
1994
|
+
type: "onFieldChange",
|
|
1995
|
+
value: {
|
|
1996
|
+
event: __spreadProps(__spreadValues({}, event), {
|
|
1997
|
+
mutationType: { type: "referenceChange" }
|
|
1998
|
+
}),
|
|
1999
|
+
form
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
2002
|
+
} else {
|
|
2003
|
+
dispatch({ type: "onFieldChange", value: { event } });
|
|
1212
2004
|
}
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
2005
|
+
});
|
|
2006
|
+
dispatch({ type: "done" });
|
|
2007
|
+
}
|
|
2008
|
+
}, [state.status]);
|
|
2009
|
+
React.useEffect(() => {
|
|
2010
|
+
state.changeSets.forEach((changeSet) => {
|
|
2011
|
+
if (changeSet.mutationType.type === "reset") {
|
|
2012
|
+
const form = cms.forms.find(changeSet.formId);
|
|
2013
|
+
resolveSubFields({
|
|
2014
|
+
formNode: changeSet.formNode,
|
|
2015
|
+
form
|
|
2016
|
+
}).then((res) => {
|
|
2017
|
+
dispatch({
|
|
2018
|
+
type: "setIn",
|
|
2019
|
+
value: {
|
|
2020
|
+
value: res,
|
|
2021
|
+
path: changeSet.path
|
|
2022
|
+
}
|
|
2023
|
+
});
|
|
2024
|
+
});
|
|
2025
|
+
return;
|
|
2026
|
+
} else if (changeSet.mutationType.type === "insert") {
|
|
2027
|
+
if (changeSet.fieldDefinition.type === "object") {
|
|
2028
|
+
const fieldName = changeSet.fieldDefinition.list ? `${changeSet.name}.[]` : changeSet.name;
|
|
2029
|
+
const { fields, __typename } = getSubFields(changeSet);
|
|
2030
|
+
resolveSubFields({
|
|
2031
|
+
formNode: changeSet.formNode,
|
|
2032
|
+
prefix: replaceRealNum(fieldName),
|
|
2033
|
+
loc: [...stripIndices(changeSet.path), 0],
|
|
2034
|
+
form: {
|
|
2035
|
+
fields,
|
|
2036
|
+
values: changeSet.value[0]
|
|
2037
|
+
}
|
|
2038
|
+
}).then((res) => {
|
|
2039
|
+
const extra = {};
|
|
2040
|
+
if (__typename) {
|
|
2041
|
+
extra["__typename"] = __typename;
|
|
2042
|
+
}
|
|
2043
|
+
dispatch({
|
|
2044
|
+
type: "setIn",
|
|
2045
|
+
value: __spreadProps(__spreadValues({
|
|
2046
|
+
displaceIndex: true
|
|
2047
|
+
}, changeSet), {
|
|
2048
|
+
value: __spreadValues(__spreadValues({}, res), extra)
|
|
2049
|
+
})
|
|
2050
|
+
});
|
|
2051
|
+
});
|
|
2052
|
+
} else {
|
|
2053
|
+
dispatch({
|
|
2054
|
+
type: "setIn",
|
|
2055
|
+
value: __spreadProps(__spreadValues({
|
|
2056
|
+
displaceIndex: true
|
|
2057
|
+
}, changeSet), {
|
|
2058
|
+
value: changeSet.value[0]
|
|
2059
|
+
})
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
} else {
|
|
2063
|
+
if (changeSet.mutationType.type === "referenceChange") {
|
|
2064
|
+
const { formNode } = changeSet;
|
|
2065
|
+
const blueprint = getFormNodeBlueprint(formNode, state);
|
|
2066
|
+
if (!changeSet.value) {
|
|
2067
|
+
dispatch({
|
|
2068
|
+
type: "setIn",
|
|
2069
|
+
value: __spreadProps(__spreadValues({}, changeSet), {
|
|
2070
|
+
value: null
|
|
2071
|
+
})
|
|
2072
|
+
});
|
|
2073
|
+
} else {
|
|
2074
|
+
cms.api.tina.request(`
|
|
2075
|
+
query Node($id: String!) {
|
|
2076
|
+
node(id: $id) {
|
|
2077
|
+
${G.print(blueprint.selection)}
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
`, { variables: { id: changeSet.value } }).then(async (res) => {
|
|
2081
|
+
const form = state.documentForms.find((documentForm) => documentForm.id === formNode.documentFormId);
|
|
2082
|
+
const data = await resolveSubFields({
|
|
2083
|
+
formNode,
|
|
2084
|
+
form,
|
|
2085
|
+
loc: formNode.location
|
|
2086
|
+
});
|
|
2087
|
+
dispatch({
|
|
2088
|
+
type: "setIn",
|
|
2089
|
+
value: __spreadProps(__spreadValues({}, changeSet), {
|
|
2090
|
+
value: __spreadProps(__spreadValues({}, res.node), {
|
|
2091
|
+
data
|
|
2092
|
+
})
|
|
2093
|
+
})
|
|
2094
|
+
});
|
|
2095
|
+
}).catch((e) => {
|
|
2096
|
+
cms.alerts.error(`Unexpected error fetching reference`);
|
|
2097
|
+
console.log(e);
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
} else {
|
|
2101
|
+
dispatch({ type: "setIn", value: changeSet });
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
2105
|
+
}, [state.changeSets.length]);
|
|
2106
|
+
React.useEffect(() => {
|
|
2107
|
+
formIds.current = state.documentForms.map((df) => df.id);
|
|
2108
|
+
}, [state.documentForms.length]);
|
|
2109
|
+
React.useEffect(() => {
|
|
2110
|
+
return () => {
|
|
2111
|
+
formIds.current.forEach((formId) => {
|
|
2112
|
+
const form = cms.forms.find(formId);
|
|
2113
|
+
if (form) {
|
|
2114
|
+
cms.plugins.remove(form);
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
2117
|
+
};
|
|
2118
|
+
}, []);
|
|
2119
|
+
const resolveSubFields = React.useCallback(async (args) => {
|
|
2120
|
+
const { form, formNode, prefix, loc } = args;
|
|
2121
|
+
const data = {};
|
|
2122
|
+
await sequential(form.fields, async (field) => {
|
|
2123
|
+
const value = form.values[field.name];
|
|
2124
|
+
const fieldName = field.list ? `${field.name}.[]` : field.name;
|
|
2125
|
+
const blueprint = getFormNodeBlueprint(formNode, state);
|
|
2126
|
+
const blueprintName = getBlueprintNamePath(blueprint);
|
|
2127
|
+
const extra = [];
|
|
2128
|
+
if (prefix) {
|
|
2129
|
+
extra.push(prefix);
|
|
2130
|
+
}
|
|
2131
|
+
const matchName = [
|
|
2132
|
+
blueprintName,
|
|
2133
|
+
DATA_NODE_NAME,
|
|
2134
|
+
...extra,
|
|
2135
|
+
fieldName
|
|
2136
|
+
].join(".");
|
|
2137
|
+
const fieldBlueprints = blueprint.fields.filter((fieldBlueprint) => {
|
|
2138
|
+
return matchName === getBlueprintNamePath(fieldBlueprint);
|
|
2139
|
+
});
|
|
2140
|
+
switch (field.type) {
|
|
2141
|
+
case "object":
|
|
2142
|
+
if (field.templates) {
|
|
2143
|
+
if (field.list) {
|
|
2144
|
+
await sequential(fieldBlueprints, async (fieldBlueprint) => {
|
|
2145
|
+
const keyName = getFieldNameOrAlias(fieldBlueprint);
|
|
2146
|
+
if (!value) {
|
|
2147
|
+
data[keyName] = null;
|
|
2148
|
+
return true;
|
|
2149
|
+
}
|
|
2150
|
+
if (!Array.isArray(value)) {
|
|
2151
|
+
throw new Error(`Expected value for object list field to be an array`);
|
|
2152
|
+
}
|
|
2153
|
+
const d = [];
|
|
2154
|
+
await sequential(value, async (item, index) => {
|
|
2155
|
+
const template = field.templates[item._template];
|
|
2156
|
+
const d2 = await resolveSubFields({
|
|
2157
|
+
formNode,
|
|
2158
|
+
form: { fields: template.fields, values: item },
|
|
2159
|
+
prefix: [prefix, fieldName].join("."),
|
|
2160
|
+
loc: [...loc, index]
|
|
2161
|
+
});
|
|
2162
|
+
d.push(d2);
|
|
2163
|
+
});
|
|
2164
|
+
data[keyName] = d;
|
|
2165
|
+
});
|
|
2166
|
+
} else {
|
|
2167
|
+
throw new Error("blocks without list true is not yet supported");
|
|
2168
|
+
}
|
|
2169
|
+
} else {
|
|
2170
|
+
if (field.list) {
|
|
2171
|
+
await sequential(fieldBlueprints, async (fieldBlueprint) => {
|
|
2172
|
+
const keyName = getFieldNameOrAlias(fieldBlueprint);
|
|
2173
|
+
if (!value) {
|
|
2174
|
+
data[keyName] = null;
|
|
2175
|
+
return true;
|
|
2176
|
+
}
|
|
2177
|
+
if (!Array.isArray(value)) {
|
|
2178
|
+
throw new Error(`Expected value for object list field to be an array`);
|
|
2179
|
+
}
|
|
2180
|
+
const d = [];
|
|
2181
|
+
await sequential(value, async (item, index) => {
|
|
2182
|
+
const d2 = await resolveSubFields({
|
|
2183
|
+
formNode,
|
|
2184
|
+
form: { fields: field.fields, values: item },
|
|
2185
|
+
prefix: [prefix, fieldName].join("."),
|
|
2186
|
+
loc: [...loc, index]
|
|
2187
|
+
});
|
|
2188
|
+
d.push(d2);
|
|
2189
|
+
return true;
|
|
2190
|
+
});
|
|
2191
|
+
data[keyName] = d;
|
|
2192
|
+
return true;
|
|
2193
|
+
});
|
|
2194
|
+
} else {
|
|
2195
|
+
await sequential(fieldBlueprints, async (fieldBlueprint) => {
|
|
2196
|
+
const keyName = getFieldNameOrAlias(fieldBlueprint);
|
|
2197
|
+
if (!value) {
|
|
2198
|
+
data[keyName] = null;
|
|
2199
|
+
return true;
|
|
2200
|
+
}
|
|
2201
|
+
const d = await resolveSubFields({
|
|
2202
|
+
formNode,
|
|
2203
|
+
form: { fields: field.fields, values: value },
|
|
2204
|
+
prefix: [prefix, fieldName].join("."),
|
|
2205
|
+
loc
|
|
2206
|
+
});
|
|
2207
|
+
data[keyName] = d;
|
|
2208
|
+
return true;
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
break;
|
|
2213
|
+
case "reference":
|
|
2214
|
+
let form2;
|
|
2215
|
+
if (typeof value === "string") {
|
|
2216
|
+
const existingForm = cms.forms.find(value);
|
|
2217
|
+
if (existingForm) {
|
|
2218
|
+
form2 = existingForm;
|
|
2219
|
+
} else {
|
|
2220
|
+
const formInfo = await cms.api.tina.request(`#graphql
|
|
2221
|
+
query Node($id: String!) {
|
|
2222
|
+
node(id: $id) {
|
|
2223
|
+
...on Document {
|
|
2224
|
+
form
|
|
2225
|
+
values
|
|
2226
|
+
_internalSys: sys {
|
|
2227
|
+
path
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
`, { variables: { id: value } });
|
|
2233
|
+
form2 = buildForm(formInfo.node, cms, formifyFunc, false, onSubmit);
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
await sequential(fieldBlueprints, async (fieldBlueprint) => {
|
|
2237
|
+
const keyName = getFieldNameOrAlias(fieldBlueprint);
|
|
2238
|
+
if (!value) {
|
|
2239
|
+
data[keyName] = null;
|
|
2240
|
+
return true;
|
|
2241
|
+
}
|
|
2242
|
+
const documentBlueprint = state.blueprints.find((dp) => getBlueprintNamePath(dp) === matchName);
|
|
2243
|
+
const location = [...formNode.location];
|
|
2244
|
+
if (loc) {
|
|
2245
|
+
loc.forEach((item) => location.push(item));
|
|
2246
|
+
}
|
|
2247
|
+
const subDocumentFormNode = buildFormNode(documentBlueprint, form2, location);
|
|
2248
|
+
dispatch({
|
|
2249
|
+
type: "addOrReplaceDocumentFormNode",
|
|
2250
|
+
value: {
|
|
2251
|
+
formNode: subDocumentFormNode,
|
|
2252
|
+
documentForm: form2
|
|
2253
|
+
}
|
|
2254
|
+
});
|
|
2255
|
+
const res = await cms.api.tina.request(`
|
|
2256
|
+
query Node($id: String!) {
|
|
2257
|
+
node(id: $id) {
|
|
2258
|
+
${G.print(documentBlueprint.selection)}
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
`, { variables: { id: value } });
|
|
2262
|
+
const d = await resolveSubFields({
|
|
2263
|
+
formNode: subDocumentFormNode,
|
|
2264
|
+
form: form2,
|
|
2265
|
+
loc: location
|
|
2266
|
+
});
|
|
2267
|
+
data[keyName] = __spreadProps(__spreadValues({}, res.node), { data: d });
|
|
2268
|
+
});
|
|
2269
|
+
break;
|
|
2270
|
+
default:
|
|
2271
|
+
fieldBlueprints.forEach((fieldBlueprint) => {
|
|
2272
|
+
const keyName = getFieldNameOrAlias(fieldBlueprint);
|
|
2273
|
+
if (!value) {
|
|
2274
|
+
data[keyName] = null;
|
|
2275
|
+
} else {
|
|
2276
|
+
data[keyName] = value;
|
|
2277
|
+
}
|
|
2278
|
+
});
|
|
2279
|
+
break;
|
|
1236
2280
|
}
|
|
2281
|
+
return true;
|
|
1237
2282
|
});
|
|
1238
|
-
return
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
2283
|
+
return data;
|
|
2284
|
+
}, [cms, JSON.stringify(state), dispatch]);
|
|
2285
|
+
return __spreadProps(__spreadValues({}, state), {
|
|
2286
|
+
queryString: G.print(state.query)
|
|
2287
|
+
});
|
|
2288
|
+
};
|
|
2289
|
+
const buildFormNode = (documentBlueprint, form, location) => {
|
|
2290
|
+
return {
|
|
2291
|
+
documentBlueprintId: documentBlueprint.id,
|
|
2292
|
+
documentFormId: form.id,
|
|
2293
|
+
location
|
|
2294
|
+
};
|
|
2295
|
+
};
|
|
2296
|
+
const captureBranchName = /^refs\/heads\/(.*)/;
|
|
2297
|
+
const parseRefForBranchName = (ref) => {
|
|
2298
|
+
const matches = ref.match(captureBranchName);
|
|
2299
|
+
return matches[1];
|
|
2300
|
+
};
|
|
2301
|
+
class Client {
|
|
2302
|
+
constructor(_a) {
|
|
2303
|
+
var _b = _a, { tokenStorage = "MEMORY" } = _b, options = __objRest(_b, ["tokenStorage"]);
|
|
2304
|
+
this.events = new EventBus();
|
|
2305
|
+
this.addPendingContent = async (props) => {
|
|
2306
|
+
const mutation = `#graphql
|
|
2307
|
+
mutation addPendingDocumentMutation(
|
|
2308
|
+
$relativePath: String!
|
|
2309
|
+
$collection: String!
|
|
2310
|
+
$template: String
|
|
2311
|
+
) {
|
|
2312
|
+
addPendingDocument(
|
|
2313
|
+
relativePath: $relativePath
|
|
2314
|
+
template: $template
|
|
2315
|
+
collection: $collection
|
|
2316
|
+
) {
|
|
2317
|
+
... on Document {
|
|
2318
|
+
sys {
|
|
2319
|
+
relativePath
|
|
2320
|
+
path
|
|
2321
|
+
breadcrumbs
|
|
2322
|
+
collection {
|
|
2323
|
+
slug
|
|
2324
|
+
}
|
|
1253
2325
|
}
|
|
1254
|
-
}
|
|
1255
|
-
return response;
|
|
2326
|
+
}
|
|
1256
2327
|
}
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
const client = cms.api.tina;
|
|
1268
|
-
const [activeModal, setActiveModal] = useState(null);
|
|
1269
|
-
const [showChildren, setShowChildren] = useState(false);
|
|
1270
|
-
React.useEffect(() => {
|
|
1271
|
-
client.isAuthenticated().then((isAuthenticated) => {
|
|
1272
|
-
if (isAuthenticated) {
|
|
1273
|
-
setShowChildren(true);
|
|
1274
|
-
cms.enable();
|
|
1275
|
-
} else {
|
|
1276
|
-
sleep(500).then(() => {
|
|
1277
|
-
setActiveModal("authenticate");
|
|
2328
|
+
}`;
|
|
2329
|
+
const result = await this.request(mutation, {
|
|
2330
|
+
variables: props
|
|
2331
|
+
});
|
|
2332
|
+
return result;
|
|
2333
|
+
};
|
|
2334
|
+
this.getSchema = async () => {
|
|
2335
|
+
if (!this.schema) {
|
|
2336
|
+
const data = await this.request(getIntrospectionQuery(), {
|
|
2337
|
+
variables: {}
|
|
1278
2338
|
});
|
|
2339
|
+
this.schema = buildClientSchema(data);
|
|
1279
2340
|
}
|
|
2341
|
+
return this.schema;
|
|
2342
|
+
};
|
|
2343
|
+
this.getOptimizedQuery = async (documentNode) => {
|
|
2344
|
+
const data = await this.request(`query GetOptimizedQuery($queryString: String!) {
|
|
2345
|
+
getOptimizedQuery(queryString: $queryString)
|
|
2346
|
+
}`, {
|
|
2347
|
+
variables: { queryString: print(documentNode) }
|
|
2348
|
+
});
|
|
2349
|
+
return parse(data.getOptimizedQuery);
|
|
2350
|
+
};
|
|
2351
|
+
this.options = options;
|
|
2352
|
+
this.setBranch(options.branch);
|
|
2353
|
+
this.events.subscribe("branch:change", ({ branchName }) => {
|
|
2354
|
+
this.setBranch(branchName);
|
|
1280
2355
|
});
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
2356
|
+
this.clientId = options.clientId;
|
|
2357
|
+
switch (tokenStorage) {
|
|
2358
|
+
case "LOCAL_STORAGE":
|
|
2359
|
+
this.getToken = async function() {
|
|
2360
|
+
const tokens = localStorage.getItem(AUTH_TOKEN_KEY) || null;
|
|
2361
|
+
if (tokens) {
|
|
2362
|
+
return await this.getRefreshedToken(tokens);
|
|
2363
|
+
} else {
|
|
2364
|
+
return {
|
|
2365
|
+
access_token: null,
|
|
2366
|
+
id_token: null,
|
|
2367
|
+
refresh_token: null
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
};
|
|
2371
|
+
this.setToken = function(token) {
|
|
2372
|
+
localStorage.setItem(AUTH_TOKEN_KEY, JSON.stringify(token, null, 2));
|
|
2373
|
+
};
|
|
2374
|
+
break;
|
|
2375
|
+
case "MEMORY":
|
|
2376
|
+
this.getToken = async () => {
|
|
2377
|
+
if (this.token) {
|
|
2378
|
+
return await this.getRefreshedToken(this.token);
|
|
2379
|
+
} else {
|
|
2380
|
+
return {
|
|
2381
|
+
access_token: null,
|
|
2382
|
+
id_token: null,
|
|
2383
|
+
refresh_token: null
|
|
2384
|
+
};
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
this.setToken = (token) => {
|
|
2388
|
+
this.token = JSON.stringify(token, null, 2);
|
|
2389
|
+
};
|
|
2390
|
+
break;
|
|
2391
|
+
case "CUSTOM":
|
|
2392
|
+
if (!options.getTokenFn) {
|
|
2393
|
+
throw new Error("When CUSTOM token storage is selected, a getTokenFn must be provided");
|
|
2394
|
+
}
|
|
2395
|
+
this.getToken = options.getTokenFn;
|
|
2396
|
+
break;
|
|
1288
2397
|
}
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
2398
|
+
}
|
|
2399
|
+
get isLocalMode() {
|
|
2400
|
+
return this.contentApiUrl.includes("localhost");
|
|
2401
|
+
}
|
|
2402
|
+
setBranch(branchName) {
|
|
2403
|
+
var _a, _b, _c;
|
|
2404
|
+
const encodedBranch = encodeURIComponent(branchName);
|
|
2405
|
+
this.frontendUrl = ((_a = this.options.tinaioConfig) == null ? void 0 : _a.frontendUrlOverride) || "https://app.tina.io";
|
|
2406
|
+
this.identityApiUrl = ((_b = this.options.tinaioConfig) == null ? void 0 : _b.identityApiUrlOverride) || "https://identity.tinajs.io";
|
|
2407
|
+
this.contentApiBase = ((_c = this.options.tinaioConfig) == null ? void 0 : _c.contentApiUrlOverride) || `https://content.tinajs.io`;
|
|
2408
|
+
this.contentApiUrl = this.options.customContentApiUrl || `${this.contentApiBase}/content/${this.options.clientId}/github/${encodedBranch}`;
|
|
2409
|
+
}
|
|
2410
|
+
async requestWithForm(query, {
|
|
2411
|
+
variables,
|
|
2412
|
+
useUnstableFormify
|
|
2413
|
+
}) {
|
|
2414
|
+
const schema = await this.getSchema();
|
|
2415
|
+
let formifiedQuery;
|
|
2416
|
+
if (useUnstableFormify) {
|
|
2417
|
+
const res = await formify({
|
|
2418
|
+
schema,
|
|
2419
|
+
query: print(query(gql$1)),
|
|
2420
|
+
getOptimizedQuery: this.getOptimizedQuery
|
|
2421
|
+
});
|
|
2422
|
+
formifiedQuery = res.formifiedQuery;
|
|
2423
|
+
} else {
|
|
2424
|
+
formifiedQuery = formify$1(query(gql$1), schema);
|
|
1293
2425
|
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
action: async () => {
|
|
1303
|
-
setEditing(false);
|
|
1304
|
-
window.location.reload();
|
|
1305
|
-
},
|
|
1306
|
-
name: "Close",
|
|
1307
|
-
primary: false
|
|
2426
|
+
return this.request(print(formifiedQuery), { variables });
|
|
2427
|
+
}
|
|
2428
|
+
async request(query, { variables }) {
|
|
2429
|
+
const res = await fetch(this.contentApiUrl, {
|
|
2430
|
+
method: "POST",
|
|
2431
|
+
headers: {
|
|
2432
|
+
"Content-Type": "application/json",
|
|
2433
|
+
Authorization: "Bearer " + (await this.getToken()).id_token
|
|
1308
2434
|
},
|
|
1309
|
-
{
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
useTinaAuthRedirect();
|
|
1324
|
-
const cms = React.useMemo(() => props.cms || new TinaCMS({
|
|
1325
|
-
enabled: true,
|
|
1326
|
-
sidebar: true
|
|
1327
|
-
}), [props.cms]);
|
|
1328
|
-
if (!cms.api.tina) {
|
|
1329
|
-
cms.registerApi("tina", createClient(props));
|
|
2435
|
+
body: JSON.stringify({
|
|
2436
|
+
query: typeof query === "function" ? print(query(gql$1)) : query,
|
|
2437
|
+
variables
|
|
2438
|
+
})
|
|
2439
|
+
});
|
|
2440
|
+
if (res.status !== 200) {
|
|
2441
|
+
throw new Error(`Unable to complete request, ${res.statusText}`);
|
|
2442
|
+
}
|
|
2443
|
+
const json = await res.json();
|
|
2444
|
+
if (json.errors) {
|
|
2445
|
+
throw new Error(`Unable to fetch, errors:
|
|
2446
|
+
${json.errors.map((error) => error.message).join("\n")}`);
|
|
2447
|
+
}
|
|
2448
|
+
return json.data;
|
|
1330
2449
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
2450
|
+
parseJwt(token) {
|
|
2451
|
+
const base64Url = token.split(".")[1];
|
|
2452
|
+
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
2453
|
+
const jsonPayload = decodeURIComponent(atob(base64).split("").map(function(c) {
|
|
2454
|
+
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
2455
|
+
}).join(""));
|
|
2456
|
+
return JSON.parse(jsonPayload);
|
|
1333
2457
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
2458
|
+
async getRefreshedToken(tokens) {
|
|
2459
|
+
const { access_token, id_token, refresh_token } = JSON.parse(tokens);
|
|
2460
|
+
const { exp, iss, client_id } = this.parseJwt(access_token);
|
|
2461
|
+
if (Date.now() / 1e3 >= exp - 120) {
|
|
2462
|
+
const refreshResponse = await fetch(iss, {
|
|
2463
|
+
method: "POST",
|
|
2464
|
+
headers: {
|
|
2465
|
+
"Content-Type": "application/x-amz-json-1.1",
|
|
2466
|
+
"x-amz-target": "AWSCognitoIdentityProviderService.InitiateAuth"
|
|
2467
|
+
},
|
|
2468
|
+
body: JSON.stringify({
|
|
2469
|
+
ClientId: client_id,
|
|
2470
|
+
AuthFlow: "REFRESH_TOKEN_AUTH",
|
|
2471
|
+
AuthParameters: {
|
|
2472
|
+
REFRESH_TOKEN: refresh_token,
|
|
2473
|
+
DEVICE_KEY: null
|
|
2474
|
+
}
|
|
2475
|
+
})
|
|
2476
|
+
});
|
|
2477
|
+
if (refreshResponse.status !== 200) {
|
|
2478
|
+
throw new Error("Unable to refresh auth tokens");
|
|
1342
2479
|
}
|
|
2480
|
+
const responseJson = await refreshResponse.json();
|
|
2481
|
+
const newToken = {
|
|
2482
|
+
access_token: responseJson.AuthenticationResult.AccessToken,
|
|
2483
|
+
id_token: responseJson.AuthenticationResult.IdToken,
|
|
2484
|
+
refresh_token
|
|
2485
|
+
};
|
|
2486
|
+
this.setToken(newToken);
|
|
2487
|
+
return Promise.resolve(newToken);
|
|
1343
2488
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
2489
|
+
return Promise.resolve({ access_token, id_token, refresh_token });
|
|
2490
|
+
}
|
|
2491
|
+
async isAuthorized() {
|
|
2492
|
+
return this.isAuthenticated();
|
|
2493
|
+
}
|
|
2494
|
+
async isAuthenticated() {
|
|
2495
|
+
return !!await this.getUser();
|
|
2496
|
+
}
|
|
2497
|
+
async authenticate() {
|
|
2498
|
+
const token = await authenticate(this.clientId, this.frontendUrl);
|
|
2499
|
+
this.setToken(token);
|
|
2500
|
+
return token;
|
|
2501
|
+
}
|
|
2502
|
+
async fetchWithToken(input, init) {
|
|
2503
|
+
const headers = (init == null ? void 0 : init.headers) || {};
|
|
2504
|
+
return await fetch(input, __spreadProps(__spreadValues({}, init), {
|
|
2505
|
+
headers: new Headers(__spreadValues({
|
|
2506
|
+
Authorization: "Bearer " + (await this.getToken()).id_token
|
|
2507
|
+
}, headers))
|
|
2508
|
+
}));
|
|
2509
|
+
}
|
|
2510
|
+
async getUser() {
|
|
2511
|
+
if (!this.clientId) {
|
|
2512
|
+
return null;
|
|
1350
2513
|
}
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
return newBranch;
|
|
1356
|
-
};
|
|
1357
|
-
setupMedia();
|
|
1358
|
-
const [branchingEnabled, setBranchingEnabled] = React.useState(() => cms.flags.get("branch-switcher"));
|
|
1359
|
-
React.useEffect(() => {
|
|
1360
|
-
cms.events.subscribe("flag:set", ({ key, value }) => {
|
|
1361
|
-
if (key === "branch-switcher") {
|
|
1362
|
-
setBranchingEnabled(value);
|
|
1363
|
-
}
|
|
1364
|
-
});
|
|
1365
|
-
}, [cms.events]);
|
|
1366
|
-
React.useEffect(() => {
|
|
1367
|
-
let branchSwitcher;
|
|
1368
|
-
if (branchingEnabled) {
|
|
1369
|
-
branchSwitcher = new BranchSwitcherPlugin({
|
|
1370
|
-
listBranches: handleListBranches,
|
|
1371
|
-
createBranch: handleCreateBranch
|
|
2514
|
+
const url = `${this.identityApiUrl}/v2/apps/${this.clientId}/currentUser`;
|
|
2515
|
+
try {
|
|
2516
|
+
const res = await this.fetchWithToken(url, {
|
|
2517
|
+
method: "GET"
|
|
1372
2518
|
});
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
cms.plugins.remove(branchSwitcher);
|
|
2519
|
+
const val = await res.json();
|
|
2520
|
+
if (!res.status.toString().startsWith("2")) {
|
|
2521
|
+
console.error(val.error);
|
|
2522
|
+
return null;
|
|
1378
2523
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
props.cmsCallback(cms);
|
|
1384
|
-
}
|
|
1385
|
-
}, []);
|
|
1386
|
-
return /* @__PURE__ */ React.createElement(BranchDataProvider, {
|
|
1387
|
-
currentBranch,
|
|
1388
|
-
setCurrentBranch: (b) => {
|
|
1389
|
-
setCurrentBranch(b);
|
|
2524
|
+
return val;
|
|
2525
|
+
} catch (e) {
|
|
2526
|
+
console.error(e);
|
|
2527
|
+
return null;
|
|
1390
2528
|
}
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
};
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
const [newUpdate, setNewUpdate] = React.useState(null);
|
|
1411
|
-
const { currentBranch } = useBranchData();
|
|
1412
|
-
const updateData = async () => {
|
|
1413
|
-
var _a;
|
|
1414
|
-
if (newUpdate) {
|
|
1415
|
-
const newValue = getIn(formValues, newUpdate.get);
|
|
1416
|
-
const activeForm = getIn(data, [newUpdate.queryName, "form"].join("."));
|
|
1417
|
-
if (!activeForm) {
|
|
1418
|
-
throw new Error(`Unable to find form for query ${newUpdate.queryName}`);
|
|
1419
|
-
}
|
|
1420
|
-
if (activeForm == null ? void 0 : activeForm.paths) {
|
|
1421
|
-
const asyncUpdate = (_a = activeForm.paths) == null ? void 0 : _a.find((p) => p.dataPath.join(".") === newUpdate.setReference);
|
|
1422
|
-
if (asyncUpdate) {
|
|
1423
|
-
const res = await cms.api.tina.request(asyncUpdate.queryString, {
|
|
1424
|
-
variables: { id: newValue }
|
|
1425
|
-
});
|
|
1426
|
-
const newData2 = setIn(data, newUpdate.set, res.node);
|
|
1427
|
-
const newDataAndNewJSONData2 = setIn(newData2, newUpdate.set.replace("data", "dataJSON"), newValue);
|
|
1428
|
-
setData(newDataAndNewJSONData2);
|
|
1429
|
-
setNewUpdate(null);
|
|
1430
|
-
return;
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
if (newUpdate.lookup) {
|
|
1434
|
-
const field = getFieldUpdate(newUpdate, activeForm, formValues);
|
|
1435
|
-
if (field && field.typeMap) {
|
|
1436
|
-
newValue.forEach((item) => {
|
|
1437
|
-
if (!item.__typename) {
|
|
1438
|
-
item["__typename"] = field.typeMap[item._template];
|
|
1439
|
-
}
|
|
1440
|
-
});
|
|
2529
|
+
}
|
|
2530
|
+
async listBranches() {
|
|
2531
|
+
const url = `${this.contentApiBase}/github/${this.clientId}/list_branches`;
|
|
2532
|
+
const res = await this.fetchWithToken(url, {
|
|
2533
|
+
method: "GET"
|
|
2534
|
+
});
|
|
2535
|
+
return res.json();
|
|
2536
|
+
}
|
|
2537
|
+
async createBranch({ baseBranch, branchName }) {
|
|
2538
|
+
const url = `${this.contentApiBase}/github/${this.clientId}/create_branch`;
|
|
2539
|
+
try {
|
|
2540
|
+
const res = await this.fetchWithToken(url, {
|
|
2541
|
+
method: "POST",
|
|
2542
|
+
body: JSON.stringify({
|
|
2543
|
+
baseBranch,
|
|
2544
|
+
branchName
|
|
2545
|
+
}),
|
|
2546
|
+
headers: {
|
|
2547
|
+
"Content-Type": "application/json"
|
|
1441
2548
|
}
|
|
1442
|
-
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
2549
|
+
});
|
|
2550
|
+
return await res.json().then((r) => parseRefForBranchName(r.data.ref));
|
|
2551
|
+
} catch (error) {
|
|
2552
|
+
console.error("There was an error creating a new branch.", error);
|
|
2553
|
+
return null;
|
|
1447
2554
|
}
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
const DEFAULT_LOCAL_TINA_GQL_SERVER_URL = "http://localhost:4001/graphql";
|
|
2558
|
+
class LocalClient extends Client {
|
|
2559
|
+
constructor(props) {
|
|
2560
|
+
const clientProps = {
|
|
2561
|
+
clientId: "",
|
|
2562
|
+
branch: "",
|
|
2563
|
+
customContentApiUrl: props && props.customContentApiUrl ? props.customContentApiUrl : DEFAULT_LOCAL_TINA_GQL_SERVER_URL
|
|
2564
|
+
};
|
|
2565
|
+
super(clientProps);
|
|
2566
|
+
}
|
|
2567
|
+
async isAuthorized() {
|
|
2568
|
+
return true;
|
|
2569
|
+
}
|
|
2570
|
+
async isAuthenticated() {
|
|
2571
|
+
return true;
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
function ModalBuilder(modalProps) {
|
|
2575
|
+
return /* @__PURE__ */ React.createElement(Modal, null, /* @__PURE__ */ React.createElement(ModalPopup, null, /* @__PURE__ */ React.createElement(ModalHeader, null, modalProps.title), /* @__PURE__ */ React.createElement(ModalBody, {
|
|
2576
|
+
padded: true
|
|
2577
|
+
}, /* @__PURE__ */ React.createElement("p", null, modalProps.message), modalProps.error && /* @__PURE__ */ React.createElement(ErrorLabel, null, modalProps.error)), /* @__PURE__ */ React.createElement(ModalActions, null, modalProps.actions.map((action) => /* @__PURE__ */ React.createElement(AsyncButton, __spreadValues({
|
|
2578
|
+
key: action.name
|
|
2579
|
+
}, action))))));
|
|
2580
|
+
}
|
|
2581
|
+
const ErrorLabel = styled.p`
|
|
2582
|
+
color: var(--tina-color-error) !important;
|
|
2583
|
+
`;
|
|
2584
|
+
const AsyncButton = ({ name, primary, action }) => {
|
|
2585
|
+
const [submitting, setSubmitting] = useState(false);
|
|
2586
|
+
const onClick = useCallback(async () => {
|
|
2587
|
+
setSubmitting(true);
|
|
2588
|
+
try {
|
|
2589
|
+
await action();
|
|
2590
|
+
setSubmitting(false);
|
|
2591
|
+
} catch (e) {
|
|
2592
|
+
setSubmitting(false);
|
|
2593
|
+
throw e;
|
|
1456
2594
|
}
|
|
1457
|
-
}, [
|
|
1458
|
-
React.
|
|
1459
|
-
|
|
1460
|
-
|
|
2595
|
+
}, [action, setSubmitting]);
|
|
2596
|
+
return /* @__PURE__ */ React.createElement(Button, {
|
|
2597
|
+
variant: primary ? "primary" : "secondary",
|
|
2598
|
+
onClick,
|
|
2599
|
+
busy: submitting,
|
|
2600
|
+
disabled: submitting
|
|
2601
|
+
}, submitting && /* @__PURE__ */ React.createElement(LoadingDots, null), !submitting && name);
|
|
2602
|
+
};
|
|
2603
|
+
const TINA_AUTH_CONFIG = "tina_auth_config";
|
|
2604
|
+
const useTinaAuthRedirect = () => {
|
|
2605
|
+
useEffect(() => {
|
|
2606
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
2607
|
+
const config = {
|
|
2608
|
+
code: urlParams.get("code") || "",
|
|
2609
|
+
scope: urlParams.get("scope") || "email",
|
|
2610
|
+
state: urlParams.get("state")
|
|
2611
|
+
};
|
|
2612
|
+
if (!config.code) {
|
|
1461
2613
|
return;
|
|
1462
2614
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
label
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
} else {
|
|
1506
|
-
try {
|
|
1507
|
-
await cms.api.tina.request(mutationString, {
|
|
1508
|
-
variables: variables2
|
|
1509
|
-
});
|
|
1510
|
-
cms.alerts.success("Document saved!");
|
|
1511
|
-
} catch (e) {
|
|
1512
|
-
cms.alerts.error("There was a problem saving your document");
|
|
1513
|
-
console.error(e);
|
|
2615
|
+
localStorage[TINA_AUTH_CONFIG] = JSON.stringify(config);
|
|
2616
|
+
}, []);
|
|
2617
|
+
};
|
|
2618
|
+
class TinaAdminApi {
|
|
2619
|
+
constructor(cms) {
|
|
2620
|
+
this.api = cms.api.tina;
|
|
2621
|
+
}
|
|
2622
|
+
async isAuthenticated() {
|
|
2623
|
+
return await this.api.isAuthenticated();
|
|
2624
|
+
}
|
|
2625
|
+
async fetchCollections() {
|
|
2626
|
+
const response = await this.api.request(`#graphql
|
|
2627
|
+
query{
|
|
2628
|
+
getCollections {
|
|
2629
|
+
label,
|
|
2630
|
+
name
|
|
2631
|
+
}
|
|
2632
|
+
}`, { variables: {} });
|
|
2633
|
+
return response;
|
|
2634
|
+
}
|
|
2635
|
+
async fetchCollection(collectionName, includeDocuments) {
|
|
2636
|
+
const response = await this.api.request(`#graphql
|
|
2637
|
+
query($collection: String!, $includeDocuments: Boolean!){
|
|
2638
|
+
getCollection(collection: $collection){
|
|
2639
|
+
name
|
|
2640
|
+
label
|
|
2641
|
+
format
|
|
2642
|
+
templates
|
|
2643
|
+
documents @include(if: $includeDocuments) {
|
|
2644
|
+
totalCount
|
|
2645
|
+
edges {
|
|
2646
|
+
node {
|
|
2647
|
+
... on Document {
|
|
2648
|
+
sys {
|
|
2649
|
+
template
|
|
2650
|
+
breadcrumbs
|
|
2651
|
+
path
|
|
2652
|
+
basename
|
|
2653
|
+
relativePath
|
|
2654
|
+
filename
|
|
2655
|
+
extension
|
|
2656
|
+
}
|
|
1514
2657
|
}
|
|
1515
2658
|
}
|
|
1516
|
-
} catch (e) {
|
|
1517
|
-
console.error(e);
|
|
1518
|
-
cms.alerts.error("There was a problem saving your document");
|
|
1519
2659
|
}
|
|
1520
2660
|
}
|
|
1521
|
-
};
|
|
1522
|
-
const { createForm, createGlobalForm } = generateFormCreators(cms);
|
|
1523
|
-
const SKIPPED = "SKIPPED";
|
|
1524
|
-
let form;
|
|
1525
|
-
let skipped;
|
|
1526
|
-
const skip = () => {
|
|
1527
|
-
skipped = SKIPPED;
|
|
1528
|
-
};
|
|
1529
|
-
if (skipped)
|
|
1530
|
-
return;
|
|
1531
|
-
if (formify2) {
|
|
1532
|
-
form = formify2({ formConfig, createForm, createGlobalForm, skip }, cms);
|
|
1533
|
-
} else {
|
|
1534
|
-
form = createForm(formConfig);
|
|
1535
2661
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
2662
|
+
}`, { variables: { collection: collectionName, includeDocuments } });
|
|
2663
|
+
return response;
|
|
2664
|
+
}
|
|
2665
|
+
async fetchDocument(collectionName, relativePath) {
|
|
2666
|
+
const response = await this.api.request(`#graphql
|
|
2667
|
+
query($collection: String!, $relativePath: String!) {
|
|
2668
|
+
getDocument(collection:$collection, relativePath:$relativePath) {
|
|
2669
|
+
... on Document {
|
|
2670
|
+
form
|
|
2671
|
+
values
|
|
1539
2672
|
}
|
|
1540
|
-
throw new Error("formify must return a form or skip()");
|
|
1541
2673
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
queryName,
|
|
1567
|
-
get: [queryName, "values", name].join("."),
|
|
1568
|
-
set: [queryName, "data", name].join("."),
|
|
1569
|
-
setReference: [queryName, "data", referenceName].join(".")
|
|
1570
|
-
}, extra));
|
|
1571
|
-
};
|
|
1572
|
-
form.finalForm.mutators = __spreadValues({
|
|
1573
|
-
insert: (...args) => {
|
|
1574
|
-
const fieldName = args[0];
|
|
1575
|
-
prepareNewUpdate(fieldName, fieldName);
|
|
1576
|
-
insert(...args);
|
|
1577
|
-
},
|
|
1578
|
-
move: (...args) => {
|
|
1579
|
-
const fieldName = args[0];
|
|
1580
|
-
prepareNewUpdate(fieldName, fieldName);
|
|
1581
|
-
move(...args);
|
|
1582
|
-
},
|
|
1583
|
-
remove: (...args) => {
|
|
1584
|
-
const fieldName = args[0];
|
|
1585
|
-
prepareNewUpdate(fieldName, fieldName);
|
|
1586
|
-
remove(...args);
|
|
1587
|
-
}
|
|
1588
|
-
}, rest);
|
|
1589
|
-
form.subscribe(({ values }) => {
|
|
1590
|
-
setFormValues(__spreadProps(__spreadValues({}, formValues), { [queryName]: { values } }));
|
|
1591
|
-
}, { values: true });
|
|
1592
|
-
});
|
|
1593
|
-
}).catch((e) => {
|
|
1594
|
-
cms.alerts.error("There was a problem setting up forms for your query");
|
|
1595
|
-
console.error("There was a problem setting up forms for your query");
|
|
1596
|
-
console.error(e);
|
|
1597
|
-
setIsLoading(false);
|
|
2674
|
+
}`, { variables: { collection: collectionName, relativePath } });
|
|
2675
|
+
return response;
|
|
2676
|
+
}
|
|
2677
|
+
async fetchDocumentFields() {
|
|
2678
|
+
const response = await this.api.request(`#graphql
|
|
2679
|
+
query {
|
|
2680
|
+
getDocumentFields
|
|
2681
|
+
}`, { variables: {} });
|
|
2682
|
+
return response;
|
|
2683
|
+
}
|
|
2684
|
+
async createDocument(collectionName, relativePath, params) {
|
|
2685
|
+
const response = await this.api.request(`#graphql
|
|
2686
|
+
mutation($collection: String!, $relativePath: String!, $params: DocumentMutation!) {
|
|
2687
|
+
createDocument(
|
|
2688
|
+
collection: $collection,
|
|
2689
|
+
relativePath: $relativePath,
|
|
2690
|
+
params: $params
|
|
2691
|
+
){__typename}
|
|
2692
|
+
}`, {
|
|
2693
|
+
variables: {
|
|
2694
|
+
collection: collectionName,
|
|
2695
|
+
relativePath,
|
|
2696
|
+
params
|
|
2697
|
+
}
|
|
1598
2698
|
});
|
|
1599
|
-
return
|
|
1600
|
-
formIds.forEach((name) => {
|
|
1601
|
-
const formPlugin = cms.forms.find(name);
|
|
1602
|
-
if (formPlugin) {
|
|
1603
|
-
cms.forms.remove(formPlugin);
|
|
1604
|
-
}
|
|
1605
|
-
});
|
|
1606
|
-
};
|
|
1607
|
-
}, [query, JSON.stringify(variables), currentBranch]);
|
|
1608
|
-
return [data, isLoading];
|
|
1609
|
-
}
|
|
1610
|
-
const transformDocumentIntoMutationRequestPayload = (document, instructions) => {
|
|
1611
|
-
const _a = document, { _collection, __typename, _template } = _a, rest = __objRest(_a, ["_collection", "__typename", "_template"]);
|
|
1612
|
-
const params = transformParams(rest);
|
|
1613
|
-
const paramsWithTemplate = instructions.includeTemplate ? { [_template]: params } : params;
|
|
1614
|
-
return instructions.includeCollection ? { [_collection]: paramsWithTemplate } : paramsWithTemplate;
|
|
1615
|
-
};
|
|
1616
|
-
const transformParams = (data) => {
|
|
1617
|
-
if (["string", "number", "boolean"].includes(typeof data)) {
|
|
1618
|
-
return data;
|
|
2699
|
+
return response;
|
|
1619
2700
|
}
|
|
1620
|
-
|
|
1621
|
-
|
|
2701
|
+
async updateDocument(collectionName, relativePath, params) {
|
|
2702
|
+
const response = await this.api.request(`#graphql
|
|
2703
|
+
mutation($collection: String!, $relativePath: String!, $params: DocumentMutation!) {
|
|
2704
|
+
updateDocument(
|
|
2705
|
+
collection: $collection,
|
|
2706
|
+
relativePath: $relativePath,
|
|
2707
|
+
params: $params
|
|
2708
|
+
){__typename}
|
|
2709
|
+
}`, {
|
|
2710
|
+
variables: {
|
|
2711
|
+
collection: collectionName,
|
|
2712
|
+
relativePath,
|
|
2713
|
+
params
|
|
2714
|
+
}
|
|
2715
|
+
});
|
|
2716
|
+
return response;
|
|
1622
2717
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
2718
|
+
}
|
|
2719
|
+
function sleep(ms) {
|
|
2720
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2721
|
+
}
|
|
2722
|
+
const AuthWallInner = ({
|
|
2723
|
+
children,
|
|
2724
|
+
cms,
|
|
2725
|
+
loginScreen,
|
|
2726
|
+
getModalActions
|
|
2727
|
+
}) => {
|
|
2728
|
+
const client = cms.api.tina;
|
|
2729
|
+
const [activeModal, setActiveModal] = useState(null);
|
|
2730
|
+
const [showChildren, setShowChildren] = useState(false);
|
|
2731
|
+
React.useEffect(() => {
|
|
2732
|
+
client.isAuthenticated().then((isAuthenticated) => {
|
|
2733
|
+
if (isAuthenticated) {
|
|
2734
|
+
setShowChildren(true);
|
|
2735
|
+
cms.enable();
|
|
2736
|
+
} else {
|
|
2737
|
+
sleep(500).then(() => {
|
|
2738
|
+
setActiveModal("authenticate");
|
|
2739
|
+
});
|
|
1632
2740
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
2741
|
+
});
|
|
2742
|
+
}, []);
|
|
2743
|
+
const onAuthSuccess = async () => {
|
|
2744
|
+
if (await client.isAuthenticated()) {
|
|
2745
|
+
setShowChildren(true);
|
|
2746
|
+
setActiveModal(null);
|
|
1638
2747
|
} else {
|
|
1639
|
-
|
|
1640
|
-
return [];
|
|
1641
|
-
}
|
|
1642
|
-
throw e;
|
|
2748
|
+
throw new Error("No access to repo");
|
|
1643
2749
|
}
|
|
1644
|
-
}
|
|
2750
|
+
};
|
|
2751
|
+
const otherModalActions = getModalActions ? getModalActions({
|
|
2752
|
+
closeModal: () => {
|
|
2753
|
+
setActiveModal(null);
|
|
2754
|
+
}
|
|
2755
|
+
}) : [];
|
|
2756
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, activeModal === "authenticate" && /* @__PURE__ */ React.createElement(ModalBuilder, {
|
|
2757
|
+
title: "Tina Cloud Authorization",
|
|
2758
|
+
message: "To save edits, Tina Cloud authorization is required. On save, changes will get commited using your account.",
|
|
2759
|
+
close,
|
|
2760
|
+
actions: [
|
|
2761
|
+
...otherModalActions,
|
|
2762
|
+
{
|
|
2763
|
+
action: async () => {
|
|
2764
|
+
setEditing(false);
|
|
2765
|
+
window.location.reload();
|
|
2766
|
+
},
|
|
2767
|
+
name: "Close",
|
|
2768
|
+
primary: false
|
|
2769
|
+
},
|
|
2770
|
+
{
|
|
2771
|
+
name: "Continue to Tina Cloud",
|
|
2772
|
+
action: async () => {
|
|
2773
|
+
await client.authenticate();
|
|
2774
|
+
onAuthSuccess();
|
|
2775
|
+
},
|
|
2776
|
+
primary: true
|
|
2777
|
+
}
|
|
2778
|
+
]
|
|
2779
|
+
}), showChildren ? children : loginScreen ? loginScreen : null);
|
|
1645
2780
|
};
|
|
1646
|
-
const
|
|
1647
|
-
const
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
2781
|
+
const TinaCloudProvider = (props) => {
|
|
2782
|
+
const baseBranch = props.branch || "main";
|
|
2783
|
+
const [currentBranch, setCurrentBranch] = useLocalStorage("tinacms-current-branch", baseBranch);
|
|
2784
|
+
useTinaAuthRedirect();
|
|
2785
|
+
const cms = React.useMemo(() => props.cms || new TinaCMS({
|
|
2786
|
+
enabled: true,
|
|
2787
|
+
sidebar: true
|
|
2788
|
+
}), [props.cms]);
|
|
2789
|
+
if (!cms.api.tina) {
|
|
2790
|
+
cms.registerApi("tina", createClient(props));
|
|
2791
|
+
}
|
|
2792
|
+
if (!cms.api.admin) {
|
|
2793
|
+
cms.registerApi("admin", new TinaAdminApi(cms));
|
|
2794
|
+
}
|
|
2795
|
+
const setupMedia = async () => {
|
|
2796
|
+
var _a;
|
|
2797
|
+
if (props.mediaStore) {
|
|
2798
|
+
if ((_a = props.mediaStore.prototype) == null ? void 0 : _a.persist) {
|
|
2799
|
+
cms.media.store = new props.mediaStore(cms.api.tina);
|
|
2800
|
+
} else {
|
|
2801
|
+
const MediaClass = await props.mediaStore();
|
|
2802
|
+
cms.media.store = new MediaClass(cms.api.tina);
|
|
1655
2803
|
}
|
|
1656
|
-
} else {
|
|
1657
|
-
const template = currentFields.templates ? currentFields.templates[value._template] : currentFields;
|
|
1658
|
-
currentFields = template.fields;
|
|
1659
2804
|
}
|
|
1660
|
-
});
|
|
1661
|
-
return currentFields;
|
|
1662
|
-
};
|
|
1663
|
-
const generateFormCreators = (cms) => {
|
|
1664
|
-
const createForm = (formConfig) => {
|
|
1665
|
-
const form = new Form(formConfig);
|
|
1666
|
-
cms.forms.add(form);
|
|
1667
|
-
return form;
|
|
1668
2805
|
};
|
|
1669
|
-
const
|
|
1670
|
-
const
|
|
1671
|
-
cms.
|
|
1672
|
-
|
|
2806
|
+
const handleListBranches = async () => {
|
|
2807
|
+
const { owner, repo } = props;
|
|
2808
|
+
const branches = await cms.api.tina.listBranches({ owner, repo });
|
|
2809
|
+
if (!Array.isArray(branches)) {
|
|
2810
|
+
return [];
|
|
2811
|
+
}
|
|
2812
|
+
return branches;
|
|
1673
2813
|
};
|
|
1674
|
-
|
|
2814
|
+
const handleCreateBranch = async (data) => {
|
|
2815
|
+
const newBranch = await cms.api.tina.createBranch(data);
|
|
2816
|
+
return newBranch;
|
|
2817
|
+
};
|
|
2818
|
+
setupMedia();
|
|
2819
|
+
const [branchingEnabled, setBranchingEnabled] = React.useState(() => cms.flags.get("branch-switcher"));
|
|
2820
|
+
React.useEffect(() => {
|
|
2821
|
+
cms.events.subscribe("flag:set", ({ key, value }) => {
|
|
2822
|
+
if (key === "branch-switcher") {
|
|
2823
|
+
setBranchingEnabled(value);
|
|
2824
|
+
}
|
|
2825
|
+
});
|
|
2826
|
+
}, [cms.events]);
|
|
2827
|
+
React.useEffect(() => {
|
|
2828
|
+
let branchSwitcher;
|
|
2829
|
+
if (branchingEnabled) {
|
|
2830
|
+
branchSwitcher = new BranchSwitcherPlugin({
|
|
2831
|
+
listBranches: handleListBranches,
|
|
2832
|
+
createBranch: handleCreateBranch
|
|
2833
|
+
});
|
|
2834
|
+
cms.plugins.add(branchSwitcher);
|
|
2835
|
+
}
|
|
2836
|
+
return () => {
|
|
2837
|
+
if (branchingEnabled && branchSwitcher) {
|
|
2838
|
+
cms.plugins.remove(branchSwitcher);
|
|
2839
|
+
}
|
|
2840
|
+
};
|
|
2841
|
+
}, [branchingEnabled, props.branch]);
|
|
2842
|
+
React.useEffect(() => {
|
|
2843
|
+
if (props.cmsCallback) {
|
|
2844
|
+
props.cmsCallback(cms);
|
|
2845
|
+
}
|
|
2846
|
+
}, []);
|
|
2847
|
+
return /* @__PURE__ */ React.createElement(BranchDataProvider, {
|
|
2848
|
+
currentBranch,
|
|
2849
|
+
setCurrentBranch: (b) => {
|
|
2850
|
+
setCurrentBranch(b);
|
|
2851
|
+
}
|
|
2852
|
+
}, /* @__PURE__ */ React.createElement(TinaProvider, {
|
|
2853
|
+
cms
|
|
2854
|
+
}, /* @__PURE__ */ React.createElement(AuthWallInner, __spreadProps(__spreadValues({}, props), {
|
|
2855
|
+
cms
|
|
2856
|
+
}))));
|
|
1675
2857
|
};
|
|
2858
|
+
const TinaCloudAuthWall = TinaCloudProvider;
|
|
1676
2859
|
class ContentCreatorPlugin {
|
|
1677
2860
|
constructor(options) {
|
|
1678
2861
|
this.__type = "content-creator";
|
|
@@ -2016,13 +3199,25 @@ const TinaDataProvider = ({
|
|
|
2016
3199
|
payload: void 0,
|
|
2017
3200
|
isLoading: true
|
|
2018
3201
|
});
|
|
3202
|
+
const cms = useCMS();
|
|
3203
|
+
const useUnstableFormify = React.useMemo(() => {
|
|
3204
|
+
if (cms == null ? void 0 : cms.flags.get("use-unstable-formify")) {
|
|
3205
|
+
return true;
|
|
3206
|
+
}
|
|
3207
|
+
return false;
|
|
3208
|
+
}, [cms == null ? void 0 : cms.flags]);
|
|
2019
3209
|
return /* @__PURE__ */ React.createElement(TinaDataContext.Provider, {
|
|
2020
3210
|
value: {
|
|
2021
3211
|
setRequest,
|
|
2022
3212
|
isLoading: state.isLoading,
|
|
2023
3213
|
state: { payload: state.payload }
|
|
2024
3214
|
}
|
|
2025
|
-
}, /* @__PURE__ */ React.createElement(
|
|
3215
|
+
}, useUnstableFormify ? /* @__PURE__ */ React.createElement(FormRegistrarUnstable, {
|
|
3216
|
+
key: request == null ? void 0 : request.query,
|
|
3217
|
+
request,
|
|
3218
|
+
formifyCallback,
|
|
3219
|
+
onPayloadStateChange: setState
|
|
3220
|
+
}) : /* @__PURE__ */ React.createElement(FormRegistrar, {
|
|
2026
3221
|
key: request == null ? void 0 : request.query,
|
|
2027
3222
|
request,
|
|
2028
3223
|
formifyCallback,
|
|
@@ -2051,6 +3246,35 @@ const FormRegistrar = ({
|
|
|
2051
3246
|
}, [JSON.stringify(payload), isLoading]);
|
|
2052
3247
|
return isLoading ? /* @__PURE__ */ React.createElement(Loader, null, /* @__PURE__ */ React.createElement(React.Fragment, null)) : null;
|
|
2053
3248
|
};
|
|
3249
|
+
const FormRegistrarUnstable = (props) => {
|
|
3250
|
+
var _a;
|
|
3251
|
+
if (!((_a = props.request) == null ? void 0 : _a.query)) {
|
|
3252
|
+
return null;
|
|
3253
|
+
}
|
|
3254
|
+
return /* @__PURE__ */ React.createElement(FormRegistrarUnstableInner, __spreadValues({}, props));
|
|
3255
|
+
};
|
|
3256
|
+
const FormRegistrarUnstableInner = ({
|
|
3257
|
+
request,
|
|
3258
|
+
formifyCallback,
|
|
3259
|
+
onPayloadStateChange
|
|
3260
|
+
}) => {
|
|
3261
|
+
const cms = useCMS();
|
|
3262
|
+
const [payload, isLoading] = useGraphqlFormsUnstable({
|
|
3263
|
+
query: request == null ? void 0 : request.query,
|
|
3264
|
+
variables: request == null ? void 0 : request.variables,
|
|
3265
|
+
formify: (args) => {
|
|
3266
|
+
if (formifyCallback) {
|
|
3267
|
+
return formifyCallback(args, cms);
|
|
3268
|
+
} else {
|
|
3269
|
+
return args.createForm(args.formConfig);
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
});
|
|
3273
|
+
React.useEffect(() => {
|
|
3274
|
+
onPayloadStateChange({ payload, isLoading });
|
|
3275
|
+
}, [JSON.stringify(payload), isLoading]);
|
|
3276
|
+
return isLoading ? /* @__PURE__ */ React.createElement(Loader, null, /* @__PURE__ */ React.createElement(React.Fragment, null)) : null;
|
|
3277
|
+
};
|
|
2054
3278
|
const Loader = (props) => {
|
|
2055
3279
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
|
|
2056
3280
|
style: {
|
|
@@ -2293,16 +3517,18 @@ const useGetCollections = (cms) => {
|
|
|
2293
3517
|
const [error, setError] = useState(void 0);
|
|
2294
3518
|
useEffect(() => {
|
|
2295
3519
|
const fetchCollections = async () => {
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
3520
|
+
if (await api.isAuthenticated()) {
|
|
3521
|
+
try {
|
|
3522
|
+
const response = await api.fetchCollections();
|
|
3523
|
+
setCollections(response.getCollections);
|
|
3524
|
+
} catch (error2) {
|
|
3525
|
+
cms.alerts.error(`[${error2.name}] GetCollections failed: ${error2.message}`, 30 * 1e3);
|
|
3526
|
+
console.error(error2);
|
|
3527
|
+
setCollections([]);
|
|
3528
|
+
setError(error2);
|
|
3529
|
+
}
|
|
3530
|
+
setLoading(false);
|
|
2304
3531
|
}
|
|
2305
|
-
setLoading(false);
|
|
2306
3532
|
};
|
|
2307
3533
|
setLoading(true);
|
|
2308
3534
|
fetchCollections();
|
|
@@ -2591,16 +3817,18 @@ const useGetCollection = (cms, collectionName, includeDocuments = true) => {
|
|
|
2591
3817
|
const [error, setError] = useState(void 0);
|
|
2592
3818
|
useEffect(() => {
|
|
2593
3819
|
const fetchCollection = async () => {
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
3820
|
+
if (await api.isAuthenticated()) {
|
|
3821
|
+
try {
|
|
3822
|
+
const response = await api.fetchCollection(collectionName, includeDocuments);
|
|
3823
|
+
setCollection(response.getCollection);
|
|
3824
|
+
} catch (error2) {
|
|
3825
|
+
cms.alerts.error(`[${error2.name}] GetCollection failed: ${error2.message}`, 30 * 1e3);
|
|
3826
|
+
console.error(error2);
|
|
3827
|
+
setCollection(void 0);
|
|
3828
|
+
setError(error2);
|
|
3829
|
+
}
|
|
3830
|
+
setLoading(false);
|
|
2602
3831
|
}
|
|
2603
|
-
setLoading(false);
|
|
2604
3832
|
};
|
|
2605
3833
|
setLoading(true);
|
|
2606
3834
|
fetchCollection();
|
|
@@ -2614,13 +3842,11 @@ const GetCollection = ({
|
|
|
2614
3842
|
children
|
|
2615
3843
|
}) => {
|
|
2616
3844
|
const { collection, loading, error } = useGetCollection(cms, collectionName, includeDocuments);
|
|
2617
|
-
if (
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
return null;
|
|
2623
|
-
}
|
|
3845
|
+
if (error) {
|
|
3846
|
+
return null;
|
|
3847
|
+
}
|
|
3848
|
+
if (loading) {
|
|
3849
|
+
return /* @__PURE__ */ React.createElement(LoadingPage, null);
|
|
2624
3850
|
}
|
|
2625
3851
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children(collection, loading));
|
|
2626
3852
|
};
|
|
@@ -2740,37 +3966,39 @@ const useGetDocumentFields = (cms, collectionName, templateName) => {
|
|
|
2740
3966
|
const [error, setError] = useState(void 0);
|
|
2741
3967
|
useEffect(() => {
|
|
2742
3968
|
const fetchDocumentFields = async () => {
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
3969
|
+
if (await api.isAuthenticated()) {
|
|
3970
|
+
try {
|
|
3971
|
+
const response = await api.fetchDocumentFields();
|
|
3972
|
+
const documentFields = response.getDocumentFields;
|
|
3973
|
+
const collection = documentFields[collectionName].collection;
|
|
3974
|
+
const mutationInfo = documentFields[collectionName].mutationInfo;
|
|
3975
|
+
let fields = void 0;
|
|
3976
|
+
let template = void 0;
|
|
3977
|
+
if (templateName && documentFields[collectionName].templates && documentFields[collectionName].templates[templateName]) {
|
|
3978
|
+
template = documentFields[collectionName].templates[templateName].template;
|
|
3979
|
+
fields = documentFields[collectionName].templates[templateName].fields;
|
|
3980
|
+
} else {
|
|
3981
|
+
fields = documentFields[collectionName].fields;
|
|
3982
|
+
}
|
|
3983
|
+
setInfo({
|
|
3984
|
+
collection,
|
|
3985
|
+
template,
|
|
3986
|
+
fields,
|
|
3987
|
+
mutationInfo
|
|
3988
|
+
});
|
|
3989
|
+
} catch (error2) {
|
|
3990
|
+
cms.alerts.error(`[${error2.name}] GetDocumentFields failed: ${error2.message}`, 30 * 1e3);
|
|
3991
|
+
console.error(error2);
|
|
3992
|
+
setInfo({
|
|
3993
|
+
collection: void 0,
|
|
3994
|
+
template: void 0,
|
|
3995
|
+
fields: void 0,
|
|
3996
|
+
mutationInfo: void 0
|
|
3997
|
+
});
|
|
3998
|
+
setError(error2);
|
|
2755
3999
|
}
|
|
2756
|
-
|
|
2757
|
-
collection,
|
|
2758
|
-
template,
|
|
2759
|
-
fields,
|
|
2760
|
-
mutationInfo
|
|
2761
|
-
});
|
|
2762
|
-
} catch (error2) {
|
|
2763
|
-
cms.alerts.error(`[${error2.name}] GetDocumentFields failed: ${error2.message}`, 30 * 1e3);
|
|
2764
|
-
console.error(error2);
|
|
2765
|
-
setInfo({
|
|
2766
|
-
collection: void 0,
|
|
2767
|
-
template: void 0,
|
|
2768
|
-
fields: void 0,
|
|
2769
|
-
mutationInfo: void 0
|
|
2770
|
-
});
|
|
2771
|
-
setError(error2);
|
|
4000
|
+
setLoading(false);
|
|
2772
4001
|
}
|
|
2773
|
-
setLoading(false);
|
|
2774
4002
|
};
|
|
2775
4003
|
setLoading(true);
|
|
2776
4004
|
fetchDocumentFields();
|
|
@@ -2784,13 +4012,11 @@ const GetDocumentFields = ({
|
|
|
2784
4012
|
children
|
|
2785
4013
|
}) => {
|
|
2786
4014
|
const { collection, template, fields, mutationInfo, loading, error } = useGetDocumentFields(cms, collectionName, templateName);
|
|
2787
|
-
if (
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
return null;
|
|
2793
|
-
}
|
|
4015
|
+
if (error) {
|
|
4016
|
+
return null;
|
|
4017
|
+
}
|
|
4018
|
+
if (loading) {
|
|
4019
|
+
return /* @__PURE__ */ React.createElement(LoadingPage, null);
|
|
2794
4020
|
}
|
|
2795
4021
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children({ collection, template, fields, mutationInfo, loading }));
|
|
2796
4022
|
};
|
|
@@ -2805,7 +4031,14 @@ const createDocument = async (cms, collection, template, mutationInfo, values) =
|
|
|
2805
4031
|
includeCollection,
|
|
2806
4032
|
includeTemplate
|
|
2807
4033
|
});
|
|
2808
|
-
await api.
|
|
4034
|
+
if (await api.isAuthenticated()) {
|
|
4035
|
+
await api.createDocument(collection.name, relativePath, params);
|
|
4036
|
+
} else {
|
|
4037
|
+
const authMessage = `[Error] CreateDocument failed: User is no longer authenticated; please login and try again.`;
|
|
4038
|
+
cms.alerts.error(authMessage, 30 * 1e3);
|
|
4039
|
+
console.error(authMessage);
|
|
4040
|
+
return false;
|
|
4041
|
+
}
|
|
2809
4042
|
};
|
|
2810
4043
|
const CollectionCreatePage = () => {
|
|
2811
4044
|
const { collectionName, templateName } = useParams();
|
|
@@ -2843,9 +4076,9 @@ const RenderForm$1 = ({ cms, collection, template, fields, mutationInfo }) => {
|
|
|
2843
4076
|
}
|
|
2844
4077
|
return true;
|
|
2845
4078
|
}
|
|
2846
|
-
const isValid = /^[_a-zA-Z][
|
|
4079
|
+
const isValid = /^[_a-zA-Z][.,-,_a-zA-Z0-9]*$/.test(value);
|
|
2847
4080
|
if (value && !isValid) {
|
|
2848
|
-
return "Must begin with a-z, A-Z, or _ and contain only a-z, A-Z, 0-9,
|
|
4081
|
+
return "Must begin with a-z, A-Z, or _ and contain only a-z, A-Z, 0-9, -, ., or _";
|
|
2849
4082
|
}
|
|
2850
4083
|
}
|
|
2851
4084
|
},
|
|
@@ -2854,6 +4087,7 @@ const RenderForm$1 = ({ cms, collection, template, fields, mutationInfo }) => {
|
|
|
2854
4087
|
onSubmit: async (values) => {
|
|
2855
4088
|
try {
|
|
2856
4089
|
await createDocument(cms, collection, template, mutationInfo, values);
|
|
4090
|
+
cms.alerts.success("Document created!");
|
|
2857
4091
|
navigate(`/collections/${collection.name}`);
|
|
2858
4092
|
} catch (error) {
|
|
2859
4093
|
cms.alerts.error(`[${error.name}] CreateDocument failed: ${error.message}`, 30 * 1e3);
|
|
@@ -2891,16 +4125,18 @@ const useGetDocument = (cms, collectionName, relativePath) => {
|
|
|
2891
4125
|
const [error, setError] = useState(void 0);
|
|
2892
4126
|
useEffect(() => {
|
|
2893
4127
|
const fetchDocument = async () => {
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
4128
|
+
if (api.isAuthenticated()) {
|
|
4129
|
+
try {
|
|
4130
|
+
const response = await api.fetchDocument(collectionName, relativePath);
|
|
4131
|
+
setDocument(response.getDocument);
|
|
4132
|
+
} catch (error2) {
|
|
4133
|
+
cms.alerts.error(`[${error2.name}] GetDocument failed: ${error2.message}`, 30 * 1e3);
|
|
4134
|
+
console.error(error2);
|
|
4135
|
+
setDocument(void 0);
|
|
4136
|
+
setError(error2);
|
|
4137
|
+
}
|
|
4138
|
+
setLoading(false);
|
|
2902
4139
|
}
|
|
2903
|
-
setLoading(false);
|
|
2904
4140
|
};
|
|
2905
4141
|
setLoading(true);
|
|
2906
4142
|
fetchDocument();
|
|
@@ -2914,13 +4150,11 @@ const GetDocument = ({
|
|
|
2914
4150
|
children
|
|
2915
4151
|
}) => {
|
|
2916
4152
|
const { document, loading, error } = useGetDocument(cms, collectionName, relativePath);
|
|
2917
|
-
if (
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
return null;
|
|
2923
|
-
}
|
|
4153
|
+
if (error) {
|
|
4154
|
+
return null;
|
|
4155
|
+
}
|
|
4156
|
+
if (loading) {
|
|
4157
|
+
return /* @__PURE__ */ React.createElement(LoadingPage, null);
|
|
2924
4158
|
}
|
|
2925
4159
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children(document, loading));
|
|
2926
4160
|
};
|
|
@@ -2931,7 +4165,14 @@ const updateDocument = async (cms, relativePath, collection, mutationInfo, value
|
|
|
2931
4165
|
includeCollection,
|
|
2932
4166
|
includeTemplate
|
|
2933
4167
|
});
|
|
2934
|
-
await api.
|
|
4168
|
+
if (await api.isAuthenticated()) {
|
|
4169
|
+
await api.updateDocument(collection.name, relativePath, params);
|
|
4170
|
+
} else {
|
|
4171
|
+
const authMessage = `[Error] UpdateDocument failed: User is no longer authenticated; please login and try again.`;
|
|
4172
|
+
cms.alerts.error(authMessage, 30 * 1e3);
|
|
4173
|
+
console.error(authMessage);
|
|
4174
|
+
return false;
|
|
4175
|
+
}
|
|
2935
4176
|
};
|
|
2936
4177
|
const CollectionUpdatePage = () => {
|
|
2937
4178
|
const { collectionName, filename } = useParams();
|
|
@@ -2963,7 +4204,7 @@ const RenderForm = ({
|
|
|
2963
4204
|
mutationInfo
|
|
2964
4205
|
}) => {
|
|
2965
4206
|
var _a, _b;
|
|
2966
|
-
|
|
4207
|
+
useNavigate();
|
|
2967
4208
|
const [formIsPristine, setFormIsPristine] = useState(true);
|
|
2968
4209
|
const form = useMemo(() => {
|
|
2969
4210
|
return new Form({
|
|
@@ -2974,7 +4215,7 @@ const RenderForm = ({
|
|
|
2974
4215
|
onSubmit: async (values) => {
|
|
2975
4216
|
try {
|
|
2976
4217
|
await updateDocument(cms, relativePath, collection, mutationInfo, values);
|
|
2977
|
-
|
|
4218
|
+
cms.alerts.success("Document updated!");
|
|
2978
4219
|
} catch (error) {
|
|
2979
4220
|
cms.alerts.error(`[${error.name}] UpdateDocument failed: ${error.message}`, 30 * 1e3);
|
|
2980
4221
|
console.error(error);
|
|
@@ -3089,4 +4330,4 @@ const defineSchema = (config) => {
|
|
|
3089
4330
|
const defineConfig = (config) => {
|
|
3090
4331
|
return config;
|
|
3091
4332
|
};
|
|
3092
|
-
export { AuthWallInner, Client, DEFAULT_LOCAL_TINA_GQL_SERVER_URL, LocalClient, RouteMappingPlugin, TinaAdmin, TinaAdminApi, TinaCMSProvider2, TinaCloudAuthWall, TinaCloudProvider, TinaDataProvider, assertShape, createClient, TinaCMSProvider2 as default, defineConfig, defineSchema, getStaticPropsForTina, gql, safeAssertShape, staticRequest, useDocumentCreatorPlugin, useGraphqlForms, useTinaAuthRedirect };
|
|
4333
|
+
export { AuthWallInner, Client, DEFAULT_LOCAL_TINA_GQL_SERVER_URL, LocalClient, RouteMappingPlugin, TinaAdmin, TinaAdminApi, TinaCMSProvider2, TinaCloudAuthWall, TinaCloudProvider, TinaDataProvider, assertShape, createClient, TinaCMSProvider2 as default, defineConfig, defineSchema, getStaticPropsForTina, gql, safeAssertShape, staticRequest, useDocumentCreatorPlugin, useGraphqlForms, useGraphqlFormsUnstable, useTinaAuthRedirect };
|