@hasna/contacts 0.6.18 → 0.6.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30,13 +30,13 @@ import { join, relative } from "path";
30
30
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "fs";
31
31
  import { homedir as homedir2 } from "os";
32
32
  import { join as join2 } from "path";
33
- import { readdirSync as readdirSync2, existsSync as existsSync3 } from "fs";
34
- import { join as join3 } from "path";
33
+ import { readdirSync as readdirSync3, existsSync as existsSync6 } from "fs";
34
+ import { join as join6 } from "path";
35
+ import { homedir as homedir5 } from "os";
35
36
  import { homedir as homedir3 } from "os";
36
- import { homedir as homedir4 } from "os";
37
- import { join as join4 } from "path";
38
- import { join as join6, dirname } from "path";
39
- import { homedir as homedir5, platform } from "os";
37
+ import { join as join3 } from "path";
38
+ import { join as join5, dirname } from "path";
39
+ import { homedir as homedir4, platform } from "os";
40
40
  function __accessProp(key) {
41
41
  return this[key];
42
42
  }
@@ -907,11 +907,11 @@ function isSyncExcludedTable(table) {
907
907
  return SYNC_EXCLUDED_TABLE_PATTERNS.some((p) => p.test(table));
908
908
  }
909
909
  function discoverServices() {
910
- const dataDir = join3(homedir3(), ".hasna");
911
- if (!existsSync3(dataDir))
910
+ const dataDir = join6(homedir5(), ".hasna");
911
+ if (!existsSync6(dataDir))
912
912
  return [];
913
913
  try {
914
- const entries = readdirSync2(dataDir, { withFileTypes: true });
914
+ const entries = readdirSync3(dataDir, { withFileTypes: true });
915
915
  return entries.filter((e) => {
916
916
  if (!e.isDirectory())
917
917
  return false;
@@ -923,30 +923,30 @@ function discoverServices() {
923
923
  return [];
924
924
  }
925
925
  }
926
- function discoverSyncableServices() {
926
+ function discoverSyncableServices2() {
927
927
  const local = discoverServices();
928
928
  const pgSet = new Set(KNOWN_PG_SERVICES);
929
929
  return local.filter((s) => pgSet.has(s));
930
930
  }
931
931
  function getServiceDbPath(service) {
932
- const dataDir = join3(homedir3(), ".hasna", service);
933
- if (!existsSync3(dataDir))
932
+ const dataDir = join6(homedir5(), ".hasna", service);
933
+ if (!existsSync6(dataDir))
934
934
  return null;
935
935
  const candidates = [
936
- join3(dataDir, `${service}.db`),
937
- join3(dataDir, "data.db"),
938
- join3(dataDir, "database.db")
936
+ join6(dataDir, `${service}.db`),
937
+ join6(dataDir, "data.db"),
938
+ join6(dataDir, "database.db")
939
939
  ];
940
940
  try {
941
- const files = readdirSync2(dataDir);
941
+ const files = readdirSync3(dataDir);
942
942
  for (const f of files) {
943
943
  if (f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm")) {
944
- candidates.push(join3(dataDir, f));
944
+ candidates.push(join6(dataDir, f));
945
945
  }
946
946
  }
947
947
  } catch {}
948
948
  for (const p of candidates) {
949
- if (existsSync3(p))
949
+ if (existsSync6(p))
950
950
  return p;
951
951
  }
952
952
  return null;
@@ -9323,7 +9323,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
9323
9323
  __export2(exports_discover, {
9324
9324
  isSyncExcludedTable: () => isSyncExcludedTable,
9325
9325
  getServiceDbPath: () => getServiceDbPath,
9326
- discoverSyncableServices: () => discoverSyncableServices,
9326
+ discoverSyncableServices: () => discoverSyncableServices2,
9327
9327
  discoverServices: () => discoverServices,
9328
9328
  SYNC_EXCLUDED_TABLE_PATTERNS: () => SYNC_EXCLUDED_TABLE_PATTERNS,
9329
9329
  KNOWN_PG_SERVICES: () => KNOWN_PG_SERVICES
@@ -9378,15 +9378,13 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
9378
9378
  init_config();
9379
9379
  init_config();
9380
9380
  init_dotfile();
9381
- init_adapter();
9382
9381
  init_config();
9383
- init_discover();
9384
- AUTO_SYNC_CONFIG_PATH = join4(homedir4(), ".hasna", "cloud", "config.json");
9382
+ AUTO_SYNC_CONFIG_PATH = join3(homedir3(), ".hasna", "cloud", "config.json");
9385
9383
  init_config();
9386
9384
  init_adapter();
9387
9385
  init_dotfile();
9388
9386
  init_config();
9389
- CONFIG_DIR2 = join6(homedir5(), ".hasna", "cloud");
9387
+ CONFIG_DIR2 = join5(homedir4(), ".hasna", "cloud");
9390
9388
  init_adapter();
9391
9389
  init_config();
9392
9390
  init_discover();
@@ -9400,18 +9398,18 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
9400
9398
  });
9401
9399
 
9402
9400
  // src/db/database.ts
9403
- import { copyFileSync as copyFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, statSync } from "fs";
9404
- import { dirname as dirname2, join as join5, resolve } from "path";
9401
+ import { copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync as readdirSync2, statSync } from "fs";
9402
+ import { dirname as dirname2, join as join4, resolve } from "path";
9405
9403
  function getDataDir2() {
9406
9404
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
9407
- const newDir = join5(home, ".hasna", "contacts");
9408
- const oldDir = join5(home, ".contacts");
9409
- if (existsSync4(oldDir) && !existsSync4(newDir)) {
9405
+ const newDir = join4(home, ".hasna", "contacts");
9406
+ const oldDir = join4(home, ".contacts");
9407
+ if (existsSync3(oldDir) && !existsSync3(newDir)) {
9410
9408
  mkdirSync3(newDir, { recursive: true });
9411
- for (const file of readdirSync3(oldDir)) {
9412
- const oldPath = join5(oldDir, file);
9409
+ for (const file of readdirSync2(oldDir)) {
9410
+ const oldPath = join4(oldDir, file);
9413
9411
  if (statSync(oldPath).isFile()) {
9414
- copyFileSync2(oldPath, join5(newDir, file));
9412
+ copyFileSync2(oldPath, join4(newDir, file));
9415
9413
  }
9416
9414
  }
9417
9415
  }
@@ -9423,13 +9421,13 @@ function getDbPath2() {
9423
9421
  return process.env["HASNA_CONTACTS_DB_PATH"];
9424
9422
  if (process.env["CONTACTS_DB_PATH"])
9425
9423
  return process.env["CONTACTS_DB_PATH"];
9426
- return join5(getDataDir2(), "contacts.db");
9424
+ return join4(getDataDir2(), "contacts.db");
9427
9425
  }
9428
9426
  function ensureDir(filePath) {
9429
9427
  if (filePath === ":memory:")
9430
9428
  return;
9431
9429
  const dir = dirname2(resolve(filePath));
9432
- if (!existsSync4(dir))
9430
+ if (!existsSync3(dir))
9433
9431
  mkdirSync3(dir, { recursive: true });
9434
9432
  }
9435
9433
  function getDatabase(path) {
@@ -12315,7 +12313,7 @@ async function importToApple(vcfData) {
12315
12313
  }
12316
12314
  // src/lib/connector.ts
12317
12315
  import { join as join7 } from "path";
12318
- import { existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
12316
+ import { existsSync as existsSync5, readFileSync as readFileSync2 } from "fs";
12319
12317
  import { homedir as homedir6 } from "os";
12320
12318
 
12321
12319
  class ConnectorNotInstalledError extends Error {
@@ -12389,7 +12387,7 @@ function getConnectorTokenPath(name, profile = "default") {
12389
12387
  join7(homedir6(), ".connect", `connect-${name}`, "tokens.json")
12390
12388
  ];
12391
12389
  for (const p of bases) {
12392
- if (existsSync6(p))
12390
+ if (existsSync5(p))
12393
12391
  return p;
12394
12392
  }
12395
12393
  return null;
@@ -13845,9 +13843,9 @@ init_contacts();
13845
13843
 
13846
13844
  // src/lib/images.ts
13847
13845
  init_database();
13848
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, copyFileSync as copyFileSync3, unlinkSync, readdirSync as readdirSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
13849
- import { join as join8, extname, basename } from "path";
13850
- var IMAGES_DIR = join8(getDataDir2(), "images");
13846
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, copyFileSync as copyFileSync3, unlinkSync, readdirSync as readdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
13847
+ import { join as join9, extname, basename } from "path";
13848
+ var IMAGES_DIR = join9(getDataDir2(), "images");
13851
13849
  function ensureImagesDir() {
13852
13850
  if (!existsSync7(IMAGES_DIR))
13853
13851
  mkdirSync5(IMAGES_DIR, { recursive: true });
@@ -13864,14 +13862,14 @@ function saveImage(entityId, source, options) {
13864
13862
  const ext2 = base64Match[1] === "jpeg" ? "jpg" : base64Match[1];
13865
13863
  const data = Buffer.from(base64Match[2], "base64");
13866
13864
  const filename2 = `${entityId}.${ext2}`;
13867
- writeFileSync2(join8(IMAGES_DIR, filename2), data);
13865
+ writeFileSync2(join9(IMAGES_DIR, filename2), data);
13868
13866
  return filename2;
13869
13867
  }
13870
13868
  if (!existsSync7(source) && /^[A-Za-z0-9+/=\n\r]+$/.test(source.trim()) && source.length > 100) {
13871
13869
  const ext2 = options?.format || "jpg";
13872
13870
  const data = Buffer.from(source.trim(), "base64");
13873
13871
  const filename2 = `${entityId}.${ext2}`;
13874
- writeFileSync2(join8(IMAGES_DIR, filename2), data);
13872
+ writeFileSync2(join9(IMAGES_DIR, filename2), data);
13875
13873
  return filename2;
13876
13874
  }
13877
13875
  if (!existsSync7(source)) {
@@ -13883,14 +13881,14 @@ function saveImage(entityId, source, options) {
13883
13881
  throw new Error(`Unsupported image format: ${ext}. Supported: ${validExts.join(", ")}`);
13884
13882
  }
13885
13883
  const filename = `${entityId}.${ext === "jpeg" ? "jpg" : ext}`;
13886
- copyFileSync3(source, join8(IMAGES_DIR, filename));
13884
+ copyFileSync3(source, join9(IMAGES_DIR, filename));
13887
13885
  return filename;
13888
13886
  }
13889
13887
  function getImagePath(entityId) {
13890
13888
  ensureImagesDir();
13891
- const files = readdirSync5(IMAGES_DIR);
13889
+ const files = readdirSync4(IMAGES_DIR);
13892
13890
  const match = files.find((f) => f.startsWith(`${entityId}.`));
13893
- return match ? join8(IMAGES_DIR, match) : null;
13891
+ return match ? join9(IMAGES_DIR, match) : null;
13894
13892
  }
13895
13893
  function getImageAsBase64(entityId) {
13896
13894
  const path = getImagePath(entityId);
@@ -13903,11 +13901,11 @@ function getImageAsBase64(entityId) {
13903
13901
  }
13904
13902
  function deleteImage(entityId) {
13905
13903
  ensureImagesDir();
13906
- const files = readdirSync5(IMAGES_DIR);
13904
+ const files = readdirSync4(IMAGES_DIR);
13907
13905
  let deleted = false;
13908
13906
  for (const f of files) {
13909
13907
  if (f.startsWith(`${entityId}.`)) {
13910
- unlinkSync(join8(IMAGES_DIR, f));
13908
+ unlinkSync(join9(IMAGES_DIR, f));
13911
13909
  deleted = true;
13912
13910
  }
13913
13911
  }
@@ -13915,22 +13913,22 @@ function deleteImage(entityId) {
13915
13913
  }
13916
13914
  function listImages() {
13917
13915
  ensureImagesDir();
13918
- const files = readdirSync5(IMAGES_DIR).filter((f) => !f.startsWith("."));
13916
+ const files = readdirSync4(IMAGES_DIR).filter((f) => !f.startsWith("."));
13919
13917
  return files.map((f) => ({
13920
13918
  entity_id: basename(f, extname(f)),
13921
13919
  filename: f,
13922
- path: join8(IMAGES_DIR, f)
13920
+ path: join9(IMAGES_DIR, f)
13923
13921
  }));
13924
13922
  }
13925
13923
  // src/lib/vault.ts
13926
13924
  init_database();
13927
- import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync6, unlinkSync as unlinkSync2 } from "fs";
13928
- import { join as join9 } from "path";
13925
+ import { existsSync as existsSync9, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync6, unlinkSync as unlinkSync2 } from "fs";
13926
+ import { join as join10 } from "path";
13929
13927
  import { createCipheriv, createDecipheriv, randomBytes, pbkdf2Sync, createHash } from "crypto";
13930
13928
  var VAULT_DIR = getDataDir2();
13931
- var VAULT_CONFIG = join9(VAULT_DIR, "vault.json");
13932
- var VAULT_SESSION = join9(VAULT_DIR, ".vault-session");
13933
- var DOCUMENTS_DIR = join9(VAULT_DIR, "documents");
13929
+ var VAULT_CONFIG = join10(VAULT_DIR, "vault.json");
13930
+ var VAULT_SESSION = join10(VAULT_DIR, ".vault-session");
13931
+ var DOCUMENTS_DIR = join10(VAULT_DIR, "documents");
13934
13932
  var SESSION_TTL_MS = 30 * 60 * 1000;
13935
13933
  var _derivedKey = null;
13936
13934
  function deriveKey(passphrase, salt) {
@@ -13944,7 +13942,7 @@ function saveSession(key) {
13944
13942
  writeFileSync3(VAULT_SESSION, JSON.stringify(session), { mode: 384 });
13945
13943
  }
13946
13944
  function loadSession() {
13947
- if (!existsSync8(VAULT_SESSION))
13945
+ if (!existsSync9(VAULT_SESSION))
13948
13946
  return null;
13949
13947
  try {
13950
13948
  const session = JSON.parse(readFileSync4(VAULT_SESSION, "utf-8"));
@@ -13961,14 +13959,14 @@ function loadSession() {
13961
13959
  }
13962
13960
  function clearSession() {
13963
13961
  try {
13964
- if (existsSync8(VAULT_SESSION))
13962
+ if (existsSync9(VAULT_SESSION))
13965
13963
  unlinkSync2(VAULT_SESSION);
13966
13964
  } catch {}
13967
13965
  }
13968
13966
  function initVault(passphrase) {
13969
- if (!existsSync8(VAULT_DIR))
13967
+ if (!existsSync9(VAULT_DIR))
13970
13968
  mkdirSync6(VAULT_DIR, { recursive: true });
13971
- if (!existsSync8(DOCUMENTS_DIR))
13969
+ if (!existsSync9(DOCUMENTS_DIR))
13972
13970
  mkdirSync6(DOCUMENTS_DIR, { recursive: true });
13973
13971
  const salt = randomBytes(32);
13974
13972
  const key = deriveKey(passphrase, salt);
@@ -13979,10 +13977,10 @@ function initVault(passphrase) {
13979
13977
  saveSession(key);
13980
13978
  }
13981
13979
  function isVaultInitialized() {
13982
- return existsSync8(VAULT_CONFIG);
13980
+ return existsSync9(VAULT_CONFIG);
13983
13981
  }
13984
13982
  function unlockVault(passphrase) {
13985
- if (!existsSync8(VAULT_CONFIG))
13983
+ if (!existsSync9(VAULT_CONFIG))
13986
13984
  throw new Error("Vault not initialized. Run 'contacts vault init' first.");
13987
13985
  const config = JSON.parse(readFileSync4(VAULT_CONFIG, "utf-8"));
13988
13986
  const salt = Buffer.from(config.salt, "hex");
@@ -14039,21 +14037,21 @@ function decrypt(ciphertext, iv) {
14039
14037
  return decrypted;
14040
14038
  }
14041
14039
  function storeFile(sourcePath, entityId) {
14042
- if (!existsSync8(DOCUMENTS_DIR))
14040
+ if (!existsSync9(DOCUMENTS_DIR))
14043
14041
  mkdirSync6(DOCUMENTS_DIR, { recursive: true });
14044
14042
  const ext = sourcePath.split(".").pop() || "bin";
14045
- const destPath = join9(DOCUMENTS_DIR, `${entityId}.${ext}`);
14043
+ const destPath = join10(DOCUMENTS_DIR, `${entityId}.${ext}`);
14046
14044
  const data = readFileSync4(sourcePath);
14047
14045
  writeFileSync3(destPath, data);
14048
14046
  return destPath;
14049
14047
  }
14050
14048
  function getDocumentFilePath(entityId) {
14051
- if (!existsSync8(DOCUMENTS_DIR))
14049
+ if (!existsSync9(DOCUMENTS_DIR))
14052
14050
  return null;
14053
- const { readdirSync: readdirSync4 } = __require("fs");
14054
- const files = readdirSync4(DOCUMENTS_DIR);
14051
+ const { readdirSync: readdirSync5 } = __require("fs");
14052
+ const files = readdirSync5(DOCUMENTS_DIR);
14055
14053
  const match = files.find((f) => f.startsWith(`${entityId}.`) && !f.endsWith(".enc"));
14056
- return match ? join9(DOCUMENTS_DIR, match) : null;
14054
+ return match ? join10(DOCUMENTS_DIR, match) : null;
14057
14055
  }
14058
14056
  function decryptFile(encPath) {
14059
14057
  const key = requireVault();
@@ -14066,13 +14064,13 @@ function decryptFile(encPath) {
14066
14064
  return Buffer.concat([decipher.update(encrypted), decipher.final()]);
14067
14065
  }
14068
14066
  function getDocumentsDir() {
14069
- if (!existsSync8(DOCUMENTS_DIR))
14067
+ if (!existsSync9(DOCUMENTS_DIR))
14070
14068
  mkdirSync6(DOCUMENTS_DIR, { recursive: true });
14071
14069
  return DOCUMENTS_DIR;
14072
14070
  }
14073
14071
  // src/db/documents.ts
14074
14072
  init_database();
14075
- import { existsSync as existsSync9, unlinkSync as unlinkSync3 } from "fs";
14073
+ import { existsSync as existsSync10, unlinkSync as unlinkSync3 } from "fs";
14076
14074
  var DOCUMENT_TYPES = [
14077
14075
  "passport",
14078
14076
  "national_id",
@@ -14129,7 +14127,7 @@ function listDocuments(contactId, db) {
14129
14127
  function deleteDocument(id, db) {
14130
14128
  const _db2 = db || getDatabase();
14131
14129
  const row = _db2.query(`SELECT encrypted_file_path FROM contact_documents WHERE id = ?`).get(id);
14132
- if (row?.encrypted_file_path && existsSync9(row.encrypted_file_path)) {
14130
+ if (row?.encrypted_file_path && existsSync10(row.encrypted_file_path)) {
14133
14131
  try {
14134
14132
  unlinkSync3(row.encrypted_file_path);
14135
14133
  } catch {}
@@ -14245,7 +14243,7 @@ function deleteHealthData(contactId, db) {
14245
14243
  _db2.query(`DELETE FROM contact_health WHERE contact_id = ?`).run(contactId);
14246
14244
  }
14247
14245
  // src/lib/document-scanner.ts
14248
- import { readFileSync as readFileSync5, existsSync as existsSync10 } from "fs";
14246
+ import { readFileSync as readFileSync5, existsSync as existsSync11 } from "fs";
14249
14247
  import { extname as extname2 } from "path";
14250
14248
  async function scanDocument(imageSource, docType) {
14251
14249
  const apiKey = process.env["OPENAI_API_KEY"];
@@ -14255,7 +14253,7 @@ async function scanDocument(imageSource, docType) {
14255
14253
  let imageData;
14256
14254
  if (imageSource.startsWith("data:image/")) {
14257
14255
  imageData = imageSource;
14258
- } else if (existsSync10(imageSource)) {
14256
+ } else if (existsSync11(imageSource)) {
14259
14257
  const buffer = readFileSync5(imageSource);
14260
14258
  const ext = extname2(imageSource).slice(1).toLowerCase();
14261
14259
  const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "png" ? "image/png" : ext === "webp" ? "image/webp" : ext === "gif" ? "image/gif" : "image/jpeg";