@payfit/unity-illustrations 2.21.15 → 2.22.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payfit/unity-illustrations",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"module": "./dist/esm/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@payfit/hr-app-eslint": "0.0.0-use.local",
|
|
40
40
|
"@payfit/hr-apps-tsconfigs": "0.0.0-use.local",
|
|
41
41
|
"@payfit/storybook-config": "0.0.0-use.local",
|
|
42
|
-
"@payfit/unity-themes": "2.
|
|
42
|
+
"@payfit/unity-themes": "2.22.0",
|
|
43
43
|
"@payfit/vite-configs": "0.0.0-use.local",
|
|
44
44
|
"@storybook/addon-a11y": "10.3.3",
|
|
45
45
|
"@storybook/addon-docs": "10.3.3",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"vite": "7.1.12"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@payfit/unity-themes": "2.
|
|
61
|
+
"@payfit/unity-themes": "2.22.0",
|
|
62
62
|
"react": "18.3.1",
|
|
63
63
|
"react-dom": "18.3.1"
|
|
64
64
|
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs'
|
|
1
2
|
import fs from 'fs/promises'
|
|
2
3
|
import path from 'path'
|
|
3
4
|
|
|
4
5
|
import type { Config } from 'svgo'
|
|
5
6
|
|
|
7
|
+
import type { ValidationEntry } from '../../scripts/shared/validate-size'
|
|
8
|
+
import type { SizeGuardrailsConfig } from '../../scripts/steps/download-assets'
|
|
9
|
+
|
|
6
10
|
import imageSize from 'image-size'
|
|
7
11
|
import { loadConfig, optimize } from 'svgo'
|
|
8
12
|
|
|
13
|
+
import {
|
|
14
|
+
parseSvgWidth,
|
|
15
|
+
reportViolations,
|
|
16
|
+
} from '../../scripts/shared/validate-size'
|
|
9
17
|
import { generateAssetModule } from './templates/assetTemplate'
|
|
10
18
|
import { generateBaseTypes } from './templates/baseTypes'
|
|
11
19
|
import { generateIndexFile } from './templates/indexTemplate'
|
|
@@ -15,6 +23,7 @@ const illustrationsSvgDir = path.resolve('./assets/')
|
|
|
15
23
|
const srcRoot = path.resolve('./src')
|
|
16
24
|
const outputDir = path.join(srcRoot, 'generated')
|
|
17
25
|
const assetsOutputDir = path.join(outputDir, 'assets') // Optimized assets go here
|
|
26
|
+
const configPath = path.resolve('./.figma-sync.json')
|
|
18
27
|
|
|
19
28
|
const verboseFromArg = process.argv.some(
|
|
20
29
|
arg => arg === '--verbose' || arg === '-v',
|
|
@@ -226,6 +235,24 @@ async function processAsset(assetPath: string) {
|
|
|
226
235
|
}
|
|
227
236
|
}
|
|
228
237
|
|
|
238
|
+
function loadSizeGuardrails(): SizeGuardrailsConfig | undefined {
|
|
239
|
+
if (!existsSync(configPath)) {
|
|
240
|
+
console.log('ℹ️ No .figma-sync.json found, skipping size guardrails')
|
|
241
|
+
return undefined
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8')) as {
|
|
245
|
+
sizeGuardrails?: SizeGuardrailsConfig
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!config.sizeGuardrails) {
|
|
249
|
+
console.log('ℹ️ No sizeGuardrails config, skipping size validation')
|
|
250
|
+
return undefined
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return config.sizeGuardrails
|
|
254
|
+
}
|
|
255
|
+
|
|
229
256
|
async function main() {
|
|
230
257
|
console.log('🎨 Generating and optimizing illustration assets...')
|
|
231
258
|
if (isVerbose) {
|
|
@@ -241,6 +268,11 @@ async function main() {
|
|
|
241
268
|
await fs.writeFile(path.join(outputDir, 'types.ts'), baseTypesContent, 'utf8')
|
|
242
269
|
verboseLog('✅ Generated base types')
|
|
243
270
|
|
|
271
|
+
// Load size guardrails config
|
|
272
|
+
const sizeGuardrails = loadSizeGuardrails()
|
|
273
|
+
const violations: ValidationEntry[] = []
|
|
274
|
+
const warnings: ValidationEntry[] = []
|
|
275
|
+
|
|
244
276
|
// Discover all asset files
|
|
245
277
|
const assetFiles = await getAllAssetFiles(illustrationsSvgDir)
|
|
246
278
|
console.log(`🔍 Found ${assetFiles.length} assets to process`)
|
|
@@ -256,6 +288,57 @@ async function main() {
|
|
|
256
288
|
try {
|
|
257
289
|
const component = await processAsset(assetPath)
|
|
258
290
|
|
|
291
|
+
// Validate optimized SVG against size guardrails
|
|
292
|
+
if (sizeGuardrails && component.type === 'svg') {
|
|
293
|
+
const optimizedContent = await fs.readFile(
|
|
294
|
+
component.optimizedPath,
|
|
295
|
+
'utf8',
|
|
296
|
+
)
|
|
297
|
+
const optimizedSize = optimizedContent.length
|
|
298
|
+
const width = parseSvgWidth(optimizedContent)
|
|
299
|
+
|
|
300
|
+
const exceedsFileSize = optimizedSize > sizeGuardrails.maxFileSize
|
|
301
|
+
const exceedsWidth =
|
|
302
|
+
width !== undefined && width > sizeGuardrails.maxWidth
|
|
303
|
+
const isAllowlisted = sizeGuardrails.allowlist.includes(
|
|
304
|
+
component.originalFileName,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
if (exceedsFileSize || exceedsWidth) {
|
|
308
|
+
const details: string[] = []
|
|
309
|
+
if (exceedsFileSize) {
|
|
310
|
+
details.push(
|
|
311
|
+
`${(optimizedSize / 1024).toFixed(1)}KB after SVGO (limit: ${(
|
|
312
|
+
sizeGuardrails.maxFileSize / 1024
|
|
313
|
+
).toFixed(0)}KB)`,
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
if (exceedsWidth) {
|
|
317
|
+
details.push(
|
|
318
|
+
`${width}px width (limit: ${sizeGuardrails.maxWidth}px)`,
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const detailStr = details.join('; ')
|
|
323
|
+
|
|
324
|
+
if (isAllowlisted) {
|
|
325
|
+
const msg = `${component.originalFileName}: ${detailStr}. Consider simplifying this illustration in Figma.`
|
|
326
|
+
warnings.push({
|
|
327
|
+
filename: component.originalFileName,
|
|
328
|
+
message: msg,
|
|
329
|
+
})
|
|
330
|
+
console.warn(` ⚠️ [Allowlisted] ${msg}`)
|
|
331
|
+
} else {
|
|
332
|
+
const msg = `${component.originalFileName}: ${detailStr}. Automatic optimization could not reduce below limit — simplify in Figma.`
|
|
333
|
+
violations.push({
|
|
334
|
+
filename: component.originalFileName,
|
|
335
|
+
message: msg,
|
|
336
|
+
})
|
|
337
|
+
console.error(` ❌ ${msg}`)
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
259
342
|
// Generate individual asset module
|
|
260
343
|
const moduleContent = generateAssetModule(
|
|
261
344
|
component.name,
|
|
@@ -338,6 +421,11 @@ async function main() {
|
|
|
338
421
|
console.log(
|
|
339
422
|
` - Total Animated: ${components.filter(c => c.animated).length}`,
|
|
340
423
|
)
|
|
424
|
+
|
|
425
|
+
// Report size guardrail results
|
|
426
|
+
if (sizeGuardrails) {
|
|
427
|
+
reportViolations(violations, warnings, sizeGuardrails.strict)
|
|
428
|
+
}
|
|
341
429
|
}
|
|
342
430
|
|
|
343
431
|
main().catch((err: unknown) => {
|