mono/packages/commons/src/component.ts
2025-03-21 00:53:11 +01:00

257 lines
7.4 KiB
TypeScript

import * as path from 'path'
import { z } from "zod"
import normalizeUrl from 'normalize-url'
import { isInvalidMarketplaceComponent, isValidLibraryComponent, isValidMarketplaceComponent, PFilterInvalid, PFilterValid } from './filter.js'
import { forward_slash, pathInfoEx } from './fs/_glob.js'
import { resolve } from './variables.js'
import { readOSRConfig } from './config.js'
const IMAGES_GLOB = '*.+(JPG|jpg|png|PNG|gif)'
export const find_items = (nodes: string[], options) => {
nodes = nodes.filter(options.filter)
return nodes.map((c) => {
const root = resolve(options.root, false, {})
return {
rel: forward_slash(`${path.relative(root, path.parse(c).dir)}`),
path: forward_slash(`${options.root}/${path.relative(root, c)}`),
config: readOSRConfig(c)
}
})
}
export const get = (src, root, type): IComponentNode[] => {
const srcInfo = pathInfoEx(src, false, {
absolute: true
})
switch (type) {
case PFilterValid.marketplace_component: {
const options = {
filter: isValidMarketplaceComponent,
root
}
return find_items(srcInfo.FILES, options)
}
case PFilterValid.library_component: {
const options = {
filter: isValidLibraryComponent,
root
}
return find_items(srcInfo.FILES, options)
}
case PFilterInvalid.marketplace_component: {
const options = {
filter: isInvalidMarketplaceComponent,
root
}
return find_items(srcInfo.FILES, options)
}
}
}
export const UrlSchema = z.string().url().transform((arg) => normalizeUrl(arg))
export const ExifSchema = z.object({
file: z.any(), // Assuming File is another schema or any type
jfif: z.any(), // Assuming Jfif is another schema or any type
exif: z.any(), // Assuming Exif2 is another schema or any type
gps: z.any() // Assuming Gps is another schema or any type
});
export const ImageMetaSchema = z.object({
format: z.string(),
width: z.number(),
height: z.number(),
space: z.string(),
channels: z.number(),
depth: z.string(),
density: z.number(),
chromaSubsampling: z.string(),
isProgressive: z.boolean(),
resolutionUnit: z.string(),
hasProfile: z.boolean(),
hasAlpha: z.boolean(),
orientation: z.number(),
exif: z.any() // Assuming Exif is another schema or any type
});
export const CADMetaSchema = z.object({
file: z.string(),
name: z.string(),
configuration: z.string(), // solidworks map
step: z.string().optional(),
model: z.string().optional(),
html: z.string().optional(),
})
export const ShippingSchema = z.object({
price: z.number().optional(),
transit: z.number().optional(),
handling: z.number().optional()
})
export const ManufacturingSchema = z.object({
lead_time: z.number().optional()
})
export const ResourceSchema = z.object({
name: z.string(),
url: z.string(),
type: z.string()
})
export const AssetImageSchema = z.object({
name: z.string().optional(),
url: z.string(),
thumb: z.string().optional(),
responsive: z.string().optional(),
meta: z.any().optional(),
keywords: z.array(z.string()).optional(),
description: z.string().optional(),
alt: z.string().optional(),
title: z.string().optional(),
height: z.number().optional(),
width: z.number().optional(),
order: z.number().optional(),
exif: ExifSchema.optional(),
})
export const GalleryConfig = z.object({
glob: z.array(z.string())
})
export const GalleryConfigsSchema = z.record(GalleryConfig)
export const AuthorSchema = z.object({
name: z.string(),
url: z.string(),
})
export const ContentSchema = z.object({
body: z.string().optional(),
features: z.string().optional(),
highlights: z.string().optional(),
specs: z.string().optional(),
license: z.string().optional(),
resources: z.string().optional(),
readme: z.string().optional(),
shared: z.string().optional()
})
export const VersionSchema = z.object({
version: z.string().optional(),
up: z.string().optional(),
down: z.string().optional(),
family: z.string().optional(),
sheet: z.string().optional()
})
export const AssetsSchema = z.object({
gallery: z.array(AssetImageSchema).optional(),
renderings: z.array(AssetImageSchema).optional(),
components: z.array(AssetImageSchema).optional(),
configurations: z.array(AssetImageSchema).optional(),
showcase: z.array(AssetImageSchema).optional(),
samples: z.array(AssetImageSchema).optional()
})
export const ProductionSchema = z.object({
"fusion-folder": z.string(),
"nc-folder": z.string(),
cam: z.array(AuthorSchema)
})
export const ComponentConfigSchema = z.object({
// shop
cart_id: z.string().optional(),
code: z.string(),
price: z.number().optional(),
cscartCats: z.array(z.number()).optional(),
cscartId: z.number().optional(),
vendorId: z.number().optional(),
shipping: ShippingSchema.optional().default({
price: 0,
transit: 12,
handling: 2
}),
// references
replaced_by: z.string().optional(),
alternatives: z.array(ResourceSchema).optional(),
used_by: z.array(ResourceSchema).optional(),
image: AssetImageSchema.optional(),
name: z.string(),
// cad
edrawings: z.string().optional(),
cad: z.array(CADMetaSchema).default([]),
manufacturing: ManufacturingSchema,
// settings
showDimensions: z.boolean().optional(),
showParts: z.boolean().optional(),
Preview3d: z.boolean().optional(),
flags: z.number().optional().default(0),
// meta
slug: z.string(),
keywords: z.string().optional(),
meta_keywords: z.string().optional(),
version: z.string().optional(),
versions: VersionSchema.optional(),
status: z.string().optional(),
authors: z.array(AuthorSchema).optional(),
// content
assets: AssetsSchema.default({
gallery: [],
renderings: [],
components: [],
configurations: [],
showcase: [],
samples: []
}),
resources: z.array(ResourceSchema).default([]),
tests: z.array(ResourceSchema).default([]),
download: z.boolean().optional(),
// galleries
gallery: GalleryConfigsSchema.default({}).default(Object.fromEntries(
["renderings", "gallery", "components", "configurations", "showcase", "samples"].map(key => [key, { glob: [IMAGES_GLOB] }])
)),
// nesting
components: z.array(z.lazy(() => ComponentConfigSchema)).optional().default([]),
// @deprecated
howto_categories: z.union([z.string(), z.array(z.string())]).optional(),
steps: z.any().optional(),
sourceLanguage: z.string().optional(),
category: z.string(),
product_dimensions: z.string().optional(),
production: ProductionSchema.optional(),
score: z.number().optional()
}).merge(ContentSchema).passthrough()
export type IComponentConfig = z.infer<typeof ComponentConfigSchema>
export type ICADNodeSchema = z.infer<typeof CADMetaSchema>
export interface IComponentNode {
rel: string
path: string
config: IComponentConfig
}