generated from MuhammadIqbalMaulana/UAS-SIG
Initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.git
|
||||
.gitignore
|
||||
database_baru.sqlite
|
||||
database_baru.sqlite-journal
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
# Menggunakan image Node.js versi resmi berbasis Alpine Linux yang sangat ringan untuk efisiensi memori server
|
||||
FROM node:22.16.0-alpine
|
||||
|
||||
# Menetapkan direktori kerja utama di dalam ruang penyimpanan virtual kontainer
|
||||
WORKDIR /app
|
||||
|
||||
# Menyalin manifes dependensi proyek untuk manajemen instalasi package npm
|
||||
COPY package*.json ./
|
||||
|
||||
# Menginstal package produksi secara bersih tanpa menyertakan dependensi untuk tahap development
|
||||
RUN npm install --omit=dev
|
||||
# Menyalin seluruh berkas kode sumber proyek WebGIS ke dalam kontainer virtual
|
||||
COPY . .
|
||||
|
||||
# Membuat folder isolasi untuk penyimpanan berkas basis data SQLite agar bisa dipetakan ke volume eksternal
|
||||
RUN mkdir -p /app/data
|
||||
|
||||
# Menetapkan variabel lingkungan bawaan ke mode produksi untuk mengaktifkan optimasi performa Express
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Menghubungkan port internal aplikasi Express agar dapat diakses oleh sistem reverse proxy Coolify
|
||||
EXPOSE 3000
|
||||
|
||||
# Menjalankan perintah utama untuk menghidupkan server webgis secara otomatis saat kontainer aktif
|
||||
CMD ["node", "server.js"]
|
||||
Submodule
+1
Submodule UAS-SIG added at 6d4f436443
@@ -0,0 +1,91 @@
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const path = require('path');
|
||||
|
||||
// Menentukan lokasi penyimpanan file fisik database baru di dalam root proyek
|
||||
const db_path = process.env.NODE_ENV === 'production'
|
||||
? '/app/data/database_baru.sqlite'
|
||||
: path.resolve(__dirname, '../database_baru.sqlite');
|
||||
|
||||
// Menginisialisasi koneksi basis data dengan penanganan kesalahan otomatis
|
||||
const db = new sqlite3.Database(db_path, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (error_koneksi) => {
|
||||
/* Baris kompleks: Flag bitwise 'OPEN_READWRITE | OPEN_CREATE' memaksa sistem untuk
|
||||
membuat file 'database_baru.sqlite' secara otomatis jika belum ada di direktori target,
|
||||
sehingga mencegah aplikasi crash saat inisialisasi awal di server baru. */
|
||||
if (error_koneksi) {
|
||||
console.error('Kegagalan kritis: Sistem tidak dapat memuat file SQLite.', error_koneksi.message);
|
||||
// Praktik keamanan: Langsung menghentikan proses aplikasi jika koneksi database gagal
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('Sistem berhasil terhubung ke file basis data SQLite yang baru.');
|
||||
});
|
||||
|
||||
// Membangun tabel struktur data secara otomatis
|
||||
const initialize_database = () => {
|
||||
db.serialize(() => {
|
||||
|
||||
// 1. Membuat tabel MUSTAHIK sebagai entitas utama data warga
|
||||
db.run(`CREATE TABLE IF NOT EXISTS MUSTAHIK (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
nik TEXT NOT NULL UNIQUE,
|
||||
nama_kk TEXT NOT NULL,
|
||||
no_kk TEXT,
|
||||
jumlah_tanggungan INTEGER DEFAULT 0,
|
||||
lat REAL NOT NULL,
|
||||
lng REAL NOT NULL,
|
||||
status_validasi TEXT DEFAULT 'Pending'
|
||||
)`, (error_tabel) => {
|
||||
if (error_tabel) {
|
||||
console.error('Gagal mengeksekusi DDL tabel MUSTAHIK:', error_tabel.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Membuat tabel INDIKATOR_BPS untuk menyimpan parameter kelayakan hasil survei lapangan
|
||||
db.run(`CREATE TABLE IF NOT EXISTS INDIKATOR_BPS (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
id_mustahik INTEGER NOT NULL,
|
||||
luas_lantai_per_kapita TEXT,
|
||||
material_lantai TEXT,
|
||||
material_dinding TEXT,
|
||||
fasilitas_sanitasi TEXT,
|
||||
sumber_air_minum TEXT,
|
||||
sumber_penerangan TEXT,
|
||||
pekerjaan_utama TEXT,
|
||||
pendapatan_bulanan REAL,
|
||||
frekuensi_makan TEXT,
|
||||
kepemilikan_aset TEXT,
|
||||
FOREIGN KEY (id_mustahik) REFERENCES MUSTAHIK(id) ON DELETE CASCADE
|
||||
)`, (error_tabel) => {
|
||||
/* Baris kompleks: Definisi 'FOREIGN KEY' dengan klausa 'ON DELETE CASCADE' memastikan integritas
|
||||
referensial data terjaga secara otomatis. Jika data warga di tabel MUSTAHIK dihapus oleh admin,
|
||||
maka seluruh baris rekaman kriteria surveinya di tabel INDIKATOR_BPS akan ikut terhapus otomatis
|
||||
oleh engine database untuk mencegah tumpukan data sampah (orphan data). */
|
||||
if (error_tabel) {
|
||||
console.error('Gagal mengeksekusi DDL tabel INDIKATOR_BPS:', error_tabel.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Membuat tabel PETUGAS (Kini sejajar di luar callback INDIKATOR_BPS)
|
||||
db.run(`CREATE TABLE IF NOT EXISTS PETUGAS (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password TEXT NOT NULL
|
||||
)`, (error_tabel) => {
|
||||
if (error_tabel) console.error('Gagal mengeksekusi DDL tabel PETUGAS:', error_tabel.message);
|
||||
});
|
||||
|
||||
// 4. Membuat tabel ADMIN (Kini sejajar di luar callback INDIKATOR_BPS)
|
||||
db.run(`CREATE TABLE IF NOT EXISTS ADMIN (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password TEXT NOT NULL
|
||||
)`, (error_tabel) => {
|
||||
if (error_tabel) console.error('Gagal mengeksekusi DDL tabel ADMIN:', error_tabel.message);
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
// Mengeksekusi pembuatan struktur tabel baru
|
||||
initialize_database();
|
||||
|
||||
module.exports = db;
|
||||
@@ -0,0 +1,76 @@
|
||||
const db = require('../config/database');
|
||||
|
||||
// Menarik seluruh data warga mustahik untuk keperluan dasbor manajemen admin
|
||||
const ambil_semua_mustahik = (req, res) => {
|
||||
const kueri_ambil = `SELECT id, nik, nama_kk, no_kk, jumlah_tanggungan, status_validasi FROM MUSTAHIK ORDER BY id DESC`;
|
||||
|
||||
db.all(kueri_ambil, [], (error_sql, baris_data) => {
|
||||
if (error_sql) {
|
||||
console.error('Gagal fetch data tabel MUSTAHIK:', error_sql.message);
|
||||
return res.status(500).json({ error: 'Terjadi kegagalan sistem internal server.' });
|
||||
}
|
||||
res.status(200).json(baris_data);
|
||||
});
|
||||
};
|
||||
|
||||
// Menarik rekaman informasi detail warga beserta indikator kemiskinan BPS secara spesifik
|
||||
const ambil_detail_mustahik = (req, res) => {
|
||||
const id_warga = req.params.id;
|
||||
|
||||
const kueri_detail = `
|
||||
SELECT m.*, i.luas_lantai_per_kapita, i.material_lantai, i.material_dinding,
|
||||
i.fasilitas_sanitasi, i.sumber_air_minum, i.sumber_penerangan,
|
||||
i.pekerjaan_utama, i.pendapatan_bulanan, i.frekuensi_makan, i.kepemilikan_aset
|
||||
FROM MUSTAHIK m
|
||||
LEFT JOIN INDIKATOR_BPS i ON m.id = i.id_mustahik
|
||||
WHERE m.id = ?
|
||||
`;
|
||||
|
||||
/* Baris kompleks: Kita menggunakan kueri SQL 'LEFT JOIN' untuk menyatukan baris data dari
|
||||
tabel MUSTAHIK dan tabel INDIKATOR_BPS berdasarkan kecocokan Foreign Key (id_mustahik).
|
||||
Metode 'db.get' dipilih karena pencarian ini bersifat unik dan hanya mengembalikan
|
||||
satu baris data objek tunggal sesuai parameter ID warga. */
|
||||
db.get(kueri_detail, [id_warga], (error_sql, baris_data) => {
|
||||
if (error_sql) {
|
||||
console.error('Gagal memproses query detail:', error_sql.message);
|
||||
return res.status(500).json({ error: 'Terjadi kesalahan internal pada database peladen.' });
|
||||
}
|
||||
|
||||
if (!baris_data) {
|
||||
return res.status(404).json({ error: 'Rekaman data detail warga tidak ditemukan.' });
|
||||
}
|
||||
|
||||
res.status(200).json(baris_data);
|
||||
});
|
||||
};
|
||||
|
||||
// Melakukan mutasi pembaruan status validasi secara aman parsial
|
||||
const perbarui_status_validasi = (req, res) => {
|
||||
const id_warga = req.params.id;
|
||||
const { status_validasi } = req.body;
|
||||
|
||||
if (!status_validasi || !['Verified', 'Rejected', 'Pending'].includes(status_validasi)) {
|
||||
return res.status(400).json({ error: 'Parameter status validasi tidak sah.' });
|
||||
}
|
||||
|
||||
const kueri_update = `UPDATE MUSTAHIK SET status_validasi = ? WHERE id = ?`;
|
||||
|
||||
db.run(kueri_update, [status_validasi, id_warga], function(error_sql) {
|
||||
if (error_sql) {
|
||||
console.error('Gagal memproses DML UPDATE status:', error_sql.message);
|
||||
return res.status(500).json({ error: 'Gagal memperbarui status verifikasi di basis data.' });
|
||||
}
|
||||
|
||||
if (this.changes === 0) {
|
||||
return res.status(404).json({ error: 'Rekaman data warga tidak ditemukan.' });
|
||||
}
|
||||
|
||||
res.status(200).json({ message: 'Status verifikasi data warga berhasil diperbarui.' });
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ambil_semua_mustahik,
|
||||
ambil_detail_mustahik,
|
||||
perbarui_status_validasi
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
const bcrypt = require('bcrypt');
|
||||
const db = require('../config/database');
|
||||
|
||||
// Memvalidasi kredensial login petugas lapangan menggunakan pencarian SQLite
|
||||
const proses_autentikasi_petugas = (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
|
||||
// Praktik keamanan: Memblokir eksekusi lebih lanjut jika muatan data kosong untuk menghindari error sistem
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({ error: 'Username dan kata sandi petugas wajib diisi.' });
|
||||
}
|
||||
|
||||
const kueri_petugas = `SELECT * FROM PETUGAS WHERE username = ?`;
|
||||
|
||||
db.get(kueri_petugas, [username], async (error_sql, baris_petugas) => {
|
||||
if (error_sql) {
|
||||
console.error('Gagal query tabel PETUGAS:', error_sql.message);
|
||||
return res.status(500).json({ error: 'Terjadi kegagalan sistem internal server.' });
|
||||
}
|
||||
|
||||
// Praktik keamanan: Memberikan pesan error generik agar peretas tidak mengetahui apakah username tersebut ada di database atau tidak
|
||||
if (!baris_petugas) {
|
||||
return res.status(401).json({ error: 'Kredensial login tidak valid.' });
|
||||
}
|
||||
|
||||
try {
|
||||
/* Baris kompleks: Melakukan verifikasi asinkron untuk mencocokkan kata sandi teks murni dari klien
|
||||
dengan nilai hash terenkripsi di database menggunakan bcrypt.compare, yang secara inheren kebal
|
||||
terhadap serangan timing-attack. */
|
||||
const validasi_password = await bcrypt.compare(password, baris_petugas.password);
|
||||
|
||||
if (!validasi_password) {
|
||||
return res.status(401).json({ error: 'Kredensial login tidak valid.' });
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
message: 'Autentikasi petugas berhasil',
|
||||
token: `simulasi_jwt_token_untuk_petugas_${baris_petugas.username}`
|
||||
});
|
||||
|
||||
} catch (error_kripto) {
|
||||
console.error('Error komputasi hash:', error_kripto.message);
|
||||
res.status(500).json({ error: 'Gagal memproses verifikasi keamanan.' });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Memvalidasi kredensial login administrator utama menggunakan pencarian SQLite
|
||||
const proses_autentikasi_admin = (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
|
||||
// Praktik keamanan: Memblokir eksekusi lebih lanjut jika muatan data kosong
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({ error: 'Username dan kata sandi admin wajib diisi.' });
|
||||
}
|
||||
|
||||
const kueri_admin = `SELECT * FROM ADMIN WHERE username = ?`;
|
||||
|
||||
// Baris kompleks: Eksekusi pencarian data dengan parameterized query (?) memastikan nilai input diperlakukan murni sebagai string data, menutup celah eksploitasi SQL Injection secara absolut.
|
||||
db.get(kueri_admin, [username], async (error_sql, baris_admin) => {
|
||||
if (error_sql) {
|
||||
console.error('Gagal query tabel ADMIN:', error_sql.message);
|
||||
return res.status(500).json({ error: 'Terjadi kegagalan sistem internal server.' });
|
||||
}
|
||||
|
||||
if (!baris_admin) {
|
||||
return res.status(401).json({ error: 'Kredensial login admin tidak valid.' });
|
||||
}
|
||||
|
||||
try {
|
||||
const validasi_password = await bcrypt.compare(password, baris_admin.password);
|
||||
|
||||
if (!validasi_password) {
|
||||
return res.status(401).json({ error: 'Kredensial login admin tidak valid.' });
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
message: 'Autentikasi admin berhasil',
|
||||
token: `simulasi_jwt_token_untuk_admin_${baris_admin.username}`
|
||||
});
|
||||
|
||||
} catch (error_kripto) {
|
||||
console.error('Error komputasi hash admin:', error_kripto.message);
|
||||
res.status(500).json({ error: 'Gagal memproses verifikasi keamanan admin.' });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Mengekspor semua fungsi agar dapat diakses oleh file router
|
||||
module.exports = {
|
||||
proses_autentikasi_petugas,
|
||||
proses_autentikasi_admin
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
const fs = require('fs');
|
||||
const csv = require('csv-parser');
|
||||
const db = require('../config/database');
|
||||
|
||||
// Memproses unggahan berkas CSV dan memasukkan datanya ke tabel MUSTAHIK
|
||||
const import_data_bps = (req, res) => {
|
||||
try {
|
||||
// Praktik keamanan: Memastikan ada berkas yang dikirimkan oleh klien sebelum sistem mencoba membacanya
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ error: 'Tidak ada berkas CSV yang diunggah' });
|
||||
}
|
||||
|
||||
const path_berkas = req.file.path;
|
||||
const hasil_parsing = [];
|
||||
|
||||
// Baris kompleks: Kita menggunakan fs.createReadStream untuk membaca berkas secara bertahap (streaming) agar memori peladen tidak kelebihan beban jika ukuran CSV sangat besar, lalu mengalirkannya (pipe) ke modul csv-parser untuk diubah menjadi baris objek JavaScript secara asinkron.
|
||||
fs.createReadStream(path_berkas)
|
||||
.pipe(csv())
|
||||
.on('data', (data) => hasil_parsing.push(data))
|
||||
.on('end', () => {
|
||||
db.serialize(() => {
|
||||
db.run('BEGIN TRANSACTION');
|
||||
|
||||
// Data dari BPS langsung ditandai 'Verified' karena sudah merupakan data resmi
|
||||
const perintah_insert = db.prepare(`INSERT INTO MUSTAHIK (nik, nama_kk, lat, lng, status_validasi) VALUES (?, ?, ?, ?, 'Verified')`);
|
||||
|
||||
hasil_parsing.forEach((baris) => {
|
||||
// Menyesuaikan dengan standar header kolom CSV: NIK, Nama_KK, Latitude, Longitude
|
||||
perintah_insert.run([baris.NIK, baris.Nama_KK, baris.Latitude, baris.Longitude], (err) => {
|
||||
if (err) {
|
||||
console.error('Gagal mengimpor baris data:', err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
perintah_insert.finalize();
|
||||
|
||||
db.run('COMMIT', (err) => {
|
||||
if (err) {
|
||||
db.run('ROLLBACK');
|
||||
return res.status(500).json({ error: 'Gagal menyimpan data impor ke basis data' });
|
||||
}
|
||||
|
||||
// Praktik keamanan dan kebersihan: Menghapus berkas CSV sementara dari peladen secara otomatis setelah seluruh datanya berhasil diekstrak ke dalam tabel
|
||||
fs.unlinkSync(path_berkas);
|
||||
|
||||
res.status(200).json({ message: `Berhasil mengimpor ${hasil_parsing.length} data baseline BPS` });
|
||||
});
|
||||
});
|
||||
})
|
||||
.on('error', (error) => {
|
||||
// Penanganan kesalahan otomatis saat file CSV korup
|
||||
fs.unlinkSync(path_berkas);
|
||||
res.status(500).json({ error: 'Kesalahan saat membaca struktur baris CSV' });
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Kesalahan sistem impor:', error);
|
||||
res.status(500).json({ error: 'Kegagalan pemrosesan internal server' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
import_data_bps
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
const db = require('../config/database');
|
||||
|
||||
// Mengambil data titik warga dan mengubahnya ke format GeoJSON
|
||||
const dapatkan_data_publik = async (req, res) => {
|
||||
try {
|
||||
// Praktik keamanan: Query secara eksplisit hanya memilih data dengan status 'Verified' agar draf data lapangan tidak bocor ke publik
|
||||
const query_publik = `SELECT lat, lng FROM MUSTAHIK WHERE status_validasi = 'Verified'`;
|
||||
|
||||
db.all(query_publik, [], (err, rows) => {
|
||||
if (err) {
|
||||
console.error('Gagal mengambil data peta:', err.message);
|
||||
return res.status(500).json({ error: 'Kegagalan mengambil titik koordinat' });
|
||||
}
|
||||
|
||||
// Baris kompleks: Melakukan pemetaan array objek dari baris basis data menjadi struktur hierarki GeoJSON standar. Format FeatureCollection ini adalah spesifikasi wajib yang dipahami oleh pustaka LeafletJS untuk merender penanda di atas peta.
|
||||
const geojson_data = {
|
||||
type: 'FeatureCollection',
|
||||
features: rows.map(row => ({
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [row.lng, row.lat]
|
||||
},
|
||||
properties: {
|
||||
keterangan: 'Lokasi Terverifikasi'
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
res.status(200).json(geojson_data);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Kesalahan sistem pemetaan:', error);
|
||||
res.status(500).json({ error: 'Kegagalan pemrosesan internal server' });
|
||||
}
|
||||
};
|
||||
|
||||
// Mengambil data rumah ibadah dan mengubahnya ke format GeoJSON
|
||||
const dapatkan_rumah_ibadah = async (req, res) => {
|
||||
try {
|
||||
const query_rumah_ibadah = `SELECT nama_tempat, jenis_agama, lat, lng, alamat FROM RUMAH_IBADAH`;
|
||||
|
||||
db.all(query_rumah_ibadah, [], (err, rows) => {
|
||||
if (err) {
|
||||
console.error('Gagal mengambil data rumah ibadah:', err.message);
|
||||
return res.status(500).json({ error: 'Kegagalan mengambil titik koordinat rumah ibadah' });
|
||||
}
|
||||
|
||||
// Baris kompleks: Selain koordinat, kita menyisipkan atribut 'properties' yang berisi nama tempat dan jenis agama agar nantinya antarmuka LeafletJS bisa menampilkan popup informasi (tooltip) saat marker diklik oleh pengguna.
|
||||
const geojson_data = {
|
||||
type: 'FeatureCollection',
|
||||
features: rows.map(row => ({
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [row.lng, row.lat]
|
||||
},
|
||||
properties: {
|
||||
nama_tempat: row.nama_tempat,
|
||||
jenis_agama: row.jenis_agama,
|
||||
alamat: row.alamat
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
res.status(200).json(geojson_data);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Kesalahan sistem pemetaan rumah ibadah:', error);
|
||||
res.status(500).json({ error: 'Kegagalan pemrosesan internal server' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
dapatkan_data_publik,
|
||||
dapatkan_rumah_ibadah
|
||||
};
|
||||
@@ -0,0 +1,166 @@
|
||||
const db = require('../config/database');
|
||||
|
||||
// Mengambil data status bantuan warga beserta lokasi pangkalan ibadah
|
||||
const cek_status_nik = (req, res) => {
|
||||
const nik_warga = req.params.nik;
|
||||
|
||||
// Praktik keamanan: Memastikan input NIK murni berupa 16 digit angka untuk mencegah manipulasi query
|
||||
if (!/^\d{16}$/.test(nik_warga)) {
|
||||
return res.status(400).json({ error: 'Format NIK tidak valid.' });
|
||||
}
|
||||
|
||||
// Baris kompleks: Operasi LEFT JOIN menghubungkan tabel MUSTAHIK dengan RUMAH_IBADAH berdasarkan Foreign Key id_rumah_ibadah untuk menarik koordinat pangkalan distribusi secara simultan dalam satu siklus I/O.
|
||||
const kueri_pencarian = `
|
||||
SELECT m.nik, m.nama_kk, m.status_validasi, m.lat, m.lng, m.agama,
|
||||
r.nama_tempat AS rumah_ibadah_nama,
|
||||
r.lat AS rumah_ibadah_lat,
|
||||
r.lng AS rumah_ibadah_lng
|
||||
FROM MUSTAHIK m
|
||||
LEFT JOIN RUMAH_IBADAH r ON m.id_rumah_ibadah = r.id
|
||||
WHERE m.nik = ?
|
||||
`;
|
||||
|
||||
db.get(kueri_pencarian, [nik_warga], (error_sistem, baris_data) => {
|
||||
if (error_sistem) {
|
||||
console.error('Sistem gagal membaca tabel gabungan:', error_sistem.message);
|
||||
return res.status(500).json({ error: 'Terjadi kegagalan server internal.' });
|
||||
}
|
||||
|
||||
if (!baris_data) {
|
||||
return res.status(404).json({ error: 'Data tidak ditemukan.' });
|
||||
}
|
||||
|
||||
res.status(200).json(baris_data);
|
||||
});
|
||||
};
|
||||
|
||||
// Mengontrol alur penerimaan data survei lapangan beserta penentuan pangkalan bantuan
|
||||
const submit_survey_data = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
nik,
|
||||
nama_kk,
|
||||
no_kk,
|
||||
jumlah_tanggungan,
|
||||
lat,
|
||||
lng,
|
||||
agama,
|
||||
indikator_bps
|
||||
} = req.body;
|
||||
|
||||
// Praktik keamanan: Validasi input dasar untuk mencegah insersi data kosong (null pointer exception)
|
||||
if (!nik || !nama_kk || !lat || !lng || !agama || !indikator_bps) {
|
||||
return res.status(400).json({ error: 'Payload data survei tidak lengkap dari klien.' });
|
||||
}
|
||||
|
||||
// Memulai transaksi basis data untuk menjaga integritas penyimpanan parsial
|
||||
db.serialize(() => {
|
||||
db.run('BEGIN TRANSACTION');
|
||||
|
||||
// Baris kompleks: Memanfaatkan db.serialize untuk memastikan kueri SELECT pencarian pangkalan ibadah selesai dieksekusi sebelum beralih ke perintah INSERT transaksional berikutnya guna menghindari balapan data (race condition).
|
||||
const kueri_cari_pangkalan = `SELECT id FROM RUMAH_IBADAH WHERE agama = ? LIMIT 1`;
|
||||
|
||||
db.get(kueri_cari_pangkalan, [agama], (error_cari, baris_pangkalan) => {
|
||||
if (error_cari) {
|
||||
db.run('ROLLBACK');
|
||||
console.error('Gagal mencocokkan rumah ibadah:', error_cari.message);
|
||||
return res.status(500).json({ error: 'Gagal memproses penentuan lokasi bantuan.' });
|
||||
}
|
||||
|
||||
const id_pangkalan_terpilih = baris_pangkalan ? baris_pangkalan.id : null;
|
||||
|
||||
// 1. Menyimpan data identitas dan relasi pangkalan ke tabel MUSTAHIK
|
||||
const kueri_mustahik = `
|
||||
INSERT INTO MUSTAHIK (nik, nama_kk, no_kk, jumlah_tanggungan, lat, lng, agama, id_rumah_ibadah)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`;
|
||||
|
||||
db.run(kueri_mustahik, [nik, nama_kk, no_kk, jumlah_tanggungan, lat, lng, agama, id_pangkalan_terpilih], function(error_mustahik) {
|
||||
if (error_mustahik) {
|
||||
db.run('ROLLBACK');
|
||||
console.error('Gagal menyimpan DML MUSTAHIK:', error_mustahik.message);
|
||||
return res.status(500).json({ error: 'Gagal menyimpan data identitas warga, NIK mungkin sudah terdaftar.' });
|
||||
}
|
||||
|
||||
const id_mustahik_baru = this.lastID;
|
||||
const {
|
||||
luas_lantai_per_kapita,
|
||||
material_lantai,
|
||||
material_dinding,
|
||||
fasilitas_sanitasi,
|
||||
sumber_air_minum,
|
||||
sumber_penerangan,
|
||||
pekerjaan_utama,
|
||||
pendapatan_bulanan,
|
||||
frekuensi_makan,
|
||||
kepemilikan_aset
|
||||
} = indikator_bps;
|
||||
|
||||
// 2. Menyimpan 10 parameter kondisi ke tabel INDIKATOR_BPS
|
||||
const kueri_indikator = `
|
||||
INSERT INTO INDIKATOR_BPS (
|
||||
id_mustahik, luas_lantai_per_kapita, material_lantai, material_dinding,
|
||||
fasilitas_sanitasi, sumber_air_minum, sumber_penerangan,
|
||||
pekerjaan_utama, pendapatan_bulanan, frekuensi_makan, kepemilikan_aset
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`;
|
||||
|
||||
db.run(kueri_indikator, [
|
||||
id_mustahik_baru,
|
||||
luas_lantai_per_kapita,
|
||||
material_lantai,
|
||||
material_dinding,
|
||||
fasilitas_sanitasi,
|
||||
sumber_air_minum,
|
||||
sumber_penerangan,
|
||||
pekerjaan_utama,
|
||||
pendapatan_bulanan,
|
||||
frekuensi_makan,
|
||||
kepemilikan_aset
|
||||
], function(error_indikator) {
|
||||
if (error_indikator) {
|
||||
db.run('ROLLBACK');
|
||||
console.error('Gagal menyimpan DML INDIKATOR_BPS:', error_indikator.message);
|
||||
return res.status(500).json({ error: 'Gagal merekam indikator ekonomi BPS.' });
|
||||
}
|
||||
|
||||
// Secara permanen menerapkan semua kueri yang tertunda ke dalam file SQLite
|
||||
db.run('COMMIT');
|
||||
res.status(201).json({
|
||||
message: 'Data survei kriteria BPS dan pangkalan bantuan berhasil disimpan.',
|
||||
id_mustahik: id_mustahik_baru
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} catch (error_sistem) {
|
||||
console.error('Kesalahan eksekusi sistem:', error_sistem);
|
||||
res.status(500).json({ error: 'Kegagalan pemrosesan internal server.' });
|
||||
}
|
||||
};
|
||||
|
||||
// Menarik agregasi data statistik untuk ditampilkan di halaman publik
|
||||
const ambil_statistik_publik = (req, res) => {
|
||||
const kueri_statistik = `
|
||||
SELECT
|
||||
COUNT(CASE WHEN status_validasi = 'Verified' THEN 1 END) AS terverifikasi,
|
||||
COUNT(CASE WHEN status_validasi = 'Pending' THEN 1 END) AS diproses
|
||||
FROM MUSTAHIK
|
||||
`;
|
||||
|
||||
db.get(kueri_statistik, [], (error_sql, baris_data) => {
|
||||
if (error_sql) {
|
||||
console.error('Gagal menarik agregasi statistik:', error_sql.message);
|
||||
return res.status(500).json({ error: 'Gagal memuat statistik.' });
|
||||
}
|
||||
res.status(200).json(baris_data);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
cek_status_nik,
|
||||
submit_survey_data,
|
||||
ambil_statistik_publik
|
||||
};
|
||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
// Menjaga rute spesifik agar hanya dapat diakses dengan token yang valid
|
||||
const verify_token = (req, res, next) => {
|
||||
try {
|
||||
const auth_header = req.headers['authorization'];
|
||||
|
||||
// Praktik keamanan: Memastikan header ada dan memisahkan kata 'Bearer ' dari token utamanya
|
||||
const token = auth_header && auth_header.split(' ')[1];
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: 'Akses ditolak: Token tidak ditemukan' });
|
||||
}
|
||||
|
||||
// Baris kompleks: jwt.verify() mendekripsi token menggunakan kunci rahasia yang sama dengan saat pembuatan. Jika kunci cocok dan token belum kedaluwarsa, ia akan mengembalikan data payload (decoded), jika tidak, ia akan melempar error (termasuk jika token dipalsukan).
|
||||
jwt.verify(token, 'kunci_rahasia_webgis_pontianak', (err, decoded_data) => {
|
||||
if (err) {
|
||||
return res.status(403).json({ error: 'Sesi tidak valid atau telah berakhir' });
|
||||
}
|
||||
|
||||
req.admin_terotentikasi = decoded_data;
|
||||
next();
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Kesalahan verifikasi keamanan:', error);
|
||||
res.status(500).json({ error: 'Kesalahan internal saat memverifikasi sesi' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
verify_token
|
||||
};
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../autoprefixer/bin/autoprefixer" "$@"
|
||||
else
|
||||
exec node "$basedir/../autoprefixer/bin/autoprefixer" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\autoprefixer\bin\autoprefixer" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../autoprefixer/bin/autoprefixer" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../autoprefixer/bin/autoprefixer" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../autoprefixer/bin/autoprefixer" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../autoprefixer/bin/autoprefixer" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../baseline-browser-mapping/dist/cli.cjs" "$@"
|
||||
else
|
||||
exec node "$basedir/../baseline-browser-mapping/dist/cli.cjs" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\baseline-browser-mapping\dist\cli.cjs" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../baseline-browser-mapping/dist/cli.cjs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../baseline-browser-mapping/dist/cli.cjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../browserslist/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../browserslist/cli.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\browserslist\cli.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../browserslist/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../browserslist/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../browserslist/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../browserslist/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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
@@ -0,0 +1,17 @@
|
||||
@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
@@ -0,0 +1,28 @@
|
||||
#!/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
@@ -0,0 +1,16 @@
|
||||
#!/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/../nanoid/bin/nanoid.cjs" "$@"
|
||||
else
|
||||
exec node "$basedir/../nanoid/bin/nanoid.cjs" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\nanoid\bin\nanoid.cjs" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../nanoid/bin/nanoid.cjs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nanoid/bin/nanoid.cjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../node-gyp/bin/node-gyp.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../node-gyp/bin/node-gyp.js" "$@"
|
||||
fi
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../node-gyp-build/bin.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../node-gyp-build/bin.js" "$@"
|
||||
fi
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../node-gyp-build/optional.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../node-gyp-build/optional.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\node-gyp-build\optional.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../node-gyp-build/optional.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../node-gyp-build/optional.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../node-gyp-build/optional.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../node-gyp-build/optional.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../node-gyp-build/build-test.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../node-gyp-build/build-test.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\node-gyp-build\build-test.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../node-gyp-build/build-test.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../node-gyp-build/build-test.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../node-gyp-build/build-test.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../node-gyp-build/build-test.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\node-gyp-build\bin.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../node-gyp-build/bin.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../node-gyp-build/bin.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../node-gyp-build/bin.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../node-gyp-build/bin.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\node-gyp\bin\node-gyp.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../node-gyp/bin/node-gyp.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../node-gyp/bin/node-gyp.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../which/bin/which.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../which/bin/which.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\which\bin\which.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../which/bin/which.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../which/bin/which.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../which/bin/which.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../which/bin/which.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../nopt/bin/nopt.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../nopt/bin/nopt.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\nopt\bin\nopt.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../nopt/bin/nopt.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../prebuild-install/bin.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../prebuild-install/bin.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\prebuild-install\bin.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../prebuild-install/bin.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../prebuild-install/bin.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../prebuild-install/bin.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../prebuild-install/bin.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../rc/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../rc/cli.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\rc\cli.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../rc/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../rc/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../rc/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../rc/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../semver/bin/semver.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../semver/bin/semver.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\semver\bin\semver.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/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/../update-browserslist-db/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../update-browserslist-db/cli.js" "$@"
|
||||
fi
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@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%\..\update-browserslist-db\cli.js" %*
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#!/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/../update-browserslist-db/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../update-browserslist-db/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../update-browserslist-db/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../update-browserslist-db/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
+2071
File diff suppressed because it is too large
Load Diff
+15
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
# fs-minipass
|
||||
|
||||
Filesystem streams based on [minipass](http://npm.im/minipass).
|
||||
|
||||
4 classes are exported:
|
||||
|
||||
- ReadStream
|
||||
- ReadStreamSync
|
||||
- WriteStream
|
||||
- WriteStreamSync
|
||||
|
||||
When using `ReadStreamSync`, all of the data is made available
|
||||
immediately upon consuming the stream. Nothing is buffered in memory
|
||||
when the stream is constructed. If the stream is piped to a writer,
|
||||
then it will synchronously `read()` and emit data into the writer as
|
||||
fast as the writer can consume it. (That is, it will respect
|
||||
backpressure.) If you call `stream.read()` then it will read the
|
||||
entire file and return the contents.
|
||||
|
||||
When using `WriteStreamSync`, every write is flushed to the file
|
||||
synchronously. If your writes all come in a single tick, then it'll
|
||||
write it all out in a single tick. It's as synchronous as you are.
|
||||
|
||||
The async versions work much like their node builtin counterparts,
|
||||
with the exception of introducing significantly less Stream machinery
|
||||
overhead.
|
||||
|
||||
## USAGE
|
||||
|
||||
It's just streams, you pipe them or read() them or write() to them.
|
||||
|
||||
```js
|
||||
import { ReadStream, WriteStream } from 'fs-minipass'
|
||||
// or: const { ReadStream, WriteStream } = require('fs-minipass')
|
||||
const readStream = new ReadStream('file.txt')
|
||||
const writeStream = new WriteStream('output.txt')
|
||||
writeStream.write('some file header or whatever\n')
|
||||
readStream.pipe(writeStream)
|
||||
```
|
||||
|
||||
## ReadStream(path, options)
|
||||
|
||||
Path string is required, but somewhat irrelevant if an open file
|
||||
descriptor is passed in as an option.
|
||||
|
||||
Options:
|
||||
|
||||
- `fd` Pass in a numeric file descriptor, if the file is already open.
|
||||
- `readSize` The size of reads to do, defaults to 16MB
|
||||
- `size` The size of the file, if known. Prevents zero-byte read()
|
||||
call at the end.
|
||||
- `autoClose` Set to `false` to prevent the file descriptor from being
|
||||
closed when the file is done being read.
|
||||
|
||||
## WriteStream(path, options)
|
||||
|
||||
Path string is required, but somewhat irrelevant if an open file
|
||||
descriptor is passed in as an option.
|
||||
|
||||
Options:
|
||||
|
||||
- `fd` Pass in a numeric file descriptor, if the file is already open.
|
||||
- `mode` The mode to create the file with. Defaults to `0o666`.
|
||||
- `start` The position in the file to start reading. If not
|
||||
specified, then the file will start writing at position zero, and be
|
||||
truncated by default.
|
||||
- `autoClose` Set to `false` to prevent the file descriptor from being
|
||||
closed when the stream is ended.
|
||||
- `flags` Flags to use when opening the file. Irrelevant if `fd` is
|
||||
passed in, since file won't be opened in that case. Defaults to
|
||||
`'a'` if a `pos` is specified, or `'w'` otherwise.
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import EE from 'events';
|
||||
import { Minipass } from 'minipass';
|
||||
declare const _autoClose: unique symbol;
|
||||
declare const _close: unique symbol;
|
||||
declare const _ended: unique symbol;
|
||||
declare const _fd: unique symbol;
|
||||
declare const _finished: unique symbol;
|
||||
declare const _flags: unique symbol;
|
||||
declare const _flush: unique symbol;
|
||||
declare const _handleChunk: unique symbol;
|
||||
declare const _makeBuf: unique symbol;
|
||||
declare const _mode: unique symbol;
|
||||
declare const _needDrain: unique symbol;
|
||||
declare const _onerror: unique symbol;
|
||||
declare const _onopen: unique symbol;
|
||||
declare const _onread: unique symbol;
|
||||
declare const _onwrite: unique symbol;
|
||||
declare const _open: unique symbol;
|
||||
declare const _path: unique symbol;
|
||||
declare const _pos: unique symbol;
|
||||
declare const _queue: unique symbol;
|
||||
declare const _read: unique symbol;
|
||||
declare const _readSize: unique symbol;
|
||||
declare const _reading: unique symbol;
|
||||
declare const _remain: unique symbol;
|
||||
declare const _size: unique symbol;
|
||||
declare const _write: unique symbol;
|
||||
declare const _writing: unique symbol;
|
||||
declare const _defaultFlag: unique symbol;
|
||||
declare const _errored: unique symbol;
|
||||
export type ReadStreamOptions = Minipass.Options<Minipass.ContiguousData> & {
|
||||
fd?: number;
|
||||
readSize?: number;
|
||||
size?: number;
|
||||
autoClose?: boolean;
|
||||
};
|
||||
export type ReadStreamEvents = Minipass.Events<Minipass.ContiguousData> & {
|
||||
open: [fd: number];
|
||||
};
|
||||
export declare class ReadStream extends Minipass<Minipass.ContiguousData, Buffer, ReadStreamEvents> {
|
||||
[_errored]: boolean;
|
||||
[_fd]?: number;
|
||||
[_path]: string;
|
||||
[_readSize]: number;
|
||||
[_reading]: boolean;
|
||||
[_size]: number;
|
||||
[_remain]: number;
|
||||
[_autoClose]: boolean;
|
||||
constructor(path: string, opt: ReadStreamOptions);
|
||||
get fd(): number | undefined;
|
||||
get path(): string;
|
||||
write(): void;
|
||||
end(): void;
|
||||
[_open](): void;
|
||||
[_onopen](er?: NodeJS.ErrnoException | null, fd?: number): void;
|
||||
[_makeBuf](): Buffer;
|
||||
[_read](): void;
|
||||
[_onread](er?: NodeJS.ErrnoException | null, br?: number, buf?: Buffer): void;
|
||||
[_close](): void;
|
||||
[_onerror](er: NodeJS.ErrnoException): void;
|
||||
[_handleChunk](br: number, buf: Buffer): boolean;
|
||||
emit<Event extends keyof ReadStreamEvents>(ev: Event, ...args: ReadStreamEvents[Event]): boolean;
|
||||
}
|
||||
export declare class ReadStreamSync extends ReadStream {
|
||||
[_open](): void;
|
||||
[_read](): void;
|
||||
[_close](): void;
|
||||
}
|
||||
export type WriteStreamOptions = {
|
||||
fd?: number;
|
||||
autoClose?: boolean;
|
||||
mode?: number;
|
||||
captureRejections?: boolean;
|
||||
start?: number;
|
||||
flags?: string;
|
||||
};
|
||||
export declare class WriteStream extends EE {
|
||||
readable: false;
|
||||
writable: boolean;
|
||||
[_errored]: boolean;
|
||||
[_writing]: boolean;
|
||||
[_ended]: boolean;
|
||||
[_queue]: Buffer[];
|
||||
[_needDrain]: boolean;
|
||||
[_path]: string;
|
||||
[_mode]: number;
|
||||
[_autoClose]: boolean;
|
||||
[_fd]?: number;
|
||||
[_defaultFlag]: boolean;
|
||||
[_flags]: string;
|
||||
[_finished]: boolean;
|
||||
[_pos]?: number;
|
||||
constructor(path: string, opt: WriteStreamOptions);
|
||||
emit(ev: string, ...args: any[]): boolean;
|
||||
get fd(): number | undefined;
|
||||
get path(): string;
|
||||
[_onerror](er: NodeJS.ErrnoException): void;
|
||||
[_open](): void;
|
||||
[_onopen](er?: null | NodeJS.ErrnoException, fd?: number): void;
|
||||
end(buf: string, enc?: BufferEncoding): this;
|
||||
end(buf?: Buffer, enc?: undefined): this;
|
||||
write(buf: string, enc?: BufferEncoding): boolean;
|
||||
write(buf: Buffer, enc?: undefined): boolean;
|
||||
[_write](buf: Buffer): void;
|
||||
[_onwrite](er?: null | NodeJS.ErrnoException, bw?: number): void;
|
||||
[_flush](): void;
|
||||
[_close](): void;
|
||||
}
|
||||
export declare class WriteStreamSync extends WriteStream {
|
||||
[_open](): void;
|
||||
[_close](): void;
|
||||
[_write](buf: Buffer): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
||||
+430
@@ -0,0 +1,430 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WriteStreamSync = exports.WriteStream = exports.ReadStreamSync = exports.ReadStream = void 0;
|
||||
const events_1 = __importDefault(require("events"));
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const minipass_1 = require("minipass");
|
||||
const writev = fs_1.default.writev;
|
||||
const _autoClose = Symbol('_autoClose');
|
||||
const _close = Symbol('_close');
|
||||
const _ended = Symbol('_ended');
|
||||
const _fd = Symbol('_fd');
|
||||
const _finished = Symbol('_finished');
|
||||
const _flags = Symbol('_flags');
|
||||
const _flush = Symbol('_flush');
|
||||
const _handleChunk = Symbol('_handleChunk');
|
||||
const _makeBuf = Symbol('_makeBuf');
|
||||
const _mode = Symbol('_mode');
|
||||
const _needDrain = Symbol('_needDrain');
|
||||
const _onerror = Symbol('_onerror');
|
||||
const _onopen = Symbol('_onopen');
|
||||
const _onread = Symbol('_onread');
|
||||
const _onwrite = Symbol('_onwrite');
|
||||
const _open = Symbol('_open');
|
||||
const _path = Symbol('_path');
|
||||
const _pos = Symbol('_pos');
|
||||
const _queue = Symbol('_queue');
|
||||
const _read = Symbol('_read');
|
||||
const _readSize = Symbol('_readSize');
|
||||
const _reading = Symbol('_reading');
|
||||
const _remain = Symbol('_remain');
|
||||
const _size = Symbol('_size');
|
||||
const _write = Symbol('_write');
|
||||
const _writing = Symbol('_writing');
|
||||
const _defaultFlag = Symbol('_defaultFlag');
|
||||
const _errored = Symbol('_errored');
|
||||
class ReadStream extends minipass_1.Minipass {
|
||||
[_errored] = false;
|
||||
[_fd];
|
||||
[_path];
|
||||
[_readSize];
|
||||
[_reading] = false;
|
||||
[_size];
|
||||
[_remain];
|
||||
[_autoClose];
|
||||
constructor(path, opt) {
|
||||
opt = opt || {};
|
||||
super(opt);
|
||||
this.readable = true;
|
||||
this.writable = false;
|
||||
if (typeof path !== 'string') {
|
||||
throw new TypeError('path must be a string');
|
||||
}
|
||||
this[_errored] = false;
|
||||
this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined;
|
||||
this[_path] = path;
|
||||
this[_readSize] = opt.readSize || 16 * 1024 * 1024;
|
||||
this[_reading] = false;
|
||||
this[_size] = typeof opt.size === 'number' ? opt.size : Infinity;
|
||||
this[_remain] = this[_size];
|
||||
this[_autoClose] =
|
||||
typeof opt.autoClose === 'boolean' ? opt.autoClose : true;
|
||||
if (typeof this[_fd] === 'number') {
|
||||
this[_read]();
|
||||
}
|
||||
else {
|
||||
this[_open]();
|
||||
}
|
||||
}
|
||||
get fd() {
|
||||
return this[_fd];
|
||||
}
|
||||
get path() {
|
||||
return this[_path];
|
||||
}
|
||||
//@ts-ignore
|
||||
write() {
|
||||
throw new TypeError('this is a readable stream');
|
||||
}
|
||||
//@ts-ignore
|
||||
end() {
|
||||
throw new TypeError('this is a readable stream');
|
||||
}
|
||||
[_open]() {
|
||||
fs_1.default.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd));
|
||||
}
|
||||
[_onopen](er, fd) {
|
||||
if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else {
|
||||
this[_fd] = fd;
|
||||
this.emit('open', fd);
|
||||
this[_read]();
|
||||
}
|
||||
}
|
||||
[_makeBuf]() {
|
||||
return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain]));
|
||||
}
|
||||
[_read]() {
|
||||
if (!this[_reading]) {
|
||||
this[_reading] = true;
|
||||
const buf = this[_makeBuf]();
|
||||
/* c8 ignore start */
|
||||
if (buf.length === 0) {
|
||||
return process.nextTick(() => this[_onread](null, 0, buf));
|
||||
}
|
||||
/* c8 ignore stop */
|
||||
fs_1.default.read(this[_fd], buf, 0, buf.length, null, (er, br, b) => this[_onread](er, br, b));
|
||||
}
|
||||
}
|
||||
[_onread](er, br, buf) {
|
||||
this[_reading] = false;
|
||||
if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else if (this[_handleChunk](br, buf)) {
|
||||
this[_read]();
|
||||
}
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs_1.default.close(fd, er => er ? this.emit('error', er) : this.emit('close'));
|
||||
}
|
||||
}
|
||||
[_onerror](er) {
|
||||
this[_reading] = true;
|
||||
this[_close]();
|
||||
this.emit('error', er);
|
||||
}
|
||||
[_handleChunk](br, buf) {
|
||||
let ret = false;
|
||||
// no effect if infinite
|
||||
this[_remain] -= br;
|
||||
if (br > 0) {
|
||||
ret = super.write(br < buf.length ? buf.subarray(0, br) : buf);
|
||||
}
|
||||
if (br === 0 || this[_remain] <= 0) {
|
||||
ret = false;
|
||||
this[_close]();
|
||||
super.end();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
emit(ev, ...args) {
|
||||
switch (ev) {
|
||||
case 'prefinish':
|
||||
case 'finish':
|
||||
return false;
|
||||
case 'drain':
|
||||
if (typeof this[_fd] === 'number') {
|
||||
this[_read]();
|
||||
}
|
||||
return false;
|
||||
case 'error':
|
||||
if (this[_errored]) {
|
||||
return false;
|
||||
}
|
||||
this[_errored] = true;
|
||||
return super.emit(ev, ...args);
|
||||
default:
|
||||
return super.emit(ev, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ReadStream = ReadStream;
|
||||
class ReadStreamSync extends ReadStream {
|
||||
[_open]() {
|
||||
let threw = true;
|
||||
try {
|
||||
this[_onopen](null, fs_1.default.openSync(this[_path], 'r'));
|
||||
threw = false;
|
||||
}
|
||||
finally {
|
||||
if (threw) {
|
||||
this[_close]();
|
||||
}
|
||||
}
|
||||
}
|
||||
[_read]() {
|
||||
let threw = true;
|
||||
try {
|
||||
if (!this[_reading]) {
|
||||
this[_reading] = true;
|
||||
do {
|
||||
const buf = this[_makeBuf]();
|
||||
/* c8 ignore start */
|
||||
const br = buf.length === 0
|
||||
? 0
|
||||
: fs_1.default.readSync(this[_fd], buf, 0, buf.length, null);
|
||||
/* c8 ignore stop */
|
||||
if (!this[_handleChunk](br, buf)) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
this[_reading] = false;
|
||||
}
|
||||
threw = false;
|
||||
}
|
||||
finally {
|
||||
if (threw) {
|
||||
this[_close]();
|
||||
}
|
||||
}
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs_1.default.closeSync(fd);
|
||||
this.emit('close');
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ReadStreamSync = ReadStreamSync;
|
||||
class WriteStream extends events_1.default {
|
||||
readable = false;
|
||||
writable = true;
|
||||
[_errored] = false;
|
||||
[_writing] = false;
|
||||
[_ended] = false;
|
||||
[_queue] = [];
|
||||
[_needDrain] = false;
|
||||
[_path];
|
||||
[_mode];
|
||||
[_autoClose];
|
||||
[_fd];
|
||||
[_defaultFlag];
|
||||
[_flags];
|
||||
[_finished] = false;
|
||||
[_pos];
|
||||
constructor(path, opt) {
|
||||
opt = opt || {};
|
||||
super(opt);
|
||||
this[_path] = path;
|
||||
this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined;
|
||||
this[_mode] = opt.mode === undefined ? 0o666 : opt.mode;
|
||||
this[_pos] = typeof opt.start === 'number' ? opt.start : undefined;
|
||||
this[_autoClose] =
|
||||
typeof opt.autoClose === 'boolean' ? opt.autoClose : true;
|
||||
// truncating makes no sense when writing into the middle
|
||||
const defaultFlag = this[_pos] !== undefined ? 'r+' : 'w';
|
||||
this[_defaultFlag] = opt.flags === undefined;
|
||||
this[_flags] = opt.flags === undefined ? defaultFlag : opt.flags;
|
||||
if (this[_fd] === undefined) {
|
||||
this[_open]();
|
||||
}
|
||||
}
|
||||
emit(ev, ...args) {
|
||||
if (ev === 'error') {
|
||||
if (this[_errored]) {
|
||||
return false;
|
||||
}
|
||||
this[_errored] = true;
|
||||
}
|
||||
return super.emit(ev, ...args);
|
||||
}
|
||||
get fd() {
|
||||
return this[_fd];
|
||||
}
|
||||
get path() {
|
||||
return this[_path];
|
||||
}
|
||||
[_onerror](er) {
|
||||
this[_close]();
|
||||
this[_writing] = true;
|
||||
this.emit('error', er);
|
||||
}
|
||||
[_open]() {
|
||||
fs_1.default.open(this[_path], this[_flags], this[_mode], (er, fd) => this[_onopen](er, fd));
|
||||
}
|
||||
[_onopen](er, fd) {
|
||||
if (this[_defaultFlag] &&
|
||||
this[_flags] === 'r+' &&
|
||||
er &&
|
||||
er.code === 'ENOENT') {
|
||||
this[_flags] = 'w';
|
||||
this[_open]();
|
||||
}
|
||||
else if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else {
|
||||
this[_fd] = fd;
|
||||
this.emit('open', fd);
|
||||
if (!this[_writing]) {
|
||||
this[_flush]();
|
||||
}
|
||||
}
|
||||
}
|
||||
end(buf, enc) {
|
||||
if (buf) {
|
||||
//@ts-ignore
|
||||
this.write(buf, enc);
|
||||
}
|
||||
this[_ended] = true;
|
||||
// synthetic after-write logic, where drain/finish live
|
||||
if (!this[_writing] &&
|
||||
!this[_queue].length &&
|
||||
typeof this[_fd] === 'number') {
|
||||
this[_onwrite](null, 0);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
write(buf, enc) {
|
||||
if (typeof buf === 'string') {
|
||||
buf = Buffer.from(buf, enc);
|
||||
}
|
||||
if (this[_ended]) {
|
||||
this.emit('error', new Error('write() after end()'));
|
||||
return false;
|
||||
}
|
||||
if (this[_fd] === undefined || this[_writing] || this[_queue].length) {
|
||||
this[_queue].push(buf);
|
||||
this[_needDrain] = true;
|
||||
return false;
|
||||
}
|
||||
this[_writing] = true;
|
||||
this[_write](buf);
|
||||
return true;
|
||||
}
|
||||
[_write](buf) {
|
||||
fs_1.default.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => this[_onwrite](er, bw));
|
||||
}
|
||||
[_onwrite](er, bw) {
|
||||
if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else {
|
||||
if (this[_pos] !== undefined && typeof bw === 'number') {
|
||||
this[_pos] += bw;
|
||||
}
|
||||
if (this[_queue].length) {
|
||||
this[_flush]();
|
||||
}
|
||||
else {
|
||||
this[_writing] = false;
|
||||
if (this[_ended] && !this[_finished]) {
|
||||
this[_finished] = true;
|
||||
this[_close]();
|
||||
this.emit('finish');
|
||||
}
|
||||
else if (this[_needDrain]) {
|
||||
this[_needDrain] = false;
|
||||
this.emit('drain');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[_flush]() {
|
||||
if (this[_queue].length === 0) {
|
||||
if (this[_ended]) {
|
||||
this[_onwrite](null, 0);
|
||||
}
|
||||
}
|
||||
else if (this[_queue].length === 1) {
|
||||
this[_write](this[_queue].pop());
|
||||
}
|
||||
else {
|
||||
const iovec = this[_queue];
|
||||
this[_queue] = [];
|
||||
writev(this[_fd], iovec, this[_pos], (er, bw) => this[_onwrite](er, bw));
|
||||
}
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs_1.default.close(fd, er => er ? this.emit('error', er) : this.emit('close'));
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.WriteStream = WriteStream;
|
||||
class WriteStreamSync extends WriteStream {
|
||||
[_open]() {
|
||||
let fd;
|
||||
// only wrap in a try{} block if we know we'll retry, to avoid
|
||||
// the rethrow obscuring the error's source frame in most cases.
|
||||
if (this[_defaultFlag] && this[_flags] === 'r+') {
|
||||
try {
|
||||
fd = fs_1.default.openSync(this[_path], this[_flags], this[_mode]);
|
||||
}
|
||||
catch (er) {
|
||||
if (er?.code === 'ENOENT') {
|
||||
this[_flags] = 'w';
|
||||
return this[_open]();
|
||||
}
|
||||
else {
|
||||
throw er;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
fd = fs_1.default.openSync(this[_path], this[_flags], this[_mode]);
|
||||
}
|
||||
this[_onopen](null, fd);
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs_1.default.closeSync(fd);
|
||||
this.emit('close');
|
||||
}
|
||||
}
|
||||
[_write](buf) {
|
||||
// throw the original, but try to close if it fails
|
||||
let threw = true;
|
||||
try {
|
||||
this[_onwrite](null, fs_1.default.writeSync(this[_fd], buf, 0, buf.length, this[_pos]));
|
||||
threw = false;
|
||||
}
|
||||
finally {
|
||||
if (threw) {
|
||||
try {
|
||||
this[_close]();
|
||||
}
|
||||
catch {
|
||||
// ok error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.WriteStreamSync = WriteStreamSync;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/// <reference types="node" resolution-mode="require"/>
|
||||
/// <reference types="node" resolution-mode="require"/>
|
||||
/// <reference types="node" resolution-mode="require"/>
|
||||
import EE from 'events';
|
||||
import { Minipass } from 'minipass';
|
||||
declare const _autoClose: unique symbol;
|
||||
declare const _close: unique symbol;
|
||||
declare const _ended: unique symbol;
|
||||
declare const _fd: unique symbol;
|
||||
declare const _finished: unique symbol;
|
||||
declare const _flags: unique symbol;
|
||||
declare const _flush: unique symbol;
|
||||
declare const _handleChunk: unique symbol;
|
||||
declare const _makeBuf: unique symbol;
|
||||
declare const _mode: unique symbol;
|
||||
declare const _needDrain: unique symbol;
|
||||
declare const _onerror: unique symbol;
|
||||
declare const _onopen: unique symbol;
|
||||
declare const _onread: unique symbol;
|
||||
declare const _onwrite: unique symbol;
|
||||
declare const _open: unique symbol;
|
||||
declare const _path: unique symbol;
|
||||
declare const _pos: unique symbol;
|
||||
declare const _queue: unique symbol;
|
||||
declare const _read: unique symbol;
|
||||
declare const _readSize: unique symbol;
|
||||
declare const _reading: unique symbol;
|
||||
declare const _remain: unique symbol;
|
||||
declare const _size: unique symbol;
|
||||
declare const _write: unique symbol;
|
||||
declare const _writing: unique symbol;
|
||||
declare const _defaultFlag: unique symbol;
|
||||
declare const _errored: unique symbol;
|
||||
export type ReadStreamOptions = Minipass.Options<Minipass.ContiguousData> & {
|
||||
fd?: number;
|
||||
readSize?: number;
|
||||
size?: number;
|
||||
autoClose?: boolean;
|
||||
};
|
||||
export type ReadStreamEvents = Minipass.Events<Minipass.ContiguousData> & {
|
||||
open: [fd: number];
|
||||
};
|
||||
export declare class ReadStream extends Minipass<Minipass.ContiguousData, Buffer, ReadStreamEvents> {
|
||||
[_errored]: boolean;
|
||||
[_fd]?: number;
|
||||
[_path]: string;
|
||||
[_readSize]: number;
|
||||
[_reading]: boolean;
|
||||
[_size]: number;
|
||||
[_remain]: number;
|
||||
[_autoClose]: boolean;
|
||||
constructor(path: string, opt: ReadStreamOptions);
|
||||
get fd(): number | undefined;
|
||||
get path(): string;
|
||||
write(): void;
|
||||
end(): void;
|
||||
[_open](): void;
|
||||
[_onopen](er?: NodeJS.ErrnoException | null, fd?: number): void;
|
||||
[_makeBuf](): Buffer;
|
||||
[_read](): void;
|
||||
[_onread](er?: NodeJS.ErrnoException | null, br?: number, buf?: Buffer): void;
|
||||
[_close](): void;
|
||||
[_onerror](er: NodeJS.ErrnoException): void;
|
||||
[_handleChunk](br: number, buf: Buffer): boolean;
|
||||
emit<Event extends keyof ReadStreamEvents>(ev: Event, ...args: ReadStreamEvents[Event]): boolean;
|
||||
}
|
||||
export declare class ReadStreamSync extends ReadStream {
|
||||
[_open](): void;
|
||||
[_read](): void;
|
||||
[_close](): void;
|
||||
}
|
||||
export type WriteStreamOptions = {
|
||||
fd?: number;
|
||||
autoClose?: boolean;
|
||||
mode?: number;
|
||||
captureRejections?: boolean;
|
||||
start?: number;
|
||||
flags?: string;
|
||||
};
|
||||
export declare class WriteStream extends EE {
|
||||
readable: false;
|
||||
writable: boolean;
|
||||
[_errored]: boolean;
|
||||
[_writing]: boolean;
|
||||
[_ended]: boolean;
|
||||
[_queue]: Buffer[];
|
||||
[_needDrain]: boolean;
|
||||
[_path]: string;
|
||||
[_mode]: number;
|
||||
[_autoClose]: boolean;
|
||||
[_fd]?: number;
|
||||
[_defaultFlag]: boolean;
|
||||
[_flags]: string;
|
||||
[_finished]: boolean;
|
||||
[_pos]?: number;
|
||||
constructor(path: string, opt: WriteStreamOptions);
|
||||
emit(ev: string, ...args: any[]): boolean;
|
||||
get fd(): number | undefined;
|
||||
get path(): string;
|
||||
[_onerror](er: NodeJS.ErrnoException): void;
|
||||
[_open](): void;
|
||||
[_onopen](er?: null | NodeJS.ErrnoException, fd?: number): void;
|
||||
end(buf: string, enc?: BufferEncoding): this;
|
||||
end(buf?: Buffer, enc?: undefined): this;
|
||||
write(buf: string, enc?: BufferEncoding): boolean;
|
||||
write(buf: Buffer, enc?: undefined): boolean;
|
||||
[_write](buf: Buffer): void;
|
||||
[_onwrite](er?: null | NodeJS.ErrnoException, bw?: number): void;
|
||||
[_flush](): void;
|
||||
[_close](): void;
|
||||
}
|
||||
export declare class WriteStreamSync extends WriteStream {
|
||||
[_open](): void;
|
||||
[_close](): void;
|
||||
[_write](buf: Buffer): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
import EE from 'events';
|
||||
import fs from 'fs';
|
||||
import { Minipass } from 'minipass';
|
||||
const writev = fs.writev;
|
||||
const _autoClose = Symbol('_autoClose');
|
||||
const _close = Symbol('_close');
|
||||
const _ended = Symbol('_ended');
|
||||
const _fd = Symbol('_fd');
|
||||
const _finished = Symbol('_finished');
|
||||
const _flags = Symbol('_flags');
|
||||
const _flush = Symbol('_flush');
|
||||
const _handleChunk = Symbol('_handleChunk');
|
||||
const _makeBuf = Symbol('_makeBuf');
|
||||
const _mode = Symbol('_mode');
|
||||
const _needDrain = Symbol('_needDrain');
|
||||
const _onerror = Symbol('_onerror');
|
||||
const _onopen = Symbol('_onopen');
|
||||
const _onread = Symbol('_onread');
|
||||
const _onwrite = Symbol('_onwrite');
|
||||
const _open = Symbol('_open');
|
||||
const _path = Symbol('_path');
|
||||
const _pos = Symbol('_pos');
|
||||
const _queue = Symbol('_queue');
|
||||
const _read = Symbol('_read');
|
||||
const _readSize = Symbol('_readSize');
|
||||
const _reading = Symbol('_reading');
|
||||
const _remain = Symbol('_remain');
|
||||
const _size = Symbol('_size');
|
||||
const _write = Symbol('_write');
|
||||
const _writing = Symbol('_writing');
|
||||
const _defaultFlag = Symbol('_defaultFlag');
|
||||
const _errored = Symbol('_errored');
|
||||
export class ReadStream extends Minipass {
|
||||
[_errored] = false;
|
||||
[_fd];
|
||||
[_path];
|
||||
[_readSize];
|
||||
[_reading] = false;
|
||||
[_size];
|
||||
[_remain];
|
||||
[_autoClose];
|
||||
constructor(path, opt) {
|
||||
opt = opt || {};
|
||||
super(opt);
|
||||
this.readable = true;
|
||||
this.writable = false;
|
||||
if (typeof path !== 'string') {
|
||||
throw new TypeError('path must be a string');
|
||||
}
|
||||
this[_errored] = false;
|
||||
this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined;
|
||||
this[_path] = path;
|
||||
this[_readSize] = opt.readSize || 16 * 1024 * 1024;
|
||||
this[_reading] = false;
|
||||
this[_size] = typeof opt.size === 'number' ? opt.size : Infinity;
|
||||
this[_remain] = this[_size];
|
||||
this[_autoClose] =
|
||||
typeof opt.autoClose === 'boolean' ? opt.autoClose : true;
|
||||
if (typeof this[_fd] === 'number') {
|
||||
this[_read]();
|
||||
}
|
||||
else {
|
||||
this[_open]();
|
||||
}
|
||||
}
|
||||
get fd() {
|
||||
return this[_fd];
|
||||
}
|
||||
get path() {
|
||||
return this[_path];
|
||||
}
|
||||
//@ts-ignore
|
||||
write() {
|
||||
throw new TypeError('this is a readable stream');
|
||||
}
|
||||
//@ts-ignore
|
||||
end() {
|
||||
throw new TypeError('this is a readable stream');
|
||||
}
|
||||
[_open]() {
|
||||
fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd));
|
||||
}
|
||||
[_onopen](er, fd) {
|
||||
if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else {
|
||||
this[_fd] = fd;
|
||||
this.emit('open', fd);
|
||||
this[_read]();
|
||||
}
|
||||
}
|
||||
[_makeBuf]() {
|
||||
return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain]));
|
||||
}
|
||||
[_read]() {
|
||||
if (!this[_reading]) {
|
||||
this[_reading] = true;
|
||||
const buf = this[_makeBuf]();
|
||||
/* c8 ignore start */
|
||||
if (buf.length === 0) {
|
||||
return process.nextTick(() => this[_onread](null, 0, buf));
|
||||
}
|
||||
/* c8 ignore stop */
|
||||
fs.read(this[_fd], buf, 0, buf.length, null, (er, br, b) => this[_onread](er, br, b));
|
||||
}
|
||||
}
|
||||
[_onread](er, br, buf) {
|
||||
this[_reading] = false;
|
||||
if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else if (this[_handleChunk](br, buf)) {
|
||||
this[_read]();
|
||||
}
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs.close(fd, er => er ? this.emit('error', er) : this.emit('close'));
|
||||
}
|
||||
}
|
||||
[_onerror](er) {
|
||||
this[_reading] = true;
|
||||
this[_close]();
|
||||
this.emit('error', er);
|
||||
}
|
||||
[_handleChunk](br, buf) {
|
||||
let ret = false;
|
||||
// no effect if infinite
|
||||
this[_remain] -= br;
|
||||
if (br > 0) {
|
||||
ret = super.write(br < buf.length ? buf.subarray(0, br) : buf);
|
||||
}
|
||||
if (br === 0 || this[_remain] <= 0) {
|
||||
ret = false;
|
||||
this[_close]();
|
||||
super.end();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
emit(ev, ...args) {
|
||||
switch (ev) {
|
||||
case 'prefinish':
|
||||
case 'finish':
|
||||
return false;
|
||||
case 'drain':
|
||||
if (typeof this[_fd] === 'number') {
|
||||
this[_read]();
|
||||
}
|
||||
return false;
|
||||
case 'error':
|
||||
if (this[_errored]) {
|
||||
return false;
|
||||
}
|
||||
this[_errored] = true;
|
||||
return super.emit(ev, ...args);
|
||||
default:
|
||||
return super.emit(ev, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
export class ReadStreamSync extends ReadStream {
|
||||
[_open]() {
|
||||
let threw = true;
|
||||
try {
|
||||
this[_onopen](null, fs.openSync(this[_path], 'r'));
|
||||
threw = false;
|
||||
}
|
||||
finally {
|
||||
if (threw) {
|
||||
this[_close]();
|
||||
}
|
||||
}
|
||||
}
|
||||
[_read]() {
|
||||
let threw = true;
|
||||
try {
|
||||
if (!this[_reading]) {
|
||||
this[_reading] = true;
|
||||
do {
|
||||
const buf = this[_makeBuf]();
|
||||
/* c8 ignore start */
|
||||
const br = buf.length === 0
|
||||
? 0
|
||||
: fs.readSync(this[_fd], buf, 0, buf.length, null);
|
||||
/* c8 ignore stop */
|
||||
if (!this[_handleChunk](br, buf)) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
this[_reading] = false;
|
||||
}
|
||||
threw = false;
|
||||
}
|
||||
finally {
|
||||
if (threw) {
|
||||
this[_close]();
|
||||
}
|
||||
}
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs.closeSync(fd);
|
||||
this.emit('close');
|
||||
}
|
||||
}
|
||||
}
|
||||
export class WriteStream extends EE {
|
||||
readable = false;
|
||||
writable = true;
|
||||
[_errored] = false;
|
||||
[_writing] = false;
|
||||
[_ended] = false;
|
||||
[_queue] = [];
|
||||
[_needDrain] = false;
|
||||
[_path];
|
||||
[_mode];
|
||||
[_autoClose];
|
||||
[_fd];
|
||||
[_defaultFlag];
|
||||
[_flags];
|
||||
[_finished] = false;
|
||||
[_pos];
|
||||
constructor(path, opt) {
|
||||
opt = opt || {};
|
||||
super(opt);
|
||||
this[_path] = path;
|
||||
this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined;
|
||||
this[_mode] = opt.mode === undefined ? 0o666 : opt.mode;
|
||||
this[_pos] = typeof opt.start === 'number' ? opt.start : undefined;
|
||||
this[_autoClose] =
|
||||
typeof opt.autoClose === 'boolean' ? opt.autoClose : true;
|
||||
// truncating makes no sense when writing into the middle
|
||||
const defaultFlag = this[_pos] !== undefined ? 'r+' : 'w';
|
||||
this[_defaultFlag] = opt.flags === undefined;
|
||||
this[_flags] = opt.flags === undefined ? defaultFlag : opt.flags;
|
||||
if (this[_fd] === undefined) {
|
||||
this[_open]();
|
||||
}
|
||||
}
|
||||
emit(ev, ...args) {
|
||||
if (ev === 'error') {
|
||||
if (this[_errored]) {
|
||||
return false;
|
||||
}
|
||||
this[_errored] = true;
|
||||
}
|
||||
return super.emit(ev, ...args);
|
||||
}
|
||||
get fd() {
|
||||
return this[_fd];
|
||||
}
|
||||
get path() {
|
||||
return this[_path];
|
||||
}
|
||||
[_onerror](er) {
|
||||
this[_close]();
|
||||
this[_writing] = true;
|
||||
this.emit('error', er);
|
||||
}
|
||||
[_open]() {
|
||||
fs.open(this[_path], this[_flags], this[_mode], (er, fd) => this[_onopen](er, fd));
|
||||
}
|
||||
[_onopen](er, fd) {
|
||||
if (this[_defaultFlag] &&
|
||||
this[_flags] === 'r+' &&
|
||||
er &&
|
||||
er.code === 'ENOENT') {
|
||||
this[_flags] = 'w';
|
||||
this[_open]();
|
||||
}
|
||||
else if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else {
|
||||
this[_fd] = fd;
|
||||
this.emit('open', fd);
|
||||
if (!this[_writing]) {
|
||||
this[_flush]();
|
||||
}
|
||||
}
|
||||
}
|
||||
end(buf, enc) {
|
||||
if (buf) {
|
||||
//@ts-ignore
|
||||
this.write(buf, enc);
|
||||
}
|
||||
this[_ended] = true;
|
||||
// synthetic after-write logic, where drain/finish live
|
||||
if (!this[_writing] &&
|
||||
!this[_queue].length &&
|
||||
typeof this[_fd] === 'number') {
|
||||
this[_onwrite](null, 0);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
write(buf, enc) {
|
||||
if (typeof buf === 'string') {
|
||||
buf = Buffer.from(buf, enc);
|
||||
}
|
||||
if (this[_ended]) {
|
||||
this.emit('error', new Error('write() after end()'));
|
||||
return false;
|
||||
}
|
||||
if (this[_fd] === undefined || this[_writing] || this[_queue].length) {
|
||||
this[_queue].push(buf);
|
||||
this[_needDrain] = true;
|
||||
return false;
|
||||
}
|
||||
this[_writing] = true;
|
||||
this[_write](buf);
|
||||
return true;
|
||||
}
|
||||
[_write](buf) {
|
||||
fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => this[_onwrite](er, bw));
|
||||
}
|
||||
[_onwrite](er, bw) {
|
||||
if (er) {
|
||||
this[_onerror](er);
|
||||
}
|
||||
else {
|
||||
if (this[_pos] !== undefined && typeof bw === 'number') {
|
||||
this[_pos] += bw;
|
||||
}
|
||||
if (this[_queue].length) {
|
||||
this[_flush]();
|
||||
}
|
||||
else {
|
||||
this[_writing] = false;
|
||||
if (this[_ended] && !this[_finished]) {
|
||||
this[_finished] = true;
|
||||
this[_close]();
|
||||
this.emit('finish');
|
||||
}
|
||||
else if (this[_needDrain]) {
|
||||
this[_needDrain] = false;
|
||||
this.emit('drain');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[_flush]() {
|
||||
if (this[_queue].length === 0) {
|
||||
if (this[_ended]) {
|
||||
this[_onwrite](null, 0);
|
||||
}
|
||||
}
|
||||
else if (this[_queue].length === 1) {
|
||||
this[_write](this[_queue].pop());
|
||||
}
|
||||
else {
|
||||
const iovec = this[_queue];
|
||||
this[_queue] = [];
|
||||
writev(this[_fd], iovec, this[_pos], (er, bw) => this[_onwrite](er, bw));
|
||||
}
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs.close(fd, er => er ? this.emit('error', er) : this.emit('close'));
|
||||
}
|
||||
}
|
||||
}
|
||||
export class WriteStreamSync extends WriteStream {
|
||||
[_open]() {
|
||||
let fd;
|
||||
// only wrap in a try{} block if we know we'll retry, to avoid
|
||||
// the rethrow obscuring the error's source frame in most cases.
|
||||
if (this[_defaultFlag] && this[_flags] === 'r+') {
|
||||
try {
|
||||
fd = fs.openSync(this[_path], this[_flags], this[_mode]);
|
||||
}
|
||||
catch (er) {
|
||||
if (er?.code === 'ENOENT') {
|
||||
this[_flags] = 'w';
|
||||
return this[_open]();
|
||||
}
|
||||
else {
|
||||
throw er;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
fd = fs.openSync(this[_path], this[_flags], this[_mode]);
|
||||
}
|
||||
this[_onopen](null, fd);
|
||||
}
|
||||
[_close]() {
|
||||
if (this[_autoClose] && typeof this[_fd] === 'number') {
|
||||
const fd = this[_fd];
|
||||
this[_fd] = undefined;
|
||||
fs.closeSync(fd);
|
||||
this.emit('close');
|
||||
}
|
||||
}
|
||||
[_write](buf) {
|
||||
// throw the original, but try to close if it fails
|
||||
let threw = true;
|
||||
try {
|
||||
this[_onwrite](null, fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos]));
|
||||
threw = false;
|
||||
}
|
||||
finally {
|
||||
if (threw) {
|
||||
try {
|
||||
this[_close]();
|
||||
}
|
||||
catch {
|
||||
// ok error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "@isaacs/fs-minipass",
|
||||
"version": "4.0.1",
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"scripts": {
|
||||
"prepare": "tshy",
|
||||
"pretest": "npm run prepare",
|
||||
"test": "tap",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"prepublishOnly": "git push origin --follow-tags",
|
||||
"format": "prettier --write . --loglevel warn",
|
||||
"typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Isaac Z. Schlueter",
|
||||
"license": "ISC",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/npm/fs-minipass.git"
|
||||
},
|
||||
"description": "fs read and write streams based on minipass",
|
||||
"dependencies": {
|
||||
"minipass": "^7.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.30",
|
||||
"mutate-fs": "^2.1.1",
|
||||
"prettier": "^3.2.5",
|
||||
"tap": "^18.7.1",
|
||||
"tshy": "^1.12.0",
|
||||
"typedoc": "^0.25.12"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"tshy": {
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts"
|
||||
}
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"type": "module",
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"printWidth": 75,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": false,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "avoid",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018-2024 Jukka Kurkela
|
||||
|
||||
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.
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
# @kurkle/color
|
||||
|
||||
[](https://www.npmjs.com/package/@kurkle/color) [](https://github.com/kurkle/color/releases/latest) [](https://www.npmjs.com/package/@kurkle/color) [](https://github.com/kurkle/color) [](https://github.com/kurkle/color/blob/main/LICENSE.md)
|
||||
|
||||
## Overview
|
||||
|
||||
Fast and small CSS color parsing and manipulation library.
|
||||
|
||||
## Parsing
|
||||
|
||||
Supported formats:
|
||||
|
||||
- named
|
||||
|
||||
```text
|
||||
blue
|
||||
transparent
|
||||
```
|
||||
|
||||
- hex
|
||||
|
||||
```text
|
||||
#aaa
|
||||
#bbba
|
||||
#1A2b3c
|
||||
#f1f2f388
|
||||
```
|
||||
|
||||
- rgb(a)
|
||||
|
||||
```text
|
||||
rgb(255, 255, 255)
|
||||
rgb(255, 0, 0, 0.5)
|
||||
rgb(50%, 50%, 50%, 50%)
|
||||
rgb(0 0 100% / 80%)
|
||||
rgba(200, 20, 233, 0.2)
|
||||
rgba(200, 20, 233, 2e-1)
|
||||
```
|
||||
|
||||
- hsl(a)
|
||||
|
||||
```text
|
||||
hsl(240deg, 100%, 50.5%)
|
||||
hsl(0deg 100% 50%)
|
||||
hsla(12, 10%, 50%, .3)
|
||||
hsla(-1.2, 10.2%, 50.9%, 0.4)
|
||||
```
|
||||
|
||||
- hwb
|
||||
|
||||
```text
|
||||
hwb(240, 100%, 50.5%)
|
||||
hwb(244, 100%, 100%, 0.6)
|
||||
```
|
||||
|
||||
- hsv
|
||||
|
||||
```text
|
||||
hsv(240, 100%, 50.5%)
|
||||
hsv(244, 100%, 100%, 0.6)
|
||||
```
|
||||
|
||||
## Docs
|
||||
|
||||
[typedocs](https://kurkle.github.io/color/)
|
||||
|
||||
**note** The docs are for the ESM module. UMD module only exports the [default export](https://kurkle.github.io/color/modules.html#default)
|
||||
|
||||
## Benchmarks
|
||||
|
||||
[benchmarks](https://kurkle.github.io/color/dev/bench/)
|
||||
|
||||
## Size visualization
|
||||
|
||||
[color.min.js](https://kurkle.github.io/color/stats.html)
|
||||
|
||||
## License
|
||||
|
||||
`@kurkle/color` is available under the [MIT license](https://github.com/kurkle/color/blob/main/LICENSE.md).
|
||||
+624
@@ -0,0 +1,624 @@
|
||||
/*!
|
||||
* @kurkle/color v0.3.4
|
||||
* https://github.com/kurkle/color#readme
|
||||
* (c) 2024 Jukka Kurkela
|
||||
* Released under the MIT License
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global["@kurkle/color"] = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
|
||||
function round(v) {
|
||||
return v + 0.5 | 0;
|
||||
}
|
||||
const lim = (v, l, h) => Math.max(Math.min(v, h), l);
|
||||
function p2b(v) {
|
||||
return lim(round(v * 2.55), 0, 255);
|
||||
}
|
||||
function b2p(v) {
|
||||
return lim(round(v / 2.55), 0, 100);
|
||||
}
|
||||
function n2b(v) {
|
||||
return lim(round(v * 255), 0, 255);
|
||||
}
|
||||
function b2n(v) {
|
||||
return lim(round(v / 2.55) / 100, 0, 1);
|
||||
}
|
||||
function n2p(v) {
|
||||
return lim(round(v * 100), 0, 100);
|
||||
}
|
||||
|
||||
const map$1 = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15};
|
||||
const hex = [...'0123456789ABCDEF'];
|
||||
const h1 = b => hex[b & 0xF];
|
||||
const h2 = b => hex[(b & 0xF0) >> 4] + hex[b & 0xF];
|
||||
const eq = b => ((b & 0xF0) >> 4) === (b & 0xF);
|
||||
const isShort = v => eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
|
||||
function hexParse(str) {
|
||||
var len = str.length;
|
||||
var ret;
|
||||
if (str[0] === '#') {
|
||||
if (len === 4 || len === 5) {
|
||||
ret = {
|
||||
r: 255 & map$1[str[1]] * 17,
|
||||
g: 255 & map$1[str[2]] * 17,
|
||||
b: 255 & map$1[str[3]] * 17,
|
||||
a: len === 5 ? map$1[str[4]] * 17 : 255
|
||||
};
|
||||
} else if (len === 7 || len === 9) {
|
||||
ret = {
|
||||
r: map$1[str[1]] << 4 | map$1[str[2]],
|
||||
g: map$1[str[3]] << 4 | map$1[str[4]],
|
||||
b: map$1[str[5]] << 4 | map$1[str[6]],
|
||||
a: len === 9 ? (map$1[str[7]] << 4 | map$1[str[8]]) : 255
|
||||
};
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const alpha = (a, f) => a < 255 ? f(a) : '';
|
||||
function hexString(v) {
|
||||
var f = isShort(v) ? h1 : h2;
|
||||
return v
|
||||
? '#' + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
|
||||
function hsl2rgbn(h, s, l) {
|
||||
const a = s * Math.min(l, 1 - l);
|
||||
const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
return [f(0), f(8), f(4)];
|
||||
}
|
||||
function hsv2rgbn(h, s, v) {
|
||||
const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
|
||||
return [f(5), f(3), f(1)];
|
||||
}
|
||||
function hwb2rgbn(h, w, b) {
|
||||
const rgb = hsl2rgbn(h, 1, 0.5);
|
||||
let i;
|
||||
if (w + b > 1) {
|
||||
i = 1 / (w + b);
|
||||
w *= i;
|
||||
b *= i;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
rgb[i] *= 1 - w - b;
|
||||
rgb[i] += w;
|
||||
}
|
||||
return rgb;
|
||||
}
|
||||
function hueValue(r, g, b, d, max) {
|
||||
if (r === max) {
|
||||
return ((g - b) / d) + (g < b ? 6 : 0);
|
||||
}
|
||||
if (g === max) {
|
||||
return (b - r) / d + 2;
|
||||
}
|
||||
return (r - g) / d + 4;
|
||||
}
|
||||
function rgb2hsl(v) {
|
||||
const range = 255;
|
||||
const r = v.r / range;
|
||||
const g = v.g / range;
|
||||
const b = v.b / range;
|
||||
const max = Math.max(r, g, b);
|
||||
const min = Math.min(r, g, b);
|
||||
const l = (max + min) / 2;
|
||||
let h, s, d;
|
||||
if (max !== min) {
|
||||
d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
h = hueValue(r, g, b, d, max);
|
||||
h = h * 60 + 0.5;
|
||||
}
|
||||
return [h | 0, s || 0, l];
|
||||
}
|
||||
function calln(f, a, b, c) {
|
||||
return (
|
||||
Array.isArray(a)
|
||||
? f(a[0], a[1], a[2])
|
||||
: f(a, b, c)
|
||||
).map(n2b);
|
||||
}
|
||||
function hsl2rgb(h, s, l) {
|
||||
return calln(hsl2rgbn, h, s, l);
|
||||
}
|
||||
function hwb2rgb(h, w, b) {
|
||||
return calln(hwb2rgbn, h, w, b);
|
||||
}
|
||||
function hsv2rgb(h, s, v) {
|
||||
return calln(hsv2rgbn, h, s, v);
|
||||
}
|
||||
function hue(h) {
|
||||
return (h % 360 + 360) % 360;
|
||||
}
|
||||
function hueParse(str) {
|
||||
const m = HUE_RE.exec(str);
|
||||
let a = 255;
|
||||
let v;
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
if (m[5] !== v) {
|
||||
a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
|
||||
}
|
||||
const h = hue(+m[2]);
|
||||
const p1 = +m[3] / 100;
|
||||
const p2 = +m[4] / 100;
|
||||
if (m[1] === 'hwb') {
|
||||
v = hwb2rgb(h, p1, p2);
|
||||
} else if (m[1] === 'hsv') {
|
||||
v = hsv2rgb(h, p1, p2);
|
||||
} else {
|
||||
v = hsl2rgb(h, p1, p2);
|
||||
}
|
||||
return {
|
||||
r: v[0],
|
||||
g: v[1],
|
||||
b: v[2],
|
||||
a: a
|
||||
};
|
||||
}
|
||||
function rotate(v, deg) {
|
||||
var h = rgb2hsl(v);
|
||||
h[0] = hue(h[0] + deg);
|
||||
h = hsl2rgb(h);
|
||||
v.r = h[0];
|
||||
v.g = h[1];
|
||||
v.b = h[2];
|
||||
}
|
||||
function hslString(v) {
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
const a = rgb2hsl(v);
|
||||
const h = a[0];
|
||||
const s = n2p(a[1]);
|
||||
const l = n2p(a[2]);
|
||||
return v.a < 255
|
||||
? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`
|
||||
: `hsl(${h}, ${s}%, ${l}%)`;
|
||||
}
|
||||
|
||||
const map = {
|
||||
x: 'dark',
|
||||
Z: 'light',
|
||||
Y: 're',
|
||||
X: 'blu',
|
||||
W: 'gr',
|
||||
V: 'medium',
|
||||
U: 'slate',
|
||||
A: 'ee',
|
||||
T: 'ol',
|
||||
S: 'or',
|
||||
B: 'ra',
|
||||
C: 'lateg',
|
||||
D: 'ights',
|
||||
R: 'in',
|
||||
Q: 'turquois',
|
||||
E: 'hi',
|
||||
P: 'ro',
|
||||
O: 'al',
|
||||
N: 'le',
|
||||
M: 'de',
|
||||
L: 'yello',
|
||||
F: 'en',
|
||||
K: 'ch',
|
||||
G: 'arks',
|
||||
H: 'ea',
|
||||
I: 'ightg',
|
||||
J: 'wh'
|
||||
};
|
||||
const names$1 = {
|
||||
OiceXe: 'f0f8ff',
|
||||
antiquewEte: 'faebd7',
|
||||
aqua: 'ffff',
|
||||
aquamarRe: '7fffd4',
|
||||
azuY: 'f0ffff',
|
||||
beige: 'f5f5dc',
|
||||
bisque: 'ffe4c4',
|
||||
black: '0',
|
||||
blanKedOmond: 'ffebcd',
|
||||
Xe: 'ff',
|
||||
XeviTet: '8a2be2',
|
||||
bPwn: 'a52a2a',
|
||||
burlywood: 'deb887',
|
||||
caMtXe: '5f9ea0',
|
||||
KartYuse: '7fff00',
|
||||
KocTate: 'd2691e',
|
||||
cSO: 'ff7f50',
|
||||
cSnflowerXe: '6495ed',
|
||||
cSnsilk: 'fff8dc',
|
||||
crimson: 'dc143c',
|
||||
cyan: 'ffff',
|
||||
xXe: '8b',
|
||||
xcyan: '8b8b',
|
||||
xgTMnPd: 'b8860b',
|
||||
xWay: 'a9a9a9',
|
||||
xgYF: '6400',
|
||||
xgYy: 'a9a9a9',
|
||||
xkhaki: 'bdb76b',
|
||||
xmagFta: '8b008b',
|
||||
xTivegYF: '556b2f',
|
||||
xSange: 'ff8c00',
|
||||
xScEd: '9932cc',
|
||||
xYd: '8b0000',
|
||||
xsOmon: 'e9967a',
|
||||
xsHgYF: '8fbc8f',
|
||||
xUXe: '483d8b',
|
||||
xUWay: '2f4f4f',
|
||||
xUgYy: '2f4f4f',
|
||||
xQe: 'ced1',
|
||||
xviTet: '9400d3',
|
||||
dAppRk: 'ff1493',
|
||||
dApskyXe: 'bfff',
|
||||
dimWay: '696969',
|
||||
dimgYy: '696969',
|
||||
dodgerXe: '1e90ff',
|
||||
fiYbrick: 'b22222',
|
||||
flSOwEte: 'fffaf0',
|
||||
foYstWAn: '228b22',
|
||||
fuKsia: 'ff00ff',
|
||||
gaRsbSo: 'dcdcdc',
|
||||
ghostwEte: 'f8f8ff',
|
||||
gTd: 'ffd700',
|
||||
gTMnPd: 'daa520',
|
||||
Way: '808080',
|
||||
gYF: '8000',
|
||||
gYFLw: 'adff2f',
|
||||
gYy: '808080',
|
||||
honeyMw: 'f0fff0',
|
||||
hotpRk: 'ff69b4',
|
||||
RdianYd: 'cd5c5c',
|
||||
Rdigo: '4b0082',
|
||||
ivSy: 'fffff0',
|
||||
khaki: 'f0e68c',
|
||||
lavFMr: 'e6e6fa',
|
||||
lavFMrXsh: 'fff0f5',
|
||||
lawngYF: '7cfc00',
|
||||
NmoncEffon: 'fffacd',
|
||||
ZXe: 'add8e6',
|
||||
ZcSO: 'f08080',
|
||||
Zcyan: 'e0ffff',
|
||||
ZgTMnPdLw: 'fafad2',
|
||||
ZWay: 'd3d3d3',
|
||||
ZgYF: '90ee90',
|
||||
ZgYy: 'd3d3d3',
|
||||
ZpRk: 'ffb6c1',
|
||||
ZsOmon: 'ffa07a',
|
||||
ZsHgYF: '20b2aa',
|
||||
ZskyXe: '87cefa',
|
||||
ZUWay: '778899',
|
||||
ZUgYy: '778899',
|
||||
ZstAlXe: 'b0c4de',
|
||||
ZLw: 'ffffe0',
|
||||
lime: 'ff00',
|
||||
limegYF: '32cd32',
|
||||
lRF: 'faf0e6',
|
||||
magFta: 'ff00ff',
|
||||
maPon: '800000',
|
||||
VaquamarRe: '66cdaa',
|
||||
VXe: 'cd',
|
||||
VScEd: 'ba55d3',
|
||||
VpurpN: '9370db',
|
||||
VsHgYF: '3cb371',
|
||||
VUXe: '7b68ee',
|
||||
VsprRggYF: 'fa9a',
|
||||
VQe: '48d1cc',
|
||||
VviTetYd: 'c71585',
|
||||
midnightXe: '191970',
|
||||
mRtcYam: 'f5fffa',
|
||||
mistyPse: 'ffe4e1',
|
||||
moccasR: 'ffe4b5',
|
||||
navajowEte: 'ffdead',
|
||||
navy: '80',
|
||||
Tdlace: 'fdf5e6',
|
||||
Tive: '808000',
|
||||
TivedBb: '6b8e23',
|
||||
Sange: 'ffa500',
|
||||
SangeYd: 'ff4500',
|
||||
ScEd: 'da70d6',
|
||||
pOegTMnPd: 'eee8aa',
|
||||
pOegYF: '98fb98',
|
||||
pOeQe: 'afeeee',
|
||||
pOeviTetYd: 'db7093',
|
||||
papayawEp: 'ffefd5',
|
||||
pHKpuff: 'ffdab9',
|
||||
peru: 'cd853f',
|
||||
pRk: 'ffc0cb',
|
||||
plum: 'dda0dd',
|
||||
powMrXe: 'b0e0e6',
|
||||
purpN: '800080',
|
||||
YbeccapurpN: '663399',
|
||||
Yd: 'ff0000',
|
||||
Psybrown: 'bc8f8f',
|
||||
PyOXe: '4169e1',
|
||||
saddNbPwn: '8b4513',
|
||||
sOmon: 'fa8072',
|
||||
sandybPwn: 'f4a460',
|
||||
sHgYF: '2e8b57',
|
||||
sHshell: 'fff5ee',
|
||||
siFna: 'a0522d',
|
||||
silver: 'c0c0c0',
|
||||
skyXe: '87ceeb',
|
||||
UXe: '6a5acd',
|
||||
UWay: '708090',
|
||||
UgYy: '708090',
|
||||
snow: 'fffafa',
|
||||
sprRggYF: 'ff7f',
|
||||
stAlXe: '4682b4',
|
||||
tan: 'd2b48c',
|
||||
teO: '8080',
|
||||
tEstN: 'd8bfd8',
|
||||
tomato: 'ff6347',
|
||||
Qe: '40e0d0',
|
||||
viTet: 'ee82ee',
|
||||
JHt: 'f5deb3',
|
||||
wEte: 'ffffff',
|
||||
wEtesmoke: 'f5f5f5',
|
||||
Lw: 'ffff00',
|
||||
LwgYF: '9acd32'
|
||||
};
|
||||
function unpack() {
|
||||
const unpacked = {};
|
||||
const keys = Object.keys(names$1);
|
||||
const tkeys = Object.keys(map);
|
||||
let i, j, k, ok, nk;
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
ok = nk = keys[i];
|
||||
for (j = 0; j < tkeys.length; j++) {
|
||||
k = tkeys[j];
|
||||
nk = nk.replace(k, map[k]);
|
||||
}
|
||||
k = parseInt(names$1[ok], 16);
|
||||
unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];
|
||||
}
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
let names;
|
||||
function nameParse(str) {
|
||||
if (!names) {
|
||||
names = unpack();
|
||||
names.transparent = [0, 0, 0, 0];
|
||||
}
|
||||
const a = names[str.toLowerCase()];
|
||||
return a && {
|
||||
r: a[0],
|
||||
g: a[1],
|
||||
b: a[2],
|
||||
a: a.length === 4 ? a[3] : 255
|
||||
};
|
||||
}
|
||||
|
||||
const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
|
||||
function rgbParse(str) {
|
||||
const m = RGB_RE.exec(str);
|
||||
let a = 255;
|
||||
let r, g, b;
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
if (m[7] !== r) {
|
||||
const v = +m[7];
|
||||
a = m[8] ? p2b(v) : lim(v * 255, 0, 255);
|
||||
}
|
||||
r = +m[1];
|
||||
g = +m[3];
|
||||
b = +m[5];
|
||||
r = 255 & (m[2] ? p2b(r) : lim(r, 0, 255));
|
||||
g = 255 & (m[4] ? p2b(g) : lim(g, 0, 255));
|
||||
b = 255 & (m[6] ? p2b(b) : lim(b, 0, 255));
|
||||
return {
|
||||
r: r,
|
||||
g: g,
|
||||
b: b,
|
||||
a: a
|
||||
};
|
||||
}
|
||||
function rgbString(v) {
|
||||
return v && (
|
||||
v.a < 255
|
||||
? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`
|
||||
: `rgb(${v.r}, ${v.g}, ${v.b})`
|
||||
);
|
||||
}
|
||||
|
||||
const to = v => v <= 0.0031308 ? v * 12.92 : Math.pow(v, 1.0 / 2.4) * 1.055 - 0.055;
|
||||
const from = v => v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
|
||||
function interpolate(rgb1, rgb2, t) {
|
||||
const r = from(b2n(rgb1.r));
|
||||
const g = from(b2n(rgb1.g));
|
||||
const b = from(b2n(rgb1.b));
|
||||
return {
|
||||
r: n2b(to(r + t * (from(b2n(rgb2.r)) - r))),
|
||||
g: n2b(to(g + t * (from(b2n(rgb2.g)) - g))),
|
||||
b: n2b(to(b + t * (from(b2n(rgb2.b)) - b))),
|
||||
a: rgb1.a + t * (rgb2.a - rgb1.a)
|
||||
};
|
||||
}
|
||||
|
||||
function modHSL(v, i, ratio) {
|
||||
if (v) {
|
||||
let tmp = rgb2hsl(v);
|
||||
tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));
|
||||
tmp = hsl2rgb(tmp);
|
||||
v.r = tmp[0];
|
||||
v.g = tmp[1];
|
||||
v.b = tmp[2];
|
||||
}
|
||||
}
|
||||
function clone(v, proto) {
|
||||
return v ? Object.assign(proto || {}, v) : v;
|
||||
}
|
||||
function fromObject(input) {
|
||||
var v = {r: 0, g: 0, b: 0, a: 255};
|
||||
if (Array.isArray(input)) {
|
||||
if (input.length >= 3) {
|
||||
v = {r: input[0], g: input[1], b: input[2], a: 255};
|
||||
if (input.length > 3) {
|
||||
v.a = n2b(input[3]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v = clone(input, {r: 0, g: 0, b: 0, a: 1});
|
||||
v.a = n2b(v.a);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
function functionParse(str) {
|
||||
if (str.charAt(0) === 'r') {
|
||||
return rgbParse(str);
|
||||
}
|
||||
return hueParse(str);
|
||||
}
|
||||
class Color {
|
||||
constructor(input) {
|
||||
if (input instanceof Color) {
|
||||
return input;
|
||||
}
|
||||
const type = typeof input;
|
||||
let v;
|
||||
if (type === 'object') {
|
||||
v = fromObject(input);
|
||||
} else if (type === 'string') {
|
||||
v = hexParse(input) || nameParse(input) || functionParse(input);
|
||||
}
|
||||
this._rgb = v;
|
||||
this._valid = !!v;
|
||||
}
|
||||
get valid() {
|
||||
return this._valid;
|
||||
}
|
||||
get rgb() {
|
||||
var v = clone(this._rgb);
|
||||
if (v) {
|
||||
v.a = b2n(v.a);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
set rgb(obj) {
|
||||
this._rgb = fromObject(obj);
|
||||
}
|
||||
rgbString() {
|
||||
return this._valid ? rgbString(this._rgb) : undefined;
|
||||
}
|
||||
hexString() {
|
||||
return this._valid ? hexString(this._rgb) : undefined;
|
||||
}
|
||||
hslString() {
|
||||
return this._valid ? hslString(this._rgb) : undefined;
|
||||
}
|
||||
mix(color, weight) {
|
||||
if (color) {
|
||||
const c1 = this.rgb;
|
||||
const c2 = color.rgb;
|
||||
let w2;
|
||||
const p = weight === w2 ? 0.5 : weight;
|
||||
const w = 2 * p - 1;
|
||||
const a = c1.a - c2.a;
|
||||
const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
|
||||
w2 = 1 - w1;
|
||||
c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;
|
||||
c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;
|
||||
c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;
|
||||
c1.a = p * c1.a + (1 - p) * c2.a;
|
||||
this.rgb = c1;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
interpolate(color, t) {
|
||||
if (color) {
|
||||
this._rgb = interpolate(this._rgb, color._rgb, t);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
clone() {
|
||||
return new Color(this.rgb);
|
||||
}
|
||||
alpha(a) {
|
||||
this._rgb.a = n2b(a);
|
||||
return this;
|
||||
}
|
||||
clearer(ratio) {
|
||||
const rgb = this._rgb;
|
||||
rgb.a *= 1 - ratio;
|
||||
return this;
|
||||
}
|
||||
greyscale() {
|
||||
const rgb = this._rgb;
|
||||
const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
|
||||
rgb.r = rgb.g = rgb.b = val;
|
||||
return this;
|
||||
}
|
||||
opaquer(ratio) {
|
||||
const rgb = this._rgb;
|
||||
rgb.a *= 1 + ratio;
|
||||
return this;
|
||||
}
|
||||
negate() {
|
||||
const v = this._rgb;
|
||||
v.r = 255 - v.r;
|
||||
v.g = 255 - v.g;
|
||||
v.b = 255 - v.b;
|
||||
return this;
|
||||
}
|
||||
lighten(ratio) {
|
||||
modHSL(this._rgb, 2, ratio);
|
||||
return this;
|
||||
}
|
||||
darken(ratio) {
|
||||
modHSL(this._rgb, 2, -ratio);
|
||||
return this;
|
||||
}
|
||||
saturate(ratio) {
|
||||
modHSL(this._rgb, 1, ratio);
|
||||
return this;
|
||||
}
|
||||
desaturate(ratio) {
|
||||
modHSL(this._rgb, 1, -ratio);
|
||||
return this;
|
||||
}
|
||||
rotate(deg) {
|
||||
rotate(this._rgb, deg);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
function index_esm(input) {
|
||||
return new Color(input);
|
||||
}
|
||||
|
||||
var color = /*#__PURE__*/Object.freeze({
|
||||
__proto__: null,
|
||||
Color: Color,
|
||||
b2n: b2n,
|
||||
b2p: b2p,
|
||||
default: index_esm,
|
||||
hexParse: hexParse,
|
||||
hexString: hexString,
|
||||
hsl2rgb: hsl2rgb,
|
||||
hslString: hslString,
|
||||
hsv2rgb: hsv2rgb,
|
||||
hueParse: hueParse,
|
||||
hwb2rgb: hwb2rgb,
|
||||
lim: lim,
|
||||
n2b: n2b,
|
||||
n2p: n2p,
|
||||
nameParse: nameParse,
|
||||
p2b: p2b,
|
||||
rgb2hsl: rgb2hsl,
|
||||
rgbParse: rgbParse,
|
||||
rgbString: rgbString,
|
||||
rotate: rotate,
|
||||
round: round
|
||||
});
|
||||
|
||||
var index = Object.assign(index_esm, color);
|
||||
|
||||
return index;
|
||||
|
||||
}));
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* @packageDocumentation
|
||||
* @module @kurkle/color
|
||||
*/
|
||||
export type RGBA = {
|
||||
/**
|
||||
* - red [0..255]
|
||||
*/
|
||||
r: number;
|
||||
/**
|
||||
* - green [0..255]
|
||||
*/
|
||||
g: number;
|
||||
/**
|
||||
* - blue [0..255]
|
||||
*/
|
||||
b: number;
|
||||
/**
|
||||
* - alpha [0..1]
|
||||
*/
|
||||
a: number;
|
||||
};
|
||||
/**
|
||||
* Parse HEX to color
|
||||
* @param {string} str - the string
|
||||
*/
|
||||
export function hexParse(str: string): {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
a: number;
|
||||
};
|
||||
/**
|
||||
* Return HEX string from color
|
||||
* @param {RGBA} v - the color
|
||||
*/
|
||||
export function hexString(v: RGBA): string | RGBA;
|
||||
/**
|
||||
* Rounds decimal to nearest integer
|
||||
* @param {number} v - the number to round
|
||||
*/
|
||||
export function round(v: number): number;
|
||||
/**
|
||||
* convert percent to byte 0..255
|
||||
* @param {number} v - 0..100
|
||||
*/
|
||||
export function p2b(v: number): number;
|
||||
/**
|
||||
* convert byte to percet 0..100
|
||||
* @param {number} v - 0..255
|
||||
*/
|
||||
export function b2p(v: number): number;
|
||||
/**
|
||||
* convert normalized to byte 0..255
|
||||
* @param {number} v - 0..1
|
||||
*/
|
||||
export function n2b(v: number): number;
|
||||
/**
|
||||
* convert byte to normalized 0..1
|
||||
* @param {number} v - 0..255
|
||||
*/
|
||||
export function b2n(v: number): number;
|
||||
/**
|
||||
* convert normalized to percent 0..100
|
||||
* @param {number} v - 0..1
|
||||
*/
|
||||
export function n2p(v: number): number;
|
||||
/**
|
||||
* Convert rgb to hsl
|
||||
* @param {RGBA} v - the color
|
||||
* @returns {number[]} - [h, s, l]
|
||||
*/
|
||||
export function rgb2hsl(v: RGBA): number[];
|
||||
/**
|
||||
* Convert hsl to rgb
|
||||
* @param {number|number[]} h - hue | [h, s, l]
|
||||
* @param {number} [s] - saturation
|
||||
* @param {number} [l] - lightness
|
||||
* @returns {number[]}
|
||||
*/
|
||||
export function hsl2rgb(h: number | number[], s?: number, l?: number): number[];
|
||||
/**
|
||||
* Convert hwb to rgb
|
||||
* @param {number|number[]} h - hue | [h, s, l]
|
||||
* @param {number} [w] - whiteness
|
||||
* @param {number} [b] - blackness
|
||||
* @returns {number[]}
|
||||
*/
|
||||
export function hwb2rgb(h: number | number[], w?: number, b?: number): number[];
|
||||
/**
|
||||
* Convert hsv to rgb
|
||||
* @param {number|number[]} h - hue | [h, s, l]
|
||||
* @param {number} [s] - saturation
|
||||
* @param {number} [v] - value
|
||||
* @returns {number[]}
|
||||
*/
|
||||
export function hsv2rgb(h: number | number[], s?: number, v?: number): number[];
|
||||
/**
|
||||
* Parse hsl/hsv/hwb color string
|
||||
* @param {string} str - hsl/hsv/hwb color string
|
||||
* @returns {RGBA} - the parsed color components
|
||||
*/
|
||||
export function hueParse(str: string): RGBA;
|
||||
/**
|
||||
* Rotate the `v` color by `deg` degrees
|
||||
* @param {RGBA} v - the color
|
||||
* @param {number} deg - degrees to rotate
|
||||
*/
|
||||
export function rotate(v: RGBA, deg: number): void;
|
||||
/**
|
||||
* Return hsl(a) string from color components
|
||||
* @param {RGBA} v - the color
|
||||
* @return {string|undefined}
|
||||
*/
|
||||
export function hslString(v: RGBA): string;
|
||||
/**
|
||||
* Parse color name
|
||||
* @param {string} str - the color name
|
||||
* @return {RGBA} - the color
|
||||
*/
|
||||
export function nameParse(str: string): RGBA;
|
||||
/**
|
||||
* Parse rgb(a) string to RGBA
|
||||
* @param {string} str - the rgb string
|
||||
* @returns {RGBA} - the parsed color
|
||||
*/
|
||||
export function rgbParse(str: string): RGBA;
|
||||
/**
|
||||
* Return rgb(a) string from color
|
||||
* @param {RGBA} v - the color
|
||||
*/
|
||||
export function rgbString(v: RGBA): string;
|
||||
|
||||
export class Color {
|
||||
/**
|
||||
* constructor
|
||||
* @param {Color|RGBA|string|number[]} input
|
||||
*/
|
||||
constructor(input: string | number[] | Color | RGBA);
|
||||
/**
|
||||
* @type {RGBA}
|
||||
* @hidden
|
||||
**/
|
||||
_rgb: RGBA;
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @hidden
|
||||
**/
|
||||
_valid: boolean;
|
||||
/**
|
||||
* `true` if this is a valid color
|
||||
* @returns {boolean}
|
||||
*/
|
||||
get valid(): boolean;
|
||||
/**
|
||||
* @param {RGBA} obj - the color
|
||||
*/
|
||||
set rgb(arg: RGBA);
|
||||
/**
|
||||
* @returns {RGBA} - the color
|
||||
*/
|
||||
get rgb(): RGBA;
|
||||
/**
|
||||
* rgb(a) string
|
||||
*/
|
||||
rgbString(): string;
|
||||
/**
|
||||
* hex string
|
||||
*/
|
||||
hexString(): string;
|
||||
/**
|
||||
* hsl(a) string
|
||||
*/
|
||||
hslString(): string;
|
||||
/**
|
||||
* Mix another color to this color.
|
||||
* @param {Color} color - Color to mix in
|
||||
* @param {number} weight - 0..1
|
||||
*/
|
||||
mix(color: Color, weight: number): Color;
|
||||
/**
|
||||
* Clone
|
||||
*/
|
||||
clone(): Color;
|
||||
/**
|
||||
* Set aplha
|
||||
* @param {number} a - the alpha [0..1]
|
||||
*/
|
||||
alpha(a: number): Color;
|
||||
/**
|
||||
* Make clearer
|
||||
* @param {number} ratio - ratio [0..1]
|
||||
*/
|
||||
clearer(ratio: number): Color;
|
||||
/**
|
||||
* Convert to grayscale
|
||||
*/
|
||||
greyscale(): Color;
|
||||
/**
|
||||
* Opaquer
|
||||
* @param {number} ratio - ratio [0..1]
|
||||
*/
|
||||
opaquer(ratio: number): Color;
|
||||
negate(): Color;
|
||||
/**
|
||||
* Lighten
|
||||
* @param {number} ratio - ratio [0..1]
|
||||
*/
|
||||
lighten(ratio: number): Color;
|
||||
/**
|
||||
* Darken
|
||||
* @param {number} ratio - ratio [0..1]
|
||||
*/
|
||||
darken(ratio: number): Color;
|
||||
/**
|
||||
* Saturate
|
||||
* @param {number} ratio - ratio [0..1]
|
||||
*/
|
||||
saturate(ratio: number): Color;
|
||||
/**
|
||||
* Desaturate
|
||||
* @param {number} ratio - ratio [0..1]
|
||||
*/
|
||||
desaturate(ratio: number): Color;
|
||||
/**
|
||||
* Rotate
|
||||
* @param {number} deg - degrees to rotate
|
||||
*/
|
||||
rotate(deg: number): Color;
|
||||
}
|
||||
/**
|
||||
* Construct new Color instance
|
||||
* @param {Color|RGBA|string|number[]} input
|
||||
*/
|
||||
export default function _default(input: string | number[] | Color | RGBA): Color;
|
||||
+589
@@ -0,0 +1,589 @@
|
||||
/*!
|
||||
* @kurkle/color v0.3.4
|
||||
* https://github.com/kurkle/color#readme
|
||||
* (c) 2024 Jukka Kurkela
|
||||
* Released under the MIT License
|
||||
*/
|
||||
function round(v) {
|
||||
return v + 0.5 | 0;
|
||||
}
|
||||
const lim = (v, l, h) => Math.max(Math.min(v, h), l);
|
||||
function p2b(v) {
|
||||
return lim(round(v * 2.55), 0, 255);
|
||||
}
|
||||
function b2p(v) {
|
||||
return lim(round(v / 2.55), 0, 100);
|
||||
}
|
||||
function n2b(v) {
|
||||
return lim(round(v * 255), 0, 255);
|
||||
}
|
||||
function b2n(v) {
|
||||
return lim(round(v / 2.55) / 100, 0, 1);
|
||||
}
|
||||
function n2p(v) {
|
||||
return lim(round(v * 100), 0, 100);
|
||||
}
|
||||
|
||||
const map$1 = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15};
|
||||
const hex = [...'0123456789ABCDEF'];
|
||||
const h1 = b => hex[b & 0xF];
|
||||
const h2 = b => hex[(b & 0xF0) >> 4] + hex[b & 0xF];
|
||||
const eq = b => ((b & 0xF0) >> 4) === (b & 0xF);
|
||||
const isShort = v => eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
|
||||
function hexParse(str) {
|
||||
var len = str.length;
|
||||
var ret;
|
||||
if (str[0] === '#') {
|
||||
if (len === 4 || len === 5) {
|
||||
ret = {
|
||||
r: 255 & map$1[str[1]] * 17,
|
||||
g: 255 & map$1[str[2]] * 17,
|
||||
b: 255 & map$1[str[3]] * 17,
|
||||
a: len === 5 ? map$1[str[4]] * 17 : 255
|
||||
};
|
||||
} else if (len === 7 || len === 9) {
|
||||
ret = {
|
||||
r: map$1[str[1]] << 4 | map$1[str[2]],
|
||||
g: map$1[str[3]] << 4 | map$1[str[4]],
|
||||
b: map$1[str[5]] << 4 | map$1[str[6]],
|
||||
a: len === 9 ? (map$1[str[7]] << 4 | map$1[str[8]]) : 255
|
||||
};
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const alpha = (a, f) => a < 255 ? f(a) : '';
|
||||
function hexString(v) {
|
||||
var f = isShort(v) ? h1 : h2;
|
||||
return v
|
||||
? '#' + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
|
||||
function hsl2rgbn(h, s, l) {
|
||||
const a = s * Math.min(l, 1 - l);
|
||||
const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
return [f(0), f(8), f(4)];
|
||||
}
|
||||
function hsv2rgbn(h, s, v) {
|
||||
const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
|
||||
return [f(5), f(3), f(1)];
|
||||
}
|
||||
function hwb2rgbn(h, w, b) {
|
||||
const rgb = hsl2rgbn(h, 1, 0.5);
|
||||
let i;
|
||||
if (w + b > 1) {
|
||||
i = 1 / (w + b);
|
||||
w *= i;
|
||||
b *= i;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
rgb[i] *= 1 - w - b;
|
||||
rgb[i] += w;
|
||||
}
|
||||
return rgb;
|
||||
}
|
||||
function hueValue(r, g, b, d, max) {
|
||||
if (r === max) {
|
||||
return ((g - b) / d) + (g < b ? 6 : 0);
|
||||
}
|
||||
if (g === max) {
|
||||
return (b - r) / d + 2;
|
||||
}
|
||||
return (r - g) / d + 4;
|
||||
}
|
||||
function rgb2hsl(v) {
|
||||
const range = 255;
|
||||
const r = v.r / range;
|
||||
const g = v.g / range;
|
||||
const b = v.b / range;
|
||||
const max = Math.max(r, g, b);
|
||||
const min = Math.min(r, g, b);
|
||||
const l = (max + min) / 2;
|
||||
let h, s, d;
|
||||
if (max !== min) {
|
||||
d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
h = hueValue(r, g, b, d, max);
|
||||
h = h * 60 + 0.5;
|
||||
}
|
||||
return [h | 0, s || 0, l];
|
||||
}
|
||||
function calln(f, a, b, c) {
|
||||
return (
|
||||
Array.isArray(a)
|
||||
? f(a[0], a[1], a[2])
|
||||
: f(a, b, c)
|
||||
).map(n2b);
|
||||
}
|
||||
function hsl2rgb(h, s, l) {
|
||||
return calln(hsl2rgbn, h, s, l);
|
||||
}
|
||||
function hwb2rgb(h, w, b) {
|
||||
return calln(hwb2rgbn, h, w, b);
|
||||
}
|
||||
function hsv2rgb(h, s, v) {
|
||||
return calln(hsv2rgbn, h, s, v);
|
||||
}
|
||||
function hue(h) {
|
||||
return (h % 360 + 360) % 360;
|
||||
}
|
||||
function hueParse(str) {
|
||||
const m = HUE_RE.exec(str);
|
||||
let a = 255;
|
||||
let v;
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
if (m[5] !== v) {
|
||||
a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
|
||||
}
|
||||
const h = hue(+m[2]);
|
||||
const p1 = +m[3] / 100;
|
||||
const p2 = +m[4] / 100;
|
||||
if (m[1] === 'hwb') {
|
||||
v = hwb2rgb(h, p1, p2);
|
||||
} else if (m[1] === 'hsv') {
|
||||
v = hsv2rgb(h, p1, p2);
|
||||
} else {
|
||||
v = hsl2rgb(h, p1, p2);
|
||||
}
|
||||
return {
|
||||
r: v[0],
|
||||
g: v[1],
|
||||
b: v[2],
|
||||
a: a
|
||||
};
|
||||
}
|
||||
function rotate(v, deg) {
|
||||
var h = rgb2hsl(v);
|
||||
h[0] = hue(h[0] + deg);
|
||||
h = hsl2rgb(h);
|
||||
v.r = h[0];
|
||||
v.g = h[1];
|
||||
v.b = h[2];
|
||||
}
|
||||
function hslString(v) {
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
const a = rgb2hsl(v);
|
||||
const h = a[0];
|
||||
const s = n2p(a[1]);
|
||||
const l = n2p(a[2]);
|
||||
return v.a < 255
|
||||
? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`
|
||||
: `hsl(${h}, ${s}%, ${l}%)`;
|
||||
}
|
||||
|
||||
const map = {
|
||||
x: 'dark',
|
||||
Z: 'light',
|
||||
Y: 're',
|
||||
X: 'blu',
|
||||
W: 'gr',
|
||||
V: 'medium',
|
||||
U: 'slate',
|
||||
A: 'ee',
|
||||
T: 'ol',
|
||||
S: 'or',
|
||||
B: 'ra',
|
||||
C: 'lateg',
|
||||
D: 'ights',
|
||||
R: 'in',
|
||||
Q: 'turquois',
|
||||
E: 'hi',
|
||||
P: 'ro',
|
||||
O: 'al',
|
||||
N: 'le',
|
||||
M: 'de',
|
||||
L: 'yello',
|
||||
F: 'en',
|
||||
K: 'ch',
|
||||
G: 'arks',
|
||||
H: 'ea',
|
||||
I: 'ightg',
|
||||
J: 'wh'
|
||||
};
|
||||
const names$1 = {
|
||||
OiceXe: 'f0f8ff',
|
||||
antiquewEte: 'faebd7',
|
||||
aqua: 'ffff',
|
||||
aquamarRe: '7fffd4',
|
||||
azuY: 'f0ffff',
|
||||
beige: 'f5f5dc',
|
||||
bisque: 'ffe4c4',
|
||||
black: '0',
|
||||
blanKedOmond: 'ffebcd',
|
||||
Xe: 'ff',
|
||||
XeviTet: '8a2be2',
|
||||
bPwn: 'a52a2a',
|
||||
burlywood: 'deb887',
|
||||
caMtXe: '5f9ea0',
|
||||
KartYuse: '7fff00',
|
||||
KocTate: 'd2691e',
|
||||
cSO: 'ff7f50',
|
||||
cSnflowerXe: '6495ed',
|
||||
cSnsilk: 'fff8dc',
|
||||
crimson: 'dc143c',
|
||||
cyan: 'ffff',
|
||||
xXe: '8b',
|
||||
xcyan: '8b8b',
|
||||
xgTMnPd: 'b8860b',
|
||||
xWay: 'a9a9a9',
|
||||
xgYF: '6400',
|
||||
xgYy: 'a9a9a9',
|
||||
xkhaki: 'bdb76b',
|
||||
xmagFta: '8b008b',
|
||||
xTivegYF: '556b2f',
|
||||
xSange: 'ff8c00',
|
||||
xScEd: '9932cc',
|
||||
xYd: '8b0000',
|
||||
xsOmon: 'e9967a',
|
||||
xsHgYF: '8fbc8f',
|
||||
xUXe: '483d8b',
|
||||
xUWay: '2f4f4f',
|
||||
xUgYy: '2f4f4f',
|
||||
xQe: 'ced1',
|
||||
xviTet: '9400d3',
|
||||
dAppRk: 'ff1493',
|
||||
dApskyXe: 'bfff',
|
||||
dimWay: '696969',
|
||||
dimgYy: '696969',
|
||||
dodgerXe: '1e90ff',
|
||||
fiYbrick: 'b22222',
|
||||
flSOwEte: 'fffaf0',
|
||||
foYstWAn: '228b22',
|
||||
fuKsia: 'ff00ff',
|
||||
gaRsbSo: 'dcdcdc',
|
||||
ghostwEte: 'f8f8ff',
|
||||
gTd: 'ffd700',
|
||||
gTMnPd: 'daa520',
|
||||
Way: '808080',
|
||||
gYF: '8000',
|
||||
gYFLw: 'adff2f',
|
||||
gYy: '808080',
|
||||
honeyMw: 'f0fff0',
|
||||
hotpRk: 'ff69b4',
|
||||
RdianYd: 'cd5c5c',
|
||||
Rdigo: '4b0082',
|
||||
ivSy: 'fffff0',
|
||||
khaki: 'f0e68c',
|
||||
lavFMr: 'e6e6fa',
|
||||
lavFMrXsh: 'fff0f5',
|
||||
lawngYF: '7cfc00',
|
||||
NmoncEffon: 'fffacd',
|
||||
ZXe: 'add8e6',
|
||||
ZcSO: 'f08080',
|
||||
Zcyan: 'e0ffff',
|
||||
ZgTMnPdLw: 'fafad2',
|
||||
ZWay: 'd3d3d3',
|
||||
ZgYF: '90ee90',
|
||||
ZgYy: 'd3d3d3',
|
||||
ZpRk: 'ffb6c1',
|
||||
ZsOmon: 'ffa07a',
|
||||
ZsHgYF: '20b2aa',
|
||||
ZskyXe: '87cefa',
|
||||
ZUWay: '778899',
|
||||
ZUgYy: '778899',
|
||||
ZstAlXe: 'b0c4de',
|
||||
ZLw: 'ffffe0',
|
||||
lime: 'ff00',
|
||||
limegYF: '32cd32',
|
||||
lRF: 'faf0e6',
|
||||
magFta: 'ff00ff',
|
||||
maPon: '800000',
|
||||
VaquamarRe: '66cdaa',
|
||||
VXe: 'cd',
|
||||
VScEd: 'ba55d3',
|
||||
VpurpN: '9370db',
|
||||
VsHgYF: '3cb371',
|
||||
VUXe: '7b68ee',
|
||||
VsprRggYF: 'fa9a',
|
||||
VQe: '48d1cc',
|
||||
VviTetYd: 'c71585',
|
||||
midnightXe: '191970',
|
||||
mRtcYam: 'f5fffa',
|
||||
mistyPse: 'ffe4e1',
|
||||
moccasR: 'ffe4b5',
|
||||
navajowEte: 'ffdead',
|
||||
navy: '80',
|
||||
Tdlace: 'fdf5e6',
|
||||
Tive: '808000',
|
||||
TivedBb: '6b8e23',
|
||||
Sange: 'ffa500',
|
||||
SangeYd: 'ff4500',
|
||||
ScEd: 'da70d6',
|
||||
pOegTMnPd: 'eee8aa',
|
||||
pOegYF: '98fb98',
|
||||
pOeQe: 'afeeee',
|
||||
pOeviTetYd: 'db7093',
|
||||
papayawEp: 'ffefd5',
|
||||
pHKpuff: 'ffdab9',
|
||||
peru: 'cd853f',
|
||||
pRk: 'ffc0cb',
|
||||
plum: 'dda0dd',
|
||||
powMrXe: 'b0e0e6',
|
||||
purpN: '800080',
|
||||
YbeccapurpN: '663399',
|
||||
Yd: 'ff0000',
|
||||
Psybrown: 'bc8f8f',
|
||||
PyOXe: '4169e1',
|
||||
saddNbPwn: '8b4513',
|
||||
sOmon: 'fa8072',
|
||||
sandybPwn: 'f4a460',
|
||||
sHgYF: '2e8b57',
|
||||
sHshell: 'fff5ee',
|
||||
siFna: 'a0522d',
|
||||
silver: 'c0c0c0',
|
||||
skyXe: '87ceeb',
|
||||
UXe: '6a5acd',
|
||||
UWay: '708090',
|
||||
UgYy: '708090',
|
||||
snow: 'fffafa',
|
||||
sprRggYF: 'ff7f',
|
||||
stAlXe: '4682b4',
|
||||
tan: 'd2b48c',
|
||||
teO: '8080',
|
||||
tEstN: 'd8bfd8',
|
||||
tomato: 'ff6347',
|
||||
Qe: '40e0d0',
|
||||
viTet: 'ee82ee',
|
||||
JHt: 'f5deb3',
|
||||
wEte: 'ffffff',
|
||||
wEtesmoke: 'f5f5f5',
|
||||
Lw: 'ffff00',
|
||||
LwgYF: '9acd32'
|
||||
};
|
||||
function unpack() {
|
||||
const unpacked = {};
|
||||
const keys = Object.keys(names$1);
|
||||
const tkeys = Object.keys(map);
|
||||
let i, j, k, ok, nk;
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
ok = nk = keys[i];
|
||||
for (j = 0; j < tkeys.length; j++) {
|
||||
k = tkeys[j];
|
||||
nk = nk.replace(k, map[k]);
|
||||
}
|
||||
k = parseInt(names$1[ok], 16);
|
||||
unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];
|
||||
}
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
let names;
|
||||
function nameParse(str) {
|
||||
if (!names) {
|
||||
names = unpack();
|
||||
names.transparent = [0, 0, 0, 0];
|
||||
}
|
||||
const a = names[str.toLowerCase()];
|
||||
return a && {
|
||||
r: a[0],
|
||||
g: a[1],
|
||||
b: a[2],
|
||||
a: a.length === 4 ? a[3] : 255
|
||||
};
|
||||
}
|
||||
|
||||
const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
|
||||
function rgbParse(str) {
|
||||
const m = RGB_RE.exec(str);
|
||||
let a = 255;
|
||||
let r, g, b;
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
if (m[7] !== r) {
|
||||
const v = +m[7];
|
||||
a = m[8] ? p2b(v) : lim(v * 255, 0, 255);
|
||||
}
|
||||
r = +m[1];
|
||||
g = +m[3];
|
||||
b = +m[5];
|
||||
r = 255 & (m[2] ? p2b(r) : lim(r, 0, 255));
|
||||
g = 255 & (m[4] ? p2b(g) : lim(g, 0, 255));
|
||||
b = 255 & (m[6] ? p2b(b) : lim(b, 0, 255));
|
||||
return {
|
||||
r: r,
|
||||
g: g,
|
||||
b: b,
|
||||
a: a
|
||||
};
|
||||
}
|
||||
function rgbString(v) {
|
||||
return v && (
|
||||
v.a < 255
|
||||
? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`
|
||||
: `rgb(${v.r}, ${v.g}, ${v.b})`
|
||||
);
|
||||
}
|
||||
|
||||
const to = v => v <= 0.0031308 ? v * 12.92 : Math.pow(v, 1.0 / 2.4) * 1.055 - 0.055;
|
||||
const from = v => v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
|
||||
function interpolate(rgb1, rgb2, t) {
|
||||
const r = from(b2n(rgb1.r));
|
||||
const g = from(b2n(rgb1.g));
|
||||
const b = from(b2n(rgb1.b));
|
||||
return {
|
||||
r: n2b(to(r + t * (from(b2n(rgb2.r)) - r))),
|
||||
g: n2b(to(g + t * (from(b2n(rgb2.g)) - g))),
|
||||
b: n2b(to(b + t * (from(b2n(rgb2.b)) - b))),
|
||||
a: rgb1.a + t * (rgb2.a - rgb1.a)
|
||||
};
|
||||
}
|
||||
|
||||
function modHSL(v, i, ratio) {
|
||||
if (v) {
|
||||
let tmp = rgb2hsl(v);
|
||||
tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));
|
||||
tmp = hsl2rgb(tmp);
|
||||
v.r = tmp[0];
|
||||
v.g = tmp[1];
|
||||
v.b = tmp[2];
|
||||
}
|
||||
}
|
||||
function clone(v, proto) {
|
||||
return v ? Object.assign(proto || {}, v) : v;
|
||||
}
|
||||
function fromObject(input) {
|
||||
var v = {r: 0, g: 0, b: 0, a: 255};
|
||||
if (Array.isArray(input)) {
|
||||
if (input.length >= 3) {
|
||||
v = {r: input[0], g: input[1], b: input[2], a: 255};
|
||||
if (input.length > 3) {
|
||||
v.a = n2b(input[3]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v = clone(input, {r: 0, g: 0, b: 0, a: 1});
|
||||
v.a = n2b(v.a);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
function functionParse(str) {
|
||||
if (str.charAt(0) === 'r') {
|
||||
return rgbParse(str);
|
||||
}
|
||||
return hueParse(str);
|
||||
}
|
||||
class Color {
|
||||
constructor(input) {
|
||||
if (input instanceof Color) {
|
||||
return input;
|
||||
}
|
||||
const type = typeof input;
|
||||
let v;
|
||||
if (type === 'object') {
|
||||
v = fromObject(input);
|
||||
} else if (type === 'string') {
|
||||
v = hexParse(input) || nameParse(input) || functionParse(input);
|
||||
}
|
||||
this._rgb = v;
|
||||
this._valid = !!v;
|
||||
}
|
||||
get valid() {
|
||||
return this._valid;
|
||||
}
|
||||
get rgb() {
|
||||
var v = clone(this._rgb);
|
||||
if (v) {
|
||||
v.a = b2n(v.a);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
set rgb(obj) {
|
||||
this._rgb = fromObject(obj);
|
||||
}
|
||||
rgbString() {
|
||||
return this._valid ? rgbString(this._rgb) : undefined;
|
||||
}
|
||||
hexString() {
|
||||
return this._valid ? hexString(this._rgb) : undefined;
|
||||
}
|
||||
hslString() {
|
||||
return this._valid ? hslString(this._rgb) : undefined;
|
||||
}
|
||||
mix(color, weight) {
|
||||
if (color) {
|
||||
const c1 = this.rgb;
|
||||
const c2 = color.rgb;
|
||||
let w2;
|
||||
const p = weight === w2 ? 0.5 : weight;
|
||||
const w = 2 * p - 1;
|
||||
const a = c1.a - c2.a;
|
||||
const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
|
||||
w2 = 1 - w1;
|
||||
c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;
|
||||
c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;
|
||||
c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;
|
||||
c1.a = p * c1.a + (1 - p) * c2.a;
|
||||
this.rgb = c1;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
interpolate(color, t) {
|
||||
if (color) {
|
||||
this._rgb = interpolate(this._rgb, color._rgb, t);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
clone() {
|
||||
return new Color(this.rgb);
|
||||
}
|
||||
alpha(a) {
|
||||
this._rgb.a = n2b(a);
|
||||
return this;
|
||||
}
|
||||
clearer(ratio) {
|
||||
const rgb = this._rgb;
|
||||
rgb.a *= 1 - ratio;
|
||||
return this;
|
||||
}
|
||||
greyscale() {
|
||||
const rgb = this._rgb;
|
||||
const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
|
||||
rgb.r = rgb.g = rgb.b = val;
|
||||
return this;
|
||||
}
|
||||
opaquer(ratio) {
|
||||
const rgb = this._rgb;
|
||||
rgb.a *= 1 + ratio;
|
||||
return this;
|
||||
}
|
||||
negate() {
|
||||
const v = this._rgb;
|
||||
v.r = 255 - v.r;
|
||||
v.g = 255 - v.g;
|
||||
v.b = 255 - v.b;
|
||||
return this;
|
||||
}
|
||||
lighten(ratio) {
|
||||
modHSL(this._rgb, 2, ratio);
|
||||
return this;
|
||||
}
|
||||
darken(ratio) {
|
||||
modHSL(this._rgb, 2, -ratio);
|
||||
return this;
|
||||
}
|
||||
saturate(ratio) {
|
||||
modHSL(this._rgb, 1, ratio);
|
||||
return this;
|
||||
}
|
||||
desaturate(ratio) {
|
||||
modHSL(this._rgb, 1, -ratio);
|
||||
return this;
|
||||
}
|
||||
rotate(deg) {
|
||||
rotate(this._rgb, deg);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
function index_esm(input) {
|
||||
return new Color(input);
|
||||
}
|
||||
|
||||
export { Color, b2n, b2p, index_esm as default, hexParse, hexString, hsl2rgb, hslString, hsv2rgb, hueParse, hwb2rgb, lim, n2b, n2p, nameParse, p2b, rgb2hsl, rgbParse, rgbString, rotate, round };
|
||||
+8
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+77
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "@kurkle/color",
|
||||
"type": "module",
|
||||
"version": "0.3.4",
|
||||
"description": "css color parsing, manupulation and conversion",
|
||||
"sideEffects": false,
|
||||
"main": "dist/color.cjs",
|
||||
"module": "dist/color.esm.js",
|
||||
"types": "dist/color.d.ts",
|
||||
"exports": {
|
||||
"types": "./dist/color.d.ts",
|
||||
"import": "./dist/color.esm.js",
|
||||
"require": "./dist/color.cjs"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node util/copy_dist.js && rollup -c",
|
||||
"lint": "eslint src/*.js test/*.js util/*.js",
|
||||
"test": "node test/index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/kurkle/color.git"
|
||||
},
|
||||
"files": [
|
||||
"dist/*",
|
||||
"dist/color.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"color",
|
||||
"colour",
|
||||
"css",
|
||||
"hsl",
|
||||
"hex",
|
||||
"rgb",
|
||||
"rgba",
|
||||
"hwb",
|
||||
"hsv",
|
||||
"cmyk"
|
||||
],
|
||||
"author": "Jukka Kurkela",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/kurkle/color/issues"
|
||||
},
|
||||
"homepage": "https://github.com/kurkle/color#readme",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"assert": "^2.0.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"chartjs-color": "^2.4.1",
|
||||
"chartjs-color-string": "^0.6.0",
|
||||
"child_process": "^1.0.2",
|
||||
"chroma-js": "^3.1.1",
|
||||
"color-name": "^2.0.0",
|
||||
"color-names": "^2.0.0",
|
||||
"color-parse": "^2.0.2",
|
||||
"color-parser": "^0.1.0",
|
||||
"color-string": "^1.5.5",
|
||||
"csscolorparser": "^1.0.3",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-config-chartjs": "^0.3.0",
|
||||
"eslint-config-defaults": "^9.0.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"fs": "0.0.1-security",
|
||||
"perf_hooks": "0.0.1",
|
||||
"rollup": "^4.25.0",
|
||||
"rollup-plugin-analyzer": "^4.0.0",
|
||||
"rollup-plugin-cleanup": "^3.2.1",
|
||||
"rollup-plugin-istanbul": "^5.0.0",
|
||||
"rollup-plugin-visualizer": "^5.8.3",
|
||||
"tinycolor2": "^1.4.2",
|
||||
"typedoc": "^0.26.7",
|
||||
"typescript": "^5.6.2",
|
||||
"util": "^0.12.3"
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
This software is dual-licensed under the ISC and MIT licenses.
|
||||
You may use this software under EITHER of the following licenses.
|
||||
|
||||
----------
|
||||
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
----------
|
||||
|
||||
Copyright Isaac Z. Schlueter and Contributors
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# abbrev-js
|
||||
|
||||
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
|
||||
|
||||
Usage:
|
||||
|
||||
var abbrev = require("abbrev");
|
||||
abbrev("foo", "fool", "folding", "flop");
|
||||
|
||||
// returns:
|
||||
{ fl: 'flop'
|
||||
, flo: 'flop'
|
||||
, flop: 'flop'
|
||||
, fol: 'folding'
|
||||
, fold: 'folding'
|
||||
, foldi: 'folding'
|
||||
, foldin: 'folding'
|
||||
, folding: 'folding'
|
||||
, foo: 'foo'
|
||||
, fool: 'fool'
|
||||
}
|
||||
|
||||
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
module.exports = abbrev
|
||||
|
||||
function abbrev (...args) {
|
||||
let list = args
|
||||
if (args.length === 1 && (Array.isArray(args[0]) || typeof args[0] === 'string')) {
|
||||
list = [].concat(args[0])
|
||||
}
|
||||
|
||||
for (let i = 0, l = list.length; i < l; i++) {
|
||||
list[i] = typeof list[i] === 'string' ? list[i] : String(list[i])
|
||||
}
|
||||
|
||||
// sort them lexicographically, so that they're next to their nearest kin
|
||||
list = list.sort(lexSort)
|
||||
|
||||
// walk through each, seeing how much it has in common with the next and previous
|
||||
const abbrevs = {}
|
||||
let prev = ''
|
||||
for (let ii = 0, ll = list.length; ii < ll; ii++) {
|
||||
const current = list[ii]
|
||||
const next = list[ii + 1] || ''
|
||||
let nextMatches = true
|
||||
let prevMatches = true
|
||||
if (current === next) {
|
||||
continue
|
||||
}
|
||||
let j = 0
|
||||
const cl = current.length
|
||||
for (; j < cl; j++) {
|
||||
const curChar = current.charAt(j)
|
||||
nextMatches = nextMatches && curChar === next.charAt(j)
|
||||
prevMatches = prevMatches && curChar === prev.charAt(j)
|
||||
if (!nextMatches && !prevMatches) {
|
||||
j++
|
||||
break
|
||||
}
|
||||
}
|
||||
prev = current
|
||||
if (j === cl) {
|
||||
abbrevs[current] = current
|
||||
continue
|
||||
}
|
||||
for (let a = current.slice(0, j); j <= cl; j++) {
|
||||
abbrevs[a] = current
|
||||
a += current.charAt(j)
|
||||
}
|
||||
}
|
||||
return abbrevs
|
||||
}
|
||||
|
||||
function lexSort (a, b) {
|
||||
return a === b ? 0 : a > b ? 1 : -1
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
"version": "4.0.0",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "GitHub Inc.",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"test": "node --test",
|
||||
"lint": "npm run eslint",
|
||||
"postlint": "template-oss-check",
|
||||
"template-oss-apply": "template-oss-apply --force",
|
||||
"lintfix": "npm run eslint -- --fix",
|
||||
"snap": "node --test --test-update-snapshots",
|
||||
"posttest": "npm run lint",
|
||||
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
|
||||
"test:cover": "node --test --experimental-test-coverage --test-timeout=3000 --test-coverage-lines=100 --test-coverage-functions=100 --test-coverage-branches=100"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/npm/abbrev-js.git"
|
||||
},
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^5.0.0",
|
||||
"@npmcli/template-oss": "4.26.1"
|
||||
},
|
||||
"files": [
|
||||
"bin/",
|
||||
"lib/"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.17.0 || >=22.9.0"
|
||||
},
|
||||
"templateOSS": {
|
||||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||
"version": "4.26.1",
|
||||
"publish": true,
|
||||
"testRunner": "node:test",
|
||||
"latestCiVersion": 24
|
||||
}
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
2.0.0 / 2024-08-31
|
||||
==================
|
||||
|
||||
* Drop node <18 support
|
||||
* deps: mime-types@^3.0.0
|
||||
* deps: negotiator@^1.0.0
|
||||
|
||||
1.3.8 / 2022-02-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.34
|
||||
- deps: mime-db@~1.51.0
|
||||
* deps: negotiator@0.6.3
|
||||
|
||||
1.3.7 / 2019-04-29
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.6.2
|
||||
- Fix sorting charset, encoding, and language with extra parameters
|
||||
|
||||
1.3.6 / 2019-04-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.24
|
||||
- deps: mime-db@~1.40.0
|
||||
|
||||
1.3.5 / 2018-02-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.18
|
||||
- deps: mime-db@~1.33.0
|
||||
|
||||
1.3.4 / 2017-08-22
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.16
|
||||
- deps: mime-db@~1.29.0
|
||||
|
||||
1.3.3 / 2016-05-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.11
|
||||
- deps: mime-db@~1.23.0
|
||||
* deps: negotiator@0.6.1
|
||||
- perf: improve `Accept` parsing speed
|
||||
- perf: improve `Accept-Charset` parsing speed
|
||||
- perf: improve `Accept-Encoding` parsing speed
|
||||
- perf: improve `Accept-Language` parsing speed
|
||||
|
||||
1.3.2 / 2016-03-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.10
|
||||
- Fix extension of `application/dash+xml`
|
||||
- Update primary extension for `audio/mp4`
|
||||
- deps: mime-db@~1.22.0
|
||||
|
||||
1.3.1 / 2016-01-19
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.9
|
||||
- deps: mime-db@~1.21.0
|
||||
|
||||
1.3.0 / 2015-09-29
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.7
|
||||
- deps: mime-db@~1.19.0
|
||||
* deps: negotiator@0.6.0
|
||||
- Fix including type extensions in parameters in `Accept` parsing
|
||||
- Fix parsing `Accept` parameters with quoted equals
|
||||
- Fix parsing `Accept` parameters with quoted semicolons
|
||||
- Lazy-load modules from main entry point
|
||||
- perf: delay type concatenation until needed
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove closures getting spec properties
|
||||
- perf: remove a closure from media type parsing
|
||||
- perf: remove property delete from media type parsing
|
||||
|
||||
1.2.13 / 2015-09-06
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.6
|
||||
- deps: mime-db@~1.18.0
|
||||
|
||||
1.2.12 / 2015-07-30
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.4
|
||||
- deps: mime-db@~1.16.0
|
||||
|
||||
1.2.11 / 2015-07-16
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.3
|
||||
- deps: mime-db@~1.15.0
|
||||
|
||||
1.2.10 / 2015-07-01
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.2
|
||||
- deps: mime-db@~1.14.0
|
||||
|
||||
1.2.9 / 2015-06-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.1
|
||||
- perf: fix deopt during mapping
|
||||
|
||||
1.2.8 / 2015-06-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.0
|
||||
- deps: mime-db@~1.13.0
|
||||
* perf: avoid argument reassignment & argument slice
|
||||
* perf: avoid negotiator recursive construction
|
||||
* perf: enable strict mode
|
||||
* perf: remove unnecessary bitwise operator
|
||||
|
||||
1.2.7 / 2015-05-10
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.3
|
||||
- Fix media type parameter matching to be case-insensitive
|
||||
|
||||
1.2.6 / 2015-05-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.11
|
||||
- deps: mime-db@~1.9.1
|
||||
* deps: negotiator@0.5.2
|
||||
- Fix comparing media types with quoted values
|
||||
- Fix splitting media types with quoted commas
|
||||
|
||||
1.2.5 / 2015-03-13
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.10
|
||||
- deps: mime-db@~1.8.0
|
||||
|
||||
1.2.4 / 2015-02-14
|
||||
==================
|
||||
|
||||
* Support Node.js 0.6
|
||||
* deps: mime-types@~2.0.9
|
||||
- deps: mime-db@~1.7.0
|
||||
* deps: negotiator@0.5.1
|
||||
- Fix preference sorting to be stable for long acceptable lists
|
||||
|
||||
1.2.3 / 2015-01-31
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.8
|
||||
- deps: mime-db@~1.6.0
|
||||
|
||||
1.2.2 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.7
|
||||
- deps: mime-db@~1.5.0
|
||||
|
||||
1.2.1 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.5
|
||||
- deps: mime-db@~1.3.1
|
||||
|
||||
1.2.0 / 2014-12-19
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.0
|
||||
- Fix list return order when large accepted list
|
||||
- Fix missing identity encoding when q=0 exists
|
||||
- Remove dynamic building of Negotiator class
|
||||
|
||||
1.1.4 / 2014-12-10
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.4
|
||||
- deps: mime-db@~1.3.0
|
||||
|
||||
1.1.3 / 2014-11-09
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.3
|
||||
- deps: mime-db@~1.2.0
|
||||
|
||||
1.1.2 / 2014-10-14
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.9
|
||||
- Fix error when media type has invalid parameter
|
||||
|
||||
1.1.1 / 2014-09-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.2
|
||||
- deps: mime-db@~1.1.0
|
||||
* deps: negotiator@0.4.8
|
||||
- Fix all negotiations to be case-insensitive
|
||||
- Stable sort preferences of same quality according to client order
|
||||
|
||||
1.1.0 / 2014-09-02
|
||||
==================
|
||||
|
||||
* update `mime-types`
|
||||
|
||||
1.0.7 / 2014-07-04
|
||||
==================
|
||||
|
||||
* Fix wrong type returned from `type` when match after unknown extension
|
||||
|
||||
1.0.6 / 2014-06-24
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.7
|
||||
|
||||
1.0.5 / 2014-06-20
|
||||
==================
|
||||
|
||||
* fix crash when unknown extension given
|
||||
|
||||
1.0.4 / 2014-06-19
|
||||
==================
|
||||
|
||||
* use `mime-types`
|
||||
|
||||
1.0.3 / 2014-06-11
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.6
|
||||
- Order by specificity when quality is the same
|
||||
|
||||
1.0.2 / 2014-05-29
|
||||
==================
|
||||
|
||||
* Fix interpretation when header not in request
|
||||
* deps: pin negotiator@0.4.5
|
||||
|
||||
1.0.1 / 2014-01-18
|
||||
==================
|
||||
|
||||
* Identity encoding isn't always acceptable
|
||||
* deps: negotiator@~0.4.0
|
||||
|
||||
1.0.0 / 2013-12-27
|
||||
==================
|
||||
|
||||
* Genesis
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
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.
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
# accepts
|
||||
|
||||
[![NPM Version][npm-version-image]][npm-url]
|
||||
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||
[![Node.js Version][node-version-image]][node-version-url]
|
||||
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
|
||||
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
|
||||
|
||||
In addition to negotiator, it allows:
|
||||
|
||||
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
|
||||
as well as `('text/html', 'application/json')`.
|
||||
- Allows type shorthands such as `json`.
|
||||
- Returns `false` when no types match
|
||||
- Treats non-existent headers as `*`
|
||||
|
||||
## Installation
|
||||
|
||||
This is a [Node.js](https://nodejs.org/en/) module available through the
|
||||
[npm registry](https://www.npmjs.com/). Installation is done using the
|
||||
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
||||
|
||||
```sh
|
||||
$ npm install accepts
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
```
|
||||
|
||||
### accepts(req)
|
||||
|
||||
Create a new `Accepts` object for the given `req`.
|
||||
|
||||
#### .charset(charsets)
|
||||
|
||||
Return the first accepted charset. If nothing in `charsets` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .charsets()
|
||||
|
||||
Return the charsets that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .encoding(encodings)
|
||||
|
||||
Return the first accepted encoding. If nothing in `encodings` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .encodings()
|
||||
|
||||
Return the encodings that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .language(languages)
|
||||
|
||||
Return the first accepted language. If nothing in `languages` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .languages()
|
||||
|
||||
Return the languages that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .type(types)
|
||||
|
||||
Return the first accepted type (and it is returned as the same text as what
|
||||
appears in the `types` array). If nothing in `types` is accepted, then `false`
|
||||
is returned.
|
||||
|
||||
The `types` array can contain full MIME types or file extensions. Any value
|
||||
that is not a full MIME type is passed to `require('mime-types').lookup`.
|
||||
|
||||
#### .types()
|
||||
|
||||
Return the types that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple type negotiation
|
||||
|
||||
This simple example shows how to use `accepts` to return a different typed
|
||||
respond body based on what the client wants to accept. The server lists it's
|
||||
preferences in order and will get back the best match between the client and
|
||||
server.
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
var http = require('http')
|
||||
|
||||
function app (req, res) {
|
||||
var accept = accepts(req)
|
||||
|
||||
// the order of this list is significant; should be server preferred order
|
||||
switch (accept.type(['json', 'html'])) {
|
||||
case 'json':
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.write('{"hello":"world!"}')
|
||||
break
|
||||
case 'html':
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.write('<b>hello, world!</b>')
|
||||
break
|
||||
default:
|
||||
// the fallback is text/plain, so no need to specify it above
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.write('hello, world!')
|
||||
break
|
||||
}
|
||||
|
||||
res.end()
|
||||
}
|
||||
|
||||
http.createServer(app).listen(3000)
|
||||
```
|
||||
|
||||
You can test this out with the cURL program:
|
||||
```sh
|
||||
curl -I -H'Accept: text/html' http://localhost:3000/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
|
||||
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
|
||||
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
|
||||
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
|
||||
[node-version-image]: https://badgen.net/npm/node/accepts
|
||||
[node-version-url]: https://nodejs.org/en/download
|
||||
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
|
||||
[npm-url]: https://npmjs.org/package/accepts
|
||||
[npm-version-image]: https://badgen.net/npm/v/accepts
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*!
|
||||
* accepts
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var Negotiator = require('negotiator')
|
||||
var mime = require('mime-types')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = Accepts
|
||||
|
||||
/**
|
||||
* Create a new Accepts object for the given req.
|
||||
*
|
||||
* @param {object} req
|
||||
* @public
|
||||
*/
|
||||
|
||||
function Accepts (req) {
|
||||
if (!(this instanceof Accepts)) {
|
||||
return new Accepts(req)
|
||||
}
|
||||
|
||||
this.headers = req.headers
|
||||
this.negotiator = new Negotiator(req)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given `type(s)` is acceptable, returning
|
||||
* the best match when true, otherwise `undefined`, in which
|
||||
* case you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* The `type` value may be a single mime type string
|
||||
* such as "application/json", the extension name
|
||||
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
|
||||
* or array is given the _best_ match, if any is returned.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // Accept: text/html
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
* this.types('text/html');
|
||||
* // => "text/html"
|
||||
* this.types('json', 'text');
|
||||
* // => "json"
|
||||
* this.types('application/json');
|
||||
* // => "application/json"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('image/png');
|
||||
* this.types('png');
|
||||
* // => undefined
|
||||
*
|
||||
* // Accept: text/*;q=.5, application/json
|
||||
* this.types(['html', 'json']);
|
||||
* this.types('html', 'json');
|
||||
* // => "json"
|
||||
*
|
||||
* @param {String|Array} types...
|
||||
* @return {String|Array|Boolean}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.type =
|
||||
Accepts.prototype.types = function (types_) {
|
||||
var types = types_
|
||||
|
||||
// support flattened arguments
|
||||
if (types && !Array.isArray(types)) {
|
||||
types = new Array(arguments.length)
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
types[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no types, return all requested types
|
||||
if (!types || types.length === 0) {
|
||||
return this.negotiator.mediaTypes()
|
||||
}
|
||||
|
||||
// no accept header, return first given type
|
||||
if (!this.headers.accept) {
|
||||
return types[0]
|
||||
}
|
||||
|
||||
var mimes = types.map(extToMime)
|
||||
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
|
||||
var first = accepts[0]
|
||||
|
||||
return first
|
||||
? types[mimes.indexOf(first)]
|
||||
: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted encodings or best fit based on `encodings`.
|
||||
*
|
||||
* Given `Accept-Encoding: gzip, deflate`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['gzip', 'deflate']
|
||||
*
|
||||
* @param {String|Array} encodings...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.encoding =
|
||||
Accepts.prototype.encodings = function (encodings_) {
|
||||
var encodings = encodings_
|
||||
|
||||
// support flattened arguments
|
||||
if (encodings && !Array.isArray(encodings)) {
|
||||
encodings = new Array(arguments.length)
|
||||
for (var i = 0; i < encodings.length; i++) {
|
||||
encodings[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no encodings, return all requested encodings
|
||||
if (!encodings || encodings.length === 0) {
|
||||
return this.negotiator.encodings()
|
||||
}
|
||||
|
||||
return this.negotiator.encodings(encodings)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted charsets or best fit based on `charsets`.
|
||||
*
|
||||
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||
*
|
||||
* @param {String|Array} charsets...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.charset =
|
||||
Accepts.prototype.charsets = function (charsets_) {
|
||||
var charsets = charsets_
|
||||
|
||||
// support flattened arguments
|
||||
if (charsets && !Array.isArray(charsets)) {
|
||||
charsets = new Array(arguments.length)
|
||||
for (var i = 0; i < charsets.length; i++) {
|
||||
charsets[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no charsets, return all requested charsets
|
||||
if (!charsets || charsets.length === 0) {
|
||||
return this.negotiator.charsets()
|
||||
}
|
||||
|
||||
return this.negotiator.charsets(charsets)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted languages or best fit based on `langs`.
|
||||
*
|
||||
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['es', 'pt', 'en']
|
||||
*
|
||||
* @param {String|Array} langs...
|
||||
* @return {Array|String}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.lang =
|
||||
Accepts.prototype.langs =
|
||||
Accepts.prototype.language =
|
||||
Accepts.prototype.languages = function (languages_) {
|
||||
var languages = languages_
|
||||
|
||||
// support flattened arguments
|
||||
if (languages && !Array.isArray(languages)) {
|
||||
languages = new Array(arguments.length)
|
||||
for (var i = 0; i < languages.length; i++) {
|
||||
languages[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no languages, return all requested languages
|
||||
if (!languages || languages.length === 0) {
|
||||
return this.negotiator.languages()
|
||||
}
|
||||
|
||||
return this.negotiator.languages(languages)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert extnames to mime.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function extToMime (type) {
|
||||
return type.indexOf('/') === -1
|
||||
? mime.lookup(type)
|
||||
: type
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mime is valid.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {Boolean}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function validMime (type) {
|
||||
return typeof type === 'string'
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "accepts",
|
||||
"description": "Higher-level content negotiation",
|
||||
"version": "2.0.0",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "jshttp/accepts",
|
||||
"dependencies": {
|
||||
"mime-types": "^3.0.0",
|
||||
"negotiator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"deep-equal": "1.0.1",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-standard": "14.1.1",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-markdown": "2.2.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "4.3.1",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"mocha": "9.2.0",
|
||||
"nyc": "15.1.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"HISTORY.md",
|
||||
"index.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||
},
|
||||
"keywords": [
|
||||
"content",
|
||||
"negotiation",
|
||||
"accept",
|
||||
"accepts"
|
||||
]
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Linus Unnebäck
|
||||
|
||||
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.
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
# `append-field`
|
||||
|
||||
A [W3C HTML JSON forms spec](http://www.w3.org/TR/html-json-forms/) compliant
|
||||
field appender (for lack of a better name). Useful for people implementing
|
||||
`application/x-www-form-urlencoded` and `multipart/form-data` parsers.
|
||||
|
||||
It works best on objects created with `Object.create(null)`. Otherwise it might
|
||||
conflict with variables from the prototype (e.g. `hasOwnProperty`).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save append-field
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var appendField = require('append-field')
|
||||
var obj = Object.create(null)
|
||||
|
||||
appendField(obj, 'pets[0][species]', 'Dahut')
|
||||
appendField(obj, 'pets[0][name]', 'Hypatia')
|
||||
appendField(obj, 'pets[1][species]', 'Felis Stultus')
|
||||
appendField(obj, 'pets[1][name]', 'Billie')
|
||||
|
||||
console.log(obj)
|
||||
```
|
||||
|
||||
```text
|
||||
{ pets:
|
||||
[ { species: 'Dahut', name: 'Hypatia' },
|
||||
{ species: 'Felis Stultus', name: 'Billie' } ] }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `appendField(store, key, value)`
|
||||
|
||||
Adds the field named `key` with the value `value` to the object `store`.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
var parsePath = require('./lib/parse-path')
|
||||
var setValue = require('./lib/set-value')
|
||||
|
||||
function appendField (store, key, value) {
|
||||
var steps = parsePath(key)
|
||||
|
||||
steps.reduce(function (context, step) {
|
||||
return setValue(context, step, context[step.key], value)
|
||||
}, store)
|
||||
}
|
||||
|
||||
module.exports = appendField
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
var reFirstKey = /^[^\[]*/
|
||||
var reDigitPath = /^\[(\d+)\]/
|
||||
var reNormalPath = /^\[([^\]]+)\]/
|
||||
|
||||
function parsePath (key) {
|
||||
function failure () {
|
||||
return [{ type: 'object', key: key, last: true }]
|
||||
}
|
||||
|
||||
var firstKey = reFirstKey.exec(key)[0]
|
||||
if (!firstKey) return failure()
|
||||
|
||||
var len = key.length
|
||||
var pos = firstKey.length
|
||||
var tail = { type: 'object', key: firstKey }
|
||||
var steps = [tail]
|
||||
|
||||
while (pos < len) {
|
||||
var m
|
||||
|
||||
if (key[pos] === '[' && key[pos + 1] === ']') {
|
||||
pos += 2
|
||||
tail.append = true
|
||||
if (pos !== len) return failure()
|
||||
continue
|
||||
}
|
||||
|
||||
m = reDigitPath.exec(key.substring(pos))
|
||||
if (m !== null) {
|
||||
pos += m[0].length
|
||||
tail.nextType = 'array'
|
||||
tail = { type: 'array', key: parseInt(m[1], 10) }
|
||||
steps.push(tail)
|
||||
continue
|
||||
}
|
||||
|
||||
m = reNormalPath.exec(key.substring(pos))
|
||||
if (m !== null) {
|
||||
pos += m[0].length
|
||||
tail.nextType = 'object'
|
||||
tail = { type: 'object', key: m[1] }
|
||||
steps.push(tail)
|
||||
continue
|
||||
}
|
||||
|
||||
return failure()
|
||||
}
|
||||
|
||||
tail.last = true
|
||||
return steps
|
||||
}
|
||||
|
||||
module.exports = parsePath
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
function valueType (value) {
|
||||
if (value === undefined) return 'undefined'
|
||||
if (Array.isArray(value)) return 'array'
|
||||
if (typeof value === 'object') return 'object'
|
||||
return 'scalar'
|
||||
}
|
||||
|
||||
function setLastValue (context, step, currentValue, entryValue) {
|
||||
switch (valueType(currentValue)) {
|
||||
case 'undefined':
|
||||
if (step.append) {
|
||||
context[step.key] = [entryValue]
|
||||
} else {
|
||||
context[step.key] = entryValue
|
||||
}
|
||||
break
|
||||
case 'array':
|
||||
context[step.key].push(entryValue)
|
||||
break
|
||||
case 'object':
|
||||
return setLastValue(currentValue, { type: 'object', key: '', last: true }, currentValue[''], entryValue)
|
||||
case 'scalar':
|
||||
context[step.key] = [context[step.key], entryValue]
|
||||
break
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
function setValue (context, step, currentValue, entryValue) {
|
||||
if (step.last) return setLastValue(context, step, currentValue, entryValue)
|
||||
|
||||
var obj
|
||||
switch (valueType(currentValue)) {
|
||||
case 'undefined':
|
||||
if (step.nextType === 'array') {
|
||||
context[step.key] = []
|
||||
} else {
|
||||
context[step.key] = Object.create(null)
|
||||
}
|
||||
return context[step.key]
|
||||
case 'object':
|
||||
return context[step.key]
|
||||
case 'array':
|
||||
if (step.nextType === 'array') {
|
||||
return currentValue
|
||||
}
|
||||
|
||||
obj = Object.create(null)
|
||||
context[step.key] = obj
|
||||
currentValue.forEach(function (item, i) {
|
||||
if (item !== undefined) obj['' + i] = item
|
||||
})
|
||||
|
||||
return obj
|
||||
case 'scalar':
|
||||
obj = Object.create(null)
|
||||
obj[''] = currentValue
|
||||
context[step.key] = obj
|
||||
return obj
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = setValue
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "append-field",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"author": "Linus Unnebäck <linus@folkdatorn.se>",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"mocha": "^2.2.4",
|
||||
"standard": "^6.0.5",
|
||||
"testdata-w3c-json-form": "^0.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "standard && mocha"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/LinusU/node-append-field.git"
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
var assert = require('assert')
|
||||
var appendField = require('../')
|
||||
var testData = require('testdata-w3c-json-form')
|
||||
|
||||
describe('Append Field', function () {
|
||||
for (var test of testData) {
|
||||
it('handles ' + test.name, function () {
|
||||
var store = Object.create(null)
|
||||
|
||||
for (var field of test.fields) {
|
||||
appendField(store, field.key, field.value)
|
||||
}
|
||||
|
||||
assert.deepEqual(store, test.expected)
|
||||
})
|
||||
}
|
||||
})
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2013 Andrey Sitnik <andrey@sitnik.es>
|
||||
|
||||
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.
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
# Autoprefixer [![Cult Of Martians][cult-img]][cult]
|
||||
|
||||
<img align="right" width="94" height="71"
|
||||
src="https://postcss.github.io/autoprefixer/logo.svg"
|
||||
title="Autoprefixer logo by Anton Lovchikov">
|
||||
|
||||
[PostCSS] plugin to parse CSS and add vendor prefixes to CSS rules using values
|
||||
from [Can I Use]. It is recommended by Google and used in Twitter and Alibaba.
|
||||
|
||||
Write your CSS rules without vendor prefixes (in fact, forget about them
|
||||
entirely):
|
||||
|
||||
```css
|
||||
::placeholder {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: stretch;
|
||||
}
|
||||
```
|
||||
|
||||
Autoprefixer will use the data based on current browser popularity and property
|
||||
support to apply prefixes for you. You can try the [interactive demo]
|
||||
of Autoprefixer.
|
||||
|
||||
```css
|
||||
::-moz-placeholder {
|
||||
color: gray;
|
||||
}
|
||||
::placeholder {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: -webkit-fill-available;
|
||||
width: -moz-available;
|
||||
width: stretch;
|
||||
}
|
||||
```
|
||||
|
||||
Twitter account for news and releases: [@autoprefixer].
|
||||
|
||||
<a href="https://evilmartians.com/?utm_source=autoprefixer">
|
||||
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
||||
</a>
|
||||
|
||||
[interactive demo]: https://autoprefixer.github.io/
|
||||
[@autoprefixer]: https://twitter.com/autoprefixer
|
||||
[Can I Use]: https://caniuse.com/
|
||||
[cult-img]: https://cultofmartians.com/assets/badges/badge.svg
|
||||
[PostCSS]: https://github.com/postcss/postcss
|
||||
[cult]: https://cultofmartians.com/tasks/autoprefixer-grid.html
|
||||
|
||||
## Docs
|
||||
Read full docs **[here](https://github.com/postcss/autoprefixer#readme)**.
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
let mode = process.argv[2]
|
||||
if (mode === '--info') {
|
||||
process.stdout.write(require('../')().info() + '\n')
|
||||
} else if (mode === '--version') {
|
||||
process.stdout.write(
|
||||
'autoprefixer ' + require('../package.json').version + '\n'
|
||||
)
|
||||
} else {
|
||||
process.stdout.write(
|
||||
'autoprefix\n' +
|
||||
'\n' +
|
||||
'Options:\n' +
|
||||
' --info Show target browsers and used prefixes\n' +
|
||||
' --version Show version number\n' +
|
||||
' --help Show help\n' +
|
||||
'\n' +
|
||||
'Usage:\n' +
|
||||
' autoprefixer --info\n'
|
||||
)
|
||||
}
|
||||
+1141
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user