Compare commits
10 Commits
f28ad3a716
...
3e39b9c36a
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e39b9c36a | |||
|
|
5543f87348 | ||
|
|
e24db52732 | ||
| e5b530f9a4 | |||
| 2542bb1f44 | |||
|
|
15485bb405 | ||
| b3bca576da | |||
| 0de64d4024 | |||
|
|
7fce4cf7b8 | ||
|
|
3942864554 |
15
.env
15
.env
@ -1,15 +0,0 @@
|
|||||||
GOOGLE_API_KEY="AIzaSyCTrRFGKCZSspHRmTWQiclmIEOg-LROgyo"
|
|
||||||
API_URL="https://plutao.geogridmaps.com.br/vale/api/v3/viabilidade/raio"
|
|
||||||
API_KEY="6d717e972ba17c7cf0ab731801b8bbeac2f281e5"
|
|
||||||
COKIE="PHPSESSID=6d717e972ba17c7cf0ab731801b8bbeac2f281e5"
|
|
||||||
PORT="3000"
|
|
||||||
|
|
||||||
OAUTH_CLIENT_ID=e2104cd1-d67c-4ac1-8fe2-36e8caac89b7
|
|
||||||
OAUTH_CLIENT_SECRET=sVj8Q~eSXJpnQoqjvpOwjYeesVf_DJNRqTa4ua-6
|
|
||||||
OAUTH_TENANT_ID=5cd8533a-4260-48c5-87fd-8511b1b42f9b
|
|
||||||
OAUTH_REDIRECT_URI=https://viabiliza.sothis.com.br/auth/callback
|
|
||||||
OAUTH_SCOPES=https://graph.microsoft.com/.default
|
|
||||||
SESSION_SECRET=j2633669
|
|
||||||
|
|
||||||
NODE_ENV=production
|
|
||||||
DEV_SKIP_AUTH=false
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,3 +4,5 @@ node_modules/
|
|||||||
.vscode/
|
.vscode/
|
||||||
.cache/
|
.cache/
|
||||||
uploads/
|
uploads/
|
||||||
|
.cache/
|
||||||
|
.vscode/
|
||||||
1
.node-version
Normal file
1
.node-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
20
|
||||||
709
app.js
709
app.js
@ -1,669 +1,82 @@
|
|||||||
require("dotenv").config();
|
const requireAuth = require('./middlewares/requireAuth');
|
||||||
|
const authRoutes = require('./routes/authRoutes');
|
||||||
|
const express = require('express');
|
||||||
|
const path = require('path');
|
||||||
|
const session = require('express-session');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
const express = require("express");
|
const viabilidadeRoutes = require('./routes/viabilidadeRoutes');
|
||||||
const multer = require("multer");
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
const csv = require("csv-parser");
|
|
||||||
const fastCsv = require("fast-csv");
|
|
||||||
const axios = require("axios");
|
|
||||||
const cors = require("cors");
|
|
||||||
const session = require("express-session"); // adiciona session
|
|
||||||
const { geocodeWithGoogle, addressWithGoogle } = require("./service/geocodeService");
|
|
||||||
const { fetchJson } = require("./service/fetchService");
|
|
||||||
const { BASE_BACKOFF_MS, MAX_RETRIES, REQUEST_DELAY_MS, sleep } = require("./service/retryService");
|
|
||||||
const { API_URL, HEADERS } = require("./config/apiConfig");
|
|
||||||
const { normalizePartnerSigla } = require("./service/normalizeService");
|
|
||||||
const authRoutes = require("./routes/authRoutes.js");
|
|
||||||
|
|
||||||
function createApp() {
|
const app = express();
|
||||||
const upload = multer({ dest: "uploads/" });
|
|
||||||
const app = express();
|
|
||||||
|
|
||||||
// se estiver atrás de um reverse proxy (nginx/traefik) em produção, habilite:
|
// Basic middleware
|
||||||
app.set("trust proxy", 1);
|
app.use(express.json({ limit: '5mb' }));
|
||||||
|
app.use(express.urlencoded({ extended: true }));
|
||||||
|
|
||||||
app.use(cors());
|
// Session (in-memory, fine for dev/tests)
|
||||||
app.use(express.json());
|
app.use(session({
|
||||||
|
secret: process.env.SESSION_SECRET || 'dev-secret',
|
||||||
// session TEM que vir antes das rotas que usam req.session
|
|
||||||
app.use(
|
|
||||||
session({
|
|
||||||
secret: process.env.SESSION_SECRET || "change-me",
|
|
||||||
resave: false,
|
resave: false,
|
||||||
saveUninitialized: false,
|
saveUninitialized: false,
|
||||||
cookie: {
|
cookie: { secure: false } // secure should be true behind HTTPS in prod
|
||||||
maxAge: 24 * 60 * 60 * 1000,
|
}));
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
sameSite: "lax",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// -- Desenvolvimento: pular autenticação se configurado
|
// Registrar authRoutes primeiro (rotas de login)
|
||||||
// Para ativar: defina NODE_ENV=development e DEV_SKIP_AUTH=true no .env
|
app.use(authRoutes);
|
||||||
if (process.env.NODE_ENV === 'development' && process.env.DEV_SKIP_AUTH === 'true') {
|
|
||||||
|
// Dev bypass for Microsoft auth / session (only when explicitly enabled)
|
||||||
|
// MUST come before the global protection middleware so it can insert req.session.user
|
||||||
|
if (process.env.NODE_ENV === 'development' && process.env.DEV_SKIP_AUTH === 'true') {
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
// garante que exista uma sessão autenticada para facilitar testes locais
|
if (!req.session) return next();
|
||||||
if (req.session && (!req.session.user || !req.session.user.authenticated)) {
|
// note: property must be `authenticated` (with 'h') so requireAuth recognizes it
|
||||||
req.session.user = { authenticated: true, dev: true };
|
req.session.user = req.session.user || { authenticated: true, id: 'dev', name: 'developer' };
|
||||||
}
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// middleware que protege rotas que exigem login
|
// Note: static assets must be served AFTER the global protection middleware
|
||||||
function requireAuth(req, res, next) {
|
// when you want the site to redirect to /login before delivering the UI.
|
||||||
if (req.session?.user?.authenticated) {
|
|
||||||
|
// Proteção global (após static + dev bypass)
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
if (
|
||||||
|
req.path.startsWith('/auth') ||
|
||||||
|
req.path === '/login' ||
|
||||||
|
req.path === '/health'
|
||||||
|
) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.xhr || req.headers.accept?.includes("application/json")) {
|
|
||||||
return res.status(401).json({ error: "not_authenticated" });
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.redirect("/login");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// proteger demais rotas (ex.: /upload, /consulta)
|
|
||||||
app.use((req, res, next) => {
|
|
||||||
// permissão liberada para rotas de auth já tratadas; proteger o resto
|
|
||||||
if (req.path.startsWith("/auth") || req.path === "/login") return next();
|
|
||||||
return requireAuth(req, res, next);
|
return requireAuth(req, res, next);
|
||||||
});
|
});
|
||||||
|
|
||||||
// redirect raiz
|
// Serve static assets (UI) AFTER protection so the app redirects to /login first
|
||||||
app.get("/", (req, res) => {
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
// em dev com bypass, sirva a página diretamente (sem redirect)
|
|
||||||
|
// Mount API routes
|
||||||
|
app.use('/', viabilidadeRoutes);
|
||||||
|
|
||||||
|
// Health endpoint
|
||||||
|
app.get('/health', (req, res) => res.json({ ok: true }));
|
||||||
|
|
||||||
|
// 404
|
||||||
|
app.use((req, res) => res.status(404).json({ error: 'Not found' }));
|
||||||
|
|
||||||
|
// Error handler
|
||||||
|
app.use((err, req, res, next) => {
|
||||||
|
console.error(err && (err.stack || err.message) || err);
|
||||||
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
|
});
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
const port = parseInt(process.env.PORT, 10) || 3000;
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server listening on port ${port} (env=${process.env.NODE_ENV || 'production'})`);
|
||||||
if (process.env.NODE_ENV === 'development' && process.env.DEV_SKIP_AUTH === 'true') {
|
if (process.env.NODE_ENV === 'development' && process.env.DEV_SKIP_AUTH === 'true') {
|
||||||
return res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
console.log('[START-NOAUTH] DEV_SKIP_AUTH=true — authentication is bypassed');
|
||||||
}
|
|
||||||
|
|
||||||
if (req.session?.user?.authenticated) {
|
|
||||||
return res.redirect("/public/index.html");
|
|
||||||
}
|
|
||||||
return res.redirect("/login");
|
|
||||||
});
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
async function getMinDistance(lat, lon) {
|
|
||||||
// tenta várias vezes com backoff exponencial; trata 429 usando Retry-After se disponível
|
|
||||||
let attempt = 0;
|
|
||||||
while (attempt < MAX_RETRIES) {
|
|
||||||
try {
|
|
||||||
// envia também o raio (em metros) - API espera esse parâmetro em várias rotas
|
|
||||||
const resp = await axios.get(API_URL, {
|
|
||||||
headers: HEADERS,
|
|
||||||
params: {
|
|
||||||
raio: 5000,
|
|
||||||
latitude: lat,
|
|
||||||
longitude: lon,
|
|
||||||
"itens[]": ["caixa"],
|
|
||||||
consultarPasta: "S",
|
|
||||||
},
|
|
||||||
timeout: 10000,
|
|
||||||
});
|
|
||||||
const data = resp.data;
|
|
||||||
const registros = data && data.registros ? data.registros : [];
|
|
||||||
// find registros that have a numeric distancia and keep original object for robust extraction
|
|
||||||
const candidates = registros
|
|
||||||
.map((r) => ({ raw: r, distanciaRaw: r && r.distancia }))
|
|
||||||
.map((o) => ({
|
|
||||||
raw: o.raw,
|
|
||||||
num:
|
|
||||||
o.distanciaRaw !== undefined &&
|
|
||||||
o.distanciaRaw !== null &&
|
|
||||||
o.distanciaRaw !== ""
|
|
||||||
? Number(o.distanciaRaw)
|
|
||||||
: null,
|
|
||||||
}))
|
|
||||||
.filter((x) => x.num !== null && !Number.isNaN(x.num));
|
|
||||||
if (candidates.length) {
|
|
||||||
candidates.sort((a, b) => a.num - b.num);
|
|
||||||
const best = candidates[0];
|
|
||||||
const r = best.raw || {};
|
|
||||||
// robust extraction of pasta sigla with fallbacks
|
|
||||||
let pastaSigla = null;
|
|
||||||
try {
|
|
||||||
if (r.pasta) {
|
|
||||||
if (typeof r.pasta === "string" && r.pasta.trim())
|
|
||||||
pastaSigla = r.pasta.trim();
|
|
||||||
else if (r.pasta.sigla && String(r.pasta.sigla).trim())
|
|
||||||
pastaSigla = String(r.pasta.sigla).trim();
|
|
||||||
else if (
|
|
||||||
r.pasta.cidade &&
|
|
||||||
r.pasta.cidade.sigla &&
|
|
||||||
String(r.pasta.cidade.sigla).trim()
|
|
||||||
)
|
|
||||||
pastaSigla = String(r.pasta.cidade.sigla).trim();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
pastaSigla = null;
|
|
||||||
}
|
|
||||||
// if closest has no pastaSigla, try find any candidate with non-empty sigla
|
|
||||||
if (!pastaSigla) {
|
|
||||||
for (let j = 0; j < candidates.length; j++) {
|
|
||||||
const rr = candidates[j].raw || {};
|
|
||||||
try {
|
|
||||||
if (rr.pasta) {
|
|
||||||
if (typeof rr.pasta === "string" && rr.pasta.trim()) {
|
|
||||||
pastaSigla = rr.pasta.trim();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rr.pasta.sigla && String(rr.pasta.sigla).trim()) {
|
|
||||||
pastaSigla = String(rr.pasta.sigla).trim();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
rr.pasta.cidade &&
|
|
||||||
rr.pasta.cidade.sigla &&
|
|
||||||
String(rr.pasta.cidade.sigla).trim()
|
|
||||||
) {
|
|
||||||
pastaSigla = String(rr.pasta.cidade.sigla).trim();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!pastaSigla)
|
|
||||||
console.warn(
|
|
||||||
`[WARN] Nenhuma pasta.sigla encontrada para coordenadas ${lat},${lon} (closest dist ${best.num})`
|
|
||||||
);
|
|
||||||
pastaSigla = normalizePartnerSigla(pastaSigla);
|
|
||||||
return { dist: best.num, pastaSigla };
|
|
||||||
}
|
|
||||||
// sem distancias válidas
|
|
||||||
return null;
|
|
||||||
} catch (err) {
|
|
||||||
attempt += 1;
|
|
||||||
// se for 429, tente respeitar Retry-After quando disponível
|
|
||||||
if (err.response && err.response.status === 429) {
|
|
||||||
const ra =
|
|
||||||
err.response.headers &&
|
|
||||||
(err.response.headers["retry-after"] ||
|
|
||||||
err.response.headers["Retry-After"]);
|
|
||||||
let waitMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
|
|
||||||
if (ra) {
|
|
||||||
const raSec = parseInt(ra, 10);
|
|
||||||
if (!isNaN(raSec)) waitMs = raSec * 1000;
|
|
||||||
}
|
|
||||||
console.warn(
|
|
||||||
`[WARN] 429 recebido para ${lat},${lon} - aguardando ${waitMs}ms e tentando novamente (attempt ${attempt}/${MAX_RETRIES})`
|
|
||||||
);
|
|
||||||
await sleep(waitMs);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// para outros erros de rede/timeout, aguarda backoff exponencial e tenta de novo
|
|
||||||
const waitMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
|
|
||||||
console.warn(
|
|
||||||
`[WARN] Erro ao consultar API para ${lat},${lon}: ${err.message} - backoff ${waitMs}ms (attempt ${attempt}/${MAX_RETRIES})`
|
|
||||||
);
|
|
||||||
await sleep(waitMs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// exauriu tentativas
|
|
||||||
console.error(`[ERROR] Exauriu retries para ${lat},${lon}`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// upload CSV endpoint
|
|
||||||
const jobs = {}; // jobId -> { status, total, processed, download, error }
|
|
||||||
|
|
||||||
app.post("/upload", upload.single("csvfile"), (req, res) => {
|
|
||||||
if (!req.file)
|
|
||||||
return res.status(400).json({ error: "Nenhum arquivo enviado" });
|
|
||||||
const filePath = req.file.path;
|
|
||||||
const jobId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
||||||
jobs[jobId] = {
|
|
||||||
status: "queued",
|
|
||||||
total: 0,
|
|
||||||
processed: 0,
|
|
||||||
download: null,
|
|
||||||
error: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
jobs[jobId].status = "processing";
|
|
||||||
try {
|
|
||||||
const rows = [];
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
fs.createReadStream(filePath)
|
|
||||||
.pipe(csv({ separator: ";" }))
|
|
||||||
.on("data", (data) => {
|
|
||||||
// ignora linhas totalmente vazias (todos os campos nulos/undefined/strings vazias)
|
|
||||||
const values = Object.values(data);
|
|
||||||
const allEmpty =
|
|
||||||
values.length === 0 ||
|
|
||||||
values.every(
|
|
||||||
(v) => v === null || v === undefined || String(v).trim() === ""
|
|
||||||
);
|
|
||||||
if (!allEmpty) rows.push(data);
|
|
||||||
})
|
|
||||||
.on("end", resolve)
|
|
||||||
.on("error", reject);
|
|
||||||
});
|
|
||||||
|
|
||||||
jobs[jobId].total = rows.length;
|
|
||||||
|
|
||||||
const coordCache = new Map();
|
|
||||||
|
|
||||||
const outRows = [];
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
const row = rows[i];
|
|
||||||
// normalize keys to avoid duplicates caused by different headers
|
|
||||||
const norm = {};
|
|
||||||
Object.keys(row).forEach((k) => {
|
|
||||||
// normalize header: lowercase, remove diacritics and non-alphanumeric
|
|
||||||
const kn = k
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
.normalize("NFKD")
|
|
||||||
.replace(/[\u0300-\u036f]/g, "")
|
|
||||||
.replace(/[^a-z0-9]/g, "");
|
|
||||||
norm[kn] = row[k];
|
|
||||||
});
|
|
||||||
|
|
||||||
// Input columns (from normalized map)
|
|
||||||
const rawCep = norm["cep"]
|
|
||||||
? String(norm["cep"]).replace(/\D/g, "")
|
|
||||||
: "";
|
|
||||||
const rawNumero = norm["numero"] ? String(norm["numero"]).trim() : "";
|
|
||||||
// prefer lat/lon from normalized input if available
|
|
||||||
const rawLat = norm["latitude"] || norm["lat"] || null;
|
|
||||||
const rawLon =
|
|
||||||
norm["longitude"] || norm["lon"] || norm["long"] || null;
|
|
||||||
|
|
||||||
// Prefer existing lat/lon if provided from normalized fields
|
|
||||||
let lat = null,
|
|
||||||
lon = null;
|
|
||||||
if (rawLat && rawLon) {
|
|
||||||
lat = Number(String(rawLat).replace(",", "."));
|
|
||||||
lon = Number(String(rawLon).replace(",", "."));
|
|
||||||
}
|
|
||||||
|
|
||||||
let builtAddress = "";
|
|
||||||
|
|
||||||
const googleGeocodeAddress = await addressWithGoogle(lat, lon);
|
|
||||||
if (googleGeocodeAddress) {
|
|
||||||
builtAddress = googleGeocodeAddress;
|
|
||||||
} else {
|
|
||||||
console.warn(
|
|
||||||
`Google Reverse Geocoding não retornou resultado para coords ${lat},${lon} (row ${i + 1})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Row ${i + 1}: CEP='${rawCep}' Número='${rawNumero}' Lat='${lat}' Lon='${lon}' BuiltAddress='${builtAddress}'`);
|
|
||||||
|
|
||||||
// If no coords, try ViaCEP -> Google
|
|
||||||
if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
|
|
||||||
if (rawCep) {
|
|
||||||
const cep8 = rawCep.padStart(8, "0");
|
|
||||||
const cepRestData = await fetch(
|
|
||||||
'https://api.cep.rest/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ cep: cep8 })
|
|
||||||
}
|
|
||||||
).then(r => r.json());
|
|
||||||
if (cepRestData && !cepRestData.erro) {
|
|
||||||
const logradouro = cepRestData.data.logradouro || "";
|
|
||||||
const bairro = cepRestData.data.bairro || "";
|
|
||||||
const cidade = cepRestData.data.localidade || "";
|
|
||||||
const uf = cepRestData.data.uf || "";
|
|
||||||
if (logradouro) {
|
|
||||||
builtAddress =
|
|
||||||
`${logradouro}, ${rawNumero}, ${bairro}, ${cidade} - ${uf}`
|
|
||||||
.replace(/, ,/g, ",")
|
|
||||||
.replace(/^,\s*/, "");
|
|
||||||
} else {
|
|
||||||
// fallback: use neighborhood/city
|
|
||||||
builtAddress = `${bairro || ""} ${
|
|
||||||
cidade ? ", " + cidade : ""
|
|
||||||
} ${uf ? "- " + uf : ""}`.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
// build addressToUse (builtAddress already assembled above)
|
|
||||||
if (!process.env.GOOGLE_API_KEY) {
|
|
||||||
console.error(
|
|
||||||
"[ERROR] GOOGLE_API_KEY não definida. Não será possível geocodificar. Defina a chave no .env ou em process.env"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const addressToUse =
|
|
||||||
builtAddress || `${cidade} ${uf} ${cep8}`;
|
|
||||||
const geo = await geocodeWithGoogle(addressToUse);
|
|
||||||
if (geo) {
|
|
||||||
lat = geo.lat;
|
|
||||||
lon = geo.lon;
|
|
||||||
} else
|
|
||||||
console.warn(
|
|
||||||
`Google Geocoding não retornou resultado para '${addressToUse}' (CEP ${cep8}, row ${
|
|
||||||
i + 1
|
|
||||||
})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.warn(`ViaCEP erro for CEP ${rawCep} (row ${i + 1})`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(`Row ${i + 1}: missing/invalid CEP -> '${rawCep}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare explicit output row to avoid extra columns
|
|
||||||
const out = {
|
|
||||||
CEP: rawCep || "",
|
|
||||||
Número: rawNumero || "",
|
|
||||||
Endereço: builtAddress || "",
|
|
||||||
// write lat/lon as strings with dot decimal and fixed precision to avoid locale swaps
|
|
||||||
Latitude: Number.isFinite(lat) ? Number(lat).toFixed(6) : "",
|
|
||||||
Longitude: Number.isFinite(lon) ? Number(lon).toFixed(6) : "",
|
|
||||||
"Não dedicado": "",
|
|
||||||
Dedicado: "",
|
|
||||||
Distancia: "",
|
|
||||||
"Parceiro/Sothis": "",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Number.isFinite(lat) && Number.isFinite(lon)) {
|
|
||||||
const coordKey = `${lat.toFixed(6)},${lon.toFixed(6)}`;
|
|
||||||
if (coordCache.has(coordKey)) {
|
|
||||||
const cached = coordCache.get(coordKey); // cached is either null or { dist, pastaSigla }
|
|
||||||
if (cached !== null) {
|
|
||||||
const d = cached.dist;
|
|
||||||
const di = Math.round(Number(d));
|
|
||||||
out["Não dedicado"] = di <= 500 ? "viável" : "Não viável";
|
|
||||||
out["Dedicado"] = di <= 1000 ? "viável" : "Não viável";
|
|
||||||
out["Distancia"] = `${di}M`;
|
|
||||||
out["Parceiro/Sothis"] =
|
|
||||||
normalizePartnerSigla(cached.pastaSigla) || "";
|
|
||||||
} else {
|
|
||||||
out["Não dedicado"] = "Não viável";
|
|
||||||
out["Dedicado"] = "Não viável";
|
|
||||||
out["Distancia"] = "5km +";
|
|
||||||
out["Parceiro/Sothis"] = "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const minResult = await getMinDistance(lat, lon); // { dist, pastaSigla } or null
|
|
||||||
coordCache.set(coordKey, minResult);
|
|
||||||
if (minResult !== null) {
|
|
||||||
const di = Math.round(Number(minResult.dist));
|
|
||||||
out["Não dedicado"] = di <= 500 ? "viável" : "Não viável";
|
|
||||||
out["Dedicado"] = di <= 1000 ? "viável" : "Não viável";
|
|
||||||
out["Distancia"] = `${di}M`;
|
|
||||||
out["Parceiro/Sothis"] =
|
|
||||||
normalizePartnerSigla(minResult.pastaSigla) || "";
|
|
||||||
} else {
|
|
||||||
out["Não dedicado"] = "Não viável";
|
|
||||||
out["Dedicado"] = "Não viável";
|
|
||||||
out["Distancia"] = "5km +";
|
|
||||||
out["Parceiro/Sothis"] = "";
|
|
||||||
}
|
|
||||||
await sleep(REQUEST_DELAY_MS);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no coords available -> keep defaults
|
|
||||||
}
|
|
||||||
|
|
||||||
outRows.push(out);
|
|
||||||
jobs[jobId].processed = i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write output csv - use explicit outRows and fixed header order
|
|
||||||
const outPath = path.join(__dirname, "outputs");
|
|
||||||
if (!fs.existsSync(outPath)) fs.mkdirSync(outPath);
|
|
||||||
const originalName =
|
|
||||||
req.file && req.file.originalname
|
|
||||||
? req.file.originalname
|
|
||||||
: `upload_${Date.now()}.csv`;
|
|
||||||
const parsed = path.parse(originalName);
|
|
||||||
let outBase = `${parsed.name}_output`;
|
|
||||||
let outFile = path.join(outPath, `${outBase}.csv`);
|
|
||||||
if (fs.existsSync(outFile)) {
|
|
||||||
outFile = path.join(outPath, `${outBase}_${Date.now()}.csv`);
|
|
||||||
}
|
|
||||||
const headers = [
|
|
||||||
"CEP",
|
|
||||||
"Número",
|
|
||||||
"Endereço",
|
|
||||||
"Latitude",
|
|
||||||
"Longitude",
|
|
||||||
"Não dedicado",
|
|
||||||
"Dedicado",
|
|
||||||
"Distancia",
|
|
||||||
"Parceiro/Sothis",
|
|
||||||
];
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
const ws = fs.createWriteStream(outFile);
|
|
||||||
ws.write("\uFEFF");
|
|
||||||
fastCsv
|
|
||||||
.write(outRows, { headers: headers, delimiter: ";" })
|
|
||||||
.pipe(ws)
|
|
||||||
.on("finish", resolve)
|
|
||||||
.on("error", reject);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.unlinkSync(filePath);
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
jobs[jobId].status = "done";
|
|
||||||
jobs[jobId].download = `/download/${path.basename(outFile)}`;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
jobs[jobId].status = "error";
|
|
||||||
jobs[jobId].error = String(err.message || err);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
return res.json({ jobId });
|
|
||||||
});
|
|
||||||
|
|
||||||
// download model endpoint
|
|
||||||
app.get("/download-model", (req, res) => {
|
|
||||||
const modelPath = path.join(__dirname, "models", "modelo.viabilidade.csv");
|
|
||||||
if (!fs.existsSync(modelPath)) return res.status(404).send("Modelo não encontrado");
|
|
||||||
return res.download(modelPath, "modelo.viabilidade.csv");
|
|
||||||
});
|
|
||||||
|
|
||||||
// download result endpoint
|
|
||||||
app.get("/download/:name", (req, res) => {
|
|
||||||
const name = req.params.name;
|
|
||||||
const p = path.join(__dirname, "outputs", name);
|
|
||||||
if (!fs.existsSync(p))
|
|
||||||
return res.status(404).send("Arquivo não encontrado");
|
|
||||||
res.download(p);
|
|
||||||
});
|
|
||||||
|
|
||||||
// job status endpoint
|
|
||||||
app.get("/status/:jobId", (req, res) => {
|
|
||||||
const job = jobs[req.params.jobId];
|
|
||||||
if (!job) return res.status(404).json({ error: "job não encontrado" });
|
|
||||||
return res.json(job);
|
|
||||||
});
|
|
||||||
|
|
||||||
// manual query endpoint
|
|
||||||
// /consulta now accepts either latitude+longitude OR cep+numero. If cep is provided we resolve ViaCEP -> Google -> Geogrid
|
|
||||||
app.get("/consulta", async (req, res) => {
|
|
||||||
const {
|
|
||||||
latitude: rawLat,
|
|
||||||
longitude: rawLon,
|
|
||||||
cep: rawCep,
|
|
||||||
numero: rawNumero,
|
|
||||||
} = req.query;
|
|
||||||
|
|
||||||
// If cep provided, use ViaCEP -> Google geocoding -> Geogrid
|
|
||||||
if (rawCep) {
|
|
||||||
const cep = String(rawCep).replace(/\D/g, "");
|
|
||||||
const numero = rawNumero ? String(rawNumero).trim() : "";
|
|
||||||
try {
|
|
||||||
const viaCepData = await fetch(
|
|
||||||
'https://api.cep.rest/', { method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ cep })
|
|
||||||
}
|
|
||||||
).then(r => r.json());
|
|
||||||
if (!viaCepData || viaCepData.erro)
|
|
||||||
return res.status(404).json({ error: "CEP não encontrado" });
|
|
||||||
const logradouro = viaCepData.data.logradouro || "";
|
|
||||||
const bairro = viaCepData.data.bairro || "";
|
|
||||||
const cidade = viaCepData.data.localidade || "";
|
|
||||||
const uf = viaCepData.data.uf || "";
|
|
||||||
const endereco =
|
|
||||||
`${logradouro}, ${numero}, ${bairro}, ${cidade} - ${uf}`
|
|
||||||
.replace(/, ,/g, ",")
|
|
||||||
.replace(/^,\s*/, "");
|
|
||||||
|
|
||||||
if (!process.env.GOOGLE_API_KEY)
|
|
||||||
return res
|
|
||||||
.status(500)
|
|
||||||
.json({ error: "GOOGLE_API_KEY não definida no servidor" });
|
|
||||||
const geo = await geocodeWithGoogle(
|
|
||||||
endereco || `${cidade} ${uf} ${cep}`
|
|
||||||
);
|
|
||||||
if (!geo)
|
|
||||||
return res
|
|
||||||
.status(404)
|
|
||||||
.json({ error: "geocode não encontrado (Google)" });
|
|
||||||
const lat = Number(geo.lat);
|
|
||||||
const lon = Number(geo.lon);
|
|
||||||
const result = await getMinDistance(lat, lon);
|
|
||||||
if (result && result.dist !== undefined) {
|
|
||||||
return res.json({
|
|
||||||
endereco,
|
|
||||||
latitude: lat,
|
|
||||||
longitude: lon,
|
|
||||||
distancia: result.dist,
|
|
||||||
parceiro: result.pastaSigla || "",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return res.json({
|
|
||||||
endereco,
|
|
||||||
latitude: lat,
|
|
||||||
longitude: lon,
|
|
||||||
distancia: "5km +",
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return res.status(500).json({ error: "Erro na consulta" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise require latitude+longitude
|
|
||||||
if (!rawLat || !rawLon)
|
|
||||||
return res.status(400).json({
|
|
||||||
error: "latitude e longitude são obrigatórios (ou forneça cep)",
|
|
||||||
});
|
|
||||||
const latitude = Number(String(rawLat).replace(",", "."));
|
|
||||||
const longitude = Number(String(rawLon).replace(",", "."));
|
|
||||||
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
|
|
||||||
console.warn(
|
|
||||||
`Consulta manual com parâmetros inválidos: lat='${rawLat}' lon='${rawLon}'`
|
|
||||||
);
|
|
||||||
return res.status(400).json({ error: "latitude ou longitude inválidos" });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log(`Consulta manual: lat=${latitude} lon=${longitude}`);
|
|
||||||
const result = await getMinDistance(latitude, longitude);
|
|
||||||
console.log(`Resultado consulta manual: ${JSON.stringify(result)}`);
|
|
||||||
if (result && result.dist !== undefined) {
|
|
||||||
return res.json({
|
|
||||||
distancia: result.dist,
|
|
||||||
parceiro: result.pastaSigla || "",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return res.json({ distancia: "5km +" });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return res.status(500).json({ error: "Erro na consulta" });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// manual CEP+Numero query: resolves ViaCEP -> Nominatim -> Geogrid
|
|
||||||
app.get("/consulta-cep", async (req, res) => {
|
|
||||||
const { cep: rawCep, numero: rawNumero } = req.query;
|
|
||||||
if (!rawCep) return res.status(400).json({ error: "cep é obrigatório" });
|
|
||||||
const cep = String(rawCep).replace(/\D/g, "");
|
|
||||||
const numero = rawNumero ? String(rawNumero).trim() : "";
|
|
||||||
|
|
||||||
try {
|
|
||||||
const cepRestData = await fetch(
|
|
||||||
'https://api.cep.rest/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ cep })
|
|
||||||
}
|
|
||||||
).then(r => r.json());
|
|
||||||
if (!cepRestData || cepRestData.erro)
|
|
||||||
return res.status(404).json({ error: "CEP não encontrado" });
|
|
||||||
const logradouro = cepRestData.data.logradouro || "";
|
|
||||||
const bairro = cepRestData.data.bairro || "";
|
|
||||||
const cidade = cepRestData.data.localidade || "";
|
|
||||||
const uf = cepRestData.data.uf || "";
|
|
||||||
const endereco = `${logradouro}, ${numero}, ${bairro}, ${cidade} - ${uf}`
|
|
||||||
.replace(/, ,/g, ",")
|
|
||||||
.replace(/^,\s*/, "");
|
|
||||||
|
|
||||||
if (!process.env.GOOGLE_API_KEY)
|
|
||||||
return res
|
|
||||||
.status(500)
|
|
||||||
.json({ error: "GOOGLE_API_KEY não definida no servidor" });
|
|
||||||
const geo = await geocodeWithGoogle(endereco || `${cidade} ${uf} ${cep}`);
|
|
||||||
if (!geo)
|
|
||||||
return res
|
|
||||||
.status(404)
|
|
||||||
.json({ error: "geocode não encontrado (Google)" });
|
|
||||||
const lat = Number(geo.lat);
|
|
||||||
const lon = Number(geo.lon);
|
|
||||||
const result = await getMinDistance(lat, lon);
|
|
||||||
if (result && result.dist !== undefined) {
|
|
||||||
return res.json({
|
|
||||||
endereco,
|
|
||||||
latitude: lat,
|
|
||||||
longitude: lon,
|
|
||||||
distancia: result.dist,
|
|
||||||
parceiro: result.pastaSigla || "",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return res.json({
|
|
||||||
endereco,
|
|
||||||
latitude: lat,
|
|
||||||
longitude: lon,
|
|
||||||
distancia: "5km +",
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return res.status(500).json({ error: "erro na consulta" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Servir arquivos estáticos (index.html)
|
|
||||||
// app.use("/public", express.static(path.join(__dirname, "public")));
|
|
||||||
|
|
||||||
// Usa as rotas de autenticação
|
|
||||||
app.use("/", authRoutes);
|
|
||||||
|
|
||||||
// servir arquivos estáticos da pasta public (rotas protegidas já são tratadas pelo middleware global)
|
|
||||||
app.use(express.static(path.join(__dirname, "public")));
|
|
||||||
|
|
||||||
// rota protegida que serve o index.html
|
|
||||||
app.get("/app", requireAuth, (req, res) => {
|
|
||||||
res.sendFile(path.join(__dirname, "public", "index.html"));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
return app;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = app;
|
||||||
createApp,
|
|
||||||
};
|
|
||||||
681
app.old.js
Normal file
681
app.old.js
Normal file
@ -0,0 +1,681 @@
|
|||||||
|
// require("dotenv").config();
|
||||||
|
|
||||||
|
// const express = require("express");
|
||||||
|
// const multer = require("multer");
|
||||||
|
// const fs = require("fs");
|
||||||
|
// const path = require("path");
|
||||||
|
// const csv = require("csv-parser");
|
||||||
|
// const fastCsv = require("fast-csv");
|
||||||
|
// const axios = require("axios");
|
||||||
|
// const cors = require("cors");
|
||||||
|
// const session = require("express-session"); // adiciona session
|
||||||
|
// const { geocodeWithGoogle, addressWithGoogle } = require("./service/geocodeService");
|
||||||
|
// const { fetchJson } = require("./service/fetchService");
|
||||||
|
// const { BASE_BACKOFF_MS, MAX_RETRIES, REQUEST_DELAY_MS, sleep } = require("./service/retryService");
|
||||||
|
// const { API_URL, HEADERS } = require("./config/apiConfig");
|
||||||
|
// const { normalizePartnerSigla } = require("./service/normalizeService");
|
||||||
|
// const authRoutes = require("./routes/authRoutes.js");
|
||||||
|
|
||||||
|
// function createApp() {
|
||||||
|
// const upload = multer({ dest: "uploads/" });
|
||||||
|
// const app = express();
|
||||||
|
|
||||||
|
// // se estiver atrás de um reverse proxy (nginx/traefik) em produção, habilite:
|
||||||
|
// app.set("trust proxy", 1);
|
||||||
|
|
||||||
|
// app.use(cors());
|
||||||
|
// app.use(express.json());
|
||||||
|
|
||||||
|
// // session TEM que vir antes das rotas que usam req.session
|
||||||
|
// app.use(
|
||||||
|
// session({
|
||||||
|
// secret: process.env.SESSION_SECRET || "change-me",
|
||||||
|
// resave: false,
|
||||||
|
// saveUninitialized: false,
|
||||||
|
// cookie: {
|
||||||
|
// maxAge: 24 * 60 * 60 * 1000,
|
||||||
|
// secure: process.env.NODE_ENV === "production",
|
||||||
|
// sameSite: "lax",
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
|
||||||
|
// // -- Desenvolvimento: pular autenticação se configurado
|
||||||
|
// // Para ativar: defina NODE_ENV=development e DEV_SKIP_AUTH=true no .env
|
||||||
|
// if (process.env.NODE_ENV === 'development' && process.env.DEV_SKIP_AUTH === 'true') {
|
||||||
|
// app.use((req, res, next) => {
|
||||||
|
// // garante que exista uma sessão autenticada para facilitar testes locais
|
||||||
|
// if (req.session && (!req.session.user || !req.session.user.authenticated)) {
|
||||||
|
// req.session.user = { authenticated: true, dev: true };
|
||||||
|
// }
|
||||||
|
// next();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // middleware que protege rotas que exigem login
|
||||||
|
// function requireAuth(req, res, next) {
|
||||||
|
// if (req.session?.user?.authenticated) {
|
||||||
|
// return next();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (req.xhr || req.headers.accept?.includes("application/json")) {
|
||||||
|
// return res.status(401).json({ error: "not_authenticated" });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return res.redirect("/login");
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// // proteger demais rotas (ex.: /upload, /consulta)
|
||||||
|
// app.use((req, res, next) => {
|
||||||
|
// // permissão liberada para rotas de auth já tratadas; proteger o resto
|
||||||
|
// if (req.path.startsWith("/auth") || req.path === "/login") return next();
|
||||||
|
// return requireAuth(req, res, next);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // redirect raiz
|
||||||
|
// app.get("/", (req, res) => {
|
||||||
|
// // em dev com bypass, sirva a página diretamente (sem redirect)
|
||||||
|
// if (process.env.NODE_ENV === 'development' && process.env.DEV_SKIP_AUTH === 'true') {
|
||||||
|
// return res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (req.session?.user?.authenticated) {
|
||||||
|
// return res.redirect("/public/index.html");
|
||||||
|
// }
|
||||||
|
// return res.redirect("/login");
|
||||||
|
// });
|
||||||
|
|
||||||
|
// /////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// async function getMinDistance(lat, lon) {
|
||||||
|
// // tenta várias vezes com backoff exponencial; trata 429 usando Retry-After se disponível
|
||||||
|
// let attempt = 0;
|
||||||
|
// while (attempt < MAX_RETRIES) {
|
||||||
|
// try {
|
||||||
|
// // envia também o raio (em metros) - API espera esse parâmetro em várias rotas
|
||||||
|
// const resp = await axios.get(API_URL, {
|
||||||
|
// headers: HEADERS,
|
||||||
|
// params: {
|
||||||
|
// raio: 5000,
|
||||||
|
// latitude: lat,
|
||||||
|
// longitude: lon,
|
||||||
|
// "itens[]": ["caixa"],
|
||||||
|
// consultarPasta: "S",
|
||||||
|
// },
|
||||||
|
// timeout: 10000,
|
||||||
|
// });
|
||||||
|
// const data = resp.data;
|
||||||
|
// const registros = data && data.registros ? data.registros : [];
|
||||||
|
// // find registros that have a numeric distancia and keep original object for robust extraction
|
||||||
|
// const candidates = registros
|
||||||
|
// .map((r) => ({ raw: r, distanciaRaw: r && r.distancia }))
|
||||||
|
// .map((o) => ({
|
||||||
|
// raw: o.raw,
|
||||||
|
// num:
|
||||||
|
// o.distanciaRaw !== undefined &&
|
||||||
|
// o.distanciaRaw !== null &&
|
||||||
|
// o.distanciaRaw !== ""
|
||||||
|
// ? Number(o.distanciaRaw)
|
||||||
|
// : null,
|
||||||
|
// }))
|
||||||
|
// .filter((x) => x.num !== null && !Number.isNaN(x.num));
|
||||||
|
// if (candidates.length) {
|
||||||
|
// candidates.sort((a, b) => a.num - b.num);
|
||||||
|
// const best = candidates[0];
|
||||||
|
// const r = best.raw || {};
|
||||||
|
// // robust extraction of pasta sigla with fallbacks
|
||||||
|
// let pastaSigla = null;
|
||||||
|
// try {
|
||||||
|
// if (r.pasta) {
|
||||||
|
// if (typeof r.pasta === "string" && r.pasta.trim())
|
||||||
|
// pastaSigla = r.pasta.trim();
|
||||||
|
// else if (r.pasta.sigla && String(r.pasta.sigla).trim())
|
||||||
|
// pastaSigla = String(r.pasta.sigla).trim();
|
||||||
|
// else if (
|
||||||
|
// r.pasta.cidade &&
|
||||||
|
// r.pasta.cidade.sigla &&
|
||||||
|
// String(r.pasta.cidade.sigla).trim()
|
||||||
|
// )
|
||||||
|
// pastaSigla = String(r.pasta.cidade.sigla).trim();
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// pastaSigla = null;
|
||||||
|
// }
|
||||||
|
// // if closest has no pastaSigla, try find any candidate with non-empty sigla
|
||||||
|
// if (!pastaSigla) {
|
||||||
|
// for (let j = 0; j < candidates.length; j++) {
|
||||||
|
// const rr = candidates[j].raw || {};
|
||||||
|
// try {
|
||||||
|
// if (rr.pasta) {
|
||||||
|
// if (typeof rr.pasta === "string" && rr.pasta.trim()) {
|
||||||
|
// pastaSigla = rr.pasta.trim();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (rr.pasta.sigla && String(rr.pasta.sigla).trim()) {
|
||||||
|
// pastaSigla = String(rr.pasta.sigla).trim();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (
|
||||||
|
// rr.pasta.cidade &&
|
||||||
|
// rr.pasta.cidade.sigla &&
|
||||||
|
// String(rr.pasta.cidade.sigla).trim()
|
||||||
|
// ) {
|
||||||
|
// pastaSigla = String(rr.pasta.cidade.sigla).trim();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// // continue
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (!pastaSigla)
|
||||||
|
// console.warn(
|
||||||
|
// `[WARN] Nenhuma pasta.sigla encontrada para coordenadas ${lat},${lon} (closest dist ${best.num})`
|
||||||
|
// );
|
||||||
|
// pastaSigla = normalizePartnerSigla(pastaSigla);
|
||||||
|
// return { dist: best.num, pastaSigla };
|
||||||
|
// }
|
||||||
|
// // sem distancias válidas
|
||||||
|
// return null;
|
||||||
|
// } catch (err) {
|
||||||
|
// attempt += 1;
|
||||||
|
// // se for 429, tente respeitar Retry-After quando disponível
|
||||||
|
// if (err.response && err.response.status === 429) {
|
||||||
|
// const ra =
|
||||||
|
// err.response.headers &&
|
||||||
|
// (err.response.headers["retry-after"] ||
|
||||||
|
// err.response.headers["Retry-After"]);
|
||||||
|
// let waitMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
|
||||||
|
// if (ra) {
|
||||||
|
// const raSec = parseInt(ra, 10);
|
||||||
|
// if (!isNaN(raSec)) waitMs = raSec * 1000;
|
||||||
|
// }
|
||||||
|
// console.warn(
|
||||||
|
// `[WARN] 429 recebido para ${lat},${lon} - aguardando ${waitMs}ms e tentando novamente (attempt ${attempt}/${MAX_RETRIES})`
|
||||||
|
// );
|
||||||
|
// await sleep(waitMs);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // para outros erros de rede/timeout, aguarda backoff exponencial e tenta de novo
|
||||||
|
// const waitMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
|
||||||
|
// console.warn(
|
||||||
|
// `[WARN] Erro ao consultar API para ${lat},${lon}: ${err.message} - backoff ${waitMs}ms (attempt ${attempt}/${MAX_RETRIES})`
|
||||||
|
// );
|
||||||
|
// await sleep(waitMs);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // exauriu tentativas
|
||||||
|
// console.error(`[ERROR] Exauriu retries para ${lat},${lon}`);
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // upload CSV endpoint
|
||||||
|
// const jobs = {}; // jobId -> { status, total, processed, download, error }
|
||||||
|
|
||||||
|
// app.post("/upload", upload.single("csvfile"), (req, res) => {
|
||||||
|
// if (!req.file)
|
||||||
|
// return res.status(400).json({ error: "Nenhum arquivo enviado" });
|
||||||
|
// const filePath = req.file.path;
|
||||||
|
// const jobId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||||
|
// jobs[jobId] = {
|
||||||
|
// status: "queued",
|
||||||
|
// total: 0,
|
||||||
|
// processed: 0,
|
||||||
|
// download: null,
|
||||||
|
// error: null,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// (async () => {
|
||||||
|
// jobs[jobId].status = "processing";
|
||||||
|
// try {
|
||||||
|
// const rows = [];
|
||||||
|
// await new Promise((resolve, reject) => {
|
||||||
|
// fs.createReadStream(filePath)
|
||||||
|
// .pipe(csv({ separator: ";" }))
|
||||||
|
// .on("data", (data) => {
|
||||||
|
// // ignora linhas totalmente vazias (todos os campos nulos/undefined/strings vazias)
|
||||||
|
// const values = Object.values(data);
|
||||||
|
// const allEmpty =
|
||||||
|
// values.length === 0 ||
|
||||||
|
// values.every(
|
||||||
|
// (v) => v === null || v === undefined || String(v).trim() === ""
|
||||||
|
// );
|
||||||
|
// if (!allEmpty) rows.push(data);
|
||||||
|
// })
|
||||||
|
// .on("end", resolve)
|
||||||
|
// .on("error", reject);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// jobs[jobId].total = rows.length;
|
||||||
|
|
||||||
|
// const coordCache = new Map();
|
||||||
|
|
||||||
|
// const outRows = [];
|
||||||
|
// for (let i = 0; i < rows.length; i++) {
|
||||||
|
// const row = rows[i];
|
||||||
|
// // normalize keys to avoid duplicates caused by different headers
|
||||||
|
// const norm = {};
|
||||||
|
// Object.keys(row).forEach((k) => {
|
||||||
|
// // normalize header: lowercase, remove diacritics and non-alphanumeric
|
||||||
|
// const kn = k
|
||||||
|
// .trim()
|
||||||
|
// .toLowerCase()
|
||||||
|
// .normalize("NFKD")
|
||||||
|
// .replace(/[\u0300-\u036f]/g, "")
|
||||||
|
// .replace(/[^a-z0-9]/g, "");
|
||||||
|
// norm[kn] = row[k];
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Input columns (from normalized map)
|
||||||
|
// const rawCep = norm["cep"]
|
||||||
|
// ? String(norm["cep"]).replace(/\D/g, "")
|
||||||
|
// : "";
|
||||||
|
// const rawNumero = norm["numero"] ? String(norm["numero"]).trim() : "";
|
||||||
|
// // prefer lat/lon from normalized input if available
|
||||||
|
// const rawLat = norm["latitude"] || norm["lat"] || null;
|
||||||
|
// const rawLon =
|
||||||
|
// norm["longitude"] || norm["lon"] || norm["long"] || null;
|
||||||
|
|
||||||
|
// // Prefer existing lat/lon if provided from normalized fields
|
||||||
|
// let lat = null,
|
||||||
|
// lon = null;
|
||||||
|
// if (rawLat && rawLon) {
|
||||||
|
// lat = Number(String(rawLat).replace(",", "."));
|
||||||
|
// lon = Number(String(rawLon).replace(",", "."));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let builtAddress = "";
|
||||||
|
|
||||||
|
// const googleGeocodeAddress = await addressWithGoogle(lat, lon);
|
||||||
|
// if (googleGeocodeAddress) {
|
||||||
|
// builtAddress = googleGeocodeAddress;
|
||||||
|
// } else {
|
||||||
|
// console.warn(
|
||||||
|
// `Google Reverse Geocoding não retornou resultado para coords ${lat},${lon} (row ${i + 1})`
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// console.log(`Row ${i + 1}: CEP='${rawCep}' Número='${rawNumero}' Lat='${lat}' Lon='${lon}' BuiltAddress='${builtAddress}'`);
|
||||||
|
|
||||||
|
// // If no coords, try ViaCEP -> Google
|
||||||
|
// if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
|
||||||
|
// if (rawCep) {
|
||||||
|
// const cep8 = rawCep.padStart(8, "0");
|
||||||
|
// const cepRestData = await fetch(
|
||||||
|
// 'https://api.cep.rest/', {
|
||||||
|
// method: 'POST',
|
||||||
|
// headers: { 'Content-Type': 'application/json' },
|
||||||
|
// body: JSON.stringify({ cep: cep8 })
|
||||||
|
// }
|
||||||
|
// ).then(r => r.json());
|
||||||
|
// if (cepRestData && !cepRestData.erro) {
|
||||||
|
// const logradouro = cepRestData.data.logradouro || "";
|
||||||
|
// const bairro = cepRestData.data.bairro || "";
|
||||||
|
// const cidade = cepRestData.data.localidade || "";
|
||||||
|
// const uf = cepRestData.data.uf || "";
|
||||||
|
// if (logradouro) {
|
||||||
|
// builtAddress =
|
||||||
|
// `${logradouro}, ${rawNumero}, ${bairro}, ${cidade} - ${uf}`
|
||||||
|
// .replace(/, ,/g, ",")
|
||||||
|
// .replace(/^,\s*/, "");
|
||||||
|
// } else {
|
||||||
|
// // fallback: use neighborhood/city
|
||||||
|
// builtAddress = `${bairro || ""} ${
|
||||||
|
// cidade ? ", " + cidade : ""
|
||||||
|
// } ${uf ? "- " + uf : ""}`.trim();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // build addressToUse (builtAddress already assembled above)
|
||||||
|
// if (!process.env.GOOGLE_API_KEY) {
|
||||||
|
// console.error(
|
||||||
|
// "[ERROR] GOOGLE_API_KEY não definida. Não será possível geocodificar. Defina a chave no .env ou em process.env"
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// const addressToUse =
|
||||||
|
// builtAddress || `${cidade} ${uf} ${cep8}`;
|
||||||
|
// const geo = await geocodeWithGoogle(addressToUse);
|
||||||
|
// if (geo) {
|
||||||
|
// lat = geo.lat;
|
||||||
|
// lon = geo.lon;
|
||||||
|
// } else
|
||||||
|
// console.warn(
|
||||||
|
// `Google Geocoding não retornou resultado para '${addressToUse}' (CEP ${cep8}, row ${
|
||||||
|
// i + 1
|
||||||
|
// })`
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.warn(`ViaCEP erro for CEP ${rawCep} (row ${i + 1})`);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log(`Row ${i + 1}: missing/invalid CEP -> '${rawCep}'`);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Prepare explicit output row to avoid extra columns
|
||||||
|
// const out = {
|
||||||
|
// CEP: rawCep || "",
|
||||||
|
// Número: rawNumero || "",
|
||||||
|
// Endereço: builtAddress || "",
|
||||||
|
// // write lat/lon as strings with dot decimal and fixed precision to avoid locale swaps
|
||||||
|
// Latitude: Number.isFinite(lat) ? Number(lat).toFixed(6) : "",
|
||||||
|
// Longitude: Number.isFinite(lon) ? Number(lon).toFixed(6) : "",
|
||||||
|
// "Não dedicado": "",
|
||||||
|
// Dedicado: "",
|
||||||
|
// Distancia: "",
|
||||||
|
// "Parceiro/Sothis": "",
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if (Number.isFinite(lat) && Number.isFinite(lon)) {
|
||||||
|
// const coordKey = `${lat.toFixed(6)},${lon.toFixed(6)}`;
|
||||||
|
// if (coordCache.has(coordKey)) {
|
||||||
|
// const cached = coordCache.get(coordKey); // cached is either null or { dist, pastaSigla }
|
||||||
|
// if (cached !== null) {
|
||||||
|
// const d = cached.dist;
|
||||||
|
// const di = Math.round(Number(d));
|
||||||
|
// out["Não dedicado"] = di <= 500 ? "viável" : "Não viável";
|
||||||
|
// out["Dedicado"] = di <= 1000 ? "viável" : "Não viável";
|
||||||
|
// out["Distancia"] = `${di}M`;
|
||||||
|
// out["Parceiro/Sothis"] =
|
||||||
|
// normalizePartnerSigla(cached.pastaSigla) || "";
|
||||||
|
// } else {
|
||||||
|
// out["Não dedicado"] = "Não viável";
|
||||||
|
// out["Dedicado"] = "Não viável";
|
||||||
|
// out["Distancia"] = "5km +";
|
||||||
|
// out["Parceiro/Sothis"] = "";
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// const minResult = await getMinDistance(lat, lon); // { dist, pastaSigla } or null
|
||||||
|
// coordCache.set(coordKey, minResult);
|
||||||
|
// if (minResult !== null) {
|
||||||
|
// const di = Math.round(Number(minResult.dist));
|
||||||
|
// out["Não dedicado"] = di <= 500 ? "viável" : "Não viável";
|
||||||
|
// out["Dedicado"] = di <= 1000 ? "viável" : "Não viável";
|
||||||
|
// out["Distancia"] = `${di}M`;
|
||||||
|
// out["Parceiro/Sothis"] =
|
||||||
|
// normalizePartnerSigla(minResult.pastaSigla) || "";
|
||||||
|
// } else {
|
||||||
|
// out["Não dedicado"] = "Não viável";
|
||||||
|
// out["Dedicado"] = "Não viável";
|
||||||
|
// out["Distancia"] = "5km +";
|
||||||
|
// out["Parceiro/Sothis"] = "";
|
||||||
|
// }
|
||||||
|
// await sleep(REQUEST_DELAY_MS);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// // no coords available -> keep defaults
|
||||||
|
// }
|
||||||
|
|
||||||
|
// outRows.push(out);
|
||||||
|
// jobs[jobId].processed = i + 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // write output csv - use explicit outRows and fixed header order
|
||||||
|
// const outPath = path.join(__dirname, "outputs");
|
||||||
|
// if (!fs.existsSync(outPath)) fs.mkdirSync(outPath);
|
||||||
|
// const originalName =
|
||||||
|
// req.file && req.file.originalname
|
||||||
|
// ? req.file.originalname
|
||||||
|
// : `upload_${Date.now()}.csv`;
|
||||||
|
// const parsed = path.parse(originalName);
|
||||||
|
// let outBase = `${parsed.name}_output`;
|
||||||
|
// let outFile = path.join(outPath, `${outBase}.csv`);
|
||||||
|
// if (fs.existsSync(outFile)) {
|
||||||
|
// outFile = path.join(outPath, `${outBase}_${Date.now()}.csv`);
|
||||||
|
// }
|
||||||
|
// const headers = [
|
||||||
|
// "CEP",
|
||||||
|
// "Número",
|
||||||
|
// "Endereço",
|
||||||
|
// "Latitude",
|
||||||
|
// "Longitude",
|
||||||
|
// "Não dedicado",
|
||||||
|
// "Dedicado",
|
||||||
|
// "Distancia",
|
||||||
|
// "Parceiro/Sothis",
|
||||||
|
// ];
|
||||||
|
// await new Promise((resolve, reject) => {
|
||||||
|
// const ws = fs.createWriteStream(outFile);
|
||||||
|
// ws.write("\uFEFF");
|
||||||
|
// fastCsv
|
||||||
|
// .write(outRows, { headers: headers, delimiter: ";" })
|
||||||
|
// .pipe(ws)
|
||||||
|
// .on("finish", resolve)
|
||||||
|
// .on("error", reject);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// fs.unlinkSync(filePath);
|
||||||
|
// } catch (e) {}
|
||||||
|
|
||||||
|
// jobs[jobId].status = "done";
|
||||||
|
// jobs[jobId].download = `/download/${path.basename(outFile)}`;
|
||||||
|
// } catch (err) {
|
||||||
|
// console.error(err);
|
||||||
|
// jobs[jobId].status = "error";
|
||||||
|
// jobs[jobId].error = String(err.message || err);
|
||||||
|
// }
|
||||||
|
// })();
|
||||||
|
|
||||||
|
// return res.json({ jobId });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // download model endpoint
|
||||||
|
// app.get("/download-model/:name", (req, res) => {
|
||||||
|
// const name = req.params.name;
|
||||||
|
// const safeName = path.basename(name); // evita ../
|
||||||
|
// const filePath = path.join(__dirname, "models", safeName);
|
||||||
|
// if (!fs.existsSync(filePath)) return res.status(404).send("Arquivo não encontrado");
|
||||||
|
// return res.download(filePath, safeName);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // lista os arquivos disponíveis em /models
|
||||||
|
// app.get("/download-models/list", (req, res) => {
|
||||||
|
// const modelDir = path.join(__dirname, "models");
|
||||||
|
// if (!fs.existsSync(modelDir)) return res.status(404).json({ error: "Pasta de modelos não encontrada" });
|
||||||
|
// const files = fs.readdirSync(modelDir).filter((f) => fs.statSync(path.join(modelDir, f)).isFile());
|
||||||
|
// return res.json({ files });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // download result endpoint
|
||||||
|
// app.get("/download/:name", (req, res) => {
|
||||||
|
// const name = req.params.name;
|
||||||
|
// const p = path.join(__dirname, "outputs", name);
|
||||||
|
// if (!fs.existsSync(p))
|
||||||
|
// return res.status(404).send("Arquivo não encontrado");
|
||||||
|
// res.download(p);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // job status endpoint
|
||||||
|
// app.get("/status/:jobId", (req, res) => {
|
||||||
|
// const job = jobs[req.params.jobId];
|
||||||
|
// if (!job) return res.status(404).json({ error: "job não encontrado" });
|
||||||
|
// return res.json(job);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // manual query endpoint
|
||||||
|
// // /consulta now accepts either latitude+longitude OR cep+numero. If cep is provided we resolve ViaCEP -> Google -> Geogrid
|
||||||
|
// app.get("/consulta", async (req, res) => {
|
||||||
|
// const {
|
||||||
|
// latitude: rawLat,
|
||||||
|
// longitude: rawLon,
|
||||||
|
// cep: rawCep,
|
||||||
|
// numero: rawNumero,
|
||||||
|
// } = req.query;
|
||||||
|
|
||||||
|
// // If cep provided, use ViaCEP -> Google geocoding -> Geogrid
|
||||||
|
// if (rawCep) {
|
||||||
|
// const cep = String(rawCep).replace(/\D/g, "");
|
||||||
|
// const numero = rawNumero ? String(rawNumero).trim() : "";
|
||||||
|
// try {
|
||||||
|
// const viaCepData = await fetch(
|
||||||
|
// 'https://api.cep.rest/', { method: 'POST',
|
||||||
|
// headers: { 'Content-Type': 'application/json' },
|
||||||
|
// body: JSON.stringify({ cep })
|
||||||
|
// }
|
||||||
|
// ).then(r => r.json());
|
||||||
|
// if (!viaCepData || viaCepData.erro)
|
||||||
|
// return res.status(404).json({ error: "CEP não encontrado" });
|
||||||
|
// const logradouro = viaCepData.data.logradouro || "";
|
||||||
|
// const bairro = viaCepData.data.bairro || "";
|
||||||
|
// const cidade = viaCepData.data.localidade || "";
|
||||||
|
// const uf = viaCepData.data.uf || "";
|
||||||
|
// const endereco =
|
||||||
|
// `${logradouro}, ${numero}, ${bairro}, ${cidade} - ${uf}`
|
||||||
|
// .replace(/, ,/g, ",")
|
||||||
|
// .replace(/^,\s*/, "");
|
||||||
|
|
||||||
|
// if (!process.env.GOOGLE_API_KEY)
|
||||||
|
// return res
|
||||||
|
// .status(500)
|
||||||
|
// .json({ error: "GOOGLE_API_KEY não definida no servidor" });
|
||||||
|
// const geo = await geocodeWithGoogle(
|
||||||
|
// endereco || `${cidade} ${uf} ${cep}`
|
||||||
|
// );
|
||||||
|
// if (!geo)
|
||||||
|
// return res
|
||||||
|
// .status(404)
|
||||||
|
// .json({ error: "geocode não encontrado (Google)" });
|
||||||
|
// const lat = Number(geo.lat);
|
||||||
|
// const lon = Number(geo.lon);
|
||||||
|
// const result = await getMinDistance(lat, lon);
|
||||||
|
// if (result && result.dist !== undefined) {
|
||||||
|
// return res.json({
|
||||||
|
// endereco,
|
||||||
|
// latitude: lat,
|
||||||
|
// longitude: lon,
|
||||||
|
// distancia: result.dist,
|
||||||
|
// parceiro: result.pastaSigla || "",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// return res.json({
|
||||||
|
// endereco,
|
||||||
|
// latitude: lat,
|
||||||
|
// longitude: lon,
|
||||||
|
// distancia: "5km +",
|
||||||
|
// });
|
||||||
|
// } catch (err) {
|
||||||
|
// console.error(err);
|
||||||
|
// return res.status(500).json({ error: "Erro na consulta" });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Otherwise require latitude+longitude
|
||||||
|
// if (!rawLat || !rawLon)
|
||||||
|
// return res.status(400).json({
|
||||||
|
// error: "latitude e longitude são obrigatórios (ou forneça cep)",
|
||||||
|
// });
|
||||||
|
// const latitude = Number(String(rawLat).replace(",", "."));
|
||||||
|
// const longitude = Number(String(rawLon).replace(",", "."));
|
||||||
|
// if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
|
||||||
|
// console.warn(
|
||||||
|
// `Consulta manual com parâmetros inválidos: lat='${rawLat}' lon='${rawLon}'`
|
||||||
|
// );
|
||||||
|
// return res.status(400).json({ error: "latitude ou longitude inválidos" });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// console.log(`Consulta manual: lat=${latitude} lon=${longitude}`);
|
||||||
|
// const result = await getMinDistance(latitude, longitude);
|
||||||
|
// console.log(`Resultado consulta manual: ${JSON.stringify(result)}`);
|
||||||
|
// if (result && result.dist !== undefined) {
|
||||||
|
// return res.json({
|
||||||
|
// distancia: result.dist,
|
||||||
|
// parceiro: result.pastaSigla || "",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// return res.json({ distancia: "5km +" });
|
||||||
|
// } catch (err) {
|
||||||
|
// console.error(err);
|
||||||
|
// return res.status(500).json({ error: "Erro na consulta" });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // manual CEP+Numero query: resolves ViaCEP -> Nominatim -> Geogrid
|
||||||
|
// app.get("/consulta-cep", async (req, res) => {
|
||||||
|
// const { cep: rawCep, numero: rawNumero } = req.query;
|
||||||
|
// if (!rawCep) return res.status(400).json({ error: "cep é obrigatório" });
|
||||||
|
// const cep = String(rawCep).replace(/\D/g, "");
|
||||||
|
// const numero = rawNumero ? String(rawNumero).trim() : "";
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const cepRestData = await fetch(
|
||||||
|
// 'https://api.cep.rest/', {
|
||||||
|
// method: 'POST',
|
||||||
|
// headers: { 'Content-Type': 'application/json' },
|
||||||
|
// body: JSON.stringify({ cep })
|
||||||
|
// }
|
||||||
|
// ).then(r => r.json());
|
||||||
|
// if (!cepRestData || cepRestData.erro)
|
||||||
|
// return res.status(404).json({ error: "CEP não encontrado" });
|
||||||
|
// const logradouro = cepRestData.data.logradouro || "";
|
||||||
|
// const bairro = cepRestData.data.bairro || "";
|
||||||
|
// const cidade = cepRestData.data.localidade || "";
|
||||||
|
// const uf = cepRestData.data.uf || "";
|
||||||
|
// const endereco = `${logradouro}, ${numero}, ${bairro}, ${cidade} - ${uf}`
|
||||||
|
// .replace(/, ,/g, ",")
|
||||||
|
// .replace(/^,\s*/, "");
|
||||||
|
|
||||||
|
// if (!process.env.GOOGLE_API_KEY)
|
||||||
|
// return res
|
||||||
|
// .status(500)
|
||||||
|
// .json({ error: "GOOGLE_API_KEY não definida no servidor" });
|
||||||
|
// const geo = await geocodeWithGoogle(endereco || `${cidade} ${uf} ${cep}`);
|
||||||
|
// if (!geo)
|
||||||
|
// return res
|
||||||
|
// .status(404)
|
||||||
|
// .json({ error: "geocode não encontrado (Google)" });
|
||||||
|
// const lat = Number(geo.lat);
|
||||||
|
// const lon = Number(geo.lon);
|
||||||
|
// const result = await getMinDistance(lat, lon);
|
||||||
|
// if (result && result.dist !== undefined) {
|
||||||
|
// return res.json({
|
||||||
|
// endereco,
|
||||||
|
// latitude: lat,
|
||||||
|
// longitude: lon,
|
||||||
|
// distancia: result.dist,
|
||||||
|
// parceiro: result.pastaSigla || "",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// return res.json({
|
||||||
|
// endereco,
|
||||||
|
// latitude: lat,
|
||||||
|
// longitude: lon,
|
||||||
|
// distancia: "5km +",
|
||||||
|
// });
|
||||||
|
// } catch (err) {
|
||||||
|
// console.error(err);
|
||||||
|
// return res.status(500).json({ error: "erro na consulta" });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// // Servir arquivos estáticos (index.html)
|
||||||
|
// // app.use("/public", express.static(path.join(__dirname, "public")));
|
||||||
|
|
||||||
|
// // Usa as rotas de autenticação
|
||||||
|
// app.use("/", authRoutes);
|
||||||
|
|
||||||
|
// // servir arquivos estáticos da pasta public (rotas protegidas já são tratadas pelo middleware global)
|
||||||
|
// app.use(express.static(path.join(__dirname, "public")));
|
||||||
|
|
||||||
|
// // rota protegida que serve o index.html
|
||||||
|
// app.get("/app", requireAuth, (req, res) => {
|
||||||
|
// res.sendFile(path.join(__dirname, "public", "index.html"));
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
// /////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// return app;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
// createApp,
|
||||||
|
// };
|
||||||
@ -19,4 +19,8 @@ const apiConfig = {
|
|||||||
COOKIE,
|
COOKIE,
|
||||||
HEADERS
|
HEADERS
|
||||||
};
|
};
|
||||||
module.exports = apiConfig;
|
|
||||||
|
const apiViabilidadeUrl = process.env.API_VIABILIDADE_URL;
|
||||||
|
const apiUrlBase = process.env.API_URL_BASE;
|
||||||
|
|
||||||
|
module.exports = { apiConfig, apiViabilidadeUrl, apiUrlBase };
|
||||||
175
controller/viabilidadeController.js
Normal file
175
controller/viabilidadeController.js
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
const { consultarViabilidade, discoverDataType } = require('../service/viabilidadeService');
|
||||||
|
const { processCsvFile, countValidLines } = require('../service/csvService');
|
||||||
|
const { getJob, createJob } = require('../service/jobStore.service');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
|
||||||
|
// Controlador para consultar viabilidade
|
||||||
|
async function consultarViabilidadeController(req, res) {
|
||||||
|
try {
|
||||||
|
const data = req.body;
|
||||||
|
data.source = 'viabiliza.sothis.com.br';
|
||||||
|
const result = await consultarViabilidade(data);
|
||||||
|
res.json(result);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao consultar viabilidade:", error && (error.message || error));
|
||||||
|
res.status(500).json({ error: "Erro ao consultar viabilidade" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controlador para consultar viabilidade via geolocalização
|
||||||
|
async function consultarViaGeolocalizacaoController(req, res) {
|
||||||
|
try {
|
||||||
|
const data = req.body;
|
||||||
|
data.source = 'viabiliza.sothis.com.br';
|
||||||
|
const result = await consultarViabilidade(data);
|
||||||
|
res.json(result);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao consultar viabilidade por geolocalização:", error && (error.message || error));
|
||||||
|
res.status(500).json({ error: "Erro ao consultar viabilidade por geolocalização" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function uploadCsvFile(req, res) {
|
||||||
|
try {
|
||||||
|
// validação simples: verifica se multer populou req.file
|
||||||
|
if (!req.file) {
|
||||||
|
return res.status(400).json({ error: 'Nenhum arquivo enviado. Campo do form deve ser "csvfile".' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = req.file.path;
|
||||||
|
const originalName = req.file.originalname || req.file.filename || 'input.csv';
|
||||||
|
|
||||||
|
// Verifica o tipo de dados do CSV
|
||||||
|
const dataType = await discoverDataType(filePath);
|
||||||
|
if (dataType === 'unknown') {
|
||||||
|
return res.status(400).json({ error: 'Formato de CSV inválido. Deve conter colunas CEP e Número ou Latitude e Longitude.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conta as linhas válidas primeiro
|
||||||
|
const total = await countValidLines(filePath);
|
||||||
|
if (total === 0) {
|
||||||
|
return res.status(400).json({ error: 'Nenhuma linha válida encontrada no CSV. Verifique se há colunas CEP e Número.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cria o job
|
||||||
|
const jobId = createJob(total);
|
||||||
|
|
||||||
|
// Inicia o processamento em background (não aguarda)
|
||||||
|
processCsvFile(jobId, filePath, originalName).catch(err => {
|
||||||
|
console.error('Erro no processamento em background:', err);
|
||||||
|
// Em caso de erro, marca o job como falhado
|
||||||
|
require('../service/jobStore.service').failJob(jobId, err.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Retorna o jobId imediatamente para acompanhamento em tempo real
|
||||||
|
return res.json({ jobId });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao iniciar processamento do CSV:", error && (error.message || error));
|
||||||
|
return res.status(500).json({ error: 'Erro ao iniciar processamento do CSV' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getJobController(req, res) {
|
||||||
|
try {
|
||||||
|
const jobId = req.params.jobId;
|
||||||
|
const job = getJob(jobId);
|
||||||
|
if (!job) {
|
||||||
|
return res.status(404).json({ error: 'Job não encontrado' });
|
||||||
|
}
|
||||||
|
res.json(job);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao obter job:", error && (error.message || error));
|
||||||
|
return res.status(500).json({ error: 'Erro ao obter job' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controlador para download do CSV processado
|
||||||
|
// Verifica se o job está concluído e serve o arquivo para download
|
||||||
|
async function downloadCsvController(req, res) {
|
||||||
|
try {
|
||||||
|
const jobId = req.params.jobId;
|
||||||
|
const job = getJob(jobId);
|
||||||
|
|
||||||
|
// Verifica se o job existe, está concluído e tem um link de download
|
||||||
|
if (!job) {
|
||||||
|
return res.status(404).json({ error: 'Job não encontrado' });
|
||||||
|
}
|
||||||
|
if (job.status !== 'done') {
|
||||||
|
return res.status(400).json({ error: 'Processamento ainda não concluído' });
|
||||||
|
}
|
||||||
|
if (!job.download) {
|
||||||
|
return res.status(404).json({ error: 'Arquivo de download não disponível' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extrai o nome do arquivo do campo download (ex: '/download/processed_123.csv' -> 'processed_123.csv')
|
||||||
|
const filename = path.basename(job.download);
|
||||||
|
const filePath = path.join(__dirname, '..', 'outputs', filename);
|
||||||
|
|
||||||
|
// Verifica se o arquivo existe no sistema de arquivos
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
return res.status(404).json({ error: 'Arquivo não encontrado no servidor' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicia o download do arquivo
|
||||||
|
res.download(filePath, filename, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Erro ao fazer download do arquivo:", err);
|
||||||
|
// Se o download falhar, envia erro (mas headers já podem ter sido enviados)
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.status(500).json({ error: 'Erro ao fazer download do arquivo' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro no controlador de download:", error && (error.message || error));
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.status(500).json({ error: 'Erro interno no servidor' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controlador para download dos modelos de CSV
|
||||||
|
// Aceita parâmetro :type ('cep' ou 'geo') para escolher qual modelo baixar
|
||||||
|
async function downloadModelController(req, res) {
|
||||||
|
try {
|
||||||
|
const type = req.params.type;
|
||||||
|
let filename;
|
||||||
|
|
||||||
|
// Define o nome do arquivo baseado no tipo
|
||||||
|
if (type === 'cep') {
|
||||||
|
filename = 'modelo.viabilidade-cep.csv';
|
||||||
|
} else if (type === 'geo') {
|
||||||
|
filename = 'modelo.viabilidade-geolocalizacao.csv';
|
||||||
|
} else {
|
||||||
|
return res.status(400).json({ error: 'Tipo de modelo inválido. Use "cep" ou "geo".' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = path.join(__dirname, '..', 'models', filename);
|
||||||
|
|
||||||
|
// Verifica se o arquivo existe
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
return res.status(404).json({ error: 'Arquivo de modelo não encontrado' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicia o download do arquivo
|
||||||
|
res.download(filePath, filename, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Erro ao fazer download do modelo:", err);
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.status(500).json({ error: 'Erro ao fazer download do modelo' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro no controlador de download de modelo:", error && (error.message || error));
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.status(500).json({ error: 'Erro interno no servidor' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { consultarViabilidadeController, uploadCsvFile, getJobController, downloadCsvController, downloadModelController, consultarViaGeolocalizacaoController };
|
||||||
12
middlewares/requireAuth.js
Normal file
12
middlewares/requireAuth.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module.exports = function requireAuth(req, res, next) {
|
||||||
|
if (req.session?.user?.authenticated) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// chamadas AJAX / API
|
||||||
|
if (req.xhr || req.headers.accept?.includes('application/json')) {
|
||||||
|
return res.status(401).json({ error: 'not_authenticated' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.redirect('/login');
|
||||||
|
};
|
||||||
5957
models/modelo.viabilidade-geolocalizacao.csv
Normal file
5957
models/modelo.viabilidade-geolocalizacao.csv
Normal file
File diff suppressed because it is too large
Load Diff
16
node_modules/.bin/csv-parser
generated
vendored
16
node_modules/.bin/csv-parser
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../csv-parser/bin/csv-parser" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../csv-parser/bin/csv-parser" "$@"
|
|
||||||
fi
|
|
||||||
17
node_modules/.bin/csv-parser.cmd
generated
vendored
17
node_modules/.bin/csv-parser.cmd
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\csv-parser\bin\csv-parser" %*
|
|
||||||
28
node_modules/.bin/csv-parser.ps1
generated
vendored
28
node_modules/.bin/csv-parser.ps1
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../csv-parser/bin/csv-parser" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../csv-parser/bin/csv-parser" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../csv-parser/bin/csv-parser" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../csv-parser/bin/csv-parser" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
16
node_modules/.bin/mime
generated
vendored
16
node_modules/.bin/mime
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../mime/cli.js" "$@"
|
|
||||||
fi
|
|
||||||
17
node_modules/.bin/mime.cmd
generated
vendored
17
node_modules/.bin/mime.cmd
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
|
||||||
28
node_modules/.bin/mime.ps1
generated
vendored
28
node_modules/.bin/mime.ps1
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
16
node_modules/.bin/mkdirp
generated
vendored
16
node_modules/.bin/mkdirp
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../mkdirp/bin/cmd.js" "$@"
|
|
||||||
fi
|
|
||||||
17
node_modules/.bin/mkdirp.cmd
generated
vendored
17
node_modules/.bin/mkdirp.cmd
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mkdirp\bin\cmd.js" %*
|
|
||||||
28
node_modules/.bin/mkdirp.ps1
generated
vendored
28
node_modules/.bin/mkdirp.ps1
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
1213
node_modules/.package-lock.json
generated
vendored
1213
node_modules/.package-lock.json
generated
vendored
File diff suppressed because it is too large
Load Diff
73
node_modules/@fast-csv/format/CHANGELOG.md
generated
vendored
73
node_modules/@fast-csv/format/CHANGELOG.md
generated
vendored
@ -1,73 +0,0 @@
|
|||||||
# Change Log
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
||||||
|
|
||||||
## [4.3.5](https://github.com/C2FO/fast-csv/compare/v4.3.4...v4.3.5) (2020-11-03)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **formatting,#446:** Do not quote fields that do not contain a quote ([13e688c](https://github.com/C2FO/fast-csv/commit/13e688cb38dcb67c7182211968c794146be54692)), closes [#446](https://github.com/C2FO/fast-csv/issues/446)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.4](https://github.com/C2FO/fast-csv/compare/v4.3.3...v4.3.4) (2020-11-03)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **formatter,#503:** Do not ignore rows when headers is false ([1560564](https://github.com/C2FO/fast-csv/commit/1560564819c8b1254ca4ad43487830a4296570f6)), closes [#503](https://github.com/C2FO/fast-csv/issues/503)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.3](https://github.com/C2FO/fast-csv/compare/v4.3.2...v4.3.3) (2020-10-30)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/format
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.1](https://github.com/C2FO/fast-csv/compare/v4.3.0...v4.3.1) (2020-06-23)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/format
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [4.3.0](https://github.com/C2FO/fast-csv/compare/v4.2.0...v4.3.0) (2020-05-27)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/format
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [4.2.0](https://github.com/C2FO/fast-csv/compare/v4.1.6...v4.2.0) (2020-05-19)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **parsing:** Less restrictive row parsing type [#356](https://github.com/C2FO/fast-csv/issues/356) ([87d74ec](https://github.com/C2FO/fast-csv/commit/87d74ecd2cb16f3700b1942ebbbec221afe38790))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.1.5](https://github.com/C2FO/fast-csv/compare/v4.1.4...v4.1.5) (2020-05-15)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/format
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.1.4](https://github.com/C2FO/fast-csv/compare/v4.1.3...v4.1.4) (2020-05-15)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/format
|
|
||||||
21
node_modules/@fast-csv/format/LICENSE
generated
vendored
21
node_modules/@fast-csv/format/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2011-2019 C2FO
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
20
node_modules/@fast-csv/format/README.md
generated
vendored
20
node_modules/@fast-csv/format/README.md
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
<p align="center">
|
|
||||||
<a href="https://c2fo.io/fast-csv" target="blank"><img src="https://c2fo.io/fast-csv/img/logo.svg" width="200" alt="fast-csv Logo" /></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
[](https://www.npmjs.org/package/@fast-csv/format)
|
|
||||||
[](https://travis-ci.org/C2FO/fast-csv)
|
|
||||||
[](https://coveralls.io/github/C2FO/fast-csv?branch=master)
|
|
||||||
[](https://snyk.io/test/github/C2FO/fast-csv?targetFile=packages/format/package.json)
|
|
||||||
|
|
||||||
# `@fast-csv/format`
|
|
||||||
|
|
||||||
`fast-csv` package to format CSVs.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
[Install Guide](https://c2fo.io/fast-csv/docs/introduction/install)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To get started with `@fast-csv/format` [check out the docs](https://c2fo.io/fast-csv/docs/formatting/getting-started)
|
|
||||||
13
node_modules/@fast-csv/format/build/src/CsvFormatterStream.d.ts
generated
vendored
13
node_modules/@fast-csv/format/build/src/CsvFormatterStream.d.ts
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import { Transform, TransformCallback } from 'stream';
|
|
||||||
import { FormatterOptions } from './FormatterOptions';
|
|
||||||
import { Row, RowTransformFunction } from './types';
|
|
||||||
export declare class CsvFormatterStream<I extends Row, O extends Row> extends Transform {
|
|
||||||
private formatterOptions;
|
|
||||||
private rowFormatter;
|
|
||||||
private hasWrittenBOM;
|
|
||||||
constructor(formatterOptions: FormatterOptions<I, O>);
|
|
||||||
transform(transformFunction: RowTransformFunction<I, O>): CsvFormatterStream<I, O>;
|
|
||||||
_transform(row: I, encoding: string, cb: TransformCallback): void;
|
|
||||||
_flush(cb: TransformCallback): void;
|
|
||||||
}
|
|
||||||
63
node_modules/@fast-csv/format/build/src/CsvFormatterStream.js
generated
vendored
63
node_modules/@fast-csv/format/build/src/CsvFormatterStream.js
generated
vendored
@ -1,63 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.CsvFormatterStream = void 0;
|
|
||||||
const stream_1 = require("stream");
|
|
||||||
const formatter_1 = require("./formatter");
|
|
||||||
class CsvFormatterStream extends stream_1.Transform {
|
|
||||||
constructor(formatterOptions) {
|
|
||||||
super({ writableObjectMode: formatterOptions.objectMode });
|
|
||||||
this.hasWrittenBOM = false;
|
|
||||||
this.formatterOptions = formatterOptions;
|
|
||||||
this.rowFormatter = new formatter_1.RowFormatter(formatterOptions);
|
|
||||||
// if writeBOM is false then set to true
|
|
||||||
// if writeBOM is true then set to false by default so it is written out
|
|
||||||
this.hasWrittenBOM = !formatterOptions.writeBOM;
|
|
||||||
}
|
|
||||||
transform(transformFunction) {
|
|
||||||
this.rowFormatter.rowTransform = transformFunction;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
_transform(row, encoding, cb) {
|
|
||||||
let cbCalled = false;
|
|
||||||
try {
|
|
||||||
if (!this.hasWrittenBOM) {
|
|
||||||
this.push(this.formatterOptions.BOM);
|
|
||||||
this.hasWrittenBOM = true;
|
|
||||||
}
|
|
||||||
this.rowFormatter.format(row, (err, rows) => {
|
|
||||||
if (err) {
|
|
||||||
cbCalled = true;
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
if (rows) {
|
|
||||||
rows.forEach((r) => {
|
|
||||||
this.push(Buffer.from(r, 'utf8'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cbCalled = true;
|
|
||||||
return cb();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (cbCalled) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
cb(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_flush(cb) {
|
|
||||||
this.rowFormatter.finish((err, rows) => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
if (rows) {
|
|
||||||
rows.forEach((r) => {
|
|
||||||
this.push(Buffer.from(r, 'utf8'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return cb();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.CsvFormatterStream = CsvFormatterStream;
|
|
||||||
//# sourceMappingURL=CsvFormatterStream.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/CsvFormatterStream.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/CsvFormatterStream.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"CsvFormatterStream.js","sourceRoot":"","sources":["../../src/CsvFormatterStream.ts"],"names":[],"mappings":";;;AAAA,mCAAsD;AAGtD,2CAA2C;AAE3C,MAAa,kBAAiD,SAAQ,kBAAS;IAO3E,YAAmB,gBAAwC;QACvD,KAAK,CAAC,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC;QAHvD,kBAAa,GAAG,KAAK,CAAC;QAI1B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,wBAAY,CAAC,gBAAgB,CAAC,CAAC;QACvD,wCAAwC;QACxC,wEAAwE;QACxE,IAAI,CAAC,aAAa,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACpD,CAAC;IAEM,SAAS,CAAC,iBAA6C;QAC1D,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,iBAAiB,CAAC;QACnD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,UAAU,CAAC,GAAM,EAAE,QAAgB,EAAE,EAAqB;QAC7D,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI;YACA,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;gBACrB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;gBACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;aAC7B;YACD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,EAAQ,EAAE;gBAC9C,IAAI,GAAG,EAAE;oBACL,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;iBAClB;gBACD,IAAI,IAAI,EAAE;oBACN,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAQ,EAAE;wBACrB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;oBACtC,CAAC,CAAC,CAAC;iBACN;gBACD,QAAQ,GAAG,IAAI,CAAC;gBAChB,OAAO,EAAE,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC;SACN;QAAC,OAAO,CAAC,EAAE;YACR,IAAI,QAAQ,EAAE;gBACV,MAAM,CAAC,CAAC;aACX;YACD,EAAE,CAAC,CAAC,CAAC,CAAC;SACT;IACL,CAAC;IAEM,MAAM,CAAC,EAAqB;QAC/B,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAQ,EAAE;YACzC,IAAI,GAAG,EAAE;gBACL,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;aAClB;YACD,IAAI,IAAI,EAAE;gBACN,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAQ,EAAE;oBACrB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;gBACtC,CAAC,CAAC,CAAC;aACN;YACD,OAAO,EAAE,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AA9DD,gDA8DC"}
|
|
||||||
39
node_modules/@fast-csv/format/build/src/FormatterOptions.d.ts
generated
vendored
39
node_modules/@fast-csv/format/build/src/FormatterOptions.d.ts
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
import { Row, RowTransformFunction } from './types';
|
|
||||||
interface QuoteColumnMap {
|
|
||||||
[s: string]: boolean;
|
|
||||||
}
|
|
||||||
declare type QuoteColumns = boolean | boolean[] | QuoteColumnMap;
|
|
||||||
export interface FormatterOptionsArgs<I extends Row, O extends Row> {
|
|
||||||
objectMode?: boolean;
|
|
||||||
delimiter?: string;
|
|
||||||
rowDelimiter?: string;
|
|
||||||
quote?: string | boolean;
|
|
||||||
escape?: string;
|
|
||||||
quoteColumns?: QuoteColumns;
|
|
||||||
quoteHeaders?: QuoteColumns;
|
|
||||||
headers?: null | boolean | string[];
|
|
||||||
writeHeaders?: boolean;
|
|
||||||
includeEndRowDelimiter?: boolean;
|
|
||||||
writeBOM?: boolean;
|
|
||||||
transform?: RowTransformFunction<I, O>;
|
|
||||||
alwaysWriteHeaders?: boolean;
|
|
||||||
}
|
|
||||||
export declare class FormatterOptions<I extends Row, O extends Row> {
|
|
||||||
readonly objectMode: boolean;
|
|
||||||
readonly delimiter: string;
|
|
||||||
readonly rowDelimiter: string;
|
|
||||||
readonly quote: string;
|
|
||||||
readonly escape: string;
|
|
||||||
readonly quoteColumns: QuoteColumns;
|
|
||||||
readonly quoteHeaders: QuoteColumns;
|
|
||||||
readonly headers: null | string[];
|
|
||||||
readonly includeEndRowDelimiter: boolean;
|
|
||||||
readonly transform?: RowTransformFunction<I, O>;
|
|
||||||
readonly shouldWriteHeaders: boolean;
|
|
||||||
readonly writeBOM: boolean;
|
|
||||||
readonly escapedQuote: string;
|
|
||||||
readonly BOM: string;
|
|
||||||
readonly alwaysWriteHeaders: boolean;
|
|
||||||
constructor(opts?: FormatterOptionsArgs<I, O>);
|
|
||||||
}
|
|
||||||
export {};
|
|
||||||
38
node_modules/@fast-csv/format/build/src/FormatterOptions.js
generated
vendored
38
node_modules/@fast-csv/format/build/src/FormatterOptions.js
generated
vendored
@ -1,38 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.FormatterOptions = void 0;
|
|
||||||
class FormatterOptions {
|
|
||||||
constructor(opts = {}) {
|
|
||||||
var _a;
|
|
||||||
this.objectMode = true;
|
|
||||||
this.delimiter = ',';
|
|
||||||
this.rowDelimiter = '\n';
|
|
||||||
this.quote = '"';
|
|
||||||
this.escape = this.quote;
|
|
||||||
this.quoteColumns = false;
|
|
||||||
this.quoteHeaders = this.quoteColumns;
|
|
||||||
this.headers = null;
|
|
||||||
this.includeEndRowDelimiter = false;
|
|
||||||
this.writeBOM = false;
|
|
||||||
this.BOM = '\ufeff';
|
|
||||||
this.alwaysWriteHeaders = false;
|
|
||||||
Object.assign(this, opts || {});
|
|
||||||
if (typeof (opts === null || opts === void 0 ? void 0 : opts.quoteHeaders) === 'undefined') {
|
|
||||||
this.quoteHeaders = this.quoteColumns;
|
|
||||||
}
|
|
||||||
if ((opts === null || opts === void 0 ? void 0 : opts.quote) === true) {
|
|
||||||
this.quote = '"';
|
|
||||||
}
|
|
||||||
else if ((opts === null || opts === void 0 ? void 0 : opts.quote) === false) {
|
|
||||||
this.quote = '';
|
|
||||||
}
|
|
||||||
if (typeof (opts === null || opts === void 0 ? void 0 : opts.escape) !== 'string') {
|
|
||||||
this.escape = this.quote;
|
|
||||||
}
|
|
||||||
this.shouldWriteHeaders = !!this.headers && ((_a = opts.writeHeaders) !== null && _a !== void 0 ? _a : true);
|
|
||||||
this.headers = Array.isArray(this.headers) ? this.headers : null;
|
|
||||||
this.escapedQuote = `${this.escape}${this.quote}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.FormatterOptions = FormatterOptions;
|
|
||||||
//# sourceMappingURL=FormatterOptions.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/FormatterOptions.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/FormatterOptions.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"FormatterOptions.js","sourceRoot":"","sources":["../../src/FormatterOptions.ts"],"names":[],"mappings":";;;AAwBA,MAAa,gBAAgB;IA+BzB,YAAmB,OAAmC,EAAE;;QA9BxC,eAAU,GAAY,IAAI,CAAC;QAE3B,cAAS,GAAW,GAAG,CAAC;QAExB,iBAAY,GAAW,IAAI,CAAC;QAE5B,UAAK,GAAW,GAAG,CAAC;QAEpB,WAAM,GAAW,IAAI,CAAC,KAAK,CAAC;QAE5B,iBAAY,GAAiB,KAAK,CAAC;QAEnC,iBAAY,GAAiB,IAAI,CAAC,YAAY,CAAC;QAE/C,YAAO,GAAoB,IAAI,CAAC;QAEhC,2BAAsB,GAAY,KAAK,CAAC;QAMxC,aAAQ,GAAY,KAAK,CAAC;QAI1B,QAAG,GAAW,QAAQ,CAAC;QAEvB,uBAAkB,GAAY,KAAK,CAAC;QAGhD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAEhC,IAAI,QAAO,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY,CAAA,KAAK,WAAW,EAAE;YAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;SACzC;QACD,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,MAAK,IAAI,EAAE;YACtB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;SACpB;aAAM,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,MAAK,KAAK,EAAE;YAC9B,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;SACnB;QACD,IAAI,QAAO,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,CAAA,KAAK,QAAQ,EAAE;YAClC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;SAC5B;QACD,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,OAAC,IAAI,CAAC,YAAY,mCAAI,IAAI,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,IAAI,CAAC,YAAY,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IACtD,CAAC;CACJ;AAjDD,4CAiDC"}
|
|
||||||
13
node_modules/@fast-csv/format/build/src/formatter/FieldFormatter.d.ts
generated
vendored
13
node_modules/@fast-csv/format/build/src/formatter/FieldFormatter.d.ts
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
import { FormatterOptions } from '../FormatterOptions';
|
|
||||||
import { Row } from '../types';
|
|
||||||
export declare class FieldFormatter<I extends Row, O extends Row> {
|
|
||||||
private readonly formatterOptions;
|
|
||||||
private _headers;
|
|
||||||
private readonly REPLACE_REGEXP;
|
|
||||||
private readonly ESCAPE_REGEXP;
|
|
||||||
constructor(formatterOptions: FormatterOptions<I, O>);
|
|
||||||
set headers(headers: string[]);
|
|
||||||
private shouldQuote;
|
|
||||||
format(field: string, fieldIndex: number, isHeader: boolean): string;
|
|
||||||
private quoteField;
|
|
||||||
}
|
|
||||||
58
node_modules/@fast-csv/format/build/src/formatter/FieldFormatter.js
generated
vendored
58
node_modules/@fast-csv/format/build/src/formatter/FieldFormatter.js
generated
vendored
@ -1,58 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.FieldFormatter = void 0;
|
|
||||||
const lodash_isboolean_1 = __importDefault(require("lodash.isboolean"));
|
|
||||||
const lodash_isnil_1 = __importDefault(require("lodash.isnil"));
|
|
||||||
const lodash_escaperegexp_1 = __importDefault(require("lodash.escaperegexp"));
|
|
||||||
class FieldFormatter {
|
|
||||||
constructor(formatterOptions) {
|
|
||||||
this._headers = null;
|
|
||||||
this.formatterOptions = formatterOptions;
|
|
||||||
if (formatterOptions.headers !== null) {
|
|
||||||
this.headers = formatterOptions.headers;
|
|
||||||
}
|
|
||||||
this.REPLACE_REGEXP = new RegExp(formatterOptions.quote, 'g');
|
|
||||||
const escapePattern = `[${formatterOptions.delimiter}${lodash_escaperegexp_1.default(formatterOptions.rowDelimiter)}|\r|\n]`;
|
|
||||||
this.ESCAPE_REGEXP = new RegExp(escapePattern);
|
|
||||||
}
|
|
||||||
set headers(headers) {
|
|
||||||
this._headers = headers;
|
|
||||||
}
|
|
||||||
shouldQuote(fieldIndex, isHeader) {
|
|
||||||
const quoteConfig = isHeader ? this.formatterOptions.quoteHeaders : this.formatterOptions.quoteColumns;
|
|
||||||
if (lodash_isboolean_1.default(quoteConfig)) {
|
|
||||||
return quoteConfig;
|
|
||||||
}
|
|
||||||
if (Array.isArray(quoteConfig)) {
|
|
||||||
return quoteConfig[fieldIndex];
|
|
||||||
}
|
|
||||||
if (this._headers !== null) {
|
|
||||||
return quoteConfig[this._headers[fieldIndex]];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
format(field, fieldIndex, isHeader) {
|
|
||||||
const preparedField = `${lodash_isnil_1.default(field) ? '' : field}`.replace(/\0/g, '');
|
|
||||||
const { formatterOptions } = this;
|
|
||||||
if (formatterOptions.quote !== '') {
|
|
||||||
const shouldEscape = preparedField.indexOf(formatterOptions.quote) !== -1;
|
|
||||||
if (shouldEscape) {
|
|
||||||
return this.quoteField(preparedField.replace(this.REPLACE_REGEXP, formatterOptions.escapedQuote));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const hasEscapeCharacters = preparedField.search(this.ESCAPE_REGEXP) !== -1;
|
|
||||||
if (hasEscapeCharacters || this.shouldQuote(fieldIndex, isHeader)) {
|
|
||||||
return this.quoteField(preparedField);
|
|
||||||
}
|
|
||||||
return preparedField;
|
|
||||||
}
|
|
||||||
quoteField(field) {
|
|
||||||
const { quote } = this.formatterOptions;
|
|
||||||
return `${quote}${field}${quote}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.FieldFormatter = FieldFormatter;
|
|
||||||
//# sourceMappingURL=FieldFormatter.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/formatter/FieldFormatter.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/formatter/FieldFormatter.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"FieldFormatter.js","sourceRoot":"","sources":["../../../src/formatter/FieldFormatter.ts"],"names":[],"mappings":";;;;;;AAAA,wEAAyC;AACzC,gEAAiC;AACjC,8EAA+C;AAI/C,MAAa,cAAc;IASvB,YAAmB,gBAAwC;QANnD,aAAQ,GAAoB,IAAI,CAAC;QAOrC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,gBAAgB,CAAC,OAAO,KAAK,IAAI,EAAE;YACnC,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC;SAC3C;QACD,IAAI,CAAC,cAAc,GAAG,IAAI,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9D,MAAM,aAAa,GAAG,IAAI,gBAAgB,CAAC,SAAS,GAAG,6BAAY,CAAC,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC;QAC5G,IAAI,CAAC,aAAa,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,IAAW,OAAO,CAAC,OAAiB;QAChC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAEO,WAAW,CAAC,UAAkB,EAAE,QAAiB;QACrD,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC;QACvG,IAAI,0BAAS,CAAC,WAAW,CAAC,EAAE;YACxB,OAAO,WAAW,CAAC;SACtB;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YAC5B,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;SAClC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE;YACxB,OAAO,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;SACjD;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,MAAM,CAAC,KAAa,EAAE,UAAkB,EAAE,QAAiB;QAC9D,MAAM,aAAa,GAAG,GAAG,sBAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;QAClC,IAAI,gBAAgB,CAAC,KAAK,KAAK,EAAE,EAAE;YAC/B,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1E,IAAI,YAAY,EAAE;gBACd,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC;aACrG;SACJ;QACD,MAAM,mBAAmB,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,IAAI,mBAAmB,IAAI,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;YAC/D,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;SACzC;QACD,OAAO,aAAa,CAAC;IACzB,CAAC;IAEO,UAAU,CAAC,KAAa;QAC5B,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACxC,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE,CAAC;IACtC,CAAC;CACJ;AAzDD,wCAyDC"}
|
|
||||||
25
node_modules/@fast-csv/format/build/src/formatter/RowFormatter.d.ts
generated
vendored
25
node_modules/@fast-csv/format/build/src/formatter/RowFormatter.d.ts
generated
vendored
@ -1,25 +0,0 @@
|
|||||||
import { FormatterOptions } from '../FormatterOptions';
|
|
||||||
import { Row, RowArray, RowTransformFunction } from '../types';
|
|
||||||
declare type RowFormatterCallback = (error: Error | null, data?: RowArray) => void;
|
|
||||||
export declare class RowFormatter<I extends Row, O extends Row> {
|
|
||||||
private static isRowHashArray;
|
|
||||||
private static isRowArray;
|
|
||||||
private static gatherHeaders;
|
|
||||||
private static createTransform;
|
|
||||||
private readonly formatterOptions;
|
|
||||||
private readonly fieldFormatter;
|
|
||||||
private readonly shouldWriteHeaders;
|
|
||||||
private _rowTransform?;
|
|
||||||
private headers;
|
|
||||||
private hasWrittenHeaders;
|
|
||||||
private rowCount;
|
|
||||||
constructor(formatterOptions: FormatterOptions<I, O>);
|
|
||||||
set rowTransform(transformFunction: RowTransformFunction<I, O>);
|
|
||||||
format(row: I, cb: RowFormatterCallback): void;
|
|
||||||
finish(cb: RowFormatterCallback): void;
|
|
||||||
private checkHeaders;
|
|
||||||
private gatherColumns;
|
|
||||||
private callTransformer;
|
|
||||||
private formatColumns;
|
|
||||||
}
|
|
||||||
export {};
|
|
||||||
168
node_modules/@fast-csv/format/build/src/formatter/RowFormatter.js
generated
vendored
168
node_modules/@fast-csv/format/build/src/formatter/RowFormatter.js
generated
vendored
@ -1,168 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.RowFormatter = void 0;
|
|
||||||
const lodash_isfunction_1 = __importDefault(require("lodash.isfunction"));
|
|
||||||
const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
|
|
||||||
const FieldFormatter_1 = require("./FieldFormatter");
|
|
||||||
const types_1 = require("../types");
|
|
||||||
class RowFormatter {
|
|
||||||
constructor(formatterOptions) {
|
|
||||||
this.rowCount = 0;
|
|
||||||
this.formatterOptions = formatterOptions;
|
|
||||||
this.fieldFormatter = new FieldFormatter_1.FieldFormatter(formatterOptions);
|
|
||||||
this.headers = formatterOptions.headers;
|
|
||||||
this.shouldWriteHeaders = formatterOptions.shouldWriteHeaders;
|
|
||||||
this.hasWrittenHeaders = false;
|
|
||||||
if (this.headers !== null) {
|
|
||||||
this.fieldFormatter.headers = this.headers;
|
|
||||||
}
|
|
||||||
if (formatterOptions.transform) {
|
|
||||||
this.rowTransform = formatterOptions.transform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static isRowHashArray(row) {
|
|
||||||
if (Array.isArray(row)) {
|
|
||||||
return Array.isArray(row[0]) && row[0].length === 2;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
static isRowArray(row) {
|
|
||||||
return Array.isArray(row) && !this.isRowHashArray(row);
|
|
||||||
}
|
|
||||||
// get headers from a row item
|
|
||||||
static gatherHeaders(row) {
|
|
||||||
if (RowFormatter.isRowHashArray(row)) {
|
|
||||||
// lets assume a multi-dimesional array with item 0 being the header
|
|
||||||
return row.map((it) => it[0]);
|
|
||||||
}
|
|
||||||
if (Array.isArray(row)) {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
return Object.keys(row);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
static createTransform(transformFunction) {
|
|
||||||
if (types_1.isSyncTransform(transformFunction)) {
|
|
||||||
return (row, cb) => {
|
|
||||||
let transformedRow = null;
|
|
||||||
try {
|
|
||||||
transformedRow = transformFunction(row);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return cb(e);
|
|
||||||
}
|
|
||||||
return cb(null, transformedRow);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return (row, cb) => {
|
|
||||||
transformFunction(row, cb);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
set rowTransform(transformFunction) {
|
|
||||||
if (!lodash_isfunction_1.default(transformFunction)) {
|
|
||||||
throw new TypeError('The transform should be a function');
|
|
||||||
}
|
|
||||||
this._rowTransform = RowFormatter.createTransform(transformFunction);
|
|
||||||
}
|
|
||||||
format(row, cb) {
|
|
||||||
this.callTransformer(row, (err, transformedRow) => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
if (!row) {
|
|
||||||
return cb(null);
|
|
||||||
}
|
|
||||||
const rows = [];
|
|
||||||
if (transformedRow) {
|
|
||||||
const { shouldFormatColumns, headers } = this.checkHeaders(transformedRow);
|
|
||||||
if (this.shouldWriteHeaders && headers && !this.hasWrittenHeaders) {
|
|
||||||
rows.push(this.formatColumns(headers, true));
|
|
||||||
this.hasWrittenHeaders = true;
|
|
||||||
}
|
|
||||||
if (shouldFormatColumns) {
|
|
||||||
const columns = this.gatherColumns(transformedRow);
|
|
||||||
rows.push(this.formatColumns(columns, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cb(null, rows);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
finish(cb) {
|
|
||||||
const rows = [];
|
|
||||||
// check if we should write headers and we didnt get any rows
|
|
||||||
if (this.formatterOptions.alwaysWriteHeaders && this.rowCount === 0) {
|
|
||||||
if (!this.headers) {
|
|
||||||
return cb(new Error('`alwaysWriteHeaders` option is set to true but `headers` option not provided.'));
|
|
||||||
}
|
|
||||||
rows.push(this.formatColumns(this.headers, true));
|
|
||||||
}
|
|
||||||
if (this.formatterOptions.includeEndRowDelimiter) {
|
|
||||||
rows.push(this.formatterOptions.rowDelimiter);
|
|
||||||
}
|
|
||||||
return cb(null, rows);
|
|
||||||
}
|
|
||||||
// check if we need to write header return true if we should also write a row
|
|
||||||
// could be false if headers is true and the header row(first item) is passed in
|
|
||||||
checkHeaders(row) {
|
|
||||||
if (this.headers) {
|
|
||||||
// either the headers were provided by the user or we have already gathered them.
|
|
||||||
return { shouldFormatColumns: true, headers: this.headers };
|
|
||||||
}
|
|
||||||
const headers = RowFormatter.gatherHeaders(row);
|
|
||||||
this.headers = headers;
|
|
||||||
this.fieldFormatter.headers = headers;
|
|
||||||
if (!this.shouldWriteHeaders) {
|
|
||||||
// if we are not supposed to write the headers then
|
|
||||||
// always format the columns
|
|
||||||
return { shouldFormatColumns: true, headers: null };
|
|
||||||
}
|
|
||||||
// if the row is equal to headers dont format
|
|
||||||
return { shouldFormatColumns: !lodash_isequal_1.default(headers, row), headers };
|
|
||||||
}
|
|
||||||
// todo change this method to unknown[]
|
|
||||||
gatherColumns(row) {
|
|
||||||
if (this.headers === null) {
|
|
||||||
throw new Error('Headers is currently null');
|
|
||||||
}
|
|
||||||
if (!Array.isArray(row)) {
|
|
||||||
return this.headers.map((header) => row[header]);
|
|
||||||
}
|
|
||||||
if (RowFormatter.isRowHashArray(row)) {
|
|
||||||
return this.headers.map((header, i) => {
|
|
||||||
const col = row[i];
|
|
||||||
if (col) {
|
|
||||||
return col[1];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// if its a one dimensional array and headers were not provided
|
|
||||||
// then just return the row
|
|
||||||
if (RowFormatter.isRowArray(row) && !this.shouldWriteHeaders) {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
return this.headers.map((header, i) => row[i]);
|
|
||||||
}
|
|
||||||
callTransformer(row, cb) {
|
|
||||||
if (!this._rowTransform) {
|
|
||||||
return cb(null, row);
|
|
||||||
}
|
|
||||||
return this._rowTransform(row, cb);
|
|
||||||
}
|
|
||||||
formatColumns(columns, isHeadersRow) {
|
|
||||||
const formattedCols = columns
|
|
||||||
.map((field, i) => this.fieldFormatter.format(field, i, isHeadersRow))
|
|
||||||
.join(this.formatterOptions.delimiter);
|
|
||||||
const { rowCount } = this;
|
|
||||||
this.rowCount += 1;
|
|
||||||
if (rowCount) {
|
|
||||||
return [this.formatterOptions.rowDelimiter, formattedCols].join('');
|
|
||||||
}
|
|
||||||
return formattedCols;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.RowFormatter = RowFormatter;
|
|
||||||
//# sourceMappingURL=RowFormatter.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/formatter/RowFormatter.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/formatter/RowFormatter.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2
node_modules/@fast-csv/format/build/src/formatter/index.d.ts
generated
vendored
2
node_modules/@fast-csv/format/build/src/formatter/index.d.ts
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
export { RowFormatter } from './RowFormatter';
|
|
||||||
export { FieldFormatter } from './FieldFormatter';
|
|
||||||
8
node_modules/@fast-csv/format/build/src/formatter/index.js
generated
vendored
8
node_modules/@fast-csv/format/build/src/formatter/index.js
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.FieldFormatter = exports.RowFormatter = void 0;
|
|
||||||
var RowFormatter_1 = require("./RowFormatter");
|
|
||||||
Object.defineProperty(exports, "RowFormatter", { enumerable: true, get: function () { return RowFormatter_1.RowFormatter; } });
|
|
||||||
var FieldFormatter_1 = require("./FieldFormatter");
|
|
||||||
Object.defineProperty(exports, "FieldFormatter", { enumerable: true, get: function () { return FieldFormatter_1.FieldFormatter; } });
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/formatter/index.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/formatter/index.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/formatter/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA"}
|
|
||||||
14
node_modules/@fast-csv/format/build/src/index.d.ts
generated
vendored
14
node_modules/@fast-csv/format/build/src/index.d.ts
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import { Row } from './types';
|
|
||||||
import { FormatterOptionsArgs } from './FormatterOptions';
|
|
||||||
import { CsvFormatterStream } from './CsvFormatterStream';
|
|
||||||
export * from './types';
|
|
||||||
export { CsvFormatterStream } from './CsvFormatterStream';
|
|
||||||
export { FormatterOptions, FormatterOptionsArgs } from './FormatterOptions';
|
|
||||||
export declare const format: <I extends Row, O extends Row>(options?: FormatterOptionsArgs<I, O> | undefined) => CsvFormatterStream<I, O>;
|
|
||||||
export declare const write: <I extends Row, O extends Row>(rows: I[], options?: FormatterOptionsArgs<I, O> | undefined) => CsvFormatterStream<I, O>;
|
|
||||||
export declare const writeToStream: <T extends NodeJS.WritableStream, I extends Row, O extends Row>(ws: T, rows: I[], options?: FormatterOptionsArgs<I, O> | undefined) => T;
|
|
||||||
export declare const writeToBuffer: <I extends Row, O extends Row>(rows: I[], opts?: FormatterOptionsArgs<I, O>) => Promise<Buffer>;
|
|
||||||
export declare const writeToString: <I extends Row, O extends Row>(rows: I[], options?: FormatterOptionsArgs<I, O> | undefined) => Promise<string>;
|
|
||||||
export declare const writeToPath: <I extends Row, O extends Row>(path: string, rows: I[], options?: FormatterOptionsArgs<I, O> | undefined) => fs.WriteStream;
|
|
||||||
68
node_modules/@fast-csv/format/build/src/index.js
generated
vendored
68
node_modules/@fast-csv/format/build/src/index.js
generated
vendored
@ -1,68 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
||||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.writeToPath = exports.writeToString = exports.writeToBuffer = exports.writeToStream = exports.write = exports.format = exports.FormatterOptions = exports.CsvFormatterStream = void 0;
|
|
||||||
const util_1 = require("util");
|
|
||||||
const stream_1 = require("stream");
|
|
||||||
const fs = __importStar(require("fs"));
|
|
||||||
const FormatterOptions_1 = require("./FormatterOptions");
|
|
||||||
const CsvFormatterStream_1 = require("./CsvFormatterStream");
|
|
||||||
__exportStar(require("./types"), exports);
|
|
||||||
var CsvFormatterStream_2 = require("./CsvFormatterStream");
|
|
||||||
Object.defineProperty(exports, "CsvFormatterStream", { enumerable: true, get: function () { return CsvFormatterStream_2.CsvFormatterStream; } });
|
|
||||||
var FormatterOptions_2 = require("./FormatterOptions");
|
|
||||||
Object.defineProperty(exports, "FormatterOptions", { enumerable: true, get: function () { return FormatterOptions_2.FormatterOptions; } });
|
|
||||||
exports.format = (options) => new CsvFormatterStream_1.CsvFormatterStream(new FormatterOptions_1.FormatterOptions(options));
|
|
||||||
exports.write = (rows, options) => {
|
|
||||||
const csvStream = exports.format(options);
|
|
||||||
const promiseWrite = util_1.promisify((row, cb) => {
|
|
||||||
csvStream.write(row, undefined, cb);
|
|
||||||
});
|
|
||||||
rows.reduce((prev, row) => prev.then(() => promiseWrite(row)), Promise.resolve())
|
|
||||||
.then(() => csvStream.end())
|
|
||||||
.catch((err) => {
|
|
||||||
csvStream.emit('error', err);
|
|
||||||
});
|
|
||||||
return csvStream;
|
|
||||||
};
|
|
||||||
exports.writeToStream = (ws, rows, options) => exports.write(rows, options).pipe(ws);
|
|
||||||
exports.writeToBuffer = (rows, opts = {}) => {
|
|
||||||
const buffers = [];
|
|
||||||
const ws = new stream_1.Writable({
|
|
||||||
write(data, enc, writeCb) {
|
|
||||||
buffers.push(data);
|
|
||||||
writeCb();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
ws.on('error', rej).on('finish', () => res(Buffer.concat(buffers)));
|
|
||||||
exports.write(rows, opts).pipe(ws);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.writeToString = (rows, options) => exports.writeToBuffer(rows, options).then((buffer) => buffer.toString());
|
|
||||||
exports.writeToPath = (path, rows, options) => {
|
|
||||||
const stream = fs.createWriteStream(path, { encoding: 'utf8' });
|
|
||||||
return exports.write(rows, options).pipe(stream);
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/index.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/index.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAiC;AACjC,mCAAkC;AAClC,uCAAyB;AAEzB,yDAA4E;AAC5E,6DAA0D;AAE1D,0CAAwB;AACxB,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,uDAA4E;AAAnE,oHAAA,gBAAgB,OAAA;AAEZ,QAAA,MAAM,GAAG,CAA+B,OAAoC,EAA4B,EAAE,CACnH,IAAI,uCAAkB,CAAC,IAAI,mCAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AAE7C,QAAA,KAAK,GAAG,CACjB,IAAS,EACT,OAAoC,EACZ,EAAE;IAC1B,MAAM,SAAS,GAAG,cAAM,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,gBAAS,CAAC,CAAC,GAAM,EAAE,EAAkC,EAAQ,EAAE;QAChF,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CACP,CAAC,IAAmB,EAAE,GAAM,EAAiB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAkB,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EACjG,OAAO,CAAC,OAAO,EAAE,CACpB;SACI,IAAI,CAAC,GAAS,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;SACjC,KAAK,CAAC,CAAC,GAAG,EAAQ,EAAE;QACjB,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IACP,OAAO,SAAS,CAAC;AACrB,CAAC,CAAC;AAEW,QAAA,aAAa,GAAG,CACzB,EAAK,EACL,IAAS,EACT,OAAoC,EACnC,EAAE,CAAC,aAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEzB,QAAA,aAAa,GAAG,CACzB,IAAS,EACT,OAAmC,EAAE,EACtB,EAAE;IACjB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,iBAAQ,CAAC;QACpB,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO;YACpB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,EAAE,CAAC;QACd,CAAC;KACJ,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAQ,EAAE;QAClC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAS,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1E,aAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEW,QAAA,aAAa,GAAG,CACzB,IAAS,EACT,OAAoC,EACrB,EAAE,CAAC,qBAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAU,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAElF,QAAA,WAAW,GAAG,CACvB,IAAY,EACZ,IAAS,EACT,OAAoC,EACtB,EAAE;IAChB,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAChE,OAAO,aAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC,CAAC"}
|
|
||||||
9
node_modules/@fast-csv/format/build/src/types.d.ts
generated
vendored
9
node_modules/@fast-csv/format/build/src/types.d.ts
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
export declare type RowMap<V = any> = Record<string, V>;
|
|
||||||
export declare type RowHashArray<V = any> = [string, V][];
|
|
||||||
export declare type RowArray = string[];
|
|
||||||
export declare type Row = RowArray | RowHashArray | RowMap;
|
|
||||||
export declare type RowTransformCallback<R extends Row> = (error?: Error | null, row?: R) => void;
|
|
||||||
export declare type SyncRowTransform<I extends Row, O extends Row> = (row: I) => O;
|
|
||||||
export declare type AsyncRowTransform<I extends Row, O extends Row> = (row: I, cb: RowTransformCallback<O>) => void;
|
|
||||||
export declare type RowTransformFunction<I extends Row, O extends Row> = SyncRowTransform<I, O> | AsyncRowTransform<I, O>;
|
|
||||||
export declare const isSyncTransform: <I extends Row, O extends Row>(transform: RowTransformFunction<I, O>) => transform is SyncRowTransform<I, O>;
|
|
||||||
6
node_modules/@fast-csv/format/build/src/types.js
generated
vendored
6
node_modules/@fast-csv/format/build/src/types.js
generated
vendored
@ -1,6 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.isSyncTransform = void 0;
|
|
||||||
exports.isSyncTransform = (transform) => transform.length === 1;
|
|
||||||
//# sourceMappingURL=types.js.map
|
|
||||||
1
node_modules/@fast-csv/format/build/src/types.js.map
generated
vendored
1
node_modules/@fast-csv/format/build/src/types.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,uDAAuD;;;AAY1C,QAAA,eAAe,GAAG,CAC3B,SAAqC,EACF,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC"}
|
|
||||||
55
node_modules/@fast-csv/format/package.json
generated
vendored
55
node_modules/@fast-csv/format/package.json
generated
vendored
@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@fast-csv/format",
|
|
||||||
"version": "4.3.5",
|
|
||||||
"description": "fast-csv formatting module",
|
|
||||||
"keywords": [
|
|
||||||
"csv",
|
|
||||||
"format",
|
|
||||||
"write"
|
|
||||||
],
|
|
||||||
"author": "doug-martin <doug@dougamartin.com>",
|
|
||||||
"homepage": "http://c2fo.github.com/fast-csv/packages/format",
|
|
||||||
"license": "MIT",
|
|
||||||
"main": "build/src/index.js",
|
|
||||||
"types": "build/src/index.d.ts",
|
|
||||||
"directories": {
|
|
||||||
"lib": "src",
|
|
||||||
"test": "__tests__"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"build/src/**"
|
|
||||||
],
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/C2FO/fast-csv.git",
|
|
||||||
"directory": "packages/format"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prepublishOnly": "npm run build",
|
|
||||||
"build": "npm run clean && npm run compile",
|
|
||||||
"clean": "rm -rf ./build && rm -rf tsconfig.tsbuildinfo",
|
|
||||||
"compile": "tsc"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/C2FO/fast-csv/issues"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "^14.0.1",
|
|
||||||
"lodash.escaperegexp": "^4.1.2",
|
|
||||||
"lodash.isboolean": "^3.0.3",
|
|
||||||
"lodash.isequal": "^4.5.0",
|
|
||||||
"lodash.isfunction": "^3.0.9",
|
|
||||||
"lodash.isnil": "^4.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/lodash.escaperegexp": "4.1.6",
|
|
||||||
"@types/lodash.isboolean": "3.0.6",
|
|
||||||
"@types/lodash.isequal": "4.5.5",
|
|
||||||
"@types/lodash.isfunction": "3.0.6",
|
|
||||||
"@types/lodash.isnil": "4.0.6"
|
|
||||||
},
|
|
||||||
"gitHead": "b908170cb49398ae12847d050af5c8e5b0dc812f"
|
|
||||||
}
|
|
||||||
87
node_modules/@fast-csv/parse/CHANGELOG.md
generated
vendored
87
node_modules/@fast-csv/parse/CHANGELOG.md
generated
vendored
@ -1,87 +0,0 @@
|
|||||||
# Change Log
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
||||||
|
|
||||||
## [4.3.6](https://github.com/C2FO/fast-csv/compare/v4.3.5...v4.3.6) (2020-12-04)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* Simplify empty row check by removing complex regex ([4bbd39f](https://github.com/C2FO/fast-csv/commit/4bbd39f26a8cd7382151ab4f5fb102234b2f829e))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.3](https://github.com/C2FO/fast-csv/compare/v4.3.2...v4.3.3) (2020-10-30)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/parse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.2](https://github.com/C2FO/fast-csv/compare/v4.3.1...v4.3.2) (2020-09-02)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **parsing, #423:** Prevent callback from being called multiple times ([040febe](https://github.com/C2FO/fast-csv/commit/040febe17f5fe763a00f45b1d83c5acd47bbbe0b)), closes [#423](https://github.com/C2FO/fast-csv/issues/423)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.1](https://github.com/C2FO/fast-csv/compare/v4.3.0...v4.3.1) (2020-06-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **parsing:** Pass errors through callbacks ([84ecdf6](https://github.com/C2FO/fast-csv/commit/84ecdf6ed18b15d68b4ed3e2bfec7eb41b438ad8))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [4.3.0](https://github.com/C2FO/fast-csv/compare/v4.2.0...v4.3.0) (2020-05-27)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/parse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [4.2.0](https://github.com/C2FO/fast-csv/compare/v4.1.6...v4.2.0) (2020-05-19)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **parsing:** Less restrictive row parsing type [#356](https://github.com/C2FO/fast-csv/issues/356) ([87d74ec](https://github.com/C2FO/fast-csv/commit/87d74ecd2cb16f3700b1942ebbbec221afe38790))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.1.6](https://github.com/C2FO/fast-csv/compare/v4.1.5...v4.1.6) (2020-05-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **parse:** Handle escaped escape properly [#340](https://github.com/C2FO/fast-csv/issues/340) ([78d9b16](https://github.com/C2FO/fast-csv/commit/78d9b160152ee399f31086cc6b5f66a7ca7f9e24))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.1.5](https://github.com/C2FO/fast-csv/compare/v4.1.4...v4.1.5) (2020-05-15)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/parse
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.1.4](https://github.com/C2FO/fast-csv/compare/v4.1.3...v4.1.4) (2020-05-15)
|
|
||||||
|
|
||||||
**Note:** Version bump only for package @fast-csv/parse
|
|
||||||
21
node_modules/@fast-csv/parse/LICENSE
generated
vendored
21
node_modules/@fast-csv/parse/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2011-2019 C2FO
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
20
node_modules/@fast-csv/parse/README.md
generated
vendored
20
node_modules/@fast-csv/parse/README.md
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
<p align="center">
|
|
||||||
<a href="https://c2fo.io/fast-csv" target="blank"><img src="https://c2fo.io/fast-csv/img/logo.svg" width="200" alt="fast-csv Logo" /></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
[](https://www.npmjs.org/package/@fast-csv/parse)
|
|
||||||
[](https://travis-ci.org/C2FO/fast-csv)
|
|
||||||
[](https://coveralls.io/github/C2FO/fast-csv?branch=master)
|
|
||||||
[](https://snyk.io/test/github/C2FO/fast-csv?targetFile=packages/parse/package.json)
|
|
||||||
|
|
||||||
# `@fast-csv/parse`
|
|
||||||
|
|
||||||
`fast-csv` package to parse CSVs.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
[Install Guide](https://c2fo.io/fast-csv/docs/introduction/install)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To get started with `@fast-csv/parse` [check out the docs](https://c2fo.io/fast-csv/docs/parsing/getting-started)
|
|
||||||
33
node_modules/@fast-csv/parse/build/src/CsvParserStream.d.ts
generated
vendored
33
node_modules/@fast-csv/parse/build/src/CsvParserStream.d.ts
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import { Transform, TransformCallback } from 'stream';
|
|
||||||
import { ParserOptions } from './ParserOptions';
|
|
||||||
import { Row, RowTransformFunction, RowValidate } from './types';
|
|
||||||
export declare class CsvParserStream<I extends Row, O extends Row> extends Transform {
|
|
||||||
private readonly parserOptions;
|
|
||||||
private readonly decoder;
|
|
||||||
private readonly parser;
|
|
||||||
private readonly headerTransformer;
|
|
||||||
private readonly rowTransformerValidator;
|
|
||||||
private lines;
|
|
||||||
private rowCount;
|
|
||||||
private parsedRowCount;
|
|
||||||
private parsedLineCount;
|
|
||||||
private endEmitted;
|
|
||||||
private headersEmitted;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
private get hasHitRowLimit();
|
|
||||||
private get shouldEmitRows();
|
|
||||||
private get shouldSkipLine();
|
|
||||||
transform(transformFunction: RowTransformFunction<I, O>): CsvParserStream<I, O>;
|
|
||||||
validate(validateFunction: RowValidate<O>): CsvParserStream<I, O>;
|
|
||||||
emit(event: string | symbol, ...rest: any[]): boolean;
|
|
||||||
_transform(data: Buffer, encoding: string, done: TransformCallback): void;
|
|
||||||
_flush(done: TransformCallback): void;
|
|
||||||
private parse;
|
|
||||||
private processRows;
|
|
||||||
private transformRow;
|
|
||||||
private checkAndEmitHeaders;
|
|
||||||
private skipRow;
|
|
||||||
private pushRow;
|
|
||||||
private static wrapDoneCallback;
|
|
||||||
}
|
|
||||||
212
node_modules/@fast-csv/parse/build/src/CsvParserStream.js
generated
vendored
212
node_modules/@fast-csv/parse/build/src/CsvParserStream.js
generated
vendored
@ -1,212 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.CsvParserStream = void 0;
|
|
||||||
const string_decoder_1 = require("string_decoder");
|
|
||||||
const stream_1 = require("stream");
|
|
||||||
const transforms_1 = require("./transforms");
|
|
||||||
const parser_1 = require("./parser");
|
|
||||||
class CsvParserStream extends stream_1.Transform {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
super({ objectMode: parserOptions.objectMode });
|
|
||||||
this.lines = '';
|
|
||||||
this.rowCount = 0;
|
|
||||||
this.parsedRowCount = 0;
|
|
||||||
this.parsedLineCount = 0;
|
|
||||||
this.endEmitted = false;
|
|
||||||
this.headersEmitted = false;
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
this.parser = new parser_1.Parser(parserOptions);
|
|
||||||
this.headerTransformer = new transforms_1.HeaderTransformer(parserOptions);
|
|
||||||
this.decoder = new string_decoder_1.StringDecoder(parserOptions.encoding);
|
|
||||||
this.rowTransformerValidator = new transforms_1.RowTransformerValidator();
|
|
||||||
}
|
|
||||||
get hasHitRowLimit() {
|
|
||||||
return this.parserOptions.limitRows && this.rowCount >= this.parserOptions.maxRows;
|
|
||||||
}
|
|
||||||
get shouldEmitRows() {
|
|
||||||
return this.parsedRowCount > this.parserOptions.skipRows;
|
|
||||||
}
|
|
||||||
get shouldSkipLine() {
|
|
||||||
return this.parsedLineCount <= this.parserOptions.skipLines;
|
|
||||||
}
|
|
||||||
transform(transformFunction) {
|
|
||||||
this.rowTransformerValidator.rowTransform = transformFunction;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
validate(validateFunction) {
|
|
||||||
this.rowTransformerValidator.rowValidator = validateFunction;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
emit(event, ...rest) {
|
|
||||||
if (event === 'end') {
|
|
||||||
if (!this.endEmitted) {
|
|
||||||
this.endEmitted = true;
|
|
||||||
super.emit('end', this.rowCount);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return super.emit(event, ...rest);
|
|
||||||
}
|
|
||||||
_transform(data, encoding, done) {
|
|
||||||
// if we have hit our maxRows parsing limit then skip parsing
|
|
||||||
if (this.hasHitRowLimit) {
|
|
||||||
return done();
|
|
||||||
}
|
|
||||||
const wrappedCallback = CsvParserStream.wrapDoneCallback(done);
|
|
||||||
try {
|
|
||||||
const { lines } = this;
|
|
||||||
const newLine = lines + this.decoder.write(data);
|
|
||||||
const rows = this.parse(newLine, true);
|
|
||||||
return this.processRows(rows, wrappedCallback);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return wrappedCallback(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_flush(done) {
|
|
||||||
const wrappedCallback = CsvParserStream.wrapDoneCallback(done);
|
|
||||||
// if we have hit our maxRows parsing limit then skip parsing
|
|
||||||
if (this.hasHitRowLimit) {
|
|
||||||
return wrappedCallback();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const newLine = this.lines + this.decoder.end();
|
|
||||||
const rows = this.parse(newLine, false);
|
|
||||||
return this.processRows(rows, wrappedCallback);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return wrappedCallback(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parse(data, hasMoreData) {
|
|
||||||
if (!data) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const { line, rows } = this.parser.parse(data, hasMoreData);
|
|
||||||
this.lines = line;
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
processRows(rows, cb) {
|
|
||||||
const rowsLength = rows.length;
|
|
||||||
const iterate = (i) => {
|
|
||||||
const callNext = (err) => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
if (i % 100 === 0) {
|
|
||||||
// incase the transform are sync insert a next tick to prevent stack overflow
|
|
||||||
setImmediate(() => iterate(i + 1));
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return iterate(i + 1);
|
|
||||||
};
|
|
||||||
this.checkAndEmitHeaders();
|
|
||||||
// if we have emitted all rows or we have hit the maxRows limit option
|
|
||||||
// then end
|
|
||||||
if (i >= rowsLength || this.hasHitRowLimit) {
|
|
||||||
return cb();
|
|
||||||
}
|
|
||||||
this.parsedLineCount += 1;
|
|
||||||
if (this.shouldSkipLine) {
|
|
||||||
return callNext();
|
|
||||||
}
|
|
||||||
const row = rows[i];
|
|
||||||
this.rowCount += 1;
|
|
||||||
this.parsedRowCount += 1;
|
|
||||||
const nextRowCount = this.rowCount;
|
|
||||||
return this.transformRow(row, (err, transformResult) => {
|
|
||||||
if (err) {
|
|
||||||
this.rowCount -= 1;
|
|
||||||
return callNext(err);
|
|
||||||
}
|
|
||||||
if (!transformResult) {
|
|
||||||
return callNext(new Error('expected transform result'));
|
|
||||||
}
|
|
||||||
if (!transformResult.isValid) {
|
|
||||||
this.emit('data-invalid', transformResult.row, nextRowCount, transformResult.reason);
|
|
||||||
}
|
|
||||||
else if (transformResult.row) {
|
|
||||||
return this.pushRow(transformResult.row, callNext);
|
|
||||||
}
|
|
||||||
return callNext();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
iterate(0);
|
|
||||||
}
|
|
||||||
transformRow(parsedRow, cb) {
|
|
||||||
try {
|
|
||||||
this.headerTransformer.transform(parsedRow, (err, withHeaders) => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
if (!withHeaders) {
|
|
||||||
return cb(new Error('Expected result from header transform'));
|
|
||||||
}
|
|
||||||
if (!withHeaders.isValid) {
|
|
||||||
if (this.shouldEmitRows) {
|
|
||||||
return cb(null, { isValid: false, row: parsedRow });
|
|
||||||
}
|
|
||||||
// skipped because of skipRows option remove from total row count
|
|
||||||
return this.skipRow(cb);
|
|
||||||
}
|
|
||||||
if (withHeaders.row) {
|
|
||||||
if (this.shouldEmitRows) {
|
|
||||||
return this.rowTransformerValidator.transformAndValidate(withHeaders.row, cb);
|
|
||||||
}
|
|
||||||
// skipped because of skipRows option remove from total row count
|
|
||||||
return this.skipRow(cb);
|
|
||||||
}
|
|
||||||
// this is a header row dont include in the rowCount or parsedRowCount
|
|
||||||
this.rowCount -= 1;
|
|
||||||
this.parsedRowCount -= 1;
|
|
||||||
return cb(null, { row: null, isValid: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
cb(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkAndEmitHeaders() {
|
|
||||||
if (!this.headersEmitted && this.headerTransformer.headers) {
|
|
||||||
this.headersEmitted = true;
|
|
||||||
this.emit('headers', this.headerTransformer.headers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
skipRow(cb) {
|
|
||||||
// skipped because of skipRows option remove from total row count
|
|
||||||
this.rowCount -= 1;
|
|
||||||
return cb(null, { row: null, isValid: true });
|
|
||||||
}
|
|
||||||
pushRow(row, cb) {
|
|
||||||
try {
|
|
||||||
if (!this.parserOptions.objectMode) {
|
|
||||||
this.push(JSON.stringify(row));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.push(row);
|
|
||||||
}
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
cb(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static wrapDoneCallback(done) {
|
|
||||||
let errorCalled = false;
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
return (err, ...args) => {
|
|
||||||
if (err) {
|
|
||||||
if (errorCalled) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
errorCalled = true;
|
|
||||||
done(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
done(...args);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.CsvParserStream = CsvParserStream;
|
|
||||||
//# sourceMappingURL=CsvParserStream.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/CsvParserStream.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/CsvParserStream.js.map
generated
vendored
File diff suppressed because one or more lines are too long
47
node_modules/@fast-csv/parse/build/src/ParserOptions.d.ts
generated
vendored
47
node_modules/@fast-csv/parse/build/src/ParserOptions.d.ts
generated
vendored
@ -1,47 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import { HeaderArray, HeaderTransformFunction } from './types';
|
|
||||||
export interface ParserOptionsArgs {
|
|
||||||
objectMode?: boolean;
|
|
||||||
delimiter?: string;
|
|
||||||
quote?: string | null;
|
|
||||||
escape?: string;
|
|
||||||
headers?: boolean | HeaderTransformFunction | HeaderArray;
|
|
||||||
renameHeaders?: boolean;
|
|
||||||
ignoreEmpty?: boolean;
|
|
||||||
comment?: string;
|
|
||||||
strictColumnHandling?: boolean;
|
|
||||||
discardUnmappedColumns?: boolean;
|
|
||||||
trim?: boolean;
|
|
||||||
ltrim?: boolean;
|
|
||||||
rtrim?: boolean;
|
|
||||||
encoding?: string;
|
|
||||||
maxRows?: number;
|
|
||||||
skipLines?: number;
|
|
||||||
skipRows?: number;
|
|
||||||
}
|
|
||||||
export declare class ParserOptions {
|
|
||||||
readonly escapedDelimiter: string;
|
|
||||||
readonly objectMode: boolean;
|
|
||||||
readonly delimiter: string;
|
|
||||||
readonly ignoreEmpty: boolean;
|
|
||||||
readonly quote: string | null;
|
|
||||||
readonly escape: string | null;
|
|
||||||
readonly escapeChar: string | null;
|
|
||||||
readonly comment: string | null;
|
|
||||||
readonly supportsComments: boolean;
|
|
||||||
readonly ltrim: boolean;
|
|
||||||
readonly rtrim: boolean;
|
|
||||||
readonly trim: boolean;
|
|
||||||
readonly headers: boolean | HeaderTransformFunction | HeaderArray | null;
|
|
||||||
readonly renameHeaders: boolean;
|
|
||||||
readonly strictColumnHandling: boolean;
|
|
||||||
readonly discardUnmappedColumns: boolean;
|
|
||||||
readonly carriageReturn: string;
|
|
||||||
readonly NEXT_TOKEN_REGEXP: RegExp;
|
|
||||||
readonly encoding: BufferEncoding;
|
|
||||||
readonly limitRows: boolean;
|
|
||||||
readonly maxRows: number;
|
|
||||||
readonly skipLines: number;
|
|
||||||
readonly skipRows: number;
|
|
||||||
constructor(opts?: ParserOptionsArgs);
|
|
||||||
}
|
|
||||||
47
node_modules/@fast-csv/parse/build/src/ParserOptions.js
generated
vendored
47
node_modules/@fast-csv/parse/build/src/ParserOptions.js
generated
vendored
@ -1,47 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.ParserOptions = void 0;
|
|
||||||
const lodash_escaperegexp_1 = __importDefault(require("lodash.escaperegexp"));
|
|
||||||
const lodash_isnil_1 = __importDefault(require("lodash.isnil"));
|
|
||||||
class ParserOptions {
|
|
||||||
constructor(opts) {
|
|
||||||
var _a;
|
|
||||||
this.objectMode = true;
|
|
||||||
this.delimiter = ',';
|
|
||||||
this.ignoreEmpty = false;
|
|
||||||
this.quote = '"';
|
|
||||||
this.escape = null;
|
|
||||||
this.escapeChar = this.quote;
|
|
||||||
this.comment = null;
|
|
||||||
this.supportsComments = false;
|
|
||||||
this.ltrim = false;
|
|
||||||
this.rtrim = false;
|
|
||||||
this.trim = false;
|
|
||||||
this.headers = null;
|
|
||||||
this.renameHeaders = false;
|
|
||||||
this.strictColumnHandling = false;
|
|
||||||
this.discardUnmappedColumns = false;
|
|
||||||
this.carriageReturn = '\r';
|
|
||||||
this.encoding = 'utf8';
|
|
||||||
this.limitRows = false;
|
|
||||||
this.maxRows = 0;
|
|
||||||
this.skipLines = 0;
|
|
||||||
this.skipRows = 0;
|
|
||||||
Object.assign(this, opts || {});
|
|
||||||
if (this.delimiter.length > 1) {
|
|
||||||
throw new Error('delimiter option must be one character long');
|
|
||||||
}
|
|
||||||
this.escapedDelimiter = lodash_escaperegexp_1.default(this.delimiter);
|
|
||||||
this.escapeChar = (_a = this.escape) !== null && _a !== void 0 ? _a : this.quote;
|
|
||||||
this.supportsComments = !lodash_isnil_1.default(this.comment);
|
|
||||||
this.NEXT_TOKEN_REGEXP = new RegExp(`([^\\s]|\\r\\n|\\n|\\r|${this.escapedDelimiter})`);
|
|
||||||
if (this.maxRows > 0) {
|
|
||||||
this.limitRows = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ParserOptions = ParserOptions;
|
|
||||||
//# sourceMappingURL=ParserOptions.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/ParserOptions.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/ParserOptions.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"ParserOptions.js","sourceRoot":"","sources":["../../src/ParserOptions.ts"],"names":[],"mappings":";;;;;;AAAA,8EAA+C;AAC/C,gEAAiC;AAuBjC,MAAa,aAAa;IA+CtB,YAAmB,IAAwB;;QA5C3B,eAAU,GAAY,IAAI,CAAC;QAE3B,cAAS,GAAW,GAAG,CAAC;QAExB,gBAAW,GAAY,KAAK,CAAC;QAE7B,UAAK,GAAkB,GAAG,CAAC;QAE3B,WAAM,GAAkB,IAAI,CAAC;QAE7B,eAAU,GAAkB,IAAI,CAAC,KAAK,CAAC;QAEvC,YAAO,GAAkB,IAAI,CAAC;QAE9B,qBAAgB,GAAY,KAAK,CAAC;QAElC,UAAK,GAAY,KAAK,CAAC;QAEvB,UAAK,GAAY,KAAK,CAAC;QAEvB,SAAI,GAAY,KAAK,CAAC;QAEtB,YAAO,GAA2D,IAAI,CAAC;QAEvE,kBAAa,GAAY,KAAK,CAAC;QAE/B,yBAAoB,GAAY,KAAK,CAAC;QAEtC,2BAAsB,GAAY,KAAK,CAAC;QAExC,mBAAc,GAAW,IAAI,CAAC;QAI9B,aAAQ,GAAmB,MAAM,CAAC;QAElC,cAAS,GAAY,KAAK,CAAC;QAE3B,YAAO,GAAW,CAAC,CAAC;QAEpB,cAAS,GAAW,CAAC,CAAC;QAEtB,aAAQ,GAAW,CAAC,CAAC;QAGjC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAClE;QACD,IAAI,CAAC,gBAAgB,GAAG,6BAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,SAAG,IAAI,CAAC,MAAM,mCAAI,IAAI,CAAC,KAAK,CAAC;QAC5C,IAAI,CAAC,gBAAgB,GAAG,CAAC,sBAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,iBAAiB,GAAG,IAAI,MAAM,CAAC,0BAA0B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAExF,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE;YAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;SACzB;IACL,CAAC;CACJ;AA7DD,sCA6DC"}
|
|
||||||
11
node_modules/@fast-csv/parse/build/src/index.d.ts
generated
vendored
11
node_modules/@fast-csv/parse/build/src/index.d.ts
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import { ParserOptionsArgs } from './ParserOptions';
|
|
||||||
import { CsvParserStream } from './CsvParserStream';
|
|
||||||
import { Row } from './types';
|
|
||||||
export * from './types';
|
|
||||||
export { CsvParserStream } from './CsvParserStream';
|
|
||||||
export { ParserOptions, ParserOptionsArgs } from './ParserOptions';
|
|
||||||
export declare const parse: <I extends Row<any>, O extends Row<any>>(args?: ParserOptionsArgs | undefined) => CsvParserStream<I, O>;
|
|
||||||
export declare const parseStream: <I extends Row<any>, O extends Row<any>>(stream: NodeJS.ReadableStream, options?: ParserOptionsArgs | undefined) => CsvParserStream<I, O>;
|
|
||||||
export declare const parseFile: <I extends Row<any>, O extends Row<any>>(location: string, options?: ParserOptionsArgs) => CsvParserStream<I, O>;
|
|
||||||
export declare const parseString: <I extends Row<any>, O extends Row<any>>(string: string, options?: ParserOptionsArgs | undefined) => CsvParserStream<I, O>;
|
|
||||||
44
node_modules/@fast-csv/parse/build/src/index.js
generated
vendored
44
node_modules/@fast-csv/parse/build/src/index.js
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
||||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.parseString = exports.parseFile = exports.parseStream = exports.parse = exports.ParserOptions = exports.CsvParserStream = void 0;
|
|
||||||
const fs = __importStar(require("fs"));
|
|
||||||
const stream_1 = require("stream");
|
|
||||||
const ParserOptions_1 = require("./ParserOptions");
|
|
||||||
const CsvParserStream_1 = require("./CsvParserStream");
|
|
||||||
__exportStar(require("./types"), exports);
|
|
||||||
var CsvParserStream_2 = require("./CsvParserStream");
|
|
||||||
Object.defineProperty(exports, "CsvParserStream", { enumerable: true, get: function () { return CsvParserStream_2.CsvParserStream; } });
|
|
||||||
var ParserOptions_2 = require("./ParserOptions");
|
|
||||||
Object.defineProperty(exports, "ParserOptions", { enumerable: true, get: function () { return ParserOptions_2.ParserOptions; } });
|
|
||||||
exports.parse = (args) => new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(args));
|
|
||||||
exports.parseStream = (stream, options) => stream.pipe(new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(options)));
|
|
||||||
exports.parseFile = (location, options = {}) => fs.createReadStream(location).pipe(new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(options)));
|
|
||||||
exports.parseString = (string, options) => {
|
|
||||||
const rs = new stream_1.Readable();
|
|
||||||
rs.push(string);
|
|
||||||
rs.push(null);
|
|
||||||
return rs.pipe(new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(options)));
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/index.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/index.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,mCAAkC;AAClC,mDAAmE;AACnE,uDAAoD;AAGpD,0CAAwB;AACxB,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,iDAAmE;AAA1D,8GAAA,aAAa,OAAA;AAET,QAAA,KAAK,GAAG,CAA+B,IAAwB,EAAyB,EAAE,CACnG,IAAI,iCAAe,CAAC,IAAI,6BAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AAEpC,QAAA,WAAW,GAAG,CACvB,MAA6B,EAC7B,OAA2B,EACN,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iCAAe,CAAC,IAAI,6BAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAE5E,QAAA,SAAS,GAAG,CACrB,QAAgB,EAChB,UAA6B,EAAE,EACV,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,iCAAe,CAAC,IAAI,6BAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEnG,QAAA,WAAW,GAAG,CACvB,MAAc,EACd,OAA2B,EACN,EAAE;IACvB,MAAM,EAAE,GAAG,IAAI,iBAAQ,EAAE,CAAC;IAC1B,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,iCAAe,CAAC,IAAI,6BAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,CAAC"}
|
|
||||||
15
node_modules/@fast-csv/parse/build/src/parser/Parser.d.ts
generated
vendored
15
node_modules/@fast-csv/parse/build/src/parser/Parser.d.ts
generated
vendored
@ -1,15 +0,0 @@
|
|||||||
import { ParserOptions } from '../ParserOptions';
|
|
||||||
export interface ParseResult {
|
|
||||||
line: string;
|
|
||||||
rows: string[][];
|
|
||||||
}
|
|
||||||
export declare class Parser {
|
|
||||||
private static removeBOM;
|
|
||||||
private readonly parserOptions;
|
|
||||||
private readonly rowParser;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
parse(line: string, hasMoreData: boolean): ParseResult;
|
|
||||||
private parseWithoutComments;
|
|
||||||
private parseWithComments;
|
|
||||||
private parseRow;
|
|
||||||
}
|
|
||||||
76
node_modules/@fast-csv/parse/build/src/parser/Parser.js
generated
vendored
76
node_modules/@fast-csv/parse/build/src/parser/Parser.js
generated
vendored
@ -1,76 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Parser = void 0;
|
|
||||||
const Scanner_1 = require("./Scanner");
|
|
||||||
const RowParser_1 = require("./RowParser");
|
|
||||||
const Token_1 = require("./Token");
|
|
||||||
class Parser {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
this.rowParser = new RowParser_1.RowParser(this.parserOptions);
|
|
||||||
}
|
|
||||||
static removeBOM(line) {
|
|
||||||
// Catches EFBBBF (UTF-8 BOM) because the buffer-to-string
|
|
||||||
// conversion translates it to FEFF (UTF-16 BOM)
|
|
||||||
if (line && line.charCodeAt(0) === 0xfeff) {
|
|
||||||
return line.slice(1);
|
|
||||||
}
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
parse(line, hasMoreData) {
|
|
||||||
const scanner = new Scanner_1.Scanner({
|
|
||||||
line: Parser.removeBOM(line),
|
|
||||||
parserOptions: this.parserOptions,
|
|
||||||
hasMoreData,
|
|
||||||
});
|
|
||||||
if (this.parserOptions.supportsComments) {
|
|
||||||
return this.parseWithComments(scanner);
|
|
||||||
}
|
|
||||||
return this.parseWithoutComments(scanner);
|
|
||||||
}
|
|
||||||
parseWithoutComments(scanner) {
|
|
||||||
const rows = [];
|
|
||||||
let shouldContinue = true;
|
|
||||||
while (shouldContinue) {
|
|
||||||
shouldContinue = this.parseRow(scanner, rows);
|
|
||||||
}
|
|
||||||
return { line: scanner.line, rows };
|
|
||||||
}
|
|
||||||
parseWithComments(scanner) {
|
|
||||||
const { parserOptions } = this;
|
|
||||||
const rows = [];
|
|
||||||
for (let nextToken = scanner.nextCharacterToken; nextToken !== null; nextToken = scanner.nextCharacterToken) {
|
|
||||||
if (Token_1.Token.isTokenComment(nextToken, parserOptions)) {
|
|
||||||
const cursor = scanner.advancePastLine();
|
|
||||||
if (cursor === null) {
|
|
||||||
return { line: scanner.lineFromCursor, rows };
|
|
||||||
}
|
|
||||||
if (!scanner.hasMoreCharacters) {
|
|
||||||
return { line: scanner.lineFromCursor, rows };
|
|
||||||
}
|
|
||||||
scanner.truncateToCursor();
|
|
||||||
}
|
|
||||||
else if (!this.parseRow(scanner, rows)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { line: scanner.line, rows };
|
|
||||||
}
|
|
||||||
parseRow(scanner, rows) {
|
|
||||||
const nextToken = scanner.nextNonSpaceToken;
|
|
||||||
if (!nextToken) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const row = this.rowParser.parse(scanner);
|
|
||||||
if (row === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this.parserOptions.ignoreEmpty && RowParser_1.RowParser.isEmptyRow(row)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
rows.push(row);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Parser = Parser;
|
|
||||||
//# sourceMappingURL=Parser.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/Parser.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/Parser.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"Parser.js","sourceRoot":"","sources":["../../../src/parser/Parser.ts"],"names":[],"mappings":";;;AAAA,uCAAoC;AACpC,2CAAwC;AAGxC,mCAAgC;AAMhC,MAAa,MAAM;IAcf,YAAmB,aAA4B;QAC3C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACvD,CAAC;IAhBO,MAAM,CAAC,SAAS,CAAC,IAAY;QACjC,0DAA0D;QAC1D,gDAAgD;QAChD,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE;YACvC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACxB;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAWM,KAAK,CAAC,IAAY,EAAE,WAAoB;QAC3C,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC;YACxB,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;YAC5B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,WAAW;SACd,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;YACrC,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;SAC1C;QACD,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAEO,oBAAoB,CAAC,OAAgB;QACzC,MAAM,IAAI,GAAe,EAAE,CAAC;QAC5B,IAAI,cAAc,GAAG,IAAI,CAAC;QAC1B,OAAO,cAAc,EAAE;YACnB,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;SACjD;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IAEO,iBAAiB,CAAC,OAAgB;QACtC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;QAC/B,MAAM,IAAI,GAAe,EAAE,CAAC;QAC5B,KAAK,IAAI,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,SAAS,KAAK,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE;YACzG,IAAI,aAAK,CAAC,cAAc,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE;gBAChD,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;gBACzC,IAAI,MAAM,KAAK,IAAI,EAAE;oBACjB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;iBACjD;gBACD,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE;oBAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;iBACjD;gBACD,OAAO,CAAC,gBAAgB,EAAE,CAAC;aAC9B;iBAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;gBACtC,MAAM;aACT;SACJ;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IAEO,QAAQ,CAAC,OAAgB,EAAE,IAAgB;QAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE;YACZ,OAAO,KAAK,CAAC;SAChB;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,GAAG,KAAK,IAAI,EAAE;YACd,OAAO,KAAK,CAAC;SAChB;QACD,IAAI,IAAI,CAAC,aAAa,CAAC,WAAW,IAAI,qBAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YAC7D,OAAO,IAAI,CAAC;SACf;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AA3ED,wBA2EC"}
|
|
||||||
12
node_modules/@fast-csv/parse/build/src/parser/RowParser.d.ts
generated
vendored
12
node_modules/@fast-csv/parse/build/src/parser/RowParser.d.ts
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
import { Scanner } from './Scanner';
|
|
||||||
import { ParserOptions } from '../ParserOptions';
|
|
||||||
import { RowArray } from '../types';
|
|
||||||
export declare class RowParser {
|
|
||||||
static isEmptyRow(row: RowArray): boolean;
|
|
||||||
private readonly parserOptions;
|
|
||||||
private readonly columnParser;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
parse(scanner: Scanner): RowArray | null;
|
|
||||||
private getStartToken;
|
|
||||||
private shouldSkipColumnParse;
|
|
||||||
}
|
|
||||||
76
node_modules/@fast-csv/parse/build/src/parser/RowParser.js
generated
vendored
76
node_modules/@fast-csv/parse/build/src/parser/RowParser.js
generated
vendored
@ -1,76 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.RowParser = void 0;
|
|
||||||
const column_1 = require("./column");
|
|
||||||
const Token_1 = require("./Token");
|
|
||||||
const EMPTY_STRING = '';
|
|
||||||
class RowParser {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
this.columnParser = new column_1.ColumnParser(parserOptions);
|
|
||||||
}
|
|
||||||
static isEmptyRow(row) {
|
|
||||||
return row.join(EMPTY_STRING).replace(/\s+/g, EMPTY_STRING) === EMPTY_STRING;
|
|
||||||
}
|
|
||||||
parse(scanner) {
|
|
||||||
const { parserOptions } = this;
|
|
||||||
const { hasMoreData } = scanner;
|
|
||||||
const currentScanner = scanner;
|
|
||||||
const columns = [];
|
|
||||||
let currentToken = this.getStartToken(currentScanner, columns);
|
|
||||||
while (currentToken) {
|
|
||||||
if (Token_1.Token.isTokenRowDelimiter(currentToken)) {
|
|
||||||
currentScanner.advancePastToken(currentToken);
|
|
||||||
// if ends with CR and there is more data, keep unparsed due to possible
|
|
||||||
// coming LF in CRLF
|
|
||||||
if (!currentScanner.hasMoreCharacters &&
|
|
||||||
Token_1.Token.isTokenCarriageReturn(currentToken, parserOptions) &&
|
|
||||||
hasMoreData) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
currentScanner.truncateToCursor();
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
if (!this.shouldSkipColumnParse(currentScanner, currentToken, columns)) {
|
|
||||||
const item = this.columnParser.parse(currentScanner);
|
|
||||||
if (item === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
columns.push(item);
|
|
||||||
}
|
|
||||||
currentToken = currentScanner.nextNonSpaceToken;
|
|
||||||
}
|
|
||||||
if (!hasMoreData) {
|
|
||||||
currentScanner.truncateToCursor();
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
getStartToken(scanner, columns) {
|
|
||||||
const currentToken = scanner.nextNonSpaceToken;
|
|
||||||
if (currentToken !== null && Token_1.Token.isTokenDelimiter(currentToken, this.parserOptions)) {
|
|
||||||
columns.push('');
|
|
||||||
return scanner.nextNonSpaceToken;
|
|
||||||
}
|
|
||||||
return currentToken;
|
|
||||||
}
|
|
||||||
shouldSkipColumnParse(scanner, currentToken, columns) {
|
|
||||||
const { parserOptions } = this;
|
|
||||||
if (Token_1.Token.isTokenDelimiter(currentToken, parserOptions)) {
|
|
||||||
scanner.advancePastToken(currentToken);
|
|
||||||
// if the delimiter is at the end of a line
|
|
||||||
const nextToken = scanner.nextCharacterToken;
|
|
||||||
if (!scanner.hasMoreCharacters || (nextToken !== null && Token_1.Token.isTokenRowDelimiter(nextToken))) {
|
|
||||||
columns.push('');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (nextToken !== null && Token_1.Token.isTokenDelimiter(nextToken, parserOptions)) {
|
|
||||||
columns.push('');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.RowParser = RowParser;
|
|
||||||
//# sourceMappingURL=RowParser.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/RowParser.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/RowParser.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"RowParser.js","sourceRoot":"","sources":["../../../src/parser/RowParser.ts"],"names":[],"mappings":"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"}
|
|
||||||
25
node_modules/@fast-csv/parse/build/src/parser/Scanner.d.ts
generated
vendored
25
node_modules/@fast-csv/parse/build/src/parser/Scanner.d.ts
generated
vendored
@ -1,25 +0,0 @@
|
|||||||
import { ParserOptions } from '../ParserOptions';
|
|
||||||
import { MaybeToken, Token } from './Token';
|
|
||||||
export interface ScannerArgs {
|
|
||||||
line: string;
|
|
||||||
parserOptions: ParserOptions;
|
|
||||||
hasMoreData: boolean;
|
|
||||||
cursor?: number;
|
|
||||||
}
|
|
||||||
export declare class Scanner {
|
|
||||||
line: string;
|
|
||||||
private readonly parserOptions;
|
|
||||||
lineLength: number;
|
|
||||||
readonly hasMoreData: boolean;
|
|
||||||
cursor: number;
|
|
||||||
constructor(args: ScannerArgs);
|
|
||||||
get hasMoreCharacters(): boolean;
|
|
||||||
get nextNonSpaceToken(): MaybeToken;
|
|
||||||
get nextCharacterToken(): MaybeToken;
|
|
||||||
get lineFromCursor(): string;
|
|
||||||
advancePastLine(): Scanner | null;
|
|
||||||
advanceTo(cursor: number): Scanner;
|
|
||||||
advanceToToken(token: Token): Scanner;
|
|
||||||
advancePastToken(token: Token): Scanner;
|
|
||||||
truncateToCursor(): Scanner;
|
|
||||||
}
|
|
||||||
82
node_modules/@fast-csv/parse/build/src/parser/Scanner.js
generated
vendored
82
node_modules/@fast-csv/parse/build/src/parser/Scanner.js
generated
vendored
@ -1,82 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Scanner = void 0;
|
|
||||||
const Token_1 = require("./Token");
|
|
||||||
const ROW_DELIMITER = /((?:\r\n)|\n|\r)/;
|
|
||||||
class Scanner {
|
|
||||||
constructor(args) {
|
|
||||||
this.cursor = 0;
|
|
||||||
this.line = args.line;
|
|
||||||
this.lineLength = this.line.length;
|
|
||||||
this.parserOptions = args.parserOptions;
|
|
||||||
this.hasMoreData = args.hasMoreData;
|
|
||||||
this.cursor = args.cursor || 0;
|
|
||||||
}
|
|
||||||
get hasMoreCharacters() {
|
|
||||||
return this.lineLength > this.cursor;
|
|
||||||
}
|
|
||||||
get nextNonSpaceToken() {
|
|
||||||
const { lineFromCursor } = this;
|
|
||||||
const regex = this.parserOptions.NEXT_TOKEN_REGEXP;
|
|
||||||
if (lineFromCursor.search(regex) === -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const match = regex.exec(lineFromCursor);
|
|
||||||
if (match == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const token = match[1];
|
|
||||||
const startCursor = this.cursor + (match.index || 0);
|
|
||||||
return new Token_1.Token({
|
|
||||||
token,
|
|
||||||
startCursor,
|
|
||||||
endCursor: startCursor + token.length - 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
get nextCharacterToken() {
|
|
||||||
const { cursor, lineLength } = this;
|
|
||||||
if (lineLength <= cursor) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new Token_1.Token({
|
|
||||||
token: this.line[cursor],
|
|
||||||
startCursor: cursor,
|
|
||||||
endCursor: cursor,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
get lineFromCursor() {
|
|
||||||
return this.line.substr(this.cursor);
|
|
||||||
}
|
|
||||||
advancePastLine() {
|
|
||||||
const match = ROW_DELIMITER.exec(this.lineFromCursor);
|
|
||||||
if (!match) {
|
|
||||||
if (this.hasMoreData) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
this.cursor = this.lineLength;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.cursor += (match.index || 0) + match[0].length;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
advanceTo(cursor) {
|
|
||||||
this.cursor = cursor;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
advanceToToken(token) {
|
|
||||||
this.cursor = token.startCursor;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
advancePastToken(token) {
|
|
||||||
this.cursor = token.endCursor + 1;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
truncateToCursor() {
|
|
||||||
this.line = this.lineFromCursor;
|
|
||||||
this.lineLength = this.line.length;
|
|
||||||
this.cursor = 0;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Scanner = Scanner;
|
|
||||||
//# sourceMappingURL=Scanner.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/Scanner.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/Scanner.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"Scanner.js","sourceRoot":"","sources":["../../../src/parser/Scanner.ts"],"names":[],"mappings":"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"}
|
|
||||||
19
node_modules/@fast-csv/parse/build/src/parser/Token.d.ts
generated
vendored
19
node_modules/@fast-csv/parse/build/src/parser/Token.d.ts
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
import { ParserOptions } from '../ParserOptions';
|
|
||||||
export declare type MaybeToken = Token | null;
|
|
||||||
export interface TokenArgs {
|
|
||||||
token: string;
|
|
||||||
startCursor: number;
|
|
||||||
endCursor: number;
|
|
||||||
}
|
|
||||||
export declare class Token {
|
|
||||||
static isTokenRowDelimiter(token: Token): boolean;
|
|
||||||
static isTokenCarriageReturn(token: Token, parserOptions: ParserOptions): boolean;
|
|
||||||
static isTokenComment(token: Token, parserOptions: ParserOptions): boolean;
|
|
||||||
static isTokenEscapeCharacter(token: Token, parserOptions: ParserOptions): boolean;
|
|
||||||
static isTokenQuote(token: Token, parserOptions: ParserOptions): boolean;
|
|
||||||
static isTokenDelimiter(token: Token, parserOptions: ParserOptions): boolean;
|
|
||||||
readonly token: string;
|
|
||||||
readonly startCursor: number;
|
|
||||||
readonly endCursor: number;
|
|
||||||
constructor(tokenArgs: TokenArgs);
|
|
||||||
}
|
|
||||||
31
node_modules/@fast-csv/parse/build/src/parser/Token.js
generated
vendored
31
node_modules/@fast-csv/parse/build/src/parser/Token.js
generated
vendored
@ -1,31 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Token = void 0;
|
|
||||||
class Token {
|
|
||||||
constructor(tokenArgs) {
|
|
||||||
this.token = tokenArgs.token;
|
|
||||||
this.startCursor = tokenArgs.startCursor;
|
|
||||||
this.endCursor = tokenArgs.endCursor;
|
|
||||||
}
|
|
||||||
static isTokenRowDelimiter(token) {
|
|
||||||
const content = token.token;
|
|
||||||
return content === '\r' || content === '\n' || content === '\r\n';
|
|
||||||
}
|
|
||||||
static isTokenCarriageReturn(token, parserOptions) {
|
|
||||||
return token.token === parserOptions.carriageReturn;
|
|
||||||
}
|
|
||||||
static isTokenComment(token, parserOptions) {
|
|
||||||
return parserOptions.supportsComments && !!token && token.token === parserOptions.comment;
|
|
||||||
}
|
|
||||||
static isTokenEscapeCharacter(token, parserOptions) {
|
|
||||||
return token.token === parserOptions.escapeChar;
|
|
||||||
}
|
|
||||||
static isTokenQuote(token, parserOptions) {
|
|
||||||
return token.token === parserOptions.quote;
|
|
||||||
}
|
|
||||||
static isTokenDelimiter(token, parserOptions) {
|
|
||||||
return token.token === parserOptions.delimiter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Token = Token;
|
|
||||||
//# sourceMappingURL=Token.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/Token.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/Token.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"Token.js","sourceRoot":"","sources":["../../../src/parser/Token.ts"],"names":[],"mappings":";;;AAUA,MAAa,KAAK;IAgCd,YAAmB,SAAoB;QACnC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;IACzC,CAAC;IAnCM,MAAM,CAAC,mBAAmB,CAAC,KAAY;QAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC;QAC5B,OAAO,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,CAAC;IACtE,CAAC;IAEM,MAAM,CAAC,qBAAqB,CAAC,KAAY,EAAE,aAA4B;QAC1E,OAAO,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,cAAc,CAAC;IACxD,CAAC;IAEM,MAAM,CAAC,cAAc,CAAC,KAAY,EAAE,aAA4B;QACnE,OAAO,aAAa,CAAC,gBAAgB,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,OAAO,CAAC;IAC9F,CAAC;IAEM,MAAM,CAAC,sBAAsB,CAAC,KAAY,EAAE,aAA4B;QAC3E,OAAO,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,UAAU,CAAC;IACpD,CAAC;IAEM,MAAM,CAAC,YAAY,CAAC,KAAY,EAAE,aAA4B;QACjE,OAAO,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,KAAK,CAAC;IAC/C,CAAC;IAEM,MAAM,CAAC,gBAAgB,CAAC,KAAY,EAAE,aAA4B;QACrE,OAAO,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,SAAS,CAAC;IACnD,CAAC;CAaJ;AArCD,sBAqCC"}
|
|
||||||
5
node_modules/@fast-csv/parse/build/src/parser/column/ColumnFormatter.d.ts
generated
vendored
5
node_modules/@fast-csv/parse/build/src/parser/column/ColumnFormatter.d.ts
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
import { ParserOptions } from '../../ParserOptions';
|
|
||||||
export declare class ColumnFormatter {
|
|
||||||
readonly format: (col: string) => string;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
}
|
|
||||||
21
node_modules/@fast-csv/parse/build/src/parser/column/ColumnFormatter.js
generated
vendored
21
node_modules/@fast-csv/parse/build/src/parser/column/ColumnFormatter.js
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.ColumnFormatter = void 0;
|
|
||||||
class ColumnFormatter {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
if (parserOptions.trim) {
|
|
||||||
this.format = (col) => col.trim();
|
|
||||||
}
|
|
||||||
else if (parserOptions.ltrim) {
|
|
||||||
this.format = (col) => col.trimLeft();
|
|
||||||
}
|
|
||||||
else if (parserOptions.rtrim) {
|
|
||||||
this.format = (col) => col.trimRight();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.format = (col) => col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ColumnFormatter = ColumnFormatter;
|
|
||||||
//# sourceMappingURL=ColumnFormatter.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/column/ColumnFormatter.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/column/ColumnFormatter.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"ColumnFormatter.js","sourceRoot":"","sources":["../../../../src/parser/column/ColumnFormatter.ts"],"names":[],"mappings":";;;AAEA,MAAa,eAAe;IAGxB,YAAmB,aAA4B;QAC3C,IAAI,aAAa,CAAC,IAAI,EAAE;YACpB,IAAI,CAAC,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;SACrD;aAAM,IAAI,aAAa,CAAC,KAAK,EAAE;YAC5B,IAAI,CAAC,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;SACzD;aAAM,IAAI,aAAa,CAAC,KAAK,EAAE;YAC5B,IAAI,CAAC,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;SAC1D;aAAM;YACH,IAAI,CAAC,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC;SAC9C;IACL,CAAC;CACJ;AAdD,0CAcC"}
|
|
||||||
11
node_modules/@fast-csv/parse/build/src/parser/column/ColumnParser.d.ts
generated
vendored
11
node_modules/@fast-csv/parse/build/src/parser/column/ColumnParser.d.ts
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
import { ParserOptions } from '../../ParserOptions';
|
|
||||||
import { NonQuotedColumnParser } from './NonQuotedColumnParser';
|
|
||||||
import { QuotedColumnParser } from './QuotedColumnParser';
|
|
||||||
import { Scanner } from '../Scanner';
|
|
||||||
export declare class ColumnParser {
|
|
||||||
private readonly parserOptions;
|
|
||||||
readonly nonQuotedColumnParser: NonQuotedColumnParser;
|
|
||||||
readonly quotedColumnParser: QuotedColumnParser;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
parse(scanner: Scanner): string | null;
|
|
||||||
}
|
|
||||||
23
node_modules/@fast-csv/parse/build/src/parser/column/ColumnParser.js
generated
vendored
23
node_modules/@fast-csv/parse/build/src/parser/column/ColumnParser.js
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.ColumnParser = void 0;
|
|
||||||
const NonQuotedColumnParser_1 = require("./NonQuotedColumnParser");
|
|
||||||
const QuotedColumnParser_1 = require("./QuotedColumnParser");
|
|
||||||
const Token_1 = require("../Token");
|
|
||||||
class ColumnParser {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
this.quotedColumnParser = new QuotedColumnParser_1.QuotedColumnParser(parserOptions);
|
|
||||||
this.nonQuotedColumnParser = new NonQuotedColumnParser_1.NonQuotedColumnParser(parserOptions);
|
|
||||||
}
|
|
||||||
parse(scanner) {
|
|
||||||
const { nextNonSpaceToken } = scanner;
|
|
||||||
if (nextNonSpaceToken !== null && Token_1.Token.isTokenQuote(nextNonSpaceToken, this.parserOptions)) {
|
|
||||||
scanner.advanceToToken(nextNonSpaceToken);
|
|
||||||
return this.quotedColumnParser.parse(scanner);
|
|
||||||
}
|
|
||||||
return this.nonQuotedColumnParser.parse(scanner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ColumnParser = ColumnParser;
|
|
||||||
//# sourceMappingURL=ColumnParser.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/column/ColumnParser.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/column/ColumnParser.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"ColumnParser.js","sourceRoot":"","sources":["../../../../src/parser/column/ColumnParser.ts"],"names":[],"mappings":";;;AACA,mEAAgE;AAChE,6DAA0D;AAE1D,oCAAiC;AAEjC,MAAa,YAAY;IAOrB,YAAmB,aAA4B;QAC3C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,kBAAkB,GAAG,IAAI,uCAAkB,CAAC,aAAa,CAAC,CAAC;QAChE,IAAI,CAAC,qBAAqB,GAAG,IAAI,6CAAqB,CAAC,aAAa,CAAC,CAAC;IAC1E,CAAC;IAEM,KAAK,CAAC,OAAgB;QACzB,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;QACtC,IAAI,iBAAiB,KAAK,IAAI,IAAI,aAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE;YACzF,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;SACjD;QACD,OAAO,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;CACJ;AArBD,oCAqBC"}
|
|
||||||
8
node_modules/@fast-csv/parse/build/src/parser/column/NonQuotedColumnParser.d.ts
generated
vendored
8
node_modules/@fast-csv/parse/build/src/parser/column/NonQuotedColumnParser.d.ts
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
import { ParserOptions } from '../../ParserOptions';
|
|
||||||
import { Scanner } from '../Scanner';
|
|
||||||
export declare class NonQuotedColumnParser {
|
|
||||||
private readonly parserOptions;
|
|
||||||
private readonly columnFormatter;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
parse(scanner: Scanner): string | null;
|
|
||||||
}
|
|
||||||
29
node_modules/@fast-csv/parse/build/src/parser/column/NonQuotedColumnParser.js
generated
vendored
29
node_modules/@fast-csv/parse/build/src/parser/column/NonQuotedColumnParser.js
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.NonQuotedColumnParser = void 0;
|
|
||||||
const ColumnFormatter_1 = require("./ColumnFormatter");
|
|
||||||
const Token_1 = require("../Token");
|
|
||||||
class NonQuotedColumnParser {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
this.columnFormatter = new ColumnFormatter_1.ColumnFormatter(parserOptions);
|
|
||||||
}
|
|
||||||
parse(scanner) {
|
|
||||||
if (!scanner.hasMoreCharacters) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const { parserOptions } = this;
|
|
||||||
const characters = [];
|
|
||||||
let nextToken = scanner.nextCharacterToken;
|
|
||||||
for (; nextToken; nextToken = scanner.nextCharacterToken) {
|
|
||||||
if (Token_1.Token.isTokenDelimiter(nextToken, parserOptions) || Token_1.Token.isTokenRowDelimiter(nextToken)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
characters.push(nextToken.token);
|
|
||||||
scanner.advancePastToken(nextToken);
|
|
||||||
}
|
|
||||||
return this.columnFormatter.format(characters.join(''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.NonQuotedColumnParser = NonQuotedColumnParser;
|
|
||||||
//# sourceMappingURL=NonQuotedColumnParser.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/column/NonQuotedColumnParser.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/column/NonQuotedColumnParser.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"NonQuotedColumnParser.js","sourceRoot":"","sources":["../../../../src/parser/column/NonQuotedColumnParser.ts"],"names":[],"mappings":";;;AACA,uDAAoD;AAEpD,oCAAiC;AAEjC,MAAa,qBAAqB;IAK9B,YAAmB,aAA4B;QAC3C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,IAAI,iCAAe,CAAC,aAAa,CAAC,CAAC;IAC9D,CAAC;IAEM,KAAK,CAAC,OAAgB;QACzB,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE;YAC5B,OAAO,IAAI,CAAC;SACf;QACD,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;QAC/B,MAAM,UAAU,GAAG,EAAE,CAAC;QACtB,IAAI,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC;QAC3C,OAAO,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE;YACtD,IAAI,aAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,IAAI,aAAK,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE;gBAC1F,MAAM;aACT;YACD,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACjC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;SACvC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;CACJ;AA1BD,sDA0BC"}
|
|
||||||
10
node_modules/@fast-csv/parse/build/src/parser/column/QuotedColumnParser.d.ts
generated
vendored
10
node_modules/@fast-csv/parse/build/src/parser/column/QuotedColumnParser.d.ts
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
import { ParserOptions } from '../../ParserOptions';
|
|
||||||
import { Scanner } from '../Scanner';
|
|
||||||
export declare class QuotedColumnParser {
|
|
||||||
private readonly parserOptions;
|
|
||||||
private readonly columnFormatter;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
parse(scanner: Scanner): string | null;
|
|
||||||
private gatherDataBetweenQuotes;
|
|
||||||
private checkForMalformedColumn;
|
|
||||||
}
|
|
||||||
97
node_modules/@fast-csv/parse/build/src/parser/column/QuotedColumnParser.js
generated
vendored
97
node_modules/@fast-csv/parse/build/src/parser/column/QuotedColumnParser.js
generated
vendored
@ -1,97 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.QuotedColumnParser = void 0;
|
|
||||||
const ColumnFormatter_1 = require("./ColumnFormatter");
|
|
||||||
const Token_1 = require("../Token");
|
|
||||||
class QuotedColumnParser {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
this.columnFormatter = new ColumnFormatter_1.ColumnFormatter(parserOptions);
|
|
||||||
}
|
|
||||||
parse(scanner) {
|
|
||||||
if (!scanner.hasMoreCharacters) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const originalCursor = scanner.cursor;
|
|
||||||
const { foundClosingQuote, col } = this.gatherDataBetweenQuotes(scanner);
|
|
||||||
if (!foundClosingQuote) {
|
|
||||||
// reset the cursor to the original
|
|
||||||
scanner.advanceTo(originalCursor);
|
|
||||||
// if we didnt find a closing quote but we potentially have more data then skip the parsing
|
|
||||||
// and return the original scanner.
|
|
||||||
if (!scanner.hasMoreData) {
|
|
||||||
throw new Error(`Parse Error: missing closing: '${this.parserOptions.quote || ''}' in line: at '${scanner.lineFromCursor.replace(/[\r\n]/g, "\\n'")}'`);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
this.checkForMalformedColumn(scanner);
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
gatherDataBetweenQuotes(scanner) {
|
|
||||||
const { parserOptions } = this;
|
|
||||||
let foundStartingQuote = false;
|
|
||||||
let foundClosingQuote = false;
|
|
||||||
const characters = [];
|
|
||||||
let nextToken = scanner.nextCharacterToken;
|
|
||||||
for (; !foundClosingQuote && nextToken !== null; nextToken = scanner.nextCharacterToken) {
|
|
||||||
const isQuote = Token_1.Token.isTokenQuote(nextToken, parserOptions);
|
|
||||||
// ignore first quote
|
|
||||||
if (!foundStartingQuote && isQuote) {
|
|
||||||
foundStartingQuote = true;
|
|
||||||
}
|
|
||||||
else if (foundStartingQuote) {
|
|
||||||
if (Token_1.Token.isTokenEscapeCharacter(nextToken, parserOptions)) {
|
|
||||||
// advance past the escape character so we can get the next one in line
|
|
||||||
scanner.advancePastToken(nextToken);
|
|
||||||
const tokenFollowingEscape = scanner.nextCharacterToken;
|
|
||||||
// if the character following the escape is a quote character then just add
|
|
||||||
// the quote and advance to that character
|
|
||||||
if (tokenFollowingEscape !== null &&
|
|
||||||
(Token_1.Token.isTokenQuote(tokenFollowingEscape, parserOptions) ||
|
|
||||||
Token_1.Token.isTokenEscapeCharacter(tokenFollowingEscape, parserOptions))) {
|
|
||||||
characters.push(tokenFollowingEscape.token);
|
|
||||||
nextToken = tokenFollowingEscape;
|
|
||||||
}
|
|
||||||
else if (isQuote) {
|
|
||||||
// if the escape is also a quote then we found our closing quote and finish early
|
|
||||||
foundClosingQuote = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// other wise add the escape token to the characters since it wast escaping anything
|
|
||||||
characters.push(nextToken.token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isQuote) {
|
|
||||||
// we found our closing quote!
|
|
||||||
foundClosingQuote = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// add the token to the characters
|
|
||||||
characters.push(nextToken.token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scanner.advancePastToken(nextToken);
|
|
||||||
}
|
|
||||||
return { col: this.columnFormatter.format(characters.join('')), foundClosingQuote };
|
|
||||||
}
|
|
||||||
checkForMalformedColumn(scanner) {
|
|
||||||
const { parserOptions } = this;
|
|
||||||
const { nextNonSpaceToken } = scanner;
|
|
||||||
if (nextNonSpaceToken) {
|
|
||||||
const isNextTokenADelimiter = Token_1.Token.isTokenDelimiter(nextNonSpaceToken, parserOptions);
|
|
||||||
const isNextTokenARowDelimiter = Token_1.Token.isTokenRowDelimiter(nextNonSpaceToken);
|
|
||||||
if (!(isNextTokenADelimiter || isNextTokenARowDelimiter)) {
|
|
||||||
// if the final quote was NOT followed by a column (,) or row(\n) delimiter then its a bad column
|
|
||||||
// tldr: only part of the column was quoted
|
|
||||||
const linePreview = scanner.lineFromCursor.substr(0, 10).replace(/[\r\n]/g, "\\n'");
|
|
||||||
throw new Error(`Parse Error: expected: '${parserOptions.escapedDelimiter}' OR new line got: '${nextNonSpaceToken.token}'. at '${linePreview}`);
|
|
||||||
}
|
|
||||||
scanner.advanceToToken(nextNonSpaceToken);
|
|
||||||
}
|
|
||||||
else if (!scanner.hasMoreData) {
|
|
||||||
scanner.advancePastLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.QuotedColumnParser = QuotedColumnParser;
|
|
||||||
//# sourceMappingURL=QuotedColumnParser.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/column/QuotedColumnParser.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/column/QuotedColumnParser.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"QuotedColumnParser.js","sourceRoot":"","sources":["../../../../src/parser/column/QuotedColumnParser.ts"],"names":[],"mappings":"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"}
|
|
||||||
4
node_modules/@fast-csv/parse/build/src/parser/column/index.d.ts
generated
vendored
4
node_modules/@fast-csv/parse/build/src/parser/column/index.d.ts
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
export { ColumnParser } from './ColumnParser';
|
|
||||||
export { NonQuotedColumnParser } from './NonQuotedColumnParser';
|
|
||||||
export { QuotedColumnParser } from './QuotedColumnParser';
|
|
||||||
export { ColumnFormatter } from './ColumnFormatter';
|
|
||||||
12
node_modules/@fast-csv/parse/build/src/parser/column/index.js
generated
vendored
12
node_modules/@fast-csv/parse/build/src/parser/column/index.js
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.ColumnFormatter = exports.QuotedColumnParser = exports.NonQuotedColumnParser = exports.ColumnParser = void 0;
|
|
||||||
var ColumnParser_1 = require("./ColumnParser");
|
|
||||||
Object.defineProperty(exports, "ColumnParser", { enumerable: true, get: function () { return ColumnParser_1.ColumnParser; } });
|
|
||||||
var NonQuotedColumnParser_1 = require("./NonQuotedColumnParser");
|
|
||||||
Object.defineProperty(exports, "NonQuotedColumnParser", { enumerable: true, get: function () { return NonQuotedColumnParser_1.NonQuotedColumnParser; } });
|
|
||||||
var QuotedColumnParser_1 = require("./QuotedColumnParser");
|
|
||||||
Object.defineProperty(exports, "QuotedColumnParser", { enumerable: true, get: function () { return QuotedColumnParser_1.QuotedColumnParser; } });
|
|
||||||
var ColumnFormatter_1 = require("./ColumnFormatter");
|
|
||||||
Object.defineProperty(exports, "ColumnFormatter", { enumerable: true, get: function () { return ColumnFormatter_1.ColumnFormatter; } });
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/column/index.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/column/index.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/parser/column/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,qDAAoD;AAA3C,kHAAA,eAAe,OAAA"}
|
|
||||||
5
node_modules/@fast-csv/parse/build/src/parser/index.d.ts
generated
vendored
5
node_modules/@fast-csv/parse/build/src/parser/index.d.ts
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
export { Parser } from './Parser';
|
|
||||||
export { RowParser } from './RowParser';
|
|
||||||
export { Scanner } from './Scanner';
|
|
||||||
export { Token, MaybeToken } from './Token';
|
|
||||||
export { ColumnParser, NonQuotedColumnParser, QuotedColumnParser } from './column';
|
|
||||||
16
node_modules/@fast-csv/parse/build/src/parser/index.js
generated
vendored
16
node_modules/@fast-csv/parse/build/src/parser/index.js
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.QuotedColumnParser = exports.NonQuotedColumnParser = exports.ColumnParser = exports.Token = exports.Scanner = exports.RowParser = exports.Parser = void 0;
|
|
||||||
var Parser_1 = require("./Parser");
|
|
||||||
Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return Parser_1.Parser; } });
|
|
||||||
var RowParser_1 = require("./RowParser");
|
|
||||||
Object.defineProperty(exports, "RowParser", { enumerable: true, get: function () { return RowParser_1.RowParser; } });
|
|
||||||
var Scanner_1 = require("./Scanner");
|
|
||||||
Object.defineProperty(exports, "Scanner", { enumerable: true, get: function () { return Scanner_1.Scanner; } });
|
|
||||||
var Token_1 = require("./Token");
|
|
||||||
Object.defineProperty(exports, "Token", { enumerable: true, get: function () { return Token_1.Token; } });
|
|
||||||
var column_1 = require("./column");
|
|
||||||
Object.defineProperty(exports, "ColumnParser", { enumerable: true, get: function () { return column_1.ColumnParser; } });
|
|
||||||
Object.defineProperty(exports, "NonQuotedColumnParser", { enumerable: true, get: function () { return column_1.NonQuotedColumnParser; } });
|
|
||||||
Object.defineProperty(exports, "QuotedColumnParser", { enumerable: true, get: function () { return column_1.QuotedColumnParser; } });
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/parser/index.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/parser/index.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/parser/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,iCAA4C;AAAnC,8FAAA,KAAK,OAAA;AACd,mCAAmF;AAA1E,sGAAA,YAAY,OAAA;AAAE,+GAAA,qBAAqB,OAAA;AAAE,4GAAA,kBAAkB,OAAA"}
|
|
||||||
17
node_modules/@fast-csv/parse/build/src/transforms/HeaderTransformer.d.ts
generated
vendored
17
node_modules/@fast-csv/parse/build/src/transforms/HeaderTransformer.d.ts
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
import { ParserOptions } from '../ParserOptions';
|
|
||||||
import { HeaderArray, Row, RowArray, RowValidatorCallback } from '../types';
|
|
||||||
export declare class HeaderTransformer<O extends Row> {
|
|
||||||
private readonly parserOptions;
|
|
||||||
headers: HeaderArray | null;
|
|
||||||
private receivedHeaders;
|
|
||||||
private readonly shouldUseFirstRow;
|
|
||||||
private processedFirstRow;
|
|
||||||
private headersLength;
|
|
||||||
private readonly headersTransform?;
|
|
||||||
constructor(parserOptions: ParserOptions);
|
|
||||||
transform(row: RowArray, cb: RowValidatorCallback<O>): void;
|
|
||||||
private shouldMapRow;
|
|
||||||
private processRow;
|
|
||||||
private mapHeaders;
|
|
||||||
private setHeaders;
|
|
||||||
}
|
|
||||||
115
node_modules/@fast-csv/parse/build/src/transforms/HeaderTransformer.js
generated
vendored
115
node_modules/@fast-csv/parse/build/src/transforms/HeaderTransformer.js
generated
vendored
@ -1,115 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.HeaderTransformer = void 0;
|
|
||||||
const lodash_isundefined_1 = __importDefault(require("lodash.isundefined"));
|
|
||||||
const lodash_isfunction_1 = __importDefault(require("lodash.isfunction"));
|
|
||||||
const lodash_uniq_1 = __importDefault(require("lodash.uniq"));
|
|
||||||
const lodash_groupby_1 = __importDefault(require("lodash.groupby"));
|
|
||||||
class HeaderTransformer {
|
|
||||||
constructor(parserOptions) {
|
|
||||||
this.headers = null;
|
|
||||||
this.receivedHeaders = false;
|
|
||||||
this.shouldUseFirstRow = false;
|
|
||||||
this.processedFirstRow = false;
|
|
||||||
this.headersLength = 0;
|
|
||||||
this.parserOptions = parserOptions;
|
|
||||||
if (parserOptions.headers === true) {
|
|
||||||
this.shouldUseFirstRow = true;
|
|
||||||
}
|
|
||||||
else if (Array.isArray(parserOptions.headers)) {
|
|
||||||
this.setHeaders(parserOptions.headers);
|
|
||||||
}
|
|
||||||
else if (lodash_isfunction_1.default(parserOptions.headers)) {
|
|
||||||
this.headersTransform = parserOptions.headers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transform(row, cb) {
|
|
||||||
if (!this.shouldMapRow(row)) {
|
|
||||||
return cb(null, { row: null, isValid: true });
|
|
||||||
}
|
|
||||||
return cb(null, this.processRow(row));
|
|
||||||
}
|
|
||||||
shouldMapRow(row) {
|
|
||||||
const { parserOptions } = this;
|
|
||||||
if (!this.headersTransform && parserOptions.renameHeaders && !this.processedFirstRow) {
|
|
||||||
if (!this.receivedHeaders) {
|
|
||||||
throw new Error('Error renaming headers: new headers must be provided in an array');
|
|
||||||
}
|
|
||||||
this.processedFirstRow = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!this.receivedHeaders && Array.isArray(row)) {
|
|
||||||
if (this.headersTransform) {
|
|
||||||
this.setHeaders(this.headersTransform(row));
|
|
||||||
}
|
|
||||||
else if (this.shouldUseFirstRow) {
|
|
||||||
this.setHeaders(row);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// dont do anything with the headers if we didnt receive a transform or shouldnt use the first row.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
processRow(row) {
|
|
||||||
if (!this.headers) {
|
|
||||||
return { row: row, isValid: true };
|
|
||||||
}
|
|
||||||
const { parserOptions } = this;
|
|
||||||
if (!parserOptions.discardUnmappedColumns && row.length > this.headersLength) {
|
|
||||||
if (!parserOptions.strictColumnHandling) {
|
|
||||||
throw new Error(`Unexpected Error: column header mismatch expected: ${this.headersLength} columns got: ${row.length}`);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
row: row,
|
|
||||||
isValid: false,
|
|
||||||
reason: `Column header mismatch expected: ${this.headersLength} columns got: ${row.length}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (parserOptions.strictColumnHandling && row.length < this.headersLength) {
|
|
||||||
return {
|
|
||||||
row: row,
|
|
||||||
isValid: false,
|
|
||||||
reason: `Column header mismatch expected: ${this.headersLength} columns got: ${row.length}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return { row: this.mapHeaders(row), isValid: true };
|
|
||||||
}
|
|
||||||
mapHeaders(row) {
|
|
||||||
const rowMap = {};
|
|
||||||
const { headers, headersLength } = this;
|
|
||||||
for (let i = 0; i < headersLength; i += 1) {
|
|
||||||
const header = headers[i];
|
|
||||||
if (!lodash_isundefined_1.default(header)) {
|
|
||||||
const val = row[i];
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
if (lodash_isundefined_1.default(val)) {
|
|
||||||
rowMap[header] = '';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rowMap[header] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rowMap;
|
|
||||||
}
|
|
||||||
setHeaders(headers) {
|
|
||||||
var _a;
|
|
||||||
const filteredHeaders = headers.filter((h) => !!h);
|
|
||||||
if (lodash_uniq_1.default(filteredHeaders).length !== filteredHeaders.length) {
|
|
||||||
const grouped = lodash_groupby_1.default(filteredHeaders);
|
|
||||||
const duplicates = Object.keys(grouped).filter((dup) => grouped[dup].length > 1);
|
|
||||||
throw new Error(`Duplicate headers found ${JSON.stringify(duplicates)}`);
|
|
||||||
}
|
|
||||||
this.headers = headers;
|
|
||||||
this.receivedHeaders = true;
|
|
||||||
this.headersLength = ((_a = this.headers) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.HeaderTransformer = HeaderTransformer;
|
|
||||||
//# sourceMappingURL=HeaderTransformer.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/transforms/HeaderTransformer.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/transforms/HeaderTransformer.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"HeaderTransformer.js","sourceRoot":"","sources":["../../../src/transforms/HeaderTransformer.ts"],"names":[],"mappings":"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"}
|
|
||||||
12
node_modules/@fast-csv/parse/build/src/transforms/RowTransformerValidator.d.ts
generated
vendored
12
node_modules/@fast-csv/parse/build/src/transforms/RowTransformerValidator.d.ts
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
import { Row, RowTransformFunction, RowValidatorCallback, RowValidate } from '../types';
|
|
||||||
export declare class RowTransformerValidator<I extends Row, O extends Row> {
|
|
||||||
private static createTransform;
|
|
||||||
private static createValidator;
|
|
||||||
private _rowTransform;
|
|
||||||
private _rowValidator;
|
|
||||||
set rowTransform(transformFunction: RowTransformFunction<I, O>);
|
|
||||||
set rowValidator(validateFunction: RowValidate<O>);
|
|
||||||
transformAndValidate(row: I, cb: RowValidatorCallback<O>): void;
|
|
||||||
private callTransformer;
|
|
||||||
private callValidator;
|
|
||||||
}
|
|
||||||
93
node_modules/@fast-csv/parse/build/src/transforms/RowTransformerValidator.js
generated
vendored
93
node_modules/@fast-csv/parse/build/src/transforms/RowTransformerValidator.js
generated
vendored
@ -1,93 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.RowTransformerValidator = void 0;
|
|
||||||
const lodash_isfunction_1 = __importDefault(require("lodash.isfunction"));
|
|
||||||
const types_1 = require("../types");
|
|
||||||
class RowTransformerValidator {
|
|
||||||
constructor() {
|
|
||||||
this._rowTransform = null;
|
|
||||||
this._rowValidator = null;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
static createTransform(transformFunction) {
|
|
||||||
if (types_1.isSyncTransform(transformFunction)) {
|
|
||||||
return (row, cb) => {
|
|
||||||
let transformed = null;
|
|
||||||
try {
|
|
||||||
transformed = transformFunction(row);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return cb(e);
|
|
||||||
}
|
|
||||||
return cb(null, transformed);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return transformFunction;
|
|
||||||
}
|
|
||||||
static createValidator(validateFunction) {
|
|
||||||
if (types_1.isSyncValidate(validateFunction)) {
|
|
||||||
return (row, cb) => {
|
|
||||||
cb(null, { row, isValid: validateFunction(row) });
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return (row, cb) => {
|
|
||||||
validateFunction(row, (err, isValid, reason) => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
if (isValid) {
|
|
||||||
return cb(null, { row, isValid, reason });
|
|
||||||
}
|
|
||||||
return cb(null, { row, isValid: false, reason });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
set rowTransform(transformFunction) {
|
|
||||||
if (!lodash_isfunction_1.default(transformFunction)) {
|
|
||||||
throw new TypeError('The transform should be a function');
|
|
||||||
}
|
|
||||||
this._rowTransform = RowTransformerValidator.createTransform(transformFunction);
|
|
||||||
}
|
|
||||||
set rowValidator(validateFunction) {
|
|
||||||
if (!lodash_isfunction_1.default(validateFunction)) {
|
|
||||||
throw new TypeError('The validate should be a function');
|
|
||||||
}
|
|
||||||
this._rowValidator = RowTransformerValidator.createValidator(validateFunction);
|
|
||||||
}
|
|
||||||
transformAndValidate(row, cb) {
|
|
||||||
return this.callTransformer(row, (transformErr, transformedRow) => {
|
|
||||||
if (transformErr) {
|
|
||||||
return cb(transformErr);
|
|
||||||
}
|
|
||||||
if (!transformedRow) {
|
|
||||||
return cb(null, { row: null, isValid: true });
|
|
||||||
}
|
|
||||||
return this.callValidator(transformedRow, (validateErr, validationResult) => {
|
|
||||||
if (validateErr) {
|
|
||||||
return cb(validateErr);
|
|
||||||
}
|
|
||||||
if (validationResult && !validationResult.isValid) {
|
|
||||||
return cb(null, { row: transformedRow, isValid: false, reason: validationResult.reason });
|
|
||||||
}
|
|
||||||
return cb(null, { row: transformedRow, isValid: true });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
callTransformer(row, cb) {
|
|
||||||
if (!this._rowTransform) {
|
|
||||||
return cb(null, row);
|
|
||||||
}
|
|
||||||
return this._rowTransform(row, cb);
|
|
||||||
}
|
|
||||||
callValidator(row, cb) {
|
|
||||||
if (!this._rowValidator) {
|
|
||||||
return cb(null, { row, isValid: true });
|
|
||||||
}
|
|
||||||
return this._rowValidator(row, cb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.RowTransformerValidator = RowTransformerValidator;
|
|
||||||
//# sourceMappingURL=RowTransformerValidator.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/transforms/RowTransformerValidator.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/transforms/RowTransformerValidator.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"RowTransformerValidator.js","sourceRoot":"","sources":["../../../src/transforms/RowTransformerValidator.ts"],"names":[],"mappings":"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"}
|
|
||||||
2
node_modules/@fast-csv/parse/build/src/transforms/index.d.ts
generated
vendored
2
node_modules/@fast-csv/parse/build/src/transforms/index.d.ts
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
export { RowTransformerValidator } from './RowTransformerValidator';
|
|
||||||
export { HeaderTransformer } from './HeaderTransformer';
|
|
||||||
8
node_modules/@fast-csv/parse/build/src/transforms/index.js
generated
vendored
8
node_modules/@fast-csv/parse/build/src/transforms/index.js
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.HeaderTransformer = exports.RowTransformerValidator = void 0;
|
|
||||||
var RowTransformerValidator_1 = require("./RowTransformerValidator");
|
|
||||||
Object.defineProperty(exports, "RowTransformerValidator", { enumerable: true, get: function () { return RowTransformerValidator_1.RowTransformerValidator; } });
|
|
||||||
var HeaderTransformer_1 = require("./HeaderTransformer");
|
|
||||||
Object.defineProperty(exports, "HeaderTransformer", { enumerable: true, get: function () { return HeaderTransformer_1.HeaderTransformer; } });
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/transforms/index.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/transforms/index.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transforms/index.ts"],"names":[],"mappings":";;;AAAA,qEAAoE;AAA3D,kIAAA,uBAAuB,OAAA;AAChC,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA"}
|
|
||||||
21
node_modules/@fast-csv/parse/build/src/types.d.ts
generated
vendored
21
node_modules/@fast-csv/parse/build/src/types.d.ts
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
export declare type RowMap<V = any> = Record<string, V>;
|
|
||||||
export declare type RowArray<V = any> = V[];
|
|
||||||
export declare type Row<V = any> = RowMap<V> | RowArray<V>;
|
|
||||||
export interface RowValidationResult<R extends Row> {
|
|
||||||
row: R | null;
|
|
||||||
isValid: boolean;
|
|
||||||
reason?: string;
|
|
||||||
}
|
|
||||||
export declare type RowValidatorCallback<R extends Row> = (error: Error | null, result?: RowValidationResult<R>) => void;
|
|
||||||
export declare type RowTransformCallback<R extends Row> = (error?: Error | null, row?: R) => void;
|
|
||||||
export declare type SyncRowTransform<I extends Row, O extends Row> = (row: I) => O;
|
|
||||||
export declare type AsyncRowTransform<I extends Row, O extends Row> = (row: I, cb: RowTransformCallback<O>) => void;
|
|
||||||
export declare type RowTransformFunction<I extends Row, O extends Row> = SyncRowTransform<I, O> | AsyncRowTransform<I, O>;
|
|
||||||
export declare const isSyncTransform: <I extends Row<any>, O extends Row<any>>(transform: RowTransformFunction<I, O>) => transform is SyncRowTransform<I, O>;
|
|
||||||
export declare type RowValidateCallback = (error?: Error | null, isValid?: boolean, reason?: string) => void;
|
|
||||||
export declare type SyncRowValidate<R extends Row> = (row: R) => boolean;
|
|
||||||
export declare type AsyncRowValidate<R extends Row> = (row: R, cb: RowValidateCallback) => void;
|
|
||||||
export declare type RowValidate<R extends Row> = AsyncRowValidate<R> | SyncRowValidate<R>;
|
|
||||||
export declare const isSyncValidate: <R extends Row<any>>(validate: RowValidate<R>) => validate is SyncRowValidate<R>;
|
|
||||||
export declare type HeaderArray = (string | undefined | null)[];
|
|
||||||
export declare type HeaderTransformFunction = (headers: HeaderArray) => HeaderArray;
|
|
||||||
6
node_modules/@fast-csv/parse/build/src/types.js
generated
vendored
6
node_modules/@fast-csv/parse/build/src/types.js
generated
vendored
@ -1,6 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.isSyncValidate = exports.isSyncTransform = void 0;
|
|
||||||
exports.isSyncTransform = (transform) => transform.length === 1;
|
|
||||||
exports.isSyncValidate = (validate) => validate.length === 1;
|
|
||||||
//# sourceMappingURL=types.js.map
|
|
||||||
1
node_modules/@fast-csv/parse/build/src/types.js.map
generated
vendored
1
node_modules/@fast-csv/parse/build/src/types.js.map
generated
vendored
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";;;AAoBa,QAAA,eAAe,GAAG,CAC3B,SAAqC,EACF,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;AAQpD,QAAA,cAAc,GAAG,CAAgB,QAAwB,EAAkC,EAAE,CACtG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC"}
|
|
||||||
62
node_modules/@fast-csv/parse/package.json
generated
vendored
62
node_modules/@fast-csv/parse/package.json
generated
vendored
@ -1,62 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@fast-csv/parse",
|
|
||||||
"version": "4.3.6",
|
|
||||||
"description": "fast-csv parsing package",
|
|
||||||
"keywords": [
|
|
||||||
"csv",
|
|
||||||
"parse",
|
|
||||||
"fast-csv",
|
|
||||||
"parser"
|
|
||||||
],
|
|
||||||
"author": "doug-martin <doug@dougamartin.com>",
|
|
||||||
"homepage": "http://c2fo.github.com/fast-csv/packages/parse",
|
|
||||||
"license": "MIT",
|
|
||||||
"main": "build/src/index.js",
|
|
||||||
"types": "build/src/index.d.ts",
|
|
||||||
"directories": {
|
|
||||||
"lib": "src",
|
|
||||||
"test": "__tests__"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"build/src/**"
|
|
||||||
],
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/C2FO/fast-csv.git",
|
|
||||||
"directory": "packages/parse"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prepublishOnly": "npm run build",
|
|
||||||
"build": "npm run clean && npm run compile",
|
|
||||||
"clean": "rm -rf ./build && rm -rf tsconfig.tsbuildinfo",
|
|
||||||
"compile": "tsc"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/C2FO/fast-csv/issues"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "^14.0.1",
|
|
||||||
"lodash.escaperegexp": "^4.1.2",
|
|
||||||
"lodash.groupby": "^4.6.0",
|
|
||||||
"lodash.isfunction": "^3.0.9",
|
|
||||||
"lodash.isnil": "^4.0.0",
|
|
||||||
"lodash.isundefined": "^3.0.1",
|
|
||||||
"lodash.uniq": "^4.5.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/lodash.escaperegexp": "4.1.6",
|
|
||||||
"@types/lodash.groupby": "4.6.6",
|
|
||||||
"@types/lodash.isfunction": "3.0.6",
|
|
||||||
"@types/lodash.isnil": "4.0.6",
|
|
||||||
"@types/lodash.isundefined": "3.0.6",
|
|
||||||
"@types/lodash.partition": "4.6.6",
|
|
||||||
"@types/lodash.uniq": "4.5.6",
|
|
||||||
"@types/sinon": "9.0.9",
|
|
||||||
"lodash.partition": "4.6.0",
|
|
||||||
"sinon": "9.2.1"
|
|
||||||
},
|
|
||||||
"gitHead": "3dc859edb19924b315051e4c87d6273808a0de73"
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user