MOHAN 6582ec5641 feat: add live import progress tracking with job store
- Add jobStore.js: in-memory job store with rich job objects (liveStats,
  logs, errors, cancellation, timing, success rate)
- Rewrite manageProducts.js: structured logging ([STATS], [PRODUCT-OK],
  [PRODUCT-FAIL], [SKIP], [FETCH], [CANCEL], etc.), per-product cancel
  checks, jobStore integration
- server.js: expose GET /health, GET /jobs, GET /jobs/:id,
  POST /jobs/:id/cancel, GET /shops endpoints
- tokenStore.js: add listTokens() export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 02:22:58 +05:30

147 lines
4.1 KiB
JavaScript
Executable File

// // tokenStore.js
// const fs = require('fs');
// const path = require('path');
// const dataFile = path.resolve(__dirname, 'data', 'tokens.json');
// const dataDir = path.dirname(dataFile);
// // ensure data directory and file exist
// if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir);
// if (!fs.existsSync(dataFile)) fs.writeFileSync(dataFile, '{}', 'utf8');
// function readStore() {
// return JSON.parse(fs.readFileSync(dataFile, 'utf8'));
// }
// function saveStore(store) {
// fs.writeFileSync(dataFile, JSON.stringify(store, null, 2), 'utf8');
// }
// function saveToken(shop, accessToken, scope) {
// const store = readStore();
// store[shop] = { accessToken, scope, savedAt: new Date().toISOString() };
// saveStore(store);
// }
// function getToken(shop) {
// const store = readStore();
// return store[shop] || null;
// }
// module.exports = { saveToken, getToken };
// const fs = require('fs');
// const path = require('path');
// const dataFile = path.resolve(__dirname, 'data', 'tokens.json');
// const dataDir = path.dirname(dataFile);
// // Ensure data directory and file exist
// if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir);
// if (!fs.existsSync(dataFile)) fs.writeFileSync(dataFile, '{}', 'utf8');
// function readStore() {
// return JSON.parse(fs.readFileSync(dataFile, 'utf8'));
// }
// function saveStore(store) {
// fs.writeFileSync(dataFile, JSON.stringify(store, null, 2), 'utf8');
// }
// /**
// * Save token data, and optionally fulfillment service details.
// * @param {string} shop - Shopify store domain.
// * @param {string} accessToken - Access token.
// * @param {string} scope - Granted scope.
// * @param {object} [fulfillmentService] - Optional fulfillment service details.
// */
// function saveToken(shop, accessToken, scope, fulfillmentService = null) {
// const store = readStore();
// store[shop] = {
// accessToken,
// scope,
// savedAt: new Date().toISOString(),
// fulfillmentService: fulfillmentService || null
// };
// saveStore(store);
// }
// /**
// * Retrieve stored token (and fulfillment service info if available).
// * @param {string} shop - Shopify store domain.
// * @returns {object|null} Stored token and data.
// */
// function getToken(shop) {
// const store = readStore();
// return store[shop] || null;
// }
// module.exports = { saveToken, getToken };
const fs = require('fs');
const path = require('path');
const dataFile = path.resolve(__dirname, 'data', 'tokens.json');
const dataDir = path.dirname(dataFile);
// Ensure data directory and file exist
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir);
if (!fs.existsSync(dataFile)) fs.writeFileSync(dataFile, '{}', 'utf8');
function readStore() {
return JSON.parse(fs.readFileSync(dataFile, 'utf8'));
}
function saveStore(store) {
fs.writeFileSync(dataFile, JSON.stringify(store, null, 2), 'utf8');
}
/**
* Save token data, and optionally fulfillment service details.
* Will skip update if token params are null or undefined.
* @param {string} shop - Shopify store domain.
* @param {string|null} accessToken - Access token.
* @param {string|null} scope - Granted scope.
* @param {object|null} fulfillmentService - Optional fulfillment service details.
*/
function saveToken(shop, accessToken, scope, fulfillmentService = null,locationId = null) {
if (!shop) return; // Shop is required
const store = readStore();
// If accessToken or scope is null/undefined, do nothing
if (accessToken == null || scope == null) {
return; // Skip update
}
store[shop] = {
accessToken,
scope,
savedAt: new Date().toISOString(),
locationId: locationId || store[shop]?.locationId || null,
fulfillmentService: fulfillmentService || store[shop]?.fulfillmentService || null
};
saveStore(store);
}
/**
* Retrieve stored token (and fulfillment service info if available).
* @param {string} shop - Shopify store domain.
* @returns {object|null} Stored token and data.
*/
function getToken(shop) {
const store = readStore();
return store[shop] || null;
}
function listTokens() {
return readStore();
}
module.exports = { saveToken, getToken, listTokens };