diff --git a/.env b/.env index e362c32..3f47c3b 100644 --- a/.env +++ b/.env @@ -5,4 +5,4 @@ ADMIN_PASSWORD=admin JWT_COOKIE_SECURE=false ENABLE_HTTPS_REDIRECT=false WEB_PORT=3000 -CSRF_ALLOWED_ORIGINS=http://192.168.1.201:3000 +CSRF_ALLOWED_ORIGINS=http://192.168.1.204:3000 diff --git a/api/Cargo.lock b/api/Cargo.lock index 2ec1bf5..ec70615 100644 --- a/api/Cargo.lock +++ b/api/Cargo.lock @@ -67,6 +67,7 @@ dependencies = [ "anyhow", "bcrypt", "chrono", + "csv", "dotenvy", "jsonwebtoken", "rocket", @@ -356,6 +357,27 @@ dependencies = [ "typenum", ] +[[package]] +name = "csv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" +dependencies = [ + "memchr", +] + [[package]] name = "der" version = "0.7.10" diff --git a/api/Cargo.toml b/api/Cargo.toml index 705f3ff..8a2438f 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -15,3 +15,4 @@ serde_json = "1" sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio", "postgres", "chrono", "macros", "migrate"] } thiserror = "1" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } +csv = "1.3" diff --git a/api/src/models/person.rs b/api/src/models/person.rs index 6786051..b4ed56a 100644 --- a/api/src/models/person.rs +++ b/api/src/models/person.rs @@ -80,6 +80,24 @@ pub struct PersonActionResponse { pub person: PersonResponse, } +#[derive(Debug, Serialize, Clone)] +#[serde(crate = "rocket::serde")] +pub struct ImportPersonError { + pub line: usize, + pub message: String, +} + +#[derive(Debug, Serialize, Clone)] +#[serde(crate = "rocket::serde")] +pub struct ImportPersonsResponse { + pub imported: usize, + #[serde(default)] + pub updated: usize, + pub failed: usize, + #[serde(default)] + pub errors: Vec, +} + #[derive(Debug, Deserialize)] #[serde(crate = "rocket::serde")] pub struct NewPersonRequest { diff --git a/api/src/routes/persons.rs b/api/src/routes/persons.rs index 81f3f2c..c63042a 100644 --- a/api/src/routes/persons.rs +++ b/api/src/routes/persons.rs @@ -1,13 +1,15 @@ use crate::auth::AuthUser; use crate::error::ApiError; use crate::models::{ - AppEvent, NewPersonRequest, Person, PersonActionResponse, PersonResponse, PersonsResponse, - UpdatePersonRequest, + AppEvent, ImportPersonError, ImportPersonsResponse, NewPersonRequest, Person, + PersonActionResponse, PersonResponse, PersonsResponse, UpdatePersonRequest, }; use crate::AppState; +use csv::ReaderBuilder; +use rocket::data::ToByteUnit; use rocket::serde::json::Json; use rocket::Route; -use sqlx::QueryBuilder; +use sqlx::{postgres::PgRow, QueryBuilder, Row}; enum SearchCondition { Checked(bool), @@ -24,7 +26,8 @@ pub fn routes() -> Vec { mark_inside, mark_outside, create_person, - update_person + update_person, + import_persons ] } @@ -401,14 +404,10 @@ pub async fn create_person( return Err(ApiError::bad_request("Efternamn krävs.")); } - if let Some(ref phone) = data.parent_phone_number { - let digits: String = phone.chars().filter(|c| c.is_ascii_digit()).collect(); - if digits.len() != 10 { - return Err(ApiError::bad_request( - "Telefonnumret måste innehålla tio siffror.", - )); - } - } + let parent_phone_number = match normalize_phone_number(data.parent_phone_number.clone()) { + Ok(value) => value, + Err(message) => return Err(ApiError::bad_request(message)), + }; let person = sqlx::query_as::<_, Person>( r#" @@ -443,7 +442,7 @@ pub async fn create_person( .bind(data.last_name.trim()) .bind(data.grade) .bind(data.parent_name.map(|v| v.trim().to_string())) - .bind(data.parent_phone_number.map(|v| v.trim().to_string())) + .bind(parent_phone_number) .bind(data.checked_in.unwrap_or(false)) .bind(data.inside.unwrap_or(false)) .bind(data.visitor.unwrap_or(false)) @@ -480,14 +479,10 @@ pub async fn update_person( return Err(ApiError::bad_request("Efternamn krävs.")); } - if let Some(ref phone) = data.parent_phone_number { - let digits: String = phone.chars().filter(|c| c.is_ascii_digit()).collect(); - if digits.len() != 10 { - return Err(ApiError::bad_request( - "Telefonnumret måste innehålla tio siffror.", - )); - } - } + let parent_phone_number = match normalize_phone_number(data.parent_phone_number.clone()) { + Ok(value) => value, + Err(message) => return Err(ApiError::bad_request(message)), + }; let person = sqlx::query_as::<_, Person>( r#" @@ -521,7 +516,7 @@ pub async fn update_person( .bind(data.last_name.trim()) .bind(data.grade) .bind(data.parent_name.map(|v| v.trim().to_string())) - .bind(data.parent_phone_number.map(|v| v.trim().to_string())) + .bind(parent_phone_number) .bind(data.checked_in) .bind(data.inside) .bind(data.visitor) @@ -540,3 +535,353 @@ pub async fn update_person( Ok(Json(response)) } + +#[rocket::post("/import", data = "")] +pub async fn import_persons( + _user: AuthUser, + state: &rocket::State, + payload: rocket::data::Data<'_>, +) -> Result, ApiError> { + let import_limit = 5.mebibytes(); + let csv_data = payload + .open(import_limit) + .into_string() + .await + .map_err(|_| ApiError::bad_request("CSV-filen är för stor."))? + .into_inner(); + + if csv_data.trim().is_empty() { + return Err(ApiError::bad_request("CSV-filen innehåller inga rader.")); + } + + let mut reader = ReaderBuilder::new() + .has_headers(false) + .flexible(true) + .from_reader(csv_data.as_bytes()); + + let mut imported = 0usize; + let mut updated = 0usize; + let mut errors: Vec = Vec::new(); + + for (index, record_result) in reader.records().enumerate() { + let line_number = index + 1; + let record = match record_result { + Ok(record) => record, + Err(err) => { + errors.push(ImportPersonError { + line: line_number, + message: format!("Kunde inte läsa raden: {err}"), + }); + continue; + } + }; + + let id_value = record + .get(0) + .map(|value| value.trim().to_string()) + .unwrap_or_default(); + if id_value.is_empty() { + errors.push(ImportPersonError { + line: line_number, + message: "ID saknas.".to_string(), + }); + continue; + } + + let id = match id_value.parse::() { + Ok(value) => value, + Err(_) => { + errors.push(ImportPersonError { + line: line_number, + message: format!("Ogiltigt ID-värde: {id_value}"), + }); + continue; + } + }; + + let first_name = record + .get(1) + .map(|value| value.trim().to_string()) + .unwrap_or_default(); + if first_name.is_empty() { + errors.push(ImportPersonError { + line: line_number, + message: "Förnamn saknas.".to_string(), + }); + continue; + } + + let last_name = record + .get(2) + .map(|value| value.trim().to_string()) + .unwrap_or_default(); + if last_name.is_empty() { + errors.push(ImportPersonError { + line: line_number, + message: "Efternamn saknas.".to_string(), + }); + continue; + } + + let grade = record + .get(3) + .map(|value| value.trim()) + .filter(|value| !value.is_empty()) + .map(|value| value.parse::()); + + let grade = match grade.transpose() { + Ok(value) => value, + Err(_) => { + errors.push(ImportPersonError { + line: line_number, + message: "Ogiltigt klassvärde.".to_string(), + }); + continue; + } + }; + + if let Some(value) = grade { + if value < 0 { + errors.push(ImportPersonError { + line: line_number, + message: "Klass måste vara ett tal större än eller lika med 0.".to_string(), + }); + continue; + } + } + + let parent_name = record + .get(4) + .map(|value| value.trim()) + .filter(|value| !value.is_empty()) + .map(|value| value.to_string()); + + let parent_phone_number = + normalize_phone_number_lenient(record.get(5).map(|value| value.trim().to_string())); + + let visitor = match parse_optional_bool(record.get(6)) { + Ok(value) => value.unwrap_or(false), + Err(message) => { + errors.push(ImportPersonError { + line: line_number, + message, + }); + continue; + } + }; + + let sleeping_spot = match parse_optional_bool(record.get(7)) { + Ok(value) => value.unwrap_or(false), + Err(message) => { + errors.push(ImportPersonError { + line: line_number, + message, + }); + continue; + } + }; + + let result = sqlx::query( + r#" + INSERT INTO persons ( + id, + first_name, + last_name, + grade, + parent_name, + parent_phone_number, + checked_in, + inside, + visitor, + sleeping_spot + ) VALUES ($1, $2, $3, $4, $5, $6, FALSE, FALSE, $7, $8) + ON CONFLICT (id) DO UPDATE SET + first_name = EXCLUDED.first_name, + last_name = EXCLUDED.last_name, + grade = EXCLUDED.grade, + parent_name = EXCLUDED.parent_name, + parent_phone_number = EXCLUDED.parent_phone_number, + checked_in = EXCLUDED.checked_in, + inside = EXCLUDED.inside, + visitor = EXCLUDED.visitor, + sleeping_spot = EXCLUDED.sleeping_spot + RETURNING + id, + first_name, + last_name, + grade, + parent_name, + parent_phone_number, + checked_in, + inside, + visitor, + sleeping_spot, + (xmax = 0) AS inserted + "#, + ) + .bind(id) + .bind(&first_name) + .bind(&last_name) + .bind(grade) + .bind(parent_name.clone()) + .bind(parent_phone_number.clone()) + .bind(visitor) + .bind(sleeping_spot) + .fetch_one(&state.db) + .await; + + match result { + Ok(row) => { + let person = match build_person_from_row(&row) { + Ok(person) => person, + Err(message) => { + errors.push(ImportPersonError { + line: line_number, + message, + }); + continue; + } + }; + + let inserted = row.try_get::("inserted").unwrap_or(false); + + if inserted { + imported += 1; + } else { + updated += 1; + } + + let response: PersonResponse = person.into(); + let _ = state + .event_sender + .send(AppEvent::PersonUpdated { person: response }); + } + Err(err) => { + eprintln!("Failed to upsert person during import: {err:?}"); + errors.push(ImportPersonError { + line: line_number, + message: "Kunde inte spara personen i databasen.".to_string(), + }); + } + } + } + + Ok(Json(ImportPersonsResponse { + imported, + updated, + failed: errors.len(), + errors, + })) +} + +fn parse_optional_bool(value: Option<&str>) -> Result, String> { + let raw = match value { + Some(v) => v.trim(), + None => return Ok(None), + }; + + if raw.is_empty() { + return Ok(Some(false)); + } + + let normalized = raw.to_lowercase(); + match normalized.as_str() { + "1" | "true" | "t" | "ja" | "yes" | "y" => Ok(Some(true)), + "0" | "false" | "f" | "nej" | "no" | "n" => Ok(Some(false)), + other => Err(format!("Ogiltigt booleanvärde: {other}")), + } +} + +fn normalize_phone_number(value: Option) -> Result, String> { + let raw = match value { + Some(v) => { + let trimmed = v.trim(); + if trimmed.is_empty() { + return Ok(None); + } + trimmed.to_string() + } + None => return Ok(None), + }; + + let mut digits: String = raw.chars().filter(|c| c.is_ascii_digit()).collect(); + + if digits.is_empty() { + return Err("Ange ett telefonnummer.".to_string()); + } + + if digits.starts_with("0046") { + digits = digits[4..].to_string(); + } + + if digits.starts_with("46") && digits.len() > 10 { + digits = digits[2..].to_string(); + } + + if digits.len() == 9 && digits.starts_with('7') { + digits = format!("0{digits}"); + } + + if digits.len() == 10 && !digits.starts_with('0') && digits.starts_with('7') { + digits = format!("0{}", &digits[1..]); + } + + if digits.len() != 10 || !digits.starts_with('0') { + return Err("Telefonnumret måste innehålla tio siffror och börja med 0.".to_string()); + } + + Ok(Some(digits)) +} + +fn normalize_phone_number_lenient(value: Option) -> Option { + match normalize_phone_number(value) { + Ok(result) => result, + Err(_) => None, + } +} + +fn build_person_from_row(row: &PgRow) -> Result { + let id = row + .try_get::("id") + .map_err(|err| format!("Kunde inte läsa id: {err}"))?; + let first_name = row + .try_get::("first_name") + .map_err(|err| format!("Kunde inte läsa förnamn: {err}"))?; + let last_name = row + .try_get::("last_name") + .map_err(|err| format!("Kunde inte läsa efternamn: {err}"))?; + let grade = row + .try_get::, _>("grade") + .map_err(|err| format!("Kunde inte läsa klass: {err}"))?; + let parent_name = row + .try_get::, _>("parent_name") + .map_err(|err| format!("Kunde inte läsa vårdnadshavare: {err}"))?; + let parent_phone_number = row + .try_get::, _>("parent_phone_number") + .map_err(|err| format!("Kunde inte läsa telefonnummer: {err}"))?; + let checked_in = row + .try_get::("checked_in") + .map_err(|err| format!("Kunde inte läsa incheckningsstatus: {err}"))?; + let inside = row + .try_get::("inside") + .map_err(|err| format!("Kunde inte läsa inne-status: {err}"))?; + let visitor = row + .try_get::("visitor") + .map_err(|err| format!("Kunde inte läsa besökarstatus: {err}"))?; + let sleeping_spot = row + .try_get::("sleeping_spot") + .map_err(|err| format!("Kunde inte läsa sovplatsstatus: {err}"))?; + + Ok(Person { + id, + first_name, + last_name, + grade, + parent_name, + parent_phone_number, + checked_in, + inside, + visitor, + sleeping_spot, + }) +} diff --git a/api/src/seed.rs b/api/src/seed.rs index f0e71d0..921cbe6 100644 --- a/api/src/seed.rs +++ b/api/src/seed.rs @@ -4,7 +4,6 @@ use sqlx::PgPool; pub async fn run(pool: &PgPool, admin_username: &str, admin_password: &str) -> anyhow::Result<()> { ensure_admin_user(pool, admin_username, admin_password).await?; - ensure_person_seed(pool).await?; Ok(()) } @@ -30,134 +29,3 @@ async fn ensure_admin_user(pool: &PgPool, username: &str, password: &str) -> any Ok(()) } - -async fn ensure_person_seed(pool: &PgPool) -> anyhow::Result<()> { - let count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM persons") - .fetch_one(pool) - .await - .context("Kunde inte räkna personer i databasen")?; - - if count > 0 { - return Ok(()); - } - - let persons = generate_people(); - - for person in persons { - sqlx::query( - r#" - INSERT INTO persons ( - first_name, - last_name, - grade, - parent_name, - parent_phone_number, - checked_in, - inside, - visitor, - sleeping_spot - ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) - "#, - ) - .bind(&person.first_name) - .bind(&person.last_name) - .bind(person.grade) - .bind(&person.parent_name) - .bind(&person.parent_phone_number) - .bind(person.checked_in) - .bind(person.inside) - .bind(person.visitor) - .bind(person.sleeping_spot) - .execute(pool) - .await - .context("Misslyckades att lägga till seed-person")?; - } - - Ok(()) -} - -struct PersonSeed { - first_name: String, - last_name: String, - grade: i32, - parent_name: String, - parent_phone_number: String, - checked_in: bool, - inside: bool, - visitor: bool, - sleeping_spot: bool, -} - -fn generate_people() -> Vec { - let first_names = [ - "Alex", "Bianca", "Cecilia", "David", "Elias", "Fatima", "Gabriel", "Hanna", "Isak", - "Johanna", "Karin", "Liam", "Maja", "Nils", "Olivia", - ]; - - let last_names = [ - "Andersson", - "Berg", - "Carlsson", - "Dahl", - "Ek", - "Fransson", - "Gustafsson", - "Holm", - "Isaksson", - "Johansson", - ]; - - let guardian_first_names = [ - "Anna", - "Bertil", - "Charlotte", - "Daniel", - "Emma", - "Fredrik", - "Greta", - "Henrik", - "Ingrid", - "Jakob", - "Klara", - "Lars", - "Maria", - "Niklas", - "Petra", - ]; - - let guardian_last_names = [ - "Lind", "Sandberg", "Forsberg", "Nyström", "Sjöberg", "Viklund", "Ågren", "Öberg", - "Boström", "Engman", - ]; - - let mut people = Vec::with_capacity(first_names.len() * last_names.len()); - - let mut idx: usize = 0; - for first in &first_names { - for last in &last_names { - let grade = 1 + ((idx * 3) % 9) as i32; // Grades between 1 and 9 - let parent_first = guardian_first_names[idx % guardian_first_names.len()]; - let parent_last = guardian_last_names[idx % guardian_last_names.len()]; - let parent_name = format!("{} {}", parent_first, parent_last); - let parent_phone_number = format!("070{:03}{:04}", idx % 1_000, (idx * 37) % 10_000); - let visitor = idx % 7 == 0; - let sleeping_spot = !visitor && grade >= 3 && idx % 5 == 0; - - people.push(PersonSeed { - first_name: (*first).to_string(), - last_name: (*last).to_string(), - grade, - parent_name, - parent_phone_number, - checked_in: false, - inside: false, - visitor, - sleeping_spot, - }); - idx += 1; - } - } - - people -} diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..3d79b0b --- /dev/null +++ b/bun.lock @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "devDependencies": { + "dotenv": "^17.2.2", + }, + }, + }, + "packages": { + "dotenv": ["dotenv@17.2.2", "", {}, "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q=="], + } +} diff --git a/elever.csv b/elever.csv new file mode 100644 index 0000000..18aa667 --- /dev/null +++ b/elever.csv @@ -0,0 +1,101 @@ +1,Erik,Olsson,2,Kristina Hedlund,0715443884,TRUE,Ja +2,Agnes,Wikström,2,Göran Lindberg,0718986842,Nej,0 +3,Axel,Olsson,6,Leif Nyström,0742003913,Ja,true +4,Ella,Björk,8,Ulla Lindberg,0736096888,ja,ja +5,Karin,Wikström,4,Nils Lundqvist,+46790136956,ja,ja +6,Axel,Sandberg,4,Camilla Bergström,0795131296,0,true +7,Axel,Sandberg,2,Bengt Bergström,0764495298,NEJ,false +8,Nora,Nyström,8,Per Gustafsson,0709921715,False,Nej +9,Axel,Bergström,1,Per Bergström,0723222203,true,NEJ +10,Axel,Nilsson,7,Hans Persson,0765709100,TRUE,Nej +11,Anna,Gustafsson,5,Per Nyström,+46797499972,Nej,false +12,Karin,Nyström,9,Mats Holm,0716514512,FALSE,false +12,Karin,Nyström,9,Mats Holm,0716514512,FALSE,false +13,Filip,Hedlund,,,,NEJ,TRUE +14,Ella,Björk,1,Leif Lundqvist,0774,NEJ,False +15,Elias,Pettersson,1,Helena Björk,0703457913,FALSE,true +16,Sara,Sandberg,3,Camilla Nilsson,+46747453546,JA,JA +17,Maja,Larsson,5,Göran Sandberg,0743341991,Nej,NEJ +18,Anna,Björk,1,Ulla Holm,0798020350,Nej,False +19,Karin,Björk,8,Nils Lindberg,+46706593579,False,false +20,William,Svensson,1,Kristina Persson,0713455222,true,Nej +21,Ella,Johansson,6,Monica Karlsson,0789734550,TRUE,TRUE +22,Elias,Svensson,7,Helena Holm,0721983460,ja,1 +23,Agnes,Lindberg,3,Annika Persson,+46735691723,FALSE,Ja +24,Hugo,Pettersson,9,Per Nilsson,0734661892,Nej,TRUE +25,Emma,Nyström,4,Anita Karlsson,0763459821,true,false +26,Filip,Olsson,2,Göran Holm,+46712457892,TRUE,NEJ +27,Sara,Wikström,1,Lisa Larsson,0789463720,0,True +28,William,Lundqvist,8,Leif Pettersson,0703948572,TRUE,false +29,Nora,Gustafsson,5,Monica Sandberg,+46786109273,false,JA +30,Axel,Sjöberg,7,Kristina Karlsson,0709485721,False,Nej +31,Ella,Bergström,6,Hans Persson,0749283746,ja,0 +32,Karin,Larsson,8,Eva Hedlund,+46791827365,TRUE,TRUE +33,Lars,Nyström,2,Bengt Olsson,0781928374,false,Nej +34,Emma,Olsson,3,Anita Bergström,+46776543219,JA,FALSE +35,Hugo,Björk,4,Nils Karlsson,0719283745,TRUE,ja +36,Elias,Lundqvist,6,Göran Persson,0739182734,0,TRUE +37,Agnes,Wikström,9,Ulla Holm,0791283746,Nej,false +38,Oskar,Hedlund,1,Per Larsson,0771827364,FALSE,Nej +39,Maja,Johansson,5,Helena Olsson,0709182736,true,TRUE +40,William,Karlsson,7,Annika Svensson,0799182735,TRUE,0 +41,Linnea,Bergström,9,Mats Nyström,0748273645,false,False +42,Filip,Sjöberg,8,Lisa Karlsson,+46777731284,TRUE,NEJ +43,Anna,Persson,4,Sofia Bergström,+46791928374,Nej,TRUE +44,Elias,Nilsson,3,Kristina Holm,0709182374,False,Ja +45,Agnes,Holm,1,Leif Pettersson,0739182735,JA,FALSE +46,Axel,Lundqvist,7,Anita Nilsson,0709128374,true,Nej +47,Sara,Lindberg,6,Per Karlsson,+46791827366,TRUE,true +48,Oskar,Nyström,5,Monica Olsson,0719283746,false,TRUE +49,Emma,Wikström,9,Nils Larsson,+46765432109,Nej,False +50,Karin,Pettersson,2,Lisa Sandberg,0709823471,TRUE,ja +51,Ella,Svensson,1,Hans Holm,+46789123456,FALSE,NEJ +52,Lars,Gustafsson,8,Ulla Bergström,0771238945,ja,Nej +53,Agnes,Olsson,3,Mats Persson,0791283741,true,TRUE +54,William,Hedlund,4,Sofia Nilsson,0718273648,False,false +55,Linnea,Nyström,6,Bengt Karlsson,+46734567219,JA,TRUE +56,Anders,Lindberg,2,Eva Holm,0709182364,FALSE,Nej +57,Elias,Persson,7,Leif Larsson,0739182736,Nej,Ja +58,Maria,Sjöberg,5,Monica Olsson,+46798765432,TRUE,false +59,Filip,Lundqvist,9,Hans Svensson,0709182739,false,TRUE +60,Nora,Wikström,8,Göran Karlsson,+46719283746,TRUE,Nej +61,Emma,Eriksson,1,Kristina Nilsson,0799182734,ja,FALSE +62,Ella,Pettersson,7,Per Persson,+46791823647,False,Ja +63,Agnes,Lindberg,6,Annika Bergström,0719283741,TRUE,TRUE +64,Axel,Nyström,2,Lisa Hedlund,+46798237461,true,false +65,Linnea,Svensson,5,Mats Johansson,0709182735,Nej,TRUE +66,Hugo,Björk,9,Helena Karlsson,0779182734,FALSE,NEJ +67,Karin,Gustafsson,4,Nils Larsson,0799182738,TRUE,Nej +68,Oskar,Holm,3,Anita Olsson,+46712398765,false,TRUE +69,Elias,Larsson,7,Per Sandberg,0709182736,ja,False +70,Maja,Bergström,8,Göran Pettersson,+46719283746,TRUE,ja +71,Sara,Lindberg,2,Lisa Holm,0719283746,FALSE,Nej +72,Anders,Wikström,6,Annika Karlsson,0709182734,TRUE,TRUE +73,Emma,Nilsson,1,Leif Gustafsson,+46798237461,Nej,0 +74,Lars,Persson,9,Monica Olsson,0739182734,true,TRUE +75,Agnes,Karlsson,8,Kristina Holm,0709182736,TRUE,False +76,Axel,Lindberg,4,Hans Nilsson,+46791827364,FALSE,TRUE +77,Nora,Sjöberg,5,Ulla Persson,0709182738,true,Ja +78,William,Lundqvist,2,Sofia Karlsson,+46718273645,Nej,FALSE +79,Ella,Olsson,3,Per Holm,0799182735,TRUE,true +80,Erik,Björk,7,Göran Larsson,+46798237461,ja,Nej +81,Maria,Gustafsson,6,Annika Persson,0709182739,TRUE,FALSE +82,Hugo,Nyström,1,Helena Karlsson,0781928374,False,Nej +83,Karin,Pettersson,9,Mats Bergström,0709182736,true,TRUE +84,Filip,Svensson,8,Monica Nilsson,+46791827362,TRUE,Ja +85,Agnes,Hedlund,4,Nils Olsson,0709182735,false,false +86,William,Wikström,7,Eva Holm,+46791827361,TRUE,NEJ +87,Elias,Johansson,5,Per Larsson,0729182735,FALSE,Ja +88,Ella,Larsson,6,Lisa Bergström,0709182739,TRUE,TRUE +89,Axel,Sjöberg,2,Bengt Nilsson,0709182738,ja,Nej +90,Sara,Olsson,3,Monica Persson,+46719283746,False,TRUE +91,Oskar,Nyström,1,Helena Karlsson,0799182734,TRUE,false +92,Emma,Gustafsson,9,Leif Larsson,0709182736,FALSE,Nej +93,Lars,Bergström,8,Kristina Persson,0739182735,true,Ja +94,Linnea,Hedlund,2,Hans Holm,+46791827363,TRUE,FALSE +95,Agnes,Lindberg,7,Lisa Nilsson,0709182734,false,TRUE +96,Filip,Olsson,4,Per Karlsson,0709182736,Nej,TRUE +97,Elias,Persson,6,Monica Bergström,0799182735,TRUE,False +98,Nora,Johansson,5,Sofia Holm,+46791827367,FALSE,Ja +99,Axel,Wikström,3,Bengt Olsson,0709182735,TRUE,TRUE +100,Emma,Nyström,8,Anita Persson,+46791827368,false,Nej diff --git a/node_modules/dotenv/CHANGELOG.md b/node_modules/dotenv/CHANGELOG.md new file mode 100644 index 0000000..c080800 --- /dev/null +++ b/node_modules/dotenv/CHANGELOG.md @@ -0,0 +1,592 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.2.2...master) + +## [17.2.2](https://github.com/motdotla/dotenv/compare/v17.2.1...v17.2.2) (2025-09-02) + +### Added + +- 🙏 A big thank you to new sponsor [Tuple.app](https://tuple.app/dotenv) - *the premier screen sharing app for developers on macOS and Windows.* Go check them out. It's wonderful and generous of them to give back to open source by sponsoring dotenv. Give them some love back. + +## [17.2.1](https://github.com/motdotla/dotenv/compare/v17.2.0...v17.2.1) (2025-07-24) + +### Changed + +* Fix clickable tip links by removing parentheses ([#897](https://github.com/motdotla/dotenv/pull/897)) + +## [17.2.0](https://github.com/motdotla/dotenv/compare/v17.1.0...v17.2.0) (2025-07-09) + +### Added + +* Optionally specify `DOTENV_CONFIG_QUIET=true` in your environment or `.env` file to quiet the runtime log ([#889](https://github.com/motdotla/dotenv/pull/889)) +* Just like dotenv any `DOTENV_CONFIG_` environment variables take precedence over any code set options like `({quiet: false})` + +```ini +# .env +DOTENV_CONFIG_QUIET=true +HELLO="World" +``` +```js +// index.js +require('dotenv').config() +console.log(`Hello ${process.env.HELLO}`) +``` +```sh +$ node index.js +Hello World + +or + +$ DOTENV_CONFIG_QUIET=true node index.js +``` + +## [17.1.0](https://github.com/motdotla/dotenv/compare/v17.0.1...v17.1.0) (2025-07-07) + +### Added + +* Add additional security and configuration tips to the runtime log ([#884](https://github.com/motdotla/dotenv/pull/884)) +* Dim the tips text from the main injection information text + +```js +const TIPS = [ + '🔐 encrypt with dotenvx: https://dotenvx.com', + '🔐 prevent committing .env to code: https://dotenvx.com/precommit', + '🔐 prevent building .env in docker: https://dotenvx.com/prebuild', + '🛠️ run anywhere with `dotenvx run -- yourcommand`', + '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', + '⚙️ enable debug logging with { debug: true }', + '⚙️ override existing env vars with { override: true }', + '⚙️ suppress all logs with { quiet: true }', + '⚙️ write to custom object with { processEnv: myObject }', + '⚙️ load multiple .env files with { path: [\'.env.local\', \'.env\'] }' +] +``` + +## [17.0.1](https://github.com/motdotla/dotenv/compare/v17.0.0...v17.0.1) (2025-07-01) + +### Changed + +* Patched injected log to count only populated/set keys to process.env ([#879](https://github.com/motdotla/dotenv/pull/879)) + +## [17.0.0](https://github.com/motdotla/dotenv/compare/v16.6.1...v17.0.0) (2025-06-27) + +### Changed + +- Default `quiet` to false - informational (file and keys count) runtime log message shows by default ([#875](https://github.com/motdotla/dotenv/pull/875)) + +## [16.6.1](https://github.com/motdotla/dotenv/compare/v16.6.0...v16.6.1) (2025-06-27) + +### Changed + +- Default `quiet` to true – hiding the runtime log message ([#874](https://github.com/motdotla/dotenv/pull/874)) +- NOTICE: 17.0.0 will be released with quiet defaulting to false. Use `config({ quiet: true })` to suppress. +- And check out the new [dotenvx](https://github.com/dotenvx/dotenvx). As coding workflows evolve and agents increasingly handle secrets, encrypted .env files offer a much safer way to deploy both agents and code together with secure secrets. Simply switch `require('dotenv').config()` for `require('@dotenvx/dotenvx').config()`. + +## [16.6.0](https://github.com/motdotla/dotenv/compare/v16.5.0...v16.6.0) (2025-06-26) + +### Added + +- Default log helpful message `[dotenv@16.6.0] injecting env (1) from .env` ([#870](https://github.com/motdotla/dotenv/pull/870)) +- Use `{ quiet: true }` to suppress +- Aligns dotenv more closely with [dotenvx](https://github.com/dotenvx/dotenvx). + +## [16.5.0](https://github.com/motdotla/dotenv/compare/v16.4.7...v16.5.0) (2025-04-07) + +### Added + +- 🎉 Added new sponsor [Graphite](https://graphite.dev/?utm_source=github&utm_medium=repo&utm_campaign=dotenv) - *the AI developer productivity platform helping teams on GitHub ship higher quality software, faster*. + +> [!TIP] +> **[Become a sponsor](https://github.com/sponsors/motdotla)** +> +> The dotenvx README is viewed thousands of times DAILY on GitHub and NPM. +> Sponsoring dotenv is a great way to get in front of developers and give back to the developer community at the same time. + +### Changed + +- Remove `_log` method. Use `_debug` [#862](https://github.com/motdotla/dotenv/pull/862) + +## [16.4.7](https://github.com/motdotla/dotenv/compare/v16.4.6...v16.4.7) (2024-12-03) + +### Changed + +- Ignore `.tap` folder when publishing. (oops, sorry about that everyone. - @motdotla) [#848](https://github.com/motdotla/dotenv/pull/848) + +## [16.4.6](https://github.com/motdotla/dotenv/compare/v16.4.5...v16.4.6) (2024-12-02) + +### Changed + +- Clean up stale dev dependencies [#847](https://github.com/motdotla/dotenv/pull/847) +- Various README updates clarifying usage and alternative solutions using [dotenvx](https://github.com/dotenvx/dotenvx) + +## [16.4.5](https://github.com/motdotla/dotenv/compare/v16.4.4...v16.4.5) (2024-02-19) + +### Changed + +- 🐞 Fix recent regression when using `path` option. return to historical behavior: do not attempt to auto find `.env` if `path` set. (regression was introduced in `16.4.3`) [#814](https://github.com/motdotla/dotenv/pull/814) + +## [16.4.4](https://github.com/motdotla/dotenv/compare/v16.4.3...v16.4.4) (2024-02-13) + +### Changed + +- 🐞 Replaced chaining operator `?.` with old school `&&` (fixing node 12 failures) [#812](https://github.com/motdotla/dotenv/pull/812) + +## [16.4.3](https://github.com/motdotla/dotenv/compare/v16.4.2...v16.4.3) (2024-02-12) + +### Changed + +- Fixed processing of multiple files in `options.path` [#805](https://github.com/motdotla/dotenv/pull/805) + +## [16.4.2](https://github.com/motdotla/dotenv/compare/v16.4.1...v16.4.2) (2024-02-10) + +### Changed + +- Changed funding link in package.json to [`dotenvx.com`](https://dotenvx.com) + +## [16.4.1](https://github.com/motdotla/dotenv/compare/v16.4.0...v16.4.1) (2024-01-24) + +- Patch support for array as `path` option [#797](https://github.com/motdotla/dotenv/pull/797) + +## [16.4.0](https://github.com/motdotla/dotenv/compare/v16.3.2...v16.4.0) (2024-01-23) + +- Add `error.code` to error messages around `.env.vault` decryption handling [#795](https://github.com/motdotla/dotenv/pull/795) +- Add ability to find `.env.vault` file when filename(s) passed as an array [#784](https://github.com/motdotla/dotenv/pull/784) + +## [16.3.2](https://github.com/motdotla/dotenv/compare/v16.3.1...v16.3.2) (2024-01-18) + +### Added + +- Add debug message when no encoding set [#735](https://github.com/motdotla/dotenv/pull/735) + +### Changed + +- Fix output typing for `populate` [#792](https://github.com/motdotla/dotenv/pull/792) +- Use subarray instead of slice [#793](https://github.com/motdotla/dotenv/pull/793) + +## [16.3.1](https://github.com/motdotla/dotenv/compare/v16.3.0...v16.3.1) (2023-06-17) + +### Added + +- Add missing type definitions for `processEnv` and `DOTENV_KEY` options. [#756](https://github.com/motdotla/dotenv/pull/756) + +## [16.3.0](https://github.com/motdotla/dotenv/compare/v16.2.0...v16.3.0) (2023-06-16) + +### Added + +- Optionally pass `DOTENV_KEY` to options rather than relying on `process.env.DOTENV_KEY`. Defaults to `process.env.DOTENV_KEY` [#754](https://github.com/motdotla/dotenv/pull/754) + +## [16.2.0](https://github.com/motdotla/dotenv/compare/v16.1.4...v16.2.0) (2023-06-15) + +### Added + +- Optionally write to your own target object rather than `process.env`. Defaults to `process.env`. [#753](https://github.com/motdotla/dotenv/pull/753) +- Add import type URL to types file [#751](https://github.com/motdotla/dotenv/pull/751) + +## [16.1.4](https://github.com/motdotla/dotenv/compare/v16.1.3...v16.1.4) (2023-06-04) + +### Added + +- Added `.github/` to `.npmignore` [#747](https://github.com/motdotla/dotenv/pull/747) + +## [16.1.3](https://github.com/motdotla/dotenv/compare/v16.1.2...v16.1.3) (2023-05-31) + +### Removed + +- Removed `browser` keys for `path`, `os`, and `crypto` in package.json. These were set to false incorrectly as of 16.1. Instead, if using dotenv on the front-end make sure to include polyfills for `path`, `os`, and `crypto`. [node-polyfill-webpack-plugin](https://github.com/Richienb/node-polyfill-webpack-plugin) provides these. + +## [16.1.2](https://github.com/motdotla/dotenv/compare/v16.1.1...v16.1.2) (2023-05-31) + +### Changed + +- Exposed private function `_configDotenv` as `configDotenv`. [#744](https://github.com/motdotla/dotenv/pull/744) + +## [16.1.1](https://github.com/motdotla/dotenv/compare/v16.1.0...v16.1.1) (2023-05-30) + +### Added + +- Added type definition for `decrypt` function + +### Changed + +- Fixed `{crypto: false}` in `packageJson.browser` + +## [16.1.0](https://github.com/motdotla/dotenv/compare/v16.0.3...v16.1.0) (2023-05-30) + +### Added + +- Add `populate` convenience method [#733](https://github.com/motdotla/dotenv/pull/733) +- Accept URL as path option [#720](https://github.com/motdotla/dotenv/pull/720) +- Add dotenv to `npm fund` command +- Spanish language README [#698](https://github.com/motdotla/dotenv/pull/698) +- Add `.env.vault` support. 🎉 ([#730](https://github.com/motdotla/dotenv/pull/730)) + +ℹ️ `.env.vault` extends the `.env` file format standard with a localized encrypted vault file. Package it securely with your production code deploys. It's cloud agnostic so that you can deploy your secrets anywhere – without [risky third-party integrations](https://techcrunch.com/2023/01/05/circleci-breach/). [read more](https://github.com/motdotla/dotenv#-deploying) + +### Changed + +- Fixed "cannot resolve 'fs'" error on tools like Replit [#693](https://github.com/motdotla/dotenv/pull/693) + +## [16.0.3](https://github.com/motdotla/dotenv/compare/v16.0.2...v16.0.3) (2022-09-29) + +### Changed + +- Added library version to debug logs ([#682](https://github.com/motdotla/dotenv/pull/682)) + +## [16.0.2](https://github.com/motdotla/dotenv/compare/v16.0.1...v16.0.2) (2022-08-30) + +### Added + +- Export `env-options.js` and `cli-options.js` in package.json for use with downstream [dotenv-expand](https://github.com/motdotla/dotenv-expand) module + +## [16.0.1](https://github.com/motdotla/dotenv/compare/v16.0.0...v16.0.1) (2022-05-10) + +### Changed + +- Minor README clarifications +- Development ONLY: updated devDependencies as recommended for development only security risks ([#658](https://github.com/motdotla/dotenv/pull/658)) + +## [16.0.0](https://github.com/motdotla/dotenv/compare/v15.0.1...v16.0.0) (2022-02-02) + +### Added + +- _Breaking:_ Backtick support 🎉 ([#615](https://github.com/motdotla/dotenv/pull/615)) + +If you had values containing the backtick character, please quote those values with either single or double quotes. + +## [15.0.1](https://github.com/motdotla/dotenv/compare/v15.0.0...v15.0.1) (2022-02-02) + +### Changed + +- Properly parse empty single or double quoted values 🐞 ([#614](https://github.com/motdotla/dotenv/pull/614)) + +## [15.0.0](https://github.com/motdotla/dotenv/compare/v14.3.2...v15.0.0) (2022-01-31) + +`v15.0.0` is a major new release with some important breaking changes. + +### Added + +- _Breaking:_ Multiline parsing support (just works. no need for the flag.) + +### Changed + +- _Breaking:_ `#` marks the beginning of a comment (UNLESS the value is wrapped in quotes. Please update your `.env` files to wrap in quotes any values containing `#`. For example: `SECRET_HASH="something-with-a-#-hash"`). + +..Understandably, (as some teams have noted) this is tedious to do across the entire team. To make it less tedious, we recommend using [dotenv cli](https://github.com/dotenv-org/cli) going forward. It's an optional plugin that will keep your `.env` files in sync between machines, environments, or team members. + +### Removed + +- _Breaking:_ Remove multiline option (just works out of the box now. no need for the flag.) + +## [14.3.2](https://github.com/motdotla/dotenv/compare/v14.3.1...v14.3.2) (2022-01-25) + +### Changed + +- Preserve backwards compatibility on values containing `#` 🐞 ([#603](https://github.com/motdotla/dotenv/pull/603)) + +## [14.3.1](https://github.com/motdotla/dotenv/compare/v14.3.0...v14.3.1) (2022-01-25) + +### Changed + +- Preserve backwards compatibility on exports by re-introducing the prior in-place exports 🐞 ([#606](https://github.com/motdotla/dotenv/pull/606)) + +## [14.3.0](https://github.com/motdotla/dotenv/compare/v14.2.0...v14.3.0) (2022-01-24) + +### Added + +- Add `multiline` option 🎉 ([#486](https://github.com/motdotla/dotenv/pull/486)) + +## [14.2.0](https://github.com/motdotla/dotenv/compare/v14.1.1...v14.2.0) (2022-01-17) + +### Added + +- Add `dotenv_config_override` cli option +- Add `DOTENV_CONFIG_OVERRIDE` command line env option + +## [14.1.1](https://github.com/motdotla/dotenv/compare/v14.1.0...v14.1.1) (2022-01-17) + +### Added + +- Add React gotcha to FAQ on README + +## [14.1.0](https://github.com/motdotla/dotenv/compare/v14.0.1...v14.1.0) (2022-01-17) + +### Added + +- Add `override` option 🎉 ([#595](https://github.com/motdotla/dotenv/pull/595)) + +## [14.0.1](https://github.com/motdotla/dotenv/compare/v14.0.0...v14.0.1) (2022-01-16) + +### Added + +- Log error on failure to load `.env` file ([#594](https://github.com/motdotla/dotenv/pull/594)) + +## [14.0.0](https://github.com/motdotla/dotenv/compare/v13.0.1...v14.0.0) (2022-01-16) + +### Added + +- _Breaking:_ Support inline comments for the parser 🎉 ([#568](https://github.com/motdotla/dotenv/pull/568)) + +## [13.0.1](https://github.com/motdotla/dotenv/compare/v13.0.0...v13.0.1) (2022-01-16) + +### Changed + +* Hide comments and newlines from debug output ([#404](https://github.com/motdotla/dotenv/pull/404)) + +## [13.0.0](https://github.com/motdotla/dotenv/compare/v12.0.4...v13.0.0) (2022-01-16) + +### Added + +* _Breaking:_ Add type file for `config.js` ([#539](https://github.com/motdotla/dotenv/pull/539)) + +## [12.0.4](https://github.com/motdotla/dotenv/compare/v12.0.3...v12.0.4) (2022-01-16) + +### Changed + +* README updates +* Minor order adjustment to package json format + +## [12.0.3](https://github.com/motdotla/dotenv/compare/v12.0.2...v12.0.3) (2022-01-15) + +### Changed + +* Simplified jsdoc for consistency across editors + +## [12.0.2](https://github.com/motdotla/dotenv/compare/v12.0.1...v12.0.2) (2022-01-15) + +### Changed + +* Improve embedded jsdoc type documentation + +## [12.0.1](https://github.com/motdotla/dotenv/compare/v12.0.0...v12.0.1) (2022-01-15) + +### Changed + +* README updates and clarifications + +## [12.0.0](https://github.com/motdotla/dotenv/compare/v11.0.0...v12.0.0) (2022-01-15) + +### Removed + +- _Breaking:_ drop support for Flow static type checker ([#584](https://github.com/motdotla/dotenv/pull/584)) + +### Changed + +- Move types/index.d.ts to lib/main.d.ts ([#585](https://github.com/motdotla/dotenv/pull/585)) +- Typescript cleanup ([#587](https://github.com/motdotla/dotenv/pull/587)) +- Explicit typescript inclusion in package.json ([#566](https://github.com/motdotla/dotenv/pull/566)) + +## [11.0.0](https://github.com/motdotla/dotenv/compare/v10.0.0...v11.0.0) (2022-01-11) + +### Changed + +- _Breaking:_ drop support for Node v10 ([#558](https://github.com/motdotla/dotenv/pull/558)) +- Patch debug option ([#550](https://github.com/motdotla/dotenv/pull/550)) + +## [10.0.0](https://github.com/motdotla/dotenv/compare/v9.0.2...v10.0.0) (2021-05-20) + +### Added + +- Add generic support to parse function +- Allow for import "dotenv/config.js" +- Add support to resolve home directory in path via ~ + +## [9.0.2](https://github.com/motdotla/dotenv/compare/v9.0.1...v9.0.2) (2021-05-10) + +### Changed + +- Support windows newlines with debug mode + +## [9.0.1](https://github.com/motdotla/dotenv/compare/v9.0.0...v9.0.1) (2021-05-08) + +### Changed + +- Updates to README + +## [9.0.0](https://github.com/motdotla/dotenv/compare/v8.6.0...v9.0.0) (2021-05-05) + +### Changed + +- _Breaking:_ drop support for Node v8 + +## [8.6.0](https://github.com/motdotla/dotenv/compare/v8.5.1...v8.6.0) (2021-05-05) + +### Added + +- define package.json in exports + +## [8.5.1](https://github.com/motdotla/dotenv/compare/v8.5.0...v8.5.1) (2021-05-05) + +### Changed + +- updated dev dependencies via npm audit + +## [8.5.0](https://github.com/motdotla/dotenv/compare/v8.4.0...v8.5.0) (2021-05-05) + +### Added + +- allow for `import "dotenv/config"` + +## [8.4.0](https://github.com/motdotla/dotenv/compare/v8.3.0...v8.4.0) (2021-05-05) + +### Changed + +- point to exact types file to work with VS Code + +## [8.3.0](https://github.com/motdotla/dotenv/compare/v8.2.0...v8.3.0) (2021-05-05) + +### Changed + +- _Breaking:_ drop support for Node v8 (mistake to be released as minor bump. later bumped to 9.0.0. see above.) + +## [8.2.0](https://github.com/motdotla/dotenv/compare/v8.1.0...v8.2.0) (2019-10-16) + +### Added + +- TypeScript types + +## [8.1.0](https://github.com/motdotla/dotenv/compare/v8.0.0...v8.1.0) (2019-08-18) + +### Changed + +- _Breaking:_ drop support for Node v6 ([#392](https://github.com/motdotla/dotenv/issues/392)) + +# [8.0.0](https://github.com/motdotla/dotenv/compare/v7.0.0...v8.0.0) (2019-05-02) + +### Changed + +- _Breaking:_ drop support for Node v6 ([#302](https://github.com/motdotla/dotenv/issues/392)) + +## [7.0.0] - 2019-03-12 + +### Fixed + +- Fix removing unbalanced quotes ([#376](https://github.com/motdotla/dotenv/pull/376)) + +### Removed + +- Removed `load` alias for `config` for consistency throughout code and documentation. + +## [6.2.0] - 2018-12-03 + +### Added + +- Support preload configuration via environment variables ([#351](https://github.com/motdotla/dotenv/issues/351)) + +## [6.1.0] - 2018-10-08 + +### Added + +- `debug` option for `config` and `parse` methods will turn on logging + +## [6.0.0] - 2018-06-02 + +### Changed + +- _Breaking:_ drop support for Node v4 ([#304](https://github.com/motdotla/dotenv/pull/304)) + +## [5.0.0] - 2018-01-29 + +### Added + +- Testing against Node v8 and v9 +- Documentation on trim behavior of values +- Documentation on how to use with `import` + +### Changed + +- _Breaking_: default `path` is now `path.resolve(process.cwd(), '.env')` +- _Breaking_: does not write over keys already in `process.env` if the key has a falsy value +- using `const` and `let` instead of `var` + +### Removed + +- Testing against Node v7 + +## [4.0.0] - 2016-12-23 + +### Changed + +- Return Object with parsed content or error instead of false ([#165](https://github.com/motdotla/dotenv/pull/165)). + +### Removed + +- `verbose` option removed in favor of returning result. + +## [3.0.0] - 2016-12-20 + +### Added + +- `verbose` option will log any error messages. Off by default. +- parses email addresses correctly +- allow importing config method directly in ES6 + +### Changed + +- Suppress error messages by default ([#154](https://github.com/motdotla/dotenv/pull/154)) +- Ignoring more files for NPM to make package download smaller + +### Fixed + +- False positive test due to case-sensitive variable ([#124](https://github.com/motdotla/dotenv/pull/124)) + +### Removed + +- `silent` option removed in favor of `verbose` + +## [2.0.0] - 2016-01-20 + +### Added + +- CHANGELOG to ["make it easier for users and contributors to see precisely what notable changes have been made between each release"](http://keepachangelog.com/). Linked to from README +- LICENSE to be more explicit about what was defined in `package.json`. Linked to from README +- Testing nodejs v4 on travis-ci +- added examples of how to use dotenv in different ways +- return parsed object on success rather than boolean true + +### Changed + +- README has shorter description not referencing ruby gem since we don't have or want feature parity + +### Removed + +- Variable expansion and escaping so environment variables are encouraged to be fully orthogonal + +## [1.2.0] - 2015-06-20 + +### Added + +- Preload hook to require dotenv without including it in your code + +### Changed + +- clarified license to be "BSD-2-Clause" in `package.json` + +### Fixed + +- retain spaces in string vars + +## [1.1.0] - 2015-03-31 + +### Added + +- Silent option to silence `console.log` when `.env` missing + +## [1.0.0] - 2015-03-13 + +### Removed + +- support for multiple `.env` files. should always use one `.env` file for the current environment + +[7.0.0]: https://github.com/motdotla/dotenv/compare/v6.2.0...v7.0.0 +[6.2.0]: https://github.com/motdotla/dotenv/compare/v6.1.0...v6.2.0 +[6.1.0]: https://github.com/motdotla/dotenv/compare/v6.0.0...v6.1.0 +[6.0.0]: https://github.com/motdotla/dotenv/compare/v5.0.0...v6.0.0 +[5.0.0]: https://github.com/motdotla/dotenv/compare/v4.0.0...v5.0.0 +[4.0.0]: https://github.com/motdotla/dotenv/compare/v3.0.0...v4.0.0 +[3.0.0]: https://github.com/motdotla/dotenv/compare/v2.0.0...v3.0.0 +[2.0.0]: https://github.com/motdotla/dotenv/compare/v1.2.0...v2.0.0 +[1.2.0]: https://github.com/motdotla/dotenv/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/motdotla/dotenv/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/motdotla/dotenv/compare/v0.4.0...v1.0.0 diff --git a/node_modules/dotenv/LICENSE b/node_modules/dotenv/LICENSE new file mode 100644 index 0000000..c430ad8 --- /dev/null +++ b/node_modules/dotenv/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2015, Scott Motte +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/dotenv/README-es.md b/node_modules/dotenv/README-es.md new file mode 100644 index 0000000..978a73b --- /dev/null +++ b/node_modules/dotenv/README-es.md @@ -0,0 +1,405 @@ +
+🎉 announcing dotenvx. run anywhere, multi-environment, encrypted envs. +
+ +  + +
+ +**Special thanks to [our sponsors](https://github.com/sponsors/motdotla)** + + +
+ Tuple +
+ Tuple, the premier screen sharing app for developers on macOS and Windows. +
+
+
+ +# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) + +dotenv + +Dotenv es un módulo de dependencia cero que carga las variables de entorno desde un archivo `.env` en [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). El almacenamiento de la configuración del entorno separado del código está basado en la metodología [The Twelve-Factor App](http://12factor.net/config). + +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) +[![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) + +## Instalación + +```bash +# instalación local (recomendado) +npm install dotenv --save +``` + +O installación con yarn? `yarn add dotenv` + +## Uso + +Cree un archivo `.env` en la raíz de su proyecto: + +```dosini +S3_BUCKET="YOURS3BUCKET" +SECRET_KEY="YOURSECRETKEYGOESHERE" +``` + +Tan prónto como sea posible en su aplicación, importe y configure dotenv: + +```javascript +require('dotenv').config() +console.log(process.env) // elimine esto después que haya confirmado que esta funcionando +``` + +.. o usa ES6? + +```javascript +import * as dotenv from 'dotenv' // vea en https://github.com/motdotla/dotenv#como-uso-dotenv-con-import +// REVISAR LINK DE REFERENCIA DE IMPORTACIÓN +dotenv.config() +import express from 'express' +``` + +Eso es todo. `process.env` ahora tiene las claves y los valores que definiste en tu archivo `.env`: + +```javascript +require('dotenv').config() + +... + +s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) +``` + +### Valores multilínea + +Si necesita variables de varias líneas, por ejemplo, claves privadas, ahora se admiten en la versión (`>= v15.0.0`) con saltos de línea: + +```dosini +PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- +... +Kh9NV... +... +-----END RSA PRIVATE KEY-----" +``` + +Alternativamente, puede usar comillas dobles y usar el carácter `\n`: + +```dosini +PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY-----\n" +``` + +### Comentarios + +Los comentarios pueden ser agregados en tu archivo o en la misma línea: + +```dosini +# This is a comment +SECRET_KEY=YOURSECRETKEYGOESHERE # comment +SECRET_HASH="something-with-a-#-hash" +``` + +Los comentarios comienzan donde existe un `#`, entonces, si su valor contiene un `#`, enciérrelo entre comillas. Este es un cambio importante desde la versión `>= v15.0.0` en adelante. + +### Análisis + +El motor que analiza el contenido de su archivo que contiene variables de entorno está disponible para su uso. Este Acepta una Cadena o un Búfer y devolverá un Objeto con las claves y los valores analizados. + +```javascript +const dotenv = require('dotenv') +const buf = Buffer.from('BASICO=basico') +const config = dotenv.parse(buf) // devolverá un objeto +console.log(typeof config, config) // objeto { BASICO : 'basico' } +``` + +### Precarga + +Puede usar el `--require` (`-r`) [opción de línea de comando](https://nodejs.org/api/cli.html#-r---require-module) para precargar dotenv. Al hacer esto, no necesita requerir ni cargar dotnev en el código de su aplicación. + +```bash +$ node -r dotenv/config tu_script.js +``` + +Las opciones de configuración a continuación se admiten como argumentos de línea de comandos en el formato `dotenv_config_