203 lines
5.8 KiB
JavaScript
203 lines
5.8 KiB
JavaScript
const https = require('node:https');
|
|
const { gunzipSync } = require('node:zlib');
|
|
|
|
const HOST = process.env.JTL_HOST || '192.168.178.81';
|
|
const PORT = Number(process.env.JTL_PORT) || 4433;
|
|
|
|
const INIT_QUERY =
|
|
'mandantId=1&lastChangedCategory=0&lastChangedCustomer=0&lastChangedCustomerGroup=0&lastChangedProduct=0&lastChangedConfigurationGroup=0&lastChangedConfigurationItem=0&lastChangedCompositeProduct=0&lastChangedDeletedEntity=0';
|
|
|
|
function usage() {
|
|
console.error('Usage:');
|
|
console.error(' node test-client.js <authCode> [name] # 6-digit: step1+2, 4-digit: step1 only');
|
|
console.error(' node test-client.js init <authToken>');
|
|
console.error(' node test-client.js customergroup <authToken> [lastChangedCustomerGroup]');
|
|
console.error(' node test-client.js deletedentity <authToken> [lastChangedDeletedEntity]');
|
|
console.error(' node test-client.js category <authToken> [lastChangedCategory]');
|
|
console.error(' node test-client.js customer <authToken> [lastChangedCustomer]');
|
|
console.error(' node test-client.js product <authToken> [lastChangedProduct]');
|
|
console.error(' node test-client.js productcomposite <authToken> [lastChangedCompositeProduct]');
|
|
process.exit(1);
|
|
}
|
|
|
|
function posHeaders(authToken) {
|
|
const headers = {
|
|
accept: 'application/json',
|
|
'content-type': 'application/json',
|
|
'cache-control': 'no-cache',
|
|
version: '1.0.11.14',
|
|
system: 'JTL-POS',
|
|
charset: 'utf-8',
|
|
connection: 'Keep-Alive',
|
|
'user-agent':
|
|
'Dalvik/2.1.0 (Linux; U; Android 14; SM-A528B Build/UP1A.231005.007)',
|
|
'accept-encoding': 'gzip',
|
|
};
|
|
|
|
if (authToken) {
|
|
headers.authorization = `Bearer ${authToken}`;
|
|
}
|
|
|
|
return headers;
|
|
}
|
|
|
|
function decodeBody(buffer, headers) {
|
|
if (headers['content-encoding'] === 'gzip') {
|
|
return gunzipSync(buffer);
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
function request(path, authToken) {
|
|
return new Promise((resolve, reject) => {
|
|
const req = https.request(
|
|
{
|
|
hostname: HOST,
|
|
port: PORT,
|
|
path,
|
|
method: 'GET',
|
|
headers: posHeaders(authToken),
|
|
rejectUnauthorized: false,
|
|
},
|
|
(res) => {
|
|
const chunks = [];
|
|
res.on('data', (chunk) => chunks.push(chunk));
|
|
res.on('end', () => {
|
|
const raw = Buffer.concat(chunks);
|
|
resolve({
|
|
statusCode: res.statusCode,
|
|
headers: res.headers,
|
|
body: decodeBody(raw, res.headers),
|
|
});
|
|
});
|
|
}
|
|
);
|
|
|
|
req.on('error', reject);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
function printResponse(res) {
|
|
console.log(`status: ${res.statusCode}`);
|
|
console.log('headers:', JSON.stringify(res.headers, null, 2));
|
|
console.log('body:');
|
|
try {
|
|
console.log(JSON.stringify(JSON.parse(res.body.toString('utf8')), null, 2));
|
|
} catch {
|
|
console.log(res.body.toString('utf8'));
|
|
}
|
|
}
|
|
|
|
async function clientRequest(authCode, name, label) {
|
|
const path = `/api/v1/client?authCode=${encodeURIComponent(authCode)}&name=${encodeURIComponent(name)}`;
|
|
console.log(`${label} GET https://${HOST}:${PORT}${path}\n`);
|
|
const res = await request(path);
|
|
printResponse(res);
|
|
console.log();
|
|
return res;
|
|
}
|
|
|
|
async function main() {
|
|
const mode = process.argv[2];
|
|
|
|
if (!mode) {
|
|
usage();
|
|
}
|
|
|
|
if (mode === 'init') {
|
|
const authToken = process.argv[3] || process.env.AUTH_TOKEN;
|
|
if (!authToken) {
|
|
usage();
|
|
}
|
|
|
|
const path = `/api/v1/init?${INIT_QUERY}`;
|
|
console.log(`GET https://${HOST}:${PORT}${path}\n`);
|
|
|
|
const res = await request(path, authToken);
|
|
printResponse(res);
|
|
return;
|
|
}
|
|
|
|
if (mode === 'customergroup') {
|
|
const authToken = process.argv[3] || process.env.AUTH_TOKEN;
|
|
if (!authToken) {
|
|
usage();
|
|
}
|
|
|
|
const lastChanged = process.argv[4] || '0';
|
|
const path = `/api/v1/customergroup?mandantId=1&lastChangedCustomerGroup=${encodeURIComponent(lastChanged)}`;
|
|
console.log(`GET https://${HOST}:${PORT}${path}\n`);
|
|
|
|
const res = await request(path, authToken);
|
|
printResponse(res);
|
|
return;
|
|
}
|
|
|
|
if (mode === 'deletedentity') {
|
|
const authToken = process.argv[3] || process.env.AUTH_TOKEN;
|
|
if (!authToken) {
|
|
usage();
|
|
}
|
|
|
|
const lastChanged = process.argv[4] || '0';
|
|
const path = `/api/v1/deletedentity?mandantId=1&limit=200&lastChangedDeletedEntity=${encodeURIComponent(lastChanged)}`;
|
|
console.log(`GET https://${HOST}:${PORT}${path}\n`);
|
|
|
|
const res = await request(path, authToken);
|
|
printResponse(res);
|
|
return;
|
|
}
|
|
|
|
const entityModes = {
|
|
category: {
|
|
param: 'lastChangedCategory',
|
|
path: '/api/v1/category?mandantId=1&limit=20',
|
|
},
|
|
customer: {
|
|
param: 'lastChangedCustomer',
|
|
path: '/api/v1/customer?mandantId=1&limit=20',
|
|
},
|
|
product: {
|
|
param: 'lastChangedProduct',
|
|
path: '/api/v1/product?mandantId=1&limit=20',
|
|
},
|
|
productcomposite: {
|
|
param: 'lastChangedCompositeProduct',
|
|
path: '/api/v1/productcomposite?mandantId=1&limit=20',
|
|
},
|
|
};
|
|
|
|
if (entityModes[mode]) {
|
|
const authToken = process.argv[3] || process.env.AUTH_TOKEN;
|
|
if (!authToken) {
|
|
usage();
|
|
}
|
|
|
|
const { param, path: basePath } = entityModes[mode];
|
|
const lastChanged = process.argv[4] || '0';
|
|
const path = `${basePath}&${param}=${encodeURIComponent(lastChanged)}`;
|
|
console.log(`GET https://${HOST}:${PORT}${path}\n`);
|
|
|
|
const res = await request(path, authToken);
|
|
printResponse(res);
|
|
return;
|
|
}
|
|
|
|
const name = process.argv[3] || process.env.CLIENT_NAME || '001';
|
|
const fullCode = mode;
|
|
|
|
if (fullCode.length === 6) {
|
|
await clientRequest(fullCode.slice(0, 4), name, '=== step 1 (4 digits) ===');
|
|
await clientRequest(fullCode, name, '=== step 2 (6 digits) ===');
|
|
return;
|
|
}
|
|
|
|
await clientRequest(fullCode, name, '=== step 1 (4 digits) ===');
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('request failed:', err.message);
|
|
process.exit(1);
|
|
});
|