Spaces:
Running
Running
Download server.js from Tataaicoltd/api: direct link, hf CLI and curl.
- Browser
- Download file 2.63 kB
-
https://huggingface.co/spaces/Tataaicoltd/api/resolve/main/server.js
- Command line
-
hf download hf://spaces/Tataaicoltd/api/server.js
-
curl -L -o server.js https://huggingface.co/spaces/Tataaicoltd/api/resolve/main/server.js
2.63 kB
| import express from 'express'; | |
| import cors from 'cors'; | |
| import { fileURLToPath } from 'url'; | |
| import path from 'path'; | |
| import dotenv from 'dotenv'; | |
| import swaggerUi from 'swagger-ui-express'; | |
| import projectsRouter from './src/routes/projects.js'; | |
| import ticketsRouter from './src/routes/tickets.js'; | |
| import flowRouter from './src/routes/flow.js'; | |
| import chefsysRouter from './src/routes/chefsys.js'; | |
| import { openapiSpec } from './src/openapi.js'; | |
| dotenv.config(); | |
| const __filename = fileURLToPath(import.meta.url); | |
| const __dirname = path.dirname(__filename); | |
| const app = express(); | |
| const PORT = process.env.PORT || 3000; | |
| // Derive the Supabase storage origin so images can be whitelisted explicitly | |
| // (instead of using a wildcard) in the Content-Security-Policy. | |
| let supabaseOrigin = ''; | |
| try { | |
| if (process.env.SUPABASE_URL) supabaseOrigin = new URL(process.env.SUPABASE_URL).origin; | |
| } catch { | |
| supabaseOrigin = ''; | |
| } | |
| const baseCsp = [ | |
| "default-src 'self'", | |
| "script-src 'self'", | |
| "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", | |
| "font-src 'self' https://fonts.gstatic.com", | |
| `img-src 'self' data: blob:${supabaseOrigin ? ' ' + supabaseOrigin : ''}`, | |
| `connect-src 'self'${supabaseOrigin ? ' ' + supabaseOrigin : ''}`, | |
| "object-src 'none'", | |
| "base-uri 'self'", | |
| "form-action 'self'", | |
| "frame-ancestors 'none'" | |
| ].join('; '); | |
| // Swagger UI ships inline scripts/styles, so it needs a slightly relaxed policy. | |
| const swaggerCsp = [ | |
| "default-src 'self'", | |
| "script-src 'self' 'unsafe-inline'", | |
| "style-src 'self' 'unsafe-inline'", | |
| "img-src 'self' data:", | |
| "object-src 'none'", | |
| "base-uri 'self'", | |
| "frame-ancestors 'none'" | |
| ].join('; '); | |
| app.use((req, res, next) => { | |
| res.setHeader( | |
| 'Content-Security-Policy', | |
| req.path.startsWith('/api-docs') ? swaggerCsp : baseCsp | |
| ); | |
| res.setHeader('X-Content-Type-Options', 'nosniff'); | |
| res.setHeader('Referrer-Policy', 'no-referrer'); | |
| next(); | |
| }); | |
| app.use(cors()); | |
| app.use(express.json({ limit: '5mb' })); | |
| // API routes | |
| app.use('/api/projects', projectsRouter); | |
| app.use('/api/tickets', ticketsRouter); | |
| app.use('/flow/tickets', flowRouter); | |
| app.use('/chefsys', chefsysRouter); | |
| app.get('/api/health', (req, res) => res.json({ ok: true })); | |
| // API documentation (Swagger UI) + raw OpenAPI spec | |
| app.get('/api-docs.json', (req, res) => res.json(openapiSpec)); | |
| app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openapiSpec, { | |
| customSiteTitle: 'Taboard API Docs' | |
| })); | |
| // Static frontend | |
| app.use(express.static(path.join(__dirname, 'public'))); | |
| app.listen(PORT, () => { | |
| console.log(`Taboard running at http://localhost:${PORT}`); | |
| }); | |