@newlogic-digital/core 4.1.6 → 4.1.7

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/index.js CHANGED
@@ -12,6 +12,7 @@ import heroicons from '@newlogic-digital/vite-plugin-heroicons'
12
12
  import { fileURLToPath } from 'node:url'
13
13
  import { processPostcssCustomProperties } from './src/postcssCustomProperties.js'
14
14
  import { fontsManifest } from './src/fontsManifest.js'
15
+ import { createCustomProvider } from './src/fontsCustomProvider.js'
15
16
  import { createLogger } from 'vite'
16
17
  import console from 'node:console'
17
18
 
@@ -78,6 +79,7 @@ const defaultOptions = {
78
79
  tailwindcss: {},
79
80
  send: {},
80
81
  fontless: {
82
+ customProvider: undefined,
81
83
  options: undefined,
82
84
  manifest: undefined,
83
85
  },
@@ -137,6 +139,11 @@ const plugin = async (options = {}) => {
137
139
  if (options.fontless?.options) {
138
140
  const { fontless } = await import('fontless')
139
141
 
142
+ if (Array.isArray(options.fontless.customProvider) && options.fontless.customProvider.length > 0) {
143
+ options.fontless.options.providers ??= {}
144
+ options.fontless.options.providers.custom = createCustomProvider(options.fontless.customProvider)
145
+ }
146
+
140
147
  optionalPlugins.push(fontless(options.fontless.options), fontsManifest(options.fontless.manifest))
141
148
  }
142
149
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@newlogic-digital/core",
3
3
  "type": "module",
4
- "version": "4.1.6",
4
+ "version": "4.1.7",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "newlogic-core": "./bin/newlogic-core.js"
@@ -27,8 +27,8 @@
27
27
  "browserslist": "^4.28.2",
28
28
  "browserslist-to-esbuild": "^2.1.1",
29
29
  "lightningcss": "^1.32.0",
30
- "npm-check-updates": "^22.2.0",
31
- "oxlint": "^1.66.0",
30
+ "npm-check-updates": "^22.2.3",
31
+ "oxlint": "^1.70.0",
32
32
  "postcss-custom-properties": "^15.0.1",
33
33
  "stylelint-config-standard": "^40.0.0",
34
34
  "vituum": "^2.0.2"
@@ -51,11 +51,11 @@
51
51
  }
52
52
  },
53
53
  "devDependencies": {
54
- "@tailwindcss/vite": "^4.3.0",
54
+ "@tailwindcss/vite": "^4.3.1",
55
55
  "@types/node": "^25.9",
56
56
  "@vituum/vite-plugin-twig": "^2.0.1",
57
57
  "fontless": "^0.2.1",
58
- "rolldown": "^1.0.2",
58
+ "rolldown": "^1.1.1",
59
59
  "typescript": "^6"
60
60
  },
61
61
  "files": [
@@ -0,0 +1,59 @@
1
+ import { readFileSync } from 'node:fs'
2
+ import { resolve } from 'node:path'
3
+ import process from 'node:process'
4
+ import { defineFontProvider } from 'unifont'
5
+
6
+ /**
7
+ * File extension → CSS format() + MIME for the data URL
8
+ *
9
+ * @type {Record<string, { format: string, mime: string }>}
10
+ */
11
+ const fontFormats = {
12
+ woff2: { format: 'woff2', mime: 'font/woff2' },
13
+ woff: { format: 'woff', mime: 'font/woff' },
14
+ ttf: { format: 'truetype', mime: 'font/ttf' },
15
+ otf: { format: 'opentype', mime: 'font/otf' },
16
+ }
17
+
18
+ /**
19
+ * Reads a font file and returns it as a base64 data URL
20
+ *
21
+ * @param {string} src - font path relative to process.cwd()
22
+ * @returns {{ url: string, format: string }}
23
+ */
24
+ const fontSource = (src) => {
25
+ const extension = src.split('.').pop()?.toLowerCase() ?? ''
26
+ const type = fontFormats[extension]
27
+
28
+ if (!type) {
29
+ throw new Error(`[fontless] Unsupported font extension "${extension}" (${src}). Supported: ${Object.keys(fontFormats).join(', ')}`)
30
+ }
31
+
32
+ const data = readFileSync(resolve(process.cwd(), src)).toString('base64')
33
+
34
+ return { url: `data:${type.mime};base64,${data}`, format: type.format }
35
+ }
36
+
37
+ /**
38
+ * Builds the "custom" unifont provider that base64-inlines the local fonts
39
+ * defined by the `customProvider` array in the fontless configuration
40
+ *
41
+ * @param {Array<{ name: string, fonts: Array<{ src: string, weight?: number | string, style?: string }> }>} entries
42
+ * @returns {import('unifont').ProviderFactory<'custom'>}
43
+ */
44
+ export const createCustomProvider = entries =>
45
+ /** @type {import('unifont').ProviderFactory<'custom'>} */ (defineFontProvider('custom', () => ({
46
+ resolveFont(family) {
47
+ const entry = entries.find(item => item.name === family)
48
+
49
+ if (!entry) return
50
+
51
+ return {
52
+ fonts: entry.fonts.map(font => ({
53
+ src: [fontSource(font.src)],
54
+ weight: font.weight,
55
+ style: font.style,
56
+ })),
57
+ }
58
+ },
59
+ })))
@@ -82,9 +82,10 @@ export const fontsManifest = families => ({
82
82
  if (fonts.length === 0) continue
83
83
 
84
84
  entry.assets = [...new Set([...entry.assets ?? [], ...fonts.map(font => font.file)])]
85
- // rodina → subset → pole souborů; umožňuje preloadovat jen vybrané rodiny a subsety
85
+ // family → subset → array of files; allows preloading only selected families and subsets.
86
+ // Fonts without a detectable subset (e.g. non-subsetted local fonts) fall back to the 'default' key.
86
87
  entry.fonts = fonts.reduce((acc, font) => {
87
- if (font.family && font.subset) ((acc[font.family] ??= {})[font.subset] ??= []).push(font.file)
88
+ if (font.family) ((acc[font.family] ??= {})[font.subset ?? 'default'] ??= []).push(font.file)
88
89
  return acc
89
90
  }, {})
90
91
  hasFonts = true
package/types/index.d.ts CHANGED
@@ -16,6 +16,14 @@ export interface PluginUserConfig {
16
16
  send?: import('@vituum/vite-plugin-send').PluginUserConfig
17
17
  tailwindcss?: import('@tailwindcss/vite').PluginOptions
18
18
  fontless?: {
19
+ customProvider?: Array<{
20
+ name: string
21
+ fonts: Array<{
22
+ src: string
23
+ weight?: number | string
24
+ style?: string
25
+ }>
26
+ }>
19
27
  options?: import('fontless').FontlessOptions
20
28
  manifest?: string[]
21
29
  }