Files
Express_developer_docs/parse_apis.cjs

183 lines
6.4 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const { existingTopics } = require('./original_topics.cjs');
const getApisContent = fs.readFileSync(path.join(__dirname, "Get Api's.txt"), 'utf8');
const postApisContent = fs.readFileSync(path.join(__dirname, "Post, put and delete Api's.txt"), 'utf8');
const endpoints = [];
// Parse GET APIs
let currentGet = null;
const getLines = getApisContent.split('\n');
for (let line of getLines) {
const trimmed = line.trim();
if (trimmed.startsWith('# ')) {
currentGet = { method: 'GET', description: trimmed.substring(2), name: trimmed.substring(2) };
} else if (trimmed.startsWith('https://')) {
if (currentGet) {
currentGet.url = trimmed;
endpoints.push(currentGet);
currentGet = null;
}
}
}
// Better Parse POST/PUT/DELETE APIs
const postLines = postApisContent.split('\n');
let i = 0;
while (i < postLines.length) {
let line = postLines[i].trim();
if (line.startsWith('POST ') || line.startsWith('PUT ') || line.startsWith('DELETE ')) {
const parts = line.split(' ');
const method = parts[0];
const name = parts.slice(1).join(' ');
let url = '';
let body = null;
let description = name;
i++;
while (i < postLines.length) {
let l = postLines[i].trim();
if (l.startsWith('POST ') || l.startsWith('PUT ') || l.startsWith('DELETE ') || l.startsWith('1. ') || l.startsWith('2. ') || l.startsWith('3. ') || l.startsWith('4. ') || l.startsWith('5. ') || l.startsWith('6. ') || l.startsWith('💻') || l.startsWith('📱')) {
break; // Next block starts
}
if (l.startsWith('URL: ')) {
url = l.substring(5).trim();
} else if (l.startsWith('Payload: (Uses the same schema')) {
description += ' ' + l;
} else if (l === 'json') {
// start capturing json
let jsonStr = '';
i++;
while (i < postLines.length) {
let jl = postLines[i].trim();
if (jl.startsWith('POST ') || jl.startsWith('PUT ') || jl.startsWith('DELETE ') || jl.startsWith('1. ') || jl.startsWith('2. ') || jl.startsWith('3. ') || jl.startsWith('4. ') || jl.startsWith('5. ') || jl.startsWith('6. ') || jl.startsWith('💻') || jl.startsWith('📱')) {
break;
}
jsonStr += postLines[i] + '\n';
i++;
}
let rawBody = jsonStr.trim();
try {
body = JSON.parse(rawBody);
} catch (e) {
body = rawBody; // fallback to string
}
continue;
}
i++;
}
if (url) {
const ep = { method, name, description, url };
if (body) {
ep.body = body;
}
endpoints.push(ep);
}
} else {
i++;
}
}
// Second pass: Resolve "Uses the same schema as"
endpoints.forEach(ep => {
if (!ep.body && ep.description.includes('Uses the same schema as')) {
const match = ep.description.match(/Uses the same schema as(.*?)\)/);
if (match) {
let refText = match[1].trim().toLowerCase();
// Try to find the referenced endpoint
let refEp = endpoints.find(e => {
if (!e.body) return false;
let eName = e.name.toLowerCase();
// Remove 'web ' or 'mobile ' for looser matching
refText = refText.replace('web ', '').replace('mobile ', '');
eName = eName.replace('web ', '').replace('mobile ', '');
return refText.includes(eName) || eName.includes(refText);
});
if (refEp) {
ep.body = refEp.body;
}
}
}
});
// Map to topics
const topicMapping = {
'utils': ['utils', 'config', 'category'],
'users': ['user'],
'partners': ['partner', 'rider'],
'tenants': ['tenant', 'location'],
'customers': ['customer'],
'deliveries': ['deliver'],
'orders': ['order'],
'products': ['product', 'catalog', 'stock'],
'invoice': ['invoice'],
'payments': ['payment']
};
const mapToTopic = (url) => {
const urlLower = url.toLowerCase();
for (const [topicId, keywords] of Object.entries(topicMapping)) {
if (urlLower.includes('/' + topicId + '/')) return topicId;
for (const kw of keywords) {
if (urlLower.includes('/' + kw)) return topicId;
}
}
return 'utils';
};
const restTopicsMap = {
utils: { id: 'utils', name: 'Utils', description: 'Shared lookup endpoints roles, locations, configs, app types, pricing.', endpoints: [] },
users: { id: 'users', name: 'Users', description: 'Manage users and roles across the Xpress platform.', endpoints: [] },
partners: { id: 'partners', name: 'Partners', description: 'Partners, riders, locations, shifts, and rider pricing.', endpoints: [] },
tenants: { id: 'tenants', name: 'Tenants', description: 'Tenant accounts info, locations, customers, orders, pricing, summary.', endpoints: [] },
customers: { id: 'customers', name: 'Customers', description: 'Customer accounts, lookups, and search.', endpoints: [] },
deliveries: { id: 'deliveries', name: 'Deliveries', description: 'Delivery records, queues, and rider-delivery joins.', endpoints: [] },
orders: { id: 'orders', name: 'Orders', description: 'Order records, details, and aggregate summaries.', endpoints: [] },
products: { id: 'products', name: 'Products', description: 'Product catalog, categories, and subcategories.', endpoints: [] },
invoice: { id: 'invoice', name: 'Invoice', description: 'Invoice insights and billing analytics.', endpoints: [] },
payments: { id: 'payments', name: 'Payments', description: 'Payment requests and settlements.', endpoints: [] }
};
endpoints.forEach(ep => {
let parsedUrl;
try {
parsedUrl = new URL(ep.url);
} catch (e) {
return;
}
const fullPath = parsedUrl.pathname + parsedUrl.search;
const topicId = mapToTopic(fullPath);
if (restTopicsMap[topicId]) {
const newEp = {
name: ep.name,
method: ep.method,
url: fullPath,
description: ep.description
};
if (ep.body) {
newEp.body = ep.body;
}
restTopicsMap[topicId].endpoints.push(newEp);
}
});
const restTopics = Object.values(restTopicsMap);
const out = `export const LEGACY_BASE_URL = 'https://api.workolik.com';
export const REST_BASE_URL = 'https://fiesta.nearle.app';
export const legacyTopics = ${JSON.stringify(existingTopics, null, 2)};
export const restTopics = ${JSON.stringify(restTopics, null, 2)};
`;
fs.writeFileSync(path.join(__dirname, 'src', 'data', 'topics.js'), out, 'utf8');
console.log('Successfully updated topics.js with ' + endpoints.length + ' parsed endpoints (fixed payload parsing).');