mirror of
https://github.com/Lifeforge-app/lifeforge.git
synced 2026-03-03 02:27:00 +00:00
feat(tools): WIP
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
"prompts": "^2.4.2",
|
||||
"semver": "^7.7.3",
|
||||
"shared": "workspace:*",
|
||||
"zod": "^4.3.5",
|
||||
"zod": "4.3.5",
|
||||
"@lifeforge/log": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -53,7 +53,7 @@ async function processCollectionSchema(
|
||||
* // const schemas = {
|
||||
* // events: {
|
||||
* // schema: z.object({ title: z.string(), ... }),
|
||||
* // raw: { name: 'calendar__events', ... }
|
||||
* // raw: { name: 'events', ... }
|
||||
* // },
|
||||
* // }
|
||||
* //
|
||||
@@ -70,10 +70,11 @@ export default async function generateSchemaContent(
|
||||
}
|
||||
|
||||
return `import z from 'zod'
|
||||
import { cleanSchemas } from '@lifeforge/server-utils'
|
||||
|
||||
const schemas = {
|
||||
export const schemas = {
|
||||
${schemaEntries.join('\n')}
|
||||
}
|
||||
|
||||
export default schemas`
|
||||
export default cleanSchemas(schemas)`
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import getPBInstance from '@/utils/pocketbase'
|
||||
*
|
||||
* @example
|
||||
* const collections = await getCollectionsFromPB()
|
||||
* // Returns: [{ name: 'calendar__events', type: 'base', ... }, ...]
|
||||
* // Returns: [{ name: 'events', type: 'base', ... }, ...]
|
||||
*/
|
||||
export default async function getCollectionsFromPB() {
|
||||
logger.debug('Connecting to PocketBase...')
|
||||
|
||||
@@ -7,8 +7,8 @@ import { parsePackageName } from '@/commands/modules/functions/parsePackageName'
|
||||
* Finds the module that owns a given PocketBase collection.
|
||||
*
|
||||
* PocketBase collection names follow a naming convention:
|
||||
* - First-party: `moduleName__collectionName` (e.g., `calendar__events`)
|
||||
* - Third-party: `username___moduleName__collectionName` (e.g., `melvinchia3636___melvinchia3636$invoiceMaker__clients`)
|
||||
* - First-party: `moduleName__collectionName` (e.g., `events`)
|
||||
* - Third-party: `username___moduleName__collectionName` (e.g., `melvinchia3636___clients`)
|
||||
*
|
||||
* This function parses the collection name and matches it against registered modules
|
||||
* by comparing the username and module name prefixes.
|
||||
@@ -20,8 +20,8 @@ import { parsePackageName } from '@/commands/modules/functions/parsePackageName'
|
||||
* @returns Matching module directory path, or undefined if no match found
|
||||
*
|
||||
* @example
|
||||
* // Collection 'calendar__events' matches module at '/apps/lifeforge--calendar'
|
||||
* // Collection 'melvinchia3636___melvinchia3636$invoiceMaker__clients' matches '/apps/melvinchia3636--invoice-maker'
|
||||
* // Collection 'events' matches module at '/apps/lifeforge--calendar'
|
||||
* // Collection 'melvinchia3636___clients' matches '/apps/melvinchia3636--invoice-maker'
|
||||
*/
|
||||
export async function matchCollectionToModule(
|
||||
allModules: string[],
|
||||
|
||||
@@ -90,7 +90,7 @@ export async function importSchemaModules(targetModule?: string): Promise<
|
||||
|
||||
return {
|
||||
moduleName: getModuleName(schemaPath) || 'unknown-module',
|
||||
schema: module.default
|
||||
schema: module.schemas
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function generateRouteRegistry() {
|
||||
.join('\n')
|
||||
|
||||
const registry = `// AUTO-GENERATED - DO NOT EDIT
|
||||
import { forgeRouter } from '@functions/routes'
|
||||
import { forgeRouter } from '@lifeforge/server-utils'
|
||||
|
||||
const appRoutes = forgeRouter({
|
||||
${imports}
|
||||
|
||||
@@ -8,16 +8,28 @@ import normalizePackage from '@/utils/normalizePackage'
|
||||
|
||||
import listModules from '../functions/listModules'
|
||||
|
||||
interface BuildOptions {
|
||||
docker?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds module client and server bundles.
|
||||
*
|
||||
* For each module:
|
||||
* - If client/vite.config.ts exists: Runs `bun run build:client`
|
||||
* - If server/index.ts exists: Runs `bun run build:server`
|
||||
*
|
||||
* @param moduleName - Optional module name to build (builds all if omitted)
|
||||
* @param options.docker - If true, builds for Docker (outputs to dist-docker with /api base)
|
||||
*/
|
||||
export async function buildModuleHandler(moduleName?: string): Promise<void> {
|
||||
export async function buildModuleHandler(
|
||||
moduleName?: string,
|
||||
options?: BuildOptions
|
||||
): Promise<void> {
|
||||
const modules = listModules()
|
||||
|
||||
const isDocker = options?.docker ?? false
|
||||
|
||||
const moduleNames = moduleName
|
||||
? [normalizePackage(moduleName).fullName]
|
||||
: Object.keys(modules)
|
||||
@@ -26,6 +38,10 @@ export async function buildModuleHandler(moduleName?: string): Promise<void> {
|
||||
let serverBuiltCount = 0
|
||||
let skippedCount = 0
|
||||
|
||||
if (isDocker) {
|
||||
logger.info('Building for Docker (output: dist-docker, base: /api)')
|
||||
}
|
||||
|
||||
for (const mod of moduleNames) {
|
||||
const { targetDir, shortName } = normalizePackage(mod)
|
||||
|
||||
@@ -56,7 +72,8 @@ export async function buildModuleHandler(moduleName?: string): Promise<void> {
|
||||
try {
|
||||
executeCommand('bun run build:client', {
|
||||
cwd: targetDir,
|
||||
stdio: 'pipe'
|
||||
stdio: 'pipe',
|
||||
env: isDocker ? { ...process.env, DOCKER_BUILD: 'true' } : undefined
|
||||
})
|
||||
clientBuiltCount++
|
||||
} catch (error) {
|
||||
|
||||
@@ -55,6 +55,10 @@ export default function setup(program: Command): void {
|
||||
.alias('b')
|
||||
.description('Build module client bundles for federation')
|
||||
.argument('[module]', 'Module to build (optional, builds all if omitted)')
|
||||
.option(
|
||||
'--docker',
|
||||
'Build for Docker (outputs to dist-docker with /api base)'
|
||||
)
|
||||
.action(buildModuleHandler)
|
||||
|
||||
command
|
||||
|
||||
85
tools/src/scripts/add-build-server-scripts.ts
Normal file
85
tools/src/scripts/add-build-server-scripts.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* Script to add build:server script to all module package.json files
|
||||
*/
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
// Resolve from the lifeforge root (where this script is run from)
|
||||
const ROOT_DIR = process.cwd()
|
||||
|
||||
const APPS_DIR = path.resolve(ROOT_DIR, 'apps')
|
||||
|
||||
const BUILD_SERVER_SCRIPT =
|
||||
'bun build ./server/index.ts --outdir ./server/dist --target bun --external @lifeforge/server-utils --external zod'
|
||||
|
||||
async function main() {
|
||||
const moduleDirs = fs.readdirSync(APPS_DIR).filter(name => {
|
||||
const fullPath = path.join(APPS_DIR, name)
|
||||
|
||||
return (
|
||||
fs.statSync(fullPath).isDirectory() &&
|
||||
!name.startsWith('.') &&
|
||||
name !== 'node_modules'
|
||||
)
|
||||
})
|
||||
|
||||
let updatedCount = 0
|
||||
let skippedCount = 0
|
||||
let noServerCount = 0
|
||||
|
||||
for (const moduleName of moduleDirs) {
|
||||
const moduleDir = path.join(APPS_DIR, moduleName)
|
||||
|
||||
const packageJsonPath = path.join(moduleDir, 'package.json')
|
||||
|
||||
const serverIndexPath = path.join(moduleDir, 'server', 'index.ts')
|
||||
|
||||
// Check if server/index.ts exists
|
||||
if (!fs.existsSync(serverIndexPath)) {
|
||||
console.log(`⏭️ Skipping ${moduleName} (no server/index.ts)`)
|
||||
noServerCount++
|
||||
continue
|
||||
}
|
||||
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
console.log(`⚠️ ${moduleName}: No package.json found`)
|
||||
skippedCount++
|
||||
continue
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
|
||||
|
||||
// Initialize scripts if not present
|
||||
if (!packageJson.scripts) {
|
||||
packageJson.scripts = {}
|
||||
}
|
||||
|
||||
// Check if build:server already exists
|
||||
if (packageJson.scripts['build:server']) {
|
||||
console.log(`⏭️ ${moduleName}: build:server already exists`)
|
||||
skippedCount++
|
||||
continue
|
||||
}
|
||||
|
||||
// Add build:server script
|
||||
packageJson.scripts['build:server'] = BUILD_SERVER_SCRIPT
|
||||
|
||||
// Write back
|
||||
fs.writeFileSync(
|
||||
packageJsonPath,
|
||||
JSON.stringify(packageJson, null, 2) + '\n'
|
||||
)
|
||||
console.log(`✅ ${moduleName}: Added build:server script`)
|
||||
updatedCount++
|
||||
}
|
||||
|
||||
console.log('\n--- Summary ---')
|
||||
console.log(`Updated: ${updatedCount}`)
|
||||
console.log(
|
||||
`Skipped (already had script or no package.json): ${skippedCount}`
|
||||
)
|
||||
console.log(`Skipped (no server): ${noServerCount}`)
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
@@ -34,16 +34,11 @@
|
||||
"./*"
|
||||
],
|
||||
"@server/*": [
|
||||
"../../../server/src/*"
|
||||
"../server/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { type AppRoutes } from '@server/core/routes/routes.type'
|
||||
import { createForgeAPIClient } from 'shared'
|
||||
import routes from '@server/index'
|
||||
import routes from '@server/index'
|
||||
import { createForgeProxy } from 'shared'
|
||||
|
||||
if (!import.meta.env.VITE_API_HOST) {
|
||||
throw new Error('VITE_API_HOST is not defined')
|
||||
}
|
||||
|
||||
const forgeAPI = createForgeAPIClient<AppRoutes>(import.meta.env.VITE_API_HOST)
|
||||
const forgeAPI = createForgeProxy<typeof routes>(import.meta.env.VITE_API_HOST)
|
||||
|
||||
export default forgeAPI
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "^4.3.5"
|
||||
"zod": "4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
@@ -32,4 +32,4 @@
|
||||
},
|
||||
"./server/schema": "./server/schema.ts"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
"extends": "../../../server/tsconfig.json",
|
||||
"include": ["./**/*.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { forgeRouter } from '@functions/routes'
|
||||
import { forgeRouter } from '@lifeforge/server-utils'
|
||||
import { createForge } from '@lifeforge/server-utils'
|
||||
|
||||
const forge = createForge(schema)
|
||||
|
||||
export default forgeRouter({})
|
||||
|
||||
@@ -34,16 +34,11 @@
|
||||
"./*"
|
||||
],
|
||||
"@server/*": [
|
||||
"../../../server/src/*"
|
||||
"../server/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,33 +1,33 @@
|
||||
{
|
||||
"name": "@lifeforge/lifeforge--{{kebab moduleName.en}}",
|
||||
"version": "0.0.0",
|
||||
"description": "{{moduleDesc.en}}",
|
||||
"scripts": {
|
||||
"types": "cd client && bun tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@tanstack/react-query": "^5.90.2",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.18",
|
||||
"lifeforge-ui": "workspace:*",
|
||||
"react": "^19.2.0",
|
||||
"react-i18next": "^15.1.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "^4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0"
|
||||
},
|
||||
"exports": {
|
||||
"./manifest": {
|
||||
"types": "./manifest.d.ts",
|
||||
"default": "./manifest.ts"
|
||||
}
|
||||
"name": "@lifeforge/lifeforge--{{kebab moduleName.en}}",
|
||||
"version": "0.0.0",
|
||||
"description": "{{moduleDesc.en}}",
|
||||
"scripts": {
|
||||
"types": "cd client && bun tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@tanstack/react-query": "^5.90.2",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.18",
|
||||
"lifeforge-ui": "workspace:*",
|
||||
"react": "^19.2.0",
|
||||
"react-i18next": "^15.1.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0"
|
||||
},
|
||||
"exports": {
|
||||
"./manifest": {
|
||||
"types": "./manifest.d.ts",
|
||||
"default": "./manifest.ts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,16 +34,11 @@
|
||||
"./index/*"
|
||||
],
|
||||
"@server/*": [
|
||||
"../../../server/src/*"
|
||||
"../server/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { type AppRoutes } from '@server/core/routes/routes.type'
|
||||
import { createForgeAPIClient } from 'shared'
|
||||
import routes from '@server/index'
|
||||
import routes from '@server/index'
|
||||
import { createForgeProxy } from 'shared'
|
||||
|
||||
if (!import.meta.env.VITE_API_HOST) {
|
||||
throw new Error('VITE_API_HOST is not defined')
|
||||
}
|
||||
|
||||
const forgeAPI = createForgeAPIClient<AppRoutes>(import.meta.env.VITE_API_HOST)
|
||||
const forgeAPI = createForgeProxy<typeof routes>(import.meta.env.VITE_API_HOST)
|
||||
|
||||
export default forgeAPI
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
{
|
||||
"name": "@lifeforge/lifeforge--{{kebab moduleName.en}}",
|
||||
"version": "0.0.0",
|
||||
"description": "{{moduleDesc.en}}",
|
||||
"scripts": {
|
||||
"types": "cd client && bun tsc"
|
||||
"name": "@lifeforge/lifeforge--{{kebab moduleName.en}}",
|
||||
"version": "0.0.0",
|
||||
"description": "{{moduleDesc.en}}",
|
||||
"scripts": {
|
||||
"types": "cd client && bun tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@tanstack/react-query": "^5.90.2",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.18",
|
||||
"lifeforge-ui": "workspace:*",
|
||||
"react": "^19.2.0",
|
||||
"react-i18next": "^15.1.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0"
|
||||
},
|
||||
"exports": {
|
||||
"./server": "./server/index.ts",
|
||||
"./manifest": {
|
||||
"types": "./manifest.d.ts",
|
||||
"default": "./manifest.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@tanstack/react-query": "^5.90.2",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.18",
|
||||
"lifeforge-ui": "workspace:*",
|
||||
"react": "^19.2.0",
|
||||
"react-i18next": "^15.1.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "^4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0"
|
||||
},
|
||||
"exports": {
|
||||
"./server": "./server/index.ts",
|
||||
"./manifest": {
|
||||
"types": "./manifest.d.ts",
|
||||
"default": "./manifest.ts"
|
||||
},
|
||||
"./server/schema": "./server/schema.ts"
|
||||
}
|
||||
}
|
||||
"./server/schema": "./server/schema.ts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
"extends": "../../../server/tsconfig.json",
|
||||
"include": ["./**/*.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { forgeRouter } from '@functions/routes'
|
||||
import { forgeRouter } from '@lifeforge/server-utils'
|
||||
import { createForge } from '@lifeforge/server-utils'
|
||||
|
||||
import * as entriesRoutes from './routes/entries'
|
||||
|
||||
const forge = createForge(schema)
|
||||
|
||||
export default forgeRouter({
|
||||
entries: entriesRoutes
|
||||
})
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { forgeController } from '@functions/routes'
|
||||
|
||||
import { SCHEMAS } from '@schema'
|
||||
import z from 'zod'
|
||||
|
||||
export const list = forgeController
|
||||
export const list = forge
|
||||
.query()
|
||||
.description('List all entries')
|
||||
.input({})
|
||||
.callback(({ pb }) => pb.getFullList.collection('{{snake moduleName.en}}__entries').execute())
|
||||
|
||||
export const getById = forgeController
|
||||
export const getById = forge
|
||||
.query()
|
||||
.description('Get entry by ID')
|
||||
.input({
|
||||
@@ -23,24 +23,24 @@ export const getById = forgeController
|
||||
pb.getOne.collection('{{snake moduleName.en}}__entries').id(id).execute()
|
||||
)
|
||||
|
||||
export const create = forgeController
|
||||
export const create = forge
|
||||
.mutation()
|
||||
.description('Create a new entry')
|
||||
.input({
|
||||
body: SCHEMAS.{{snake moduleName.en}}.entries.schema.omit({ created: true, updated: true })
|
||||
body: SCHEMAS.{{snake moduleName.en}}.entries.omit({ created: true, updated: true })
|
||||
})
|
||||
.callback(({ pb, body }) =>
|
||||
pb.create.collection('{{snake moduleName.en}}__entries').data(body).execute()
|
||||
)
|
||||
|
||||
export const update = forgeController
|
||||
export const update = forge
|
||||
.mutation()
|
||||
.description('Update an existing entry')
|
||||
.input({
|
||||
query: z.object({
|
||||
id: z.string()
|
||||
}),
|
||||
body: SCHEMAS.{{snake moduleName.en}}.entries.schema
|
||||
body: SCHEMAS.{{snake moduleName.en}}.entries
|
||||
.partial()
|
||||
.omit({ created: true, updated: true })
|
||||
})
|
||||
@@ -51,7 +51,7 @@ export const update = forgeController
|
||||
pb.update.collection('{{snake moduleName.en}}__entries').id(id).data(body).execute()
|
||||
)
|
||||
|
||||
export const remove = forgeController
|
||||
export const remove = forge
|
||||
.mutation()
|
||||
.description('Delete an entry')
|
||||
.input({
|
||||
|
||||
@@ -34,16 +34,11 @@
|
||||
"./*"
|
||||
],
|
||||
"@server/*": [
|
||||
"../../../server/src/*"
|
||||
"../server/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { type AppRoutes } from '@server/core/routes/routes.type'
|
||||
import { createForgeAPIClient } from 'shared'
|
||||
import routes from '@server/index'
|
||||
import routes from '@server/index'
|
||||
import { createForgeProxy } from 'shared'
|
||||
|
||||
if (!import.meta.env.VITE_API_HOST) {
|
||||
throw new Error('VITE_API_HOST is not defined')
|
||||
}
|
||||
|
||||
const forgeAPI = createForgeAPIClient<AppRoutes>(import.meta.env.VITE_API_HOST)
|
||||
const forgeAPI = createForgeProxy<typeof routes>(import.meta.env.VITE_API_HOST)
|
||||
|
||||
export default forgeAPI
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
{
|
||||
"name": "@lifeforge/lifeforge--{{kebab moduleName.en}}",
|
||||
"version": "0.0.0",
|
||||
"description": "{{moduleDesc.en}}",
|
||||
"scripts": {
|
||||
"types": "cd client && bun tsc"
|
||||
"name": "@lifeforge/lifeforge--{{kebab moduleName.en}}",
|
||||
"version": "0.0.0",
|
||||
"description": "{{moduleDesc.en}}",
|
||||
"scripts": {
|
||||
"types": "cd client && bun tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@tanstack/react-query": "^5.90.2",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.18",
|
||||
"lifeforge-ui": "workspace:*",
|
||||
"react": "^19.2.0",
|
||||
"react-i18next": "^15.1.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0"
|
||||
},
|
||||
"exports": {
|
||||
"./server": "./server/index.ts",
|
||||
"./manifest": {
|
||||
"types": "./manifest.d.ts",
|
||||
"default": "./manifest.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@tanstack/react-query": "^5.90.2",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.18",
|
||||
"lifeforge-ui": "workspace:*",
|
||||
"react": "^19.2.0",
|
||||
"react-i18next": "^15.1.1",
|
||||
"react-toastify": "^11.0.5",
|
||||
"shared": "workspace:*",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vite": "^7.1.9",
|
||||
"zod": "^4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0"
|
||||
},
|
||||
"exports": {
|
||||
"./server": "./server/index.ts",
|
||||
"./manifest": {
|
||||
"types": "./manifest.d.ts",
|
||||
"default": "./manifest.ts"
|
||||
},
|
||||
"./server/schema": "./server/schema.ts"
|
||||
}
|
||||
}
|
||||
"./server/schema": "./server/schema.ts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
"extends": "../../../server/tsconfig.json",
|
||||
"include": ["./**/*.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../server/tsconfig.json"
|
||||
}
|
||||
]
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { forgeRouter } from '@functions/routes'
|
||||
import { forgeRouter } from '@lifeforge/server-utils'
|
||||
import { createForge } from '@lifeforge/server-utils'
|
||||
|
||||
const forge = createForge(schema)
|
||||
|
||||
export default forgeRouter({})
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function getAPIKey(): Promise<string | null> {
|
||||
const { pb, killPB } = await getPBInstance()
|
||||
|
||||
const apiKey = await pb
|
||||
.collection('api_keys__entries')
|
||||
.collection('entries')
|
||||
.getFirstListItem('keyId="openai"')
|
||||
.catch(() => {})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user