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