feat: Razorpay, Minio, multi-role patient dashboard, and advanced profiles
Build Curio HMS / build-and-deploy (push) Successful in 1m6s
Details
Build Curio HMS / build-and-deploy (push) Successful in 1m6s
Details
This commit is contained in:
parent
1d9c314c4f
commit
8b27b68932
|
|
@ -30,6 +30,7 @@ CREATE TABLE IF NOT EXISTS tenants (
|
||||||
working_hours JSONB DEFAULT '[{"start":"09:00","end":"13:00"},{"start":"17:00","end":"22:00"}]',
|
working_hours JSONB DEFAULT '[{"start":"09:00","end":"13:00"},{"start":"17:00","end":"22:00"}]',
|
||||||
days_off JSONB DEFAULT '[0]',
|
days_off JSONB DEFAULT '[0]',
|
||||||
holidays JSONB DEFAULT '[]',
|
holidays JSONB DEFAULT '[]',
|
||||||
|
services_catalog JSONB DEFAULT '[]',
|
||||||
created_at TIMESTAMPTZ DEFAULT now()
|
created_at TIMESTAMPTZ DEFAULT now()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -39,7 +40,10 @@ CREATE TABLE IF NOT EXISTS users (
|
||||||
email TEXT UNIQUE NOT NULL,
|
email TEXT UNIQUE NOT NULL,
|
||||||
password_hash TEXT NOT NULL,
|
password_hash TEXT NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
role TEXT NOT NULL CHECK (role IN ('SUPER_ADMIN','OWNER','DOCTOR','RECEPTIONIST','PHARMACIST','LAB_TECH')),
|
role TEXT NOT NULL CHECK (role IN ('SUPER_ADMIN','OWNER','DOCTOR','RECEPTIONIST','PHARMACIST','LAB_TECH','PATIENT')),
|
||||||
|
profile_media JSONB DEFAULT '{}',
|
||||||
|
q_and_a JSONB DEFAULT '[]',
|
||||||
|
blocked_dates JSONB DEFAULT '[]',
|
||||||
status TEXT DEFAULT 'active',
|
status TEXT DEFAULT 'active',
|
||||||
created_at TIMESTAMPTZ DEFAULT now()
|
created_at TIMESTAMPTZ DEFAULT now()
|
||||||
);
|
);
|
||||||
|
|
@ -58,9 +62,30 @@ CREATE TABLE IF NOT EXISTS pending_registrations (
|
||||||
created_at TIMESTAMPTZ DEFAULT now()
|
created_at TIMESTAMPTZ DEFAULT now()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS transactions (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
order_id TEXT NOT NULL UNIQUE,
|
||||||
|
payment_id TEXT,
|
||||||
|
amount INTEGER NOT NULL,
|
||||||
|
currency TEXT DEFAULT 'INR',
|
||||||
|
status TEXT DEFAULT 'created',
|
||||||
|
tenant_id TEXT REFERENCES tenants(id),
|
||||||
|
user_id INTEGER REFERENCES users(id),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_users_tenant ON users(tenant_id);
|
CREATE INDEX IF NOT EXISTS idx_users_tenant ON users(tenant_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||||
CREATE INDEX IF NOT EXISTS idx_pending_status ON pending_registrations(status);
|
CREATE INDEX IF NOT EXISTS idx_pending_status ON pending_registrations(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_transactions_order ON transactions(order_id);
|
||||||
|
|
||||||
|
-- Migrations for existing DBs
|
||||||
|
ALTER TABLE tenants ADD COLUMN IF NOT EXISTS services_catalog JSONB DEFAULT '[]';
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS profile_media JSONB DEFAULT '{}';
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS q_and_a JSONB DEFAULT '[]';
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS blocked_dates JSONB DEFAULT '[]';
|
||||||
|
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_role_check;
|
||||||
|
ALTER TABLE users ADD CONSTRAINT users_role_check CHECK (role IN ('SUPER_ADMIN','OWNER','DOCTOR','RECEPTIONIST','PHARMACIST','LAB_TECH','PATIENT'));
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// ── Seed super admin ─────────────────────────────────────────────────────────
|
// ── Seed super admin ─────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,13 @@ const { getTenantConfig, updateTenantConfig } = require('./configManager');
|
||||||
const { getTemporalClient } = require('./temporalClient');
|
const { getTemporalClient } = require('./temporalClient');
|
||||||
const { query, initSchema } = require('./db');
|
const { query, initSchema } = require('./db');
|
||||||
const { signToken, requireAuth } = require('./authMiddleware');
|
const { signToken, requireAuth } = require('./authMiddleware');
|
||||||
|
const Razorpay = require('razorpay');
|
||||||
|
const { upload, initStorage, uploadFile } = require('./storage');
|
||||||
|
|
||||||
|
const razorpayInstance = new Razorpay({
|
||||||
|
key_id: process.env.RAZORPAY_KEY_ID || 'rzp_test_dummy_key_id',
|
||||||
|
key_secret: process.env.RAZORPAY_KEY_SECRET || 'dummy_secret_key',
|
||||||
|
});
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 3000;
|
const port = 3000;
|
||||||
|
|
@ -462,7 +469,7 @@ app.post('/api/super/pending/:id/reject', requireAuth('SUPER_ADMIN'), async (req
|
||||||
* PATCH /api/clinic/settings — clinic owner updates own settings
|
* PATCH /api/clinic/settings — clinic owner updates own settings
|
||||||
*/
|
*/
|
||||||
app.patch('/api/clinic/settings', requireAuth('OWNER'), async (req, res) => {
|
app.patch('/api/clinic/settings', requireAuth('OWNER'), async (req, res) => {
|
||||||
const { consultationFee, workingHours, daysOff, holidays, primaryColor, secondaryColor } = req.body;
|
const { consultationFee, workingHours, daysOff, holidays, primaryColor, secondaryColor, servicesCatalog } = req.body;
|
||||||
const tenantId = req.user.tenantId;
|
const tenantId = req.user.tenantId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -476,6 +483,7 @@ app.patch('/api/clinic/settings', requireAuth('OWNER'), async (req, res) => {
|
||||||
if (workingHours !== undefined) { fields.push(`working_hours=$${i++}::jsonb`); values.push(JSON.stringify(workingHours)); }
|
if (workingHours !== undefined) { fields.push(`working_hours=$${i++}::jsonb`); values.push(JSON.stringify(workingHours)); }
|
||||||
if (daysOff !== undefined) { fields.push(`days_off=$${i++}::jsonb`); values.push(JSON.stringify(daysOff)); }
|
if (daysOff !== undefined) { fields.push(`days_off=$${i++}::jsonb`); values.push(JSON.stringify(daysOff)); }
|
||||||
if (holidays !== undefined) { fields.push(`holidays=$${i++}::jsonb`); values.push(JSON.stringify(holidays)); }
|
if (holidays !== undefined) { fields.push(`holidays=$${i++}::jsonb`); values.push(JSON.stringify(holidays)); }
|
||||||
|
if (servicesCatalog !== undefined) { fields.push(`services_catalog=$${i++}::jsonb`); values.push(JSON.stringify(servicesCatalog)); }
|
||||||
|
|
||||||
if (fields.length === 0) return res.status(400).json({ error: 'No fields to update' });
|
if (fields.length === 0) return res.status(400).json({ error: 'No fields to update' });
|
||||||
|
|
||||||
|
|
@ -488,6 +496,114 @@ app.patch('/api/clinic/settings', requireAuth('OWNER'), async (req, res) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PATCH /api/doctor/profile — Doctor updates own profile
|
||||||
|
*/
|
||||||
|
app.patch('/api/doctor/profile', requireAuth('DOCTOR'), async (req, res) => {
|
||||||
|
const { blockedDates, qAndA } = req.body;
|
||||||
|
const userId = req.user.userId;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fields = [];
|
||||||
|
const values = [];
|
||||||
|
let i = 1;
|
||||||
|
|
||||||
|
if (blockedDates !== undefined) { fields.push(`blocked_dates=$${i++}::jsonb`); values.push(JSON.stringify(blockedDates)); }
|
||||||
|
if (qAndA !== undefined) { fields.push(`q_and_a=$${i++}::jsonb`); values.push(JSON.stringify(qAndA)); }
|
||||||
|
|
||||||
|
if (fields.length === 0) return res.status(400).json({ error: 'No fields to update' });
|
||||||
|
|
||||||
|
values.push(userId);
|
||||||
|
await query(`UPDATE users SET ${fields.join(',')} WHERE id=$${i}`, values);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[Doctor Profile]', err);
|
||||||
|
res.status(500).json({ error: 'Failed to update profile' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /api/doctor/upload-media — Upload images/videos to MinIO
|
||||||
|
*/
|
||||||
|
app.post('/api/doctor/upload-media', requireAuth('DOCTOR'), upload.single('media'), async (req, res) => {
|
||||||
|
if (!req.file) return res.status(400).json({ error: 'No file uploaded' });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userId = req.user.userId;
|
||||||
|
const ext = path.extname(req.file.originalname) || '.jpg';
|
||||||
|
const fileName = `profile_${userId}_${Date.now()}${ext}`;
|
||||||
|
|
||||||
|
const fileUrl = await uploadFile(fileName, req.file.buffer, req.file.mimetype);
|
||||||
|
|
||||||
|
// Append to profile_media JSON
|
||||||
|
const userRow = await query('SELECT profile_media FROM users WHERE id = $1', [userId]);
|
||||||
|
const media = userRow.rows[0].profile_media || {};
|
||||||
|
const mediaList = media.uploads || [];
|
||||||
|
mediaList.push({ url: fileUrl, type: req.file.mimetype, name: req.file.originalname });
|
||||||
|
|
||||||
|
await query('UPDATE users SET profile_media = $1::jsonb WHERE id = $2', [JSON.stringify({ uploads: mediaList }), userId]);
|
||||||
|
|
||||||
|
res.json({ success: true, url: fileUrl });
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[Media Upload]', err);
|
||||||
|
res.status(500).json({ error: 'Failed to upload media' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── RAZORPAY PAYMENTS ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
app.post('/api/payments/create-order', requireAuth(), async (req, res) => {
|
||||||
|
const { amount, currency = 'INR', notes } = req.body;
|
||||||
|
|
||||||
|
if (!amount) return res.status(400).json({ error: 'Amount is required' });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {
|
||||||
|
amount: amount * 100, // Razorpay works in smallest currency unit (paise)
|
||||||
|
currency,
|
||||||
|
receipt: `rcpt_${Date.now()}`,
|
||||||
|
notes,
|
||||||
|
};
|
||||||
|
|
||||||
|
const order = await razorpayInstance.orders.create(options);
|
||||||
|
|
||||||
|
// Save transaction to DB
|
||||||
|
await query(
|
||||||
|
`INSERT INTO transactions (order_id, amount, currency, tenant_id, user_id)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)`,
|
||||||
|
[order.id, amount, currency, req.user.tenantId, req.user.userId]
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ success: true, orderId: order.id, amount: order.amount, currency: order.currency });
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[Create Order Error]', err);
|
||||||
|
res.status(500).json({ error: 'Failed to create payment order' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/api/payments/verify', requireAuth(), async (req, res) => {
|
||||||
|
const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = req.body;
|
||||||
|
|
||||||
|
const secret = process.env.RAZORPAY_KEY_SECRET || 'dummy_secret_key';
|
||||||
|
const body = razorpay_order_id + '|' + razorpay_payment_id;
|
||||||
|
|
||||||
|
const expectedSignature = crypto
|
||||||
|
.createHmac('sha256', secret)
|
||||||
|
.update(body.toString())
|
||||||
|
.digest('hex');
|
||||||
|
|
||||||
|
if (expectedSignature === razorpay_signature) {
|
||||||
|
// Mark as paid
|
||||||
|
await query('UPDATE transactions SET status = $1, payment_id = $2 WHERE order_id = $3',
|
||||||
|
['PAID', razorpay_payment_id, razorpay_order_id]);
|
||||||
|
|
||||||
|
res.json({ success: true });
|
||||||
|
} else {
|
||||||
|
res.status(400).json({ error: 'Invalid signature' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// ── WHATSAPP WEBHOOK ──────────────────────────────────────────────────────────
|
// ── WHATSAPP WEBHOOK ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// Using twilio.webhook() middleware for request validation
|
// Using twilio.webhook() middleware for request validation
|
||||||
|
|
@ -495,9 +611,10 @@ app.patch('/api/clinic/settings', requireAuth('OWNER'), async (req, res) => {
|
||||||
const shouldValidate = process.env.NODE_ENV === 'production';
|
const shouldValidate = process.env.NODE_ENV === 'production';
|
||||||
app.post('/whatsapp/webhook', twilio.webhook({ validate: shouldValidate }), async (req, res) => {
|
app.post('/whatsapp/webhook', twilio.webhook({ validate: shouldValidate }), async (req, res) => {
|
||||||
const from = req.body.From || req.body.from;
|
const from = req.body.From || req.body.from;
|
||||||
|
const to = req.body.To || req.body.to;
|
||||||
const body = req.body.Body || req.body.body;
|
const body = req.body.Body || req.body.body;
|
||||||
|
|
||||||
console.log(`[WhatsApp Webhook] Received message from ${from}: ${body}`);
|
console.log(`[WhatsApp Webhook] Received message from ${from} to ${to}: ${body}`);
|
||||||
if (!from || !body) return res.status(400).send('Missing from or body');
|
if (!from || !body) return res.status(400).send('Missing from or body');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -515,7 +632,7 @@ app.post('/whatsapp/webhook', twilio.webhook({ validate: shouldValidate }), asyn
|
||||||
} catch (err) { /* start new */ }
|
} catch (err) { /* start new */ }
|
||||||
|
|
||||||
await temporalClient.workflow.start('AppointmentBookingWorkflow', {
|
await temporalClient.workflow.start('AppointmentBookingWorkflow', {
|
||||||
args: [body, from], taskQueue: 'curaflow-tasks', workflowId,
|
args: [body, from, to], taskQueue: 'curaflow-tasks', workflowId,
|
||||||
});
|
});
|
||||||
res.type('text/xml').send('<Response></Response>');
|
res.type('text/xml').send('<Response></Response>');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -659,7 +776,9 @@ app.get('/api/ai/lab/alerts/:patientId', async (req, res) => {
|
||||||
// ── START ─────────────────────────────────────────────────────────────────────
|
// ── START ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
initSchema().then(() => {
|
initSchema().then(() => {
|
||||||
app.listen(port, '0.0.0.0', () => {
|
initStorage().then(() => {
|
||||||
console.log(`Curio HMS running at http://0.0.0.0:${port}`);
|
app.listen(port, '0.0.0.0', () => {
|
||||||
|
console.log(`Curio HMS running at http://0.0.0.0:${port}`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
const Minio = require('minio');
|
||||||
|
const multer = require('multer');
|
||||||
|
|
||||||
|
// Configure MinIO Client
|
||||||
|
const minioClient = new Minio.Client({
|
||||||
|
endPoint: process.env.MINIO_ENDPOINT || 'localhost',
|
||||||
|
port: parseInt(process.env.MINIO_PORT) || 9000,
|
||||||
|
useSSL: process.env.MINIO_USE_SSL === 'true',
|
||||||
|
accessKey: process.env.MINIO_ACCESS_KEY || 'minioadmin',
|
||||||
|
secretKey: process.env.MINIO_SECRET_KEY || 'minioadmin'
|
||||||
|
});
|
||||||
|
|
||||||
|
const BUCKET_NAME = process.env.MINIO_BUCKET_NAME || 'curio-media';
|
||||||
|
|
||||||
|
// Ensure bucket exists
|
||||||
|
async function initStorage() {
|
||||||
|
try {
|
||||||
|
const exists = await minioClient.bucketExists(BUCKET_NAME);
|
||||||
|
if (!exists) {
|
||||||
|
await minioClient.makeBucket(BUCKET_NAME, 'us-east-1');
|
||||||
|
console.log(`[Storage] Bucket '${BUCKET_NAME}' created successfully.`);
|
||||||
|
|
||||||
|
// Set basic public read policy for media
|
||||||
|
const policy = {
|
||||||
|
Version: '2012-10-17',
|
||||||
|
Statement: [
|
||||||
|
{
|
||||||
|
Action: ['s3:GetObject'],
|
||||||
|
Effect: 'Allow',
|
||||||
|
Principal: '*',
|
||||||
|
Resource: [`arn:aws:s3:::${BUCKET_NAME}/*`],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
await minioClient.setBucketPolicy(BUCKET_NAME, JSON.stringify(policy));
|
||||||
|
} else {
|
||||||
|
console.log(`[Storage] Bucket '${BUCKET_NAME}' already exists.`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[Storage] MinIO Init Error:', err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multer in-memory storage for handling multipart form data before streaming to MinIO
|
||||||
|
const upload = multer({
|
||||||
|
storage: multer.memoryStorage(),
|
||||||
|
limits: {
|
||||||
|
fileSize: 10 * 1024 * 1024, // 10MB max file size
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a file buffer to MinIO
|
||||||
|
* @param {string} fileName
|
||||||
|
* @param {Buffer} fileBuffer
|
||||||
|
* @param {string} mimeType
|
||||||
|
* @returns {Promise<string>} Public URL of the uploaded file
|
||||||
|
*/
|
||||||
|
async function uploadFile(fileName, fileBuffer, mimeType) {
|
||||||
|
try {
|
||||||
|
await minioClient.putObject(BUCKET_NAME, fileName, fileBuffer, fileBuffer.length, {
|
||||||
|
'Content-Type': mimeType
|
||||||
|
});
|
||||||
|
|
||||||
|
const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http';
|
||||||
|
const port = process.env.MINIO_PORT ? `:${process.env.MINIO_PORT}` : '';
|
||||||
|
// If MinIO is accessible publicly, return the direct URL.
|
||||||
|
// For production behind proxy, this might need to be the proxy URL.
|
||||||
|
const publicUrl = process.env.MINIO_PUBLIC_URL
|
||||||
|
? `${process.env.MINIO_PUBLIC_URL}/${BUCKET_NAME}/${fileName}`
|
||||||
|
: `${protocol}://${process.env.MINIO_ENDPOINT || 'localhost'}${port}/${BUCKET_NAME}/${fileName}`;
|
||||||
|
|
||||||
|
return publicUrl;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[Storage] Upload Error:', err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
minioClient,
|
||||||
|
upload,
|
||||||
|
initStorage,
|
||||||
|
uploadFile
|
||||||
|
};
|
||||||
|
|
@ -54,7 +54,9 @@
|
||||||
try {
|
try {
|
||||||
const p = JSON.parse(atob(token.split('.')[1]));
|
const p = JSON.parse(atob(token.split('.')[1]));
|
||||||
if (p.exp && Date.now() / 1000 < p.exp) {
|
if (p.exp && Date.now() / 1000 < p.exp) {
|
||||||
window.location.href = p.role === 'SUPER_ADMIN' ? 'super-admin.html' : 'dashboard.html';
|
if (p.role === 'SUPER_ADMIN') window.location.href = 'super-admin.html';
|
||||||
|
else if (p.role === 'PATIENT') window.location.href = 'patient-dashboard.html';
|
||||||
|
else window.location.href = 'dashboard.html';
|
||||||
}
|
}
|
||||||
} catch(_) {}
|
} catch(_) {}
|
||||||
}
|
}
|
||||||
|
|
@ -104,6 +106,8 @@
|
||||||
// Route by role
|
// Route by role
|
||||||
if (data.role === 'SUPER_ADMIN') {
|
if (data.role === 'SUPER_ADMIN') {
|
||||||
window.location.href = 'super-admin.html';
|
window.location.href = 'super-admin.html';
|
||||||
|
} else if (data.role === 'PATIENT') {
|
||||||
|
window.location.href = 'patient-dashboard.html';
|
||||||
} else {
|
} else {
|
||||||
window.location.href = 'dashboard.html';
|
window.location.href = 'dashboard.html';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,18 @@
|
||||||
"url": "https://opencollective.com/js-sdsl"
|
"url": "https://opencollective.com/js-sdsl"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nodable/entities": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nodable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@protobufjs/aspromise": {
|
"node_modules/@protobufjs/aspromise": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||||
|
|
@ -296,12 +308,24 @@
|
||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/append-field": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/array-flatten": {
|
"node_modules/array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/async": {
|
||||||
|
"version": "3.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
||||||
|
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
|
@ -329,6 +353,15 @@
|
||||||
"bcrypt": "bin/bcrypt"
|
"bcrypt": "bin/bcrypt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/block-stream2": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": "^3.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.5",
|
"version": "1.20.5",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
||||||
|
|
@ -353,12 +386,44 @@
|
||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/browser-or-node": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/buffer-crc32": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-equal-constant-time": {
|
"node_modules/buffer-equal-constant-time": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer-from": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/busboy": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||||
|
"dependencies": {
|
||||||
|
"streamsearch": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.16.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
|
@ -441,6 +506,21 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||||
|
"engines": [
|
||||||
|
"node >= 6.0"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^3.0.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
|
|
@ -498,6 +578,15 @@
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/decode-uri-component": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/delayed-stream": {
|
"node_modules/delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
|
@ -660,6 +749,12 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "5.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
|
||||||
|
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.22.2",
|
"version": "4.22.2",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
||||||
|
|
@ -712,6 +807,53 @@
|
||||||
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
|
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
|
||||||
"license": "Unlicense"
|
"license": "Unlicense"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-xml-builder": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"path-expression-matcher": "^1.5.0",
|
||||||
|
"xml-naming": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-xml-parser": {
|
||||||
|
"version": "5.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz",
|
||||||
|
"integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nodable/entities": "^2.1.0",
|
||||||
|
"fast-xml-builder": "^1.2.0",
|
||||||
|
"path-expression-matcher": "^1.5.0",
|
||||||
|
"strnum": "^2.3.0",
|
||||||
|
"xml-naming": "^0.1.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"fxparser": "src/cli/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/filter-obj": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
||||||
|
|
@ -1044,6 +1186,12 @@
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
|
||||||
|
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lodash.camelcase": {
|
"node_modules/lodash.camelcase": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||||
|
|
@ -1167,6 +1315,39 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/minio": {
|
||||||
|
"version": "8.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/minio/-/minio-8.0.7.tgz",
|
||||||
|
"integrity": "sha512-E737MgufW8CeQAsTAtnEMrxZ9scMSf29kkhZoXzDTKj/Jszzo2SfeZUH9wbDQH2Rsq6TCtl/yQL0+XdVKZansQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"async": "^3.2.4",
|
||||||
|
"block-stream2": "^2.1.0",
|
||||||
|
"browser-or-node": "^2.1.1",
|
||||||
|
"buffer-crc32": "^1.0.0",
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
|
"fast-xml-parser": "^5.3.4",
|
||||||
|
"ipaddr.js": "^2.0.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
|
"query-string": "^7.1.3",
|
||||||
|
"stream-json": "^1.8.0",
|
||||||
|
"through2": "^4.0.2",
|
||||||
|
"xml2js": "^0.5.0 || ^0.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^16 || ^18 || >=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minio/node_modules/ipaddr.js": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "3.0.0-canary.1",
|
"version": "3.0.0-canary.1",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz",
|
||||||
|
|
@ -1176,6 +1357,25 @@
|
||||||
"node": ">=12.13"
|
"node": ">=12.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/multer": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"append-field": "^1.0.0",
|
||||||
|
"busboy": "^1.6.0",
|
||||||
|
"concat-stream": "^2.0.0",
|
||||||
|
"type-is": "^1.6.18"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.16.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/negotiator": {
|
"node_modules/negotiator": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
|
|
@ -1248,6 +1448,21 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-expression-matcher": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
||||||
|
|
@ -1456,6 +1671,24 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/query-string": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"decode-uri-component": "^0.2.2",
|
||||||
|
"filter-obj": "^1.1.0",
|
||||||
|
"split-on-first": "^1.0.0",
|
||||||
|
"strict-uri-encode": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/range-parser": {
|
"node_modules/range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
|
@ -1480,6 +1713,29 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/razorpay": {
|
||||||
|
"version": "2.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/razorpay/-/razorpay-2.9.6.tgz",
|
||||||
|
"integrity": "sha512-zsHAQzd6e1Cc6BNoCNZQaf65ElL6O6yw0wulxmoG5VQDr363fZC90Mp1V5EktVzG45yPyNomNXWlf4cQ3622gQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readable-stream": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/require-directory": {
|
"node_modules/require-directory": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
|
|
@ -1515,6 +1771,15 @@
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/sax": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/scmp": {
|
"node_modules/scmp": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
|
||||||
|
|
@ -1657,6 +1922,15 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/split-on-first": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/split2": {
|
"node_modules/split2": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
|
@ -1685,6 +1959,47 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stream-chain": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz",
|
||||||
|
"integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/stream-json": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"stream-chain": "^2.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/streamsearch": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strict-uri-encode": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
|
@ -1711,6 +2026,27 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strnum": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/through2": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
|
@ -1757,6 +2093,12 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typedarray": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.24.6",
|
"version": "7.24.6",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||||
|
|
@ -1772,6 +2114,12 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/utils-merge": {
|
"node_modules/utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
|
@ -1820,6 +2168,43 @@
|
||||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xml-naming": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xml2js": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"sax": ">=0.6.0",
|
||||||
|
"xmlbuilder": "~11.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xml2js/node_modules/xmlbuilder": {
|
||||||
|
"version": "11.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||||
|
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xmlbuilder": {
|
"node_modules/xmlbuilder": {
|
||||||
"version": "13.0.2",
|
"version": "13.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,11 @@
|
||||||
"dotenv": "^17.4.2",
|
"dotenv": "^17.4.2",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"jsonwebtoken": "^9.0.3",
|
"jsonwebtoken": "^9.0.3",
|
||||||
|
"minio": "^8.0.7",
|
||||||
|
"multer": "^2.1.1",
|
||||||
"openai": "^6.39.0",
|
"openai": "^6.39.0",
|
||||||
"pg": "^8.21.0",
|
"pg": "^8.21.0",
|
||||||
|
"razorpay": "^2.9.6",
|
||||||
"twilio": "^6.0.2",
|
"twilio": "^6.0.2",
|
||||||
"uuid": "^14.0.0"
|
"uuid": "^14.0.0"
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +94,18 @@
|
||||||
"url": "https://opencollective.com/js-sdsl"
|
"url": "https://opencollective.com/js-sdsl"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nodable/entities": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nodable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@protobufjs/aspromise": {
|
"node_modules/@protobufjs/aspromise": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||||
|
|
@ -312,12 +327,24 @@
|
||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/append-field": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/array-flatten": {
|
"node_modules/array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/async": {
|
||||||
|
"version": "3.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
||||||
|
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
|
@ -345,6 +372,15 @@
|
||||||
"bcrypt": "bin/bcrypt"
|
"bcrypt": "bin/bcrypt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/block-stream2": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": "^3.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.5",
|
"version": "1.20.5",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz",
|
||||||
|
|
@ -369,12 +405,44 @@
|
||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/browser-or-node": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/buffer-crc32": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-equal-constant-time": {
|
"node_modules/buffer-equal-constant-time": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer-from": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/busboy": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||||
|
"dependencies": {
|
||||||
|
"streamsearch": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.16.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
|
@ -457,6 +525,21 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||||
|
"engines": [
|
||||||
|
"node >= 6.0"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^3.0.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
|
|
@ -514,6 +597,15 @@
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/decode-uri-component": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/delayed-stream": {
|
"node_modules/delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
|
@ -676,6 +768,12 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "5.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
|
||||||
|
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.22.2",
|
"version": "4.22.2",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
||||||
|
|
@ -728,6 +826,53 @@
|
||||||
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
|
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
|
||||||
"license": "Unlicense"
|
"license": "Unlicense"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-xml-builder": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"path-expression-matcher": "^1.5.0",
|
||||||
|
"xml-naming": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-xml-parser": {
|
||||||
|
"version": "5.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz",
|
||||||
|
"integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nodable/entities": "^2.1.0",
|
||||||
|
"fast-xml-builder": "^1.2.0",
|
||||||
|
"path-expression-matcher": "^1.5.0",
|
||||||
|
"strnum": "^2.3.0",
|
||||||
|
"xml-naming": "^0.1.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"fxparser": "src/cli/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/filter-obj": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
|
||||||
|
|
@ -1060,6 +1205,12 @@
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
|
||||||
|
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lodash.camelcase": {
|
"node_modules/lodash.camelcase": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||||
|
|
@ -1183,6 +1334,39 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/minio": {
|
||||||
|
"version": "8.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/minio/-/minio-8.0.7.tgz",
|
||||||
|
"integrity": "sha512-E737MgufW8CeQAsTAtnEMrxZ9scMSf29kkhZoXzDTKj/Jszzo2SfeZUH9wbDQH2Rsq6TCtl/yQL0+XdVKZansQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"async": "^3.2.4",
|
||||||
|
"block-stream2": "^2.1.0",
|
||||||
|
"browser-or-node": "^2.1.1",
|
||||||
|
"buffer-crc32": "^1.0.0",
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
|
"fast-xml-parser": "^5.3.4",
|
||||||
|
"ipaddr.js": "^2.0.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
|
"query-string": "^7.1.3",
|
||||||
|
"stream-json": "^1.8.0",
|
||||||
|
"through2": "^4.0.2",
|
||||||
|
"xml2js": "^0.5.0 || ^0.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^16 || ^18 || >=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minio/node_modules/ipaddr.js": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "3.0.0-canary.1",
|
"version": "3.0.0-canary.1",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz",
|
||||||
|
|
@ -1192,6 +1376,25 @@
|
||||||
"node": ">=12.13"
|
"node": ">=12.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/multer": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"append-field": "^1.0.0",
|
||||||
|
"busboy": "^1.6.0",
|
||||||
|
"concat-stream": "^2.0.0",
|
||||||
|
"type-is": "^1.6.18"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.16.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/negotiator": {
|
"node_modules/negotiator": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
|
|
@ -1264,6 +1467,21 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-expression-matcher": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
||||||
|
|
@ -1472,6 +1690,24 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/query-string": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"decode-uri-component": "^0.2.2",
|
||||||
|
"filter-obj": "^1.1.0",
|
||||||
|
"split-on-first": "^1.0.0",
|
||||||
|
"strict-uri-encode": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/range-parser": {
|
"node_modules/range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
|
@ -1496,6 +1732,29 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/razorpay": {
|
||||||
|
"version": "2.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/razorpay/-/razorpay-2.9.6.tgz",
|
||||||
|
"integrity": "sha512-zsHAQzd6e1Cc6BNoCNZQaf65ElL6O6yw0wulxmoG5VQDr363fZC90Mp1V5EktVzG45yPyNomNXWlf4cQ3622gQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readable-stream": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/require-directory": {
|
"node_modules/require-directory": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
|
|
@ -1531,6 +1790,15 @@
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/sax": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/scmp": {
|
"node_modules/scmp": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
|
||||||
|
|
@ -1673,6 +1941,15 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/split-on-first": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/split2": {
|
"node_modules/split2": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
|
@ -1701,6 +1978,47 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stream-chain": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz",
|
||||||
|
"integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/stream-json": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"stream-chain": "^2.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/streamsearch": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strict-uri-encode": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
|
@ -1727,6 +2045,27 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strnum": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/through2": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
|
@ -1773,6 +2112,12 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typedarray": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.24.6",
|
"version": "7.24.6",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||||
|
|
@ -1788,6 +2133,12 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/utils-merge": {
|
"node_modules/utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
|
@ -1836,6 +2187,43 @@
|
||||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xml-naming": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xml2js": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"sax": ">=0.6.0",
|
||||||
|
"xmlbuilder": "~11.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xml2js/node_modules/xmlbuilder": {
|
||||||
|
"version": "11.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||||
|
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xmlbuilder": {
|
"node_modules/xmlbuilder": {
|
||||||
"version": "13.0.2",
|
"version": "13.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
"main": "backend/server.js",
|
"main": "backend/server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node backend/server.js",
|
"start": "node backend/server.js",
|
||||||
"dev": "nodemon backend/server.js"
|
"dev": "nodemon backend/server.js",
|
||||||
|
"logs": "node tools/log-viewer/server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/sdk": "^0.98.0",
|
"@anthropic-ai/sdk": "^0.98.0",
|
||||||
|
|
@ -14,8 +15,11 @@
|
||||||
"dotenv": "^17.4.2",
|
"dotenv": "^17.4.2",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"jsonwebtoken": "^9.0.3",
|
"jsonwebtoken": "^9.0.3",
|
||||||
|
"minio": "^8.0.7",
|
||||||
|
"multer": "^2.1.1",
|
||||||
"openai": "^6.39.0",
|
"openai": "^6.39.0",
|
||||||
"pg": "^8.21.0",
|
"pg": "^8.21.0",
|
||||||
|
"razorpay": "^2.9.6",
|
||||||
"twilio": "^6.0.2",
|
"twilio": "^6.0.2",
|
||||||
"uuid": "^14.0.0"
|
"uuid": "^14.0.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Patient Portal | Curio</title>
|
||||||
|
<link rel="stylesheet" href="globals.css">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
|
||||||
|
<style>
|
||||||
|
.patient-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 300px 1fr;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.patient-layout { grid-template-columns: 1fr; }
|
||||||
|
.sidebar { display: none; }
|
||||||
|
}
|
||||||
|
.main-content {
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.bill-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="dashboard-body patient-layout">
|
||||||
|
<aside class="sidebar">
|
||||||
|
<div class="logo">
|
||||||
|
<span class="logo-icon">C</span>
|
||||||
|
<span class="logo-text">Curio</span>
|
||||||
|
</div>
|
||||||
|
<nav class="side-nav">
|
||||||
|
<a href="#" class="active"><span>🏠</span> Overview</a>
|
||||||
|
<a href="#"><span>📅</span> Appointments</a>
|
||||||
|
<a href="#"><span>📄</span> Medical Records</a>
|
||||||
|
</nav>
|
||||||
|
<div class="user-profile">
|
||||||
|
<div class="avatar" id="avatarInitials">PA</div>
|
||||||
|
<div class="info">
|
||||||
|
<strong id="patientName">Patient Name</strong>
|
||||||
|
<span>Patient</span>
|
||||||
|
<a href="login.html" class="logout-btn" onclick="localStorage.clear()"><span>🚪</span> Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<header style="margin-bottom: 2rem;">
|
||||||
|
<h1>Welcome back, <span id="welcomeName">Patient</span></h1>
|
||||||
|
<p class="text-muted">Manage your appointments, records, and payments.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="settings-grid">
|
||||||
|
<div class="section-card">
|
||||||
|
<h2>Pending Payments</h2>
|
||||||
|
<div id="pendingBills">
|
||||||
|
<div class="bill-card">
|
||||||
|
<div>
|
||||||
|
<strong>Consultation Fee</strong>
|
||||||
|
<div class="text-muted" style="font-size:0.875rem;">Dr. Sharma - Cardiology</div>
|
||||||
|
</div>
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<div style="font-weight:700; color:var(--primary); font-size:1.1rem;">₹500</div>
|
||||||
|
<button class="btn-primary" style="padding:0.4rem 1rem; margin-top:0.5rem;" onclick="initiatePayment(500, 'Consultation Fee')">Pay Now</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-card">
|
||||||
|
<h2>Upcoming Appointments</h2>
|
||||||
|
<div class="bill-card">
|
||||||
|
<div>
|
||||||
|
<strong>Dr. Sharma</strong>
|
||||||
|
<div class="text-muted" style="font-size:0.875rem;">Tomorrow, 10:30 AM</div>
|
||||||
|
</div>
|
||||||
|
<span class="badge badge-success">Confirmed</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const token = localStorage.getItem('curio_token');
|
||||||
|
if (!token) window.location.href = 'login.html';
|
||||||
|
|
||||||
|
const name = localStorage.getItem('userName') || 'Patient';
|
||||||
|
document.getElementById('patientName').innerText = name;
|
||||||
|
document.getElementById('welcomeName').innerText = name;
|
||||||
|
document.getElementById('avatarInitials').innerText = name.substring(0, 2).toUpperCase();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function initiatePayment(amount, description) {
|
||||||
|
try {
|
||||||
|
// 1. Create order on backend
|
||||||
|
const res = await fetch('/api/payments/create-order', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${localStorage.getItem('curio_token')}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ amount, notes: { description } })
|
||||||
|
});
|
||||||
|
|
||||||
|
const orderData = await res.json();
|
||||||
|
if (!res.ok) throw new Error(orderData.error);
|
||||||
|
|
||||||
|
// 2. Initialize Razorpay Checkout
|
||||||
|
const options = {
|
||||||
|
key: 'rzp_test_dummy_key_id', // Replace with Razorpay Key ID
|
||||||
|
amount: orderData.amount,
|
||||||
|
currency: orderData.currency,
|
||||||
|
name: 'Curio HMS',
|
||||||
|
description: description,
|
||||||
|
order_id: orderData.orderId,
|
||||||
|
handler: async function (response) {
|
||||||
|
// 3. Verify Payment
|
||||||
|
const verifyRes = await fetch('/api/payments/verify', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${localStorage.getItem('curio_token')}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify(response)
|
||||||
|
});
|
||||||
|
const verifyData = await verifyRes.json();
|
||||||
|
if (verifyData.success) {
|
||||||
|
alert('Payment successful!');
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
alert('Payment verification failed.');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
prefill: {
|
||||||
|
name: localStorage.getItem('userName'),
|
||||||
|
email: localStorage.getItem('userEmail'),
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
color: '#0F172A' // Curio primary color
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rzp = new Razorpay(options);
|
||||||
|
rzp.open();
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
alert('Error initiating payment. Please try again.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -93,6 +93,19 @@
|
||||||
<input type="number" value="20">
|
<input type="number" value="20">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="section-card">
|
||||||
|
<h2>Services Catalog</h2>
|
||||||
|
<p>Add specialized services/amenities offered by your clinic.</p>
|
||||||
|
<div id="servicesList" style="margin-bottom: 1rem;">
|
||||||
|
<!-- Dynamic List -->
|
||||||
|
</div>
|
||||||
|
<div class="input-group" style="display:flex; gap:0.5rem;">
|
||||||
|
<input type="text" id="newServiceName" placeholder="Service Name (e.g. ECG)">
|
||||||
|
<input type="number" id="newServicePrice" placeholder="Price (₹)" style="width: 100px;">
|
||||||
|
<button class="btn-secondary" onclick="addService()">+ Add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="settings-grid doctor-only hidden">
|
<section class="settings-grid doctor-only hidden">
|
||||||
|
|
@ -132,11 +145,35 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-card">
|
<div class="section-card">
|
||||||
<h2>Digital Signature</h2>
|
<h2>Blocked Dates</h2>
|
||||||
<div class="signature-upload" style="border: 2px dashed var(--border); padding: 2rem; text-align: center; border-radius: var(--radius-md);">
|
<p>Select dates you are unavailable for consultations.</p>
|
||||||
<p>Click to upload or drag your signature image</p>
|
<div class="input-group" style="display:flex; gap:0.5rem;">
|
||||||
<button class="btn-small secondary">Upload Image</button>
|
<input type="date" id="blockDateInput">
|
||||||
|
<button class="btn-secondary" onclick="addBlockDate()">+ Block Date</button>
|
||||||
</div>
|
</div>
|
||||||
|
<ul id="blockedDatesList" style="list-style:none; margin-top:1rem;"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-card">
|
||||||
|
<h2>Profile Media (Public)</h2>
|
||||||
|
<p>Upload a profile video or image for the patient portal.</p>
|
||||||
|
<div class="signature-upload" style="border: 2px dashed var(--border); padding: 2rem; text-align: center; border-radius: var(--radius-md);">
|
||||||
|
<input type="file" id="mediaUploadInput" accept="image/*,video/*" style="display:none;" onchange="uploadMedia()">
|
||||||
|
<p>Click to upload image or video</p>
|
||||||
|
<button class="btn-small secondary" onclick="document.getElementById('mediaUploadInput').click()">Upload Media</button>
|
||||||
|
</div>
|
||||||
|
<div id="mediaPreview" style="margin-top: 1rem; display:flex; gap: 1rem; flex-wrap: wrap;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-card">
|
||||||
|
<h2>Q&A (Public)</h2>
|
||||||
|
<p>Add common questions patients ask you.</p>
|
||||||
|
<div id="qaList" style="margin-bottom: 1rem;"></div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="qaQuestion" placeholder="Question" style="margin-bottom:0.5rem;">
|
||||||
|
<textarea id="qaAnswer" placeholder="Answer" rows="2" style="width:100%; border: 1px solid var(--border); border-radius: var(--radius-md); padding: 0.5rem; font-family: inherit;"></textarea>
|
||||||
|
</div>
|
||||||
|
<button class="btn-secondary" onclick="addQA()" style="margin-top:0.5rem;">+ Add Q&A</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Curio Live Logs</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #0d1117;
|
||||||
|
color: #c9d1d9;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #161b22;
|
||||||
|
padding: 16px 24px;
|
||||||
|
border-bottom: 1px solid #30363d;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.status-dot {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: #238636;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 8px #238636;
|
||||||
|
}
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #21262d;
|
||||||
|
border: 1px solid #30363d;
|
||||||
|
color: #c9d1d9;
|
||||||
|
padding: 6px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #30363d;
|
||||||
|
border-color: #8b949e;
|
||||||
|
}
|
||||||
|
button.active {
|
||||||
|
background-color: #1f6feb;
|
||||||
|
border-color: #1f6feb;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
#terminal {
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-family: "Fira Code", "Consolas", monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
background-color: #010409;
|
||||||
|
}
|
||||||
|
.log-line {
|
||||||
|
margin: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.02);
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
|
.log-error {
|
||||||
|
color: #f85149;
|
||||||
|
}
|
||||||
|
.log-info {
|
||||||
|
color: #58a6ff;
|
||||||
|
}
|
||||||
|
.log-warn {
|
||||||
|
color: #d29922;
|
||||||
|
}
|
||||||
|
.log-success {
|
||||||
|
color: #3fb950;
|
||||||
|
}
|
||||||
|
.log-timestamp {
|
||||||
|
color: #8b949e;
|
||||||
|
user-select: none;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1><div class="status-dot"></div> Curio Live Logs</h1>
|
||||||
|
<div class="controls">
|
||||||
|
<button id="btn-curio-app" class="active" onclick="switchService('curio-app')">Node Backend</button>
|
||||||
|
<button id="btn-curaflow-agent" onclick="switchService('curaflow-agent')">Python AI Agent</button>
|
||||||
|
<button onclick="clearLogs()">Clear</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div id="terminal"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let eventSource = null;
|
||||||
|
const terminal = document.getElementById('terminal');
|
||||||
|
|
||||||
|
function getTimestamp() {
|
||||||
|
const now = new Date();
|
||||||
|
return now.toISOString().split('T')[1].slice(0, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightLine(text) {
|
||||||
|
if (text.includes('[ERROR]') || text.includes('Exception') || text.includes('Failed')) return 'log-error';
|
||||||
|
if (text.includes('[WARN]')) return 'log-warn';
|
||||||
|
if (text.includes('success') || text.includes('Connected') || text.includes('ready')) return 'log-success';
|
||||||
|
if (text.includes('Processing') || text.includes('Triggering')) return 'log-info';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendLog(text, isError) {
|
||||||
|
const line = document.createElement('div');
|
||||||
|
line.className = 'log-line';
|
||||||
|
|
||||||
|
const timeSpan = document.createElement('span');
|
||||||
|
timeSpan.className = 'log-timestamp';
|
||||||
|
timeSpan.textContent = `[${getTimestamp()}]`;
|
||||||
|
|
||||||
|
const textSpan = document.createElement('span');
|
||||||
|
textSpan.className = isError ? 'log-error' : highlightLine(text);
|
||||||
|
textSpan.textContent = text;
|
||||||
|
|
||||||
|
line.appendChild(timeSpan);
|
||||||
|
line.appendChild(textSpan);
|
||||||
|
terminal.appendChild(line);
|
||||||
|
|
||||||
|
// Auto-scroll
|
||||||
|
terminal.scrollTop = terminal.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectSSE(service) {
|
||||||
|
if (eventSource) {
|
||||||
|
eventSource.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
appendLog(`--- Connected to ${service === 'curio-app' ? 'Node Backend' : 'Python AI Agent'} Logs ---`, false);
|
||||||
|
|
||||||
|
eventSource = new EventSource(`/api/logs?service=${service}`);
|
||||||
|
|
||||||
|
eventSource.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
appendLog(data.text, data.isError);
|
||||||
|
};
|
||||||
|
|
||||||
|
eventSource.onerror = (error) => {
|
||||||
|
appendLog('[SSE Error] Connection lost. Reconnecting...', true);
|
||||||
|
eventSource.close();
|
||||||
|
setTimeout(() => connectSSE(service), 3000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchService(service) {
|
||||||
|
document.getElementById('btn-curio-app').classList.remove('active');
|
||||||
|
document.getElementById('btn-curaflow-agent').classList.remove('active');
|
||||||
|
document.getElementById(`btn-${service}`).classList.add('active');
|
||||||
|
|
||||||
|
terminal.innerHTML = '';
|
||||||
|
connectSSE(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLogs() {
|
||||||
|
terminal.innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init
|
||||||
|
connectSSE('curio-app');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
const express = require('express');
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const PORT = 9999;
|
||||||
|
|
||||||
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
|
app.get('/api/logs', (req, res) => {
|
||||||
|
res.setHeader('Content-Type', 'text/event-stream');
|
||||||
|
res.setHeader('Cache-Control', 'no-cache');
|
||||||
|
res.setHeader('Connection', 'keep-alive');
|
||||||
|
res.flushHeaders();
|
||||||
|
|
||||||
|
const service = req.query.service || 'curio-app';
|
||||||
|
let label = 'app=curio-app';
|
||||||
|
if (service === 'curaflow-agent') {
|
||||||
|
label = 'app.kubernetes.io/name=curaflow-agent';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn kubectl logs
|
||||||
|
const kubectl = spawn('kubectl', ['logs', '-f', '-n', 'curio', '-l', label, '--tail=100']);
|
||||||
|
|
||||||
|
kubectl.stdout.on('data', (data) => {
|
||||||
|
const lines = data.toString().split('\n');
|
||||||
|
lines.forEach(line => {
|
||||||
|
if (line.trim()) {
|
||||||
|
res.write(`data: ${JSON.stringify({ text: line, isError: false })}\n\n`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
kubectl.stderr.on('data', (data) => {
|
||||||
|
const lines = data.toString().split('\n');
|
||||||
|
lines.forEach(line => {
|
||||||
|
if (line.trim()) {
|
||||||
|
res.write(`data: ${JSON.stringify({ text: line, isError: true })}\n\n`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
kubectl.on('close', (code) => {
|
||||||
|
res.write(`data: ${JSON.stringify({ text: `[Process exited with code ${code}]`, isError: true })}\n\n`);
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('close', () => {
|
||||||
|
kubectl.kill();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Curio Log Viewer running at http://localhost:${PORT}`);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue