@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.
Files changed (62) hide show
  1. package/README.md +437 -437
  2. package/dist/UploadModal-6LIX7XOK.js +6 -0
  3. package/dist/UploadModal-NME2W53V.mjs +6 -0
  4. package/dist/chunk-646WCBRR.mjs +7276 -0
  5. package/dist/chunk-FH4QKHOH.js +7276 -0
  6. package/dist/index.js +747 -1675
  7. package/dist/index.mjs +400 -1237
  8. package/package.json +85 -85
  9. package/src/components/BatchUploadFonts.jsx +653 -639
  10. package/src/components/BulkActions.jsx +99 -0
  11. package/src/components/ExistingDocumentResolver.jsx +152 -0
  12. package/src/components/FontReviewCard.jsx +415 -0
  13. package/src/components/FontScriptUploaderComponent.jsx +463 -463
  14. package/src/components/GenerateCollectionsPairsComponent.jsx +259 -259
  15. package/src/components/KeyValueInput.jsx +95 -95
  16. package/src/components/KeyValueReferenceInput.jsx +254 -254
  17. package/src/components/NestedObjectArraySelector.jsx +146 -146
  18. package/src/components/PriceInput.jsx +26 -26
  19. package/src/components/PrimaryCollectionGeneratorTypeface.jsx +116 -116
  20. package/src/components/RegenerateSubfamiliesComponent.jsx +185 -185
  21. package/src/components/SetOTF.jsx +87 -87
  22. package/src/components/SingleUploaderTool.jsx +672 -673
  23. package/src/components/StatusDisplay.jsx +26 -26
  24. package/src/components/StyleCountInput.jsx +16 -16
  25. package/src/components/UpdateScriptsComponent.jsx +76 -76
  26. package/src/components/UploadButton.jsx +43 -43
  27. package/src/components/UploadModal.jsx +268 -0
  28. package/src/components/UploadScriptsComponent.jsx +539 -537
  29. package/src/components/UploadStep1Settings.jsx +272 -0
  30. package/src/components/UploadStep2Review.jsx +472 -0
  31. package/src/components/UploadStep3Execute.jsx +234 -0
  32. package/src/components/UploadSummary.jsx +196 -0
  33. package/src/components/VariableInstanceReferencesInput.jsx +190 -190
  34. package/src/hooks/useNestedObjects.js +92 -92
  35. package/src/hooks/useSanityClient.js +9 -9
  36. package/src/index.js +115 -70
  37. package/src/schema/openTypeField.js +1945 -1945
  38. package/src/schema/styleCountField.js +12 -12
  39. package/src/schema/stylesField.js +268 -268
  40. package/src/schema/stylisticSetField.js +301 -301
  41. package/src/utils/buildUploadPlan.js +325 -0
  42. package/src/utils/executeUploadPlan.js +437 -0
  43. package/src/utils/executionReducer.js +56 -0
  44. package/src/utils/fontHelpers.js +267 -0
  45. package/src/utils/generateCssFile.js +207 -205
  46. package/src/utils/generateFontData.js +98 -145
  47. package/src/utils/generateFontFile.js +38 -38
  48. package/src/utils/generateKeywords.js +185 -185
  49. package/src/utils/generateSubset.js +45 -45
  50. package/src/utils/getEmptyFontKit.js +101 -99
  51. package/src/utils/parseFont.js +55 -0
  52. package/src/utils/parseVariableFontInstances.js +211 -211
  53. package/src/utils/planReducer.js +517 -0
  54. package/src/utils/planTypes.js +183 -0
  55. package/src/utils/processFontFiles.js +529 -477
  56. package/src/utils/regenerateFontData.js +146 -146
  57. package/src/utils/resolveExistingFont.js +87 -0
  58. package/src/utils/sanitizeForSanityId.js +65 -65
  59. package/src/utils/updateFontPrices.js +94 -94
  60. package/src/utils/updateTypefaceDocument.js +149 -160
  61. package/src/utils/uploadFontFiles.js +405 -316
  62. package/src/utils/utils.js +24 -24
