@tinacms/vercel-previews 0.0.0-b67f55a-20250513032422 → 0.0.0-b749957-20251208035121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +127 -143
- package/package.json +4 -11
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -151
- package/dist/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,153 +1,137 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}, []);
|
|
18
|
-
return { edit };
|
|
19
|
-
}
|
|
20
|
-
const tinaField = (object, property, index) => {
|
|
21
|
-
var _a, _b, _c;
|
|
22
|
-
if (!object) {
|
|
23
|
-
return "";
|
|
24
|
-
}
|
|
25
|
-
if (object._content_source) {
|
|
26
|
-
if (!property) {
|
|
27
|
-
return [
|
|
28
|
-
(_a = object._content_source) == null ? void 0 : _a.queryId,
|
|
29
|
-
object._content_source.path.join(".")
|
|
30
|
-
].join("---");
|
|
31
|
-
}
|
|
32
|
-
if (typeof index === "number") {
|
|
33
|
-
return [
|
|
34
|
-
(_b = object._content_source) == null ? void 0 : _b.queryId,
|
|
35
|
-
[...object._content_source.path, property, index].join(".")
|
|
36
|
-
].join("---");
|
|
37
|
-
}
|
|
38
|
-
return [
|
|
39
|
-
(_c = object._content_source) == null ? void 0 : _c.queryId,
|
|
40
|
-
[...object._content_source.path, property].join(".")
|
|
41
|
-
].join("---");
|
|
1
|
+
import { vercelStegaCombine } from "@vercel/stega";
|
|
2
|
+
import React, { useCallback, useEffect } from "react";
|
|
3
|
+
function useEditState() {
|
|
4
|
+
const [edit, setEdit] = React.useState(false);
|
|
5
|
+
React.useEffect(() => {
|
|
6
|
+
if (typeof window !== "undefined") {
|
|
7
|
+
parent.postMessage({ type: "isEditMode" }, window.location.origin);
|
|
8
|
+
window.addEventListener("message", (event) => {
|
|
9
|
+
var _a;
|
|
10
|
+
if (((_a = event.data) == null ? void 0 : _a.type) === "tina:editMode") {
|
|
11
|
+
setEdit(true);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
42
14
|
}
|
|
15
|
+
}, []);
|
|
16
|
+
return { edit };
|
|
17
|
+
}
|
|
18
|
+
const tinaField = (object, property, index) => {
|
|
19
|
+
const contentSource = object == null ? void 0 : object._content_source;
|
|
20
|
+
if (!contentSource) {
|
|
43
21
|
return "";
|
|
44
|
-
}
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
const
|
|
50
|
-
|
|
22
|
+
}
|
|
23
|
+
const { queryId, path } = contentSource;
|
|
24
|
+
if (!property) {
|
|
25
|
+
return `${queryId}---${path.join(".")}`;
|
|
26
|
+
}
|
|
27
|
+
const fullPath = typeof index === "number" ? [...path, property, index] : [...path, property];
|
|
28
|
+
return `${queryId}---${fullPath.join(".")}`;
|
|
29
|
+
};
|
|
30
|
+
const vercelEditInfo = (obj, field, index) => {
|
|
31
|
+
const fieldName = tinaField(obj, field, index);
|
|
32
|
+
return JSON.stringify({ origin: "tinacms", data: { fieldName } });
|
|
33
|
+
};
|
|
34
|
+
const useVisualEditing = ({
|
|
35
|
+
data,
|
|
36
|
+
query,
|
|
37
|
+
variables,
|
|
38
|
+
enabled,
|
|
39
|
+
redirect,
|
|
40
|
+
stringEncoding
|
|
41
|
+
}) => {
|
|
42
|
+
const stringifiedQuery = JSON.stringify({
|
|
51
43
|
query,
|
|
52
|
-
variables
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
()
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const handleOpenEvent = React.useCallback(
|
|
67
|
-
(event) => {
|
|
68
|
-
var _a, _b;
|
|
69
|
-
if (edit) {
|
|
70
|
-
parent.postMessage(
|
|
71
|
-
{ type: "field:selected", fieldName: (_b = (_a = event.detail) == null ? void 0 : _a.data) == null ? void 0 : _b.fieldName },
|
|
72
|
-
window.location.origin
|
|
73
|
-
);
|
|
74
|
-
} else {
|
|
75
|
-
const tinaAdminBasePath = redirect.startsWith("/") ? redirect : `/${redirect}`;
|
|
76
|
-
const tinaAdminPath = `${tinaAdminBasePath}/index.html#/~${window.location.pathname}?active-field=${event.detail.data.fieldName}`;
|
|
77
|
-
window.location.assign(tinaAdminPath);
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
[edit]
|
|
81
|
-
);
|
|
82
|
-
React.useEffect(() => {
|
|
83
|
-
window.addEventListener("edit:open", handleOpenEvent);
|
|
84
|
-
return () => {
|
|
85
|
-
window.removeEventListener("edit:open", handleOpenEvent);
|
|
86
|
-
};
|
|
87
|
-
}, [redirect, edit]);
|
|
88
|
-
function appendMetadata(obj, path = [], id2) {
|
|
89
|
-
if (typeof obj !== "object" || obj === null) {
|
|
90
|
-
if (typeof obj === "string" && stringEncoding) {
|
|
91
|
-
if (typeof stringEncoding === "boolean") {
|
|
92
|
-
if (stringEncoding) {
|
|
93
|
-
return encodeEditInfo(path, obj, id2);
|
|
94
|
-
}
|
|
95
|
-
} else if (stringEncoding.skipPaths) {
|
|
96
|
-
if (!stringEncoding.skipPaths(path.join("."), obj)) {
|
|
97
|
-
return encodeEditInfo(path, obj, id2);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return obj;
|
|
102
|
-
}
|
|
103
|
-
if (Array.isArray(obj)) {
|
|
104
|
-
return obj.map(
|
|
105
|
-
(item, index) => appendMetadata(item, [...path, index], id2)
|
|
44
|
+
variables
|
|
45
|
+
});
|
|
46
|
+
const id = React.useMemo(
|
|
47
|
+
() => hashFromQuery(stringifiedQuery),
|
|
48
|
+
[stringifiedQuery]
|
|
49
|
+
);
|
|
50
|
+
const { edit } = useEditState();
|
|
51
|
+
const handleOpenEvent = useCallback(
|
|
52
|
+
(event) => {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
if (edit) {
|
|
55
|
+
parent.postMessage(
|
|
56
|
+
{ type: "field:selected", fieldName: (_b = (_a = event.detail) == null ? void 0 : _a.data) == null ? void 0 : _b.fieldName },
|
|
57
|
+
window.location.origin
|
|
106
58
|
);
|
|
59
|
+
} else {
|
|
60
|
+
const tinaAdminBasePath = redirect.startsWith("/") ? redirect : `/${redirect}`;
|
|
61
|
+
const tinaAdminPath = `${tinaAdminBasePath}/index.html#/~${window.location.pathname}?active-field=${event.detail.data.fieldName}`;
|
|
62
|
+
window.location.assign(tinaAdminPath);
|
|
107
63
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
64
|
+
},
|
|
65
|
+
[edit]
|
|
66
|
+
);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
window.addEventListener("edit:open", handleOpenEvent);
|
|
69
|
+
return () => {
|
|
70
|
+
window.removeEventListener("edit:open", handleOpenEvent);
|
|
71
|
+
};
|
|
72
|
+
}, [redirect, edit]);
|
|
73
|
+
function appendMetadata(obj, path = [], id2) {
|
|
74
|
+
if (typeof obj !== "object" || obj === null) {
|
|
75
|
+
if (typeof obj === "string" && stringEncoding) {
|
|
76
|
+
if (typeof stringEncoding === "boolean") {
|
|
77
|
+
if (stringEncoding) {
|
|
78
|
+
return encodeEditInfo(path, obj, id2);
|
|
79
|
+
}
|
|
80
|
+
} else if (stringEncoding.skipPaths) {
|
|
81
|
+
if (!stringEncoding.skipPaths(path.join("."), obj)) {
|
|
82
|
+
return encodeEditInfo(path, obj, id2);
|
|
83
|
+
}
|
|
123
84
|
}
|
|
124
85
|
}
|
|
125
|
-
return
|
|
86
|
+
return obj;
|
|
126
87
|
}
|
|
127
|
-
if (
|
|
128
|
-
return
|
|
88
|
+
if (Array.isArray(obj)) {
|
|
89
|
+
return obj.map(
|
|
90
|
+
(item, index) => appendMetadata(item, [...path, index], id2)
|
|
91
|
+
);
|
|
129
92
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
93
|
+
const transformedObj = {};
|
|
94
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
95
|
+
const currentPath = [...path, key];
|
|
96
|
+
if ([
|
|
97
|
+
"__typename",
|
|
98
|
+
"_sys",
|
|
99
|
+
"_internalSys",
|
|
100
|
+
"_values",
|
|
101
|
+
"_internalValues",
|
|
102
|
+
"_content_source",
|
|
103
|
+
"_tina_metadata"
|
|
104
|
+
].includes(key)) {
|
|
105
|
+
transformedObj[key] = value;
|
|
106
|
+
} else {
|
|
107
|
+
transformedObj[key] = appendMetadata(value, currentPath, id2);
|
|
108
|
+
}
|
|
143
109
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
110
|
+
return { ...transformedObj, _content_source: { queryId: id2, path } };
|
|
111
|
+
}
|
|
112
|
+
if (enabled) {
|
|
113
|
+
return appendMetadata(data, [], id);
|
|
114
|
+
}
|
|
115
|
+
return data;
|
|
116
|
+
};
|
|
117
|
+
function encodeEditInfo(path, value, id) {
|
|
118
|
+
return vercelStegaCombine(value, {
|
|
119
|
+
origin: "tina.io",
|
|
120
|
+
data: { fieldName: `${id}---${path.join(".")}` }
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const hashFromQuery = (input) => {
|
|
124
|
+
let hash = 0;
|
|
125
|
+
for (let i = 0; i < input.length; i++) {
|
|
126
|
+
const char = input.charCodeAt(i);
|
|
127
|
+
hash = (hash << 5) - hash + char & 4294967295;
|
|
128
|
+
}
|
|
129
|
+
const nonNegativeHash = Math.abs(hash);
|
|
130
|
+
const alphanumericHash = nonNegativeHash.toString(36);
|
|
131
|
+
return alphanumericHash;
|
|
132
|
+
};
|
|
133
|
+
export {
|
|
134
|
+
hashFromQuery,
|
|
135
|
+
useVisualEditing,
|
|
136
|
+
vercelEditInfo
|
|
137
|
+
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/vercel-previews",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.0-b749957-20251208035121",
|
|
4
5
|
"main": "dist/index.js",
|
|
5
6
|
"types": "dist/index.d.ts",
|
|
6
|
-
"module": "./dist/index.mjs",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"tinacms",
|
|
9
9
|
"cms",
|
|
@@ -12,13 +12,6 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
|
-
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
"types": "./dist/index.d.ts",
|
|
18
|
-
"import": "./dist/index.mjs",
|
|
19
|
-
"require": "./dist/index.js"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
15
|
"buildConfig": {
|
|
23
16
|
"entryPoints": [
|
|
24
17
|
"src/index.ts"
|
|
@@ -37,11 +30,11 @@
|
|
|
37
30
|
"@types/react": "^18.3.18",
|
|
38
31
|
"react": "^18.3.1",
|
|
39
32
|
"typescript": "^5.7.3",
|
|
40
|
-
"@tinacms/scripts": "
|
|
33
|
+
"@tinacms/scripts": "0.0.0-b749957-20251208035121"
|
|
41
34
|
},
|
|
42
35
|
"dependencies": {
|
|
43
36
|
"@vercel/stega": "^0.0.5",
|
|
44
|
-
"tinacms": "0.0.0-
|
|
37
|
+
"tinacms": "0.0.0-b749957-20251208035121"
|
|
45
38
|
},
|
|
46
39
|
"peerDependencies": {
|
|
47
40
|
"react": ">=16.14"
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../tinacms/dist/react.mjs","../src/index.ts"],"sourcesContent":["import React from \"react\";\nfunction useTina(props) {\n const stringifiedQuery = JSON.stringify({\n query: props.query,\n variables: props.variables\n });\n const id = React.useMemo(\n () => hashFromQuery(stringifiedQuery),\n [stringifiedQuery]\n );\n const [data, setData] = React.useState(props.data);\n const [isClient, setIsClient] = React.useState(false);\n const [quickEditEnabled, setQuickEditEnabled] = React.useState(false);\n const [isInTinaIframe, setIsInTinaIframe] = React.useState(false);\n React.useEffect(() => {\n setIsClient(true);\n setData(props.data);\n parent.postMessage({\n type: \"url-changed\"\n });\n }, [id]);\n React.useEffect(() => {\n if (quickEditEnabled) {\n let mouseDownHandler = function(e) {\n const attributeNames = e.target.getAttributeNames();\n const tinaAttribute = attributeNames.find(\n (name) => name.startsWith(\"data-tina-field\")\n );\n let fieldName;\n if (tinaAttribute) {\n e.preventDefault();\n e.stopPropagation();\n fieldName = e.target.getAttribute(tinaAttribute);\n } else {\n const ancestor = e.target.closest(\n \"[data-tina-field], [data-tina-field-overlay]\"\n );\n if (ancestor) {\n const attributeNames2 = ancestor.getAttributeNames();\n const tinaAttribute2 = attributeNames2.find(\n (name) => name.startsWith(\"data-tina-field\")\n );\n if (tinaAttribute2) {\n e.preventDefault();\n e.stopPropagation();\n fieldName = ancestor.getAttribute(tinaAttribute2);\n }\n }\n }\n if (fieldName) {\n if (isInTinaIframe) {\n parent.postMessage(\n { type: \"field:selected\", fieldName },\n window.location.origin\n );\n }\n }\n };\n const style = document.createElement(\"style\");\n style.type = \"text/css\";\n style.textContent = `\n [data-tina-field] {\n outline: 2px dashed rgba(34,150,254,0.5);\n transition: box-shadow ease-out 150ms;\n }\n [data-tina-field]:hover {\n box-shadow: inset 100vi 100vh rgba(34,150,254,0.3);\n outline: 2px solid rgba(34,150,254,1);\n cursor: pointer;\n }\n [data-tina-field-overlay] {\n outline: 2px dashed rgba(34,150,254,0.5);\n position: relative;\n }\n [data-tina-field-overlay]:hover {\n cursor: pointer;\n outline: 2px solid rgba(34,150,254,1);\n }\n [data-tina-field-overlay]::after {\n content: '';\n position: absolute;\n inset: 0;\n z-index: 20;\n transition: opacity ease-out 150ms;\n background-color: rgba(34,150,254,0.3);\n opacity: 0;\n }\n [data-tina-field-overlay]:hover::after {\n opacity: 1;\n }\n `;\n document.head.appendChild(style);\n document.body.classList.add(\"__tina-quick-editing-enabled\");\n document.addEventListener(\"click\", mouseDownHandler, true);\n return () => {\n document.removeEventListener(\"click\", mouseDownHandler, true);\n document.body.classList.remove(\"__tina-quick-editing-enabled\");\n style.remove();\n };\n }\n }, [quickEditEnabled, isInTinaIframe]);\n React.useEffect(() => {\n if (props == null ? void 0 : props.experimental___selectFormByFormId) {\n parent.postMessage({\n type: \"user-select-form\",\n formId: props.experimental___selectFormByFormId()\n });\n }\n }, [id]);\n React.useEffect(() => {\n const { experimental___selectFormByFormId, ...rest } = props;\n parent.postMessage({ type: \"open\", ...rest, id }, window.location.origin);\n window.addEventListener(\"message\", (event) => {\n if (event.data.type === \"quickEditEnabled\") {\n setQuickEditEnabled(event.data.value);\n }\n if (event.data.id === id && event.data.type === \"updateData\") {\n setData(event.data.data);\n setIsInTinaIframe(true);\n const anyTinaField = document.querySelector(\"[data-tina-field]\");\n if (anyTinaField) {\n parent.postMessage(\n { type: \"quick-edit\", value: true },\n window.location.origin\n );\n } else {\n parent.postMessage(\n { type: \"quick-edit\", value: false },\n window.location.origin\n );\n }\n }\n });\n return () => {\n parent.postMessage({ type: \"close\", id }, window.location.origin);\n };\n }, [id, setQuickEditEnabled]);\n return { data, isClient };\n}\nfunction useEditState() {\n const [edit, setEdit] = React.useState(false);\n React.useEffect(() => {\n if (typeof window !== \"undefined\") {\n parent.postMessage({ type: \"isEditMode\" }, window.location.origin);\n window.addEventListener(\"message\", (event) => {\n var _a;\n if (((_a = event.data) == null ? void 0 : _a.type) === \"tina:editMode\") {\n setEdit(true);\n }\n });\n }\n }, []);\n return { edit };\n}\nconst tinaField = (object, property, index) => {\n var _a, _b, _c;\n if (!object) {\n return \"\";\n }\n if (object._content_source) {\n if (!property) {\n return [\n (_a = object._content_source) == null ? void 0 : _a.queryId,\n object._content_source.path.join(\".\")\n ].join(\"---\");\n }\n if (typeof index === \"number\") {\n return [\n (_b = object._content_source) == null ? void 0 : _b.queryId,\n [...object._content_source.path, property, index].join(\".\")\n ].join(\"---\");\n }\n return [\n (_c = object._content_source) == null ? void 0 : _c.queryId,\n [...object._content_source.path, property].join(\".\")\n ].join(\"---\");\n }\n return \"\";\n};\nconst addMetadata = (id, object, path) => {\n Object.entries(object).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (isScalarOrUndefined(item)) {\n return;\n }\n if (Array.isArray(item)) {\n return;\n }\n const itemObject = item;\n addMetadata(id, itemObject, [...path, key, index]);\n });\n } else {\n if (isScalarOrUndefined(value)) {\n return;\n }\n const itemObject = value;\n addMetadata(id, itemObject, [...path, key]);\n }\n });\n if ((object == null ? void 0 : object.type) === \"root\") {\n return;\n }\n object._content_source = {\n queryId: id,\n path\n };\n return object;\n};\nfunction isScalarOrUndefined(value) {\n const type = typeof value;\n if (type === \"string\")\n return true;\n if (type === \"number\")\n return true;\n if (type === \"boolean\")\n return true;\n if (type === \"undefined\")\n return true;\n if (value == null)\n return true;\n if (value instanceof String)\n return true;\n if (value instanceof Number)\n return true;\n if (value instanceof Boolean)\n return true;\n return false;\n}\nconst hashFromQuery = (input) => {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char & 4294967295;\n }\n const nonNegativeHash = Math.abs(hash);\n const alphanumericHash = nonNegativeHash.toString(36);\n return alphanumericHash;\n};\nexport {\n addMetadata,\n hashFromQuery,\n tinaField,\n useEditState,\n useTina\n};\n//# sourceMappingURL=react.mjs.map\n","import { vercelStegaCombine } from '@vercel/stega';\nimport React from 'react';\nimport { tinaField, useEditState } from 'tinacms/dist/react';\nimport { useCallback, useEffect } from 'react';\n\nexport const vercelEditInfo = <\n T extends object & {\n _content_source?: {\n queryId: string;\n path: (number | string)[];\n };\n },\n>(\n obj: T,\n field?: keyof Omit<T, '__typename' | '_sys'>,\n index?: number\n) => {\n const fieldName = tinaField(obj, field, index);\n return JSON.stringify({ origin: 'tinacms', data: { fieldName } });\n};\n\nexport const useVisualEditing = <T extends object>({\n data,\n query,\n variables,\n enabled,\n redirect,\n stringEncoding,\n}: {\n data: T;\n query: string;\n variables: object;\n enabled: boolean;\n redirect: string;\n stringEncoding:\n | boolean\n | { skipPaths: (path: string, value: string) => boolean };\n}): T => {\n const stringifiedQuery = JSON.stringify({\n query: query,\n variables: variables,\n });\n const id = React.useMemo(\n () => hashFromQuery(stringifiedQuery),\n [stringifiedQuery]\n );\n const { edit } = useEditState();\n const handleOpenEvent = useCallback(\n (event: CustomEventInit) => {\n if (edit) {\n parent.postMessage(\n { type: 'field:selected', fieldName: event.detail?.data?.fieldName },\n window.location.origin\n );\n } else {\n const tinaAdminBasePath = redirect.startsWith('/')\n ? redirect\n : `/${redirect}`;\n const tinaAdminPath = `${tinaAdminBasePath}/index.html#/~${window.location.pathname}?active-field=${event.detail.data.fieldName}`;\n window.location.assign(tinaAdminPath);\n }\n },\n [edit]\n );\n\n useEffect(() => {\n window.addEventListener('edit:open', handleOpenEvent);\n return () => {\n window.removeEventListener('edit:open', handleOpenEvent);\n };\n }, [redirect, edit]);\n\n function appendMetadata<T>(\n obj: T,\n path: (string | number)[] = [],\n id: string\n ): T {\n if (typeof obj !== 'object' || obj === null) {\n if (typeof obj === 'string' && stringEncoding) {\n if (typeof stringEncoding === 'boolean') {\n if (stringEncoding) {\n return encodeEditInfo(path, obj, id) as any;\n }\n } else if (stringEncoding.skipPaths) {\n if (!stringEncoding.skipPaths(path.join('.'), obj)) {\n return encodeEditInfo(path, obj, id) as any;\n }\n }\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item, index) =>\n appendMetadata(item, [...path, index], id)\n ) as unknown as T; // Handle arrays recursively\n }\n\n const transformedObj = {} as T;\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n if (\n [\n '__typename',\n '_sys',\n '_internalSys',\n '_values',\n '_internalValues',\n '_content_source',\n '_tina_metadata',\n ].includes(key)\n ) {\n transformedObj[key] = value;\n } else {\n transformedObj[key] = appendMetadata(value, currentPath, id);\n }\n }\n\n return { ...transformedObj, _content_source: { queryId: id, path } };\n }\n if (enabled) {\n return appendMetadata(data, [], id);\n }\n return data;\n};\n\nfunction encodeEditInfo(path: (string | number)[], value: string, id: string) {\n return vercelStegaCombine(value, {\n origin: 'tina.io',\n data: { fieldName: `${id}---${path.join('.')}` },\n });\n}\n\nexport const hashFromQuery = (input: string) => {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = ((hash << 5) - hash + char) & 0xffffffff; // Apply bitwise AND to ensure non-negative value\n }\n const nonNegativeHash = Math.abs(hash);\n const alphanumericHash = nonNegativeHash.toString(36);\n return alphanumericHash;\n};\n"],"names":["useCallback","useEffect","id","vercelStegaCombine"],"mappings":"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"}
|
package/dist/index.mjs
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { vercelStegaCombine } from "@vercel/stega";
|
|
2
|
-
import React, { useCallback, useEffect } from "react";
|
|
3
|
-
function useEditState() {
|
|
4
|
-
const [edit, setEdit] = React.useState(false);
|
|
5
|
-
React.useEffect(() => {
|
|
6
|
-
if (typeof window !== "undefined") {
|
|
7
|
-
parent.postMessage({ type: "isEditMode" }, window.location.origin);
|
|
8
|
-
window.addEventListener("message", (event) => {
|
|
9
|
-
var _a;
|
|
10
|
-
if (((_a = event.data) == null ? void 0 : _a.type) === "tina:editMode") {
|
|
11
|
-
setEdit(true);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}, []);
|
|
16
|
-
return { edit };
|
|
17
|
-
}
|
|
18
|
-
const tinaField = (object, property, index) => {
|
|
19
|
-
var _a, _b, _c;
|
|
20
|
-
if (!object) {
|
|
21
|
-
return "";
|
|
22
|
-
}
|
|
23
|
-
if (object._content_source) {
|
|
24
|
-
if (!property) {
|
|
25
|
-
return [
|
|
26
|
-
(_a = object._content_source) == null ? void 0 : _a.queryId,
|
|
27
|
-
object._content_source.path.join(".")
|
|
28
|
-
].join("---");
|
|
29
|
-
}
|
|
30
|
-
if (typeof index === "number") {
|
|
31
|
-
return [
|
|
32
|
-
(_b = object._content_source) == null ? void 0 : _b.queryId,
|
|
33
|
-
[...object._content_source.path, property, index].join(".")
|
|
34
|
-
].join("---");
|
|
35
|
-
}
|
|
36
|
-
return [
|
|
37
|
-
(_c = object._content_source) == null ? void 0 : _c.queryId,
|
|
38
|
-
[...object._content_source.path, property].join(".")
|
|
39
|
-
].join("---");
|
|
40
|
-
}
|
|
41
|
-
return "";
|
|
42
|
-
};
|
|
43
|
-
const vercelEditInfo = (obj, field, index) => {
|
|
44
|
-
const fieldName = tinaField(obj, field, index);
|
|
45
|
-
return JSON.stringify({ origin: "tinacms", data: { fieldName } });
|
|
46
|
-
};
|
|
47
|
-
const useVisualEditing = ({
|
|
48
|
-
data,
|
|
49
|
-
query,
|
|
50
|
-
variables,
|
|
51
|
-
enabled,
|
|
52
|
-
redirect,
|
|
53
|
-
stringEncoding
|
|
54
|
-
}) => {
|
|
55
|
-
const stringifiedQuery = JSON.stringify({
|
|
56
|
-
query,
|
|
57
|
-
variables
|
|
58
|
-
});
|
|
59
|
-
const id = React.useMemo(
|
|
60
|
-
() => hashFromQuery(stringifiedQuery),
|
|
61
|
-
[stringifiedQuery]
|
|
62
|
-
);
|
|
63
|
-
const { edit } = useEditState();
|
|
64
|
-
const handleOpenEvent = useCallback(
|
|
65
|
-
(event) => {
|
|
66
|
-
var _a, _b;
|
|
67
|
-
if (edit) {
|
|
68
|
-
parent.postMessage(
|
|
69
|
-
{ type: "field:selected", fieldName: (_b = (_a = event.detail) == null ? void 0 : _a.data) == null ? void 0 : _b.fieldName },
|
|
70
|
-
window.location.origin
|
|
71
|
-
);
|
|
72
|
-
} else {
|
|
73
|
-
const tinaAdminBasePath = redirect.startsWith("/") ? redirect : `/${redirect}`;
|
|
74
|
-
const tinaAdminPath = `${tinaAdminBasePath}/index.html#/~${window.location.pathname}?active-field=${event.detail.data.fieldName}`;
|
|
75
|
-
window.location.assign(tinaAdminPath);
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
[edit]
|
|
79
|
-
);
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
window.addEventListener("edit:open", handleOpenEvent);
|
|
82
|
-
return () => {
|
|
83
|
-
window.removeEventListener("edit:open", handleOpenEvent);
|
|
84
|
-
};
|
|
85
|
-
}, [redirect, edit]);
|
|
86
|
-
function appendMetadata(obj, path = [], id2) {
|
|
87
|
-
if (typeof obj !== "object" || obj === null) {
|
|
88
|
-
if (typeof obj === "string" && stringEncoding) {
|
|
89
|
-
if (typeof stringEncoding === "boolean") {
|
|
90
|
-
if (stringEncoding) {
|
|
91
|
-
return encodeEditInfo(path, obj, id2);
|
|
92
|
-
}
|
|
93
|
-
} else if (stringEncoding.skipPaths) {
|
|
94
|
-
if (!stringEncoding.skipPaths(path.join("."), obj)) {
|
|
95
|
-
return encodeEditInfo(path, obj, id2);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return obj;
|
|
100
|
-
}
|
|
101
|
-
if (Array.isArray(obj)) {
|
|
102
|
-
return obj.map(
|
|
103
|
-
(item, index) => appendMetadata(item, [...path, index], id2)
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
const transformedObj = {};
|
|
107
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
108
|
-
const currentPath = [...path, key];
|
|
109
|
-
if ([
|
|
110
|
-
"__typename",
|
|
111
|
-
"_sys",
|
|
112
|
-
"_internalSys",
|
|
113
|
-
"_values",
|
|
114
|
-
"_internalValues",
|
|
115
|
-
"_content_source",
|
|
116
|
-
"_tina_metadata"
|
|
117
|
-
].includes(key)) {
|
|
118
|
-
transformedObj[key] = value;
|
|
119
|
-
} else {
|
|
120
|
-
transformedObj[key] = appendMetadata(value, currentPath, id2);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return { ...transformedObj, _content_source: { queryId: id2, path } };
|
|
124
|
-
}
|
|
125
|
-
if (enabled) {
|
|
126
|
-
return appendMetadata(data, [], id);
|
|
127
|
-
}
|
|
128
|
-
return data;
|
|
129
|
-
};
|
|
130
|
-
function encodeEditInfo(path, value, id) {
|
|
131
|
-
return vercelStegaCombine(value, {
|
|
132
|
-
origin: "tina.io",
|
|
133
|
-
data: { fieldName: `${id}---${path.join(".")}` }
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
const hashFromQuery = (input) => {
|
|
137
|
-
let hash = 0;
|
|
138
|
-
for (let i = 0; i < input.length; i++) {
|
|
139
|
-
const char = input.charCodeAt(i);
|
|
140
|
-
hash = (hash << 5) - hash + char & 4294967295;
|
|
141
|
-
}
|
|
142
|
-
const nonNegativeHash = Math.abs(hash);
|
|
143
|
-
const alphanumericHash = nonNegativeHash.toString(36);
|
|
144
|
-
return alphanumericHash;
|
|
145
|
-
};
|
|
146
|
-
export {
|
|
147
|
-
hashFromQuery,
|
|
148
|
-
useVisualEditing,
|
|
149
|
-
vercelEditInfo
|
|
150
|
-
};
|
|
151
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../tinacms/dist/react.mjs","../src/index.ts"],"sourcesContent":["import React from \"react\";\nfunction useTina(props) {\n const stringifiedQuery = JSON.stringify({\n query: props.query,\n variables: props.variables\n });\n const id = React.useMemo(\n () => hashFromQuery(stringifiedQuery),\n [stringifiedQuery]\n );\n const [data, setData] = React.useState(props.data);\n const [isClient, setIsClient] = React.useState(false);\n const [quickEditEnabled, setQuickEditEnabled] = React.useState(false);\n const [isInTinaIframe, setIsInTinaIframe] = React.useState(false);\n React.useEffect(() => {\n setIsClient(true);\n setData(props.data);\n parent.postMessage({\n type: \"url-changed\"\n });\n }, [id]);\n React.useEffect(() => {\n if (quickEditEnabled) {\n let mouseDownHandler = function(e) {\n const attributeNames = e.target.getAttributeNames();\n const tinaAttribute = attributeNames.find(\n (name) => name.startsWith(\"data-tina-field\")\n );\n let fieldName;\n if (tinaAttribute) {\n e.preventDefault();\n e.stopPropagation();\n fieldName = e.target.getAttribute(tinaAttribute);\n } else {\n const ancestor = e.target.closest(\n \"[data-tina-field], [data-tina-field-overlay]\"\n );\n if (ancestor) {\n const attributeNames2 = ancestor.getAttributeNames();\n const tinaAttribute2 = attributeNames2.find(\n (name) => name.startsWith(\"data-tina-field\")\n );\n if (tinaAttribute2) {\n e.preventDefault();\n e.stopPropagation();\n fieldName = ancestor.getAttribute(tinaAttribute2);\n }\n }\n }\n if (fieldName) {\n if (isInTinaIframe) {\n parent.postMessage(\n { type: \"field:selected\", fieldName },\n window.location.origin\n );\n }\n }\n };\n const style = document.createElement(\"style\");\n style.type = \"text/css\";\n style.textContent = `\n [data-tina-field] {\n outline: 2px dashed rgba(34,150,254,0.5);\n transition: box-shadow ease-out 150ms;\n }\n [data-tina-field]:hover {\n box-shadow: inset 100vi 100vh rgba(34,150,254,0.3);\n outline: 2px solid rgba(34,150,254,1);\n cursor: pointer;\n }\n [data-tina-field-overlay] {\n outline: 2px dashed rgba(34,150,254,0.5);\n position: relative;\n }\n [data-tina-field-overlay]:hover {\n cursor: pointer;\n outline: 2px solid rgba(34,150,254,1);\n }\n [data-tina-field-overlay]::after {\n content: '';\n position: absolute;\n inset: 0;\n z-index: 20;\n transition: opacity ease-out 150ms;\n background-color: rgba(34,150,254,0.3);\n opacity: 0;\n }\n [data-tina-field-overlay]:hover::after {\n opacity: 1;\n }\n `;\n document.head.appendChild(style);\n document.body.classList.add(\"__tina-quick-editing-enabled\");\n document.addEventListener(\"click\", mouseDownHandler, true);\n return () => {\n document.removeEventListener(\"click\", mouseDownHandler, true);\n document.body.classList.remove(\"__tina-quick-editing-enabled\");\n style.remove();\n };\n }\n }, [quickEditEnabled, isInTinaIframe]);\n React.useEffect(() => {\n if (props == null ? void 0 : props.experimental___selectFormByFormId) {\n parent.postMessage({\n type: \"user-select-form\",\n formId: props.experimental___selectFormByFormId()\n });\n }\n }, [id]);\n React.useEffect(() => {\n const { experimental___selectFormByFormId, ...rest } = props;\n parent.postMessage({ type: \"open\", ...rest, id }, window.location.origin);\n window.addEventListener(\"message\", (event) => {\n if (event.data.type === \"quickEditEnabled\") {\n setQuickEditEnabled(event.data.value);\n }\n if (event.data.id === id && event.data.type === \"updateData\") {\n setData(event.data.data);\n setIsInTinaIframe(true);\n const anyTinaField = document.querySelector(\"[data-tina-field]\");\n if (anyTinaField) {\n parent.postMessage(\n { type: \"quick-edit\", value: true },\n window.location.origin\n );\n } else {\n parent.postMessage(\n { type: \"quick-edit\", value: false },\n window.location.origin\n );\n }\n }\n });\n return () => {\n parent.postMessage({ type: \"close\", id }, window.location.origin);\n };\n }, [id, setQuickEditEnabled]);\n return { data, isClient };\n}\nfunction useEditState() {\n const [edit, setEdit] = React.useState(false);\n React.useEffect(() => {\n if (typeof window !== \"undefined\") {\n parent.postMessage({ type: \"isEditMode\" }, window.location.origin);\n window.addEventListener(\"message\", (event) => {\n var _a;\n if (((_a = event.data) == null ? void 0 : _a.type) === \"tina:editMode\") {\n setEdit(true);\n }\n });\n }\n }, []);\n return { edit };\n}\nconst tinaField = (object, property, index) => {\n var _a, _b, _c;\n if (!object) {\n return \"\";\n }\n if (object._content_source) {\n if (!property) {\n return [\n (_a = object._content_source) == null ? void 0 : _a.queryId,\n object._content_source.path.join(\".\")\n ].join(\"---\");\n }\n if (typeof index === \"number\") {\n return [\n (_b = object._content_source) == null ? void 0 : _b.queryId,\n [...object._content_source.path, property, index].join(\".\")\n ].join(\"---\");\n }\n return [\n (_c = object._content_source) == null ? void 0 : _c.queryId,\n [...object._content_source.path, property].join(\".\")\n ].join(\"---\");\n }\n return \"\";\n};\nconst addMetadata = (id, object, path) => {\n Object.entries(object).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n if (isScalarOrUndefined(item)) {\n return;\n }\n if (Array.isArray(item)) {\n return;\n }\n const itemObject = item;\n addMetadata(id, itemObject, [...path, key, index]);\n });\n } else {\n if (isScalarOrUndefined(value)) {\n return;\n }\n const itemObject = value;\n addMetadata(id, itemObject, [...path, key]);\n }\n });\n if ((object == null ? void 0 : object.type) === \"root\") {\n return;\n }\n object._content_source = {\n queryId: id,\n path\n };\n return object;\n};\nfunction isScalarOrUndefined(value) {\n const type = typeof value;\n if (type === \"string\")\n return true;\n if (type === \"number\")\n return true;\n if (type === \"boolean\")\n return true;\n if (type === \"undefined\")\n return true;\n if (value == null)\n return true;\n if (value instanceof String)\n return true;\n if (value instanceof Number)\n return true;\n if (value instanceof Boolean)\n return true;\n return false;\n}\nconst hashFromQuery = (input) => {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char & 4294967295;\n }\n const nonNegativeHash = Math.abs(hash);\n const alphanumericHash = nonNegativeHash.toString(36);\n return alphanumericHash;\n};\nexport {\n addMetadata,\n hashFromQuery,\n tinaField,\n useEditState,\n useTina\n};\n//# sourceMappingURL=react.mjs.map\n","import { vercelStegaCombine } from '@vercel/stega';\nimport React from 'react';\nimport { tinaField, useEditState } from 'tinacms/dist/react';\nimport { useCallback, useEffect } from 'react';\n\nexport const vercelEditInfo = <\n T extends object & {\n _content_source?: {\n queryId: string;\n path: (number | string)[];\n };\n },\n>(\n obj: T,\n field?: keyof Omit<T, '__typename' | '_sys'>,\n index?: number\n) => {\n const fieldName = tinaField(obj, field, index);\n return JSON.stringify({ origin: 'tinacms', data: { fieldName } });\n};\n\nexport const useVisualEditing = <T extends object>({\n data,\n query,\n variables,\n enabled,\n redirect,\n stringEncoding,\n}: {\n data: T;\n query: string;\n variables: object;\n enabled: boolean;\n redirect: string;\n stringEncoding:\n | boolean\n | { skipPaths: (path: string, value: string) => boolean };\n}): T => {\n const stringifiedQuery = JSON.stringify({\n query: query,\n variables: variables,\n });\n const id = React.useMemo(\n () => hashFromQuery(stringifiedQuery),\n [stringifiedQuery]\n );\n const { edit } = useEditState();\n const handleOpenEvent = useCallback(\n (event: CustomEventInit) => {\n if (edit) {\n parent.postMessage(\n { type: 'field:selected', fieldName: event.detail?.data?.fieldName },\n window.location.origin\n );\n } else {\n const tinaAdminBasePath = redirect.startsWith('/')\n ? redirect\n : `/${redirect}`;\n const tinaAdminPath = `${tinaAdminBasePath}/index.html#/~${window.location.pathname}?active-field=${event.detail.data.fieldName}`;\n window.location.assign(tinaAdminPath);\n }\n },\n [edit]\n );\n\n useEffect(() => {\n window.addEventListener('edit:open', handleOpenEvent);\n return () => {\n window.removeEventListener('edit:open', handleOpenEvent);\n };\n }, [redirect, edit]);\n\n function appendMetadata<T>(\n obj: T,\n path: (string | number)[] = [],\n id: string\n ): T {\n if (typeof obj !== 'object' || obj === null) {\n if (typeof obj === 'string' && stringEncoding) {\n if (typeof stringEncoding === 'boolean') {\n if (stringEncoding) {\n return encodeEditInfo(path, obj, id) as any;\n }\n } else if (stringEncoding.skipPaths) {\n if (!stringEncoding.skipPaths(path.join('.'), obj)) {\n return encodeEditInfo(path, obj, id) as any;\n }\n }\n }\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item, index) =>\n appendMetadata(item, [...path, index], id)\n ) as unknown as T; // Handle arrays recursively\n }\n\n const transformedObj = {} as T;\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n if (\n [\n '__typename',\n '_sys',\n '_internalSys',\n '_values',\n '_internalValues',\n '_content_source',\n '_tina_metadata',\n ].includes(key)\n ) {\n transformedObj[key] = value;\n } else {\n transformedObj[key] = appendMetadata(value, currentPath, id);\n }\n }\n\n return { ...transformedObj, _content_source: { queryId: id, path } };\n }\n if (enabled) {\n return appendMetadata(data, [], id);\n }\n return data;\n};\n\nfunction encodeEditInfo(path: (string | number)[], value: string, id: string) {\n return vercelStegaCombine(value, {\n origin: 'tina.io',\n data: { fieldName: `${id}---${path.join('.')}` },\n });\n}\n\nexport const hashFromQuery = (input: string) => {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = ((hash << 5) - hash + char) & 0xffffffff; // Apply bitwise AND to ensure non-negative value\n }\n const nonNegativeHash = Math.abs(hash);\n const alphanumericHash = nonNegativeHash.toString(36);\n return alphanumericHash;\n};\n"],"names":["id"],"mappings":"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"}
|