diff --git a/apps/studio/src/api.ts b/apps/studio/src/api.ts index 1633832c..af39e931 100644 --- a/apps/studio/src/api.ts +++ b/apps/studio/src/api.ts @@ -58,8 +58,18 @@ export const router = t.router({ .input(z.object({ workspace: workspaceConfigSchema })) .mutation(async function addWorkspace(opts) { const { workspace } = opts.input + + const workspacePath = workspace.path + const workspaceProductsPath = join(workspacePath, 'products') + await mkdir(workspaceProductsPath, { recursive: true }) + + // TODO create villagekit.toml file + // [workspace] + // products = "products/*" + const config = await loadAppConfig() config.workspaces.push(workspace) + await saveAppConfig(config) }), removeWorkspace: t.procedure @@ -75,6 +85,9 @@ export const router = t.router({ .output(z.array(productIndexSchema)) .query(async function listProduct(opts) { const { workspacePath } = opts.input + + // TODO lookup villagekit.toml to get workspace products path matcher + const workspaceProductsPath = join(workspacePath, 'products') const products = [] const dirEntries = await readdir(workspaceProductsPath) @@ -87,6 +100,9 @@ export const router = t.router({ } return products }), + + // TODO createProduct({ productPath, productMeta }) + getProductMeta: t.procedure .input(z.object({ productPath: productPathSchema })) .query(async function getProductMeta(opts) { @@ -97,6 +113,14 @@ export const router = t.router({ const productMeta = productMetaFile.product return productMeta }), + putProductMeta: t.procedure + .input(z.object({ productPath: productPathSchema, productMeta: productMetaSchema })) + .mutation(async function getProductMeta(opts) { + const { productPath, productMeta } = opts.input + const productMetaPath = join(productPath, 'villagekit.toml') + const productMetaFile = { product: productMeta } + await writeTomlFile(productMetaPath, productMetaFile) + }), getProductFile: t.procedure .input(z.object({ productPath: productPathSchema, filePath: pathSchema })) @@ -106,6 +130,13 @@ export const router = t.router({ const fileData = await readFile(productFilePath, 'utf8') return fileData }), + putProductFile: t.procedure + .input(z.object({ productPath: productPathSchema, filePath: pathSchema, fileData: z.string() })) + .mutation(async function putProductFile(opts) { + const { productPath, filePath, fileData } = opts.input + const productFilePath = join(productPath, filePath) + await writeFile(productFilePath, fileData, 'utf8') + }), }) export type Router = typeof router diff --git a/apps/studio/src/context/product.tsx b/apps/studio/src/context/product.tsx index ff9581cd..54f6ee81 100644 --- a/apps/studio/src/context/product.tsx +++ b/apps/studio/src/context/product.tsx @@ -5,7 +5,7 @@ import { type ProductModule, } from '@villagekit/product' import { ProductKit } from '@villagekit/product-kit' -import { type PropsWithChildren, useEffect } from 'react' +import { type PropsWithChildren, useCallback, useEffect } from 'react' import { useEditorContext } from './editor' export type ProductOptions = { @@ -55,6 +55,11 @@ function useProductEntry(options: ProductOptions): ProductEntry { setEditorCode(productExportsQuery.data) }, [productExportsQuery.isSuccess, productExportsQuery.data, setEditorCode]) + const putProductMetaMutation = client.putProductMeta.useMutation() + const putProductFileMutation = client.putProductFile.useMutation() + + const createProduct = useCallback((productName: string) => {}, []) + if (!productMetaQuery.isSuccess) return null if (!productExportsQuery.isSuccess) return null @@ -63,3 +68,26 @@ function useProductEntry(options: ProductOptions): ProductEntry { code: editorCode, } } + +/* + + putProductMeta: t.procedure + .input(z.object({ productPath: productPathSchema, productMeta: productMetaSchema })) + .mutation(async function getProductMeta(opts) { + const { productPath, productMeta } = opts.input + const productMetaPath = join(productPath, 'villagekit.toml') + const productMetaFile = { product: productMeta } + await writeTomlFile(productMetaPath, productMetaFile) + }), + + getProductFile: t.procedure + .input(z.object({ productPath: productPathSchema, filePath: pathSchema })) + .query(async function getProductFile(opts) { + const { productPath, filePath } = opts.input + const productFilePath = join(productPath, filePath) + const fileData = await readFile(productFilePath, 'utf8') + return fileData + }), + putProductFile: t.procedure + .input(z.object({ productPath: productPathSchema, filePath: pathSchema, fileData: z.string() })) +*/