import { createUnplugin } from 'unplugin'
import * as THREE from 'three'
import fs from 'fs'
import { join } from 'pathe'
export const unplugin = createUnplugin(() => {
return {
name: 'unplugin-tres',
apply: 'build',
configResolved(config) {
// Check if the output directory exists, if not create it
const outputDir = join(config.root, 'src/types')
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir)
}
const typeDefs = `
import type { DefineComponent } from 'vue'
import type { Vector2, Vector3, Color } from 'three'
export type TresVectorProp = Vector2 | Vector3 | number[] | number
export type TresColor = string | number | Color | number[]
import type {
Mesh,
${Object.keys(THREE)
.filter(
key =>
key.endsWith('Geometry') ||
key.endsWith('Material') ||
key.endsWith('Helper') ||
key.endsWith('Light') ||
key.endsWith('Camera'),
)
.join(',\n')}
} from 'three';
type OverwrittenProps = 'position' | 'rotation' | 'scale' | 'color'
type TresModifiedObject = {
/**
* A Vector3 | Array | scalar representing the object's local position. Default is (0, 0, 0).
*
* @type {TresVectorProp}
*/
position: TresVectorProp
/**
* A Vector3 | Array | scalar representing the object's local rotation. Default is (0, 0, 0).
*
* @type {TresVectorProp}
*/
rotation: TresVectorProp
/**
* A Vector3 | Array | scalar representing the object's local scale. Default is (0, 0, 0).
*
* @type {TresVectorProp}
*/
scale: TresVectorProp
/**
* Color of the material, by default set to white (0xffffff).
*
* @type {TresColor}
*/
color: TresColor,
/**
* Arguments of the THREE instance, by default set to empty array.
*
* @type {any[]}
*
* @example
*
* \`\`\`html
* // BoxGeometry(1, 3, 4)
* \`\`\`
*/
args?: any[],
}
declare module 'vue' {
export interface GlobalComponents {
TresMesh: DefineComponent & TresModifiedObject>>
${Object.keys(THREE)
.filter(key => key.endsWith('Geometry'))
.map(
key =>
`Tres${key}: DefineComponent & TresModifiedObject>>`,
)
.join('\n')}
${Object.keys(THREE)
.filter(
key =>
key.endsWith('Geometry') ||
key.endsWith('Material') ||
key.endsWith('Helper') ||
key.endsWith('Light') ||
key.endsWith('Camera'),
)
.map(key => `Tres${key}: DefineComponent & TresModifiedObject>>`)
.join('\n')}
}
}
`
fs.writeFileSync(join(outputDir, 'tres-components.d.ts'), typeDefs)
},
}
})
export const ViteTresPlugin = unplugin.vite