257 lines
7.4 KiB
TypeScript
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
|
|
}
|
|
|