@@ -1,145 +1,98 @@
1
- // Extracts metadata, metrics, glyph count, OpenType features, and variable axes from a TTF and optionally patches the Sanity font document
2
-
3
- import { Buffer } from 'buffer';
4
- import * as fontkit from 'fontkit';
5
-
6
- /**
7
- * Extracts metadata and metrics from a fontkit font object into plain objects.
8
- * @param {Object} font - fontkit font instance
9
- * @returns {{ metaData: Object, metrics: Object }}
10
- */
11
- export function buildFontMetadata(font) {
12
- const metaData = {
13
- postscriptName: font.postscriptName,
14
- fullName: font.fullName,
15
- familyName: font.familyName,
16
- subfamilyName: font.subfamilyName,
17
- copyright: font.copyright,
18
- version: font.version ? String(font.version).replaceAll('Version ', '') : '',
19
- genDate: new Date().toISOString(),
20
- };
21
- const metrics = {
22
- unitsPerEm: font.unitsPerEm,
23
- ascender: font.ascent,
24
- descender: font.descent,
25
- lineGap: font.lineGap,
26
- underlinePosition: font.underlinePosition,
27
- underlineThickness: font.underlineThickness,
28
- italicAngle: font.italicAngle,
29
- capHeight: font.capHeight,
30
- xHeight: font.xHeight,
31
- boundingBox: font.bbox,
32
- };
33
- return { metaData, metrics };
34
- }
35
-
36
- export default async function generateFontData({ fileInput, url, fontKit, fontId, client, commit = true }) {
37
- if (fontId.startsWith('drafts.')) {
38
- fontId = fontId.replace('drafts.', '');
39
- }
40
- console.log('generate-font-data ', fontId, commit);
41
-
42
- let srcUrl;
43
- if (!url || url == null) {
44
- srcUrl = await client.fetch(`*[_id == $id]{url}`, { id: fileInput.ttf.asset._ref });
45
- console.log('src url ', srcUrl);
46
- srcUrl = srcUrl[0].url;
47
- } else {
48
- srcUrl = url;
49
- }
50
-
51
- let font = fontKit;
52
- if (!fontKit || fontKit == null) {
53
- let buffer = await fetch(srcUrl);
54
- buffer = await buffer.arrayBuffer();
55
- buffer = Buffer.from(buffer);
56
- font = fontkit.create(buffer);
57
- }
58
-
59
-
60
- let variableAxes;
61
- try {
62
- variableAxes = font.variationAxes;
63
- } catch (err) {
64
- console.error('err: ', err);
65
- }
66
-
67
- let variableInstances;
68
- try {
69
- variableInstances = font.namedVariations;
70
- } catch (e) {
71
- console.log('variable instances 2 error : ', e.message);
72
- let fvar = font?.fvar?.instance;
73
-
74
- fvar?.forEach(fv => {
75
- if (fv?.nameID === 2) fv.name = font?._tables?.name?.records?.fontSubfamily
76
- if (fv?.nameID === 17) fv.name = font?._tables?.name?.records?.preferredSubfamily
77
- })
78
-
79
- variableInstances = {};
80
- fvar.forEach(v => {
81
- let key = v.name;
82
- if (typeof key === 'object') {
83
- key = Object.values(key)[0];
84
- }
85
-
86
- let coordKeys = Object.keys(variableAxes);
87
- let coord = {};
88
-
89
- coordKeys.forEach((ck, ckIndex) => {
90
- coord[ck] = v.coord[ckIndex];
91
- });
92
- variableInstances[key] = coord;
93
- });
94
-
95
- }
96
- console.log('font : ', font);
97
- console.log('variable instances : ', variableInstances);
98
- console.log('variable axes : ', variableAxes);
99
-
100
- let opentypeFeatures = font.availableFeatures;
101
- let glyphCount = font.numGlyphs;
102
- let characterSet = font.characterSet;
103
-
104
- let metaData = {
105
- postscriptName: font.postscriptName,
106
- fullName: font.fullName,
107
- familyName: font.familyName,
108
- subfamilyName: font.subfamilyName,
109
- copyright: font.copyright,
110
- version: font.version.replaceAll("Version ", ""),
111
- genDate: new Date().toISOString(),
112
- };
113
-
114
- let metrics = {
115
- unitsPerEm: font.unitsPerEm,
116
- ascender: font.ascent,
117
- descender: font.descent,
118
- lineGap: font.lineGap,
119
- underlinePosition: font.underlinePosition,
120
- underlineThickness: font.underlineThickness,
121
- italicAngle: font.italicAngle,
122
- capHeight: font.capHeight,
123
- xHeight: font.xHeight,
124
- boundingBox: font.bbox
125
- };
126
-
127
- let variableFont = false;
128
- if (variableAxes && variableAxes != null && Object.keys(variableAxes).length > 0 && variableInstances && variableInstances != null && Object.keys(variableInstances).length > 0) {
129
- variableFont = true;
130
- }
131
- let patch = {
132
- metrics: metrics,
133
- metaData: metaData,
134
- variableFont: variableFont,
135
- variableAxes: JSON.stringify(variableAxes),
136
- variableInstances: JSON.stringify(variableInstances),
137
- glyphCount: glyphCount,
138
- opentypeFeatures: { chars: opentypeFeatures },
139
- characterSet: { chars: characterSet }
140
- }
141
-
142
- console.log('data : ', patch);
143
- if (commit) patch = await client.patch(fontId).set(patch).commit({ autoGenerateArrayKeys: true });
144
- return patch;
145
- }
1
+ // Extracts metadata, metrics, glyph count, OpenType features, and variable axes from a font and optionally patches the Sanity font document
2
+
3
+ import { parseFont } from './parseFont';
4
+ import {
5
+ getFontMetadata,
6
+ getFontMetrics,
7
+ getVariationAxes,
8
+ getNamedInstances,
9
+ getAllFeatureTags,
10
+ getGlyphCount,
11
+ getCharacterSet,
12
+ getNameString,
13
+ } from './fontHelpers';
14
+
15
+ /**
16
+ * Extracts metadata and metrics from a lib-font parsed font into plain objects.
17
+ * Uses fontHelpers for all table access — no direct font.opentype.tables usage here.
18
+ * @param {object} font - lib-font Font instance
19
+ * @returns {{ metaData: Object, metrics: Object }}
20
+ */
21
+ export function buildFontMetadata(font) {
22
+ const metaData = getFontMetadata(font);
23
+ // Strip "Version " prefix for consistency with existing Sanity documents
24
+ if (metaData.version) {
25
+ metaData.version = String(metaData.version).replaceAll('Version ', '');
26
+ }
27
+ const metrics = getFontMetrics(font);
28
+ return { metaData, metrics };
29
+ }
30
+
31
+ export default async function generateFontData({ fileInput, url, fontKit, fontId, client, commit = true }) {
32
+ if (fontId.startsWith('drafts.')) {
33
+ fontId = fontId.replace('drafts.', '');
34
+ }
35
+ console.log('Generate font data:', fontId, commit);
36
+
37
+ let srcUrl;
38
+ if (!url || url == null) {
39
+ srcUrl = await client.fetch(`*[_id == $id]{url}`, { id: fileInput.ttf.asset._ref });
40
+ srcUrl = srcUrl[0].url;
41
+ } else {
42
+ srcUrl = url;
43
+ }
44
+
45
+ let font = fontKit;
46
+ if (!fontKit || fontKit == null) {
47
+ let buffer = await fetch(srcUrl);
48
+ buffer = await buffer.arrayBuffer();
49
+ font = await parseFont(buffer, `${fontId}.ttf`);
50
+ }
51
+
52
+ const variableAxes = getVariationAxes(font);
53
+ const namedInstances = getNamedInstances(font);
54
+
55
+ // Build variableInstances as a keyed object matching existing Sanity document shape
56
+ let variableInstances = null;
57
+ if (namedInstances.length > 0 && variableAxes) {
58
+ variableInstances = {};
59
+ const axisTags = Object.keys(variableAxes);
60
+ for (const inst of namedInstances) {
61
+ const key = inst.name || inst.postScriptName || 'Unknown';
62
+ const coord = {};
63
+ axisTags.forEach((tag, index) => {
64
+ coord[tag] = inst.coordinates[index];
65
+ });
66
+ variableInstances[key] = coord;
67
+ }
68
+ }
69
+
70
+ console.log('Variable instances:', variableInstances);
71
+ console.log('Variable axes:', variableAxes);
72
+
73
+ const opentypeFeatures = getAllFeatureTags(font);
74
+ const glyphCount = getGlyphCount(font);
75
+ const characterSet = getCharacterSet(font);
76
+
77
+ const { metaData, metrics } = buildFontMetadata(font);
78
+
79
+ let variableFont = false;
80
+ if (variableAxes && variableInstances && Object.keys(variableInstances).length > 0) {
81
+ variableFont = true;
82
+ }
83
+
84
+ let patch = {
85
+ metrics: metrics,
86
+ metaData: metaData,
87
+ variableFont: variableFont,
88
+ variableAxes: JSON.stringify(variableAxes),
89
+ variableInstances: JSON.stringify(variableInstances),
90
+ glyphCount: glyphCount,
91
+ opentypeFeatures: { chars: opentypeFeatures },
92
+ characterSet: { chars: characterSet },
93
+ };
94
+
95
+ console.log('Font data patch:', Object.keys(patch));
96
+ if (commit) patch = await client.patch(fontId).set(patch).commit({ autoGenerateArrayKeys: true });
97
+ return patch;
98
+ }
@@ -1,38 +1,38 @@
1
- // Triggers server-side font format conversion via the consuming site's fontWorker API endpoint
2
-
3
- export default async function generateFontFile({
4
- srcUrl,
5
- language = null,
6
- filename,
7
- codes,
8
- documentId,
9
- documentTitle,
10
- documentVariableFont,
11
- documentStyle,
12
- documentWeight,
13
- fileInput
14
- }) {
15
- await fetch(`${process.env.SANITY_STUDIO_SITE_URL}/api/sanity/fontWorker`, {
16
- method: 'POST',
17
- mode: 'no-cors',
18
- headers: { 'Content-Type': 'application/json' },
19
- body: JSON.stringify({
20
- code: 'generate-fonts',
21
- language: language,
22
- srcUrl: srcUrl,
23
- filename: filename,
24
- documentId: documentId,
25
- documentTitle: documentTitle,
26
- documentVariableFont: documentVariableFont,
27
- documentStyle: documentStyle,
28
- documentWeight: documentWeight,
29
- fileInput: fileInput,
30
- codes: codes
31
- })
32
- }).catch(e => {
33
- console.error(e.message);
34
- return -1;
35
- });
36
- return 1;
37
-
38
- }
1
+ // Triggers server-side font format conversion via the consuming site's fontWorker API endpoint
2
+
3
+ export default async function generateFontFile({
4
+ srcUrl,
5
+ language = null,
6
+ filename,
7
+ codes,
8
+ documentId,
9
+ documentTitle,
10
+ documentVariableFont,
11
+ documentStyle,
12
+ documentWeight,
13
+ fileInput
14
+ }) {
15
+ await fetch(`${process.env.SANITY_STUDIO_SITE_URL}/api/sanity/fontWorker`, {
16
+ method: 'POST',
17
+ mode: 'no-cors',
18
+ headers: { 'Content-Type': 'application/json' },
19
+ body: JSON.stringify({
20
+ code: 'generate-fonts',
21
+ language: language,
22
+ srcUrl: srcUrl,
23
+ filename: filename,
24
+ documentId: documentId,
25
+ documentTitle: documentTitle,
26
+ documentVariableFont: documentVariableFont,
27
+ documentStyle: documentStyle,
28
+ documentWeight: documentWeight,
29
+ fileInput: fileInput,
30
+ codes: codes
31
+ })
32
+ }).catch(e => {
33
+ console.error(e.message);
34
+ return -1;
35
+ });
36
+ return 1;
37
+
38
+ }