forked from Oky-period-tracker/periodtracker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidateImages.ts
148 lines (115 loc) · 3.94 KB
/
validateImages.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
import * as fs from 'fs-extra'
import * as path from 'path'
// README: Sharp package caused errors in the Docker environment, so it is not installed as a dependency in the package.json, it is instead installed when you run the yarn script that executes this file.
// This means that the package.json will be updated with the sharp package, do not commit this change.
// @ts-ignore
import sharp from 'sharp'
const assetsFolder = './packages/components/src/assets'
const logger = (...values) => {
console.log(...values) // tslint:disable-line
}
async function generatePathsMapping() {
const filePath = `${assetsFolder}/index.ts`
const outputPath = `${assetsFolder}/paths.ts`
let content = await fs.readFile(filePath, 'utf8')
content = content.replace(/require\((['"])(.+?)\1\)/g, "'$2'")
const importStatement = `import { AppAssets } from '@oky/core'`
const exportStatement = `export const assets: AppAssets`
content = content.replace(
importStatement,
'// THIS FILE IS AUTO GENERATED, DO NOT EDIT IT MANUALLY',
)
content = content.replace(exportStatement, 'export const assetsPaths')
await fs.writeFile(outputPath, content, 'utf8')
}
const allowedExts = ['.png', '.jpg']
const getPathMetadata = async (filePath: string) => {
const ext = path.extname(filePath)
if (!allowedExts.includes(ext)) {
return undefined
}
const absolutePath = path.join(assetsFolder, filePath.substring(1))
const image = sharp(absolutePath)
const metadata = await image.metadata()
const stats = await fs.statSync(absolutePath)
return {
path: filePath,
format: metadata.format,
width: metadata.width,
height: metadata.height,
size: stats.size,
}
}
const getMetadata = async (obj) => {
const output = {}
for (const [key, value] of Object.entries(obj)) {
output[key] = value
if (typeof value === 'string') {
output[key] = await getPathMetadata(value)
}
if (typeof value === 'object') {
output[key] = await getMetadata(value)
}
}
return output
}
const generateMetadata = async () => {
const assetPathsFile = require(`${assetsFolder}/paths`)
const data = await getMetadata(assetPathsFile.assetsPaths)
const content = `
// THIS FILE IS AUTO GENERATED, DO NOT EDIT IT MANUALLY
export const metaData = ${JSON.stringify(data)}`
await fs.writeFile(`${assetsFolder}/metaData.ts`, content, 'utf8')
}
const isWithinTolerance = (a: number, b: number, percentage: number = 0.1) => {
const tolerance = a * percentage
return Math.abs(a - b) <= tolerance
}
const compareMetadata = () => {
const coreMetaDataFile = require(`./metaData`)
const assetsMetaDataFile = require(`${assetsFolder}/metaData`)
const coreData = coreMetaDataFile.metaData
const metaData = assetsMetaDataFile.metaData
;['avatars', 'backgrounds'].forEach((dataKey) => {
Object.values(metaData[dataKey]).forEach((item) => {
Object.entries(item).forEach(([imageKey, image]) => {
if (!image.path) {
return
}
Object.entries(image).forEach(([key, value]) => {
if (typeof value !== 'number') {
return
}
if (!coreData[dataKey][imageKey]) {
return
}
const coreValue = coreData[dataKey][imageKey][key]
if (!coreValue) {
return
}
if (key === 'size') {
if (value > coreValue) {
logMismatch(key, value, coreValue, image.path)
}
return
}
if (!isWithinTolerance(value, coreValue)) {
logMismatch(key, value, coreValue, image.path)
}
})
})
})
})
}
const logMismatch = (key, value, coreValue, filePath) => {
logger(`WARNING: Image ${key} mismatch`, filePath)
logger(`Expected ${key}: ${coreValue}`)
logger(`Actual ${key}: ${value}`)
logger(`\n`)
}
async function validateAssets() {
await generatePathsMapping()
await generateMetadata()
compareMetadata()
}
validateAssets()