@liiift-studio/sanity-font-manager 2.3.19 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +437 -437
- package/dist/UploadModal-6LIX7XOK.js +6 -0
- package/dist/UploadModal-NME2W53V.mjs +6 -0
- package/dist/chunk-646WCBRR.mjs +7276 -0
- package/dist/chunk-FH4QKHOH.js +7276 -0
- package/dist/index.js +747 -1675
- package/dist/index.mjs +400 -1237
- package/package.json +85 -85
- package/src/components/BatchUploadFonts.jsx +653 -639
- package/src/components/BulkActions.jsx +99 -0
- package/src/components/ExistingDocumentResolver.jsx +152 -0
- package/src/components/FontReviewCard.jsx +415 -0
- package/src/components/FontScriptUploaderComponent.jsx +463 -463
- package/src/components/GenerateCollectionsPairsComponent.jsx +259 -259
- package/src/components/KeyValueInput.jsx +95 -95
- package/src/components/KeyValueReferenceInput.jsx +254 -254
- package/src/components/NestedObjectArraySelector.jsx +146 -146
- package/src/components/PriceInput.jsx +26 -26
- package/src/components/PrimaryCollectionGeneratorTypeface.jsx +116 -116
- package/src/components/RegenerateSubfamiliesComponent.jsx +185 -185
- package/src/components/SetOTF.jsx +87 -87
- package/src/components/SingleUploaderTool.jsx +672 -673
- package/src/components/StatusDisplay.jsx +26 -26
- package/src/components/StyleCountInput.jsx +16 -16
- package/src/components/UpdateScriptsComponent.jsx +76 -76
- package/src/components/UploadButton.jsx +43 -43
- package/src/components/UploadModal.jsx +268 -0
- package/src/components/UploadScriptsComponent.jsx +539 -537
- package/src/components/UploadStep1Settings.jsx +272 -0
- package/src/components/UploadStep2Review.jsx +472 -0
- package/src/components/UploadStep3Execute.jsx +234 -0
- package/src/components/UploadSummary.jsx +196 -0
- package/src/components/VariableInstanceReferencesInput.jsx +190 -190
- package/src/hooks/useNestedObjects.js +92 -92
- package/src/hooks/useSanityClient.js +9 -9
- package/src/index.js +115 -70
- package/src/schema/openTypeField.js +1945 -1945
- package/src/schema/styleCountField.js +12 -12
- package/src/schema/stylesField.js +268 -268
- package/src/schema/stylisticSetField.js +301 -301
- package/src/utils/buildUploadPlan.js +325 -0
- package/src/utils/executeUploadPlan.js +437 -0
- package/src/utils/executionReducer.js +56 -0
- package/src/utils/fontHelpers.js +267 -0
- package/src/utils/generateCssFile.js +207 -205
- package/src/utils/generateFontData.js +98 -145
- package/src/utils/generateFontFile.js +38 -38
- package/src/utils/generateKeywords.js +185 -185
- package/src/utils/generateSubset.js +45 -45
- package/src/utils/getEmptyFontKit.js +101 -99
- package/src/utils/parseFont.js +55 -0
- package/src/utils/parseVariableFontInstances.js +211 -211
- package/src/utils/planReducer.js +517 -0
- package/src/utils/planTypes.js +183 -0
- package/src/utils/processFontFiles.js +529 -477
- package/src/utils/regenerateFontData.js +146 -146
- package/src/utils/resolveExistingFont.js +87 -0
- package/src/utils/sanitizeForSanityId.js +65 -65
- package/src/utils/updateFontPrices.js +94 -94
- package/src/utils/updateTypefaceDocument.js +149 -160
- package/src/utils/uploadFontFiles.js +405 -316
- package/src/utils/utils.js +24 -24
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
// Bulk-updates the price field across all font documents linked to a typeface
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Sets the same price on every font document referenced by a typeface.
|
|
5
|
-
*
|
|
6
|
-
* @param {Object} params
|
|
7
|
-
* @param {Object} params.client - Sanity client
|
|
8
|
-
* @param {string} params.title - Typeface title
|
|
9
|
-
* @param {Object} params.slug - Typeface slug object
|
|
10
|
-
* @param {string} params.inputPrice - New price value (will be coerced to Number)
|
|
11
|
-
* @param {string} params.doc_id - Document ID (used to detect draft state)
|
|
12
|
-
* @param {Function} params.setStatus
|
|
13
|
-
* @param {Function} params.setError
|
|
14
|
-
* @returns {Promise<Object>}
|
|
15
|
-
*/
|
|
16
|
-
export const updateFontPrices = async ({
|
|
17
|
-
client,
|
|
18
|
-
title,
|
|
19
|
-
slug,
|
|
20
|
-
inputPrice,
|
|
21
|
-
doc_id,
|
|
22
|
-
setStatus,
|
|
23
|
-
setError,
|
|
24
|
-
}) => {
|
|
25
|
-
try {
|
|
26
|
-
if (!title) {
|
|
27
|
-
setStatus('Typeface needs a title');
|
|
28
|
-
setError(true);
|
|
29
|
-
console.error('Typeface needs title');
|
|
30
|
-
return { success: false, message: 'Typeface needs title' };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!slug?.current) {
|
|
34
|
-
setStatus('Typeface needs a slug');
|
|
35
|
-
setError(true);
|
|
36
|
-
console.error('Typeface needs slug');
|
|
37
|
-
return { success: false, message: 'Typeface needs slug' };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const price = Number(inputPrice);
|
|
41
|
-
if (isNaN(price)) {
|
|
42
|
-
setStatus('Invalid price value');
|
|
43
|
-
setError(true);
|
|
44
|
-
console.error('Invalid price value');
|
|
45
|
-
return { success: false, message: 'Invalid price value' };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
setStatus('Fetching typeface document...');
|
|
49
|
-
const typeface = await client.fetch(
|
|
50
|
-
`*[_type == "typeface" && slug.current == $slug][0]`,
|
|
51
|
-
{ slug: slug.current }
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
if (!typeface) {
|
|
55
|
-
setStatus('Typeface not found');
|
|
56
|
-
setError(true);
|
|
57
|
-
console.error('Typeface not found');
|
|
58
|
-
return { success: false, message: 'Typeface not found' };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!typeface.styles?.fonts?.length) {
|
|
62
|
-
setStatus('No fonts found in typeface');
|
|
63
|
-
setError(true);
|
|
64
|
-
console.error('No fonts found in typeface');
|
|
65
|
-
return { success: false, message: 'No fonts found in typeface' };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const fontRefs = typeface.styles.fonts;
|
|
69
|
-
setStatus(`Updating prices for ${fontRefs.length} fonts...`);
|
|
70
|
-
|
|
71
|
-
let updatedCount = 0;
|
|
72
|
-
for (let i = 0; i < fontRefs.length; i++) {
|
|
73
|
-
try {
|
|
74
|
-
await client.patch(fontRefs[i]._ref).set({ price, sell: price > 0 }).commit();
|
|
75
|
-
updatedCount++;
|
|
76
|
-
setStatus(`Updated ${updatedCount}/${fontRefs.length} fonts...`);
|
|
77
|
-
} catch (err) {
|
|
78
|
-
console.error(`Error updating font ${fontRefs[i]._ref}:`, err);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const successMessage = `Successfully updated prices for ${updatedCount} fonts to $${price}`;
|
|
83
|
-
setStatus(successMessage);
|
|
84
|
-
console.log(successMessage);
|
|
85
|
-
|
|
86
|
-
return { success: true, message: successMessage, updatedCount };
|
|
87
|
-
} catch (err) {
|
|
88
|
-
const errorMessage = `Error: ${err.message}`;
|
|
89
|
-
console.error('Error updating font prices:', err);
|
|
90
|
-
setError(true);
|
|
91
|
-
setStatus(errorMessage);
|
|
92
|
-
return { success: false, message: errorMessage };
|
|
93
|
-
}
|
|
94
|
-
};
|
|
1
|
+
// Bulk-updates the price field across all font documents linked to a typeface
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sets the same price on every font document referenced by a typeface.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} params
|
|
7
|
+
* @param {Object} params.client - Sanity client
|
|
8
|
+
* @param {string} params.title - Typeface title
|
|
9
|
+
* @param {Object} params.slug - Typeface slug object
|
|
10
|
+
* @param {string} params.inputPrice - New price value (will be coerced to Number)
|
|
11
|
+
* @param {string} params.doc_id - Document ID (used to detect draft state)
|
|
12
|
+
* @param {Function} params.setStatus
|
|
13
|
+
* @param {Function} params.setError
|
|
14
|
+
* @returns {Promise<Object>}
|
|
15
|
+
*/
|
|
16
|
+
export const updateFontPrices = async ({
|
|
17
|
+
client,
|
|
18
|
+
title,
|
|
19
|
+
slug,
|
|
20
|
+
inputPrice,
|
|
21
|
+
doc_id,
|
|
22
|
+
setStatus,
|
|
23
|
+
setError,
|
|
24
|
+
}) => {
|
|
25
|
+
try {
|
|
26
|
+
if (!title) {
|
|
27
|
+
setStatus('Typeface needs a title');
|
|
28
|
+
setError(true);
|
|
29
|
+
console.error('Typeface needs title');
|
|
30
|
+
return { success: false, message: 'Typeface needs title' };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!slug?.current) {
|
|
34
|
+
setStatus('Typeface needs a slug');
|
|
35
|
+
setError(true);
|
|
36
|
+
console.error('Typeface needs slug');
|
|
37
|
+
return { success: false, message: 'Typeface needs slug' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const price = Number(inputPrice);
|
|
41
|
+
if (isNaN(price)) {
|
|
42
|
+
setStatus('Invalid price value');
|
|
43
|
+
setError(true);
|
|
44
|
+
console.error('Invalid price value');
|
|
45
|
+
return { success: false, message: 'Invalid price value' };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setStatus('Fetching typeface document...');
|
|
49
|
+
const typeface = await client.fetch(
|
|
50
|
+
`*[_type == "typeface" && slug.current == $slug][0]`,
|
|
51
|
+
{ slug: slug.current }
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (!typeface) {
|
|
55
|
+
setStatus('Typeface not found');
|
|
56
|
+
setError(true);
|
|
57
|
+
console.error('Typeface not found');
|
|
58
|
+
return { success: false, message: 'Typeface not found' };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!typeface.styles?.fonts?.length) {
|
|
62
|
+
setStatus('No fonts found in typeface');
|
|
63
|
+
setError(true);
|
|
64
|
+
console.error('No fonts found in typeface');
|
|
65
|
+
return { success: false, message: 'No fonts found in typeface' };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const fontRefs = typeface.styles.fonts;
|
|
69
|
+
setStatus(`Updating prices for ${fontRefs.length} fonts...`);
|
|
70
|
+
|
|
71
|
+
let updatedCount = 0;
|
|
72
|
+
for (let i = 0; i < fontRefs.length; i++) {
|
|
73
|
+
try {
|
|
74
|
+
await client.patch(fontRefs[i]._ref).set({ price, sell: price > 0 }).commit();
|
|
75
|
+
updatedCount++;
|
|
76
|
+
setStatus(`Updated ${updatedCount}/${fontRefs.length} fonts...`);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.error(`Error updating font ${fontRefs[i]._ref}:`, err);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const successMessage = `Successfully updated prices for ${updatedCount} fonts to $${price}`;
|
|
83
|
+
setStatus(successMessage);
|
|
84
|
+
console.log(successMessage);
|
|
85
|
+
|
|
86
|
+
return { success: true, message: successMessage, updatedCount };
|
|
87
|
+
} catch (err) {
|
|
88
|
+
const errorMessage = `Error: ${err.message}`;
|
|
89
|
+
console.error('Error updating font prices:', err);
|
|
90
|
+
setError(true);
|
|
91
|
+
setStatus(errorMessage);
|
|
92
|
+
return { success: false, message: errorMessage };
|
|
93
|
+
}
|
|
94
|
+
};
|
|
@@ -1,160 +1,149 @@
|
|
|
1
|
-
// Patches the parent typeface document's styles.fonts array with newly uploaded font references
|
|
2
|
-
|
|
3
|
-
import { nanoid } from 'nanoid';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Patches a typeface document (draft and published) with the new font references,
|
|
7
|
-
* subfamily structure, and preferred style derived from the upload batch.
|
|
8
|
-
*
|
|
9
|
-
* @param {string} doc_id - The Sanity document ID (may be a draft)
|
|
10
|
-
* @param {Object[]} fontRefs - New regular font references
|
|
11
|
-
* @param {Object[]} variableRefs - New variable font references
|
|
12
|
-
* @param {Object} subfamilies - Map of font ID → subfamily name
|
|
13
|
-
* @param {string[]} uniqueSubfamilies
|
|
14
|
-
* @param {Object[]} subfamiliesArray - Existing subfamilies array from the typeface
|
|
15
|
-
* @param {Object} preferredStyleRef - Existing preferred style reference
|
|
16
|
-
* @param {Object} newPreferredStyle - Candidate preferred style from the upload
|
|
17
|
-
* @param {Object} stylesObject - Existing typeface styles object
|
|
18
|
-
* @param {Object} client - Sanity client
|
|
19
|
-
* @param {Function} setStatus
|
|
20
|
-
* @param {Function} setError
|
|
21
|
-
*/
|
|
22
|
-
export const updateTypefaceDocument = async (
|
|
23
|
-
doc_id,
|
|
24
|
-
fontRefs,
|
|
25
|
-
variableRefs,
|
|
26
|
-
subfamilies,
|
|
27
|
-
uniqueSubfamilies,
|
|
28
|
-
subfamiliesArray,
|
|
29
|
-
preferredStyleRef,
|
|
30
|
-
newPreferredStyle,
|
|
31
|
-
stylesObject,
|
|
32
|
-
client,
|
|
33
|
-
setStatus,
|
|
34
|
-
setError,
|
|
35
|
-
) => {
|
|
36
|
-
console.log('Updating typeface document with new fonts:', { fontRefs, variableRefs, subfamilies, uniqueSubfamilies });
|
|
37
|
-
setStatus('Updating typeface references...');
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
console.log('
|
|
93
|
-
console.log('
|
|
94
|
-
console.log('
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
*
|
|
113
|
-
* @param {string} doc_id
|
|
114
|
-
* @param {Object} preferredStyleRef
|
|
115
|
-
* @param {Object} newPreferredStyle
|
|
116
|
-
* @param {Object} patch
|
|
117
|
-
* @param {Object} client
|
|
118
|
-
*/
|
|
119
|
-
const updatePreferredStyle = async (doc_id, preferredStyleRef, newPreferredStyle, patch, client) => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const publishedId = doc_id.replace('drafts.', '');
|
|
151
|
-
// Parameterized to prevent injection from any draft ID edge cases
|
|
152
|
-
const publishedDoc = await client.fetch(`*[_id == $publishedId]`, { publishedId }).then(res => res[0]);
|
|
153
|
-
|
|
154
|
-
if (publishedDoc) {
|
|
155
|
-
await client.patch(publishedId).set(patch).commit();
|
|
156
|
-
console.log(`Updated published document: ${publishedId}`);
|
|
157
|
-
} else {
|
|
158
|
-
console.log(`No published document found for ${publishedId}, skipping`);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
1
|
+
// Patches the parent typeface document's styles.fonts array with newly uploaded font references
|
|
2
|
+
|
|
3
|
+
import { nanoid } from 'nanoid';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Patches a typeface document (draft and published) with the new font references,
|
|
7
|
+
* subfamily structure, and preferred style derived from the upload batch.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} doc_id - The Sanity document ID (may be a draft)
|
|
10
|
+
* @param {Object[]} fontRefs - New regular font references
|
|
11
|
+
* @param {Object[]} variableRefs - New variable font references
|
|
12
|
+
* @param {Object} subfamilies - Map of font ID → subfamily name
|
|
13
|
+
* @param {string[]} uniqueSubfamilies
|
|
14
|
+
* @param {Object[]} subfamiliesArray - Existing subfamilies array from the typeface
|
|
15
|
+
* @param {Object} preferredStyleRef - Existing preferred style reference
|
|
16
|
+
* @param {Object} newPreferredStyle - Candidate preferred style from the upload
|
|
17
|
+
* @param {Object} stylesObject - Existing typeface styles object
|
|
18
|
+
* @param {Object} client - Sanity client
|
|
19
|
+
* @param {Function} setStatus
|
|
20
|
+
* @param {Function} setError
|
|
21
|
+
*/
|
|
22
|
+
export const updateTypefaceDocument = async (
|
|
23
|
+
doc_id,
|
|
24
|
+
fontRefs,
|
|
25
|
+
variableRefs,
|
|
26
|
+
subfamilies,
|
|
27
|
+
uniqueSubfamilies,
|
|
28
|
+
subfamiliesArray,
|
|
29
|
+
preferredStyleRef,
|
|
30
|
+
newPreferredStyle,
|
|
31
|
+
stylesObject,
|
|
32
|
+
client,
|
|
33
|
+
setStatus,
|
|
34
|
+
setError,
|
|
35
|
+
) => {
|
|
36
|
+
console.log('Updating typeface document with new fonts:', { fontRefs, variableRefs, subfamilies, uniqueSubfamilies });
|
|
37
|
+
setStatus('Updating typeface references...');
|
|
38
|
+
|
|
39
|
+
// Use dot-path keys so .set() does not clobber sibling fields
|
|
40
|
+
// (styles.collections, styles.pairs, styles.free, styles.displayStyles)
|
|
41
|
+
let patch = {
|
|
42
|
+
'styles.fonts': stylesObject.fonts ? [...stylesObject.fonts, ...fontRefs] : [...fontRefs],
|
|
43
|
+
'styles.variableFont': stylesObject?.variableFont ? [...stylesObject.variableFont, ...variableRefs] : [...variableRefs],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
setStatus('Organising font subfamilies...');
|
|
47
|
+
subfamiliesArray = subfamiliesArray || [];
|
|
48
|
+
|
|
49
|
+
// Create any missing subfamily groups
|
|
50
|
+
uniqueSubfamilies.forEach(subfamilyName => {
|
|
51
|
+
if (!subfamiliesArray.find(sf => sf.title === subfamilyName)) {
|
|
52
|
+
subfamiliesArray.push({
|
|
53
|
+
title: subfamilyName,
|
|
54
|
+
_key: nanoid(),
|
|
55
|
+
_type: 'object',
|
|
56
|
+
fonts: [],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Associate fonts with their subfamily groups (skip VF fonts)
|
|
62
|
+
if (subfamiliesArray.length > 0) {
|
|
63
|
+
Object.entries(subfamilies).forEach(([id, subfamilyName]) => {
|
|
64
|
+
if (id.toLowerCase().includes('vf')) return;
|
|
65
|
+
|
|
66
|
+
const subfamilyIndex = subfamiliesArray.findIndex(sf => sf.title === subfamilyName);
|
|
67
|
+
if (subfamilyIndex !== -1) {
|
|
68
|
+
subfamiliesArray[subfamilyIndex].fonts.push({
|
|
69
|
+
_ref: id,
|
|
70
|
+
_key: nanoid(),
|
|
71
|
+
_type: 'reference',
|
|
72
|
+
_weak: true,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Deduplicate references within each subfamily
|
|
78
|
+
subfamiliesArray = subfamiliesArray.map(subfamily => ({
|
|
79
|
+
...subfamily,
|
|
80
|
+
fonts: subfamily.fonts.filter((font, index, self) =>
|
|
81
|
+
index === self.findIndex(f => f._ref === font._ref)
|
|
82
|
+
),
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
patch['styles.subfamilies'] = subfamiliesArray;
|
|
87
|
+
|
|
88
|
+
// Optionally update preferred style
|
|
89
|
+
await updatePreferredStyle(doc_id, preferredStyleRef, newPreferredStyle, patch, client);
|
|
90
|
+
|
|
91
|
+
console.log('doc_id: ', doc_id);
|
|
92
|
+
console.log('Typeface patch: ', patch);
|
|
93
|
+
console.log('New preferred style: ', newPreferredStyle);
|
|
94
|
+
console.log('SubfamiliesArray:', subfamiliesArray);
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
await client.patch(doc_id).set(patch).commit();
|
|
98
|
+
console.log(`Updated document: ${doc_id}`);
|
|
99
|
+
|
|
100
|
+
if (doc_id.startsWith('drafts.')) {
|
|
101
|
+
await updatePublishedDocument(doc_id, patch, client);
|
|
102
|
+
}
|
|
103
|
+
} catch (err) {
|
|
104
|
+
console.error('Error updating document:', err.message);
|
|
105
|
+
setStatus('Error updating typeface');
|
|
106
|
+
setError(true);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Sets preferredStyle on the patch only when currently empty.
|
|
112
|
+
* Does not overwrite an existing preferredStyle — the user's choice is sticky.
|
|
113
|
+
* @param {string} doc_id
|
|
114
|
+
* @param {Object} preferredStyleRef
|
|
115
|
+
* @param {Object} newPreferredStyle
|
|
116
|
+
* @param {Object} patch
|
|
117
|
+
* @param {Object} client
|
|
118
|
+
*/
|
|
119
|
+
const updatePreferredStyle = async (doc_id, preferredStyleRef, newPreferredStyle, patch, client) => {
|
|
120
|
+
const isCurrentlyEmpty = !preferredStyleRef?._ref || preferredStyleRef._ref === '' || preferredStyleRef._ref === null;
|
|
121
|
+
const hasCandidate = newPreferredStyle?._ref && newPreferredStyle._ref !== '';
|
|
122
|
+
|
|
123
|
+
if (isCurrentlyEmpty && hasCandidate) {
|
|
124
|
+
patch.preferredStyle = {
|
|
125
|
+
_type: 'reference',
|
|
126
|
+
_ref: newPreferredStyle._ref,
|
|
127
|
+
_weak: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Applies the same patch to the published document if it exists.
|
|
134
|
+
* @param {string} doc_id - Draft document ID
|
|
135
|
+
* @param {Object} patch
|
|
136
|
+
* @param {Object} client
|
|
137
|
+
*/
|
|
138
|
+
const updatePublishedDocument = async (doc_id, patch, client) => {
|
|
139
|
+
const publishedId = doc_id.replace('drafts.', '');
|
|
140
|
+
// Parameterized to prevent injection from any draft ID edge cases
|
|
141
|
+
const publishedDoc = await client.fetch(`*[_id == $publishedId]`, { publishedId }).then(res => res[0]);
|
|
142
|
+
|
|
143
|
+
if (publishedDoc) {
|
|
144
|
+
await client.patch(publishedId).set(patch).commit();
|
|
145
|
+
console.log(`Updated published document: ${publishedId}`);
|
|
146
|
+
} else {
|
|
147
|
+
console.log(`No published document found for ${publishedId}, skipping`);
|
|
148
|
+
}
|
|
149
|
+
};
|